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

慢查詢日志中的 Lock_Time 從哪里來?

數據庫 MySQL
今天我們就一起來看看,Lock_Time 包含哪些鎖等待時間、以及是怎么計算得到的?

經常關注慢查詢日志的讀者,和 Lock_time 應該算是老相識了,大家對這位老相識了解有多少呢?

研究 Lock_time 之前,我對它的了解,僅限于它表示鎖等待時間。至于它包含哪些鎖等待時間、怎么計算得到的,我并不清楚。

所以,我一直有個困惑:為什么有些 SQL 執(zhí)行時間很長,Lock_time 卻很小(例如:0.001 秒)?

今天我們就一起來看看,Lock_time 包含哪些鎖等待時間、以及是怎么計算得到的?

正文

整體介紹

Lock_time 由兩部分相加得到:

  • 表鎖等待時間,如果 SQL 中包含多個表,則是多個表鎖等待時間之和。
  • 行鎖等待時間,如果 SQL 執(zhí)行過程中需要對多條記錄加鎖,則是多個行鎖等待時間之和。

對 InnoDB 來說,DML、DQL 對記錄進行增刪改查操作時,如需加鎖,都是加行級別的共享鎖、排他鎖,而不加表級別的共享鎖、排他鎖。

共享鎖又稱作 S 鎖,排他鎖又稱作 X 鎖。

那么,InnoDB 有表級別的共享鎖、排他鎖嗎?

別說,還真有!

不過,不常有!

只有執(zhí)行 LOCK TABLES ... [READ | WRITE],并且系統變量 innodb_table_locks = 1、auto_commit = 0,InnoDB 才會加表級別的共享鎖、排他鎖。

從代碼注釋和官方文檔對 innodb_table_locks 的介紹來看,執(zhí)行存儲過程和觸發(fā)器時,InnoDB 也可能會加表級別的共享鎖、排他鎖,我們就不展開介紹了。

如果 InnoDB 加了表級別的共享鎖、排他鎖,Lock_time 包含表鎖等待時間,我們比較好理解。

如果我們執(zhí)行 DML、DQL,InnoDB 沒有加表級別的共享鎖、排他鎖,Lock_time 里還包含表鎖等待時間嗎?

這個問題,就得看用什么標準了:

  • 嚴格來說,Lock_time 就不包含表鎖等待時間了。
  • 不嚴格來說,Lock_time 還是包含表鎖等待時間的(InnoDB 采用了這個標準)。

接下來,我們通過源碼,進入表鎖、行鎖等待時間的實現邏輯,來一睹芳容。

表鎖等待時間

我們先來看一下表鎖等待時間實現邏輯的堆棧:

| > mysql_execute_command(THD*, bool) sql/sql_parse.cc:4688
| + > Sql_cmd_dml::execute(THD*) sql/sql_select.cc:574
| + - > lock_tables(...) sql/sql_base.cc:6899
| + - x > mysql_lock_tables(...) sql/lock.cc:337
| + - x = > lock_external(THD*, TABLE**, unsigned int) sql/lock.cc:393
| + - x = | > handler::ha_external_lock(THD*, int) sql/handler.cc:7841
| + - x = | + > ha_innobase::external_lock(THD*, int) storage/innobase/handler/ha_innodb.cc:18869

Sql_cmd_dml::execute() 調用 lock_tables() 對多個表加鎖。

// sql/sql_base.cc
bool lock_tables(THD *thd, Table_ref *tables, uint count, uint flags) {
  ...
  if (!thd->locked_tables_mode) {
    ...
    if (!(thd->lock =
          mysql_lock_tables(thd, start, (uint)(ptr - start), flags)))
      return true;
    ...
  }
  ...
}

lock_tables() 調用 mysql_lock_tables() 對多個表加鎖。

// sql/lock.cc
MYSQL_LOCK *mysql_lock_tables(THD *thd, TABLE **tables, size_t count,
                              uint flags) {
  ...
  // 記錄開始時間
  ulonglong lock_start_usec = my_micro_time();
  ...
  if (sql_lock->table_count &&
      lock_external(thd, sql_lock->table, sql_lock->table_count)) {
    /* Clear the lock type of all lock data to avoid reusage. */
    reset_lock_data_and_free(&sql_lock);
    goto end;
  }
  ...
  // lock_external() 執(zhí)行完成之后
  // 當前時間減去開始時間
  // 就是表鎖等待時間
  ulonglong lock_end_usec = my_micro_time();
  thd->inc_lock_usec(lock_end_usec - lock_start_usec);
  ...
}

mysql_lock_tables() 調用 lock_external() 之前,先把當前時間記錄下來,作為表鎖等待的開始時間。

然后調用 lock_external() 對多個表加鎖。

最后,調用 thd->inc_lock_usec() 把表鎖等待時間累加到 server 層線程對象(thd)的 m_lock_usec 屬性中。

// sql/lock.cc
static int lock_external(THD *thd, TABLE **tables, uint count) {
  ...
  // 循環(huán) SQL 中的表
  for (i = 1; i <= count; i++, tables++) {
    assert((*tables)->reginfo.lock_type >= TL_READ);
    // 默認鎖類型為寫鎖
    // 對應到 InnoDB 的鎖類型就是排他鎖(X)
    lock_type = F_WRLCK; /* Lock exclusive */
    // 如果以只讀方式打開表的數據文件(.ibd)或者
    // lock_type 大于等于 TL_READ(2) 并且
    // lock_type 小于等于 TL_READ_NO_INSERT(5)
    // 則說明是只讀操作,加讀鎖
    // 對應到 InnoDB 的鎖類型就是共享鎖(S)
    if ((*tables)->db_stat & HA_READ_ONLY ||
        ((*tables)->reginfo.lock_type >= TL_READ &&
         (*tables)->reginfo.lock_type <= TL_READ_NO_INSERT))
      lock_type = F_RDLCK;
    if ((error = (*tables)->file->ha_external_lock(thd, lock_type))) {
      // ha_external_lock() 返回非 0 值
      // 說明執(zhí)行 ha_external_lock() 方法出現了錯誤
      // 這里處理善后工作
      ...
      return error;
    } else {
      (*tables)->db_stat &= ~HA_BLOCK_LOCK;
      (*tables)->current_lock = lock_type;
    }
  }
  return 0;
}

lock_external() 會迭代 SQL 中的表,每迭代一個表,都調用 ha_external_lock() 對表進行加鎖。

// sql/handler.cc
int handler::ha_external_lock(THD *thd, int lock_type) {
  ...
  MYSQL_TABLE_LOCK_WAIT(PSI_TABLE_EXTERNAL_LOCK, lock_type,
    { error = external_lock(thd, lock_type); })
  ...
}

handler::ha_external_lock() 調用表對應存儲引擎的 external_lock() 方法。

對 InnoDB 來說,調用的是 ha_innobase::external_lock(),這個方法的代碼比較多,算是個大雜燴,可以分為三類:

  • 加表級別的共享鎖、排他鎖。
  • 把當前迭代表所屬表空間的臟頁,同步刷新到磁盤。
  • 一些初始化邏輯(執(zhí)行快,花費時間極少)。

ha_innobase::external_lock() 的執(zhí)行時間會計入表鎖等待時間,因為其中可能包含同步刷臟頁操作、執(zhí)行一些初始化邏輯花費的時間,所以,表鎖等待時間并不純粹。

對需要加表鎖的 SQL 來說,表鎖等待時間包含兩部分:

  • 加表級別的共享鎖、排他鎖的等待時間。
  • 執(zhí)行一些初始化邏輯花費的時間。

如果是 FLUSH TABLES ... WITH READ LOCK 語句,表鎖等待時間還包含:把其中涉及的表所屬表空間的臟頁同步刷新到磁盤所花費的時間。

對不需要加表鎖的 SQL 來說,表鎖等待時間就是執(zhí)行 ha_innobase::external_lock() 中一些初始化邏輯花費的時間。

我們來看看 ha_innobase::external_lock() 主要包含哪些代碼邏輯,對這部分細節(jié)不感興趣的讀者,可以跳過這個小節(jié)。

這個小節(jié)的代碼都來自于 ha_innobase::external_lock(),文件路徑 storage/innobase/handler/ha_innodb.cc。

update_thd(thd);

以上代碼,創(chuàng)建 InnoDB 的事務對象(trx_t),保存到 server 層的用戶線程對象(thd)中。

// lock_type == F_WRLCK,意味著需要加寫鎖
// 這里用于表示需要記錄 binlog
if (lock_type == F_WRLCK &&
    // 表示不支持 STATEMENT 格式的 binlog
    // table_flags() 方法會判斷事務隔離級別
    !(table_flags() & HA_BINLOG_STMT_CAPABLE) &&
    // 系統變量 binlog_format = STATEMENT
    // 表示用戶需要記錄 STATEMENT 格式的 binlog
    thd_binlog_format(thd) == BINLOG_FORMAT_STMT &&
    // 表示需要為當前連接指定的數據庫記錄 binlog
    // use <db> 或者連接數據庫時指定了數據庫
    thd_binlog_filter_ok(thd) &&
    // 表示當前執(zhí)行的 SQL 會產生 ROW 格式的 binlog
    thd_sqlcom_can_generate_row_events(thd)) {
  bool skip = false;
  ...
  if (!skip) {
    ...
    return HA_ERR_LOGGING_IMPOSSIBLE;
  }
}

上面代碼的判斷條件有點多,我們用一句話來概括一下代碼邏輯:

事務隔離級別為 READ_UNCOMMITTED、READ_COMMITTED 時,如果 SQL 會產生 ROW 格式的 binlog,而用戶設置系統變量 binlog_format 的值為 STATEMENT,要求記錄 STATEMENT 格式的 binlog,ha_innobase::external_lock() 會返回 HA_ERR_LOGGING_IMPOSSIBLE,因為 MySQL 無法處理這樣矛盾的場景。

if (lock_type == F_WRLCK) {
  /* If this is a SELECT, then it is in UPDATE TABLE ...
  or SELECT ... FOR UPDATE */
  m_prebuilt->select_lock_type = LOCK_X;
  m_stored_select_lock_type = LOCK_X;
}

InnoDB 讀取記錄時,會根據 m_prebuilt->select_lock_type 的值確定是否加行鎖、加共享鎖還是排他鎖。

lock_type 等于 F_WRLCK,表示 server 層要求加寫鎖,對應到 InnoDB 的鎖類型,就是排他鎖,設置加鎖類型為 LOCK_X。

if (lock_type == F_RDLCK) {
  ...
  // 如果當前表是數據字典表
  // 或者被標識為不需要加鎖(no_read_locking = true)
  // 設置加鎖類型為 LOCK_NONE
  if (m_prebuilt->table->is_dd_table || m_prebuilt->no_read_locking) {
    m_prebuilt->select_lock_type = LOCK_NONE;
    m_stored_select_lock_type = LOCK_NONE;
  // 如果事務隔離級別是可串行化
  } else if (trx->isolation_level == TRX_ISO_SERIALIZABLE &&
    // 并且當前 SQL 還沒有確定加鎖類型
    m_prebuilt->select_lock_type == LOCK_NONE &&
    // 并且當前事務需要手動提交
    thd_test_options(thd, OPTION_NOT_AUTOCOMMIT | OPTION_BEGIN)) {
    // 設置加鎖類型為共享鎖
    m_prebuilt->select_lock_type = LOCK_S;
    m_stored_select_lock_type = LOCK_S;
  } else {
    // Retain value set earlier for example via store_lock()
    // which is LOCK_S or LOCK_NONE
    ut_ad(m_prebuilt->select_lock_type == LOCK_S ||
          m_prebuilt->select_lock_type == LOCK_NONE);
  }
}

lock_type 等于 F_RDLCK,表示 server 層要求加讀鎖,對應到 InnoDB 的鎖類型,就是共享鎖,分兩種情況設置 InnoDB 的加鎖類型:

  • 對于 ACL 表,m_prebuilt->no_read_locking 會被設置為 true,表示讀取記錄時不加鎖。
  • 如果事務隔離級別是可串行化,并且當前事務需要手動執(zhí)行 COMMIT 語句提交,以及還沒有確定讀取該表記錄時加什么類型的行鎖,設置 InnoDB 加鎖類型為共享鎖。

ACL 表用于訪問權限控制,包含如下這些表:

  • user
  • db
  • tables_priv
  • columns_priv
  • procs_priv
  • proxies_priv
  • role_edges
  • default_roles
  • global_grants
  • password_history

switch (m_prebuilt->table->quiesce) {
  case QUIESCE_START:
    /* Check for FLUSH TABLE t WITH READ LOCK; */
    if (!srv_read_only_mode && sql_command == SQLCOM_FLUSH &&
        lock_type == F_RDLCK) {
      ...
      row_quiesce_table_start(m_prebuilt->table, trx);
      ...
    }
    break;
  ...
}

只有執(zhí)行 FLUSH TABLES ... WITH READ LOCK 語句時,才會命中代碼中的 case 分支。

row_quiesce_table_start() 會調用 buf_LRU_flush_or_remove_pages(),并把當前加表鎖的表所屬表空間對象傳給該方法,表示把該表空間的臟頁刷新到磁盤。

行鎖等待時間

我們先來看看對一條記錄加行鎖的等待時間是怎么計算的。

InnoDB 讀取一條記錄時,如需加行鎖,會調用 sel_set_rec_lock() 進行加鎖。

如果其它事務持有該記錄的行鎖,sel_set_rec_lock() 會返回 DB_LOCK_WAIT,row_search_mvcc() 調用 row_mysql_handle_errors() 處理鎖等待邏輯。

row_mysql_handle_errors() 調用 lock_wait_suspend_thread(),行鎖等待邏輯由這個方法實現。

// storage/innobase/lock/lock0wait.cc
void lock_wait_suspend_thread(que_thr_t *thr) {
  srv_slot_t *slot;
  trx_t *trx;
  // 聲明變量,用于保存行鎖等待的開始時間
  std::chrono::steady_clock::time_point start_time;
  ...
  if (thr->lock_state == QUE_THR_LOCK_ROW) {
    srv_stats.n_lock_wait_count.inc();
    srv_stats.n_lock_wait_current_count.inc();
    // 設置行鎖等待的開始時間
    start_time = std::chrono::steady_clock::now();
  }
  ...
  // 等待行鎖
  os_event_wait(slot->event);
  ...
  // 運行到這里,有兩種情況:
  // 1. 鎖等待超時
  // 2. 已經獲取到行鎖
  if (thr->lock_state == QUE_THR_LOCK_ROW) {
    // 用當前時間減去行鎖等待的開始時間
    // 就是一條記錄的行鎖等待時間
    const auto diff_time = std::chrono::steady_clock::now() - start_time;
    ...
    /* Record the lock wait time for this thread */
    // 累加線程的行鎖等待時間
    // 保存到 mysql_thd 線程中
    // mysql_thd 是 server 層的線程
    thd_set_lock_wait_time(trx->mysql_thd, diff_time);
    ...
  }
  ...
}

從上面代碼可以看到,計算一條記錄的行鎖等待時間,邏輯比較簡單: 先保存當前行鎖等待的開始時間,獲取到行鎖或等待行鎖超時之后,再用當前時間減去開始時間,就得到了一條記錄的行鎖等待時間。

累計時間

一滴水的夢想是終有一天能夠匯入大海。

表鎖、行鎖等待時間的歸宿是累加起來,最終成為 lock_time,這個過程是通過調用 thd_set_lock_wait_time() 實現的。

// storage/innobase/handler/ha_innodb.cc
void thd_set_lock_wait_time(THD *thd,
                            std::chrono::steady_clock::duration value) {
  if (thd) {
    thd_storage_lock_wait(
        thd,
        std::chrono::duration_cast<std::chrono::microseconds>(value).count());
  }
}

thd_set_lock_wait_time() 調用 thd_storage_lock_wait() 累加表鎖、行鎖等待時間。

// sql/sql_thd_api.cc
void thd_storage_lock_wait(MYSQL_THD thd, long long value) {
  thd->inc_lock_usec(value);
}

真正干活的是 THD::inc_lock_usec() 方法。

// sql/sql_class.cc
void THD::inc_lock_usec(ulonglong lock_usec) {
  m_lock_usec += lock_usec;
  MYSQL_SET_STATEMENT_LOCK_TIME(m_statement_psi, m_lock_usec);
}

server 層每獲取到一個表鎖,都會調用 thd_set_lock_wait_time(),累加表鎖等待時間。

最終會調用 THD::inc_lock_usec() 把表鎖等待時間累加到 server 層的線程對象 thd 的 m_lock_usec 屬性中。

InnoDB 每獲取到一條記錄的行鎖,或者行鎖等待超時,都會調用 thd_set_lock_wait_time(),累加行鎖等待時間。

最終會調用 THD::inc_lock_usec() 把行鎖等待時間累加到 server 層的線程對象 thd 的 m_lock_usec 屬性中。

lock_time

SQL 執(zhí)行完成之后,dispatch_command() 調用 log_slow_statement() 記錄慢查詢到文件中。

log_slow_statement() 也不是真正干活的,經過多級,最終調用 Query_logger::slow_log_write() 記錄慢查詢到文件中。

// sql/log.cc
bool Query_logger::slow_log_write(THD *thd, const char *query,
                                  size_t query_length, bool aggregate,
                                  ulonglong lock_usec, ulonglong exec_usec) {
  ...
  if (aggregate) {
    query_utime = exec_usec;
    lock_utime = lock_usec;
  } else if (thd->start_utime) {
    query_utime = (current_utime - thd->start_utime);
    lock_utime = thd->get_lock_usec();
  } else {
    query_utime = 0;
    lock_utime = 0;
  }
  ...
  bool error = false;
  for (Log_event_handler **current_handler = slow_log_handler_list;
       *current_handler;) {
    error |= (*current_handler++)->log_slow(
               thd, current_utime,
               (thd->start_time.tv_sec * 1000000ULL) +
               thd->start_time.tv_usec,
               user_host_buff, user_host_len, query_utime,
               lock_utime, is_command, query, query_length);
  }
  ...
}

Query_logger::slow_log_write() 被調用時,參數 aggregate 的值都是 false,上面代碼不會進入 if (aggregate) 分支。

if (thd->start_utime) 分支,lock_utime = thd->get_lock_usec(),從當前線程對象(thd)中獲取之前累加的表鎖、行鎖等待時間。

然后,調用 log_slow() 記錄慢查詢到文件中。

// sql/log.cc
bool Log_to_file_event_handler::log_slow(
    THD *thd, ulonglong current_utime, ulonglong query_start_utime,
    const char *user_host, size_t user_host_len, ulonglong query_utime,
    ulonglong lock_utime, bool is_command, const char *sql_text,
    size_t sql_text_len) {
  if (!mysql_slow_log.is_open()) return false;

  Silence_log_table_errors error_handler;
  thd->push_internal_handler(&error_handler);
  bool retval = mysql_slow_log.write_slow(
      thd, current_utime, query_start_utime, user_host, user_host_len,
      query_utime, lock_utime, is_command, sql_text, sql_text_len);
  thd->pop_internal_handler();
  return retval;
}

Log_to_file_event_handler::log_slow() 最終調用 mysql_slow_log.write_slow() 記錄慢查詢到文件中。

// sql/log.cc
bool File_query_log::write_slow(...) {
  ...
  if (!thd->copy_status_var_ptr) {
    if (my_b_printf(&log_file,
        "# Query_time: %s  Lock_time: %s"
        " Rows_sent: %lu  Rows_examined: %lu\n",
        query_time_buff, lock_time_buff,
        (ulong)thd->get_sent_row_count(),
        (ulong)thd->get_examined_row_count()) == (uint)-1)
      goto err; /* purecov: inspected */
  }
  ...
}

經常看慢查詢日志的讀者,想必對這 2 行會非常熟悉:

Query_time: %s  Lock_time: %s
Rows_sent: %lu  Rows_examined: %lu

其中的 Lock_time 就是本文的主題,介紹到這里,總算是和文章標題遙相呼應上了。

總結

Lock_time 由表鎖、行鎖等待時間相加得到。

表鎖等待時間并不純粹,其中包含執(zhí)行一些初始化操作花費的時間。

對 FLUSH TABLES ... WITH READ LOCK 語句來說,還包含把其中涉及的表所屬表空間的臟頁同步刷新到磁盤所花費的時間。

行鎖等待時間很純粹,就是多條記錄的行鎖等待時間之和,或者一條記錄的行鎖等待時間。

本文轉載自微信公眾號「一樹一溪」,可以通過以下二維碼關注。轉載本文請聯系一樹一溪公眾號。

責任編輯:姜華 來源: 一樹一溪
相關推薦

2011-05-03 09:34:14

項目經理

2020-04-17 10:50:19

5G運營商網絡

2021-12-31 14:39:29

AI 數據人工智能

2018-05-23 10:23:18

數據系統機器學習

2017-04-01 19:00:25

MySQL慢查詢

2018-10-12 16:45:10

MySQL查詢日志數據庫

2010-11-25 16:29:26

MySQL慢日志查詢

2010-09-28 14:59:29

sql查詢

2017-09-18 15:20:02

MySQL慢查詢日志配置

2012-01-11 14:58:08

2022-05-17 08:24:58

查詢日志MySQL

2024-11-28 09:51:35

SQL日志Go項目

2021-06-07 10:47:02

GoGoexit函數

2021-05-17 15:23:07

電腦廣告軟件

2021-04-12 10:52:55

Windows 10電腦軟件

2015-05-04 17:36:49

大數據跨過幾道坎

2018-08-02 16:10:50

MySQL數據庫清理

2019-07-08 20:22:05

人工智能AI機器人

2022-12-26 00:48:38

2011-06-28 08:32:40

MySQL慢查詢日志
點贊
收藏

51CTO技術棧公眾號

91久久久精品| 亚洲人成啪啪网站| a级免费在线观看| 欧美特黄一级视频| 免费一区视频| 在线日韩第一页| √天堂资源在线| caoporn视频在线| 国产无人区一区二区三区| 国产日韩欧美视频| 国产一级做a爰片在线看免费| 亚洲成a人片77777在线播放| 欧美久久久一区| 成人网站免费观看入口| a天堂在线资源| 国产**成人网毛片九色| 国产精品久久久久不卡| 久草视频在线资源站| 国内成人精品| 精品少妇一区二区三区在线播放| 免费高清在线观看免费| 国产素人视频在线观看| 久久网站热最新地址| 成人激情av在线| 综合网在线观看| 欧美伊人影院| 日韩在线观看免费全集电视剧网站| 国产人妖在线观看| 国产精品成人国产| 欧美性黄网官网| 毛片在线视频观看| 午夜毛片在线| 久久久久久久久久久99999| 97av影视网在线观看| 日韩综合在线观看| 亚洲美洲欧洲综合国产一区| 久久激情五月丁香伊人| x88av在线| 女一区二区三区| 日韩欧美国产综合| 污视频网址在线观看| 亚洲国产成人二区| 亚洲成人www| 久久久久久久香蕉| 黄色小网站在线观看| 国产欧美日韩精品a在线观看| 韩国成人av| 亚洲精品国产精| 国产一区91精品张津瑜| 国产精品久久久久久搜索| 久久青青草视频| 亚洲美女一区| 2019中文字幕在线观看| 日本熟妇毛茸茸丰满| 欧美日韩爆操| 精品中文字幕在线观看| 黑鬼狂亚洲人videos| 欧美丰满日韩| 色综合亚洲精品激情狠狠| 国产亚洲精品熟女国产成人| 性欧美lx╳lx╳| 日韩精品在线免费观看视频| 朝桐光av一区二区三区| 美女一区二区在线观看| 亚洲精品v天堂中文字幕| 极品白嫩少妇无套内谢| 亚洲一区二区三区四区电影 | 在线视频福利一区| 福利视频在线看| 欧美国产国产综合| 亚洲精品高清国产一线久久| 9191在线观看| 亚洲色图视频免费播放| 韩国黄色一级大片| 手机在线免费av| 亚洲v中文字幕| 国产精品丝袜久久久久久消防器材| 99re6在线精品视频免费播放| 亚洲国产aⅴ成人精品无吗| 久艹在线免费观看| 日本乱码一区二区三区不卡| 91国偷自产一区二区使用方法| 欧美精品成人网| av在线日韩| 欧美色国产精品| www.污污视频| y111111国产精品久久久| 精品99一区二区| 97人妻精品一区二区三区免 | 日韩大片在线观看视频| jizz欧美性20| 国产精品99一区二区三| 欧美激情精品久久久久久久变态 | 尤物视频在线免费观看| 亚洲欧美日韩综合aⅴ视频| 成年人看的毛片| av免费在线一区| 欧美一区二区三区系列电影| 国产极品一区二区| 欧美综合视频| 欧美激情亚洲国产| 波多野结衣黄色网址| 韩日av一区二区| 国产乱码精品一区二区三区卡| 国产在线网站| 亚洲欧美一区二区久久 | а√在线天堂官网| 在线观看91精品国产入口| 久久久九九九热| 亚洲电影男人天堂| 欧美伦理91i| 91视频在线视频| 国产mv日韩mv欧美| 午夜精品一区二区在线观看| 美洲精品一卡2卡三卡4卡四卡| 一本色道a无线码一区v| 亚洲 自拍 另类 欧美 丝袜| 日韩超碰人人爽人人做人人添| 日韩色av导航| 无码人妻丰满熟妇精品区| 国产成人午夜精品影院观看视频| 台湾成人av| av免费在线视| 51精品视频一区二区三区| 性少妇bbw张开| 亚洲高清资源| 国产欧美在线看| 午夜视频福利在线观看| 亚洲精品国产成人久久av盗摄 | 美女视频一区二区三区| 久久99精品国产一区二区三区| 黄色av电影在线播放| 在线免费精品视频| 一女三黑人理论片在线| 欧美精品啪啪| 91在线播放国产| 成人免费在线电影| 一本一道久久a久久精品综合蜜臀| 在线成人精品视频| 羞羞答答成人影院www| 国产精品情侣自拍| 撸视在线观看免费视频| 富二代精品短视频| 玖玖爱在线精品视频| 国产综合精品一区| 91九色蝌蚪成人| 黄网页在线观看| 欧美揉bbbbb揉bbbbb| 中文字幕免费高清| 久久婷婷亚洲| 欧美日韩精品免费观看| 麻豆mv在线观看| 亚洲国产精品大全| 尤物视频在线观看国产| 成人免费观看男女羞羞视频| 999久久欧美人妻一区二区| 成人av在线播放| 久久精品国产电影| 国产精品久久影视| 亚洲欧美成人一区二区三区| 国产又粗又长又爽又黄的视频| 日韩欧美一区二区三区在线视频| 国产精品欧美日韩久久| 91免费在线| 欧美精品在线视频| 欧美三级在线免费观看| 国产成人精品亚洲日本在线桃色| 精品久久久无码人妻字幂| 91精品久久久久久综合五月天| 久久99精品久久久久久琪琪| 亚洲欧美另类视频| 精品久久久久久亚洲国产300| 狠狠人妻久久久久久综合蜜桃| 久久久久看片| 亚洲欧洲一区二区在线观看| 欧美综合社区国产| 美女福利精品视频| 凸凹人妻人人澡人人添| 欧美性猛交99久久久久99按摩| 亚洲第一成人网站| 久久99精品国产麻豆婷婷洗澡| 日本高清xxxx| 狼人精品一区二区三区在线| 人人澡人人澡人人看欧美| 福利在线午夜| 91精品国产一区二区人妖| 国产一级片视频| 91蝌蚪国产九色| 中文字幕天天干| 欧美精品97| 老司机精品福利在线观看| 99久久亚洲国产日韩美女| 久久综合九色九九| 天天干天天色天天| 欧美色图天堂网| 久久午夜无码鲁丝片| 久久久不卡网国产精品二区| www.色就是色.com| 亚洲欧美日本日韩| 天堂v在线视频| 林ゆな中文字幕一区二区| 国产精品美女免费视频| 免费看电影在线| 中国china体内裑精亚洲片| 亚洲国产精品久久久久久6q| 色嗨嗨av一区二区三区| 三级影片在线看| 久久精品视频免费观看| 国产chinesehd精品露脸| 日韩国产精品久久久久久亚洲| 欧美黄网在线观看| 成人精品电影| 精品一区二区三区国产| 亚洲精品三区| 国产91在线播放九色快色| 秋霞在线视频| 色哟哟网站入口亚洲精品| 视频一区二区在线播放| 日韩无一区二区| 中文字幕乱码一区二区| 欧美日韩色婷婷| 麻豆视频在线观看| 国产精品久久国产精麻豆99网站| 蜜桃精品成人影片| 国产成人免费视频网站高清观看视频 | 精品视频亚洲| 好看的日韩精品视频在线| 国产精品中文| 国产精品一区二区电影| 日韩电影毛片| 午夜精品蜜臀一区二区三区免费| 国产在线1区| 欧美日韩中文字幕一区| 国产精品扒开腿做爽爽| 丁香另类激情小说| 久久久久久久久久毛片| 日韩成人精品视频| 成人免费在线小视频| 国产一区二区三区四区三区四| 国产大尺度在线观看| 日韩伦理视频| 天堂一区二区三区| 国产成人三级| 欧美日韩精品免费看| 无码少妇一区二区三区| 国产在线观看一区| 精品久久97| 精品国产电影| 狼人天天伊人久久| 精品不卡在线| 亚洲专区视频| 欧洲精品一区色| 欧美美女在线观看| 日韩欧美视频一区二区三区四区| 国产a久久精品一区二区三区 | 青青在线视频免费| 国产一区二区高清| 白嫩少妇丰满一区二区| 久久亚洲欧洲| 亚洲视频在线观看一区二区三区| 久久国产直播| 国产精品视频黄色| 麻豆精品久久久| 亚洲av无日韩毛片久久| 国产精品亚洲一区二区三区在线| 99中文字幕在线| 岛国一区二区在线观看| 粉嫩av懂色av蜜臀av分享| 91看片淫黄大片一级在线观看| 国产一二三四五区| 国产精品久久免费看| 欧美一区二区三区爽爽爽| 亚洲激情自拍偷拍| 久草手机在线观看| 在线亚洲一区二区| 伊人网站在线观看| 日韩午夜激情视频| 午夜福利一区二区三区| 在线观看亚洲区| 国产日产一区二区| 高清欧美性猛交| 欧美专区福利免费| 成人免费看吃奶视频网站| 亚洲精品午夜| 欧美日本亚洲| 97国产成人高清在线观看| 日韩欧美视频免费在线观看| 亚洲视频播放| 加勒比av中文字幕| 99久久精品国产一区二区三区| 国产综合精品久久久久成人av| 一区二区三区在线观看动漫| 国产美女激情视频| 欧美美女bb生活片| 天天爱天天干天天操| 揄拍成人国产精品视频| 在线免费观看的av| 日韩av免费在线观看| 久久国产精品美女| 狼狼综合久久久久综合网| 久久久久电影| 北条麻妃在线观看| 国产精品亚洲一区二区三区妖精| 朝桐光av一区二区三区| 亚洲私人影院在线观看| wwwwww国产| 欧美成人伊人久久综合网| 国产在线91| 久久久免费观看| 四虎精品永久免费| 久久精品国产精品国产精品污| 亚洲国产成人精品女人| 国产精品第12页| 成人av网址在线| 国产老头老太做爰视频| 日本久久电影网| 人妻一区二区三区四区| 综合激情国产一区| 成人动漫一区| 国产福利久久精品| 亚洲乱码在线| 亚洲欧美日韩一级| 99精品一区二区| 欧美三级免费看| 欧美日本国产视频| 欧美拍拍视频| 性日韩欧美在线视频| 日本一区影院| 男人天堂成人网| 捆绑调教一区二区三区| 无码一区二区三区在线| 精品美女久久久久久免费| 国产不卡av在线播放| www.欧美免费| 国产精品久久久久久久久久齐齐 | 日韩精品dvd| 97在线免费公开视频| 国产69精品久久久久毛片| 色欲人妻综合网| 欧美三级电影精品| av片在线看| 国产精品高潮呻吟久久av无限| 在线成人动漫av| 国产淫片免费看| 91丝袜美腿高跟国产极品老师| 国产成人亚洲精品自产在线| 精品国产乱码久久| 9765激情中文在线| 精品日产一区2区三区黄免费 | 久久夜色精品国产| 日本在线一区二区| 亚洲欧洲一二三| 另类调教123区| 久久人妻无码aⅴ毛片a片app| 欧美精品在线视频| 在线观看a级片| 国产激情美女久久久久久吹潮| 国产精品mm| 亚洲香蕉中文网| 欧美天堂在线观看| 欧美18xxxxx| 国产精品直播网红| 66视频精品| zjzjzjzjzj亚洲女人| 亚洲第一主播视频| 性xxxx视频| 国产精品久久一区| 91久久电影| 亚洲熟女一区二区三区| 性欧美大战久久久久久久久| 头脑特工队2免费完整版在线观看 头脑特工队2在线播放 | 欧美性色19p| 第一福利在线| 国产主播精品在线| 欧美区亚洲区| 欧美高清性xxxx| 欧美视频一区二区三区在线观看| 国产素人视频在线观看| 不卡一区二区三区四区五区| 日韩一级在线| 少妇人妻好深好紧精品无码| 7777精品伊人久久久大香线蕉的 | 国产精品三级在线观看| 国产精品无码白浆高潮| 久久久久久91| 一本色道久久综合亚洲精品酒店 | 可以免费在线观看的av| 国产亚洲福利一区| 人人爱人人干婷婷丁香亚洲| 日本午夜激情视频| 欧美国产1区2区| 亚洲va天堂va欧美ⅴa在线| 国产91精品久久久久久| 色琪琪久久se色| 中文字幕天堂av| 在线一区二区视频| 欧美性爽视频| 神马影院我不卡| 丁香六月久久综合狠狠色| 中文字幕av久久爽|