精品欧美一区二区三区在线观看 _久久久久国色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技術棧公眾號

久久久久久成人| 欧美一区二区三级| 天天久久人人| 97超碰中文字幕| 黑人一区二区三区四区五区| 精品视频在线观看日韩| 日本人视频jizz页码69| 91麻豆免费在线视频| av亚洲精华国产精华精华| 国产成人小视频在线观看| 青青青视频在线播放| 一区二区三区www污污污网站| 国产激情在线| av一区二区三区在线| 国产精品一区二区3区| 久久久精品视频在线| 精品欧美久久| 精品乱码亚洲一区二区不卡| 9久久婷婷国产综合精品性色 | 日韩经典中文字幕在线观看| 簧片在线免费看| 波多野结衣在线高清| 亚洲国产成人自拍| 国产女主播一区二区三区| 中文字幕一区2区3区| 国产日韩欧美高清免费| 久久五月情影视| 欧洲av一区二区三区| 亚洲一区二区三区在线免费 | 国产精品久久久国产盗摄| 日韩一区二区免费看| 久久久精品影院| 国产探花视频在线播放| 日韩欧美ww| 精品剧情在线观看| 6080国产精品| 四虎成人精品一区二区免费网站| 色综合天天综合在线视频| 69精品丰满人妻无码视频a片| 午夜激情视频在线| 国产欧美日韩在线观看| 久久国产精品高清| 成人av手机在线| 国产自产视频一区二区三区| 国产精品入口日韩视频大尺度| 99久久精品国产亚洲| 最新日韩av| 久久久噜噜噜久噜久久| 日日骚一区二区三区| 亚洲乱码精品| 久久亚洲影音av资源网| 一级片黄色录像| 欧美在线免费看视频| 亚洲欧美国产一区二区三区| 欧美 日本 国产| 精品亚洲免a| 亚洲精品wwwww| 日韩精品一区二区三区高清免费| 国产精品jk白丝蜜臀av小说| 亚洲第一综合天堂另类专 | 91片在线免费观看| 久久精品日产第一区二区三区| 免费激情视频网站| 91在线你懂得| 欧美一区观看| 91看片在线观看| 中文字幕在线观看不卡| 潘金莲一级淫片aaaaa免费看| 好了av在线| 亚洲小说欧美激情另类| 青青草国产精品视频| 激情视频网站在线播放色 | 在线视频播放大全| 免费看欧美美女黄的网站| 国产精品视频一区二区三区四| 在线观看不卡的av| 国产成人在线影院| 久久精品magnetxturnbtih| 欧美日韩免费做爰大片| 国产精品素人一区二区| 欧美少妇一区二区三区| av3级在线| 欧美中文字幕久久| 国产性生活一级片| 国产精品传媒| 亚洲天堂男人的天堂| 久久精品一区二区三区四区五区| 欧美日韩少妇| 国产精品444| 国产毛片久久久久| 97se狠狠狠综合亚洲狠狠| 相泽南亚洲一区二区在线播放 | 亚洲婷婷影院| 日韩中文有码在线视频| 九九九久久久久| 亚洲影音一区| 亚洲伊人久久综合| 亚洲欧美日韩免费| 中文字幕欧美三区| av免费看网址| 日韩电影精品| 日韩精品黄色网| 亚洲熟女毛茸茸| 国产一区二区三区的电影| 国产一区视频在线播放| 天天色综合久久| 中文字幕视频一区| 内射国产内射夫妻免费频道| 欧美久久久网站| 日韩精品免费视频| 日本aⅴ在线观看| 久久蜜桃精品| 91丨九色丨国产| a天堂在线资源| 午夜精品久久久久久| 色啦啦av综合| 精品国产成人| 91精品国产91久久久久久最新| 国产又粗又大又黄| 国产三级欧美三级日产三级99| www成人免费| 91精品福利观看| 一本色道久久88精品综合| 国产无遮挡免费视频| 国产麻豆9l精品三级站| 亚洲精品无人区| 精品91久久| 亚洲国产精品久久精品怡红院| 国精产品久拍自产在线网站| 视频一区二区欧美| 久久伊人一区二区| 美女搞黄视频在线观看| 欧美大胆人体bbbb| 国产黄色的视频| 另类综合日韩欧美亚洲| 日韩福利一区二区三区| 午夜精品成人av| 精品丝袜一区二区三区| www日韩精品| 成人激情小说网站| 黄色三级中文字幕| jizz性欧美2| 欧美日韩第一页| www夜片内射视频日韩精品成人| 国产精品的网站| 亚洲性图一区二区| 欧美激情偷拍自拍| 国产精品香蕉在线观看| 在线免费观看黄| 欧美日韩精品欧美日韩精品一 | 亚洲精品成人在线| 韩国一区二区在线播放| 天天射综合网视频| 91久久久久久| 在线免费观看的av| 欧美精品一区二区三区蜜桃视频 | 欧美午夜影院在线视频| 精品久久久久久中文字幕人妻最新| 一区二区三区四区五区在线 | 欧美有码在线观看| 欧美新色视频| 欧洲一区在线电影| 亚洲欧美综合7777色婷婷| 激情六月婷婷综合| 国产精品久久久影院| 136导航精品福利| 91精品国产色综合久久不卡98口| 亚洲欧美综合一区二区| 日韩欧美国产网站| 成人在线观看免费高清| 精品一区二区免费看| dy888午夜| 国产精品色呦| 国产91色在线| 久久综合之合合综合久久| 日韩免费视频一区二区| 奇米影视第四色777| 久久精品免费在线观看| 99re精彩视频| 国产精品theporn| 蜜桃传媒视频麻豆第一区免费观看| 高清av一区二区三区| 菠萝蜜影院一区二区免费| 国产富婆一级全黄大片| 天天综合色天天综合| 中文字幕 自拍| 国产一区二区三区av电影| 亚洲中文字幕无码av永久| 精品国产一级毛片| 成人动漫视频在线观看免费| 美女91在线看| 久久久精品国产亚洲| 偷拍精品一区二区三区| 欧美色图在线观看| 日韩av电影网| 中文字幕一区在线观看| 尤物网站在线观看| 久久国产三级精品| 分分操这里只有精品| 日韩一区二区在线| 好吊色欧美一区二区三区四区 | 欧美日韩高清一区二区三区| 久久久久亚洲av片无码下载蜜桃| 久久精品日韩一区二区三区| 久久久久久久久久久影视| 美女诱惑黄网站一区| 丰满人妻一区二区三区53号| 国产不卡一二三区| 99免费在线观看视频| 78精品国产综合久久香蕉| 欧美极品少妇xxxxⅹ喷水| aaa在线观看| 日韩不卡在线观看| www.成人免费视频| 欧美日韩的一区二区| 亚洲 欧美 中文字幕| 亚洲一区二区视频在线观看| 99国产精品无码| 国产亚洲自拍一区| 亚洲视频在线播放免费| 国产在线播放一区| 簧片在线免费看| 久久综合图片| 欧美 国产 综合| 狠狠色狠狠色综合日日tαg| 黄色www在线观看| 精品久久91| 久久青青草原| 久久久久久毛片免费看| 91黄色国产视频| 在线不卡一区| 国产综合色香蕉精品| 国产精品高清乱码在线观看| 2018中文字幕一区二区三区| 国产乱妇乱子在线播视频播放网站| 久久av红桃一区二区小说| 自拍视频在线| 中文字幕av一区二区三区谷原希美| 欧美成熟毛茸茸| 亚洲精品在线视频| 青青草视频在线免费观看| 亚洲成人黄色网| 国产自产一区二区| 精品国产成人在线影院| 亚洲风情第一页| 欧美变态凌虐bdsm| www.久久久久久久久久| 日韩视频免费观看高清完整版在线观看| 91久久精品无码一区二区| 欧美日韩国产高清一区二区三区 | 欧美自拍资源在线| 国产传媒欧美日韩成人精品大片| 美日韩免费视频| 久久最新网址| 亚洲欧美久久234| 国产精品国产一区| 婷婷视频在线播放| 亚洲香蕉网站| 日本欧美黄色片| 香蕉久久a毛片| 免费观看成人网| 麻豆精品一二三| 日本女人黄色片| 成人深夜在线观看| 国产三级视频网站| 中文字幕国产一区二区| 蜜臀av午夜精品久久| 一区二区三区日韩欧美| 国产成人无码精品久在线观看| 欧美性xxxx在线播放| 在线观看国产黄| 日韩美女视频一区二区在线观看| 天堂在线视频观看| 国产亚洲欧美视频| fc2ppv国产精品久久| 97成人精品区在线播放| 日本精品在线中文字幕| 91在线视频成人| 精品伊人久久久| 亚洲激情图片| 国产精品激情| 欧美私人情侣网站| 麻豆精品一区二区三区| 国产精品久久久久久在线观看| 久久精品人人爽人人爽| 手机在线免费看毛片| 精品毛片三在线观看| 中文字幕在线网站| 亚洲精品一区二区三区影院| 国内在线免费高清视频| 美女久久久久久久久久久| 欧美三级网站| 91久久久亚洲精品| 婷婷精品视频| 国产盗摄视频在线观看| 一本久道久久综合狠狠爱| 特黄视频免费观看| 91亚洲精华国产精华精华液| 欧美风情第一页| 色欧美88888久久久久久影院| a天堂视频在线| 亚洲无亚洲人成网站77777| 欧美xxxx黑人又粗又长| 国产精品丝袜视频| 亚州国产精品| 国产精品国产三级国产专区51| 蜜臀久久久久久久| 欧美双性人妖o0| 亚洲色图欧洲色图| 免费又黄又爽又猛大片午夜| 精品国产不卡一区二区三区| 日韩大片在线永久免费观看网站| 欧美亚洲在线视频| 香蕉大人久久国产成人av| 午夜精品视频在线观看一区二区| 在线视频精品| 国产污在线观看| 亚洲日本一区二区三区| 中文字幕日本视频| 亚洲欧美日韩精品| 高清在线视频不卡| 国产99午夜精品一区二区三区| 久久在线免费| www.99av.com| 国产欧美日韩在线| 台湾佬中文在线| 亚洲高清一二三区| 美女网站视频在线| 7777精品伊久久久大香线蕉语言| 99精品视频在线| 中文久久久久久| 久久精品一区二区| 天天综合天天干| 亚洲激情成人网| 岛国毛片av在线| 国产成人女人毛片视频在线| 在线国产一区| 国产黑丝在线视频| 亚洲婷婷国产精品电影人久久| 亚洲午夜无码久久久久| 国产亚洲一区精品| 精品无人乱码一区二区三区| 天堂va久久久噜噜噜久久va| 日本人妖一区二区| 快灬快灬一下爽蜜桃在线观看| 欧洲一区二区av| 999在线视频| 成人激情视频网| 综合激情视频| 永久免费看片在线观看| 亚洲一区中文在线| 国产成人无码www免费视频播放| 久久久在线观看| 欧美精品中文字幕亚洲专区| 欧美 日韩 国产在线观看| 26uuu欧美| 国产午夜麻豆影院在线观看| 国产亚洲福利一区| 狂野欧美性猛交xxxx| 一区二区三区一级片| 国产成人午夜精品影院观看视频 | 国产免费亚洲高清| 久久精品影视| xxxx国产视频| 亚洲国产综合91精品麻豆| 先锋av资源站| 国产97在线播放| 国产高清一区| 免费观看黄网站| 香蕉av福利精品导航| 欧美孕妇性xxxⅹ精品hd| 国产在线a不卡| 亚洲一级电影| 免费视频91蜜桃| 日韩一区二区三区四区五区六区| 欧美78videosex性欧美| 久久一区二区三区欧美亚洲| 麻豆一区二区三区| 国产精品自拍视频一区| 亚洲人成欧美中文字幕| 国产一区二区三区黄网站| 精品视频在线观看一区| 国产视频在线观看一区二区三区 | 久久精品99国产精| 亚洲码在线观看| 国产精品一区三区在线观看| 欧美成人高潮一二区在线看| 欧美国产成人精品| 国产v在线观看| 国产成人精品免高潮费视频| 一区二区三区四区日韩| 草草影院第一页| 日韩一区二区三区视频在线 | 成人国产精品久久久| 亚洲乱码久久| 日韩av手机在线免费观看| 日韩美女av在线| 亚洲高清在线一区| 密臀av一区二区三区| 亚洲网友自拍偷拍|