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

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 运维知识 > 数据库 >内容正文

数据库

openGauss数据库源码解析系列文章——存储引擎源码解析(四)

發布時間:2023/12/8 数据库 59 豆豆
生活随笔 收集整理的這篇文章主要介紹了 openGauss数据库源码解析系列文章——存储引擎源码解析(四) 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

上一篇我們詳細講述“3. astore元組多版本機制”、“4.astore訪存管理”及“5.astore空間管理和回收”相關內容。本篇我們將繼續為小伙伴們帶來“4.2.4 ustore”的詳細介紹。

4.2.4 ustore

ustore屬于In-place Update更新模式,中文意思為:原地更新,是openGauss內核新增的一種存儲模式。openGauss內核當前使用的行引擎采用的是Append Update(追加更新)模式,該模式在INSERT、DELETE、HOT UPDATE(頁面內更新)的場景下有較好的表現。但對于非HOT UPDATE場景,垃圾回收不夠高效。
In-place Update存儲模式提供“原地更新”能力,主要思路是將最新版本的“有效數據”和歷史版本的“垃圾數據”分離存儲。將最新版本的“有效數據”存儲在數據頁面上,而單獨開辟一段undo(回滾)空間,用于統一管理歷史版本的“垃圾數據”,因此數據空間不會由于頻繁更新而膨脹,垃圾回收效率更高。通過NUMA-aware的undo子系統設計,使得undo子系統在多核平臺上高效擴展。同時通過對元組和數據頁面結構的重新設計,減少存儲空間的占用。采用多版本索引技術,解決索引膨脹問題,徹底去除autovacuum(垃圾清理線程)機制,提升存儲空間的回收復用效率。

1. 整體框架及代碼概覽

數據庫中數據處理的本質是在保證ACID的基礎上支持盡量高的并發查詢。這種狀況下,并發控制、頁面多版本控制以及頁面存儲結構相互耦合在一起,數據庫存儲引擎需要進行整體設計從而在高并發的狀況下保證各個事務處理看到類似串行執行的效果。
在整個技術體系中多版本控制用來提升讀寫并發能力,按照多版本排列方式可以分為兩類。
(1)Oldest to New,即版本按照從最老到最新的方式進行鏈接,當一個事務訪問該元組時,先看到這個元組最老的版本,同時使用對應的可見性判斷機制,看是否是自己可見的版本,如果不是則沿著版本鏈條繼續往后看較新的版本是不是自己需要的。
(2)Newest to Old,即版本按照從最新到最老的方式進行連接,當一個事務訪問該元組時,先看到這個元組最新的版本,同時使用對應的可見性判斷機制,看是否是自己可見的版本,如果不是則沿著版本鏈條繼續往后看較老的版本是不是自己需要的。
在上面的描述中又引出一個設計點,如何組織新老數據,有如下幾種方式。
(1) 將新數據和老數據放在同樣的頁面內,即每個數據頁內放置著各個元組的新老數據,在需要進行不可見數據版本回收的時候需要遍歷所有的頁面。
(2) 將最新數據和老數據分離存儲,在實際的數據頁面內放置最新版本數據,所有的老版本數據都集中存儲,新版本數據通過一個指針指向老版本所在的數據區域,當進行不可見老版本數據回收的時候只要掃描老版本集中存放的位置即可。
當新老數據分別存儲的時候又引出第三個設計點,在對同一個頁面或者元組反復讀取時,是否要還原對應的頁面在數據緩沖區中,這個設計點有如下幾種方式。
(1) 訪問舊元組所在的頁面時,還原該頁面,并將該頁面的舊版本放入數據緩沖區中,節省一定時間內其他線程多次訪問該版本頁面帶來的合成開銷。弊端是占用更大的內存空間,同時緩沖區淘汰管理在原始LRU(Least Recently Used,最近最少使用算法)基礎上同時要考慮頁面版本。這種方式對應PCR(Page Consistency Read,頁面一致性讀),其本質的設計理念是空間換時間。
(2) 訪問元組時,沿著版本鏈還原該元組,直到找到自己對應的版本。這種方式對于短時間訪問沖突不高的場景能夠降低內存使用,但如果短時間內高頻訪問一個頁面內的元組,則每次都會遍歷版本鏈造成訪問效率低下。這種方式對應RCR(Row Consistency Read,行一致性讀)。
按照上面的描述,整個多版本控制設計分為三個維度,如圖4-10、表4-15所示。

圖4-10 多版本控制設計維度

表4-15 多版本控制設計維度

維度備選
版本存儲方式集中存儲、分離存儲
版本鏈組織方式Oldest to New、Newest to Old
老版本管理方式1、RCR,2、PCR

當前openGauss在版本存儲方式、版本鏈組織方式上的設計選擇是集中存儲 + Oldest to New,在清理數據舊版本時需要遍歷所有的頁面找到不可見的元組版本然后清除。商用及開源的常見數據庫的多版本控制設計三維度選擇如表4-16所示。
表4-16 當前數據庫多版本控制設計選擇

數據庫

架構設計選擇

版本存儲方式

版本鏈組織方式

老版本管理方式

常見數據庫

分離存儲

Newest to Old

PCR

集中存儲

Oldest to New

RCR

分離存儲

Oldest to New

RCR

不同的多版本控制設計都不能做到盡善盡美,都有些不足之處,相關的缺點如下。
(1)多核系統上擴展性較差,不支持多核處理器的NUMA感知;
(2)依賴于Vacuum進行老版本回收,后臺線程定期清理;
(3)缺乏對索引多版本,全局索引、閃回等功能的支持;
(4)PCR管理方式,內存管理開銷較大。
openGauss的ustore存儲模式最大程度結合各種設計的優勢,在多版本管理上的架構設計采取的組合如表4-17所示。
表4-17 ustore在多版本管理上的架構設計

維度

架構設計選擇

版本存儲方式

分離存儲

版本鏈組織方式

Newest to old

老版本管理方式

PbRCR(Page Based RCR,基于頁面的行一致性讀)

同時為了事務能夠跨存儲格式查詢,并復用現有備份、恢復、升級等能力,openGauss定義如下的融合引擎架構設計原則。
(1) 一套并發控制系統。
(2) 一套系統表管理系統。
(3) 一套日志管理系統。
(4) 一套鎖管理系統。
(5) 一套恢復系統。
ustore架構如圖4-11所示。

ustore和astore共用事務管理、并發控制、緩沖區管理、檢查點、故障恢復管理與介質管理器管理。ustore主要功能模塊如表4-18所示。

表4-18 ustore主要功能模塊

模塊

說明

代碼位置

ustore表存取管理

向上對接SQL引擎,提供對ustore表的行級查詢、插入、刪除、修改等操作接口,向下根據ustore表頁間、頁內結構,以及ustore表元組結構,完成對ustore表文件的遍歷和增刪改查操作

主要在“src/gausskernel/storage/access/ustore”目錄(單表文件管理)下

ustore索引存取管理

向上對接SQL引擎,提供對索引表的行級查詢、插入、刪除等操作接口,向下根據索引表頁間、頁內結構,以及索引表元組結構,完成對指定索引鍵的查找和增刪操作

抽象框架代碼在“src/gausskernel/storage/access/ubtree”目錄下

ustore表頁面結構

包括ustore表元組在頁面內的具體組織形式,在頁面內插入元組操作、頁面整理操作、頁面初始化操作等

主要代碼在“src/gausskernel/storage/access/ustore/knl_upage”目錄中

ustore表元組結構

包括ustore表元組的結構、填充、解構、修改、字段查詢、變形等操作

主要代碼在“src/gausskernel/storage/access/ustore/knl_utuple.cpp”文件中

Undo記錄結構

包括undo記錄的結構、填充、編碼、解碼等操作

主要代碼在“src/gausskernel/storage/access/ustore/undo”目錄中

多版本索引

包括 ustore 專用多版本索引 ubtree 的頁面結構、查詢、修改、可見性檢查、垃圾回收等模塊

主要代碼在“src/gausskernel/storage/access/ubtree”目錄中

2. 頁面元組結構

1) 元組結構

本節介紹行存儲引擎ustore表的頁面元組結構。

元組結構的定義如下:

typedef struct UHeapDiskTupleData {ShortTransactionId xid;uint16 td_id : 8, locker_td_id : 8;uint16 flag;uint16 flag2;uint8 t_hoff;uint8 data[FLEXIBLE_ARRAY_MEMBER]; } UHeapDiskTupleData;

該結構體只是元組頭部的定義,真正的元組內容跟在該結構體之后,距離元組頭部起始處的偏移由t_hoff成員保存。上面元組頭部結構體部分成員信息同時也構成了該元組的系統字段(字段序號小于0的那些字段)。對各個結構體成員的含義說明如下。
(1) flag,元組屬性掩碼。包含是否有空字段標記、是否有外部TOAST標記、是否有變長字段標記、指定的事務槽位是否已被重復使用標記,以及更新、刪除、鎖等標記。
(2) flag2,元組另一個屬性掩碼。包含元組中字段個數。
(3) t_hoff,元組數據距離元組頭部結構體起始位置的偏移。
(4) data,字段的NULL值bitmap,每個字段對應一個bit位,因此是變長數組。
ustore元組頭部比astore元組頭部小一半,因此在相同大小的頁面上,ustore可以放置更多的元組。
在內存中,上述元組結構體使用時被嵌入在一個更大的元組數據結構體中,除了保存元組內容的disk_tuple成員之外,其他的成員保存了該元組的一些其他系統信息,并構成了該元組剩余的一些系統字段內容,定義如下:

typedef struct UHeapTupleData {uint32 disk_tuple_size;uint1 tupTableType = UHEAP_TUPLE;uint1 tupInfo;int2 t_bucketId; ItemPointerData ctid;Oid table_oid;TransactionId t_xid_base;TransactionId t_multi_base;UHeapDiskTupleData* disk_tuple; } UHeapTupleData;

該結構體幾個主要成員的含義如下。
(1) disk_tuple_size,元組長度。
(2) ctid,元組所在頁面號和頁面內元組指針下標。
(3) table_oid,該元組屬主表的OID。
常用的元組操作接口和說明如表4-19所示。

表4-19 常用的元組操作接口

函數名操作含義
UHeapFormTuple利用傳入的、各個元組字段的值數組,生成一條完整的元組,一般用于插入操作
UHeapDeformTuple利用傳入的完整元組以及各個字段的類型定義,解構各個字段的值,生成值數組,一般用于更新前的準備工作
UHeapFreetuple釋放一條元組對應的內存空間
UHeapCopyTuple復制一條完整的元組,包括元組頭和元組內容
UHeapSlotGetAttr獲取一條元組中指定的用戶或系統字段值
UHeapGetSysAttr獲取一條元組中指定的系統字段值
UHeapCopyHeapTuple從ustore槽位構造一條astore元組
UHeapToHeap將一條ustore元組轉換為一條astore元組
HeapToUHeap將一條astore元組轉換為一條ustore元組

2) 頁面結構
ustore與astore相同,在openGauss中也使用默認的8kB頁面。其結構如圖4-12所示。

圖4-12 ustore引擎頁面結構示意圖
在一個頁面中,頁面頭部分對應的UHeapPageHeaderData結構體存儲了整個頁面的重要元信息。UHeapPageHeaderData之后有一個共享的頁內事務目錄(Transaction Directory,TD),對應元組指針變長數組。元組指針變長數組的每個數組成員存儲了頁面中從后往前的、每個元組的起始偏移和元組長度。如圖4-12所示,真正的元組內容從頁面尾部開始插入,向頁面頭部擴展;相應地,TD插槽目錄與記錄每條元組的元組指針從頁面頭定長成員之后插入,往頁面尾部擴展。這樣整個頁面中間就會形成一個空洞,以供后續插入的元組和元組指針使用。每一個ustore表里的一條具體元組都有一個全局唯一的邏輯地址(和astore表里的元組相同),它由元組所在的頁面號和頁面內元組指針數組下標組成。
頁面頭具體結構體定義如下:

typedef struct UHeapPageHeaderData {PageXLogRecPtr pd_lsn;uint16 pd_checksum;uint16 pd_flags;uint16 pd_lower;uint16 pd_upper;uint16 pd_special;uint16 pd_pagesize_version;uint16 potential_freespace;uint16 td_count;TransactionId pd_prune_xid;TransactionId pd_xid_base; TransactionId pd_multi_base;uint32 reserved; } UHeapPageHeaderData;

其中各個成員的含義如下。
(1) pd_lsn:該頁面最后一次修改操作對應的預寫日志位置的下一位,用于檢查點推進和保持恢復操作的冪等性。
(2) pd_checksum:頁面的CRC校驗值。
(3) pd_flags:頁面標記位,用于保存各類頁面相關的輔助信息,如頁面是否有空閑的元組指針、頁面是否已滿等。
(4) pd_lower:頁面中間空洞的起始位置,即當前已使用的元組指針數組的尾部。
(5) pd_upper:頁面中間空洞的結束位置,即下一個可以插入元組的起始位置。
(6) pd_special:頁面尾部特殊區域的起始位置。該特殊位置位于第一條元組記錄和頁面結尾之間,用于存儲一些變長的頁面級元信息,如索引的輔助信息等。
(7) pd_pagesize_version:頁面的大小和版本號。
(8) potential_freespace:頁面中已被刪除和更新的元組的潛在空間。
(9) td_count:共享的頁內事務信息描述插槽的數量。
(10) pd_prune_xid:頁面清理輔助事務號(64位),通常為該頁面內現存最老的刪除或更新操作的事務號,用于判斷是否要觸發頁面級空閑空間整理。
(11) pd_xid_base:該頁面內所有元組的基準事務號(64位)。該頁面所有元組實際生效的64位XID事務號由pd_xid_base(64位)和元組頭部的XID成員(32位)相加得到。
(12) pd_multi_base:類似pd_xid_base。當對元組加鎖時,會將持鎖的事務號寫入元組中,該64位事務號由pd_multi_base(64位)和元組頭部的XID(32位)相加得到。
頁面的主要管理接口如表4-20所示。

表4-20 頁面管理接口函數

函數名操作含義
UPageInit初始化一個新的ustore頁面
UPageAddItem在頁面中插入一條新的元組
UHeapPagePruneOptPage頁面空閑空間整理

為了節省每個元組存儲空間,元組頭部UHeapDiskTupleData采用32位元組XID的組合設計方式。64位的pd_xid_base和pd_multi_base儲存在頁面上,元組上儲存32位的XID。頁面上pd_xid_base和pd_multi_base也需要通過額外的邏輯進行維護:同一個頁面中所有元組實際的64位XID,一定要在pd_xid_base和pd_xid_base+232之間,所以如果新寫入的事務號和頁面上現有任意一個元組的XID事務號差距已經超過232,那么需要嘗試對現有元組進行基線移位操作,更新pd_xid_base和pd_multi_base。
3)事務目錄
事務目錄是一種常用的共享資源。它可以為數據頁上的元組(tuple)鏈接相應的事務表(Transaction Table)及undo子系統中的undo頁面。數據庫中的每個表可以自定義事務目錄的數量,并可以復用那些已完成事務占據的事務目錄。
每個數據頁默認會有4個事務目錄。根據并發需求的不同,事務目錄的數量可設置為2到128之間的任意值。在使用CREATE TABLE命令創建表時添加了一個新的選項INIT_TD以聲明所需的事務目錄數量:

CREATE TABLE t1 ( c1 integer; c2 boolean; ) WITH (INIT_TD=16);

當需要為新事務目錄留位置時,系統會先查找當前頁面中是否有空事務目錄。若無空事務目錄,系統將遍歷事務目錄列表來尋找可以復用的條目。條目是否可以復用取決于與該條目關聯的事務的狀態。
通常可以復用那些與已凍結或已中止的事務關聯的事務目錄。
(1) 對于已經凍結的XID,并復用該事務目錄。
對于astore而言,凍結的XID代表著事務在所有的會話中都已經不再活躍。
而在ustore中,僅當一個事務創建的所有的回滾記錄都被丟棄后,或者說沒有其他的Snapshot需要再觀察該事務創建的元組歷史版本(tuple version)時,才將該XID視為凍結。ustore中的undo回收進程會維護一個oldestXidInUndo變量,系統將通過比較XID與該變量來確定XID是否含有回滾記錄。如果XID < oldestXidInUndo,代表所有該XID產生的回滾記錄都已經被丟棄。
(2) 對于已中止的事務,在該事務被回滾后,系統才會復用相應的事務目錄條目。
(3) 對于已提交的事務,系統將不會無效化回滾記錄地址,這樣可以保證undo鏈的完整性。
當沒有事務目錄可以復用時,事務目錄將會自動擴容以容納更多的條目。需注意的是,事務目錄的后面跟隨著元組指針區,在擴展時,首先需要將row pointer array向右挪動來騰出空間。擴展后,新的事務目錄條目將會在先前的事務目錄條目之后依序添加。設計上,允許事務目錄的容量最多擴至頁面大小的約25%,即約100個事務目錄(在8kB大小的頁面中,約20Bytes/事務目錄)。目前,系統將以每次增加兩個事務目錄的方式逐步擴容,最多擴至128個事務目錄。ustore暫不支持收縮事務目錄空間。
在擴容時,可以增加的總條目數也取決于當前頁面中的可用空間。有時,頁面中的總剩余空間并不能支持事務目錄的擴容。此時若當前操作為INSERT或MULTI-INSERT,事務將會索取一個新的頁面來進行操作。若操作為UPDATE或DELETE,事務將等待10毫秒后重試獲取事務目錄。Lock timeout設置可以控制獲取事務目錄的最大等待時間。在多由短事務組成的工作負載中,等待是可以接受的。
PG stats會報告事務目錄等待等信息,以方便監測系統及描述工作負載。
事務目錄申請的過程(UHeapPageReserveTransactionSlot函數)如圖4-13所示。

圖4-13 事務目錄申請處理流程
如果當前事務需要申請一個新的事務目錄,且系統中不存在空的事務目錄時,系統會遍歷所有事務目錄并尋找可復用的事務目錄。
(1) 首先系統會遍歷事務目錄,尋找XID < oldestXidInUndo的事務目錄。這些條目將被視為已凍結。
(2) 接著系統會遍歷目標頁面上的元組。
① 系統把已刪除的元組標記為死亡,其余的標記為閑置。
② 如果系統發現元組還在活躍狀態,且相應的TD條目存在于步驟(1)給出的凍結列表之中,系統會把該事務目錄設置為UHEAPTUP_SLOT_FROZEN(凍結)。
③ 設置為凍結之后,事務目錄中的XID及Undo指針會被無效化。
(3) 如果上述的凍結操作并未產生可用的槽位,系統會遍歷事務目錄并尋找與已提交或已中止事務關聯的條目。這些條目在滿足一定條件的狀況下可被復用。
(4) 遍歷目標頁面上的元組。
① 如果系統發現元組關聯的事務目錄存在于步驟(3)給出的已提交列表中,系統就把該TD條目的flag設為UHEAP_INVALID_XACT_SLOT(無效)。
② 此外,這些事務目錄的XID被重設為無效XID。但為了維護undo鏈的完整,undo指針將被保留。
(5) 如果并未找到與已提交事務關聯的事務目錄,最后將尋找與已中止事務關聯的事務目錄。
(6) 遍歷與已中止事務關聯的事務目錄:對于每個事務目錄,沿著undo鏈執行相關的undo操作。
(7) 如果并未找到事務目錄,擴展事務目錄。
(8) 返回結果。

3. 回滾段設計與MVCC

1) 回滾段
舊版本數據會集中在回滾段的undo目錄中,為了減少讀寫沖突,舊版本數據(回滾記錄)采用追加寫的方式寫入數據目錄的undo目錄下。這樣舊版本數據的讀取和寫入不會發生沖突,同一個事務的舊版本數據也會連續存放,便于進行回滾操作。為了減少并發寫入時的競爭,undo目錄空間被劃分成多個邏輯區域(UndoZone,回滾段邏輯區域)。線程會在自己的邏輯區域上進行分配,與其他線程完全隔離,從而寫入舊數據分配空間時就不會有額外的鎖開銷。UndoZone還可以按照CPU的NUMA核進行劃分,每個線程會從當前的NUMA核上的UndoZone進行分配,進一步提升分配效率。在分配undo空間時會按照事務粒度進行記錄,舊版本數據一旦確認沒有事務進行訪問,就會進行回收。
為了在回滾段的空間尋址,回滾記錄使用8字節的指針來進行尋址,如圖4-14所示。

圖4-14 回滾記錄尋址指針
其中各個字段的含義如下:
(1) zoneId:占用20bit,表示邏輯區域的ID。
(2) blockId:占用31bit,表示塊號,默認為8k。
(3) offset:占用13bit,表示塊內偏移。
舊版本的數據采用回滾記錄的格式存入回滾段中,其中回滾記錄的格式如下所示:

Class UndoRecord { … UndoRecordHeader whdr_;UndoRecordBlock wblk_;UndoRecordTransaction wtxn_;UndoRecordPayload wpay_;UndoRecordOldTd wtd_;UndoRecordPartition wpart_;UndoRecordTablespace wtspc_; StringInfoData rawdata_; }

其中,除了rawdata_代表了舊版本數據,其他成員均為結構體,下面對每個結構體分別進行說明。
whdr_成員由下面的結構組成:

typedef struct {TransactionId xid; CommandId cid;Oid reloid;Oid relfilenode;uint8 utype;uint8 uinfo; } UndoRecordHeader;

各個字段的含義如下。
(1) xid:生成此回滾記錄的事務ID,用于檢查事務的可見性。“2)MVCC”小節有介紹。
(2) CID(Command ID,命令ID):生成此回滾記錄的命令ID,用于判斷可見性。
(3) reloid:relation對象的ID,回滾時需要。
(4) relfilenode:relfilenode對象的ID,回滾時需要。
(5) utype:操作類型,像UNDO_INSERT、UNDO_DELETE、UNDO_UPDATE等。
(6) uinfo:控制字段,用來判斷后續的結構是否存在,用來減少回滾記錄的占用空間。
wblk_成員由下面的結構組成:

typedef struct {UndoRecPtr blkprev;BlockNumber blkno;OffsetNumber offset; } UndoRecordBlock;

(1) blkprev:指向同一個block前一條回滾記錄,用于回滾和事務可見性。“2)MVCC”小節有介紹。
(2) blkno:block number(塊號)。
(3) Offset:修改的tuple在row pointer中的偏移。
wtxn_成員由下面的結構組成。

typedef struct {UndoRecPtr prevurp; } UndoRecordTransaction;

prevurp:當一個事務的回滾記錄跨越兩個UndoZone時,后續的回滾記錄使用此指針指向前一條回滾記錄。
wpay_成員由下面的結構組成。

typedef struct { UndoRecordSize payloadlen; }

payloadlen:rawdata_的長度。
wtd_成員由下面的結構組成。

typedef struct {TransactionId oldxactid; } UndoRecordOldTd;

oldxactid:舊版本數據里事務目錄的事務ID。
wpart_成員由下面的結構組成。

typedef struct {Oid partitionoid; } UndoRecordPartition;

partitionoid:分區表的分區對象OID。
wtspc_成員由下面的結構組成。

typedef struct {Oid tablespace; } UndoRecordTablespace;

tablespace:表空間的OID。
回滾段使用事務目錄來記錄每個事務分配的undo空間,便于事務回滾和回收。事務發生回滾時,會讀取事務目錄中記錄的undo空間的起始位置,再讀取undo空間中的回滾記錄進行回滾操作,其中回滾記錄中的字段如下:

class TransactionSlot {TransactionId xactId_;UndoRecPtr startUndoPtr_;/*事務分配的undo空間開始*/UndoRecPtr endUndoPtr_;/*事務分配的undo空間結束*/uint8 info_;/*標記:如事務回滾狀態*/Oid dbId_;/*數據庫對象ID*/ }

(1) xactId:事務ID。
(2) startUndoPtr:事務分配的undo空間開始位置。
(3) endUndoPtr:事務分配的undo空間結束位置。
(4) info_:標記值,如事務回滾狀態。
(5) dbId:數據庫對象ID。
回滾段提供分配undo空間和更新事務目錄的接口,主要接口如表4-21所示。

表4-21 回滾段主要接口

接口名

含義

AllocateUndoSpace

為回滾記錄分配undo空間

UpdateTransactionSlot

更新事務目錄

以ustore的刪除操作為例,undo空間分配流程如下。
(1) UheapDelete作為ustore的刪除接口,會調用UHeapPrepareUndoDelete函數準備回滾記錄(undo record)。UHeapPrepareUndoDelete函數會填充回滾記錄的各個字段(其中舊數據會設置到回滾記錄的raw data字段上),再調用PrepareUndoRecord函數分配undo空間。PrepareUndoRecord函數調用“undo::AllocateUndoSpace”函數分配undo空間,再讀取對應的回滾記錄到緩沖池中。AllocateUndoSpace函數不僅會為回滾記錄分配空間(使用“UndoZone::AllocateSpace”函數),如果是事務的第一條回滾記錄,還會調用“UndoZone::AllocateSlotSpace”函數為事務目錄分配空間。AllocateSpace函數會進行判斷,如果回滾記錄超過當前undo file的大小,就擴展當前的undo file,AllocateSlotSpace函數的邏輯類似。
(2) UheapDelete函數調用InsertPreparedUndo函數,將準備好的回滾記錄追加寫到緩沖池中的回滾段頁面。
(3) UheapDelete函數調用UpdateTransactionSlot,記錄下該事務分配的undo空間起始、事務ID、數據庫ID。如果是事務的第一次更新,會從事務目錄空間分配新的事務目錄再進行更新。
undo空間需要回收回滾記錄來保證undo空間不會無限膨脹,一旦事務id小于當前快照中最小的Xmin(oldestXmin),回滾記錄中的舊版本數據就不會被訪問,此時就可以對回滾記錄進行回收。
如前述描述undo空間中的回滾記錄按照事務ID遞增的順序存放在UndoZone中,回收的條件如下所示。
(1) 事務已經提交并且小于oldestXmin的undo空間可以回收。
(2) 事務發生回滾但已經完成回滾的undo空間可以回收。

圖4-15 undo回收過程

如圖4-15所示,UndoZone1中回收到小于oldestXmin的已提交事務16068,UndoZone2中回收到16050,UndoZone m回收到16056。而UndoZone n回收到事務16012,而事務16014待回滾但未發生回滾,因此UndoZone n回收事務id上限只到16014。其他zone的上限是oldestXmin,oldestXidInUndo會取所有undozone上的上限最小值,因此oldestXidInUndo等于16014。undo回收主要函數如表4-22所示。

表4-22 undo回收主要函數

函數名

操作含義

UndoRecycleMain

回收線程的入口函數,會在每個zone上調用RecycleUndoSpace函數

RecycleUndoSpace

按照前述條件回收undo空間,記錄日志

2) MVCC
ustore的可見性檢查和astore類似,將快照CSN和元組刪除和插入事務的CSN進行比較,判斷元組是否可見。ustore和astore使用同一套事務管理機制和快照管理機制。
ustore和astore最大的區別在于astore會在頁面上保留舊版本數據,而ustore在將舊版本數據放到回滾段統一存放。在需要獲取舊版本數據時,astore可以直接從tuple的頭部讀取到元組的插入和刪除的事務號(XID),來判斷元組的可見性。但是ustore需要從回滾段里讀取舊版本的事務信息,來判斷舊版本是否可見。由于從回滾段中讀取舊版本數據存在相對昂貴的開銷,ustore通過一系列的優化手段來避免從回滾段中讀取舊版本數據。
ustore在獲取元組時,會先檢查對應的事務目錄。事務目錄分成有效和無效兩種。當事務目錄是有效的,ustore直接就會得到元組上最新的事務。
如果事務目錄被凍結(FROZEN),意味著元組已經在所有的事務中都會可見。如果事務目錄中的事務id小于oldestXidInUndo,意味著元組已經足夠舊在所有事務中都可見。同時會把事務目錄置成凍結,來加速后續的查詢。
如果元組被標記有一個無效事務目錄,意味著修改元組的事務已經提交,并且比當前的事務目錄中的事務舊。此時ustore會使用事務目錄中的事務進行可見性判斷。如果可見,意味著修改元組的事務更已經可見,就不需要從undo目錄中再讀取事務信息。

圖4-16 元組查詢過程
元組不可見的場景,ustore會從undo目錄中讀取回滾記錄中的舊版本數據查找元組。例子如圖4-16所示。查找tbl表中c1=1的數據項,從索引中讀取到數據項位于block 1和offset 2,使用UHeapTupleFetch函數再從block 1中查詢到元組,需要判斷該元組的可見性。
(1) 從元組的TD讀到ITL2,和astore類似,根據CSN的大小,判斷TD2中的XID不可見,需要使用GetTupleFromUndo函數讀取回滾記錄。
(2) GetTupleFromUndo函數調用GetTupleFromUndoRecord函數讀取回滾記錄,使用InplaceSatisfyUndoRecord函數判斷其中的block 1和offset 2是滿足要求的元組。但是XID=1610可以判斷出當前頁面的tuple不可見,ustore繼續查詢更老的版本。由于舊元組的TD 1和當前的TD 2不一致,使用UHeapUpdateTDInfo從TD 2 undo鏈條進行切換,根據舊元組的TD 1找到當前的undo指針找到前一次修改。
(3) 再次讀取到回滾記錄,其中的block 1和offset 1并非要找的元組,ustore繼續查詢更老的版本,根據blkprev指針讀取前一次修改。
(4) 讀取到回滾記錄,其中的block 1和offset 3并非要找的元組,ustore繼續查詢更老的版本,根據blkprev指針讀取前一次修改。
(5) 讀取到回滾記錄,其中的block 1和offset 2是要求的元組,ustore判斷可見性。根據CSN的大小,事務可見。因此前一次命中的元組可見,即(1, abc)可見,因此查找到元組的c2等于abc。

4. 多版本索引

在openGauss中實現了多版本索引ubtree,是專用于ustore的B-Tree索引變種,相比原有的B-Tree索引有如下差異點。
(1) 支持索引數據的多版本管理及可見性檢查,能夠自主鑒別舊版本元組并進行回收,同時索引層的可見性檢查使得索引掃描(Index Scan)及僅索引掃描(Index Only Scan)性能有所提升。
(2) 在索引插入操作之外,增加了索引刪除操作,用于對被刪除或修改的元組對應的索引元組進行標記。
(3) 索引按照key + TID的順序排列,索引列相同的元組按照對應元組的TID作為第二關鍵字進行排序。
(4) 添加新的可選頁面分裂策略“insertpt”。
ubtree實現了索引訪問接口所要求的全部接口,如表4-23所示:

表4-23 ubtree訪問接口函數

接口名稱

對應函數

接口含義

aminsert

ubtinsert

插入一個索引元組

ambeginscan

ubtbeginscan

開始一次索引掃描

amgettuple

ubtgettuple

獲取一個索引元組

amgetbitmap

ubtgetbitmap

通過索引掃描獲取所有元組

amrescan

ubtrescan

重新開始一次索引掃描

amendscan

ubtendscan

結束索引掃描

ammarkpos

ubtmarkpos

標記一個掃描位置

amrestpos

ubtrestpos

恢復到一個掃描位置

ammerge

ubtmerge

合并多個索引

ambuild

ubtbuild

建立一個索引

ambuildempty

ubtbuildempty

建立一個空索引

ambulkdelete

ubtbulkdelete

批量刪除索引元組

amvacuumcleanup

ubtvacuumcleanup

索引后置清理

amcanreturn

ubtcanreturn

是否支持 Index Only Scan

amcostestimate

ubtcostestimate

索引掃描代價估計

amoptions

ubtoptions

索引選項

此外,還實現了新增的的索引刪除函數UBTreeDelete。
1) 索引頁面組織
多版本索引層次結構與B-Tree索引基本相同,非葉子節點與B-Tree索引保持一致,僅頁尾的Special字段有所不同。ubtree中的Special字段UBTPageOpaqueDataInternal如下所示:

typedef struct UBTPageOpaqueDataInternal {…… /* 以上部分與BTPageOpaqueDataInternal一致 */TransactionId last_delete_xid; /* 記錄頁面上最后一次刪除事務的 XID */TransactionId xid_base; /* 頁面上的 xid-base */int16 activeTupleCount; /* 頁面上活躍元組計數 */ } UBTPageOpaqueDataInternal;typedef UBTPageOpaqueDataInternal* UBTPageOpaqueInternal;

其中last_delete_xid與activeTupleCount用于索引的自治式回收,會在ustore中的“6. 空間管理和回收”一節詳細講解。
通過xid_base字段,頁面上的XID可以僅儲存基于該xid_base的一個32位偏移(Offset),節省XID存儲的空間開銷。實際的XID為頁面上的xid_base加上存儲的XID(也就是偏移)得到。
多版本中的葉子頁面的結構如圖4-17所示。

圖4-17 ubtree 葉子頁面結構示意圖
與astore堆頁面中維護版本信息的方法類似,ubtree的葉子節點中每個索引元組尾部都附加了對應的xmin和xmax。由于索引只是用于加速搜索的結構,本身不與歷史版本概念強相關,僅通過xmin和xmax來標識這個索引元組是從什么時候開始有效的,又是什么時候被刪除的,而不像astore中堆元組一樣會有指向舊版本元組的指針。
新插入的索引元組尾部用于存放xmin和xmax 空間在ubtinsert函數執行的過程中預留出來。預留的空間及xmin在索引元組插入時通過UBTreePageAddTuple函數中寫入頁面,而xmax在索引元組刪除時通過UBTreeDeleteOnPage函數中寫入頁面。
在UBTreePagePruneOpt函數中,索引元組通過其xmin和xmax信息來判斷該元組是否已經無效(Dead),進而進行獨立的頁面清理。該函數會嘗試清除所有無效的元組,并進行相應的碎片整理。
索引掃描時會調用UBTreeFirst函數定位到第一個滿足掃描條件的索引元組,然后調用UBTreeReadPage獲取當前頁面中符合索引掃描條件,且能夠通過可見性檢查的元組。可見性檢查通過UBTreeVisibilityCheckXid函數及UBTreeVisibilityCheckCid函數處理,其基本邏輯與astore類似,通過xmin與xmax及當前的快照進行可見性判斷。
在ubtree中,索引元組除了按照索引列有序排列之外,對于索引列相同的元組,還將其對應堆元組的TID作為第二關鍵字進行排序。其具體實現大致都集中在ubtbuild函數及ubtinsert函數調用的過程中,這中間對索引列相同的元組會按照TID來進行額外的比較。實現還借助了BTScanInsert結構體,該結構體定義如下:

typedef struct BTScanInsertData {bool heapkeyspace; /* 標志索引是否額外按 TID 排序 */bool anynullkeys; /* 標志待查找的索引元組是否有為 NULL的列 */bool nextkey; /* 標志是否希望尋找第一個大于掃描條件的元組 */bool pivotsearch; /* 標志是否希望查找 Pivot 元組 */ItemPointer scantid; /* 用于作為排序依據的 TID */ int keysz; /* scankeys 數組的大小 */ScanKeyData scankeys[INDEX_MAX_KEYS]; } BTScanInsertData;

在索引元組將TID作為第二關鍵字排序之后,用于劃分搜索空間的非葉子節點元組及葉子節點的Hikey元組(統稱Pivot元組)也需要攜帶對應的TID信息。這會使得Pivot元組占用空間增加,非葉子的扇出(fan out)降低。為了避免這一特性導致的扇出降低,若不需要比較TID即可區分兩個葉子頁面,則對應的Pivot原則中就不需要儲存TID信息。類似地,Pivot元組中也可以去掉一些不需要進行比較的索引列,這一邏輯在UBTreeTruncate函數中進行處理。原則是當比較前幾列就可以區分兩個葉子頁面時,Pivot元組中就不需要儲存后續的列。
2) 索引操作
對于原有的B-Tree索引而言,主要有四類操作:索引創建、索引掃描、索引插入以及索引刪除。下面將依次進行介紹。
(1) 索引創建。
索引創建操作由索引上的ubtbuild函數及ustore上的IndexBuildUHeapScan函數配合完成。IndexBuildUHeapScan函數負責掃描對應的ustore表,并取出每個元組的最新版本(遵循SnapshotNow的語義)以及其對應的xmin和xmax。若發現某個元組存在被就地更新的舊版本,則會將該索引標記為HotChainBroken。被標記為HotChainBroken的索引,會復用astore原有的邏輯,禁止隔離級別為可重復讀(Read Repeatable)的老事務訪問。ubtbuild函數會接收IndexBuildUHeapScan傳過來的元組,將其按照索引列及TID排序后依次插入到索引頁面中,并構建相應的元頁面及上層頁面。整個創建流程需要將所有頁面都記錄到XLOG中,并強制將存儲管理中的內容刷到永久存儲介質后才算成功結束。
(2) 索引掃描。
索引掃描與B-Tree索引基本一致,但是需要對索引元組進行可見性檢查。沒有通過可見性檢查的索引元組不會被返回,通過可見性檢查的元組仍需要在ustor 堆表上進行可見性檢查,并找到正確的可見版本。在IndexOnlyScan場景中,通過可見性檢查的元組即可直接返回,不需要再訪問堆表。
不過索引進行可見性檢查時,由于索引元組只存放了xmin和xmax而沒有CID(對應“4.2.3 astore”節堆表元組中的t_cid字段)信息,如果發現了當前事務修改過的索引元組則不能正確地通過CID來判斷其可見性。此時會將該元組視為可見,但會標記xs_recheck_itup,告知ustore的數據頁面需要在取到對應的數據元組后,再次構建對應的索引元組并與返回的索引元組進行比較,來確認該索引元組是不是真正可見。相關邏輯在 UBTreeVisibilityCheckXid、UBTreeVisibilityCheckCid以及RecheckIndexTuple函數中進行處理。
(3) 索引插入。
索引元組需要存儲對應的xmin和xmax版本信息,但其所占用的空間并不表現在IndexTupleSize中,而是對外部透明。索引插入的接口函數為ubtinsert,為了正確插入帶有版本信息的元組,需要在執行插入前增加IndexTupleSize以預留用于儲存版本信息的空間。真正將元組插入到頁面的時候,會將版本信息所占用的空間大小從IndexTupleSize中去除。
在索引插入的過程中若頁面空間不足,會首先調用UBTreePagePruneOpt函數嘗試對已經無效的元組進行清理。若清理失敗或清理成功后空間仍然不足,會進行索引頁面分裂。索引頁面分裂會在UBTreeInsertOnPage函數中進行。ubtree中存在兩種分裂策略:default以及insertpt。其中default策略會將原頁面上的內容均勻地分配到兩個頁面上,而insertpt會根據新插入元組的插入規律、插入位置及TID等信息選擇合適的分裂點。
在ubtree需要申請新的頁面時,并不會像原有的B-Tree索引一樣調用_bt_getbuf通過FSM來查找可用頁面。ubtree帶有自治式的空間管理機制,通過UBtreeGetNewPage函數獲取新頁面。該自治式空間管理機制將在空間管理和回收部分介紹。
(4) 索引刪除。
索引刪除操作用于在堆元組被刪除的同時,將對應的索引元組也標上對應的xmax。索引刪除的流程與插入類似,通過二分查找定位到待刪除元組的位置,并將xmax寫入到對應的位置。需要注意的是,要刪除的元組是索引列以及TID都匹配,且還未被寫入xmax的那個元組,這部分邏輯在UBTreeFindDeleteLoc函數中處理。在最后會調用UBTreeDeleteOnPage函數為對應的索引元組寫上xmax,更新頁面上的last_delete_xid以及activeTupleCount,并在檢測到activeTupleCount為0時將該頁面放入潛在空頁隊列(Potential Empty Page Queue)中。關于潛在空頁隊列會在空間管理和回收部分介紹。

5. 存取管理

openGauss中的ustore表訪存接口如表4-24所示。由于openGauss中ustore表只有一種頁面和元組結構,因此在上述接口中,直接實現了底層的頁面和元組操作流程。

表4-24 ustore表訪存接口

函數名稱

接口含義

heap_open

打開一個ustore表,得到表的相關元信息

heap_close

關閉一個ustore表,釋放該表的加鎖或引用

UHeapRescan

重新開始ustore表(順序)掃描操作

UHeapGetNext

(順序)獲取下一條元組

UHeapGetTupleFromPage

UHeapGetNext內部實現,單頁校驗模式

UHeapScanGetTuple

UHeapGetNext內部實現,單條校驗模式

UHeapGetPage

(順序)獲取并掃描下一個ustore表頁面

UHeapInsert

在ustore表中插入一條元組

UHeapMultiInsert

在ustore表中批量插入多條元組

UHeapDelete

在ustore表中刪除一條元組

UHeapUpdate

在ustore表中更新一條元組

UHeapLockTuple

在ustore表中對一條元組加鎖

6. 空間管理和回收

不同于astore的空間管理和回收機制,ustore實現了自治式的空間管理機制。ustore里堆以及索引的空間分配和回收都在業務運行的過程中平穩地進行,不依賴中量級的VACUUM及AUTOVACUUM清理機制。
1) 自治式堆頁面空間管理
ustore中堆頁面的自治式空間管理,建立在與astore類似的輕量級堆頁面清理機制的基礎上。在執行DML及DQL操作的過程中,ustore都會進行堆數據頁面清理,以取代VACUUM清理機制。UHeapPagePruneOptPage函數是頁面清理的入口函數,會清理已經提交的被刪除元組。
對于astore而言,復用數據元組的行指針前必須保證對應的索引元組已經被清理。這是為了防止通過索引元組訪問已經被復用的行指針,導致取到錯誤的數據。在astore中需要通過VACUUM操作將這樣的無效索引元組統一清除掉后才能復用行指針,這使得堆頁面和索引頁面的清理邏輯耦合在一起,也會導致間斷性的大量I/O。在ustore中能高效地單獨進行數據和索引頁面的清理,因為帶有版本信息的ubtree能夠獨立檢測并過濾掉無效的索引元組,不會通過無效索引元組訪問對應的數據表。
堆頁面的空間管理機制復用openGauss中的FSM來管理UHeap中的可用空間。在UHeapPagePruneOptPage函數成功對頁面進行清理后,會將其空閑空間刷新到對應的FSM頁面中。為了避免每次頁面清理都需要更新整個樹狀結構的FSM,從而帶來額外的開銷,引入了一個更新整個FSM的概率計算。考慮當前清理后的可用空間占預留可用空間(Reserved Free Space)閾值的百分比,計算得出清理一個頁面后調用FreeSpaceMapVacuum函數的概率。也就是說,頁面清理獲得的可用空間越大,更新整個FSM的概率也就越大。
當數據元組被刪除時,會在頁面上記錄對應的潛在空閑空間(Potential Free Space),該值用于估計頁面上的空閑空間。在運行過程中,有多個場景會調用UHeapPagePruneOpt對頁面嘗試進行清理。DML語句執行過程中,INSERT、UPDATE以及DELETE操作都會拿到頁面的寫鎖。如果發現空間不足,或者檢測到潛在空閑空間到達某個閾值,會嘗試對頁面進行清理。DQL查詢語句執行的過程中若檢測到頁面上潛在空閑空間到達閾值,也同樣會嘗試申請頁面的寫鎖;如果拿到了頁面的寫鎖,會嘗試對頁面進行清理。
存在可清理的元組,但一直不被訪問的頁面不能通過這一機制正確地清理。為了解決這一問題,引入了基于概率的清理方案。在RelationGetBufferForUTuple函數尋找新的可用空間時,若通過FSM發現沒有足夠的可用空間,在對物理文件進行擴展前,會“隨機”選取一些頁面進行清理。該機制并非完全隨機選取,在多次嘗試后選取的頁面會覆蓋到整個關系的全部頁面。為了性能考慮,該過程中默認最多選取10個頁面進行清理,該數量可以通過GUC參數max_search_length_for_prune進行設置。具體的頁面選取數量通過DeadTupleRatio以及PruneSuccessRatio計算得出。其中DeadTupleRatio表示該表中無效元組的大致比例,該變量以統計信息的方式進行收集,在進行DML的過程中會進行更新;PruneSuccessRatio大致表示近幾次嘗試清理的成功率。
2) 自治式索引頁面空間管理
索引頁面的空間管理不依靠FSM數據結構,而是依靠特有的URQ(UBtree Recycle Queue)結構,簡稱為回收隊列。索引回收隊列單獨儲存在ubtree索引對應的.urq文件中,沒有原有B-Tree索引的.fsm文件。索引回收隊列相關代碼在“ubtrecycle.cpp”文件中。涉及到的主要函數接口見表4-25。

表4-25 索引回收隊列主要接口

函數名稱

接口含義

UBTreeTryRecycleEmptyPage

嘗試從潛在空頁隊列回收一個頁面

UBTreeGetAvailablePage

獲取有效頁面(潛在空頁或空閑頁面)

UBTreeRecordUsedPage

記錄被成功使用的頁面

UBTreeRecordEmptyPage

記錄潛在的空頁

UBTreeGetNewPage

獲取新的可用頁面

索引中的回收隊列分為兩部分,一部分是潛在空頁隊列(Potential Empty Page Queue),一部分是可用頁面隊列(Available Page Queue)。兩個隊列都是跨頁面的循環隊列,其中每個元素都會儲存blkno以及XID。其中blkno表示該元素對應索引頁面的block number;XID表示該頁面在哪個時刻能夠被回收或復用。這些元素在循環隊列單個頁內按照XID的順序進行排序,以便于快速找到XID 小(最可能被回收或復用)的頁面。其結構如圖4-18所示。

圖4-18 ubtree回收隊列結構示意圖

對于潛在空頁隊列而言,里面存放頁內元組已經被全部刪除但還沒有全部無效的頁面,其中的XID就標志頁面中最后一個元組無效的可能時機。在系統整體的oldestXmin超過該XID后,該頁面就有可能被從索引上刪除,但也可能因為新插入元組或刪除元組的事務中止而導致頁面不能被刪除。潛在空頁隊列中的頁面在成功被刪除后會被放入可用頁面隊列,并記錄刪除時最新事務的XID。

對于可用頁面隊列而言,里面存放已經被刪除,可以或即將可以被復用的頁面。其中XID就表示該頁面可以被復用的時機。這樣的頁面復用時延是來自B-Tree索引頁面刪除時可能的并發訪問導致的,可以參考nbtree文件夾下README 關于頁面刪除的部分。

在ubtree進行索引刪除時,會更新頁面上的last_delete_xid字段以及activeTupleCount字段。若更新后activeTupleCount變為0,會將該頁面放入潛在空頁隊列,并將此時的last_delete_xid作為對應的可回收時間點。

在業務運行的過程中,索引會通過UBTreeTryRecycleEmptyPage函數不斷嘗試對潛在空頁隊列中的頁面進行回收。在索引申請新的頁面時,會通過UBTreeGetNewPage函數與可用頁面隊列交互,查找當前可用的空閑頁面。當可用頁面隊列中沒有可用頁面時,一般會通過擴展索引物理文件的方式來獲得新的頁面。但也存在物理文件批量擴展,或擴展后還未來得及使用就出錯退出的情況。此時在回收隊列的元信息頁面中保存了已正確追蹤的頁面數量,若該數量少于整個索引表的頁面數量,會嘗試去使用這一部分未追蹤的頁面,并更新已追蹤的頁面數量。

3) 中量級和重量級手動頁面清理
與astore相同,ustore也提供VACUUM語句來讓用戶主動執行對某個ustore表及其上的索引進行中量級清理。其對外表現與astore一致,可參考astore的空間管理和回收內容。
在ustore中,中量級清理同樣通過lazy_vacuum_rel函數進入,但不會調用lazy_scan_heap,而是調用LazyScanUHeap函數來進行數據頁面的清理。在進行索引清理時,會調用lazy_vacuum_index接口及LazyVacuumHeap函數來清理索引文件和堆表文件,索引清理時會調用ubtbulkdelete函數。
重量級的VACUUM FULL也與astore一致,會清理無效數據并對數據空間和索引空間重新進行組織。重量級清理的對外接口是cluster_rel函數,本質上是重新對數據進行聚簇,清理過程中會阻塞對該表的所有操作。

介紹完“4.2.4 ustore”,下篇我們將詳細介紹“4.2.5 行存儲索引機制”相關內容,敬請期待!

總結

以上是生活随笔為你收集整理的openGauss数据库源码解析系列文章——存储引擎源码解析(四)的全部內容,希望文章能夠幫你解決所遇到的問題。

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

www.久久色 | 五月色综合 | 午夜.dj高清免费观看视频 | 国产精品久久久 | 97成人精品视频在线观看 | 狠狠狠色丁香婷婷综合激情 | 91精彩在线视频 | 欧美日韩久久 | 亚洲免费永久精品国产 | 日韩免费一二三区 | 久久在线电影 | 国产又粗又猛又爽又黄的视频免费 | 色综合久久久久综合 | 69久久99精品久久久久婷婷 | 日韩欧美视频一区二区 | 久久久久福利视频 | 免费色网 | 国产一区免费在线观看 | www.色的| 日本在线成人 | 在线视频精品播放 | 日韩有码中文字幕在线 | 97超碰福利久久精品 | 天堂中文在线播放 | 92精品国产成人观看免费 | 日韩天堂在线观看 | 一区二区三区不卡在线 | 亚洲婷婷在线 | 91色吧| 国产激情电影综合在线看 | 91精品国产电影 | 婷婷在线不卡 | 插综合网 | 精品96久久久久久中文字幕无 | 探花视频在线观看 | 狠狠色丁香婷婷综合久小说久 | 97成人超碰 | 98涩涩国产露脸精品国产网 | 久久激情五月婷婷 | 在线91精品 | 中午字幕在线观看 | 日韩成人精品一区二区三区 | 久久久鲁 | 日本免费久久高清视频 | 免费十分钟 | 黄色录像av | 成人电影毛片 | 久久视讯 | 色狠狠狠 | 亚洲精品美女久久17c | 成人h动漫精品一区二 | av福利超碰网站 | 色综合久久天天 | 成人动漫精品一区二区 | 国产精品va最新国产精品视频 | 精品国产精品国产偷麻豆 | 国产精品 日韩 欧美 | 中文字幕日韩免费视频 | 在线播放日韩 | 精品一区二区三区在线播放 | 欧洲av不卡 | 2022中文字幕在线观看 | 草久视频在线 | 欧美综合在线观看 | 国产区 在线 | 国产精品成人免费一区久久羞羞 | 99国产一区 | 国产免费久久久久 | 一区二区不卡高清 | 黄色精品在线看 | 婷婷在线网 | 人人爽人人射 | 天天做天天爱天天爽综合网 | 国产日韩精品一区二区三区在线 | 蜜臀久久99精品久久久酒店新书 | 国产女教师精品久久av | 国产群p视频 | 国产欧美在线一区二区三区 | 国产五十路毛片 | 欧美久久久一区二区三区 | 超碰国产在线播放 | 亚洲欧美国内爽妇网 | 91激情视频在线观看 | 天天综合视频在线观看 | 国产精品大全 | 97在线免费视频 | 91精品在线观看视频 | 久久久精品二区 | 欧美一级特黄高清视频 | 在线观看国产麻豆 | 最新成人在线 | 成人精品视频久久久久 | 福利久久久 | 亚洲狠狠婷婷综合久久久 | 成年人免费观看国产 | 亚洲日本va午夜在线影院 | 国产字幕av | 激情综合网五月激情 | www.91av在线| 高潮毛片无遮挡高清免费 | 欧美日韩1区2区 | 欧洲精品视频一区二区 | 亚洲精品视频国产 | 国产97视频在线 | 日韩免费区 | 久久理伦片 | 国产色视频一区 | 黄色三级免费片 | 日韩av免费观看网站 | 国产精品theporn | 成人黄色在线视频 | 国产精品久久久久三级 | 伊人色综合网 | 国产在线自 | 天天爽夜夜操 | 国产成人精品久久久久 | 在线看v片 | 激情欧美丁香 | av看片网| 又爽又黄又刺激的视频 | 久草干| 麻豆一区在线观看 | 国产精品电影一区 | 久精品视频在线 | 中文在线免费观看 | wwxxx日本| 亚洲夜夜综合 | 玖玖视频精品 | 精品在线免费视频 | 五月激情六月丁香 | 色综合久久88色综合天天人守婷 | 另类老妇性bbwbbw高清 | 日韩精品一区二区免费 | 国产高清网站 | 人人干人人草 | 日日夜夜精品免费观看 | 午夜色性片 | 精品免费一区二区三区 | 色综合天天天天做夜夜夜夜做 | 一区二区三区日韩视频在线观看 | 国产一区在线视频 | 久久久国产电影 | 亚洲精品av中文字幕在线在线 | 国产精品久久久久av | 久久久久久久国产精品视频 | 日本不卡一区二区三区在线观看 | 特级免费毛片 | 视频国产区 | 亚洲一区二区高潮无套美女 | 91av视频在线免费观看 | 青春草视频在线播放 | 久久国产免费 | 伊人伊成久久人综合网小说 | 高清av影院 | 五月天狠狠操 | 在线国产片 | 日韩av电影免费在线观看 | 国产精品久久久久影院日本 | 久久久久久久久久久久电影 | 中文在线免费观看 | 日本久久中文 | 国产精品美女免费看 | 色综合天天爱 | 青青色影院 | 808电影| 一级片在线| av在线播放中文字幕 | 日韩成人av在线 | 国产午夜精品久久 | 黄色在线免费观看网址 | 国产精品久久久久久模特 | 亚洲精品成人网 | 91福利试看 | 免费a v在线 | 免费精品国产va自在自线 | 日本高清中文字幕有码在线 | 中文一二区 | 国产一区二区免费 | 99久久精品免费看国产免费软件 | 亚洲美女在线国产 | 久久久久久久久久伊人 | 亚洲成人av电影 | 成人a级黄色片 | 国产手机视频在线观看 | 中文字幕乱码日本亚洲一区二区 | 久久成 | 人人超碰免费 | 日本电影久久 | 欧美精品二区 | 中文字幕免费国产精品 | 在线免费亚洲 | 在线观看成人国产 | 97免费在线视频 | 808电影免费观看三年 | a天堂最新版中文在线地址 久久99久久精品国产 | 欧美日韩国内在线 | 久久久久麻豆v国产 | 麻豆传媒在线视频 | 欧洲视频一区 | 久久99精品久久只有精品 | 欧美国产大片 | 中文字幕在线影视资源 | 婷婷五月色综合 | 中文av字幕在线观看 | 久久久久久福利 | 91免费的视频在线播放 | 免费看色视频 | 久久99国产精品久久99 | 色偷偷网站视频 | 亚洲1级片 | 狠狠色狠狠色综合日日92 | 999久久久免费精品国产 | av免费电影在线 | 波多野结衣在线视频一区 | 99热精品国产一区二区在线观看 | 麻豆综合网| 91精品小视频 | 中文字幕在线一区观看 | 国产精品久久久久久五月尺 | 色之综合网 | 九色琪琪久久综合网天天 | 在线免费黄网站 | 成人sm另类专区 | 国产麻豆果冻传媒在线观看 | 91在线免费公开视频 | 色婷婷av国产精品 | 欧美日韩在线视频一区二区 | 中文字幕精品视频 | 久草网首页 | 一区二区视频在线看 | 久久久久亚洲精品成人网小说 | 福利视频一区二区 | 欧美成人91 | 国产乱对白刺激视频在线观看女王 | 国产电影黄色av | 亚洲韩国一区二区三区 | 久久综合久久综合久久综合 | 99精品久久99久久久久 | 色婷婷国产精品 | 欧美另类一二三四区 | 日韩精品久久久久久久电影竹菊 | 精品国产乱码久久 | 麻豆免费视频观看 | 黄色影院在线免费观看 | 91av视频观看 | 国产亚洲精品久久久久久移动网络 | 99在线热播精品免费 | 欧美日韩1区 | 国产成人99久久亚洲综合精品 | 亚洲黄色小说网址 | 久久综合久久88 | 国产婷婷vvvv激情久 | free. 性欧美.com| 九九综合九九综合 | 日韩免费网站 | 日本久久久精品视频 | 免费在线a | 国产精品porn | 天天操天天色天天射 | 激情网在线观看 | 欧美色图一区 | 国产精品久久久久av福利动漫 | 成人禁用看黄a在线 | 中文字幕一区在线观看视频 | 在线超碰av | www..com黄色片 | 就要干b| 亚洲国产999 | 97在线播放| 亚洲专区 国产精品 | 午夜av在线播放 | 久久成人在线视频 | 国产精品专区在线观看 | 一区 在线观看 | 精品资源在线 | 婷婷午夜 | 日韩一区二区三区高清免费看看 | 国产青青青| 免费观看一级一片 | 在线精品视频在线观看高清 | 福利网在线 | 一区二区网| 国产精品久久嫩一区二区免费 | 日韩综合精品 | caobi视频| 久久久久国产一区二区三区 | 人人舔人人爽 | 国产又粗又猛又爽又黄的视频免费 | 啪啪凸凸 | 国内精品久久久久久久久久清纯 | 国产真实在线 | 欧美a级免费视频 | 99精品视频在线播放观看 | 日日天天av | 成人宗合网 | 亚欧日韩成人h片 | 日韩精品一卡 | 久久艹欧美 | 国产高清视频在线播放 | 99精品国自产在线 | av在线收看| 久久久久在线视频 | 91精品国产综合久久久久久久 | 午夜丁香视频在线观看 | 免费视频91 | 天天操夜操 | 国产又粗又长又硬免费视频 | 美女精品在线观看 | 亚洲精品456在线播放乱码 | 久久99精品久久只有精品 | 人成在线免费视频 | 国产精品成久久久久三级 | 欧美极品少妇xbxb性爽爽视频 | 国产丝袜制服在线 | 午夜精品一区二区三区在线视频 | 久久成人精品视频 | 中文字幕在线视频网站 | 麻豆视频免费在线 | 久久激情视频免费观看 | 婷婷www | 色婷婷激情电影 | 在线天堂中文在线资源网 | 精品少妇一区二区三区在线 | 狠狠色噜噜狠狠狠狠 | 国产尤物在线 | 黄色软件在线观看免费 | 久久xxxx| 91人人插| 69国产成人综合久久精品欧美 | 亚洲色图激情文学 | 韩国一区二区三区在线观看 | 一区二区三区在线免费观看 | 国产成人精品久久久 | 91精品国产乱码久久 | 日韩在线一区二区免费 | 中文字幕在线不卡国产视频 | 国产999视频 | 一区二区三区免费在线观看 | 香蕉看片| av九九| 在线成人性视频 | 欧美一级乱黄 | 国产91大片| 欧美日韩三级在线观看 | 久久99热这里只有精品国产 | 日韩成人在线免费观看 | 成人在线视频免费观看 | 91探花系列在线播放 | 久久理论片| 久久人人爽人人人人片 | 狠狠狠狠狠狠天天爱 | 色偷偷88欧美精品久久久 | 免费三级大片 | 视频在线观看99 | 亚洲视频久久久 | a'aaa级片在线观看 | 欧美伦理电影一区二区 | 久视频在线 | 天天干天天摸天天操 | 国产一区二区三区免费观看视频 | 婷婷四房综合激情五月 | 9797在线看片亚洲精品 | 国产一区在线观看免费 | 激情综合网色播五月 | 免费高清影视 | 国产精彩在线视频 | 天天舔夜夜操 | 免费亚洲精品视频 | 久久久官网| 五月花丁香婷婷 | 欧美十八 | 五月天中文字幕mv在线 | av网址最新 | 久久一视频| 激情视频国产 | 永久免费观看视频 | 精品毛片久久久久久 | 国产免费观看av | 国产精品久久久久久久久久久杏吧 | 天天干天天色2020 | 亚洲一区二区91 | 狠狠狠狠狠狠干 | 美女黄视频免费 | 日韩大片在线播放 | 中文永久字幕 | 欧美日本三级 | 中文字幕亚洲欧美 | 狠狠五月天 | 麻豆观看| 成人免费在线观看入口 | 久久成人综合 | 久色伊人| 国产一区二区在线观看视频 | 最新日韩在线观看 | 久操中文字幕在线观看 | 最新99热 | 亚洲va欧洲va国产va不卡 | 国产精品高清在线观看 | 最新精品视频在线 | 久久艹欧美| 国产小视频免费在线观看 | 久久久久99精品成人片三人毛片 | 国产成人精品一区二区三区网站观看 | 日本久久中文 | 99久久夜色精品国产亚洲96 | 成人中文字幕在线观看 | 欧美日韩精品在线视频 | 久久热亚洲 | 超薄丝袜一二三区 | 久久国产精品一区二区 | 国产精品九九九 | 最新日本中文字幕 | 国产精品一区二区在线观看免费 | 天天操夜操视频 | 日韩美在线观看 | 色婷婷成人网 | 亚洲精品动漫在线 | 韩国一区二区在线观看 | 国产精品嫩草影院123 | 三级av黄色 | 日韩激情免费视频 | 亚洲精品一区二区网址 | 欧美福利网站 | 99高清视频有精品视频 | 五月天综合色 | 中文字幕黄色av | 久久久精品福利视频 | 久久视频这里有精品 | 一级片在线 | 国产精品婷婷午夜在线观看 | 午夜视频在线瓜伦 | 久久综合在线 | 在线午夜电影神马影院 | 久久免费视频这里只有精品 | 日韩精品视频免费看 | 精品国产一区二 | 色网av| 国产福利91精品 | 日韩av网址在线 | www日韩在线 | 88av视频| 少妇bbbb| 久久久久久久久久久久国产精品 | 亚洲国产精品免费 | 久久久久久久久艹 | 99久久久免费视频 | 蜜臀av夜夜澡人人爽人人 | aⅴ精品av导航 | 久影院 | 国产麻豆精品在线观看 | www婷婷| 中文理论片 | 缴情综合网五月天 | 天天操天天操天天操天天操天天操天天操 | 在线国产视频一区 | 精品自拍av| 天天射天天拍 | 欧美一区二区三区在线观看 | 性日韩欧美在线视频 | 亚洲精品综合欧美二区变态 | 国产一级视频在线 | 久久精品视频18 | 久久婷婷一区 | 国产一区不卡在线 | 久碰视频在线观看 | 色av男人的天堂免费在线 | 久久av中文字幕片 | 亚洲免费av观看 | 97偷拍视频| 91免费在线| 色婷婷一区 | 丁香花五月 | 最新av电影网址 | 能在线看的av | 国产成人精品一二三区 | 在线播放日韩av | 久久婷婷激情 | 免费网站在线 | 日韩黄色软件 | 99视频网站| 激情综合国产 | 午夜精品久久久久久久99 | 午夜影视剧场 | 国产视频观看 | 亚洲九九九在线观看 | 少妇搡bbb| aⅴ精品av导航 | 亚洲国产视频在线 | 91尤物在线播放 | 五月婷婷中文 | 97免费在线观看 | 国产aaa免费视频 | 成人av免费在线观看 | av一区二区三区在线播放 | 国产免费久久av | 亚洲成av人片 | 中文字幕在线观看第三页 | 奇米影视777四色米奇影院 | 天天天综合 | 五月婷婷操 | 久久艹艹 | 欧美激情综合五月色丁香小说 | 中文字幕亚洲精品日韩 | 蜜臀av在线一区二区三区 | 91女子私密保健养生少妇 | av色图天堂网| 婷婷丁香综合 | 国产一区二区在线播放 | 日韩在线观看视频在线 | 玖玖玖精品 | 亚洲综合在线一区二区三区 | 天天射天天舔天天干 | av黄色免费网站 | 视频一区二区在线 | 亚洲成av人影片在线观看 | 91成人在线观看喷潮 | 天堂中文在线视频 | 国产九九九精品视频 | 激情动态| 天天操天天射天天舔 | 久草电影在线观看 | 久久久免费视频播放 | 国产精品18久久久久vr手机版特色 | www.成人久久| 成人黄色在线观看视频 | 91在线视频 | 一区中文字幕 | 91看片淫黄大片一级在线观看 | 天天爱天天操天天爽 | 超碰在线98 | 欧美激情视频免费看 | 免费福利视频网 | 青青色影院 | 欧美最猛性xxxxx(亚洲精品) | 国产第一页精品 | 99久久99热这里只有精品 | 日日干夜夜草 | 人人草人 | 久操视频在线播放 | 欧美一区二区三区激情视频 | 日韩国产欧美在线视频 | 日日干天天爽 | 丁香花在线视频观看免费 | 色综合久久久久 | 最近2019好看的中文字幕免费 | 丝袜美女在线观看 | 欧美激情视频一区二区三区免费 | 人人干人人干人人干 | 黄色精品一区二区 | 亚洲精品永久免费视频 | 欧美激情综合色综合啪啪五月 | 91精品国产91热久久久做人人 | 国内精品免费 | 九九在线高清精品视频 | 国产精品99在线观看 | 在线免费高清 | 久草视频在 | 中文高清av | 色中射 | 亚洲精品合集 | 在线看日韩 | 国产亚洲精品美女久久 | 国产午夜精品一区二区三区四区 | 日韩中文字幕在线 | 国内精品免费久久影院 | 国产黄色播放 | 在线精品视频在线观看高清 | 98久9在线 | 免费 | 四虎永久精品在线 | 国产精品久久久久久久久久免费 | 日韩精品免费在线观看 | 亚洲成av人电影 | 韩国av免费看 | 国产自产在线视频 | 国产视频在线观看一区二区 | 色多多污污 | 色婷婷在线观看视频 | 免费看的黄色小视频 | 成人黄色在线观看视频 | 欧美精品久久久久久久 | 中文字幕av免费观看 | 黄色国产高清 | 99热这里只有精品免费 | 99在线视频免费观看 | 免费成人黄色片 | 欧美性色综合 | 在线国产99| 国产精品久久久久久久久久久久午夜 | 精品久久久成人 | 亚洲精品99久久久久中文字幕 | 97超碰人人模人人人爽人人爱 | 久久久久久久久久伊人 | 福利网址在线观看 | 2000xxx影视 | 一区二区三区在线影院 | 国产又粗又猛又黄又爽视频 | 成人av网站在线播放 | 久久精品久久久精品美女 | 欧美日韩69| 在线国产中文 | 丝袜护士aⅴ在线白丝护士 天天综合精品 | 天天爽天天爽夜夜爽 | 丁香婷婷网 | 91免费观看视频网站 | 91人人澡| 九九九毛片 | 久久久国产在线视频 | 免费av片在线 | 欧美日韩高清免费 | 黄网站免费看 | 丰满少妇久久久 | 欧美日韩国产色综合一二三四 | 国产看片网站 | 色偷偷中文字幕 | 亚洲视屏在线播放 | 国产一级特黄电影 | 免费观看一级视频 | 成人av在线播放网站 | 国产成人精品亚洲a | 久久精品日韩 | 国产一区二区三区高清播放 | 天天操天天干天天操天天干 | 激情五月亚洲 | 婷婷久久一区二区三区 | 99精品99| 国产精品第54页 | 97色婷婷成人综合在线观看 | 国产精品麻豆视频 | 国产视频精选 | 久热久草 | 国产精品乱看 | 国产精品欧美激情在线观看 | 最近2019好看的中文字幕免费 | 国产欧美综合在线观看 | 成人小视频在线 | 国产一区二区在线观看免费 | 欧美日韩一区二区三区在线观看视频 | 久久视频一区 | 黄色片视频免费 | 国产成人在线播放 | av官网在线| 在线 日韩 av | 五月婷婷激情综合网 | www夜夜操| 色婷婷狠狠18 | 成人黄色av免费在线观看 | 在线亚洲欧美视频 | 亚洲乱码久久 | 亚洲精品一区二区三区新线路 | 日韩电影一区二区三区 | 91精品国产自产在线观看永久 | 中文字幕成人在线观看 | 天天干天天拍天天操天天拍 | 成人av教育| 日韩精品一区二区三区视频播放 | 最近更新好看的中文字幕 | av免费试看 | 欧美一级大片在线观看 | 成人av观看| 久久久久久久久久久久久久电影 | 精品国产伦一区二区三区观看方式 | 精品二区视频 | 在线国产一区二区 | 亚洲美女免费视频 | 亚洲免费精品视频 | 亚洲精品在线视频观看 | 97在线观看免费高清完整版在线观看 | av在线播放快速免费阴 | 国精产品一二三线999 | 日韩理论 | 中文字幕高清免费日韩视频在线 | 99中文视频在线 | 亚洲dvd | 国产视频在 | 韩国一区二区三区视频 | 一级黄毛片| 国产一区二区在线免费播放 | 91av视频播放 | 久久综合久久综合九色 | 久久天天操 | 欧美人操人 | 国产精品一级视频 | 成人午夜精品 | 在线观看国产www | 日本在线观看一区二区 | 国产精品毛片一区二区 | 国内揄拍国产精品 | 国产精品va在线 | 亚洲欧美国产精品va在线观看 | 2019中文 | 99高清视频有精品视频 | 欧美乱大交 | 狠狠精品 | 97成人免费视频 | 一区 在线 影院 | 亚洲一级片在线看 | 成人午夜在线观看 | 日日碰狠狠躁久久躁综合网 | 日本婷婷色 | 91av中文字幕 | 高清av网站 | 亚洲激情p | 色婷婷在线观看视频 | 日操操 | 国产91九色视频 | 亚洲精品男人天堂 | 伊人成人激情 | 久久精品精品电影网 | h动漫中文字幕 | 91丨九色丨蝌蚪丨对白 | 欧美a√大片| 日本一区二区三区免费看 | 国内精品久久久久影院一蜜桃 | 黄网站色欧美视频 | 96av在线视频 | 欧美日韩高清一区二区三区 | 久久久久久久久久久久久国产精品 | 黄色免费网 | 国内一区二区视频 | 亚洲视频播放 | 在线视频日韩一区 | 亚洲视频1区2区 | 久久久久五月天 | 精品日韩在线一区 | 精品国模一区二区 | 免费在线观看污 | 久久免费观看少妇a级毛片 久久久久成人免费 | 国产精品久久久久久久久久久免费 | 日韩高清免费电影 | 国产男女无遮挡猛进猛出在线观看 | 亚洲视频,欧洲视频 | 天天激情在线 | 久草在线高清视频 | 欧美 日韩 国产 中文字幕 | 麻豆超碰 | 中文字幕在线观看一区 | 久久久久综合视频 | 午夜精品一区二区三区四区 | 日本久久中文字幕 | 日韩中文字幕免费在线播放 | 免费观看一区 | 99re亚洲国产精品 | 国产糖心vlog在线观看 | www.玖玖玖 | 久草在线最新 | 91在线观看视频网站 | 亚洲精品乱码久久久久v最新版 | 国产黄色精品视频 | 狠狠色综合网站久久久久久久 | 久草久草久草久草 | 97香蕉久久国产在线观看 | 国内精品久久久久影院一蜜桃 | 免费在线观看av电影 | 狠狠狠色丁香婷婷综合激情 | 精品一区二区三区久久久 | 在线91网| 日韩电影在线观看一区二区 | 超碰人人草人人 | 日韩精品不卡 | 婷婷夜夜 | 91精品夜夜| 午夜精品一区二区三区在线 | 麻豆传媒视频在线 | 色搞搞| 91九色性视频 | 国产成人av电影在线观看 | 国产一级二级在线观看 | 六月久久婷婷 | www99久久 | 在线不卡中文字幕播放 | 成人免费在线视频观看 | 欧美激情一区不卡 | 91一区啪爱嗯打偷拍欧美 | 欧美不卡视频在线 | 天天射天天干天天爽 | 国精产品满18岁在线 | 国产在线不卡 | 国产精品久久久久久妇 | 亚洲婷婷丁香 | 日韩电影久久 | 91麻豆网| 插综合网| 99久久日韩精品免费热麻豆美女 | 超碰人人99 | 天天操天天干天天爱 | 五月婷婷中文字幕 | 国精产品永久999 | 69久久久| 国产精品黄网站在线观看 | 国产成人福利在线观看 | 99精品乱码国产在线观看 | 一级欧美一级日韩 | 亚洲一区二区黄色 | 久久久蜜桃 | www.狠狠色| 91女神的呻吟细腰翘臀美女 | 日韩欧美在线综合网 | 亚洲欧美少妇 | 色综合天天 | 奇米网8888 | 国产精品私人影院 | 在线观看黄色国产 | 看片的网址 | 九九九热精品免费视频观看网站 | 色偷偷88888欧美精品久久 | 久久精品中文字幕一区二区三区 | 亚在线播放中文视频 | 国产又粗又猛又黄视频 | 免费成人看片 | 午夜视频99| 久久久久久久久久久免费 | 97视频在线观看成人 | 亚洲丁香久久久 | 国产精品午夜久久 | 国产人免费人成免费视频 | 欧美一区免费在线观看 | 国产精品成人av久久 | 天天综合网国产 | 久久草草影视免费网 | 日韩精品在线观看av | 香蕉精品在线观看 | 亚洲日韩中文字幕在线播放 | 亚洲一区二区观看 | 日韩精品久久一区二区三区 | 婷婷播播网 | 91人人爽人人爽人人精88v | av资源在线看 | 日韩一区二区三区免费电影 | 久久精品成人热国产成 | 97电影网手机版 | av在线电影免费观看 | 亚洲精品一区二区三区新线路 | 日韩欧美在线一区 | 91一区啪爱嗯打偷拍欧美 | 国产精品久久久久一区二区 | 免费网站在线观看人 | 亚洲蜜桃av | 成人网在线免费视频 | 久久免费电影 | 久草视频在线播放 | 91cn国产在线 | 国产特级毛片aaaaaa高清 | 天堂中文在线播放 | 国产精品69av| 国产精品99久久久久的智能播放 | 色婷婷成人网 | 888av| 超碰在线公开 | 欧美最爽乱淫视频播放 | 狠狠躁天天躁综合网 | 欧美精品久久久久久 | 91av九色 | 中文字幕日韩无 | 免费试看一区 | 亚洲爱爱视频 | 中文字幕在线看视频国产中文版 | 人人搞人人爽 | 亚洲激情小视频 | 日黄网站 | 亚洲在线视频观看 | 色99久久 | 在线观看免费av网站 | 国产伦精品一区二区三区四区视频 | av一区二区三区在线播放 | 久久免费99精品久久久久久 | 99精品免费久久久久久日本 | 五月综合色 | 91资源在线免费观看 | 国内精品久久久久影院优 | 国产精品九九视频 | 久久中文字幕导航 | 美女久久久久久久 | 麻豆视频www | 九九九九九九精品任你躁 | 99久久精品国产毛片 | 在线观看成年人 | 97在线视频免费看 | 高清精品视频 | 亚洲作爱视频 | 国产视频在线免费 | 中文字幕制服丝袜av久久 | 在线日韩中文 | 成人羞羞免费 | 久久字幕 | 草久视频在线观看 | 超碰97公开 | 精品少妇一区二区三区在线 | 亚洲区精品 | 99视频久久 | 亚洲国内精品 | 黄www在线观看 | 国产淫片免费看 | 99久久婷婷国产一区二区三区 | 精品国产一二三四区 | 午夜国产一区二区 | 日日爱夜夜爱 | 欧洲一区二区在线观看 | 97在线视频免费播放 | 麻豆国产在线播放 | av久久久 | av国产在线观看 | 色噜噜狠狠狠狠色综合 | 久久综合久久八八 | 西西444www高清大胆 | 亚洲第一区在线观看 | 国产日产av | av一区在线 | 日本久久久精品视频 | 国产区在线 | 国产 欧美 日产久久 | 欧美精品久久久久a | 成年人免费在线观看网站 | 国偷自产中文字幕亚洲手机在线 | 激情久久伊人 | 欧美性大战 | 狠狠综合网 | www.888.av| 91亚色在线观看 | av福利在线 | 日本中文字幕在线播放 | 国产美女精彩久久 | 少妇bbb搡bbbb搡bbbb′ | 综合在线色 | a√天堂中文在线 | 久久超| 亚洲伦理电影在线 | 色婷婷激情网 | 成人黄色中文字幕 | 粉嫩av一区二区三区四区 | 91在线麻豆 | 99产精品成人啪免费网站 | 久久深爱网 | a久久免费视频 | 美国av片在线观看 | 美女露久久 | 精品uu| 国产精品18videosex性欧美 | 欧美黄网站 | 成全在线视频免费观看 | 婷婷色吧| 夜夜骑日日 | 精品国产三级a∨在线欧美 免费一级片在线观看 | 91精品办公室少妇高潮对白 | 午夜电影av| 五月天狠狠操 | 日韩免费观看av | 69av免费视频 | 夜夜视频资源 | 极品国产91在线网站 | 99精品免费在线 | 欧美亚洲成人免费 | 9992tv成人免费看片 | 久久国语露脸国产精品电影 | 亚洲精品玖玖玖av在线看 | 亚洲免费在线看 | 亚洲精欧美一区二区精品 | 四虎成人精品永久免费av九九 | 久久综合偷偷噜噜噜色 | 天天综合网天天综合色 | 久久三级视频 | 久久精品高清视频 | 最新日本中文字幕 | 欧美成年黄网站色视频 | 人人射人人爽 | 日韩在观看线 | 亚洲精品久久久久www | 中文字幕你懂的 | 亚洲天堂网站视频 | 在线免费观看国产视频 | 91人人爽久久涩噜噜噜 | 国产精品夜夜夜一区二区三区尤 | 天天色官网 | 久久国产精品99久久久久久老狼 | 亚洲区另类春色综合小说校园片 | 国产一区二区精品久久 | 亚洲精品美女久久 | 五月激情丁香图片 | 国产在线免费观看 | 91免费在线播放 | 欧美在线视频免费 | 国产第一页在线观看 | 国产精品一区二区av | 亚洲成年人av | 在线观看片 | 天天精品视频 | 国产 一区二区三区 在线 | 97综合视频 | 国产精品原创在线 | 天堂网一区 | 国产一级片不卡 | 一区二区三区在线电影 | 精品国偷自产国产一区 | 亚洲成人黄色av | 国产精品第7页 | 六月丁香激情综合色啪小说 | 日韩黄色中文字幕 | 国产精品国产三级国产专区53 | 国产乱码精品一区二区三区介绍 |