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

數(shù)據(jù)庫時間慢了14個小時,Mybatis說,這個鍋我不背!

運維 數(shù)據(jù)庫運維
大家都知道,對于這類Bug本人是很感興趣的。直覺告訴我,應(yīng)該不是Mybatis的Bug,很可能是時區(qū)的問題。很好,今天又可以帶大家一起來排查Bug了,看看從這次的Bug排查中你能Get什么技能。

[[436824]]

本文轉(zhuǎn)載自微信公眾號「程序新視界」,作者二師兄。轉(zhuǎn)載本文請聯(lián)系程序新視界公眾號。

同事反饋一個問題:Mybatis插入數(shù)據(jù)庫的時間是昨天的,是不是因為生成Mybatis逆向工程生成的代碼有問題?

大家都知道,對于這類Bug本人是很感興趣的。直覺告訴我,應(yīng)該不是Mybatis的Bug,很可能是時區(qū)的問題。

很好,今天又可以帶大家一起來排查Bug了,看看從這次的Bug排查中你能Get什么技能。

這次研究的問題有點深奧,但結(jié)論很重要。Let's go!

問題猜想

同事反饋問題的時候,帶了自己的猜想:是不是數(shù)據(jù)庫字段設(shè)置為datetime導(dǎo)致?是不是Mybatis逆向工程生成的代碼中類型不一致導(dǎo)致的?

同事還要把datetime改為varchar……馬上被我制止了,說:先排查問題,再說解決方案,下午我也抽時間看看。

問題核查

第一步,檢查數(shù)據(jù)庫字段類型,是datetime的,沒問題。

第二步,檢查實體類中類型,是java.util.Date類型,沒問題。

第三步,Bug復(fù)現(xiàn)。

在Bug復(fù)現(xiàn)這一步,用到了單元測試。話說之前還跟朋友討論過單元測試的魅力,現(xiàn)在本人是越來越喜歡單元測試了。

項目基于Spring Boot的,單元測試如下(代碼已脫敏):

  1. @SpringBootTest 
  2. class DateTimeTests { 
  3.  
  4.  @Resource 
  5.  private UserMapper userMapper; 
  6.  
  7.  @Test 
  8.  public void testDate(){ 
  9.   User  user = new User(); 
  10.   // 省略其他字段 
  11.   user.setCreateDate(new Date()); 
  12.   userMapper.insertSelective(user); 
  13.  } 

執(zhí)行單元測試,查看數(shù)據(jù)庫中插入的數(shù)據(jù)。Bug復(fù)現(xiàn),時間的確是前一天的,與當(dāng)前時間相差14個小時。

經(jīng)過上面三步的排查,核實了數(shù)據(jù)庫字段和代碼中類型沒問題。單元測試也復(fù)現(xiàn)了問題,同事沒有欺騙我,總要眼見為實,哈哈。

于是基本確定是時區(qū)問題。

時區(qū)排查

檢查服務(wù)器時間

登錄測試服務(wù)器,執(zhí)行date命令,檢查服務(wù)器時間和時區(qū):

  1. [root@xxx ~]# date 
  2. 2021年 11月 25日 星期四 09:26:25 CST 
  3. [root@xxx ~]# date -R 
  4. Thu, 25 Nov 2021 09:33:34 +0800 

顯示時間是當(dāng)前時間,采用CST時間,最后的+0800,即東8區(qū),沒問題。

檢查數(shù)據(jù)庫時區(qū)

連接數(shù)據(jù)庫,執(zhí)行show命令:

  1. show variables like '%time_zone%'
  2.  
  3. +----------------------------+ 
  4. |Variable         | Value | 
  5. +----------------------------+ 
  6. |system_time_zone |CST    | 
  7. |time_zone       |SYSTEM | 
  • system_time_zone:全局參數(shù),系統(tǒng)時區(qū),在MySQL啟動時會檢查當(dāng)前系統(tǒng)的時區(qū)并根據(jù)系統(tǒng)時區(qū)設(shè)置全局參數(shù)system_time_zone的值。值為CST,與系統(tǒng)時間的時區(qū)一致。
  • time_zone:全局參數(shù),設(shè)置每個連接會話的時區(qū),默認為SYSTEM,使用全局參數(shù)system_time_zone的值。

檢查代碼中時區(qū)

在單元測試的方法內(nèi)再添加打印時區(qū)的代碼:

  1. @Test 
  2.  public void testDate(){ 
  3.   System.out.println(System.getProperty("user.timezone")); 
  4.   User  user = new User(); 
  5.   // 省略其他字段 
  6.   user.setCreateDate(new Date()); 
  7.   userMapper.insertSelective(user); 
  8.  } 

打印的時區(qū)為:

  1. Asia/Shanghai 

也就是說Java中使用的是UTC時區(qū)進行業(yè)務(wù)邏輯處理的,也是東八區(qū)的時間。

那么問題到底出在哪里呢?

問題基本呈現(xiàn)

經(jīng)過上述排查,基本上確定是時區(qū)的問題。這里,再補充一下上述相關(guān)的時區(qū)知識點。

UTC時間

UTC時間:世界協(xié)調(diào)時間(UTC)是世界上不同國家用來調(diào)節(jié)時鐘和時間的主要時間標(biāo)準(zhǔn),也就是零時區(qū)的時間。

UTC, Coordinated Universal Time是一個標(biāo)準(zhǔn),而不是一個時區(qū)。UTC 是一個全球通用的時間標(biāo)準(zhǔn)。全球各地都同意將各自的時間進行同步協(xié)調(diào) (coordinated),這也是UTC名字的來源:Universal Coordinated Time。

CST時間

CST時間:中央標(biāo)準(zhǔn)時間。

CST可以代表如下4個不同的時區(qū):

  • Central Standard Time (USA) UT-6:00,美國
  • Central Standard Time (Australia) UT+9:30,澳大利亞
  • China Standard Time UT+8:00,中國
  • Cuba Standard Time UT-4:00,古巴

再次分析

很顯然,這里與UTC時間無關(guān),它只是時間標(biāo)準(zhǔn)。目前Mysql中的system_time_zone是CST,而CST可以代表4個不同的時區(qū),那么,Mysql把它當(dāng)做哪個時區(qū)進行處理了呢?

簡單推算一下,中國時間是UT+8:00,美國是 UT-6:00,當(dāng)傳入中國時間,直接轉(zhuǎn)換為美國時間(未考慮時區(qū)問題),時間便慢了14個小時。

既然知道了問題,那么解決方案也就有了。

解決方案

針對上述問題可通過數(shù)據(jù)庫層面和代碼層面進行解決。

方案一:修改數(shù)據(jù)庫時區(qū)

既然是MySQL理解錯了CST指定的時區(qū),那么就將其設(shè)置為正確的。

連接Mysql數(shù)據(jù)庫,設(shè)置正確的時區(qū):

  1. [root@xxxxx ~]# mysql -uroot -p 
  2.  
  3. mysql> set global time_zone = '+8:00'
  4.  
  5. mysql> set time_zone = '+8:00' 
  6.  
  7. mysql> flush privileges

再次執(zhí)行show命令:

  1. show variables like '%time_zone%'
  2.  
  3. +----------------------------+ 
  4. |Variable         | Value | 
  5. +----------------------------+ 
  6. |system_time_zone |CST    | 
  7. |time_zone       |+08:00 | 

可以看到時區(qū)已經(jīng)成為東八區(qū)的時間了。再次執(zhí)行單元測試,問題得到解決。

此種方案也可以直接修改MySQL的my.cnf文件進行指定時區(qū)。

方案二:修改數(shù)據(jù)庫連接參數(shù)

在代碼連接數(shù)據(jù)庫時,通過參數(shù)指定所使用的時區(qū)。

在配置數(shù)據(jù)庫連接的URL后面添加上指定的時區(qū)serverTimezone=Asia/Shanghai:

  1. url: jdbc:mysql://xx.xx.xx.xx:3306/db_name?useUnicode=true&characterEncoding=utf8&autoReconnect=true&serverTimezone=Asia/Shanghai 

再次執(zhí)行單元測試,問題同樣可以得到解決。

問題完了?

經(jīng)過上述分析與操作,時區(qū)的問題已經(jīng)解決了。問題就這么完事了嗎?為什么是這樣呢?

為了驗證時區(qū)問題,在時區(qū)錯誤的數(shù)據(jù)庫中,創(chuàng)建了一個字段,該字段類型為datetime,默認值為CURRENT_TIMESTAMP。

那么,此時插入一條記錄,讓Mysql自動生成該字段的時間,你猜該字段的時間是什么?中國時間。

神奇不?為什么同樣是CST時區(qū),系統(tǒng)自動生成的時間是正確的,而代碼插入的時間就有時差問題呢?

到底是Mysql將CST時區(qū)理解為美國時間了,還是Mybatis、連接池或驅(qū)動程序?qū)⑵淅斫鉃槊绹鴷r間了?

重頭戲開始

為了追查到底是代碼中哪里出了問題,先開啟Mybatis的debug日志,看看insert時是什么值:

  1. 2021-11-25 11:05:28.367 [|1637809527983|] DEBUG 20178 --- [   scheduling-1] c.h.s.m.H.listByCondition                : ==> Parameters: 2021-11-25 11:05:27(String), 0(Integer), 1(Integer), 2(Integer), 3(Integer), 4(Integer) 

上面是insert時的參數(shù),也就是說在Mybatis層面時間是沒問題的。排除一個。

那是不是連接池或驅(qū)動程序的問題?連接池本身來講跟數(shù)據(jù)庫連接的具體操作關(guān)系不大,就直接來排查驅(qū)動程序。

Mybatis是xml中定義日期字段類型為TIMESTAMP,扒了一下mysql-connector-Java-8.0.x的源碼,發(fā)現(xiàn)SqlTimestampValueFactory是用來處理TIMESTAMP類型的。

在SqlTimestampValueFactory的構(gòu)造方法上打上斷點,執(zhí)行單元測試:

timezone

可以明確的看到,Calendar將時區(qū)設(shè)置為Locale.US,也就是美國時間,時區(qū)為CST,offset為-21600000。-21600000單位為毫秒,轉(zhuǎn)化為小時,恰好是“-6:00”,這與北京時間“GMT+08:00”恰好相差14個小時。

于是一路往上最終追溯調(diào)用鏈路,該TimeZone來自NativeServerSession的serverTimeZone,而serverTimeZone的值是由NativeProtocol類的configureTimezone方法設(shè)置的。

  1. public void configureTimezone() { 
  2.         String configuredTimeZoneOnServer = this.serverSession.getServerVariable("time_zone"); 
  3.  
  4.         if ("SYSTEM".equalsIgnoreCase(configuredTimeZoneOnServer)) { 
  5.             configuredTimeZoneOnServer = this.serverSession.getServerVariable("system_time_zone"); 
  6.         } 
  7.  
  8.         String canonicalTimezone = getPropertySet().getStringProperty(PropertyKey.serverTimezone).getValue(); 
  9.  
  10.         if (configuredTimeZoneOnServer != null) { 
  11.             // user can override this with driver properties, so don't detect if that's the case 
  12.             if (canonicalTimezone == null || StringUtils.isEmptyOrWhitespaceOnly(canonicalTimezone)) { 
  13.                 try { 
  14.                     canonicalTimezone = TimeUtil.getCanonicalTimezone(configuredTimeZoneOnServer, getExceptionInterceptor()); 
  15.                 } catch (IllegalArgumentException iae) { 
  16.                     throw ExceptionFactory.createException(WrongArgumentException.class, iae.getMessage(), getExceptionInterceptor()); 
  17.                 } 
  18.             } 
  19.         } 
  20.  
  21.         if (canonicalTimezone != null && canonicalTimezone.length() > 0) { 
  22.          // 此處設(shè)置TimeZone 
  23.             this.serverSession.setServerTimeZone(TimeZone.getTimeZone(canonicalTimezone)); 
  24.  
  25.             if (!canonicalTimezone.equalsIgnoreCase("GMT") && this.serverSession.getServerTimeZone().getID().equals("GMT")) { 
  26.                 throw ExceptionFactory.createException(WrongArgumentException.class, Messages.getString("Connection.9", new Object[] { canonicalTimezone }), 
  27.                         getExceptionInterceptor()); 
  28.             } 
  29.         } 
  30.  
  31.     } 

debug跟蹤一下上述代碼,顯示信息如下:

CST獲得

至此,通過canonicalTimezone值的獲取,可以看出URL后面配置serverTimezone=Asia/Shanghai的作用了。其中,上面第一個代碼塊獲取time_zone的值,第二個代碼塊中獲取system_time_zone的值。這與查詢數(shù)據(jù)庫獲得的值一致。

因為出問題時并未在url中添加參數(shù)serverTimezone=Asia/Shanghai,所以走canonicalTimezone為null的情況。隨后邏輯中調(diào)用了TimeUtil.getCanonicalTimezone方法:

  1. public static String getCanonicalTimezone(String timezoneStr, ExceptionInterceptor exceptionInterceptor) { 
  2.         if (timezoneStr == null) { 
  3.             return null
  4.         } 
  5.  
  6.         timezoneStr = timezoneStr.trim(); 
  7.  
  8.         // handle '+/-hh:mm' form ... 
  9.         if (timezoneStr.length() > 2) { 
  10.             if ((timezoneStr.charAt(0) == '+' || timezoneStr.charAt(0) == '-') && Character.isDigit(timezoneStr.charAt(1))) { 
  11.                 return "GMT" + timezoneStr; 
  12.             } 
  13.         } 
  14.  
  15.         synchronized (TimeUtil.class) { 
  16.             if (timeZoneMappings == null) { 
  17.                 loadTimeZoneMappings(exceptionInterceptor); 
  18.             } 
  19.         } 
  20.  
  21.         String canonicalTz; 
  22.         if ((canonicalTz = timeZoneMappings.getProperty(timezoneStr)) != null) { 
  23.             return canonicalTz; 
  24.         } 
  25.  
  26.         throw ExceptionFactory.createException(InvalidConnectionAttributeException.class, 
  27.                 Messages.getString("TimeUtil.UnrecognizedTimezoneId", new Object[] { timezoneStr }), exceptionInterceptor); 
  28.     } 

上述代碼中最終走到了loadTimeZoneMappings(exceptionInterceptor);方法:

  1. private static void loadTimeZoneMappings(ExceptionInterceptor exceptionInterceptor) { 
  2.         timeZoneMappings = new Properties(); 
  3.         try { 
  4.             timeZoneMappings.load(TimeUtil.class.getResourceAsStream(TIME_ZONE_MAPPINGS_RESOURCE)); 
  5.         } catch (IOException e) { 
  6.             throw ExceptionFactory.createException(Messages.getString("TimeUtil.LoadTimeZoneMappingError"), exceptionInterceptor); 
  7.         } 
  8.         // bridge all Time Zone ids known by Java 
  9.         for (String tz : TimeZone.getAvailableIDs()) { 
  10.             if (!timeZoneMappings.containsKey(tz)) { 
  11.                 timeZoneMappings.put(tz, tz); 
  12.             } 
  13.         } 
  14.     } 

該方法加載了配置文件"/com/mysql/cj/util/TimeZoneMapping.properties"里面的值,經(jīng)過轉(zhuǎn)換,timeZoneMappings中,對應(yīng)CST的為"CST"。

最終得到canonicalTimezone為“CST”,而TimeZone獲得是通過TimeZone.getTimeZone(canonicalTimezone)方法獲得的。

也就是說TimeZone.getTimeZone("CST")的值為美國時間。寫個單元測試驗證一下:

  1. public class TimeZoneTest { 
  2.  
  3.  @Test 
  4.  public void testTimeZone(){ 
  5.   System.out.println(TimeZone.getTimeZone("CST")); 
  6.  } 

打印結(jié)果:

  1. sun.util.calendar.ZoneInfo[id="CST",offset=-21600000,dstSavings=3600000,useDaylight=true,transitions=235,lastRule=java.util.SimpleTimeZone[id=CST,offset=-21600000,dstSavings=3600000,useDaylight=true,startYear=0,startMode=3,startMonth=2,startDay=8,startDayOfWeek=1,startTime=7200000,startTimeMode=0,endMode=3,endMonth=10,endDay=1,endDayOfWeek=1,endTime=7200000,endTimeMode=0]] 

很顯然,該方法傳入CST之后,默認是美國時間。

至此,問題原因基本明朗:

  • Mysql中設(shè)置的server_time_zone為CST,time_zone為SYSTEM。
  • Mysql驅(qū)動查詢到time_zone為SYSTEM,于是使用server_time_zone的值,為”CST“。
  • JDK中TimeZone.getTimeZone("CST")獲得的值為美國時區(qū);
  • 以美國時區(qū)構(gòu)造的Calendar類;
  • SqlTimestampValueFactory使用上述Calendar來格式化系統(tǒng)獲取的中國時間,時差問題便出現(xiàn)了;
  • 最終反映在數(shù)據(jù)庫數(shù)據(jù)上就是錯誤的時間。

serverVariables變量

再延伸一下,其中server_time_zone和time_zone都來自于NativeServerSession的serverVariables變量,該變量在NativeSession的loadServerVariables方法中進行初始化,關(guān)鍵代碼:

  1. if (versionMeetsMinimum(5, 1, 0)) { 
  2.                 StringBuilder queryBuf = new StringBuilder(versionComment).append("SELECT"); 
  3.                 queryBuf.append("  @@session.auto_increment_increment AS auto_increment_increment"); 
  4.                 queryBuf.append(", @@character_set_client AS character_set_client"); 
  5.                 queryBuf.append(", @@character_set_connection AS character_set_connection"); 
  6.                 queryBuf.append(", @@character_set_results AS character_set_results"); 
  7.                 queryBuf.append(", @@character_set_server AS character_set_server"); 
  8.                 queryBuf.append(", @@collation_server AS collation_server"); 
  9.                 queryBuf.append(", @@collation_connection AS collation_connection"); 
  10.                 queryBuf.append(", @@init_connect AS init_connect"); 
  11.                 queryBuf.append(", @@interactive_timeout AS interactive_timeout"); 
  12.                 if (!versionMeetsMinimum(5, 5, 0)) { 
  13.                     queryBuf.append(", @@language AS language"); 
  14.                 } 
  15.                 queryBuf.append(", @@license AS license"); 
  16.                 queryBuf.append(", @@lower_case_table_names AS lower_case_table_names"); 
  17.                 queryBuf.append(", @@max_allowed_packet AS max_allowed_packet"); 
  18.                 queryBuf.append(", @@net_write_timeout AS net_write_timeout"); 
  19.                 queryBuf.append(", @@performance_schema AS performance_schema"); 
  20.                 if (!versionMeetsMinimum(8, 0, 3)) { 
  21.                     queryBuf.append(", @@query_cache_size AS query_cache_size"); 
  22.                     queryBuf.append(", @@query_cache_type AS query_cache_type"); 
  23.                 } 
  24.                 queryBuf.append(", @@sql_mode AS sql_mode"); 
  25.                 queryBuf.append(", @@system_time_zone AS system_time_zone"); 
  26.                 queryBuf.append(", @@time_zone AS time_zone"); 
  27.                 if (versionMeetsMinimum(8, 0, 3) || (versionMeetsMinimum(5, 7, 20) && !versionMeetsMinimum(8, 0, 0))) { 
  28.                     queryBuf.append(", @@transaction_isolation AS transaction_isolation"); 
  29.                 } else { 
  30.                     queryBuf.append(", @@tx_isolation AS transaction_isolation"); 
  31.                 } 
  32.                 queryBuf.append(", @@wait_timeout AS wait_timeout"); 
  33.  
  34.                 NativePacketPayload resultPacket = sendCommand(this.commandBuilder.buildComQuery(null, queryBuf.toString()), false, 0); 
  35.                 Resultset rs = ((NativeProtocol) this.protocol).readAllResults(-1, false, resultPacket, falsenull
  36.                         new ResultsetFactory(Type.FORWARD_ONLY, null)); 
  37.                 Field[] f = rs.getColumnDefinition().getFields(); 
  38.                 if (f.length > 0) { 
  39.                     ValueFactory<String> vf = new StringValueFactory(this.propertySet); 
  40.                     Row r; 
  41.                     if ((r = rs.getRows().next()) != null) { 
  42.                         for (int i = 0; i < f.length; i++) { 
  43.                             this.protocol.getServerSession().getServerVariables().put(f[i].getColumnLabel(), r.getValue(i, vf)); 
  44.                         } 
  45.                     } 
  46.                 } 

在上述StringBuilder的append操作中,有"@@time_zone AS time_zone"和"@@system_time_zone AS system_time_zone"兩個值,然后查詢數(shù)據(jù)庫,從數(shù)據(jù)庫獲得值之后,put到serverVariables中。

再來debug一下:

system_time_zone

可以看出system_time_zone的值為CST。

time_zone

同樣time_zone的值為“SYSTEM”。

根據(jù)代碼中的提示,拼接與代碼一樣的SQL查詢一下數(shù)據(jù)庫:

  1. select @@time_zone; 
  2.  
  3. SYSTEM 

值的確是“SYSTEM”。此時,我們又得出另外一個查詢Mysql當(dāng)前時區(qū)的方法。

至此,該問題的排查完美收官。大出一口氣。

小結(jié)

在上述問題排查的過程中,多次用到單元測試,這也是單元測試的魅力所在,用最簡單的代碼,最輕量的邏輯,最節(jié)省時間的方式來驗證和追蹤錯誤。

再回顧一下上述Bug排查中用到和學(xué)到的知識點:

  • Linux日期查看,時區(qū)查看及衍生如何配置時區(qū);
  • Mysql時區(qū)查看;
  • Spring Boot單元測試;
  • Java時區(qū)獲取;
  • UTC時間和CST時間;
  • 兩種解決時區(qū)問題的方案;
  • 閱讀、debug Mysql驅(qū)動源代碼;
  • TimeZone.getTimeZone("CST")默認時區(qū)為美國時區(qū);
  • Mysql驅(qū)動中處理時區(qū)問題基本流程邏輯;
  • Mybatis debug日志相關(guān)打印;
  • 其他相關(guān)知識。 

通過本篇Bug查找的文章,你學(xué)到了什么?如果有那么一點啟發(fā),不要吝嗇,給點個贊吧!

 

責(zé)任編輯:武曉燕 來源: 程序新視界
相關(guān)推薦

2017-09-12 16:18:22

ICO區(qū)塊鏈互聯(lián)網(wǎng)+

2019-06-03 14:38:11

AWS挖掘機光纜

2020-02-20 16:21:46

遠程辦公

2015-12-09 13:51:21

Intelskylake散熱器

2021-04-13 17:38:38

區(qū)塊鏈比特幣安全

2024-08-05 08:00:53

2018-10-19 16:35:20

運維

2018-05-02 14:30:33

數(shù)據(jù)庫運維優(yōu)化故障

2018-05-08 09:49:15

數(shù)據(jù)庫運維優(yōu)化

2019-12-03 13:57:38

CIO背鍋IT

2019-01-16 18:11:28

程序員技能開發(fā)者

2017-08-23 17:11:40

WI-FI流量路由器

2021-04-16 09:20:34

黑客DDoS網(wǎng)絡(luò)攻擊

2023-04-26 07:16:25

游戲掉幀CPU

2019-12-17 10:01:40

開發(fā)技能代碼

2017-06-09 13:36:33

人工智能深度學(xué)習(xí)

2017-09-25 10:52:27

2020-12-09 11:00:44

Nginx 運維Tomcat

2021-11-03 16:25:26

Linux磁盤空間命令

2025-03-24 08:00:00

數(shù)據(jù)庫開發(fā)代碼
點贊
收藏

51CTO技術(shù)棧公眾號

午夜在线视频| 精品成人无码久久久久久| 99re热精品视频| 天天操天天干天天综合网| 欧美日韩在线播放一区二区| 做爰无遮挡三级| 欧美精品三区| 亚洲日本中文字幕免费在线不卡| 亚洲怡红院在线| 97超碰免费在线| 国产精品免费久久久久| 精品久久sese| 国产精品嫩草影院精东| 99亚洲视频| 久久国产精品影片| 人妻aⅴ无码一区二区三区 | 色偷偷久久人人79超碰人人澡| 一区二区av| 亚洲 另类 春色 国产| 久久超级碰视频| 欧美在线观看网址综合| 丁香花五月激情| 精品黄色一级片| 亚洲精品二三区| 91精产国品一二三| 视频欧美精品| 欧美午夜精品理论片a级按摩| 人人妻人人做人人爽| 老司机午夜在线| 国产精品欧美经典| 欧美日韩在线一二三| 免费激情视频网站| 国产精品一二三区| 成人午夜激情免费视频| 一区二区乱子伦在线播放| 亚洲综合不卡| 91国在线精品国内播放| 国产一级一级片| 中文字幕一区二区三区乱码图片| 中文字幕国产精品| 国产毛片欧美毛片久久久| 日韩精选在线| 日韩精品小视频| 精品视频站长推荐| 另类在线视频| 日韩h在线观看| 免费日本黄色网址| 国产一区二区在线视频你懂的| 日韩免费性生活视频播放| 伊人成人222| 91精品一区| 国产综合色精品一区二区三区| 国产97在线亚洲| 免费看一级视频| 日本欧美一区二区三区| 国产精品久久久久久网站 | 丝袜在线观看| 亚洲国产精品久久艾草纯爱| 欧美在线一区视频| 乱馆动漫1~6集在线观看| 红桃视频成人在线观看| 国产高清精品在线观看| 黑人巨大精品| 欧美三级欧美一级| xxxx在线免费观看| 亚洲欧美日本国产| 亚洲国产精品一区二区三区| www.久久国产| 日韩亚洲一区在线| 久久91亚洲精品中文字幕奶水| 久艹视频在线观看| 亚洲在线国产日韩欧美| 国产精品久久久久久网站| 国产精品无码在线播放| 成人av免费在线| 欧美日韩一区二区三区免费| 欧美三级黄网| 亚洲一线二线三线视频| 亚洲精品中文字幕无码蜜桃| 涩涩涩久久久成人精品| 欧美大胆人体bbbb| 三级网站在线免费观看| 四虎国产精品免费观看| 欧美国产视频日韩| 老熟妇仑乱一区二区av| 久久99精品久久久久| av蓝导航精品导航| 久久久久国产精品嫩草影院| 国产精品国产a| www.av蜜桃| 日本精品在线一区| 91精品国产免费久久综合| 国产香蕉精品视频| 国产精品美女久久久久久不卡| 精品国产一区二区三区久久久| 国产真实的和子乱拍在线观看| 米奇777在线欧美播放| 91精品啪aⅴ在线观看国产| 欧美性猛交 xxxx| 国产精品女主播在线观看| 日韩福利二区| 日本乱理伦在线| 欧美视频在线一区| 久久一区二区电影| 88国产精品视频一区二区三区| 欧美亚洲成人网| 午夜精品无码一区二区三区| 欧美国产亚洲另类动漫| 精品中文字幕av| 天堂av一区| 中文字幕一区日韩电影| 国产精品视频一区在线观看| 国产91综合网| 日韩人妻精品一区二区三区| 日韩不卡免费高清视频| 亚洲第一福利在线观看| 91麻豆免费视频网站| 全部av―极品视觉盛宴亚洲| 精品在线视频一区二区| 女同一区二区免费aⅴ| 欧美日韩专区在线| 性欧美精品中出| 亚洲永久视频| 久久精品国产一区二区三区日韩| 国产日韩在线观看一区| 国产亚洲1区2区3区| 2018国产在线| a级日韩大片| 欧美成人亚洲成人| 国产精品久久久久精| 欧美国产精品一区二区| 亚洲色图38p| 免费看av成人| 4p变态网欧美系列| 午夜影院在线视频| 亚洲成人你懂的| www.啪啪.com| 亚洲午夜91| 国产伦理一区二区三区| 牛牛电影国产一区二区| 日韩午夜激情av| 国产免费无码一区二区视频| 国产一区二区在线电影| 激情视频小说图片| 日韩在线成人| 色综合久久久888| 国产小视频免费观看| 亚洲在线视频网站| 国产精品一区二区无码对白| 亚洲香蕉网站| 精品国产免费一区二区三区 | 精品99在线| 国产精品女人久久久久久| 91高清在线视频| 精品视频1区2区| 三级在线观看免费大全| 国产真实乱子伦精品视频| 成人高清dvd| 国产精品2023| 欧美在线xxx| av成人手机在线| 91超碰这里只有精品国产| 欧洲猛交xxxx乱大交3| 国产.精品.日韩.另类.中文.在线.播放| 男女爱爱视频网站| 国产精品视屏| 日韩美女在线看| 拍真实国产伦偷精品| 日韩精品一区二区三区四区| 青青国产在线观看| 中文字幕精品三区| 激情小说欧美色图| 男女精品网站| 在线视频福利一区| av成人综合| 国产精品福利网| 爆操欧美美女| 亚洲欧洲激情在线| 国产男女裸体做爰爽爽| 午夜精品一区二区三区电影天堂| 午夜时刻免费入口| 国产一区二区网址| 久久人妻精品白浆国产| 亚洲午夜精品一区二区国产| 韩国成人动漫在线观看| 欧美爱爱视频| 国外成人性视频| 婷婷激情在线| 日韩成人在线免费观看| 在线观看国产精品入口男同| 亚洲在线视频网站| 91麻豆精品久久毛片一级| 成人一区在线看| 亚洲77777| 亚洲看片免费| 精品国产一区二区三区在线| 九九在线高清精品视频| 成人国产一区二区| 久久av影院| 欧美一级黄色网| 污视频网站在线免费| 亚洲视频在线看| 手机在线观看毛片| 欧美一区二区三区四区视频| 亚洲精品国产无码| 亚洲第一狼人社区| 极品魔鬼身材女神啪啪精品| 久久精品一区八戒影视| 欧美在线一级片| 国产乱人伦偷精品视频不卡| 99精品视频播放| 亚洲福利国产| 欧美日韩视频免费| 国产精品成人a在线观看| 日本视频一区在线观看| 国产福利一区二区精品秒拍| 亚洲一区二区三区毛片| 国产成+人+综合+亚洲欧美| 2019中文字幕在线观看| 免费在线观看的电影网站| xxxxx成人.com| 77导航福利在线| 亚洲欧美日韩视频一区| 午夜av免费在线观看| 欧美成人三级在线| 精品国产乱码一区二区三| 欧美日韩一二三| 最近中文字幕在线免费观看| 一本色道久久综合亚洲91 | 亚洲精品1234| 久久久久久久久久伊人| 亚洲成人最新网站| 宅男在线精品国产免费观看| 色男人天堂综合再现| 日韩三级电影免费观看| 国产在视频线精品视频www666| 精品国产一区二区三区麻豆小说| 国内自拍欧美| 国产精品亚洲一区| 成人激情自拍| 精品乱码一区二区三区| 国产一区在线电影| 精品免费国产| 西野翔中文久久精品国产| 久久亚洲综合网| 精品福利久久久| 伊甸园精品99久久久久久| 91视频精品| 免费在线精品视频| 狠狠88综合久久久久综合网| www.成年人视频| av成人激情| 黄色片一级视频| 美腿丝袜亚洲一区| www.com久久久| 国产99久久精品| 完美搭档在线观看| 91蝌蚪porny| 99国产精品免费| 亚洲图片激情小说| 国产一级做a爰片在线看免费 | 中文字幕日本人妻久久久免费| 欧美日韩免费一区二区三区视频| 亚洲一区中文字幕在线| 日韩一区二区三区免费看| 高清国产mv在线观看| 日韩av最新在线观看| av在线收看| 欧美成人黑人xx视频免费观看| bl视频在线免费观看| 欧美亚洲视频在线观看| 黄色成人小视频| 99se婷婷在线视频观看| 美国成人xxx| 五月天国产一区| 欧美日韩亚洲国产精品| 成人亚洲视频在线观看| 国产一区欧美一区| 国产伦精品一区二区三区妓女| 国产精品欧美一区喷水| 日本少妇毛茸茸高潮| 在线精品亚洲一区二区不卡| av网站在线观看免费| 亚洲乱码一区二区| 成人福利片网站| 日本精品视频在线| 精品网站999| 日韩电影免费观看在| 欧美视频在线观看| 中文字幕第80页| 成人自拍视频在线| 羞羞在线观看视频| 狠狠色狠狠色综合日日五| 国产毛片在线视频| 亚洲欧美第一页| 国产网红在线观看| 国产精品一久久香蕉国产线看观看 | 欧美wwwww| 波多野结衣乳巨码无在线| 久久精品国产免费看久久精品| 国产精品成人99一区无码| 中文天堂在线一区| 成人免费视频毛片| 日韩一区二区三区四区| 色视频在线免费观看| 欧美一乱一性一交一视频| 久久精品免视看国产成人| 色阁综合av| 免费视频一区| 韩国三级视频在线观看| 综合久久一区二区三区| 中文字幕一区二区三区人妻| 亚洲欧美电影院| 中文在线a天堂| 国产丝袜精品第一页| 免费不卡av| 999国内精品视频在线| 91麻豆精品国产91久久久平台 | 国产一区二区三区黄视频| 色噜噜日韩精品欧美一区二区| 亚洲国产色一区| 国产成人精品一区二区无码呦 | 欧美成人aa大片| 理论片午午伦夜理片在线播放| 91chinesevideo永久地址| 99a精品视频在线观看| 黄黄视频在线观看| 国产一区二区在线视频| 999精品视频在线观看播放 | www.蜜臀av.com| 久久色免费在线视频| 免费视频观看成人| 亚洲精品不卡| 日本亚洲最大的色成网站www| 3d动漫精品啪啪一区二区下载| 亚洲国产综合在线| 色wwwwww| 欧美激情国产精品| 成人精品毛片| 欧美网站免费观看| 99精品欧美一区二区三区小说| 国产熟妇久久777777| 欧美日韩在线一区| 青青色在线视频| 国产999精品| 色综合久久网| 亚洲精品乱码久久久久久动漫| 1000部国产精品成人观看| 国产精品一区二区三区在线免费观看 | 你懂的国产精品| 精品国产aⅴ一区二区三区东京热| 亚洲九九爱视频| 亚洲乱码精品久久久久..| 国内精品一区二区三区四区| 精品嫩草影院| av无码精品一区二区三区| 欧美极品xxx| 国产又爽又黄免费软件| 色综合久久久久久中文网| 国产一区丝袜| 欧美成人精品欧美一级乱| 国产精品国产三级国产普通话三级 | 麻豆视频在线看| 欧美二区在线| 麻豆成人av在线| 久久久国产成人| 日韩av综合网| 欧美成人高清视频在线观看| 日本一级黄视频| 91麻豆国产福利精品| 欧美 亚洲 另类 激情 另类| 久久精品精品电影网| 99精品中文字幕在线不卡| aa在线免费观看| 中文字幕不卡在线观看| www.蜜臀av.com| 热99久久精品| 一区二区三区在线| 一区二区不卡免费视频| 欧美伦理视频网站| 91福利在线尤物| 亚洲 日韩 国产第一区| 国产成人亚洲精品青草天美| 无码人妻一区二区三区线| 裸体女人亚洲精品一区| 亚洲美女15p| 一级黄色片在线免费观看| 欧美日韩中文字幕在线| 日本www在线观看| 久久国产主播精品| 精品一区二区三区久久久| www.日本精品| 久久大大胆人体| 国产一区二区三区日韩精品| 国产成人精品综合久久久久99| 色综合色综合色综合色综合色综合| 黄色网页在线观看| 日本日本精品二区免费| 波多野结衣一区二区三区| 国产又粗又长又大视频|