色哟哟视频在线观看-色哟哟视频在线-色哟哟欧美15最新在线-色哟哟免费在线观看-国产l精品国产亚洲区在线观看-国产l精品国产亚洲区久久

0
  • 聊天消息
  • 系統消息
  • 評論與回復
登錄后你可以
  • 下載海量資料
  • 學習在線課程
  • 觀看技術視頻
  • 寫文章/發帖/加入社區
會員中心
創作中心

完善資料讓更多小伙伴認識你,還能領取20積分哦,立即完善>

3天內不再提示

阿里二面:了解MySQL事務底層原理嗎

數據分析與開發 ? 來源:數據分析與開發 ? 2024-01-18 16:34 ? 次閱讀

MySQL 可以說是每個 Java 程序員必會的技能之一,作為 Java 的高級進階必備技能點,MySQL 的調優和底層原理必然是需要知道的。

但是大家似乎形成了一種思維定勢,那就是提到 MySQL 好像就一股腦的往 MySQL 的索引啊、優化啊、之類的上面去鉆。本文我們拋開“熱門”的話題,來和大家一起來聊一聊比較冷門但比較重要的技術點:MySQL 事務的底層原理

這事情還得從頭說起

首先大家需要知道的是 MySQL 是支持事務并發執行的,這又回到了最原始的問題了,「并發安全性問題」。在數據庫事務中并發問題是這樣子的:A 事務來寫某條記錄的數據,B 事務也在寫該條記錄的數據。那如果啥也不做,勢必會造成數據的錯亂,MySQL 在設計之初就考慮到了這個問題。

那么 MySQL 到底是如何解決這樣的問題的呢?其實是使用了 MVCC 多版本控制機制事務隔離機制鎖機制等辦法來解決事務并發問題。那說到這里不知道各位有沒有想過這樣一個問題:在數據庫中如果并發事務不做控制和處理,會有什么樣的危害呢

帶著這樣的疑問,請繼續往下看。

臟數據

什么是臟數據,它有哪些類型

臟數據的具體概念有以下四種,分別是:臟寫、臟讀、不可重復讀、幻讀。我們來看看這幾個概念的意思

1、臟寫

臟寫是指一個事務修改且已經提交的數據被另外一個事務給回滾了

首先來分析一下概念:假設有兩個事務 A、B。事務 A 先開啟事務,并且修改了一條 id 為 1 的記錄,將 name 改成 A(假設原來為 null),但是此時 事務 A 還沒有提交。這個時候事務 B 開啟了。事務 B 將 id 為 1 的記錄中 name 改成了 B,并且將事務提交 了。但是這個時候事務 A 不想修改了,就像之前自己修改的數據回滾了。也就是說此時導致的結果就是 id 為 1 的這條記錄的 name 還是為 null。

然后事務 B 去查詢這條記錄。結果蒙了。name 居然為 null。這就是臟寫。事務 B 已經寫入的記錄被事務 A 給回滾了。

看不懂沒有關系,我們先來看一張圖

3e47cf9c-b5d6-11ee-8b88-92fbcf53809c.png

對著圖再來看一下上面的分析過程。

那 MySQL 是如何來解決臟寫這種問題的?沒錯,就是。MySQL 在開啟一個事務的時候,他會將某條記錄和事務做一個綁定。這個其實和 JVM 鎖是類似的。因為此時事務 A 先開啟了,并關聯綁定了這條記錄。所以事務 B 此時如果想操作同樣的記錄,只能等待。當事務 A 執行完成了,就會通知正在等在事務。然后下一個事務繼續操作執行。

啥?說好的并發,這說到底不還是串行嗎?這樣數據庫豈不是慢的要死。實際上這些操作都是在內存中執行的。具體一點是在 Buffer Pool 中執行的。所以速度是非常快的。

2、臟讀

臟讀是指一個事務讀取到了另外一個事務沒有提交的記錄

其實臟讀是最好理解的。我們還是假設有兩個事務 A、B。事務 A 先開啟了,將 id 為 1 的記錄中的 name 改成了 A,但是還沒有提交。此時事務 B 開啟了。事務 B 查詢到當前 name 的值為 A,然后就會按照 A 邏輯去執行處理。結果事務 A 回滾了事務,事務 B 再次查詢的時候發現記錄值不是 A。這就是臟讀。

事務 B 讀取到的 name 值是事務 A 修改但是沒有提交的記錄。

來張圖來直觀的理解下:

3e4bffcc-b5d6-11ee-8b88-92fbcf53809c.png

3、不可重復讀

不可重復讀是指前后讀取到的某條記錄的結果不一樣

廢話少說,直接進分析:假設有三個事務 A、B、C ,事務 A 先開啟了,但是還沒有執行任何的操作,事務 B 開啟了,事務 B 將 id 為 1 的記錄的 name 改為 B 并提交了事務,此時事務 A 開始活動了,查詢到的這條記錄的 name 值為 B,還是還未執行任何操作。此時事務 C 開啟了,事務 C 將 id 為 1 的記錄的 name 改為 C 并提交了事務。此時事務 A 又開始活動了,結果查詢到的 id 為 1 的 name 值又變成了 C。這就是不可重復讀

其實理解起來還是很簡單的。看起來高大上名字,實際上就這么幾句話就能描述結束了。下面還是來一張圖來更直觀認識下:

3e565580-b5d6-11ee-8b88-92fbcf53809c.png

4、幻讀

幻讀是指前后讀取到的記錄的數量不一樣

幻讀和不可重復讀有點類似,不可重復讀強調的是數據的值不一樣,重點是修改,而幻讀強調的是記錄的數量不一樣,重點是新增或刪除。就好像是看花眼產生重影一樣。

先來分析一下幻讀。還是假設有兩個事務 A、B。事務 A 先開啟了,并執行了這樣的 SQL:select * from user,假設現在結果是 5 條,此時事務 B 開啟了,并往 user 表中插入了一條記錄,并提交了事務,此時事務 A 又執行了 select * from user結果發現是 6 條記錄。懵逼了。還以為自己餓昏了眼花了。這就是所謂的幻讀。

3e6a59d6-b5d6-11ee-8b88-92fbcf53809c.png

以上的四個問題是現代數據庫典型的問題,這些問題會在不同的數據庫的事務隔離級別下產生。所以下面要分析的就是事務的隔離級別。

事務的隔離級別

事務的隔離級別有以下四種

  1. Read Uncommitted:讀取未提交【生產估計沒人這么設置的】
    意思就是一個事務能夠讀取到另一個事務未提交的修改

  2. Read Committed[簡稱 RC]:讀取已提交
    意思就是一個事務能讀取到另一個事務已經提交了的修改

  3. Repeatable read[簡稱 RR]:可重復讀
    【MySQL 的默認隔離級別】,即事務之間只要是在進行中,彼此之間不會有任何的干擾

  4. serializable:串行化
    這個就有點狠了,就好比 Java 中的 synchroinzed 關鍵字,所有的請求只能一個一個來還行,很顯然效率最低,基本也不會使用這種隔離劑唄

隔離級別 臟讀 臟寫 不可重復讀 幻讀
Read Uncommitted:讀取未提交 ×
Read Committed:讀取已提交 × ×
Repeatable read:可重復讀 × × ×
Serializable:串行化(也有稱序列化的) × × × ×

MVCC 機制

MVCC(全稱 Multi-Version Concurrency Control),即多版本并發控制。MVCC 是一種并發控制的方法,一般在數據庫管理系統中,實現對數據庫的并發訪問;

我們本文的重點是事務的隔離級別的底層原理,但是似乎說到現在也并沒有發現關于事務原理的影子(想發水文?)。

實際上要了解事務的底層原理,根本沒法上來就開魯,我相信那樣的文章寫出來不僅沒人看,更是看不懂。所以為了讓大家由淺入深的慢慢掌握。我必須要做很多鋪墊,將相關的知識點進行拋磚引玉,然后一層一層剖析到原理。這里還請大家明白。

說到這里,我們又要提到一個新的概念了。就是數據在磁盤存儲的時候,每一條存儲的記錄都會有事務 ID 和回滾指針(其他的是什么本文不需要關注,學習抓住脈路即可,否則必定走火入魔)。

3e759b48-b5d6-11ee-8b88-92fbcf53809c.png

這兩個到底是干嘛的?我們還是先從概念說起

事務 ID:就是每個事務的唯一標識
回滾指針:該事務之前的記錄的引用(指針)。換句話說就是相對現在時間節點的老數據

假設你需要操作某條記錄,首先該條記錄一定是先被加載到 Buffer Pool 中的,并且有這樣的一條 undo log 記錄。

畫外音:undo log 就是修改前的記錄。用于回滾的。

3e7b6500-b5d6-11ee-8b88-92fbcf53809c.png

假設現在事務 A 開啟了事務,將值改為 A

3e7ec146-b5d6-11ee-8b88-92fbcf53809c.png

事務 A 還在活躍中,這個時候事務 B 開啟了,將值改為 B

3e89f52a-b5d6-11ee-8b88-92fbcf53809c.png

此時事務 A 和事務 B 都還在活躍中,這個時候事務 C 開啟了,并將值改為 C

3e8e2e7e-b5d6-11ee-8b88-92fbcf53809c.png

看到這里是不是稍微有一點感覺了。這上面的圖有一個專有名詞:MVCC 版本控制鏈。同時這里又涉及到一個新的名詞:ReadView。就是每個事務在開啟的時候都會創建一個 ReadView 視圖。那具體什么叫 ReadView ,我們這里還不能一帶而過,相反需要我們來詳細的討論分析下。

ReadView

ReadView 可能是你理解事務底層原理的核心部分,那么什么是 ReadView 呢

在每個事務開啟的時候都會創建一個 ReadView 視圖,作用就是用來記錄每個事務中的操作的一些 Undo Log 記錄。

他里面涉及到幾個字段。分別是:m_ids、min_trx_id、max_trx_id、creator_trx_id。他們的具體含義如下:

  1. m_ids:用于記錄活躍中的事務的 ID;

  2. min_trx_id:當前活躍的事務中的最小的事務 ID;

  3. max_trx_id:下一個即將要生成的事務 ID。注意這里并不是指的最大的事務 ID,這個事務一定是當前的 m_ids 中不存在的。(事務 ID 的生成是遞增的);

  4. creator_trx_id:當前活躍事務的 ID;

不要慌,光說概念一定是在耍流氓。下面我會通過圖文并茂的形式來一一說明解釋。假設有一個記錄現在是這樣存放的

3e91e00a-b5d6-11ee-8b88-92fbcf53809c.png

看到這里大家應該知道的是,這條記錄一定是原來的某一個事務修改后的結果。也就是說這是一條原本的已經存在的記錄。

現在假設有 A、B、C 三個事務,他們分別先后開啟,假設他們的事務 ID 依次為:4、5、6。

先來看事務 A,此時的m_ids 為:[4、5、6],min_trx_id 為:4,max_trx_id 為 7(下圖第三行為max_trx_id),creator_trx_id 為 4。

3e9567b6-b5d6-11ee-8b88-92fbcf53809c.png

事務 A 首先執行了一次查詢操作,他此時是這么執行的:

首先他會順著 MVCC 的版本控制鏈往下找。找啥?找該條記錄的以前操作它的事務 ID,他發現找到的這個 undolog 日志的對應的事務 ID 為 3,比自己的 4 要小,所以可以肯定這條記錄不是自己修改的,而又因為 m_ids 中的事務 ID 為 4、5、6,3 是比他們都要小的,所以可推斷出查找到的這條記錄是在本次事務開啟之前就已經存在的。所以事務 A 查詢到的值為 C。

此時事務 B 同樣開始查詢這條記錄了。以此類推事務 B 此時的執行流程大概是這樣子的,首先事務 B 會以同樣的方式查詢數據(PS:這些操作都是在內存中的)同樣查詢到的結果是 C,經過上面的的對于事務 A 的分析,相信這里已經不是問題了。但是假如現在事務 B 將該值改成了 B,也就是下面的這張圖的樣子。

3e99650a-b5d6-11ee-8b88-92fbcf53809c.png

此時事務 A 又開始活躍了,還是執行查詢操作,這個時候結果該是多少呢?

首先事務 A 發現同樣會順著該條記錄的 MVCC 版本控制鏈往下找,發現事務 ID 為 5 ,比 m_ids 中的最小的事務 ID 4 要大,那么可以且是存在于該集合中的,此時就可以斷定事務 ID 為 5 的事務是正在進行中的事務,所以事務 A 是不會取該條 undo log 的值的。

然后繼續往下找,找到了事務 ID 為 3 的 undo log 記錄,對比后發現 3 不在 m_ids 中,且比 m_ids 中的最小的事務 ID 都要小。下面的判斷就和剛開始的查詢判斷一樣了。

假設此時事務 A 將該條記錄的值改成 A ,然后事務 A 再查詢這條記錄,那么請問這個時候事務 A 查詢是怎么樣子的這一步非常重要)?現在這些事務以及數據在我們的腦袋中應該是這樣子的:

3ea8ad12-b5d6-11ee-8b88-92fbcf53809c.png

那么事務 A 到底是怎么查詢的?查出來的結果到底是 A 還是 B?先來看下這張圖,然后根據圖一步一步來分析

3eacabba-b5d6-11ee-8b88-92fbcf53809c.png

事務 A 開始查詢,返現此時的 undo log 日志針對于該條記錄的 undo log 鏈(MVCC 版本鏈的另一種叫法)的第一條記錄的事務 ID 為 4 ,一對比發現不就是自己修改的值嗎?那么查詢的結果就是 A。

那么此時如果是事務 B 來執行查詢呢?結果你能否分析一下?那就是首先 B 發現最新的事務 ID 為 4 ,且在 m_ids 中,可以斷定這是一條正在執行中的事務,且不和自己的一樣,所以是不會取該值的。

然后繼續順著 undo log 日志鏈往下找,找到了事務 ID 為 5 的記錄,發現和自己的一樣,那這個不就是需要查找的結果嗎?也就是說 事務 B 查找到的結果是 B。

以上是關于 ReadView 的相關的介紹,總體內容不算難,但是是需要認真思考的,這里先來一個小總結

  1. ReadView 其實使用版本鏈機制

  2. 他里面的核心屬性為:

  • m_ids: 一個列表, 存儲當前系統活躍的事務 id (重點)

  • min_trx_id: 當前 m_ids 活動事務中的最小的事務 ID

  • max_trx_id: 下一個即將被分配出來的事務 ID

  • creator_trx_id: 當前的事務的 ID

  • ReadView 記錄的是:每個事務中的 Undo log 日志

說到這里,下面繼續來分析本文的主題知識點:事務的底層原理(其實上面多多少少都說到了)。其實事務的底層就是基于 ReadView 來設計的。關于事務的底層原理,我們以 RC(Read Commit)和 RR(Repeatable read)來分析

1. Read commit

Read Commit 是事務隔離級別的其中一種,含義是:讀取已經提交的記錄。舉個例子來說,假設有事務 A 和事務 B 都在活動中,事務 B 提交的記錄是能夠被事務 A 讀取到的。

具體我們開始一步一步來分析。首先需要大家知道的是在 RC 隔離級別下,一個事務的每次查詢操作,數據庫都會為其創建一個新的 ReadView,這就是 RC 的核心思想。

假設有事務 A 和事務 B ,事務 ID 分別為 10 和 11,事務 A 還沒開始活躍,事務 B 就將某條記錄的值改為 B(假設原來的值為 X),但是還未提交,現在你可以想象一下下面這張圖:

3eb112ae-b5d6-11ee-8b88-92fbcf53809c.png

此時事務 A 開始活躍了,他首先執行了一次查詢操作。按照上面的核心思想,此時數據庫會重新創建一個 ReadView 里面的幾個屬性的值分別為:

  • m_ids:[10,11]

  • min_trx_id:10

  • max_trx_id: 12

  • creator_trx_id:10

接著就是就是和上面說過的一樣的查詢過程了,首先 A 查詢到的最近的一個事務 ID 為 11,發現在 m_ids 中,但是又和自己的事務 ID 不相等,所以就會順著 undo log 鏈繼續查找,然后找到了事務 ID 為 3 的記錄,發現不在 m_ids 中且,比最小的事務 ID 10 還要小,所以可以斷定出事務 ID 為 3 的這個記錄是原本就存在的記錄,所以查詢到的結果就是 X。

接著事務 B 又開始活躍了,事務 B 直接提交了事務,然后事務 A 又發起了一起查詢操作。現在這個時候就是 RC 的核心了:這個時候數據庫會再次為事務 A 創建一個新的 ReadView 里面的四個屬性分別為:

  • m_ids:[10]

  • min_trx_id:10

  • max_trx_id: 12

  • creator_trx_id:10

然后 A 按照正常的流程去查詢,首先查詢到的是事務 ID 為 11 的記錄,結果發現不在 m_ids 中,那這個時候就可以斷定的是:這個是最近已經提交的記錄,所以是能夠查詢到 B 這個值的,也就是說這次查詢得到的結果就是 B 。

這就是 RC,是不是如果看懂了 ReadView 原理,這些再看起來就非常簡單了?

2. Repeatable read

Repeatable read 是 MySQL 默認的隔離級別,既然是默認的,那一定是很厲害咯?其實你看完會發現 just so so ?

RR 的核心思想是:ReadView 創建以后直到事務提交,都不會再次重新生成

首先還是有事務 A 和事務 B,事務 ID 分別為 10 和 11 ,事務 B 首先將值改為 B (假設原來值為 X),然后 事務 A 發起了一次查詢的操作:

3ebe2a34-b5d6-11ee-8b88-92fbcf53809c.png

查詢過程和前面的一模一樣。我就不再贅述了。

接著事務 B 又開始活躍了,直接提交了事務,然后事務 A 又發起了一次查詢。這個時候奇跡就出現了。因為我們剛剛說了:ReadView 創建以后直到事務提交,都不會再次重新生成。因為事務 A 在創建 ReadView 的時候 m_ids 是 10 和 11,所以現在查詢的時候里面仍然是這個值,現在的查詢是這樣子的:事務 A 首先查詢到的事務 ID 為 11 ,結果發現在 m_ids 中,也就不會取該值,會繼續查找,當查找到事務 ID 為 3 的時候,發現不在 m_ids 中,所以查詢到的就是 X。

現在你知道為什么這個隔離級別下的事務不會互相干擾了吧?這就是原理

本文小結

本文為了說明事務的底層原理,做了大量的鋪墊,相信大家看完不光對不同隔離級別下事務的實現會有更深刻地理解,也同時明白了 undo log 記錄的作用,所以多探索一下底層你會發現各種知識點是如何串在一起工作的,這種通透的感覺確實很奇妙^_^


聲明:本文內容及配圖由入駐作者撰寫或者入駐合作網站授權轉載。文章觀點僅代表作者本人,不代表電子發燒友網立場。文章及其配圖僅供工程師學習之用,如有內容侵權或者其他違規問題,請聯系本站處理。 舉報投訴
  • JAVA
    +關注

    關注

    19

    文章

    2966

    瀏覽量

    104702
  • 數據庫
    +關注

    關注

    7

    文章

    3794

    瀏覽量

    64362
  • MySQL
    +關注

    關注

    1

    文章

    804

    瀏覽量

    26531

原文標題:阿里二面:了解 MySQL 事務底層原理嗎

文章出處:【微信號:DBDevs,微信公眾號:數據分析與開發】歡迎添加關注!文章轉載請注明出處。

收藏 人收藏

    評論

    相關推薦

    在制造多層板的時候,最底層的基板,它鍍銅,都要腐蝕電路嗎?

    `就是在制造多層板的時候,最底層的基板,這個基板比較難搞,它鍍銅,都要腐蝕電路嗎?`
    發表于 11-03 15:57

    全球唯一:MySQL社區2018年度公司貢獻獎頒給阿里

    摘要: 在剛剛的Percona Live開源數據庫大會上,MySQL社區委員會宣布將2018年度的MySQL社區公司貢獻獎(Corporate Contributor Award)唯一頒給阿里
    發表于 04-25 11:51

    比傳統事務快10倍?一張圖讀懂阿里云全局事務服務GTS

    摘要: 近日,阿里云全局事務服務GTS正式上線,為微服務架構中的分布式事務提供一站式解決方案。GTS有哪些功能,相比傳統事務的優勢在哪呢?我們通過一張圖讀懂GTS。近日,
    發表于 06-04 19:02

    雙11同款!阿里云發布全局事務服務GTS:每秒處理10萬筆事務

    是系統微服務化后,一個看似簡單的功能,內部可能需要調用多個服務并操作多個數據庫實現,服務調用的分布式事務問題變得非常突出。GTS處理分布式事務了解決這些難題,GTS首先將微服務從
    發表于 06-05 17:43

    詳解Mysql數據庫InnoDB存儲引擎事務

    關于Mysql數據庫InnoDB存儲引擎事務的一點理解
    發表于 05-13 10:11

    阿里云服務器上安裝MySQL的步驟

    阿里云服務器(Linux系統)上安裝MySQL
    發表于 06-05 16:43

    阿里云ECS配置MYSQL安裝

    阿里云ECS配置之MYSQL
    發表于 04-15 07:29

    MySQL的索引、事務、視圖介紹

    MySQL--索引、事務、視圖
    發表于 06-15 07:05

    關于MySQL事務一個多小時的面試 太難了

    則心里慌得一批。 果然,他手里拿著我的簡歷,快速的掃了一下,然后用眼角余光看了一下我,上來就開問。 面試官:看你簡歷上說精通Mysql優化方法,你先來說說你對Mysql事務了解吧。
    的頭像 發表于 09-24 15:39 ?1468次閱讀
    關于<b class='flag-5'>MySQL</b><b class='flag-5'>事務</b>一個多小時的面試  太難了

    MySQL事務日志

    大家都清楚,日志是 MySQL 數據庫的重要組成部分,記錄著數據庫運行期間各種狀態信息。MySQL 日志主要包括「錯誤日志」、「查詢日志」、「慢查詢日志」、「進制日志(binlog)」和
    的頭像 發表于 11-14 09:58 ?1726次閱讀
    <b class='flag-5'>MySQL</b><b class='flag-5'>事務</b>日志

    MySQL事務的四大隔離級別詳解

    之前分析一個死鎖問題,發現自己對數據庫隔離級別理解還不夠深入,所以趁著這幾天假期,整理一下MySQL事務的四大隔離級別相關知識,希望對大家有幫助~ 事務 什么是事務
    的頭像 發表于 11-27 16:07 ?2695次閱讀

    MySQL底層原理和技術學習

    很多小伙伴工作很長時間了,對于MySQL的掌握程度卻僅僅停留在表面的CRUD,對于MySQL深層次的原理和技術知識了解的少之又少,隨著工作年限的不斷增長,職場競爭力卻是不斷降低的。很多時候,出去
    的頭像 發表于 04-06 16:51 ?3045次閱讀

    MySQL事務隔離級別要實際解決的問題

    MySQL 是支持多事務并發執行的。否則來一個事務處理一個請求,處理一個人請求的時候,其它事務都等著,那估計都沒人敢用MySQL作為數據庫,
    的頭像 發表于 11-17 17:00 ?2792次閱讀
    <b class='flag-5'>MySQL</b><b class='flag-5'>事務</b>隔離級別要實際解決的問題

    你是否對MySQL數據庫中的事務已經有所了解呢?

    你是否對 MySQL 數據庫中的事務已經有所了解?看下面這張圖,按照 1~6 的順序依次執行,在RR隔離級別下,事務 A 和事務 B 各自輸
    的頭像 發表于 02-21 17:20 ?638次閱讀

    MYSQL事務底層原理詳解

    事務的實現機制上,MySQL 采用的是 WAL:Write-ahead logging,預寫式日志,機制來實現的。
    的頭像 發表于 11-15 10:10 ?577次閱讀
    <b class='flag-5'>MYSQL</b><b class='flag-5'>事務</b>的<b class='flag-5'>底層</b>原理詳解
    主站蜘蛛池模板: 国产成人免费观看| 在线免费公开视频| 九色PORNY蝌蚪视频首页| 一二三四免费中文在线1| 擼擼擼麻豆密臀AV| BL文高H强交| 色欲AV亚洲午夜精品无码| 国产美女久久久久久久久久久| 亚洲蜜桃AV永久无码精品放毛片| 久久精品免费观看久久| 97色香蕉在线| 色一欲一性一乱一区二区三区 | yellow视频免费观看高清在线| 日本无码欧美激情在线视频| 国产精品你懂的在线播放| 亚洲青青青网伊人精品| 美女张开腿让男人桶爽无弹窗| 超碰97视频在线观看| 性啪啪chinese东北女人| 久久精品一卡二卡三卡四卡视频版| 99久久久无码国产精品不卡按摩| 日韩毛片大全| 九九久久久2| good神马电影伦理午夜| 午夜A级理论片左线播放| 久久久久久久网站| 99在线精品国自产拍| 无码国产成人777爽死| 久久精品亚洲牛牛影视| 抽插内射高潮呻吟爆乳| 亚洲免费片| 欧美乱子YELLOWVIDEO| 国产精品一区二区AV97| 在线AV国产传媒18精品免费| 人人干人人看| 精品国产90后在线观看| 999久久久国产精品蜜臀AV| 我们日本在线观看免费动漫下载| 久久免费看视频| 国产AV精品无码免费看| 伊人在线视频|