精品欧美一区二区三区在线观看 _久久久久国色av免费观看性色_国产精品久久在线观看_亚洲第一综合网站_91精品又粗又猛又爽_小泽玛利亚一区二区免费_91亚洲精品国偷拍自产在线观看 _久久精品视频在线播放_美女精品久久久_欧美日韩国产成人在线

讓我們一起告別 MVCC !

數據庫 MySQL
事務是在 MySQL 引擎層實現的,我們常見的 InnoDB 引擎是支持事務的,事務的四大特性是原子性、一致性、隔離性、持久性,我們這次主要講的是隔離性。

大家好,我是小林。

之前寫過一篇 MySQL 的 MVCC 的工作原理,最近有讀者在網站上學習的時候,評論區指出了一些問題。

而這個知識點很重要,面試太常問了,所以,我就重寫了這篇文章!開車!

正文

這是我的錢包,共有 100 萬元。

今天我心情好,我決定給你的轉賬 100 萬,最后的結果肯定是我的余額變為 0 元,你的余額多了 100 萬元,是不是想到就很開心?

轉賬這一動作在程序里會涉及到一系列的操作,假設我向你轉賬 100 萬的過程是有下面這幾個步驟組成的:

可以看到這個轉賬的過程涉及到了兩次修改數據庫的操作。

假設在執行第三步驟之后,服務器忽然掉電了,就會發生一個蛋疼的事情,我的賬戶扣了 100 萬,但是錢并沒有到你的賬戶上,也就是說這 100 萬消失了!

要解決這個問題,就要保證轉賬業務里的所有數據庫的操作是不可分割的,要么全部執行成功 ,要么全部失敗,不允許出現中間狀態的數據。

數據庫中的「事務(Transaction)」就能達到這樣的效果。

我們在轉賬操作前先開啟事務,等所有數據庫操作執行完成后,才提交事務,對于已經提交的事務來說,該事務對數據庫所做的修改將永久生效,如果中途發生發生中斷或錯誤,那么該事務期間對數據庫所做的修改將會被回滾到沒執行該事務之前的狀態。

事務有哪些特性?

事務是由 MySQL 的引擎來實現的,我們常見的 InnoDB 引擎它是支持事務的。

不過并不是所有的引擎都能支持事務,比如 MySQL 原生的 MyISAM 引擎就不支持事務,也正是這樣,所以大多數 MySQL 的引擎都是用 InnoDB。

事務看起來感覺簡單,但是要實現事務必須要遵守 4 個特性,分別如下:

  • 原子性(Atomicity):一個事務中的所有操作,要么全部完成,要么全部不完成,不會結束在中間某個環節,而且事務在執行過程中發生錯誤,會被回滾到事務開始前的狀態,就像這個事務從來沒有執行過一樣;
  • 一致性(Consistency):數據庫的完整性不會因為事務的執行而受到破壞,比如表中有一個字段為姓名,它有唯一約束,也就是表中姓名不能重復,如果一個事務對姓名字段進行了修改,但是在事務提交后,表中的姓名變得非唯一性了,這就破壞了事務的一致性要求,這時數據庫就要撤銷該事務,返回初始化的狀態。
  • 隔離性(Isolation):數據庫允許多個并發事務同時對其數據進行讀寫和修改的能力,隔離性可以防止多個事務并發執行時由于交叉執行而導致數據的不一致。
  • 持久性(Durability):事務處理結束后,對數據的修改就是永久的,即便系統故障也不會丟失。

InnoDB 引擎通過什么技術來保證事務的這四個特性的呢?

  • 持久性是通過 redo log (重做日志)來保證的;
  • 原子性是通過 undo log(回滾日志) 來保證的;
  • 隔離性是通過 MVCC(多版本并發控制) 或鎖機制來保證的;
  • 一致性則是通過持久性+原子性+隔離性來保證;

這次將重點介紹事務的隔離性,這也是面試時最常問的知識的點。

為什么事務要有隔離性,我們就要知道并發事務時會引發什么問題。

并行事務會引發什么問題?

MySQL 服務端是允許多個客戶端連接的,這意味著 MySQL 會出現同時處理多個事務的情況。

那么在同時處理多個事務的時候,就可能出現臟讀(dirty read)、不可重復讀(non-repeatable read)、幻讀(phantom read)的問題。

接下來,通過舉例子給大家說明,這些問題是如何發生的。

臟讀

如果一個事務「讀到」了另一個「未提交事務修改過的數據」,就意味著發生了「臟讀」現象。

舉個栗子。

假設有 A 和 B 這兩個事務同時在處理,事務 A 先開始從數據庫中讀取小林的余額數據,然后再執行更新操作,如果此時事務 A 還沒有提交事務,而此時正好事務 B 也從數據庫中讀取小林的余額數據,那么事務 B 讀取到的余額數據是剛才事務 A 更新后的數據,即使沒有提交事務。

因為事務 A 是還沒提交事務的,也就是它隨時可能發生回滾操作,如果在上面這種情況事務 A 發生了回滾,那么事務 B 剛才得到的數據就是過期的數據,這種現象就被稱為臟讀。

不可重復讀

在一個事務內多次讀取同一個數據,如果出現前后兩次讀到的數據不一樣的情況,就意味著發生了「不可重復讀」現象。

舉個栗子。

假設有 A 和 B 這兩個事務同時在處理,事務 A 先開始從數據庫中讀取小林的余額數據,然后繼續執行代碼邏輯處理,在這過程中如果事務 B 更新了這條數據,并提交了事務,那么當事務 A 再次讀取該數據時,就會發現前后兩次讀到的數據是不一致的,這種現象就被稱為不可重復讀。

幻讀

在一個事務內多次查詢某個符合查詢條件的「記錄數量」,如果出現前后兩次查詢到的記錄數量不一樣的情況,就意味著發生了「幻讀」現象。

舉個栗子。

假設有 A 和 B 這兩個事務同時在處理,事務 A 先開始從數據庫查詢賬戶余額大于 100 萬的記錄,發現共有 5 條,然后事務 B 也按相同的搜索條件也是查詢出了 5 條記錄。

接下來,事務 A 插入了一條余額超過 100 萬的賬號,并提交了事務,此時數據庫超過 100 萬余額的賬號個數就變為 6。

然后事務 B 再次查詢賬戶余額大于 100 萬的記錄,此時查詢到的記錄數量有 6 條,發現和前一次讀到的記錄數量不一樣了,就感覺發生了幻覺一樣,這種現象就被稱為幻讀。

事務的隔離級別有哪些?

前面我們提到,當多個事務并發執行時可能會遇到「臟讀、不可重復讀、幻讀」的現象,這些現象會對事務的一致性產生不同程序的影響。

  • 臟讀:讀到其他事務未提交的數據;
  • 不可重復讀:前后讀取的數據不一致;
  • 幻讀:前后讀取的記錄數量不一致。

這三個現象的嚴重性排序如下:

SQL 標準提出了四種隔離級別來規避這些現象,隔離級別越高,性能效率就越低,這四個隔離級別如下:

  • 讀未提交(read uncommitted),指一個事務還沒提交時,它做的變更就能被其他事務看到;
  • 讀提交(read committed),指一個事務提交之后,它做的變更才能被其他事務看到;
  • 可重復讀(repeatable read),指一個事務執行過程中看到的數據,一直跟這個事務啟動時看到的數據是一致的,MySQL InnoDB 引擎的默認隔離級別;
  • 串行化(serializable );會對記錄加上讀寫鎖,在多個事務對這條記錄進行讀寫操作時,如果發生了讀寫沖突的時候,后訪問的事務必須等前一個事務執行完成,才能繼續執行;

按隔離水平高低排序如下:

針對不同的隔離級別,并發事務時可能發生的現象也會不同。

也就是說:

  • 在「讀未提交」隔離級別下,可能發生臟讀、不可重復讀和幻讀現象;
  • 在「讀提交」隔離級別下,可能發生不可重復讀和幻讀現象,但是不可能發生臟讀現象;
  • 在「可重復讀」隔離級別下,可能發生幻讀現象,但是不可能臟讀和不可重復讀現象;
  • 在「串行化」隔離級別下,臟讀、不可重復讀和幻讀現象都不可能會發生。

所以,要解決臟讀現象,就要升級到「讀提交」以上的隔離級別;要解決不可重復讀現象,就要升級到「可重復讀」的隔離級別。

不過,要解決幻讀現象不建議將隔離級別升級到「串行化」,因為這樣會導致數據庫在并發事務時性能很差。

InnoDB 引擎的默認隔離級別雖然是「可重復讀」,但是它通過next-key lock 鎖(行鎖和間隙鎖的組合)來鎖住記錄之間的“間隙”和記錄本身,防止其他事務在這個記錄之間插入新的記錄,這樣就避免了幻讀現象。

接下里,舉個具體的例子來說明這四種隔離級別,有一張賬戶余額表,里面有一條記錄:

然后有兩個并發的事務,事務 A 只負責查詢余額,事務 B 則會將我的余額改成 200 萬,下面是按照時間順序執行兩個事務的行為:

在不同隔離級別下,事務 A 執行過程中查詢到的余額可能會不同:

  • 在「讀未提交」隔離級別下,事務 B 修改余額后,雖然沒有提交事務,但是此時的余額已經可以被事務 A 看見了,于是事務 A 中余額 V1 查詢的值是 200 萬,余額 V2、V3 自然也是 200 萬了;
  • 在「讀提交」隔離級別下,事務 B 修改余額后,因為沒有提交事務,所以事務 A 中余額 V1 的值還是 100 萬,等事務 B 提交完后,最新的余額數據才能被事務 A 看見,因此額 V2、V3 都是 200 萬;
  • 在「可重復讀」隔離級別下,事務 A 只能看見啟動事務時的數據,所以余額 V1、余額 V2 的值都是 100 萬,當事務 A 提交事務后,就能看見最新的余額數據了,所以余額 V3 的值是 200 萬;
  • 在「串行化」隔離級別下,事務 B 在執行將余額 100 萬修改為 200 萬時,由于此前事務 A 執行了讀操作,這樣就發生了讀寫沖突,于是就會被鎖住,直到事務 A 提交后,事務 B 才可以繼續執行,所以從 A 的角度看,余額 V1、V2 的值是 100 萬,余額 V3 的值是 200萬。

這四種隔離級別具體是如何實現的呢?

  • 對于「讀未提交」隔離級別的事務來說,因為可以讀到未提交事務修改的數據,所以直接讀取最新的數據就好了;
  • 對于「串行化」隔離級別的事務來說,通過加讀寫鎖的方式來避免并行訪問;
  • 對于「讀提交」和「可重復讀」隔離級別的事務來說,它們是通過 Read View 來實現的,它們的區別在于創建 Read View 的時機不同,大家可以把 Read View 理解成一個數據快照,就像相機拍照那樣,定格某一時刻的風景。「讀提交」隔離級別是在「每個語句執行前」都會重新生成一個 Read View,而「可重復讀」隔離級別是「啟動事務時」生成一個 Read View,然后整個事務期間都在用這個 Read View。

注意,執行「開始事務」命令,并不意味著啟動了事務。在 MySQL 有兩種開啟事務的命令,分別是:

  • 第一種:begin/start transaction 命令;
  • 第二種:start transaction with consistent snapshot 命令;

這兩種開啟事務的命令,事務的啟動時機是不同的:

  • 執行了 begin/start transaction 命令后,并不代表事務啟動了。只有在執行這個命令后,執行了增刪查改操作的 SQL 語句,才是事務真正啟動的時機;
  • 執行了 start transaction with consistent snapshot 命令,就會馬上啟動事務。

接下來詳細說下,Read View 在 MVCC 里如何工作的?

Read View 在 MVCC 里如何工作的?

我們需要了解兩個知識:

  • Read View 中四個字段作用;
  • 聚簇索引記錄中兩個跟事務有關的隱藏列;

那 Read View 到底是個什么東西?

Read View 有四個重要的字段:

  • m_ids :指的是在創建 Read View 時,當前數據庫中「活躍事務」的事務 id 列表,注意是一個列表,“活躍事務”指的就是,啟動了但還沒提交的事務。
  • min_trx_id :指的是在創建 Read View 時,當前數據庫中「活躍事務」中事務 id 最小的事務,也就是 m_ids 的最小值。
  • max_trx_id :這個并不是 m_ids 的最大值,而是創建 Read View 時當前數據庫中應該給下一個事務的 id 值,也就是「活躍事務」中事務 id 最大值 + 1;
  • creator_trx_id :指的是創建該 Read View 的事務的事務 id。

知道了 Read View 的字段,我們還需要了解聚簇索引記錄中的兩個隱藏列。

假設在賬戶余額表插入一條小林余額為 100 萬的記錄,然后我把這兩個隱藏列也畫出來,該記錄的整個示意圖如下:

對于使用 InnoDB 存儲引擎的數據庫表,它的聚簇索引記錄中都包含下面兩個隱藏列:

  • trx_id,當一個事務對某條聚簇索引記錄進行改動時,就會把該事務的事務 id 記錄在 trx_id 隱藏列里;
  • roll_pointer,每次對某條聚簇索引記錄進行改動時,都會把舊版本的記錄寫入到 undo 日志中,然后這個隱藏列是個指針,指向每一個舊版本記錄,于是就可以通過它找到修改前的記錄。

在創建 Read View 后,我們可以將記錄中的 trx_id 劃分這三種情況:

一個事務去訪問記錄的時候,除了自己的更新記錄總是可見之外,還有這幾種情況:

  • 如果記錄的 trx_id 值小于 Read View 中的 min_trx_id 值,表示這個版本的記錄是在創建 Read View 前已經提交的事務生成的,所以該版本的記錄對當前事務可見。
  • 如果記錄的 trx_id 值大于等于 Read View 中的 max_trx_id 值,表示這個版本的記錄是在創建 Read View 后才啟動的事務生成的,所以該版本的記錄對當前事務不可見。
  • 如果記錄的 trx_id 值在 Read View 的 min_trx_id 和 max_trx_id 之間,需要判斷 trx_id 是否在 m_ids 列表中:

如果記錄的 trx_id 在 m_ids 列表中,表示生成該版本記錄的活躍事務依然活躍著(還沒提交事務),所以該版本的記錄對當前事務不可見。

如果記錄的 trx_id 不在 m_ids 列表中,表示生成該版本記錄的活躍事務已經被提交,所以該版本的記錄對當前事務可見。

這種通過「版本鏈」來控制并發事務訪問同一個記錄時的行為就叫 MVCC(多版本并發控制)。

可重復讀是如何工作的?

可重復讀隔離級別是啟動事務時生成一個 Read View,然后整個事務期間都在用這個 Read View。

假設事務 A (事務 id 為51)啟動后,緊接著事務 B (事務 id 為52)也啟動了,那這兩個事務創建的 Read View 如下:

事務 A 和 事務 B 的 Read View 具體內容如下:

  • 在事務 A 的 Read View 中,它的事務 id 是 51,由于它是第一個啟動的事務,所以此時活躍事務的事務 id 列表就只有 51,活躍事務的事務 id 列表中最小的事務 id 是事務 A 本身,下一個事務 id 則是 52。
  • 在事務 B 的 Read View 中,它的事務 id 是 52,由于事務 A 是活躍的,所以此時活躍事務的事務 id 列表是 51 和 52,活躍的事務 id 中最小的事務 id 是事務 A,下一個事務 id 應該是 53。

接著,在可重復讀隔離級別下,事務 A 和事務 B 按順序執行了以下操作:

  • 事務 B 讀取小林的賬戶余額記錄,讀到余額是 100 萬;
  • 事務 A 將小林的賬戶余額記錄修改成 200 萬,并沒有提交事務;
  • 事務 B 讀取小林的賬戶余額記錄,讀到余額還是 100 萬;
  • 事務 A 提交事務;
  • 事務 B 讀取小林的賬戶余額記錄,讀到余額依然還是 100 萬;

接下來,跟大家具體分析下。

事務 B 第一次讀小林的賬戶余額記錄,在找到記錄后,它會先看這條記錄的 trx_id,此時發現 trx_id 為 50,比事務 B 的 Read View 中的 min_trx_id 值(51)還小,這意味著修改這條記錄的事務早就在事務 B 啟動前提交過了,所以該版本的記錄對事務 B 可見的,也就是事務 B 可以獲取到這條記錄。

接著,事務 A 通過 update 語句將這條記錄修改了(還未提交事務),將小林的余額改成 200 萬,這時 MySQL 會記錄相應的 undo log,并以鏈表的方式串聯起來,形成版本鏈,如下圖:

你可以在上圖的「記錄的字段」看到,由于事務 A 修改了該記錄,以前的記錄就變成舊版本記錄了,于是最新記錄和舊版本記錄通過鏈表的方式串起來,而且最新記錄的 trx_id 是事務 A 的事務 id(trx_id = 51)。

然后事務 B 第二次去讀取該記錄,發現這條記錄的 trx_id 值為 51,在事務 B 的 Read View 的 min_trx_id 和 max_trx_id 之間,則需要判斷 trx_id 值是否在 m_ids 范圍內,判斷的結果是在的,那么說明這條記錄是被還未提交的事務修改的,這時事務 B 并不會讀取這個版本的記錄。而是沿著 undo log 鏈條往下找舊版本的記錄,直到找到 trx_id 「小于」事務 B 的 Read View 中的 min_trx_id 值的第一條記錄,所以事務 B 能讀取到的是 trx_id 為 50 的記錄,也就是小林余額是 100 萬的這條記錄。

最后,當事物 A 提交事務后,由于隔離級別時「可重復讀」,所以事務 B 再次讀區記錄時,還是基于啟動事務時創建的 Read View 來判斷當前版本的記錄是否可見。所以,即使事物 A 將小林余額修改為 200 萬并提交了事務, 事務 B 第三次讀取記錄時,讀到的記錄都是小林余額是 100 萬的這條記錄。

就是通過這樣的方式實現了,「可重復讀」隔離級別下在事務期間讀到的記錄都是事務啟動前的記錄。

讀提交是如何工作的?

讀提交隔離級別是在每次讀取數據時,都會生成一個新的 Read View。

也意味著,事務期間的多次讀取同一條數據,前后兩次讀的數據可能會出現不一致,因為可能這期間另外一個事務修改了該記錄,并提交了事務。

那讀提交隔離級別是怎么工作呢?我們還是以前面的例子來聊聊。

假設事務 A (事務 id 為51)啟動后,緊接著事務 B (事務 id 為52)也啟動了,接著按順序執行了以下操作:

  • 事務 B 讀取數據(創建 Read View),小林的賬戶余額為 100 萬;
  • 事務 A 修改數據(還沒提交事務),將小林的賬戶余額從 100 萬修改成了 200 萬;
  • 事務 B 讀取數據(創建 Read View),小林的賬戶余額為 100 萬;
  • 事務 A 提交事務;
  • 事務 B 讀取數據(創建 Read View),小林的賬戶余額為 200 萬;

那具體怎么做到的呢?我們重點看事務 B 每次讀取數據時創建的 Read View。前兩次 事務 B 讀取數據時創建的 Read View 如下圖:

我們來分析下為什么事務 B 第二次讀數據時,讀不到事務 A (還未提交事務)修改的數據?

事務 B 在找到小林這條記錄時,會看這條記錄的 trx_id 是 51,在事務 B 的 Read View 的 min_trx_id 和 max_trx_id 之間,接下來需要判斷 trx_id 值是否在 m_ids 范圍內,判斷的結果是在的,那么說明這條記錄是被還未提交的事務修改的,這時事務 B 并不會讀取這個版本的記錄。而是,沿著 undo log 鏈條往下找舊版本的記錄,直到找到 trx_id 「小于」事務 B 的 Read View 中的 min_trx_id 值的第一條記錄,所以事務 B 能讀取到的是 trx_id 為 50 的記錄,也就是小林余額是 100 萬的這條記錄。

我們來分析下為什么事務 A 提交后,事務 B 就可以讀到事務 A 修改的數據?

在事務 A 提交后,由于隔離級別是「讀提交」,所以事務 B 在每次讀數據的時候,會重新創建 Read View,此時事務 B 第三次讀取數據時創建的 Read View 如下:

[外鏈圖片轉存失敗,源站可能有防盜鏈機制,建議將圖片保存下來直接上傳(img-NhC5bZpC-1648719236189)(https://cdn.jsdelivr.net/gh/xiaolincoder/ImageHost4@main/mysql/事務隔離/讀提交事務2.drawio.png)]

事務 B 在找到小林這條記錄時,會發現這條記錄的 trx_id 是 51,比事務 B 的 Read View 中的 min_trx_id 值(52)還小,這意味著修改這條記錄的事務早就在創建 Read View 前提交過了,所以該版本的記錄對事務 B 是可見的。

正是因為在讀提交隔離級別下,事務每次讀數據時都重新創建 Read View,那么在事務期間的多次讀取同一條數據,前后兩次讀的數據可能會出現不一致,因為可能這期間另外一個事務修改了該記錄,并提交了事務。

總結

事務是在 MySQL 引擎層實現的,我們常見的 InnoDB 引擎是支持事務的,事務的四大特性是原子性、一致性、隔離性、持久性,我們這次主要講的是隔離性。

當多個事務并發執行的時候,會引發臟讀、不可重復讀、幻讀這些問題,那為了避免這些問題,SQL 提出了四種隔離級別,分別是讀未提交、讀已提交、可重復讀、串行化,從左往右隔離級別順序遞增,隔離級別越高,意味著性能越差,InnoDB 引擎的默認隔離級別是可重復讀。

要解決臟讀現象,就要將隔離級別升級到讀已提交以上的隔離級別,要解決不可重復讀現象,就要將隔離級別升級到可重復讀以上的隔離級別。

而對于幻讀現象,不建議將隔離級別升級為串行化,因為這會導致數據庫并發時性能很差。InnoDB 引擎的默認隔離級別雖然是「可重復讀」,但是它通過 next-key lock 鎖(行鎖+間隙鎖的組合)來鎖住記錄之間的“間隙”和記錄本身,防止其他事務在這個記錄之間插入新的記錄,這樣就避免了幻讀現象。

  • 對于「讀提交」和「可重復讀」隔離級別的事務來說,它們是通過 **Read View **來實現的,它們的區別在于創建 Read View 的時機不同:
  • 「讀提交」隔離級別是在每個 select 都會生成一個新的 Read View,也意味著,事務期間的多次讀取同一條數據,前后兩次讀的數據可能會出現不一致,因為可能這期間另外一個事務修改了該記錄,并提交了事務。

「可重復讀」隔離級別是啟動事務時生成一個 Read View,然后整個事務期間都在用這個 Read View,這樣就保證了在事務期間讀到的數據都是事務啟動前的記錄。

這兩個隔離級別實現是通過「事務的 Read View 里的字段」和「記錄中的兩個隱藏列」的比對,來控制并發事務訪問同一個記錄時的行為,這就叫 MVCC(多版本并發控制)。

在可重復讀隔離級別中,普通的 select 語句就是基于 MVCC 實現的快照讀,也就是不會加鎖的。而 select .. for update 語句就不是快照讀了,而是當前讀了,也就是每次讀都是拿到最新版本的數據,但是它會對讀到的記錄加上 next-key lock 鎖。

責任編輯:武曉燕 來源: 小林coding
相關推薦

2022-03-08 17:52:58

TCP格式IP

2021-08-27 07:06:10

IOJava抽象

2021-12-29 08:27:05

ByteBuffer磁盤服務器

2022-02-14 10:16:22

Axios接口HTTP

2022-06-26 09:40:55

Django框架服務

2022-02-14 07:03:31

網站安全MFA

2016-09-06 10:39:30

Dell Techno

2021-07-15 07:23:28

Singlefligh設計

2021-11-26 07:00:05

反轉整數數字

2023-08-14 08:38:26

反射reflect結構體

2012-04-14 20:47:45

Android

2021-12-16 12:01:21

區塊鏈Libra貨幣

2021-07-31 11:40:55

Openresty開源

2023-08-02 08:35:54

文件操作數據源

2022-07-10 23:15:46

Go語言內存

2022-08-01 07:57:03

數組操作內存

2021-02-23 09:21:29

代碼效率C++

2021-11-04 06:58:31

CSS性能設備

2021-03-18 00:04:13

C# 類型數據

2022-08-30 13:48:16

LinuxMySQL內存
點贊
收藏

51CTO技術棧公眾號

亚洲xxx大片| 精品人伦一区二区三区蜜桃网站| 国产主播精品在线| 亚洲无人区码一码二码三码| 美女av在线免费看| 中文一区一区三区高中清不卡| 91日本在线观看| 992在线观看| 成人高潮a毛片免费观看网站| 亚洲欧洲制服丝袜| 久久一区二区三区欧美亚洲| 国产精品无码久久久久成人app| 韩日欧美一区| 中文字幕亚洲欧美一区二区三区| 久久久国产欧美| 青草视频在线免费直播| 国产不卡在线播放| 欧美国产第二页| 精品久久久久久无码人妻| 亚洲mmav| 亚洲天堂久久久久久久| 亚洲淫片在线视频| 国产亚洲成人av| 国产成人av毛片| 亚洲第一在线综合网站| 精品欧美一区二区久久久伦| 国产又爽又黄又嫩又猛又粗| 亚洲一区二区毛片| 欧美黑人xxx| 亚洲女人毛茸茸高潮| 日韩欧美ww| 欧美影院一区二区三区| 免费看av软件| 人人妻人人澡人人爽久久av| 韩国午夜理伦三级不卡影院| 欧美国产日本在线| 性色av蜜臀av浪潮av老女人| 欧州一区二区三区| 欧美另类videos死尸| 88av.com| 中中文字幕av在线| 99视频一区二区| 99精品欧美一区二区三区| 国产一级精品视频| 一区免费视频| 亚洲天堂男人天堂| 成人性生活免费看| 精品在线网站观看| 欧美日韩在线亚洲一区蜜芽| www.日日操| 天然素人一区二区视频| 亚洲人成伊人成综合网小说| 亚洲一区二区三区四区中文| 亚洲精品一区二区三区蜜桃| 久久久久中文| 久热精品在线视频| 三级全黄做爰视频| 欧美午夜寂寞| 精品亚洲国产成av人片传媒| 极品白嫩丰满美女无套| 首页亚洲中字| 日韩一区二区精品在线观看| 国产精品秘入口18禁麻豆免会员 | 国产成人在线影院| 日韩av成人在线| 一二三区免费视频| 奇米影视一区二区三区| 国产精品啪视频| 久草手机在线观看| 久久综合中文| 国产美女精品视频免费观看| 国产一区二区三区四区视频| 国产高清久久久久| 国产一区在线免费| 精品免费久久久| 美国三级日本三级久久99| 国产主播喷水一区二区| 亚洲第一区av| 国产精品婷婷| 国产精品九九久久久久久久| 一二区在线观看| 久久久久久黄| 成人做爰www免费看视频网站| 国产精品一区二区av白丝下载| 国内精品久久久久影院薰衣草| 日韩免费av在线| 毛片视频网站在线观看| 一本一道久久综合狠狠老| 欧美疯狂性受xxxxx另类| 免费日韩一级片| 在线成人av| 九九热视频这里只有精品| 国产无码精品一区二区| 日韩av午夜在线观看| 欧美在线一级va免费观看| 精品无码m3u8在线观看| 亚洲免费综合| 青青青国产精品一区二区| 亚洲中文一区二区三区| 成人a区在线观看| 国产精品成人观看视频免费| 国产成人精品无码高潮| 99精品一区二区三区| 亚洲精品一区二区三区四区五区| 免费在线播放电影| 欧美在线啊v一区| 色片在线免费观看| 国产伦乱精品| 久久久精品欧美| 成人免费毛片xxx| 91精品电影| 2019精品视频| av 一区二区三区| 国产91精品一区二区麻豆网站| 成人免费看吃奶视频网站| 国产精品伊人久久| 国产精品中文欧美| 日本精品国语自产拍在线观看| 在线网址91| 欧美日韩一区二区三区在线| 亚洲精品乱码久久久久久久| 一道在线中文一区二区三区| 亚洲人免费视频| 欧美成人另类视频| 国产精品日韩久久久| 国产成人精品在线视频| 国产成人手机在线| 久久这里只有精品视频网| 欧美性大战久久久久| jizz在线免费观看| 亚洲男同1069视频| 手机视频在线观看| 国产成人影院| 欧美在线视频一区二区| 色综合久久久久久| 中文字幕二三区不卡| 少妇熟女一区二区| 日本免费成人| 亚洲精品videossex少妇| 日本一级免费视频| 日韩专区中文字幕一区二区| 久热国产精品视频一区二区三区| 川上优av中文字幕一区二区| 亚洲福利视频专区| 欧美一区二区三区粗大| 天堂一区二区在线| 秋霞毛片久久久久久久久| 中文字幕高清在线播放| 亚洲欧美日韩精品久久| 欧美成人777| 国产一区二区精品久久99| 久久久国产精华液999999| sqte在线播放| 欧美日韩一区高清| 99re久久精品国产| 国产一区二区精品| 欧美日韩精品久久久免费观看| 中文在线最新版地址| 日韩欧美在线影院| 久久精品一区二区免费播放| 91成人网在线观看| 国产成人短视频| 国产片在线观看| 亚洲大片免费看| 国产高清成人久久| 一区二区三区福利| 日本日本精品二区免费| 久久久男人天堂| 欧美一区二区免费视频| 美女100%露胸无遮挡| 蜜桃久久精品一区二区| 欧美二级三级| 四虎影视国产精品| 亚洲欧洲av一区二区| 久久综合色综合| 97久久超碰精品国产| 能看的毛片网站| 亚洲小说图片视频| 国模私拍视频一区| 久草视频视频在线播放| 精品久久久久久国产91| 亚洲av成人无码久久精品| 夜久久久久久| 亚洲欧美影院| 澳门精品久久国产| 欧美人与物videos| 精品乱码一区二区三四区视频| 欧美日韩一区二区三区高清| 欧美丰满美乳xxⅹ高潮www| 午夜在线一区二区| 麻豆av一区二区三区| 欧美成人黄色| 日韩一级黄色av| 深夜福利视频网站| 欧美日韩国产综合草草| 国产一级一片免费播放放a| 国产在线国偷精品产拍免费yy| 亚洲欧洲一二三| 欧美日韩免费电影| 97精品久久久中文字幕免费| 国产91免费看| 亚洲一区二区精品3399| 少妇伦子伦精品无吗| 日韩精品一二三| 国产资源第一页| 中文字幕区一区二区三| 国产精品福利网| av资源在线看片| 亚洲欧美日韩国产精品| 亚洲AV无码一区二区三区少妇 | 久久视频这里只有精品| 国产美女www爽爽爽视频| 欧美日韩另类在线| 真实乱视频国产免费观看| 国产不卡视频在线观看| 日韩福利视频在线| 在线亚洲精品| 4444亚洲人成无码网在线观看| 91在线一区| 欧美一级在线播放| 欧美videosex性欧美黑吊| 亚洲成人av片| 国产黄色片网站| 精品成人av一区| 青青操视频在线播放| 亚洲欧洲成人av每日更新| 欧美人妻一区二区三区| 久久久久久久久久电影| 免费无码一区二区三区| 日本特黄久久久高潮| 日本不卡一区二区三区四区| 国产一区二区三区电影在线观看| 国产中文字幕91| 国产极品久久久久久久久波多结野| 91国内免费在线视频| 2021中文字幕在线| 欧美精品18videosex性欧美| 久久久久国产精品嫩草影院| 亚洲韩国欧洲国产日产av | 亚洲成a人片777777久久| 九九热最新视频//这里只有精品| 久久久久久国产精品免费无遮挡| 色老头一区二区三区在线观看| 成人午夜电影在线观看| 亚洲性生活视频| 精品国产伦一区二区三区| 欧美卡1卡2卡| 国产视频在线免费观看| 色综合久久天天综合网| 26uuu成人网| 亚洲欧洲性图库| 人妻熟女aⅴ一区二区三区汇编| 99久久夜色精品国产网站| 中文字幕久久av| 激情综合网激情| 日日摸天天爽天天爽视频| 天堂在线亚洲视频| 日本黄色的视频| 石原莉奈在线亚洲二区| 欧美伦理片在线看| 六月丁香综合在线视频| 中文字幕在线视频一区二区三区 | 欧美性生活久久| 国产稀缺真实呦乱在线| 亚洲三级电影网站| 久久久国产精华液| 最新不卡av在线| 久操免费在线视频| 日韩欧美一区二区三区| 国产99久久久久久免费看| 7777精品伊人久久久大香线蕉经典版下载 | 亚洲精品福利视频| 国产裸舞福利在线视频合集| 精品国产三级电影在线观看| 天堂av2024| 在线观看日韩www视频免费| 色猫av在线| 日韩一区二区三区在线播放| 久久青青色综合| 国产精品美女在线观看| 最新日韩一区| 国产精品久久av| 日韩不卡视频在线观看| 青青在线视频一区二区三区| 日本亚洲欧洲无免费码在线| 97在线中文字幕| 国产日韩中文在线中文字幕| 国产色视频一区| 精品亚洲自拍| 美国av一区二区三区| 97精品视频| 日韩国产欧美亚洲| 一本色道久久综合亚洲精品不卡 | bt欧美亚洲午夜电影天堂| 国产熟女一区二区| 久久精品视频一区二区| 欧美激情一区二区视频| 色婷婷av一区二区三区大白胸 | 国产成人丝袜美腿| 性折磨bdsm欧美激情另类| 国产成人免费视频网站| 欧美激情 一区| 天天av天天翘天天综合网| 亚洲永久精品在线观看| 一本色道久久综合狠狠躁的推荐| 国产精品无码一区二区桃花视频| 欧美一区二区国产| 国产丰满果冻videossex| 亚洲天堂成人在线| 尤物在线视频| 日本午夜精品理论片a级appf发布| 欧美在线在线| 精品一区在线播放| 在线电影一区二区| 一区二区三区 欧美| 国产真实乱子伦精品视频| 成人午夜福利一区二区| 午夜精品一区二区三区电影天堂| 天天操夜夜操视频| 欧美天堂亚洲电影院在线播放| 亚洲国产精彩视频| 亚洲精品日韩丝袜精品| 黄色成人在线网| 亚洲永久在线观看| 天天躁日日躁狠狠躁欧美巨大小说| 欧美亚洲爱爱另类综合| av成人激情| 亚洲啪av永久无码精品放毛片| 一区二区三区在线视频免费观看| 一二三区中文字幕| 日韩在线播放视频| 国产精选在线| 成人精品视频99在线观看免费| 欧美日韩中字| 国产午夜精品视频一区二区三区| 狠狠色狠狠色合久久伊人| 国产免费嫩草影院| 欧美午夜精品理论片a级按摩| 国产小视频免费在线网址| 国产a级全部精品| 秋霞一区二区| 欧美久久久久久一卡四| 亚洲欧美色图| 手机精品视频在线| 久久午夜色播影院免费高清| 国产午夜性春猛交ⅹxxx| 日韩高清av一区二区三区| 黄色成年人视频在线观看| 欧美在线免费观看| 一本色道久久综合狠狠躁的番外| 成人羞羞国产免费网站| 久久免费偷拍视频| 日本免费一二三区| 欧美日韩和欧美的一区二区| 色影院视频在线| 91欧美精品成人综合在线观看| 中文字幕精品影院| 欧美成人黑人猛交| aaa国产一区| 国内自拍视频在线播放| 国产亚洲精品91在线| 成人看片毛片免费播放器| 狠狠干一区二区| 久久久久久影院| 亚洲视频天天射| 色综合网站在线| 天堂中文网在线| 欧美成人一二三| 综合在线影院| 亚洲一区尤物| 国产成人av电影在线播放| 国产乱码久久久久久| 亚洲欧美国产高清va在线播| 欧美videos粗暴| 黄色一级片在线看| 欧美激情综合五月色丁香小说| 久久一区二区三区视频| 在线亚洲国产精品网| 中文字幕亚洲在线观看| 日本a级片免费观看| 国产精品传媒入口麻豆| 午夜视频网站在线观看| 精品视频www| 亚洲女色av| 麻豆久久久9性大片| 精品一二线国产| 狠狠躁夜夜躁人人爽天天高潮| 在线观看国产精品日韩av| 97久久综合区小说区图片区| 少妇性饥渴无码a区免费| 波波电影院一区二区三区| 香蕉污视频在线观看| 亚洲欧美日韩一区在线| 99久久99九九99九九九| 国产高清精品软男同| www.亚洲免费av| 一级aaaa毛片| 日本国产高清不卡| 久久99国产精品视频| 成人免费视频久久|