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

解決線上數據庫死鎖,就是這么簡單!

運維 數據庫運維
前幾天,線上發生了一次數據庫死鎖問題,這一問題前前后后排查了比較久的時間,這個過程中自己也對數據庫的鎖機制有了更深的理解。

前幾天,線上發生了一次數據庫死鎖問題,這一問題前前后后排查了比較久的時間,這個過程中自己也對數據庫的鎖機制有了更深的理解。

本文總結了這次死鎖排查的全過程,并分析了導致死鎖的原因及解決方案。希望給大家提供一個死鎖的排查及解決思路。

本文涉及到 MySQL 執行引擎、數據庫隔離級別、InnoDB 鎖機制、索引、數據庫事務等多領域知識。前車之鑒,后事之師,希望讀者們都可以有所收獲。

現象

某天晚上,同事正在發布,突然線上大量報警,很多是關于數據庫死鎖的,報警提示信息如下:

  1. {"errorCode":"SYSTEM_ERROR","errorMsg":"nested exception is org.apache.ibatis.exceptions.PersistenceException:  
  2. Error updating database. Cause: ERR-CODE: [TDDL-4614][ERR_EXECUTE_ON_MYSQL]  
  3. Deadlock found when trying to get lock;  
  4. The error occurred while setting parameters\n### SQL:  
  5. update fund_transfer_stream set gmt_modified=now(),state = ? where fund_transfer_order_no = ? and seller_id = ? and state = 'NEW' 

通過報警,我們基本可以定位到發生死鎖的數據庫以及數據庫表。先來介紹下本文案例中涉及到的數據庫相關信息。

背景情況

我們使用的數據庫是 MySQL 5.7,引擎是 InnoDB,事務隔離級別是 READ-COMMITED。

數據庫版本查詢方法:

  1. select version(); 

引擎查詢方法:

  1. show create table fund_transfer_stream; 

建表語句中會顯示存儲引擎信息,形如:ENGINE=InnoDB。

事務隔離級別查詢方法:

  1. select @@tx_isolation; 

事務隔離級別設置方法(只對當前 Session 生效):

  1. set session transaction isolation level read committed

PS:注意,如果數據庫是分庫的,以上幾條 SQL 語句需要在單庫上執行,不要在邏輯庫執行。

發生死鎖的表結構及索引情況(隱去了部分無關字段和索引):

  1. CREATE TABLE `fund_transfer_stream` (  
  2.   `id` bigint(20) unsigned NOT NULL AUTO_INCREMENT COMMENT '主鍵'
  3.   `gmt_create` datetime NOT NULL COMMENT '創建時間'
  4.   `gmt_modified` datetime NOT NULL COMMENT '修改時間',  
  5.   `pay_scene_name` varchar(256) NOT NULL COMMENT '支付場景名稱',  
  6.   `pay_scene_version` varchar(256) DEFAULT NULL COMMENT '支付場景版本'
  7.   `identifier` varchar(256) NOT NULL COMMENT '唯一性標識'
  8.   `seller_id` varchar(64) NOT NULL COMMENT '賣家Id'
  9.   `state` varchar(64) DEFAULT NULL COMMENT '狀態', `fund_transfer_order_no` varchar(256)  
  10.   DEFAULT NULL COMMENT '資金平臺返回的狀態',  
  11.   PRIMARY KEY (`id`),UNIQUE KEY `uk_scene_identifier`  
  12.   (KEY `idx_seller` (`seller_id`), 
  13.   KEY `idx_seller_transNo` (`seller_id`,`fund_transfer_order_no`(20)) 
  14.   ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='資金流水'

該數據庫共有三個索引,1 個聚簇索引(主鍵索引),2 個非聚簇索引(非主鍵索引)。

聚簇索引:

  1. PRIMARY KEY (`id`) 

非聚簇索引:

  1. KEY `idx_seller` (`seller_id`), 
  2. KEY `idx_seller_transNo` (`seller_id`,`fund_transfer_order_no`(20)) 

以上兩個索引,其實 idx_seller_transNo 已經覆蓋到了 idx_seller,由于歷史原因,該表以 seller_id 分表,所以是先有的 idx_seller,后有的 idx_seller_transNo。

死鎖日志

當數據庫發生死鎖時,可以通過以下命令獲取死鎖日志:

  1. show engine innodb status 

發生死鎖,***時間查看死鎖日志,得到死鎖日志內容如下:

  1. Transactions deadlock detected, dumping detailed information. 
  2. 2019-03-19T21:44:23.516263+08:00 5877341 [Note] InnoDB:  
  3.  
  4. *** (1) TRANSACTION
  5. TRANSACTION 173268495, ACTIVE 0 sec fetching rows 
  6. mysql tables in use 1, locked 1 
  7. LOCK WAIT 304 lock struct(s), heap size 41168, 6 row lock(s), undo log entries 1 
  8. MySQL thread id 5877358, OS thread handle 47356539049728, query id 557970181 11.183.244.150 fin_instant_app updating 
  9.  
  10. update `fund_transfer_stream` set `gmt_modified` = NOW(), `state` = 'PROCESSING' where ((`state` = 'NEW'AND (`seller_id` = '38921111'AND (`fund_transfer_order_no` = '99010015000805619031958363857')) 
  11. 2019-03-19T21:44:23.516321+08:00 5877341 [Note] InnoDB:  
  12.  
  13. *** (1) HOLDS THE LOCK(S): 
  14. RECORD LOCKS space id 173 page no 13726 n bits 248 index idx_seller_transNo of table `xxx`.`fund_transfer_stream` trx id 173268495 lock_mode X locks rec but not gap 
  15. Record lock, heap no 168 PHYSICAL RECORD: n_fields 3; compact format; info bits 0 
  16.  
  17. 2019-03-19T21:44:23.516565+08:00 5877341 [Note] InnoDB:  
  18.  
  19. *** (1) WAITING FOR THIS LOCK TO BE GRANTED: 
  20. RECORD LOCKS space id 173 page no 12416 n bits 128 index PRIMARY of table `xxx`.`fund_transfer_stream` trx id 173268495 lock_mode X locks rec but not gap waiting 
  21. Record lock, heap no 56 PHYSICAL RECORD: n_fields 17; compact format; info bits 0 
  22. 2019-03-19T21:44:23.517793+08:00 5877341 [Note] InnoDB:  
  23.  
  24. *** (2) TRANSACTION
  25. TRANSACTION 173268500, ACTIVE 0 sec fetching rows, thread declared inside InnoDB 81 
  26. mysql tables in use 1, locked 1 
  27. 302 lock struct(s), heap size 41168, 2 row lock(s), undo log entries 1 
  28. MySQL thread id 5877341, OS thread handle 47362313119488, query id 557970189 11.131.81.107 fin_instant_app updating 
  29.  
  30. update `fund_transfer_stream_0056` set `gmt_modified` = NOW(), `state` = 'PROCESSING' where ((`state` = 'NEW'AND (`seller_id` = '38921111'AND (`fund_transfer_order_no` = '99010015000805619031957477256')) 
  31. 2019-03-19T21:44:23.517855+08:00 5877341 [Note] InnoDB:  
  32.  
  33. *** (2) HOLDS THE LOCK(S): 
  34. RECORD LOCKS space id 173 page no 12416 n bits 128 index PRIMARY of table `fin_instant_0003`.`fund_transfer_stream_0056` trx id 173268500 lock_mode X locks rec but not gap 
  35. Record lock, heap no 56 PHYSICAL RECORD: n_fields 17; compact format; info bits 0 
  36.  
  37. 2019-03-19T21:44:23.519053+08:00 5877341 [Note] InnoDB:  
  38.  
  39. *** (2) WAITING FOR THIS LOCK TO BE GRANTED: 
  40. RECORD LOCKS space id 173 page no 13726 n bits 248 index idx_seller_transNo of table `fin_instant_0003`.`fund_transfer_stream_0056` trx id 173268500 lock_mode X locks rec but not gap waiting 
  41. Record lock, heap no 168 PHYSICAL RECORD: n_fields 3; compact format; info bits 0 
  42.  
  43. 2019-03-19T21:44:23.519297+08:00 5877341 [Note] InnoDB: *** WE ROLL BACK TRANSACTION (2) 

簡單解讀一下死鎖日志,可以得到以下信息:

①導致死鎖的兩條 SQL 語句分別是:

  1. update `fund_transfer_stream_0056`  
  2. set `gmt_modified` = NOW(), `state` = 'PROCESSING'  
  3. where ((`state` = 'NEW'AND (`seller_id` = '38921111'AND (`fund_transfer_order_no` = '99010015000805619031957477256')) 
  1. update `fund_transfer_stream_0056`  
  2. set `gmt_modified` = NOW(), `state` = 'PROCESSING'  
  3. where ((`state` = 'NEW'AND (`seller_id` = '38921111'AND (`fund_transfer_order_no` = '99010015000805619031958363857')) 

②事務 1,持有索引 idx_seller_transNo 的鎖,在等待獲取 PRIMARY 的鎖。

③事務 2,持有 PRIMARY 的鎖,在等待獲取 idx_seller_transNo 的鎖。

④因事務 1 和事務 2 之間發生循環等待,故發生死鎖。

⑤事務 1 和事務 2 當前持有的鎖均為:lock_mode X locks rec but not gap。

兩個事務對記錄加的都是 X 鎖,No Gap 鎖,即對當行記錄加鎖(Record Lock),并未加間隙鎖。

X 鎖:排他鎖、又稱寫鎖。若事務 T 對數據對象 A 加上 X 鎖,事務 T 可以讀 A 也可以修改 A,其他事務不能再對 A 加任何鎖,直到 T 釋放 A 上的鎖。這保證了其他事務在 T 釋放 A 上的鎖之前不能再讀取和修改 A。

與之對應的是 S 鎖:共享鎖,又稱讀鎖,若事務 T 對數據對象 A 加上 S 鎖,則事務 T 可以讀 A 但不能修改 A,其他事務只能再對 A 加 S 鎖,而不能加 X 鎖,直到 T 釋放 A 上的 S 鎖。

這保證了其他事務可以讀 A,但在 T 釋放 A 上的 S 鎖之前不能對 A 做任何修改。

Gap Lock:間隙鎖,鎖定一個范圍,但不包括記錄本身。Gap 鎖的目的,是為了防止同一事務的兩次當前讀,出現幻讀的情況。

Next-Key Lock:1+2,鎖定一個范圍,并且鎖定記錄本身。對于行的查詢,都是采用該方法,主要目的是解決幻讀的問題。

問題排查

根據我們目前已知的數據庫相關信息,以及死鎖的日志,我們基本可以做一些簡單的判定。

首先,此次死鎖一定是和 Gap 鎖以及 Next-Key Lock 沒有關系的。因為我們的數據庫隔離級別是 RC(READ-COMMITED)的,這種隔離級別是不會添加 Gap 鎖的。前面的死鎖日志也提到這一點。

然后,就要翻代碼了,看看我們的代碼中事務到底是怎么做的。核心代碼及 SQL 如下:

  1. @Transactional(rollbackFor = Exception.class) 
  2. public int doProcessing(String sellerId, Long id, String fundTransferOrderNo) { 
  3.     fundTreansferStreamDAO.updateFundStreamId(sellerId, id, fundTransferOrderNo); 
  4.     return fundTreansferStreamDAO.updateStatus(sellerId, fundTransferOrderNo,"PROCESSING"); 

該代碼的目的是先后修改同一條記錄的兩個不同字段,updateFundStreamId SQL:

  1. update fund_transfer_stream 
  2.         set gmt_modified=now(),fund_transfer_order_no = #{fundTransferOrderNo} 
  3.         where id = #{id} and seller_id = #{sellerId} 

updateStatus SQL:

  1. update fund_transfer_stream 
  2.     set gmt_modified=now(),state = #{state} 
  3.     where fund_transfer_order_no = #{fundTransferOrderNo} and seller_id = #{sellerId} 
  4.     and state = 'NEW' 

可以看到,我們的同一個事務中執行了兩條 Update 語句,這里分別查看下兩條 SQL 的執行計劃:

updateFundStreamId 執行的時候使用到的是 PRIMARY 索引。

updateStatus 執行的時候使用到的是 idx_seller_transNo 索引。

通過執行計劃,我們發現 updateStatus 其實是有兩個索引可以用的,執行的時候真正使用的是 idx_seller_transNo 索引。這是因為 MySQL 查詢優化器是基于代價(cost-based)的查詢方式。

因此,在查詢過程中,最重要的一部分是根據查詢的 SQL 語句,依據多種索引,計算查詢需要的代價,從而選擇***的索引方式生成查詢計劃。

我們查詢執行計劃是在死鎖發生之后做的,事后查詢的執行計劃和發生死鎖那一刻的索引使用情況并不一定是相同的。

但是,我們結合死鎖日志,也可以定位到以上兩條 SQL 語句執行的時候使用到的索引。

即 updateFundStreamId 執行的時候使用到的是 PRIMARY 索引,updateStatus 執行的時候使用到的是 idx_seller_transNo 索引。

有了以上這些已知信息,我們就可以開始排查死鎖原因及其背后的原理了。

通過分析死鎖日志,再結合我們的代碼以及數據庫建表語句,我們發現主要問題出在我們的 idx_seller_transNo 索引上面:

  1. KEY `idx_seller_transNo` (`seller_id`,`fund_transfer_order_no`(20)) 

索引創建語句中,我們使用了前綴索引,為了節約索引空間,提高索引效率,我們只選擇了 fund_transfer_order_no 字段的前 20 位作為索引值。

因為 fund_transfer_order_no 只是普通索引,而非唯一性索引。又因為在一種特殊情況下,會有同一個用戶的兩個 fund_transfer_order_no 的前 20 位相同。

這就導致兩條不同的記錄的索引值一樣(因為 seller_id 和 fund_transfer_order_no(20) 都相同 )。

就如本文中的例子,發生死鎖的兩條記錄的 fund_transfer_order_no 字段的這兩個值就是前 20 位是相同的:

  • 99010015000805619031958363857
  • 99010015000805619031957477256

那么為什么 fund_transfer_order_no 的前 20 位相同會導致死鎖呢?

加鎖原理

我們就拿本次的案例來看一下 MySQL 數據庫加鎖的原理是怎樣的,本文的死鎖背后又發生了什么。

我們在數據庫上模擬死鎖場景,執行順序如下:

我們知道,在 MySQL 中,行級鎖并不是直接鎖記錄,而是鎖索引。索引分為主鍵索引和非主鍵索引兩種:

  • 如果一條 SQL 語句操作了主鍵索引,MySQL 就會鎖定這條主鍵索引。
  • 如果一條語句操作了非主鍵索引,MySQL 會先鎖定該非主鍵索引,再鎖定相關的主鍵索引。

主鍵索引的葉子節點存的是整行數據。在 InnoDB 中,主鍵索引也被稱為聚簇索引(Clustered Index)。

非主鍵索引的葉子節點的內容是主鍵的值,在 InnoDB 中,非主鍵索引也被稱為非聚簇索引(Secondary Index)。

所以,本文的示例中涉及到的索引結構(索引是 B+ 樹,簡化成表格了)如圖:

死鎖的發生與否,并不在于事務中有多少條 SQL 語句,死鎖的關鍵在于:兩個(或以上)的 Session 加鎖的順序不一致。

那么接下來就看下上面的例子中兩個事務的加鎖順序是怎樣的:

下圖是分解圖,每一條 SQL 執行的時候加鎖情況:

結合以上兩張圖,我們發現了導致死鎖的原因:

  • 事務 1 執行 update1 占用 PRIMARY = 1 的鎖;事務 2 執行 update1 占有 PRIMARY = 2 的鎖;。
  • 事務 1 執行 update2 占有 idx_seller_transNo = (3111095611,99010015000805619031)的鎖,嘗試占有 PRIMARY = 2 鎖失敗(阻塞)。
  • 事務 2 執行 update2 嘗試占有 idx_seller_transNo = (3111095611,99010015000805619031)的鎖失敗(死鎖)。

事務在以非主鍵索引為 Where 條件進行 Update 的時候,會先對該非主鍵索引加鎖,然后再查詢該非主鍵索引對應的主鍵索引都有哪些,再對這些主鍵索引進行加鎖。)

解決方法

至此,我們分析清楚了導致死鎖的根本原理以及其背后的原理。那么這個問題解決起來就不難了。

可以從兩方面入手,分別是:

  • 修改索引
  • 修改代碼(包含 SQL 語句)

修改索引:只要我們把前綴索引 idx_seller_transNo 中 fund_transfer_order_no 的前綴長度修改下就可以了。

比如改成 50,即可避免死鎖。但是,改了 idx_seller_transNo 的前綴長度后,可以解決死鎖的前提條件是 Update 語句真正執行的時候,會用到 fund_transfer_order_no 索引。

如果 MySQL 查詢優化器在代價分析之后,決定使用索引 KEY idx_seller(seller_id),那么還是會存在死鎖問題。原理和本文類似。

所以,根本解決辦法就是改代碼:

  • 所有 Update 都通過主鍵 ID 進行。
  • 在同一個事務中,避免出現多條 Update 語句修改同一條記錄。

總結與思考

在死鎖發生之后的一周內,我幾乎每天都會抽空研究一會,問題早早的就定位到了,修改方案也有了,但是其中原理一直沒搞清楚。

前前后后做過很多種推斷及假設,又都被自己一次次推翻。最終還是要靠實踐來驗證自己的想法。

于是我自己在本地安裝了數據庫,實戰的做了些測試,并實時查看數據庫鎖情況。show engine innodb status ;可以查看鎖情況。最終才搞清楚原理。

簡單說幾點思考:

  • 遇到問題,不要猜!!!親手復現下問題,然后再來分析。
  • 不要忽略上下文!!!我剛開始就是只關注死鎖日志,一直忽略了代碼中的事務其實還執行了另外一條 SQL 語句(updateFundStreamId)。
  • 理論知識再充足,關鍵時刻不一定想的起來!!!
  • 坑都是自己埋的!!!

 

責任編輯:武曉燕 來源: Java之道
相關推薦

2024-06-21 09:37:57

2024-02-27 08:14:51

Nginx跨域服務

2017-11-28 15:29:04

iPhone X網頁適配

2021-05-24 10:50:10

Git命令Linux

2024-08-28 08:42:21

API接口限流

2020-06-16 10:57:20

搭建

2011-06-07 11:09:19

JAVA

2009-03-31 09:50:15

死鎖超時Java

2015-09-10 14:40:32

大數據神奇

2010-09-09 13:28:11

無線網絡小誤區

2015-06-30 12:53:40

秒殺應用MySQL數據庫優化

2016-07-22 15:12:12

Win10技巧重裝

2021-02-26 10:21:35

比特幣投資金融

2019-04-15 13:15:12

數據庫MySQL死鎖

2020-04-20 10:47:57

Redis數據開發

2023-08-26 21:42:08

零拷貝I/O操作

2021-12-27 07:31:37

JavaNeo4J數據庫

2021-10-28 19:23:27

界面嵌入式 UI

2023-07-27 08:26:36

零拷貝I/O操作

2020-07-27 07:00:00

超文本鏈接Word文檔網絡
點贊
收藏

51CTO技術棧公眾號

色综合视频在线观看| 国产一区二区三区免费播放| 日韩不卡中文字幕| 精品久久久久久无码国产| 91最新在线| 国产精品538一区二区在线| 欧美劲爆第一页| 9.1成人看片免费版| 豆花视频一区| 欧美性猛交xxxx乱大交极品| 综合一区中文字幕| 网站黄在线观看| 久久成人羞羞网站| 国内伊人久久久久久网站视频 | 亚洲高清国产拍精品26u| 亚洲免费av高清| 欧美日韩一区二区三区在线视频 | 国产电影一区二区三区爱妃记| 亚洲视频一区二区免费在线观看| 精品国产一区二区三| 91九色蝌蚪91por成人| 亚洲黄色免费| 久久久精品国产亚洲| 亚洲自拍偷拍一区二区| 日韩成人在线看| 91成人在线免费观看| 成人国产一区二区三区| 成人亚洲性情网站www在线观看| 国产精一区二区三区| 国产精品电影网| 日本五十熟hd丰满| 亚洲精品a级片| 一区二区成人精品| 人妻丰满熟妇av无码久久洗澡| 婷婷久久免费视频| 欧美三区在线观看| 黄色片久久久久| 91九色国产在线播放| 亚洲视频一区二区在线| 亚洲一一在线| 成人欧美一区| 久久久久国产精品麻豆| 国产免费一区二区| www.黄色片| 国产一区二区三区在线看麻豆| 国产精品成人一区| 久久精品视频5| 国产精品老牛| 欧美一级大胆视频| 自拍偷拍欧美亚洲| 夜夜夜久久久| 91国产中文字幕| 欧洲精品一区色| 国产极品视频在线观看| 国内成人自拍| 一本色道久久88亚洲综合88| 国产精品无码久久久久久| 男人的天堂久久| 日韩av资源在线播放| 亚洲黄色在线网站| 国产一区二区三区天码| 国产亚洲欧美日韩美女| 无码人妻精品一区二区中文| 欧美日韩国产高清电影| 在线免费看av不卡| 欧美另类videoxo高潮| 香蕉久久网站| 色综合天天综合网国产成人网| 欧美丰满艳妇bbwbbw| 亚洲午夜伦理| 91国产精品电影| 日韩手机在线视频| 免费成人美女在线观看| 91麻豆桃色免费看| 亚洲精品无码专区| 久久久久久久综合日本| 亚洲精品国产一区| 宅男在线观看免费高清网站| 亚洲曰韩产成在线| 99999精品视频| 成人av集中营| 日韩一级在线观看| 亚洲精品乱码久久久久久久| 深爱激情久久| 久久最新资源网| 国产精品午夜影院| 麻豆一区二区三区| 国产精品二区在线| 青青草在线视频免费观看| 中文字幕不卡三区| www.九色.com| 欧美日韩视频免费观看| 欧美一区日本一区韩国一区| 精品国产av色一区二区深夜久久| 欧美另类69xxxxx| 九九久久国产精品| www五月天com| 成人一区在线观看| 日韩av电影在线观看| 国产毛片欧美毛片久久久| 成人无遮挡免费网站视频在线观看| 国产精品乱人伦| 无码粉嫩虎白一线天在线观看 | 欲求不满的岳中文字幕| 日韩成人精品一区二区| 久久免费国产精品1| 久久久国产免费| 成人动漫在线一区| 亚洲黄色一区二区三区| 日韩av影片| 欧美一级艳片视频免费观看| 久久av无码精品人妻系列试探| 在线一区免费| 青青久久av北条麻妃海外网| 国产麻豆一精品一男同| 久久久精品免费观看| 久久亚洲a v| 国产三级一区| 日韩精品久久久久久福利| 欧美成人三级在线观看| 蜜桃视频第一区免费观看| 国产午夜精品一区| av网址在线看| 精品视频1区2区3区| 瑟瑟视频在线观看| 国产视频一区三区| 国产精品久久久久久久天堂第1集| 九九九伊在人线综合| 欧美日韩国产限制| 99久久久无码国产精品性波多 | 人人妻人人澡人人爽人人欧美一区| 中文子幕无线码一区tr| 国产在线观看福利| 加勒比中文字幕精品| 欧美日韩爱爱视频| aaa一区二区三区| 亚洲少妇30p| 九九九九九九九九| 天堂网在线观看国产精品| 国产精品99久久久久久久久久久久| 青青草视频在线免费播放| a毛片不卡免费看片| 日韩视频一区二区三区在线播放 | 欧美一区二区三区激情视频| 日本成人免费在线| 美州a亚洲一视本频v色道| 精品国产老师黑色丝袜高跟鞋| 欧美一级片在线免费观看| 中国成人一区| 97se亚洲综合| av资源一区| 日韩精品亚洲精品| 久久国产视频一区| 久久精品亚洲乱码伦伦中文 | 韩国欧美国产1区| 永久免费精品视频网站| 亚洲精品aaa| 欧美成aaa人片免费看| 精品欧美一区二区精品少妇| 亚洲图片一区二区| 大乳护士喂奶hd| 亚洲专区一区| 亚州欧美一区三区三区在线| 精品福利在线| 欧美猛交免费看| 少妇精品高潮欲妇又嫩中文字幕| 午夜精品一区二区三区电影天堂| 无码人妻aⅴ一区二区三区| 久久不射中文字幕| 色99中文字幕| 国产精品免费精品自在线观看| 久久69精品久久久久久久电影好 | 久久久精品免费视频| a天堂中文在线观看| 亚洲国产另类精品专区| 一本加勒比北条麻妃| 麻豆成人久久精品二区三区红 | 伊人色综合一区二区三区影院视频 | 欧美综合一区| 114国产精品久久免费观看| 福利成人导航| 中文字幕久热精品视频在线| 国产精品伦一区二区三区| 亚洲一区二区精品视频| a级大片在线观看| 狠狠色狠狠色综合日日91app| 免费特级黄色片| 国产一区二区观看| 亚洲xxxxx性| 伊人成综合网站| 日韩在线视频网| 少妇一级淫片免费看| 色婷婷久久一区二区三区麻豆| 成人涩涩小片视频日本| 26uuu色噜噜精品一区二区| 中文字幕第17页| 亚洲福利久久| 中文字幕日韩精品一区二区| 国产精品tv| 国产精品一久久香蕉国产线看观看| 激情网站在线| 日韩一区二区精品视频| 黄频网站在线观看| 欧美精品aⅴ在线视频| 国产成人一级片| 亚洲精品成a人| 亚洲ⅴ国产v天堂a无码二区| 岛国av在线一区| 中文字幕亚洲欧洲| 美女被久久久| 全黄性性激高免费视频| 亚洲a在线视频| 婷婷久久伊人| 日韩精品导航| 国产高清精品一区| 97色婷婷成人综合在线观看| 国产成人鲁鲁免费视频a| 成人福利影视| 欧美老女人性视频| 天堂аⅴ在线地址8| 亚洲男人天堂2019| 五十路在线视频| 精品国产一区二区三区av性色 | 成人免费网站视频| 久久久免费精品视频| а√天堂官网中文在线| 中文字幕一精品亚洲无线一区 | 精品日韩免费| 欧美日韩无遮挡| 欧美日韩麻豆| 国产色综合一区二区三区| 亚洲日本va| 99re视频在线| 天堂久久av| 亚洲综合小说区| 美女精品久久| 亚洲自拍偷拍第一页| 国产美女精品视频免费播放软件| 国产欧美日韩高清| 精品3atv在线视频| 国产成+人+综合+亚洲欧美丁香花| 日本а中文在线天堂| 97精品国产97久久久久久| 都市激情久久综合| 97久久精品人人澡人人爽缅北| 97天天综合网| 97久久精品视频| 欧美大片免费观看网址| 清纯唯美日韩制服另类| 欧美成人黑人| 国产成人综合一区二区三区| 日本一区免费网站| 国产在线观看91精品一区| 欧美一区=区三区| 91网在线免费观看| 永久免费精品视频| 国产亚洲精品自在久久| 五月综合久久| 亚洲国产一区二区精品视频| 久久久久久美女精品| 丁香色欲久久久久久综合网| 亚洲看片免费| 国产视频一区二区三区在线播放| 秋霞电影网一区二区| 午夜免费看毛片| 国产宾馆实践打屁股91| 少妇一级淫免费观看| 久久久久久免费毛片精品| 成年人网站在线观看视频| 亚洲激情图片一区| 成人免费a视频| 欧美无砖专区一中文字| 国产99视频在线| 精品中文视频在线| 国产成人av在线| 9999在线视频| 国产999在线观看| 激情久久99| 亚洲精选免费视频| 国产一级久久久久毛片精品| 国产精品对白交换视频| 久久精品99久久久久久| 欧美丝袜一区二区| 国产又粗又猛又爽| 亚洲精品98久久久久久中文字幕| 美国成人毛片| 欧美成人精品激情在线观看 | 亚洲色图另类小说| 三级精品视频久久久久| av今日在线| 91视频国产高清| 性人久久久久| 亚洲天堂av免费在线观看| 一区二区三区国产在线| 伊人色在线视频| 久久久久久亚洲综合| 国产va在线播放| 在线亚洲一区观看| 手机在线观看免费av| 日韩最新免费不卡| 一区二区乱码| 国产精品乱码视频| 天天综合国产| 国产成人无码av在线播放dvd| 日本丰满少妇做爰爽爽| 欧美午夜视频网站| 天堂在线视频观看| 欧美乱大交xxxxx| 亚洲国产aⅴ精品一区二区三区| 久久久久资源| 亚洲欧美综合| 91女人视频在线观看| 日本免费黄视频| 久99久精品视频免费观看| 捆绑凌虐一区二区三区| 亚洲视频一区二区在线| 久久精品视频5| 亚洲国产精品成人精品| 成人看av片| 国产精品久久一| 天美av一区二区三区久久| 国产日韩第一页| 日本视频免费一区| 97超碰在线资源| 精品成人久久av| 亚洲av无码一区二区三区性色| 色噜噜国产精品视频一区二区 | 国产调教一区二区三区| av女优在线播放| 成人国产视频在线观看| 午夜免费激情视频| 在线成人高清不卡| 调教视频免费在线观看| 国产精品视频播放| 国产一区三区在线播放| 男女av免费观看| 91亚洲国产成人精品一区二区三 | www.youjizz.com亚洲| 欧美视频免费播放| 国产a亚洲精品| 欧美一级片免费观看| 中文亚洲字幕| 亚洲男女在线观看| 亚洲一区在线视频| 精品欧美在线观看| 欧美成人性色生活仑片| 亚洲精品大全| 一本二本三本亚洲码| 久久超级碰视频| 日韩国产第一页| 欧美一区二区播放| 污污网站在线看| 国产精品福利视频| 一二三区精品| 欧美 日本 国产| 在线欧美一区二区| 91福利在线视频| 91免费在线视频| 午夜国产欧美理论在线播放| 精品人妻在线视频| 婷婷开心久久网| 国产精品99999| 国产欧美日韩精品丝袜高跟鞋| 自拍日韩欧美| 欧美做受高潮中文字幕| 色综合天天综合网天天狠天天| 激情在线视频| 成人国产精品av| 雨宫琴音一区二区在线| 中国美女乱淫免费看视频| 欧美色区777第一页| 在线看福利影| 极品日韩久久| 91女主播在线观看| 国产精品尤物福利片在线观看| 97在线精品| 久久久无码人妻精品无码| 婷婷久久综合九色综合伊人色| 国产三级在线| 91久久久久久国产精品| 亚洲特色特黄| 免费看黄色三级| 日韩免费性生活视频播放| 亚洲色图官网| 在线观看视频黄色| 波多野结衣中文字幕一区| 波多野结衣视频在线观看| 欧美理论电影在线观看| 国产欧美一区| 伦伦影院午夜理论片| 色八戒一区二区三区| 国产在线看片| 日本10禁啪啪无遮挡免费一区二区| 韩国精品久久久| 久久午夜免费视频| 久久久999国产| 国产精品三级| 国产a级黄色片| 91精品国产综合久久福利软件| 中文字幕一区久|