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

聊聊 MySQL 事務二階段提交

數據庫 MySQL
二階段提交的核心邏輯是把多個事務的 Redo 日志合并刷盤,把多個事務的 binlog 日志合并刷盤,從而把少量數據多次 IO 變為更大數據更少 IO,最終達到提升事務提交效率的目標。

回想當年,高并發還沒有這么普遍,分布式也沒有這么流行。

初次接觸二階段提交,源于想以事務的方式實現對 MongoDB 中多個集合數據的修改,而 MongoDB 本身不支持事務,官方推薦的方案就是使用二階段提交。

MySQL 和事務早已成為工作中不可或缺的一部分,隨著分布式的流行,二階段提交出現在視野中的次數也越來越多。

然而,MySQL、事務、二階段提交這 3 個名詞組合在一起成為一個整體,從第一次接觸到現在也不過一年時間。

第一次接觸到 MySQL 事務二階段提交這個概念時,心里還有點小激動。

因為當年研究 MongoDB 二階段提交,其實是沒有弄明白的。

沒想到,多年以后,在 MySQL 中發現了二階段提交的身影,心頭似乎涌現出了那種感覺:眾里尋 TA 千百度,驀然回首,那人卻在燈火闌珊處。

本文我們就一起來看看 MySQL 事務是怎么實現二階段提交的。

本文內容基于 MySQL 8.0.29 源碼。

正文

1、什么是二階段提交?

二階段提交是一種用于保證分布式事務原子性的協議。

二階段提交的實現過程,有 2 個角色參與其中:

資源管理器,Resource Manager,負責管理一部分資源。對于數據庫來說,這里的資源指的就是數據。

如果把分布式事務看成是一個整體,每個資源管理器會負責其中的一部分,也就是分布式事務的一個本地事務。

資源管理器在分布式事務中的角色就是干活的,所以,我們可以稱它為執行器。

事務管理器,Transaction Manager,負責管理分布式事務,協調事務的提交、回滾、以及崩潰恢復。

事務管理器在分布式事務中,就是那個總攬全局、指揮資源管理器干活的角色,所以,我們可以稱它為協調器。

二階段提交,顧名思義,會包含 2 個階段:

prepare 階段,協調器會詢問所有執行器,是否可以提交事務。

此時,各個本地事務實際上已經執行完成,數據寫入已經成功,就差提交這最后一哆嗦了。

如果有任何一個執行器因為它所執行的本地事務有問題不能提交,分布式事務就不能提交,協調器會通知所有執行器進行回滾操作。

如果每一個執行器都回復協調器可以提交,分布式事務就會進入下一個階段,也就是 commit 階段。

commit 階段,協調器會通知執行器進行提交操作。

執行器收到提交通知之后,各自提交自己的本地事務。

所有執行器都提交完成之后,二階段提交就結束了,分布式事務也就執行完成了。

以上只介紹了二階段提交的正常流程,實際上二階段提交的復雜之處在于異常流程處理,對二階段提交完整流程感興趣的小伙伴,可以自行查找相關資料。

圖片

2、MySQL 二階段提交場景

在 MySQL 中,二階段提交有 4 種使用場景:

圖片

場景 1,外部 XA 事務,數據庫中間件、應用程序作為協調器,MySQL 數據庫實例作為執行器。

XA 事務也就是分布式事務。其它支持分布式事務的數據庫實例,如 Oracle、SQL Server,也可以和 MySQL 一起作為執行器。

這種場景下,MySQL 通過以下 XA 系列命令來實現二階段提交:

  • XA START xid,開啟分布式事務。
  • XA END xid,標識分布式事務中的 SQL 都已經執行完成。
  • XA PREPARE xid,執行分布式事務提交的 prepare 階段。
  • XA COMMIT xid,執行分布式事務提交的 commit 階段。
  • XA ROLLBACK xid,回滾分布式事務。

以上命令具體怎么使用,可以參照官方文檔的 XA Transactions 小節,鏈接:https://dev.mysql.com/doc/refman/8.0/en/xa.html

場景 2,單個 MySQL 實例的內部 XA 事務,沒有開啟 binlog 日志,SQL 語句涉及多個支持事務的存儲引擎。

TC_LOG_MMAP 類對象作為協調器,多個支持事務的存儲引擎作為執行器。

TC_LOG_MMAP 會打開一個名為 tc.log 的磁盤文件,并通過 MMAP 映射到內存中,用于記錄分布式事務的 xid。

場景 3,單個 MySQL 實例的內部 XA 事務,沒有開啟 binlog 日志,SQL 語句只涉及 1 個支持事務的存儲引擎。

這種場景下,原本是不需要二階段提交的,但是為了統一,還是會以二階段提交的結構進行提交操作。

TC_LOG_DUMMY 類對象作為協調器,不記錄 xid,存儲引擎作為執行器。

從 DUMMY 可以看出,TC_LOG_DUMMY 是個偽裝的協調器。

場景 4,單個 MySQL 實例的內部 XA 事務,開啟了 binlog 日志,SQL 語句涉及 1 個或多個支持事務的存儲引擎。

MYSQL_BIN_LOG 類對象作為協調器,分布式事務的 xid 記錄在 binlog 日志文件中。binlog 日志和存儲引擎作為執行器。

binlog 日志和存儲引擎都是獨立單元,為了保證多個存儲引擎之間、存儲引擎和 binlog 日志之間的數據一致性,在事務提交時,這些操作要么都提交,要么都回滾,需要借助 XA 事務實現。

InnoDB 是 MySQL 最常用的存儲引擎,為了支持主從架構,binlog 日志也是必須要開啟的,這是 MySQL 最常使用的場景。

接下來我們就以 InnoDB 存儲引擎 + binlog 日志為例,來介紹 MySQL 內部 XA 事務的二階段提交過程

3、prepare 階段

來到 prepare 階段之前,InnoDB 對表中數據的寫操作都已經完成,就差提交或者回滾這最后一哆嗦了。

prepare 階段,binlog 日志和 InnoDB 主要干的事情有這些:

圖片

prepare 階段,binlog 日志沒有什么需要做的,InnoDB 主要做的事情就是修改事務和 undo 段的狀態,以及記錄 xid(分布式事務的 ID)。

InnoDB 會把內存中事務對象的狀態修改為 TRX_STATE_PREPARED,把事務對應 undo 段在內存中的對象狀態修改為 TRX_UNDO_PREPARED。

修改完內存中各對象的狀態,還不算完事,還要把事務對應 undo 段的段頭頁中 Undo Segment Header 的 TRX_UNDO_STATE 字段值修改為 TRX_UNDO_PREPARED。

然后,把 xid 信息寫入當前事務對應日志組的 Undo Log Header 中的 xid 區域。

修改 TRX_UNDO_STATE 字段值、寫 xid,這兩個操作都要修改 undo 頁,修改 undo 頁之前會先記錄 Redo 日志。

4、commit 階段

(1)commit 階段整體介紹

到了 commit 階段,一個事務就已經接近尾聲了。

寫操作(包括增、刪、改)已經完成,內存中的事務狀態已經修改,undo 段的狀態也已經修改,xid 信息也已經寫入 Undo Log Header,prepare 階段產生的 Redo 日志已經寫入到 Redo 日志文件。

由于 log_flusher 線程會每秒進行刷盤操作,此時,事務產生的 Redo 日志有可能已經刷新到磁盤了,也有可能還停留在 Redo 日志文件的操作系統緩沖區中。

剩余的收尾工作,包括:

  • Redo 日志刷盤。
  • 事務的 binlog 日志從臨時存放點拷貝到 binlog 日志文件。
  • binlog 日志文件刷盤。
  • InnoDB 事務提交。

為了保證主從數據一致性,同一個事務中,上面列出的收尾工作必須串行執行。

Redo & binlog 日志刷盤都涉及到磁盤 IO,如果每提交一個事務,都把該事務中的 Redo 日志、binlog 日志刷盤,會涉及到很多小數據量的 IO 操作,頻繁的小數量 IO 操作非常消耗磁盤的讀寫性能。

為了提升磁盤 IO 效率,從而提高事務的提交效率,MySQL 從 5.6 開始引入了 binlog 日志組提交功能,5.7 中把原本在 prepare 階段進行的 Redo 日志刷盤操作遷移到了 commit 階段。

binlog 日志組提交有何神奇之處,怎么就能提升磁盤 IO 效率呢?

引入 binlog 日志組提交功能之后,commit 階段細分為 3 個子階段。

對于每個子階段,都可以有多個事務處于該子階段,寫日志 & 刷盤操作可以合并:

flush 子階段,Redo 日志可以一起刷盤,binlog 日志不需要加鎖就可以一起寫入 binlog 日志文件。

sync 子階段,binlog 日志可以一起刷盤。

commit 子階段,Redo 日志可以一起刷盤。

通過合并 Redo 日志刷盤操作、合并 binlog 日志寫入日志文件操作、合并 binlog 日志刷盤操作,把小數據量多次 IO 變為大數據量更少次數 IO,可以提升磁盤 IO 效率。

類比一下生活中的場景:這就相當于每個人從自己開車上下班,都改為坐公交或地鐵上下班,路上的車減少了,通行效率大大提升,就不堵車了。

既然要合并 Redo、binlog 日志的寫入、刷盤操作,那必須有一個管事的來負責協調這些操作。

如果引入一個單獨的協調線程,會增加額外開銷。

MySQL 的解決方案是把處于同一個子階段的事務線程分為 2 種角色:

  • leader 線程,第 1 個進入某個子階段的事務線程,就是該子階段當前分組的 leader 線程。
  • follower 線程,第 2 個及以后進入某個子階段的事務線程,都是該子階段當前分組的 follower 線程。

事務線程指的是事務所在的那個線程,我們可以把事務線程看成事務的容器,一個線程執行一個事務。

leader 線程管事的方式,并不是指揮 follower 線程干活,而是自己幫 follower 線程把活都干了。

commit 細分為 3 個子階段之后,每個子階段會有一個隊列用于記錄哪些事務線程處于該子階段。

為了保證先進入 flush 子階段的事務線程一定先進入 sync 子階段,先進入 sync 子階段的事務線程一定先進入  commit 子階段,每個子階段都會持有一把互斥鎖。

接下來,我們一起來看看這 3 個子階段具體都干了什么事情。

(2)flush 子階段

flush 子階段,第 1 個進入 flush 隊列的事務線程,會成為 leader 線程。第 2 個及以后進入 flush 隊列的事務線程,會成為 follower 線程。

follower 線程會進入等待狀態,直到收到 leader 線程從 commit 子階段發來的通知,才會醒來繼續執行后續操作。

leader 線程會獲取一把互斥鎖,保證同一時間 flush 子階段只有一個 leader 線程。

互斥鎖保存到 MYSQL_BIN_LOG 類的 Lock_log 屬性中,我們就叫它 Lock_log 互斥鎖好了。

flush 子階段 leader 線程的主要工作流程如下:

圖片圖片

第 1 步,清空 flush 隊列。

清空之前,會先鎖住 flush 隊列,在這之前進入 flush 隊列的所有事務線程就成為了一組。

鎖住之后,會清空 flush 隊列。

清空之后,進入 flush 隊列的事務線程就屬于下一組了,在這之后第 1 個進入 flush 隊列的事務線程會成為下一組的 leader 線程。

有一點需要注意,當前組的 leader 線程持有的 Lock_log 鎖要等到 sync 階段才會釋放。

如果下一組的 leader 線程在當前組的 leader 線程釋放 Lock_log 鎖之前就進入 flush 隊列了,下一組的 leader 線程會阻塞,直到當前組的 leader 線程釋放 Lock_log 鎖。

第 2 步,執行 Redo 日志刷盤操作,把 InnoDB 產生的 Redo 日志都刷新到磁盤。

第 3 步,遍歷 leader 線程帶領的一組 follower 線程,把 follower 線程中事務產生的 binlog 日志都寫入到 binlog 日志文件。

每個事務在執行過程中產生的 binlog 日志都會先寫入事務線程中專門用于存放該事務 binlog 日志的磁盤臨時文件,這是事務線程中 binlog 日志的臨時存放點。

binlog 日志磁盤臨時文件有一個 IO_CACHE(內存緩沖區),默認大小為 32K。

binlog 日志會先寫入 IO_CACHE,寫滿之后再把 IO_CACHE 中的日志寫入磁盤臨時文件,然后清空 IO_CACHE,供后續的 binlog 日志寫入。

等到二階段提交的 flush 子階段,才會按照事務提交的順序,把每個事務產生的 binlog 日志從臨時存放點拷貝到 binlog 日志文件中。

binlog 日志文件也有一個 IO_CACHE,大小為 8K。

binlog 日志從臨時存放點拷貝到 binlog 日志文件,也是先寫入 IO_CACHE,寫滿之后再把 IO_CACHE 中的日志寫入 binlog 日志文件,然后清空 IO_CACHE,供后續 binlog 日志復用。

在第 1 步中,已經早早的把 flush 隊列給清空了,還怎么遍歷 leader 線程帶領的一組 follower 線程呢?

別急,leader 線程既然作為管事的,它自然得知道它這一組中都有哪些 follower 線程。

每個線程對象(thd)中,都會有個 next_to_commit 屬性,指向緊隨其后加入到 flush 隊列的線程。

只要知道 leader 線程,根據每個線程的 next_to_commit 屬性,就可以順藤摸瓜找到 leader 線程帶領的一組 follower 線程。

第 4 步,把 binlog 日志文件 IO_CACHE 中最后剩下的日志拷貝到 binlog 日志文件。

binlog 日志從臨時存放點拷貝到 binlog 日志文件的過程中,得先寫入 IO_CACHE,寫滿之后,才會把 IO_CACHE 中的日志拷貝到 binlog 日志文件。

第 3 步執行完成之后,binlog 日志文件的 IO_CACHE 可能沒有寫滿,其中的日志也就不會被拷貝到 binlog 日志文件。

所以,第 4 步的存在就是為了把 binlog 日志文件 IO_CACHE 中最后剩下的不足 8K 的日志拷貝到 binlog 日志文件。

flush 子階段把 binlog 日志從臨時存放點拷貝到 binlog 日志文件,并沒有刷新到磁盤,只是寫入到 binlog 日志文件的操作系統緩沖區。

(3)sync 子階段

sync 子階段也有一個隊列,是 sync 隊列。

第 1 個進入 sync 隊列的事務線程是 sync 子階段的 leader 線程。

第 2 個及以后進入  sync 隊列的事務線程是 sync 子階段的 follower 線程。

flush 子階段完成之后,它的 leader 線程會進入 sync 子階段。

flush 子階段的 leader 線程來到 sync 子階段之后,它會先加入 sync 隊列,然后它的 follower 線程也會逐個加入 sync 隊列。

flush 子階段的 leader 線程和它的 follower 線程都加入到 sync 隊列之后,leader 線程會釋放它持有的  Lock_log 互斥鎖。

如果 flush 子階段的 leader 線程加入 sync 隊列之前,sync 隊列是空的,那么它又會成為 sync 子階段的 leader 線程,否則,它和它的所有 follower 線程都會成為 sync 子階段的 follower 線程。

在 sync 子階段,依然是由 leader 線程完成各項工作。

follower 線程依然處于等待狀態,直到收到 leader 線程從 commit 子階段發來的通知,才會退出等待狀態,執行后續操作。

leader 線程開展工作之前,會先獲取 Lock_sync 互斥鎖,保證同一時間 sync 子階段只有一個 leader 線程。

sync 子階段 leader 線程的主要工作流程如下:

圖片圖片

第 1 步,等待更多事務線程進入 sync 子階段。

只有符合一定條件時,leader 線程才會進入等待過程。

介紹要符合什么條件之前,我們先來看看 leader 線程為什么要有這個等待過程?

前面介紹過,binlog 日志組提交就是為了把多個事務線程攢到一起,然后再把這些事務產生的 Redo 日志、binlog 日志一起刷盤,從而提升磁盤的 IO 效率。

leader 線程的等待過程,依然是為了把更多事務線程攢到一起,從而積攢更多 binlog 日志一起刷盤。

如果沒有這個等待過程,第 1 個事務線程進入 sync 隊列成為 leader 線程之后,它可不管有沒有其它事務線程加入 sync 隊列,就會馬不停蹄的執行后面的流程。

數據庫繁忙的時候,leader 線程開始執行后續流程之前,可能就有很多其它事務線程加入 sync 隊列成為它的 follower 線程。

這種情況下,leader 線程有很多 follower 線程,它把這些 follower 線程的 binlog 日志一起刷盤,能夠提升磁盤 IO 效率。

數據庫不那么忙的時候,leader 線程開始執行后續流程之前,可能沒有或者只有很少的事務線程加入 sync 隊列成為它的 follower 線程。

這種情況下,leader 線程還是只能把少量的 binlog 日志一起刷盤,binlog 日志組提交功能提升磁盤 IO 效率就不那么明顯了。

為了在數據庫不那么忙的時候,也能盡量提升 binlog 日志組提交的效率,引入了 leader 線程的有條件等待過程,這個條件由系統變量 sync_binlog 控制。

sync_binlog 表示 binlog 日志刷盤頻率。

sync_binlog = 0,MySQL 不會主動發起 binlog 日志刷盤操作。

只需要把 binlog 日志寫入 binlog 日志文件的操作系統緩沖區,由操作系統決定什么時候執行刷盤操作。

sync_binlog = 1,sync 子階段每一組的 leader 線程都會觸發刷盤操作。

這意味著每個事務只要提交成功了,binlog 日志也一定刷新到磁盤了。

sync_binlog = 1 就是著名的雙 1 設置的其中一個 1。

sync_binlog = N,sync 子階段每 N 組才會觸發一次刷盤操作。

也就是說,執行一次刷盤操作之后,接下來第 1 ~ N-1 組的 leader 線程都不會執行 binlog 日志刷盤操作。

等到第 N 組時,它的 leader 線程才會把第 1 ~ N 組的所有事務線程產生的 binlog 日志一起刷盤。

源碼中有一個變量 sync_counter 用于記錄 sync 子階段自上次刷盤操作以后,有多少組的 leader 線程沒有進行刷盤操作。

每當有一個 leader 線程沒有執行刷盤操作,sync_counter 變量的值就會加 1。

只要有一個 leader 線程執行了刷盤操作,sync_counter 變量的值就會清零,重新開始計數。

重點來了,如果某一組的 leader 線程判斷 sync_counter + 1 >= sync_binlog 條件成立,那么該 leader 線程就要執行刷盤操作,刷盤之前會觸發等待更多事務線程進入 sync 子階段中的等待過程。

換句大白話來說:sync 子階段 leader 線程把 binlog 日志刷盤之前會進入等待過程,目的是為了攢到更多的 follower 線程,能夠把更多的 binlog 日志一起刷盤。

我們現在知道了 leader 線程為什么要等待,以及什么情況下需要等待,那要等待多長時間呢?

等待過程持續多長時間由 2 個系統變量控制。

binlog_group_commit_sync_delay,單位為微秒,表示 sync 子階段的 leader 線程在執行 binlog 日志文件刷盤操作之前,需要等待的多少微秒,默認值為 0。

如果它的值為 0,表示跳過等待過程。

如果它的值大于 0,leader 線程會等待 binlog_group_commit_sync_delay 毫秒。

但是,在等待過程中,leader 線程會每隔一段時間就去看看 sync 隊列里的事務線程數量是不是大于等于系統變量 binlog_group_commit_sync_no_delay_count 的值。

只要 binlog_group_commit_sync_no_delay_count sync 的值大于 0,并且隊列里的事務線程數量大于等于 該系統變量的值,立馬停止等待,開始執行第 2 步及之后的操作

檢查 sync 隊列里事務線程數量的時間間隔是:binlog_group_commit_sync_delay 除以 10 得到的結果,單位是 微秒,如果得到的結果是大于 1 微秒,時間間隔就是 1 微秒。

第 2 步,清空 sync 隊列。

清空之前,會先鎖住 sync 隊列,在這之前進入 sync 隊列的所有事務線程就成為了一組。

鎖住之后,會清空 sync 隊列。

清空之后,進入 sync 隊列的事務線程就屬于下一組了,在這之后第 1 個進入 sync 隊列的事務會成為下一組的 leader 線程。

第 3 步,binlog 日志文件刷盤。

刷盤操作完成后,這一組事務線程的 binlog 日志都刷新到磁盤,實現了持久化,它們再也不用擔心數據庫崩潰了。

在這一步是否會執行刷盤操作,也是由系統變量 sync_binlog 控制的,在第 1 步中已經詳細介紹過,這里就不重復了介紹了。

(4)commit 子階段

commit 子階段也有一個隊列,是 commit 隊列。

第 1 個進入 commit 隊列的事務線程是 commit 子階段的 leader 線程。

第 2 個及以后進入 commit 隊列的事務線程是 commit 子階段的 follower 線程。

sync 子階段完成之后,它的 leader 線程會進入到 commit 子階段,并加入 commit 隊列,然后再讓它的 follower 線程也逐個加入 commit 隊列。

sync 子階段的 leader 線程和 follower 線程都加入到 commit 隊列之后,leader 線程會釋放它持有的 Lock_sync 互斥鎖。

如果 sync 子階段的 leader 線程加入 commit 隊列之前,commit 隊列是空的,那么它又會成為 commit 子階段的 leader 線程。

否則,它和它的 follower 線程都會成為 commit 子階段的 follower 線程。

commit 子階段,leader 線程最重要的工作就是提交事務,然后給所有處于 commit 子階段的 follower 線程發通知。

leader 線程提交事務,是只提交自己的事務,還是會把所有 follower 線程的事務也一起提交了,由系統變量 binlog_order_commits 變量控制。

binlog_order_commits 的默認值為 ON,表示 leader 線程除了會提交自己的事務,還會提交所有 follower 線程的事務。

如果 binlog_order_commits 的值為 OFF,表示 leader 線程只會提交自己的事務。

leader 線程提交事務之后,會通知所有 follower 線程。

follower 線程收到通知之后,會退出等待狀態,繼續進行接下來的工作,也就是收尾工作。

每個事務線程中都有一個 commit_low 屬性,如果 leader 線程已經把 follower 線程的事務也一起提交了,會把 follower 線程的該屬性值設置為 false,follower 線程在執行收尾工作的時候,就不需要再提交自己的事務了。

如果 leader 線程只提交了自己的事務,而沒有提交 follower 線程的事務,commit_low 屬性的值為 true,follower 線程在執行收尾工作的時候,需要各自提交自己的事務。

5、總結

二階段提交的核心邏輯是把多個事務的 Redo 日志合并刷盤,把多個事務的 binlog 日志合并刷盤,從而把少量數據多次 IO 變為更大數據更少 IO,最終達到提升事務提交效率的目標。

最后,以一張二階段提交的整體流程圖作為本文的結尾:

圖片

本文轉載自微信公眾號「一樹一溪」,可以通過以下二維碼關注。轉載本文請聯系一樹一溪公眾號。

責任編輯:姜華 來源: 一樹一溪
相關推薦

2023-07-26 09:24:03

分布式事務分布式系統

2022-07-06 08:02:51

undo 日志數據庫

2024-05-21 14:12:07

2015-05-27 13:20:45

OpenStack私有云開源云項目

2024-01-18 17:42:11

華為鴻蒙

2023-05-12 08:02:43

分布式事務應用

2016-12-29 13:24:19

5G測試話語權

2023-12-05 09:33:08

分布式事務

2016-11-22 09:50:22

5G技術5G發展

2021-12-15 10:00:21

分布式事務框架

2012-12-25 10:48:47

網御星云IPv6

2010-10-16 12:18:07

CDMA終端華為

2024-01-18 19:56:22

鴻蒙

2024-10-29 08:34:27

RocketMQ消息類型事務消息

2023-11-06 13:15:32

分布式事務Seata

2022-03-28 10:44:51

MySQL日志存儲

2022-12-21 19:04:35

InnoDBMySQL

2025-06-19 08:03:03

2022-01-22 08:57:04

IPv6中國聯通網絡

2025-04-28 09:27:26

點贊
收藏

51CTO技術棧公眾號

久久久夜精品| 久久最新网址| 激情懂色av一区av二区av| 精品不卡一区二区三区| 日本视频免费观看| 欧美国产小视频| 精品国精品国产| 粉嫩虎白女毛片人体| 黄色av电影在线观看| 成人sese在线| 国产精品视频精品视频| 久久久久亚洲av片无码下载蜜桃| 国产成人调教视频在线观看 | 每日在线更新av| 色多多视频在线观看| 成人aaaa免费全部观看| 国产美女直播视频一区| 日韩成年人视频| 午夜欧美在线| 国产一区二区成人| 美女黄色一级视频| 日韩国产一二三区| 色综合久久88色综合天天免费| 久久av喷吹av高潮av| 美丽的姑娘在线观看免费动漫| 国产精品456| 国产精品美女www| 日韩色图在线观看| 精品电影一区| 欧美成人午夜免费视在线看片| 精品人妻无码一区| 欧美调教网站| 精品国产123| 中文字幕人妻无码系列第三区| 巨胸喷奶水www久久久| 欧美日韩一区二区三区 | 中日韩高清电影网| 国产精品视频一二三区| 久久久久一区二区三区| 肥臀熟女一区二区三区| 韩国成人精品a∨在线观看| 日本亚洲欧洲色α| 欧美另类一区二区| 在线日韩视频| 久久人91精品久久久久久不卡| 国产精品99久久久久久成人| 大胆日韩av| 日韩www在线| 亚洲一区二区在线免费| 北条麻妃一区二区三区在线观看| 欧美一区二区国产| 国产又粗又猛又爽又黄| 国产精品毛片aⅴ一区二区三区| 欧美视频在线观看一区| 爱情岛论坛成人| 亚洲四虎影院| 欧美日韩黄视频| 黄大色黄女片18第一次| 91国内外精品自在线播放| 欧美性大战久久久久久久蜜臀| 日韩av一二三四| 经典三级一区二区| 欧美网站大全在线观看| 午夜免费看毛片| 亚洲精品69| 日韩午夜在线观看视频| 国产精品99久久久精品无码| 伊人久久影院| 日韩精品高清视频| 高潮毛片无遮挡| 日韩av大片| 久久国产精品久久久久久久久久| 印度午夜性春猛xxx交| 欧美日本亚洲韩国国产| 午夜精品福利视频| 日本久久综合网| 美女视频网站久久| 91亚洲va在线va天堂va国| 国产成人三级在线播放| 成人免费视频app| 欧美美乳视频网站在线观看| av在线免费观看网| 亚洲精品中文字幕在线观看| 国产精品国产对白熟妇| 欧美色网一区| 欧美久久久久久久久中文字幕| 韩国三级hd中文字幕有哪些| 高清日韩中文字幕| 亚洲片国产一区一级在线观看| 欧美激情 一区| 久久精品亚洲人成影院 | 法国空姐在线观看免费| 成人黄色动漫| 欧美四级电影网| 亚洲美女精品视频| 国产在线观看91一区二区三区| www.日韩av.com| 日韩欧美中文字幕一区二区| 奇米一区二区三区av| 成人影片在线播放| av国产在线观看| 亚洲成国产人片在线观看| 日韩一级片播放| 91成人噜噜噜在线播放| 亚洲天堂成人在线视频| 久久久国产精华液| 秋霞影院一区二区| 国产伦精品一区二区三区高清版 | 麻豆一区二区在线观看| 亚洲男人的天堂在线视频| 激情综合色综合久久综合| 国产综合精品一区二区三区| 麻豆影视在线观看_| 精品美女永久免费视频| 午夜精品久久久久久久99热影院| 女同另类激情重口| 免费av在线一区| 中文字幕欧美在线观看| 91美女视频网站| 成人免费a级片| 欧美综合社区国产| 亚洲人成网站777色婷婷| 国产第一页在线播放| 激情综合网av| 亚洲一区美女| 日韩电影大全网站| 亚洲精品国产精品自产a区红杏吧 亚洲精品国产精品乱码不99按摩 亚洲精品国产精品久久清纯直播 亚洲精品国产精品国自产在线 | 高清不卡一区二区三区| 岛国在线视频| 狠狠久久亚洲欧美专区| 亚洲少妇中文字幕| 亚洲蜜桃视频| 成人免费黄色网| 最新电影电视剧在线观看免费观看| 欧美性猛交xxxx乱大交蜜桃| 午夜男人的天堂| 狠狠爱综合网| 国产66精品久久久久999小说 | 韩国国内大量揄拍精品视频| 国产喷水福利在线视频| 亚洲欧洲在线观看av| 亚洲五月天综合| 国产欧美日韩| 国产福利视频一区二区| 日韩三级电影网| 欧美日韩视频在线| 亚洲av无码一区二区三区观看| 极品中文字幕一区| 国产主播一区二区三区四区| 国产伦久视频在线观看| 日韩av网站电影| www.伊人久久| 国产人成一区二区三区影院| 成人性视频欧美一区二区三区| 伊人成综合网yiren22| 热久久99这里有精品| 嫩草研究院在线观看| 一本久久综合亚洲鲁鲁五月天| 黄色国产在线观看| 久久久精品性| 亚洲成人蜜桃| 粉嫩av国产一区二区三区| 欧美另类交人妖| 丰满人妻一区二区| 韩曰欧美视频免费观看| 精品成人无码一区二区三区| 蜜臀a∨国产成人精品| 中文字幕日韩一区二区三区不卡 | 国产精品成人免费观看| 国产精品一区2区| 日本一本中文字幕| 亚洲国产精品嫩草影院久久av| 国产成人精品久久二区二区| 日本精品一区二区三区在线播放| 日韩一区二区三区电影在线观看 | 二区三区四区视频| 国产精品一区在线观看你懂的| www.成年人视频| 九九视频精品全部免费播放| 国产精品色婷婷视频| av网址在线看| 亚洲精品第一页| 欧美三级网站在线观看| 亚洲另类在线一区| 中文文字幕文字幕高清| 日本欧美一区二区| 五月天激情图片| 欧美激情在线免费| 亚洲自拍欧美另类| 大胆人体一区| 欧美成在线观看| 欧洲伦理片一区 二区 三区| 欧美女孩性生活视频| 好吊操这里只有精品| 中文字幕精品一区二区三区精品| 久久久久久国产精品日本| 久久精品官网| 国产精品日韩三级| 欧美精品一区二区久久| 国产精品三区在线| 色综合视频一区二区三区44| 91精品国产91久久久久久不卡 | 人人香蕉久久| 成人亲热视频网站| 台湾佬中文娱乐网欧美电影| 日韩视频免费在线观看| 青草久久伊人| 精品久久久久一区二区国产| 中文字幕乱码视频| 欧美日韩一区二区在线播放| 男人的天堂久久久| 国产欧美日韩视频在线观看| 亚洲精品乱码久久久久久蜜桃欧美| 日韩精品一区第一页| 久久这里只有精品23| 天天超碰亚洲| 视频三区二区一区| 亚洲免费专区| 国产精品国产一区二区| 亚洲福利影视| 国产精品视频1区| 成人性生活视频| 91高清视频在线免费观看| 色呦呦在线观看视频| 日韩中文在线视频| 国产在线视频网站| 日韩精品在线免费播放| 男人天堂手机在线观看| 欧美一区二区三区在线看| 在线免费一区二区| 色婷婷亚洲综合| 啦啦啦免费高清视频在线观看| 亚洲国产精品综合小说图片区| 国产天堂av在线| 国产视频在线观看一区二区三区| 久久久无码人妻精品无码| 国产在线不卡视频| 亚洲天堂国产视频| 美女免费视频一区二区| 亚洲老女人av| 青娱乐精品在线视频| 久久精品免费网站| 久久三级视频| 18岁视频在线观看| 久久看片网站| 欧美精品aaaa| 免费人成精品欧美精品| 在线观看免费成人av| 日本成人在线电影网| 精品久久久久久中文字幕2017| 玖玖在线精品| 在线观看免费黄网站| 美腿丝袜亚洲三区| gai在线观看免费高清| 国产一区二区三区观看| 手机在线播放av| 国产精品一区2区| 黑人玩弄人妻一区二区三区| 99久久婷婷国产综合精品| 亚洲专区区免费| 国产午夜亚洲精品午夜鲁丝片| 中文字幕在线观看免费高清| 中文字幕第一区第二区| 午夜三级在线观看| 亚洲精品高清在线| 久久精品二区| 中文国产字幕在线观看| 亚洲一区二区三区四区五区中文| 中文字幕第28页| 日韩欧美国产中文字幕| 波多野结衣高清视频| 欧美日韩高清一区| 精品久久久免费视频| 亚洲а∨天堂久久精品9966| 青青久草在线| 日韩在线免费观看视频| 四虎亚洲精品| 日韩av电影国产| 少妇高潮一区二区三区99| av蓝导航精品导航| 久久不见久久见中文字幕免费| 在线观看成人一级片| 黄色工厂这里只有精品| 精品人妻一区二区三区四区在线 | 91精品国产三级| 不卡的av中国片| 蜜桃传媒一区二区亚洲| 亚洲美女偷拍久久| 国产精品久久久久久久久久久久久久久久久 | 国产美女久久| 国产在线资源一区| 国产大片一区| 鲁一鲁一鲁一鲁一澡| 毛片av一区二区三区| 稀缺呦国内精品呦| 国产精品久久久久桃色tv| 久久精品美女视频| 欧美色图在线观看| 姝姝窝人体www聚色窝| 久久久精品国产网站| 亚洲日本天堂| 成人区精品一区二区| 欧美www视频在线观看| 日韩日韩日韩日韩日韩| 男女性色大片免费观看一区二区 | 成人1区2区3区| 亚洲一二三在线| 爱福利在线视频| 成人深夜直播免费观看| 视频一区欧美| 人妻夜夜添夜夜无码av| 激情欧美日韩一区二区| 自拍偷拍亚洲天堂| 亚洲午夜免费福利视频| 国产又爽又黄又嫩又猛又粗| 亚洲三级 欧美三级| sm捆绑调教国产免费网站在线观看| 国产中文字幕日韩| 精品av一区二区| 国产精品裸体瑜伽视频| 国产精品资源站在线| 男人天堂资源网| 色哟哟一区二区在线观看| 天天摸夜夜添狠狠添婷婷| 欧美国产在线视频| 国产一区二区三区亚洲综合 | 2021av在线| 国产成人精品在线观看| 天天躁日日躁成人字幕aⅴ| 97久久国产亚洲精品超碰热| 精品午夜久久福利影院| 羞羞在线观看视频| 欧美日韩一区久久| 成人午夜在线观看视频| 日本欧美国产在线| 婷婷综合福利| 黄色免费视频大全| av激情综合网| 国产精品第72页| 亚洲а∨天堂久久精品9966| 欧洲中文在线| 高清国语自产拍免费一区二区三区| 视频在线不卡免费观看| 在线观看国产一级片| 中文字幕乱码日本亚洲一区二区 | 日韩精品一区国产麻豆| 成人区精品一区二区不卡| 91免费看片网站| 欧美a级片网站| 一级少妇精品久久久久久久| 亚洲一区二区成人在线观看| 欧洲精品久久一区二区| 91av在线播放| 黑人操亚洲人| av网站在线不卡| 亚洲免费观看高清完整版在线观看| 国产视频一区二区三区四区五区| 欧美超级乱淫片喷水| 风间由美一区二区av101| 69堂免费视频| 国产色综合一区| 国产一区二区在线视频聊天| 麻豆乱码国产一区二区三区| 国产精伦一区二区三区| 黄色一级视频片| 日本一区二区三区久久久久久久久不| 国产精品露脸视频| 久久av在线看| 久久草在线视频| 亚洲男人天堂色| 亚洲欧美偷拍三级| 午夜av免费观看| 国产精品成熟老女人| 希岛爱理一区二区三区| 日韩少妇一区二区| 在线免费不卡视频| 成人福利在线观看视频| 极品日韩久久| 麻豆精品国产91久久久久久| 在线免费观看亚洲视频| 亚洲精品视频在线播放| 麻豆久久久久| 免费毛片网站在线观看| 国产欧美一区二区精品忘忧草| 国产又粗又猛又爽又黄的| 国内精品久久久久| 成人激情免费视频| 性折磨bdsm欧美激情另类| 色香色香欲天天天影视综合网| 免费大片黄在线| 精品免费一区二区三区蜜桃| 蜜桃免费网站一区二区三区| 久久久久免费看| 一本久久综合亚洲鲁鲁| 我要色综合中文字幕| 日本va中文字幕| 午夜久久电影网| 韩国中文字幕在线| 欧美日韩亚洲在线 | 欧美日韩国产综合草草|