日韩av黄I国产麻豆传媒I国产91av视频在线观看I日韩一区二区三区在线看I美女国产在线I麻豆视频国产在线观看I成人黄色短片

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 >

庖丁解InnoDB之UNDO LOG

發布時間:2024/8/23 53 豆豆
生活随笔 收集整理的這篇文章主要介紹了 庖丁解InnoDB之UNDO LOG 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

簡介:?Undo Log是InnoDB十分重要的組成部分,它的作用橫貫InnoDB中兩個最主要的部分,并發控制(Concurrency Control)和故障恢復(Crash Recovery),InnoDB中Undo Log的實現亦日志亦數據。本文將從其作用、設計思路、記錄內容、組織結構,以及各種功能實現等方面,整體介紹InnoDB中的Undo Log。

作者 | 瀚之
來源 | 阿里技術公眾號

Undo Log是InnoDB十分重要的組成部分,它的作用橫貫InnoDB中兩個最主要的部分,并發控制(Concurrency Control)和故障恢復(Crash Recovery),InnoDB中Undo Log的實現亦日志亦數據。本文將從其作用、設計思路、記錄內容、組織結構,以及各種功能實現等方面,整體介紹InnoDB中的Undo Log,文章會深入一定的代碼實現,但在細節上還是希望用抽象的實現思路代替具體的代碼。本文基于MySQL 8.0,但在大多數的設計思路上MySQL的各個版本都是一致的。考慮到篇幅有限,以及避免過多信息的干擾,從而能夠聚焦Undo Log本身的內容,本文中一筆帶過或有意省略了一些內容,包括索引、事務系統、臨時表、XA事務、Virtual Column、外部記錄、Blob等。

一 Undo Log的作用

數據庫故障恢復機制的前世今生中提到過,Undo Log用來記錄每次修改之前的歷史值,配合Redo Log用于故障恢復。這也就是InnoDB中Undo Log的第一個作用:

1 事務回滾

在設計數據庫時,我們假設數據庫可能在任何時刻,由于如硬件故障,軟件Bug,運維操作等原因突然崩潰。這個時候尚未完成提交的事務可能已經有部分數據寫入了磁盤,如果不加處理,會違反數據庫對Atomic的保證,也就是任何事務的修改要么全部提交,要么全部取消。針對這個問題,直觀的想法是等到事務真正提交時,才能允許這個事務的任何修改落盤,也就是No-Steal策略。顯而易見,這種做法一方面造成很大的內存空間壓力,另一方面提交時的大量隨機IO會極大的影響性能。因此,數據庫實現中通常會在正常事務進行中,就不斷的連續寫入Undo Log,來記錄本次修改之前的歷史值。當Crash真正發生時,可以在Recovery過程中通過回放Undo Log將未提交事務的修改抹掉。InnoDB采用的就是這種方式。

既然已經有了在Crash Recovery時支持事務回滾的Undo Log,自然地,在正常運行過程中,死鎖處理或用戶請求的事務回滾也可以利用這部分數據來完成。

2 MVCC(Multi-Versioin Concurrency Control)

淺析數據庫并發控制機制中提到過,為了避免只讀事務與寫事務之間的沖突,避免寫操作等待讀操作,幾乎所有的主流數據庫都采用了多版本并發控制(MVCC)的方式,也就是為每條記錄保存多份歷史數據供讀事務訪問,新的寫入只需要添加新的版本即可,無需等待。InnoDB在這里復用了Undo Log中已經記錄的歷史版本數據來滿足MVCC的需求。

二 什么樣的Undo Log

庖丁解InnoDB之REDO LOG中講過的基于Page的Redo Log可以更好的支持并發的Redo應用,從而縮短DB的Crash Recovery時間。而對于Undo Log來說,InnoDB用Undo Log來實現MVCC,DB運行過程中是允許有歷史版本的數據存在的。因此,Crash Recovery時利用Undo Log的事務回滾完全可以在后臺,像正常運行的事務一樣異步回滾,從而讓數據庫先恢復服務。因此,Undo Log的設計思路不同于Redo Log,Undo Log需要的是事務之間的并發,以及方便的多版本數據維護,其重放邏輯不希望因DB的物理存儲變化而變化。因此,InnoDB中的Undo Log采用了基于事務的Logical Logging的方式。

同時,更多的責任意味著更復雜的管理邏輯,InnoDB中其實是把Undo當做一種數據來維護和使用的,也就是說,Undo Log日志本身也像其他的數據庫數據一樣,會寫自己對應的Redo Log,通過Redo Log來保證自己的原子性。因此,更合適的稱呼應該是Undo Data。

三 Undo Record中的內容

每當InnoDB中需要修改某個Record時,都會將其歷史版本寫入一個Undo Log中,對應的Undo Record是Update類型。當插入新的Record時,還沒有一個歷史版本,但為了方便事務回滾時做逆向(Delete)操作,這里還是會寫入一個Insert類型的Undo Record。

1 Insert類型的Undo Record

這種Undo Record在代碼中對應的是TRX_UNDO_INSERT_REC類型。不同于Update類型的Undo Record,Insert Undo Record僅僅是為了可能的事務回滾準備的,并不在MVCC功能中承擔作用。因此只需要記錄對應Record的Key,供回滾時查找Record位置即可。

其中Undo Number是Undo的一個遞增編號,Table ID用來表示是哪張表的修改。下面一組Key Fields的長度不定,因為對應表的主鍵可能由多個field組成,這里需要記錄Record完整的主鍵信息,回滾的時候可以通過這個信息在索引中定位到對應的Record。除此之外,在Undo Record的頭尾還各留了兩個字節用戶記錄其前序和后繼Undo Record的位置。

2 Update類型的Undo Record

由于MVCC需要保留Record的多個歷史版本,當某個Record的歷史版本還在被使用時,這個Record是不能被真正的刪除的。因此,當需要刪除時,其實只是修改對應Record的Delete Mark標記。對應的,如果這時這個Record又重新插入,其實也只是修改一下Delete Mark標記,也就是將這兩種情況的delete和insert轉變成了update操作。再加上常規的Record修改,因此這里的Update Undo Record會對應三種Type:TRX_UNDO_UPD_EXIST_REC、TRX_UNDO_DEL_MARK_REC和TRX_UNDO_UPD_DEL_REC。他們的存儲內容也類似:

除了跟Insert Undo Record相同的頭尾信息,以及主鍵Key Fileds之外,Update Undo Record增加了:

  • Transaction Id記錄了產生這個歷史版本事務Id,用作后續MVCC中的版本可見性判斷
  • Rollptr指向的是該記錄的上一個版本的位置,包括space number,page number和page內的offset。沿著Rollptr可以找到一個Record的所有歷史版本。
  • Update Fields中記錄的就是當前這個Record版本相對于其之后的一次修改的Delta信息,包括所有被修改的Field的編號,長度和歷史值。

四 Undo Record的組織方式

上面介紹了一個Undo Record中的存放的內容,每一次的修改都會產生至少一個Undo Record,那么大量Undo Record如何組織起來,來支持高效的訪問和管理呢,這一小節我們將從幾個層面來進行介紹:首先是在不考慮物理存儲的情況下的邏輯組織方式;之后,物理組織方式介紹如何將其存儲到到實際16KB物理塊中;然后文件組織方式介紹整體的文件結構;最后再介紹其在內存中的組織方式。

1 邏輯組織方式 - Undo Log

每個事務其實會修改一組的Record,對應的也就會產生一組Undo Record,這些Undo Record收尾相連就組成了這個事務的Undo Log。除了一個個的Undo Record之外,還在開頭增加了一個Undo Log Header來記錄一些必要的控制信息,因此,一個Undo Log的結構如下所示:

Undo Log Header中記錄了產生這個Undo Log的事務的Trx ID;Trx No是事務的提交順序,也會用這個來判斷是否能Purge,這個在后面會詳細介紹;Delete Mark標明該Undo Log中有沒有TRX_UNDO_DEL_MARK_REC類型的Undo Record,避免Purge時不必要的掃描;Log Start Offset中記錄Undo Log Header的結束位置,方便之后Header中增加內容時的兼容;之后是一些Flag信息;Next Undo Log及Prev Undo Log標記前后兩個Undo Log,這個會在接下來介紹;最后通過History List Node將自己掛載到為Purge準備的History List中。

索引中的同一個Record被不同事務修改,會產生不同的歷史版本,這些歷史版本又通過Rollptr穿成一個鏈表,供MVCC使用。如下圖所示:

示例中有三個事務操作了表t上,主鍵id是1的記錄,首先事務I插入了這條記錄并且設置filed a的值是A,之后事務J和事務K分別將這條id為1的記錄中的filed a的值修改為了B和C。I,J,K三個事務分別有自己的邏輯上連續的三條Undo Log,每條Undo Log有自己的Undo Log Header。從索引中的這條Record沿著Rollptr可以依次找到這三個事務Undo Log中關于這條記錄的歷史版本。同時可以看出,Insert類型Undo Record中只記錄了對應的主鍵值:id=1,而Update類型的Undo Record中還記錄了對應的歷史版本的生成事務Trx_id,以及被修改的field a的歷史值。

2 物理組織格式 - Undo Segment

上面描述了一個Undo Log的結構,一個事務會產生多大的Undo Log本身是不可控的,而最終寫入磁盤卻是按照固定的塊大小為單位的,InnoDB中默認是16KB,那么如何用固定的塊大小承載不定長的Undo Log,以實現高效的空間分配、復用,避免空間浪費。InnoDB的基本思路是讓多個較小的Undo Log緊湊存在一個Undo Page中,而對較大的Undo Log則隨著不斷的寫入,按需分配足夠多的Undo Page分散承載。下面我們就看看這部分的物理存儲方式:

如上所示,是一個Undo Segment的示意圖,每個寫事務開始寫操作之前都需要持有一個Undo Segment,一個Undo Segment中的所有磁盤空間的分配和釋放,也就是16KB Page的申請和釋放,都是由一個FSP的Segment管理的,這個跟索引中的Leaf Node Segment和Non-Leaf Node Segment的管理方式是一致的,這部分之后會有單獨的文章來進行介紹。

Undo Segment會持有至少一個Undo Page,每個Undo Page會在開頭38字節到56字節記錄Undo Page Header,其中記錄Undo Page的類型、最后一條Undo Record的位置,當前Page還空閑部分的開頭,也就是下一條Undo Record要寫入的位置。Undo Segment中的第一個Undo Page還會在56字節到86字節記錄Undo Segment Header,這個就是這個Undo Segment中磁盤空間管理的Handle;其中記錄的是這個Undo Segment的狀態,比如TRX_UNDO_CACHED、TRX_UNDO_TO_PURGE等;這個Undo Segment中最后一條Undo Record的位置;這個FSP Segment的Header,以及當前分配出來的所有Undo Page的鏈表。

Undo Page剩余的空間都是用來存放Undo Log的,對于像上圖Undo Log 1,Undo Log 2這種較短的Undo Log,為了避免Page內的空間浪費,InnoDB會復用Undo Page來存放多個Undo Log,而對于像Undo Log 3這種比較長的Undo Log可能會分配多個Undo Page來存放。需要注意的是Undo Page的復用只會發生在第一個Page。

3 文件組織方式 - Undo Tablespace

每一時刻一個Undo Segment都是被一個事務獨占的。每個寫事務都會持有至少一個Undo Segment,當有大量寫事務并發運行時,就需要存在多個Undo Segment。InnoDB中的Undo 文件中準備了大量的Undo Segment的槽位,按照1024一組劃分為Rollback Segment。每個Undo Tablespace最多會包含128個Rollback Segment,Undo Tablespace文件中的第三個Page會固定作為這128個Rollback Segment的目錄,也就是Rollback Segment Arrary Header,其中最多會有128個指針指向各個Rollback Segment Header所在的Page。Rollback Segment Header是按需分配的,其中包含1024個Slot,每個Slot占四個字節,指向一個Undo Segment的First Page。除此之前還會記錄該Rollback Segment中已提交事務的History List,后續的Purge過程會順序從這里開始回收工作。

可以看出Rollback Segment的個數會直接影響InnoDB支持的最大事務并發數。MySQL 8.0由于支持了最多127個獨立的Undo Tablespace,一方面避免了ibdata1的膨脹,方便undo空間回收,另一方面也大大增加了最大的Rollback Segment的個數,增加了可支持的最大并發寫事務數。如下圖所示:

4 內存組織結構

上面介紹的都是Undo數據在磁盤上的組織結構,除此之外,在內存中也會維護對應的數據結構來管理Undo Log,如下圖所示:

對應每個磁盤Undo Tablespace會有一個undo::Tablespace的內存結構,其中最主要的就是一組trx_rseg_t的集合,trx_rseg_t對應的就是上面介紹過的一個Rollback Segment Header,除了一些基本的元信息之外,trx_rseg_t中維護了四個trx_undo_t的鏈表,Update List中是正在被使用的用于寫入Update類型Undo的Undo Segment;Update Cache List中是空閑空間比較多,可以被后續事務復用的Update類型Undo Segment;對應的,Insert List和Insert Cache List分別是正在使用中的Insert類型Undo Segment,和空間空間較多,可以被后續復用的Insert類型Undo Segment。因此trx_undo_t對應的就是上面介紹過的Undo Segment。接下來,我們就從Undo的寫入、Undo用于Rollback、MVCC、Crash Recovery以及如何清理Undo等方面來介紹InnoDB中Undo的角色和功能。

五 Undo的寫入

當寫事務開始時,會先通過trx_assign_rseg_durable分配一個Rollback Segment,該事務的內存結構trx_t也會通過rsegs指針指向對應的trx_rseg_t內存結構,這里的分配策略很簡單,就是依次嘗試下一個Active的Rollback Segment。之后當第一次真正產生修改需要寫Undo Record的時,會調用trx_undo_assign_undo來獲得一個Undo Segment。這里會優先復用trx_rseg_t上Cached List中的trx_undo_t,也就是已經分配出來但沒有被正在使用的Undo Segment,如果沒有才調用trx_undo_create創建新的Undo Segment,trx_undo_create中會輪詢選擇當前Rollback Segment中可用的Slot,也是就值FIL_NUL的Slot,申請新的Undo Page,初始化Undo Page Header,Undo Segment Header等信息,創建新的trx_undo_t內存結構并掛到trx_rseg_t的對應List中。

獲得了可用的Undo Segment之后,該事務會在合適的位置初始化自己的Undo Log Header,之后,其所有修改產生的Undo Record都會順序的通過trx_undo_report_row_operation順序的寫入當前的Undo Log,其中會根據是insert還是update類型,分別調用trx_undo_page_report_insert或者trx_undo_page_report_modify。本文開始已經介紹過了具體的Undo Record內容。簡單的講,insert類型會記錄插入Record的主鍵,update類型除了記錄主鍵以外還會有一個update fileds記錄這個歷史值跟索引值的diff。之后指向當前Undo Record位置的Rollptr會返回寫入索引的Record上。

當一個Page寫滿后,會調用trx_undo_add_page來在當前的Undo Segment上添加新的Page,新Page寫入Undo Page Header之后繼續供事務寫入Undo Record,為了方便維護,這里有一個限制就是單條Undo Record不跨page,如果當前Page放不下,會將整個Undo Record寫入下一個Page。

當事務結束(commit或者rollback)之后,如果只占用了一個Undo Page,且當前Undo Page使用空間小于page的3/4,這個Undo Segment會保留并加入到對應的insert/update cached list中。否則,insert類型的Undo Segment會直接回收,而update類型的Undo Segment會等待后臺的Purge做完后回收。根據不同的情況,Undo Segment Header中的State會被從TRX_UNDO_ACTIVE改成TRX_UNDO_TO_FREE,TRX_UNDO_TO_PURGE或TRX_UNDO_CACHED,這個修改其實就是InnoDB的事務結束的標志,無論是Rollback還是Commit,在這個修改對應的Redo落盤之后,就可以返回用戶結果,并且Crash Recovery之后也不會再做回滾處理。

六 Undo for Rollback

InnoDB中的事務可能會由用戶主動觸發Rollback;也可能因為遇到死鎖異常Rollback;或者發生Crash,重啟后對未提交的事務回滾。在Undo層面來看,這些回滾的操作是一致的,基本的過程就是從該事務的Undo Log中,從后向前依次讀取Undo Record,并根據其中內容做逆向操作,恢復索引記錄。

回滾的入口是函數row_undo,其中會先調用trx_roll_pop_top_rec_of_trx獲取并刪除該事務的最后一條Undo Record。如下圖例子中的Undo Log包括三條Undo Records,其中Record 1在Undo Page 1中,Record 2,3在Undo Page 2中,先通過從Undo Segment Header中記錄的Page List找到當前事務的最后一個Undo Page的Header,并根據Undo Page 2的Header上記錄的Free Space Offset定位最后一條Undo Record結束的位置,當然實際運行時,這兩個值是緩存在trx_undo_t的top_page_no和top_offset中的。利用Prev Record Offset可以找到Undo Record 3,做完對應的回滾操作之后,再通過前序指針Prev Record Offset找到前一個Undo Record,依次進行處理。處理完當前Page中的所有Undo Records后,再沿著Undo Page Header中的List找到前一個Undo Page,重復前面的過程,完成一個事務所有Page上的所有Undo Records的回滾。

拿到一個Undo Record之后,自然地,就是對其中內容的解析,這里會調用row_undo_ins_parse_undo_rec,從Undo Record中獲取修改行的table,解析出其中記錄的主鍵信息,如果是update類型,還會拿到一個update vector記錄其相對于更新的一個版本的變化。

TRX_UNDO_INSERT_REC類型的Undo回滾在row_undo_ins中進行,insert的逆向操作當然就是delete,根據從Undo Record中解析出來的主鍵,用row_undo_search_clust_to_pcur定位到對應的ROW, 分別調用row_undo_ins_remove_sec_rec和row_undo_ins_remove_clust_rec在二級索引和主索引上將當前行刪除。

update類型的undo包括TRX_UNDO_UPD_EXIST_REC,TRX_UNDO_DEL_MARK_REC和TRX_UNDO_UPD_DEL_REC三種情況,他們的Undo回滾都是在row_undo_mod中進行,首先會調用row_undo_mod_del_unmark_sec_and_undo_update,其中根據從Undo Record中解析出的update vector來回退這次操作在所有二級索引上的影響,可能包括重新插入被刪除的二級索引記錄、去除其中的Delete Mark標記,或者用update vector中的diff信息將二級索引記錄修改之前的值。之后調用row_undo_mod_clust同樣利用update vector中記錄的diff信息將主索引記錄修改回之前的值。

完成回滾的Undo Log部分,會調用trx_roll_try_truncate進行回收,對不再使用的page調用trx_undo_free_last_page將磁盤空間交還給Undo Segment,這個是寫入過程中trx_undo_add_page的逆操作。

七 Undo for MVCC

多版本的目的是為了避免寫事務和讀事務的互相等待,那么每個讀事務都需要在不對Record加Lock的情況下, 找到對應的應該看到的歷史版本。所謂歷史版本就是假設在該只讀事務開始的時候對整個DB打一個快照,之后該事務的所有讀請求都從這個快照上獲取。當然實現上不能真正去為每個事務打一個快照,這個時間空間都太高了。InnoDB的做法,是在讀事務第一次讀取的時候獲取一份ReadView,并一直持有,其中記錄所有當前活躍的寫事務ID,由于寫事務的ID是自增分配的,通過這個ReadView我們可以知道在這一瞬間,哪些事務已經提交哪些還在運行,根據Read Committed的要求,未提交的事務的修改就是不應該被看見的,對應地,已經提交的事務的修改應該被看到。

作為存儲歷史版本的Undo Record,其中記錄的trx_id就是做這個可見性判斷的,對應的主索引的Record上也有這個值。當一個讀事務拿著自己的ReadView訪問某個表索引上的記錄時,會通過比較Record上的trx_id確定是否是可見的版本,如果不可見就沿著Record或Undo Record中記錄的rollptr一路找更老的歷史版本。如下圖所示,事務R開始需要查詢表t上的id為1的記錄,R開始時事務I已經提交,事務J還在運行,事務K還沒開始,這些信息都被記錄在了事務R的ReadView中。事務R從索引中找到對應的這條Record[1, C],對應的trx_id是K,不可見。沿著Rollptr找到Undo中的前一版本[1, B],對應的trx_id是J,不可見。繼續沿著Rollptr找到[1, A],trx_id是I可見,返回結果。

前面提到過,作為Logical Log,Undo中記錄的其實是前后兩個版本的diff信息,而讀操作最終是要獲得完整的Record內容的,也就是說這個沿著rollptr指針一路查找的過程中需要用Undo Record中的diff內容依次構造出對應的歷史版本,這個過程在函數row_search_mvcc中,其中trx_undo_prev_version_build會根據當前的rollptr找到對應的Undo Record位置,這里如果是rollptr指向的是insert類型,或者找到了已經Purge了的位置,說明到頭了,會直接返回失敗。否則,就會解析對應的Undo Record,恢復出trx_id、指向下一條Undo Record的rollptr、主鍵信息,diff信息update vector等信息。之后通過row_upd_rec_in_place,用update vector修改當前持有的Record拷貝中的信息,獲得Record的這個歷史版本。之后調用自己ReadView的changes_visible判斷可見性,如果可見則返回用戶。完成這個歷史版本的讀取。

八 Undo for Crash Recovery

Crash Recovery時,需要利用Undo中的信息將未提交的事務的所有影響回滾,以保證數據庫的Failure Atomic。前面提到過,InnoDB中的Undo其實是像數據一樣處理的,也從上面的組織結構中可以看出來,Undo本身有著比Redo Log復雜得多、按事務分配而不是順序寫入的組織結構,其本身的Durability像InnoDB中其他的數據一樣,需要靠Redo來保證,像庖丁解InnoDB之REDO LOG中介紹的那樣。除了通用的一些MLOG_2BYTES、MLOG_4BYTES類型之外,Undo本身也有自己對應的Redo Log類型:MLOG_UNDO_INIT類型在Undo Page舒適化的時候記錄初始化;在分配Undo Log的時候,需要重用Undo Log Header或需要創建新的Undo Log Header的時候,會分別記錄MLOG_UNDO_HDR_REUSE和MLOG_UNDO_HDR_CREATE類型的Redo Record;MLOG_UNDO_INSERT是最常見的,在Undo Log里寫入新的Undo Record都對應的寫這個日志記錄寫入Undo中的所有內容;最后,MLOG_UNDO_ERASE_END 對應Undo Log跨Undo Page時抹除最后一個不完整的Undo Record的操作。

如數據庫故障恢復機制的前世今生中講過的ARIES過程,Crash Recovery的過程中會先重放所有的Redo Log,整個Undo的磁盤組織結構,也會作為一種數據類型也會通過上面講到的這些Redo類型的重放恢復出來。之后在trx_sys_init_at_db_start中會掃描Undo的磁盤結構,遍歷所有的Rollback Segment和其中所有的Undo Segment,通過讀取Undo Segment Header中的State,可以知道在Crash前,最后持有這個Undo Segment的事務狀態。如果是TRX_UNDO_ACTIVE,說明當時事務需要回滾,否則說明事務已經結束,可以繼續清理Undo Segment的邏輯。之后,就可以恢復出Undo Log的內存組織模式,包括活躍事務的內存結構trx_t,Rollback Segment的內存結構trx_rseg_t,以及其中的trx_undo_t的四個鏈表。

Crash Recovery完成之前,會啟動在srv_dict_recover_on_restart中啟動異步回滾線程trx_recovery_rollback_thread,其中對Crash前還活躍的事務,通過trx_rollback_active進行回滾,這個過程跟上面提到的Undo for Rollback是一致的。

九 Undo的清理

我們已經知道,InnoDB在Undo Log中保存了多份歷史版本來實現MVCC,當某個歷史版本已經確認不會被任何現有的和未來的事務看到的時候,就應該被清理掉。因此就需要有辦法判斷哪些Undo Log不會再被看到。InnoDB中每個寫事務結束時都會拿一個遞增的編號trx_no作為事務的提交序號,而每個讀事務會在自己的ReadView中記錄自己開始的時候看到的最大的trx_no為m_low_limit_no。那么,如果一個事務的trx_no小于當前所有活躍的讀事務Readview中的這個m_low_limit_no,說明這個事務在所有的讀開始之前已經提交了,其修改的新版本是可見的, 因此不再需要通過undo構建之前的版本,這個事務的Undo Log也就可以被清理了。如下圖所所以,由于ReadView List中最老的ReadView在獲取時,Transaction J就已經Commit,因此所有的讀事務都一定能被Index中的版本或者第一個Undo歷史版本滿足,不需要更老的Undo,因此整個Transaction J的Undo Log都可以清理了。

Undo的清理工作是由專門的后臺線程srv_purge_coordinator_thread進行掃描和分發, 并由多個srv_worker_thread真正清理的。coordinator會首先在函數trx_purge_attach_undo_recs中掃描innodb_purge_batch_size配置個Undo Records,作為一輪清理的任務分發給worker。

1 掃描一批要清理Undo Records

事務結束的時候,對于需要Purge的Update類型的Undo Log,會按照事務提交的順序trx_no,掛載到Rollback Segment Header的History List上。Undo Log回收的基本思路,就是按照trx_no從小到大,依次遍歷所有Undo Log進行清理操作。前面介紹了,InnoDB中有多個Rollback Segment,那么就會有多個History List,每個History List內部事務有序,但還需要從多個History List上找一個trx_no全局有序的序列,如下圖所示:

圖中的事務編號是按照InnoDB這里引入了一個堆結構purge_queue,用來依次從所有History List中找到下一個擁有最小trx_no的事務。purge_queue中記錄了所有等待Purge的Rollback Segment和其History中trx_no最小的事務,trx_purge_choose_next_log依次從purge_queue中pop出擁有全局最小trx_no的Undo Log。調用trx_purge_get_next_rec遍歷對應的Undo Log,處理每一條Undo Record。之后繼續調用trx_purge_rseg_get_next_history_log從purge_queue中獲取下一條trx_no最小的Undo Log,并且將當前Rollback Segment上的下一條Undo Log繼續push進purge_queue,等待后續的順序處理。對應上圖的處理過程和對應的函數調用,如下圖所示:

其中,trx_purge_get_next_rec會從上到下遍歷一個Undo Log中的所有Undo Record,這個跟前面講過的Rollback時候從下到上的遍歷方向是相反的,還是以同樣的場景為例,要Purge的Undo Log橫跨兩個Undo Page,Undo Record 1在Page 1中,而Undo Record 2,3在Page 2中。如下圖所示,首先會從當前的Undo Log Header中找到第一個Undo Record的位置Log Start Offset,處理完Undo Record1之后沿著Next Record Offset去找下一個Undo Record,當找到Page末尾時,要通過Page List Node找下一個Page,找到Page內的第一個Undo Record,重復上面的過程直到找出所有的Undo Record。

對每個要Purge的Undo Record,在真正刪除它本身之前,可能還需要處理一些索引上的信息,這是由于正常運行過程中,當需要刪除某個Record時,為了保證其之前的歷史版本還可以通過Rollptr找到,Record是沒有真正刪除的,只是打了Delete Mark的標記,并作為一種特殊的Update操作記錄了Undo Record。那么在對應的TRX_UNDO_DEL_MARK_REC類型的Undo Record被清理之前,需要先從索引上真正地刪除這個Delete Mark的記錄。因此Undo Record的清理工作會分為兩個過程:

  • TRX_UNDO_DEL_MARK_REC類型Undo Record對應的Record的真正刪除,稱為Undo Purge;
  • 以及Undo Record本身從舊到新的刪除,稱為Undo Truncate。

除此之外,當配置的獨立Undo Tablespace大于兩個的時候,InnoDB支持通過重建來縮小超過配置大小的Undo Tablespace:

  • Undo Tablespace的重建縮小,稱為Undo Tablespace Truncate

2 Undo Purge

這一步主要針對的是TRX_UNDO_DEL_MARK_REC類型的Undo Record,用來真正的刪除索引上被標記為Delete Mark的Record。worker線程會在row_purge函數中,循環處理coordinator分配來的每一個Undo Records,先通過row_purge_parse_undo_rec,依次從Undo Record中解析出type、table_id、rollptr、對應記錄的主鍵信息以及update vector。之后,針對TRX_UNDO_DEL_MARK_REC類型,調用row_purge_remove_sec_if_poss將需要刪除的記錄從所有的二級索引上刪除,調用row_purge_remove_clust_if_poss從主索引上刪除。另外,TRX_UNDO_UPD_EXIST_REC類型的Undo雖然不涉及主索引的刪除,但可能需要做二級索引的刪除,也是在這里處理的。

3 Undo Truncate

coordinator線程會等待所有的worker完成一批Undo Records的Purge工作,之后嘗試清理不再需要的Undo Log,trx_purge_truncate函數中會遍歷所有的Rollback Segment中的所有Undo Segment,如果其狀態是TRX_UNDO_TO_PURGE,調用trx_purge_free_segment釋放占用的磁盤空間并從History List中刪除。否則,說明該Undo Segment正在被使用或者還在被cache(TRX_UNDO_CACHED類型),那么只通過trx_purge_remove_log_hd將其從History List中刪除。

需要注意的是,Undo Truncate的動作并不是每次都會進行的,它的頻次是由參數innodb_rseg_truncate_frequency控制的,也就是說要攢innodb_rseg_truncate_frequency個batch才進行一次,前面提到每一個batch中會處理innodb_purge_batch_size個Undo Records,這也就是為什么我們從show engine innodb status中看到的Undo History List的縮短是跳變的。

4 Undo Tablespace Truncate

如果innodb_trx_purge_truncate配置打開,在函數trx_purge_truncate中還會去嘗試重建Undo Tablespaces以縮小文件空間占用。Undo Truncate之后,會在函數trx_purge_mark_undo_for_truncate中掃描所有的Undo Tablespace,文件大小大于配置的innodb_max_undo_log_size的Tablespace會被標記為inactive,每一時刻最多有一個Tablespace處于inactive,inactive的Undo Tablespace上的所有Rollback Segment都不參與給新事物的分配,等該文件上所有的活躍事務退出,并且所有的Undo Log都完成Purge之后,這個Tablespace就會被通過trx_purge_initiate_truncate重建,包括重建Undo Tablespace中的文件結構和內存結構,之后被重新標記為active,參與分配給新的事務使用。

十 總結

本文首先概括地介紹了Undo Log的角色,之后介紹了一個Undo Record中的內容,緊接著介紹它的邏輯組織方式、物理組織方式、文件組織方式以及內存組織方式,詳細描述了Undo Tablespace、Rollback Segment、Undo Segment、Undo Log和Undo Record的之間的關系和層級。這些組織方式都是為了更好的使用和維護Undo信息。最后在此基礎上,介紹了Undo在各個重要的DB功能中的作用和實現方式,包括事務回滾、MVCC、Crash Recovery、Purge等。

參考:

[1] MySQL 8.0.11Source Code Documentation: Format of redo log
https://dev.mysql.com/doc/dev/mysql-server/8.0.11/PAGE_INNODB_REDO_LOG_FORMAT.html
[2] MySQL Source Code
https://github.com/mysql/mysql-server
[3] The basics of the InnoDB undo logging and history system
The basics of the InnoDB undo logging and history system – Jeremy Cole:~:text=InnoDB%20keeps%20a%20copy%20of%20everything%20that%20is%20changed&text=It's%20called%20an%20undo%20log,record%20to%20its%20previous%20version.
[4] MySQL · 引擎特性 · InnoDB undo log 漫游
MySQL · 引擎特性 · InnoDB undo log 漫游
[5] 數據庫故障恢復機制的前世今生
數據庫故障恢復機制的前世今生 | CatKang的博客
[6] 淺析數據庫并發控制機制
淺析數據庫并發控制機制 | CatKang的博客
[7] 庖丁解InnoDB之REDO LOG

原文鏈接
本文為阿里云原創內容,未經允許不得轉載。?

總結

以上是生活随笔為你收集整理的庖丁解InnoDB之UNDO LOG的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。

五月婷婷视频在线 | 国产视频观看 | 久久国产系列 | 黄色软件大全网站 | 亚洲精品乱码久久久久久蜜桃动漫 | 国产精品6999成人免费视频 | 久草在线手机视频 | 久久精品99久久久久久 | 国产高清中文字幕 | 免费av电影网站 | 麻豆一区在线观看 | 亚洲一区二区三区在线看 | 日本一区二区三区免费看 | 国产精品对白一区二区三区 | 亚洲精品乱码久久久久久蜜桃动漫 | 9999激情 | 91亚洲精品在线观看 | 美女久久精品 | 69av视频在线观看 | 中文字幕在线免费 | 亚洲专区在线 | 丰满少妇在线观看网站 | 九九免费在线看完整版 | 夜夜操天天干, | 人人爱夜夜操 | 日本久久久久久久久久 | 欧美日韩国产伦理 | 精品久久久久一区二区国产 | 久久国产精品99国产精 | 成人性生爱a∨ | www.久久久 | 婷婷色网视频在线播放 | 四虎成人网 | 日日夜日日干 | 久久理论电影 | 欧美日韩另类在线观看 | 亚洲观看黄色网 | 午夜视频在线观看一区二区三区 | 国产精品久久久久久久午夜 | 欧美日韩亚洲在线观看 | 亚洲少妇自拍 | 免费视频a | 中文字幕在线一区观看 | 五月天九九 | 91视频这里只有精品 | 国产一区二区日本 | 成人观看视频 | 亚洲精品乱码久久久久久写真 | 天天夜夜操 | 91精品国产自产在线观看 | 欧美激情视频一二区 | 免费亚洲精品 | 欧美精品中文字幕亚洲专区 | 国产一区二区精品在线 | 免费在线看成人av | 久久不射影院 | 欧美一区二视频在线免费观看 | 国产无吗一区二区三区在线欢 | 亚洲色图av| 精品久久久影院 | 欧美最新另类人妖 | 国产99久久精品一区二区永久免费 | 日日操狠狠干 | 国内精品久久久久久久 | 亚洲精品免费在线观看视频 | 久久欧美在线电影 | 免费精品国产va自在自线 | 久久久久国产精品免费 | 66av99精品福利视频在线 | 五月婷婷久草 | 狠狠色噜噜狠狠 | 天天操天天添 | 久久99久久99精品免观看粉嫩 | 久久免费视频这里只有精品 | 国产夫妻av在线 | 日韩欧美一区二区三区黑寡妇 | 久久免费精品视频 | 国产精品久久久久久久久久久久久久 | 美女免费视频观看网站 | 亚洲综合色激情五月 | 亚洲美女精品区人人人人 | 91在线免费公开视频 | 国产第一页精品 | 国产精品综合久久久久 | 四虎成人精品永久免费av | 最新中文字幕在线播放 | av在线8 | 成人午夜免费剧场 | 中文在线资源 | 在线日韩av | 91视频免费 | 玖玖爱免费视频 | 9在线观看免费高清完整版在线观看明 | 天堂va在线高清一区 | 精品91视频 | 亚洲黄色网络 | 免费av小说| 亚洲天堂网在线观看视频 | 亚洲精品黄色在线观看 | 精品国产三级 | 九九九九色| 久草视频首页 | 亚洲欧洲国产视频 | 中文高清av | 深爱五月激情网 | 99热在线观看免费 | 欧美激情第一区 | 韩国av在线播放 | 免费观看黄色12片一级视频 | 一级黄色av| 91精品国自产在线偷拍蜜桃 | 亚州国产视频 | 91大神精品视频在线观看 | 久久精品99视频 | 一本一道波多野毛片中文在线 | 视色网站 | 欧美久草视频 | 免费观看高清 | 欧美日韩1区 | 91久久精品日日躁夜夜躁国产 | 国产一区在线免费观看 | 免费日韩 精品中文字幕视频在线 | 不卡中文字幕在线 | 国产黄色大片免费看 | 精品国产一区二区三区久久久久久 | 在线看成人 | 97超碰人人| 欧美日韩国产成人 | 国产精品欧美久久久久无广告 | 九九在线国产视频 | 日韩欧美电影在线 | 亚洲欧洲国产日韩精品 | 亚洲欧美在线视频免费 | 国产一区视频在线播放 | 免费在线播放黄色 | 91桃色视频 | 久久精品国产一区二区电影 | 亚洲激精日韩激精欧美精品 | 婷婷精品国产一区二区三区日韩 | 91精品国自产在线 | 日韩免费在线观看网站 | 91av视频播放| 久久免费视频99 | 97成人精品| 国产女教师精品久久av | 99看视频在线观看 | 韩国av永久免费 | 国产精品a久久久久 | 97超碰国产精品女人人人爽 | 国产一级视频在线 | 精品国产乱码一区二 | 在线日韩一区 | 黄a网| 最近中文字幕免费 | 欧美激情视频免费看 | 特黄特色特刺激视频免费播放 | 在线观看国产v片 | 很黄很污的视频网站 | 国产精品美女久久久久久免费 | 日韩午夜高清 | 国产精品a成v人在线播放 | 天天爱天天舔 | 一区二区电影在线观看 | 久久精品久久久精品美女 | 日本久久久久久 | 色妞色视频一区二区三区四区 | 丰满少妇一级片 | 国产精品在线看 | 西西44人体做爰大胆视频 | 亚洲欧洲国产精品 | 免费大片av | 精品99免费 | 在线免费视频你懂的 | 午夜av一区| 黄色毛片一级片 | 久久开心激情 | 日韩精品视频免费在线观看 | 97香蕉久久国产在线观看 | 国产精品久久久久久久午夜片 | 亚洲精品在线国产 | 夜色资源站wwwcom | 精品一区二区综合 | 男女激情片在线观看 | 91高清视频在线 | 波多野结衣在线视频免费观看 | 九草视频在线 | 在线亚洲欧美日韩 | 日韩三区在线观看 | 午夜精品av | 亚洲精品女人久久久 | 综合成人在线 | 黄色资源在线观看 | 欧美日韩亚洲一 | 国产精品乱码久久久久久1区2区 | 免费人做人爱www的视 | 欧美日韩aa | 国内精品久久久久久久影视简单 | 97影视| 国产高清在线永久 | 五月视频| 免费看黄在线观看 | 日韩网站在线播放 | 国产日韩欧美在线观看视频 | 久草在线手机视频 | 97视频免费在线观看 | 国产在线一区观看 | 午夜视频在线观看一区 | 国产精久久久久久久 | 久久人人爽人人爽人人 | 日本精品久久久一区二区三区 | 色综合天天干 | 免费午夜网站 | 黄色综合 | 成人免费观看a | 成人av手机在线 | 国产精品毛片久久蜜 | 成 人 黄 色 视频免费播放 | 久久国产一区 | 欧美午夜理伦三级在线观看 | 在线观看免费视频你懂的 | 亚洲天堂网视频在线观看 | 久久影院中文字幕 | 天天操天天操天天操天天操 | 中文字幕在线视频一区二区 | 日韩欧美99 | 爱爱av网| 日韩精品免费在线观看视频 | 国产精品成人国产乱 | 国产精品成人一区二区三区吃奶 | 久草在线视频免费资源观看 | 视频在线观看入口黄最新永久免费国产 | 在线观看不卡视频 | 亚洲国产黄色 | 日韩网站免费观看 | 久久精品一区八戒影视 | 激情在线免费视频 | se视频网址 | 美女中文字幕 | 麻豆视频国产精品 | 亚洲www天堂com | 最新一区二区三区 | 成人va天堂| 久草在线免费在线观看 | 国产精品美女久久久久久免费 | 91色蜜桃 | 99国产精品久久久久老师 | 国产午夜三级一区二区三 | 一区国产精品 | av综合在线观看 | 99中文在线 | 久久久美女 | 久久视频在线看 | av网站在线观看免费 | 久久永久免费视频 | 久久精品电影 | 日韩中文字幕视频在线观看 | 人人躁| 国产h在线观看 | a级成人毛片 | 午夜久久网站 | 在线 视频 一区二区 | 国产中文字幕在线免费观看 | 久久夜视频 | 人人添人人澡人人澡人人人爽 | 国产二区av| 中文字幕在线观看完整版电影 | 绯色av一区 | 99精品欧美一区二区三区黑人哦 | 日韩久久精品一区二区三区下载 | 在线成人一区 | 91成人在线免费观看 | 欧美a视频在线观看 | 玖玖在线看 | 久草视频在线资源 | 久草精品视频在线看网站免费 | 91av视频网站 | www久久久| 欧美精品色 | 91在线精品播放 | 91精品国产九九九久久久亚洲 | 国产69久久久 | 三级黄色欧美 | 亚洲草视频 | 欧美日韩国产一二 | 亚洲夜夜网 | 亚洲伊人成综合网 | 国产精品美女久久久 | 99爱爱| 91综合视频在线观看 | 99超碰在线观看 | 一区二区三区污 | 精品在线一区二区 | 日本激情视频中文字幕 | 日韩视频免费 | 又黄又爽又湿又无遮挡的在线视频 | 五月综合网 | 成年人视频在线免费 | 日韩精品久久久久久久电影竹菊 | 亚洲va欧美va人人爽春色影视 | 网站你懂的 | 国产91在线免费视频 | 精品国产乱码久久久久久三级人 | 正在播放国产一区 | 99久精品视频 | 国产手机av | 91一区二区三区在线观看 | 波多野结衣电影一区二区三区 | 国产乱对白刺激视频在线观看女王 | 久久精品视频网站 | 人人爽爽人人 | 日本久热 | 99久久精品国产观看 | 国产资源在线视频 | 99精品国产免费久久久久久下载 | 天堂在线免费视频 | 日韩欧美99 | 国产一区福利在线 | 亚洲精品视频免费观看 | 狠狠的操你 | ,久久福利影视 | 99久久婷婷国产一区二区三区 | 91成人区 | 久久精品欧美日韩精品 | 色婷婷www| 久青草国产在线 | 精品国产伦一区二区三区观看方式 | 九九久久精品视频 | 亚洲美女免费精品视频在线观看 | 亚洲精品久久久久中文字幕二区 | 国产精品九九视频 | 激情欧美xxxx | 91成人破解版 | 成人在线一区二区三区 | 9999精品免费视频 | 国产福利午夜 | 国产精品成人久久久久久久 | 成人教育av | 国产成人久久精品77777综合 | 免费久久片 | 国产精品k频道 | 国产69精品久久99不卡的观看体验 | 成人国产精品av | 青青河边草免费直播 | 最新av电影网址 | 伊人国产在线观看 | 久久免费视频这里只有精品 | 天天射日 | 中文字幕免费观看视频 | 操操操综合 | 日韩综合一区二区 | 在线视频区 | 五月天精品视频 | 久久亚洲私人国产精品 | 亚洲一区久久久 | 奇米7777狠狠狠琪琪视频 | 91精品婷婷国产综合久久蝌蚪 | 五月婷婷在线视频观看 | 亚洲色图激情文学 | 国产又粗又猛又爽又黄的视频先 | 97视频免费看 | 99久久精品国产亚洲 | 国产精品久久久久久久久久不蜜月 | 日韩免费一区 | 中文字幕一区二区三区乱码不卡 | 97色免费视频 | 欧美日本啪啪无遮挡网站 | 国产日产高清dvd碟片 | 久久一区二区三区超碰国产精品 | 免费成人在线观看视频 | 国产不卡免费 | 日韩乱码在线 | 在线免费观看视频一区二区三区 | 美女久久久久久久久久 | 99久久精品免费看国产麻豆 | 精品欧美在线视频 | 99精品国产一区二区三区麻豆 | 探花系列在线 | 亚洲视频aaa | 西西人体4444www高清视频 | 在线色网站 | 欧美一级小视频 | 九九综合久久 | av不卡免费在线观看 | 国产精品久久久久久久久久免费 | 国产精品一区二区在线播放 | 国产高清绿奴videos | av在线永久免费观看 | 美女免费黄视频网站 | 国产精品久久久久久久久软件 | 青青草视频精品 | 亚洲人片在线观看 | 一区二区三区四区影院 | 日韩在线视频一区 | 欧美性大胆 | 国产精品欧美日韩在线观看 | 91麻豆精品国产自产 | 丁香婷婷电影 | 久久成人高清 | 狠狠激情中文字幕 | 日韩在线三级 | 91精品国自产在线观看欧美 | 9草在线 | 国产91成人 | 日韩欧美在线综合网 | 日本韩国精品在线 | 亚洲狠狠丁香婷婷综合久久久 | 91久久国产露脸精品国产闺蜜 | 国产做爰视频 | 91亚洲视频在线观看 | 黄网站免费久久 | 日日夜夜精品免费视频 | 天天操天天舔天天干 | 丁香视频免费观看 | 天天视频色 | 九九九九九九精品任你躁 | 亚在线播放中文视频 | 四虎影视国产精品免费久久 | 狠狠色婷婷丁香六月 | 啪啪小视频网站 | 国产亚洲精品精品精品 | 五月激情在线 | www.亚洲| 国产手机在线精品 | 欧美精品v国产精品v日韩精品 | 99色网站 | 亚洲精品乱码白浆高清久久久久久 | 中文字幕国内精品 | 精品国产乱码一区二 | 五月婷在线 | 免费成人在线观看 | 亚洲综合网 | 人人舔人人射 | 日韩黄色免费在线观看 | 伊人永久在线 | 欧美一区二区三区在线看 | 在线观看午夜 | 国产自在线观看 | 97超碰人人爱| 99免费在线| 五月天婷亚洲天综合网鲁鲁鲁 | 99久热在线精品视频 | 国产精品成人免费精品自在线观看 | 成人在线播放视频 | av网站免费看 | 国产资源中文字幕 | 国产一区二区三区视频在线 | 国产无遮挡猛进猛出免费软件 | 久久精彩 | 亚洲一二三久久 | 久久免费视频网 | 日韩 在线| 午夜av一区 | 久久九九久久九九 | 午夜 免费 | 日韩在线在线 | 成人a级大片 | 首页av在线 | 久久国产精品99久久久久久老狼 | 亚洲精品国偷自产在线99热 | 国产韩国日本高清视频 | 91夫妻视频 | www.69xx| 亚州精品一二三区 | 欧产日产国产69 | 91人人澡人人爽人人精品 | 欧美日韩首页 | 9ⅰ精品久久久久久久久中文字幕 | 日韩中文字幕网站 | 亚洲另类在线视频 | 在线观看电影av | 国产手机精品视频 | 日韩精品视| 久久国产电影 | 手机av观看| 天天插综合网 | 国精产品一二三线999 | 韩国在线一区二区 | 精品999 | 韩国一区二区av | 99热精品在线观看 | 日韩精品一区二区三区电影 | 免费观看久久久 | 免费99精品国产自在在线 | 亚洲精选久久 | 日韩色区 | av大全在线免费观看 | 91久久国产综合精品女同国语 | 91精品视频免费在线观看 | 91麻豆精品国产91久久久久久久久 | 一区二区视频欧美 | 搡bbbb搡bbb视频 | www.五月激情.com | 国产一区欧美日韩 | 天天干天天干 | 午夜性福利| 国产精品私人影院 | 国产精品尤物视频 | 久久久激情网 | 国产精品18久久久 | 日韩电影在线观看中文字幕 | 国产精品美女毛片真酒店 | 成人久久精品视频 | 久久成人欧美 | 成人av电影免费观看 | 在线观看第一页 | 日韩精品一区二区三区免费观看 | 国产色在线视频 | 免费黄在线观看 | 91精品无人成人www | 看v片| 国产精品久久久视频 | 日日干影院 | 91九色网站| 天天爽天天碰狠狠添 | 精壮的侍卫呻吟h | www.伊人色.com| 国产黄色高清 | 国产成人av免费在线观看 | 视频在线国产 | 成片人卡1卡2卡3手机免费看 | 狠狠操夜夜操 | 国产精品白浆视频 | 九月婷婷综合网 | 国产精品视屏 | 日韩在线 一区二区 | 中文字幕乱偷在线 | 蜜桃av人人夜夜澡人人爽 | 在线超碰av | 国产视频在线免费观看 | 色狠狠一区二区 | 欧美日韩中文在线观看 | 97色狠狠| 亚洲精品在线一区二区三区 | 国产精品欧美久久 | 在线免费黄色毛片 | 欧美午夜性 | 亚州精品一二三区 | 日本不卡一区二区 | 天天天综合 | 久久精品亚洲综合专区 | 色综合天天视频在线观看 | 精品国产精品久久一区免费式 | 在线视频精品 | 亚洲精品免费在线播放 | 一区二区三区在线观看 | 国产精品二区在线观看 | 友田真希av | 欧美大片在线观看一区 | www五月天婷婷 | 在线成人小视频 | 91精品网站| 天天操人人干 | 91人人视频在线观看 | 成年人视频在线免费播放 | 国内精自线一二区永久 | 亚洲精品视 | 国产丝袜美腿在线 | 成人动漫一区二区 | 久热国产视频 | 91爱爱视频 | 在线视频18在线视频4k | 操操综合网 | 天天操天天谢 | 天堂av高清 | 观看免费av | 国产精品不卡在线 | 国产一区欧美一区 | 91麻豆文化传媒在线观看 | 日韩在线视频在线观看 | 激情网综合 | 国产精品一区二区av | 成人av电影网址 | 9在线观看免费高清完整 | 欧美激情视频一二三区 | 国产精品va在线播放 | 伊人射| 天天干亚洲 | 美女精品| 色综合天天在线 | 欧美激情奇米色 | 一级片视频在线 | 500部大龄熟乱视频 欧美日本三级 | 欧美日本日韩aⅴ在线视频 插插插色综合 | 日韩欧美一区二区在线播放 | 69国产盗摄一区二区三区五区 | 曰韩在线| 国产精品网在线观看 | 色七七亚洲影院 | 成人国产精品免费 | 国产精品美女久久久久久2018 | 五月天久久综合 | 中文字幕日韩免费视频 | 色福利网站 | 美女网站色免费 | 亚洲国产小视频在线观看 | 一区二区三区在线免费播放 | 91porny九色在线播放 | 久久免费视频这里只有精品 | 国产精品自在欧美一区 | 一区二区电影网 | 在线观看视频你懂得 | 91精品视频导航 | 黄色网www| 91麻豆精品久久久久久 | 国产精品亚| 五月天丁香视频 | 青春草免费在线视频 | 免费观看的av网站 | 激情婷婷av | 国产一级黄 | 美女久久久久久久 | 在线观看麻豆av | 久久视频国产精品免费视频在线 | 伊人狠狠干| 日本不卡视频 | 黄色毛片大全 | 免费av片在线 | 香蕉久草| 在线观看一级视频 | 国产一区在线观看免费 | 久久婷婷国产色一区二区三区 | 国产精品一区二区三区视频免费 | 国产精品资源在线观看 | 亚洲精品短视频 | 久久99国产精品久久 | 成人免费电影 | 久久久久久片 | 欧美日韩精品影院 | 综合久久久 | 九九热re | 五月天婷婷狠狠 | 在线观看亚洲成人 | 色婷婷av一区二 | 国产一区二区三区免费在线观看 | 欧美在线视频免费 | 国产午夜精品av一区二区 | 黄色日视频 | 免费看黄的视频 | 亚洲精品高清在线 | 欧美日韩精品二区第二页 | 日日日操操 | 一级性视频 | av看片网址 | 天天摸天天舔天天操 | 久热香蕉视频 | 毛片区| 日韩精品一区二区三区中文字幕 | 国产精品色在线 | 亚洲成年人免费网站 | 亚洲国产播放 | 91精品一区二区三区久久久久久 | 欧美性久久久 | 波多野结衣在线观看一区 | 国产喷水在线 | 欧美激情综合五月 | 亚洲精品乱码久久久久久按摩 | 欧美 亚洲 另类 激情 另类 | 日韩精品免费一区二区三区 | 国产精品久久久久一区二区三区共 | 国产小视频免费在线网址 | 久久久五月天 | 久久久精品二区 | av在线影视 | 黄a网站 | 日日干夜夜操视频 | 最近日本字幕mv免费观看在线 | 国产精品久久久久久久久岛 | 日日干精品 | 97在线影视 | 久久精品2| 欧美日韩一区二区三区免费视频 | 国产丝袜网站 | www黄色软件| 国产精品久久免费看 | 国产色女人 | 国产一级精品视频 | 免费看国产精品 | 97视频免费在线看 | 精品成人在线 | 狠狠色综合欧美激情 | 亚洲无人区小视频 | 国产一区二区精品 | 亚洲成人网在线 | 成人亚洲免费 | 狠狠激情中文字幕 | 热久久免费视频 | 久久久精品99 | 日韩视频一区二区三区在线播放免费观看 | 中文字幕在线观看视频免费 | 亚洲成人中文在线 | 日韩成人中文字幕 | www.神马久久 | 成人午夜影院在线观看 | 亚洲闷骚少妇在线观看网站 | 香蕉精品视频在线观看 | 欧美另类美少妇69xxxx | 99久久国产免费,99久久国产免费大片 | 国产成人免费观看久久久 | 永久免费精品视频网站 | 日韩理论在线观看 | 99热九九这里只有精品10 | 日韩免费网站 | 亚洲综合欧美激情 | 99精品在线看| 免费观看丰满少妇做爰 | 久久黄色影视 | 成人久久电影 | 色综合小说 | 国产在线永久 | 成人av片免费观看app下载 | 992tv又爽又黄的免费视频 | 免费在线电影网址大全 | 91免费观看网站 | 久久九九网站 | 中文字幕刺激在线 | 五月天视频网站 | 国产日韩视频在线 | 国产三级国产精品国产专区50 | 久久精品一二三区 | 婷婷综合伊人 | 精品久久久久久国产偷窥 | 日韩精品第1页 | 色偷偷网站视频 | 久久免费片 | 久久夜视频| 久草在线费播放视频 | 亚洲闷骚少妇在线观看网站 | 天天干夜夜 | 欧美日韩在线精品 | 免费中文字幕视频 | 五月婷婷视频在线观看 | 免费高清男女打扑克视频 | 国产福利在线免费 | 国产91成人 | 99免在线观看免费视频高清 | 99国产精品一区 | 不卡的av中文字幕 | 射九九 | 国产精品一区二区三区在线看 | 东方av在线免费观看 | 国产免费观看av | 久久久久久97三级 | 亚洲成人动漫在线观看 | 精品国产免费人成在线观看 | 日韩另类在线 | 日韩免费网址 | 久久成人精品视频 | 久久一区二区三区超碰国产精品 | 992tv人人草 黄色国产区 | 亚洲一区免费在线 | 亚洲午夜精品久久久久久久久久久久 | 在线观看免费高清视频大全追剧 | 国产不卡精品 | 黄色一级网 | 国产女人免费看a级丨片 | 久久久久成人精品 | 亚洲最大免费成人网 | 国产精品成人免费一区久久羞羞 | 日本三级香港三级人妇99 | 97人人人人| 精品国产一区二区三区四区vr | 色婷婷免费 | 蜜臀av性久久久久蜜臀aⅴ涩爱 | 99精品在线看 | 色干干| 国产视频丨精品|在线观看 国产精品久久久久久久久久久久午夜 | 91视频在线免费观看 | 久草视频资源 | 欧美日韩中 | 天天鲁天天干天天射 | 又黄又爽又刺激的视频 | 久久系列 | 天天做天天爱天天爽综合网 | 在线观看视频在线 | 欧美精品一区二区三区四区在线 | 狠狠干婷婷 | 久久久影院一区二区三区 | 免费a级黄色毛片 | 午夜精品一区二区三区在线播放 | 久久免费美女视频 | av成人在线网站 | 国产成人777777 | 久久99精品国产99久久 | 国产一区二区三区在线 | 曰韩精品 | 亚洲电影自拍 | 色999五月色 | 深爱激情五月婷婷 | 久久久伦理 | 日韩理论在线视频 | 日韩精品久久中文字幕 | 天天操天天干天天 | 女人18精品一区二区三区 | 日韩免费看视频 | 91精品爽啪蜜夜国产在线播放 | 国产99久久久国产精品成人免费 | 日韩午夜在线观看 | 久久久久久蜜av免费网站 | 国产99中文字幕 | 国产一级免费播放 | 免费国产在线视频 | 国产一级大片免费看 | 国产在线v | 麻花豆传媒mv在线观看 | 在线国产专区 | 久久精品在线免费观看 | 免费福利片2019潦草影视午夜 | 狠狠色丁香久久婷婷综 | 色中色亚洲 | 午夜精品久久久久久久久久久久 | 精品免费一区 | 9797在线看片亚洲精品 | 91精品国产综合久久福利不卡 | 国产精品毛片一区二区 | 蜜桃视频精品 | 99久久精品国产毛片 | 激情久久一区二区三区 | 免费观看av网站 | 国产最新在线视频 | 91精品色| 国产手机在线视频 | 欧美大香线蕉线伊人久久 | 亚洲精品国产精品乱码在线观看 | 久草视频免费观 | 欧美激情视频一区二区三区免费 | 国产 日韩 中文字幕 | 亚洲成年人在线播放 | 香蕉视频久久久 | 色婷婷在线视频 | 午夜丁香视频在线观看 | 99视频在线| 日韩久久一区 | 久久伊人国产精品 | 日日夜夜噜 | 欧美,日韩 | 九九综合九九综合 | 免费视频一区二区 | 一区二区视频在线免费观看 | 9色在线视频| 国产精品99久久久 | 亚洲一区二区精品在线 | 五月婷婷激情六月 | 狠狠干天天射 | 国产成人免费在线观看 | 日韩视频免费在线观看 | 久草在线高清 | 免费网址在线播放 | 91久久国产综合精品女同国语 | 99久久er热在这里只有精品15 | 国产精品a久久 | 精品欧美小视频在线观看 | 美女网站在线 | 在线观看免费视频 | 六月丁香综合 | 国产精品99久久久久久人免费 | 超碰人人草人人 | 一级黄色片在线 | 色婷婷亚洲综合 | 亚洲精品 在线视频 | 午夜在线看片 | 五月婷婷另类国产 | 黄色毛片在线 | 精品久久久久一区二区国产 | 久久精品在线视频 | av成人在线网站 | 久久久亚洲麻豆日韩精品一区三区 | 成人久久18免费 | 人人草在线视频 | 婷婷丁香国产 | 91久久国产露脸精品国产闺蜜 | 夜夜躁狠狠躁日日躁视频黑人 | 九九热精品在线 | 亚洲天堂精品视频在线观看 | 久久99中文字幕 | 国产免费嫩草影院 | 97国产在线| 99久热在线精品视频成人一区 | 免费激情网 | a久久久久| 五月天色中色 | 最近中文国产在线视频 | 91尤物国产尤物福利在线播放 | 色综合久 | 五月婷婷狠狠 | 亚洲精品一区二区在线观看 | www操操 | 免费视频一区二区 | 最新日韩精品 | 五月婷婷开心 | 六月丁香婷婷久久 | 中文字幕在线观看视频免费 | 天天色天天射天天综合网 | 欧美在线观看视频一区二区三区 | 国产97免费 | 久久综合色一综合色88 | 亚洲国产精品va在线看黑人动漫 | 国产黄大片 | 天堂va在线高清一区 | 久久久国产在线视频 | 丁香色婷婷 | 夜夜操狠狠干 | 欧美福利久久 | 国产精品嫩草影院99网站 | 亚洲精品66 | 国产成人久久精品 | 黄色的视频 | 在线99热 | 一区二区三区在线免费观看 | av7777777| 国产69久久久欧美一级 | 亚洲精品小区久久久久久 | 中文字幕第一页在线视频 | 91人人澡人人爽人人精品 | 高清不卡一区二区三区 | 亚洲国产成人精品久久 | 国产一区二区精品久久91 | 久久久蜜桃 | 亚洲精品乱码白浆高清久久久久久 | 夜夜操狠狠干 | 狠狠操狠狠插 | 玖玖爱在线观看 | 黄网站污 | 国际精品网 | 香蕉视频免费看 | 国产午夜麻豆影院在线观看 | 国产精品视频在线看 | 在线观看免费日韩 | 国产精品小视频网站 | av中文在线影视 | 天天曰天天爽 | 国产香蕉视频 | 色com| 国产v在线 | 一区av在线播放 | av中文字幕电影 | 青青色影院 | 久久精品视频观看 | 亚洲精品日韩在线观看 | 日韩高清精品免费观看 | 久久国产成人午夜av影院潦草 | 青青久草在线 | 色资源二区在线视频 | 免费观看全黄做爰大片国产 | 手机在线欧美 | 亚洲精品成人网 | 中文字幕在线视频国产 | 国产精品久久久久久久7电影 | 蜜桃av久久久亚洲精品 | 18网站在线观看 | 国产1级毛片 | 日本中文字幕在线一区 | avwww在线| 日韩在线国产 | 综合色在线观看 | 三级av小说| 精品免费久久久久久 | 四虎永久视频 | 丰满少妇麻豆av | 91中文视频 | 亚洲少妇xxxx | 欧美日韩国产三级 | 日韩av电影免费观看 | 日韩精品电影在线播放 | 99免费在线| 就操操久久| 国产亚洲人成网站在线观看 | 久久久 激情 | av免费成人 | 亚洲国产日韩欧美在线 | 中文字幕乱视频 | 99在线视频免费观看 | 午夜在线日韩 | 96精品高清视频在线观看软件特色 | 天天射天天干天天爽 | 成人av免费在线 | 成人午夜片av在线看 | 一区二区三区福利 | 69性欧美 | 中文字幕日韩电影 | 五月婷婷欧美视频 | 日韩色爱| 久久ww| 久草99| 成人黄色中文字幕 | 99精品欧美一区二区三区 | 99tvdz@gmail.com| 国产高清在线不卡 | 一区精品在线 | 最近中文字幕免费av | www久久99| 中文字幕精品久久 | 日本公妇在线观看高清 | 久草在线免费在线观看 | 国产精品久久99精品毛片三a | 91看国产| 色99色| 99国产在线视频 | 波多野结衣一区二区三区中文字幕 |