91超碰碰碰碰久久久久久综合_超碰av人澡人澡人澡人澡人掠_国产黄大片在线观看画质优化_txt小说免费全本

溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點擊 登錄注冊 即表示同意《億速云用戶服務條款》

Searching rows for update狀態初探

發布時間:2020-07-14 08:11:00 來源:網絡 閱讀:311 作者:ckllf 欄目:MySQL數據庫

  一、背景說明

  最近有位朋友咨詢說為何如此多線程處于Searching rows for update,當時看到這個狀態的第一反應就是鎖,這里暫且拋開鎖不談,談一談為何出現Searching rows for update

  二、實驗環境:

  root@mysqldb 10:15: [xucl]> show create table test1\G

  *************************** 1. row ***************************

  Table: test1

  Create Table: CREATE TABLE `test1` (

  `a` int(11) NOT NULL,

  `b` varchar(20) DEFAULT NULL,

  PRIMARY KEY (`a`),

  KEY `b` (`b`)

  ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4

  1 row in set (0.00 sec)

  root@mysqldb 10:15: [xucl]> select * from test1;

  +---+------+

  | a | b |

  +---+------+

  | 2 | b |

  | 3 | c |

  | 1 | ccc |

  +---+------+

  3 rows in set (0.00 sec)

  大概出現的狀態如下所示:

  

Searching rows for update狀態初探


  三、初探過程

  簡單做了pstack,其中id=2的線程堆棧如下:

  從堆棧很明顯可以看出,該線程處于鎖等待的狀態,但為何處于Searching rows for update并沒有給出明確暗示,可以看到調用的順序是

  mysql_parse

  mysql_execute_command

  Sql_cmd_update::execute_command

  mysql_update

  ...

  ha_innobase::index_read

  ...

  lock_wait_suspend_thread

  ...

  廢話不多說,咱們直接從mysql_update切入,該入口函數位置在sql_update.cc

  bool mysql_update(THD *thd,

  List &fields,

  List &values,

  ha_rows limit,

  enum enum_duplicates handle_duplicates,

  ha_rows *found_return, ha_rows *updated_return)

  {

  ...

  if (used_key_is_modified || order)

  {

  /*

  When we get here, we have one of the following options:

  A. used_index == MAX_KEY

  This means we should use full table scan, and start it with

  init_read_record call

  B. used_index != MAX_KEY

  B.1 quick select is used, start the scan with init_read_record

  B.2 quick select is not used, this is full index scan (with LIMIT)

  Full index scan must be started with init_read_record_idx

  */

  if (used_index == MAX_KEY || (qep_tab.quick()))

  error= init_read_record(&info, thd, NULL, &qep_tab, 0, 1, FALSE);

  else

  error= init_read_record_idx(&info, thd, table, 1, used_index, reverse);

  if (error)

  goto exit_without_my_ok;

  THD_STAGE_INFO(thd, stage_searching_rows_for_update);

  ha_rows tmp_limit= limit;

  }

  ...

  debug結果如下:

  

Searching rows for update狀態初探


  這里判斷條件為used_index是否等于MAX_KEY,其中MAX_KEY為常量,used_index的定義如下:

  used_index= get_index_for_order(order, &qep_tab, limit, &need_sort, &reverse);

  這里的判斷就比較復雜了,本人水平有限,暫時未深入理解優化器的部分,也不展開說明,源碼位置在sql_select.cc,有興趣的同學可以深入研究一下

  函數is_key_used定義如下:無錫看婦科的醫院 http://www.ytsgfk120.com/

  bool is_key_used(TABLE *table, uint idx, const MY_BITMAP *fields)

  {

  bitmap_clear_all(&table->tmp_set); //清空tmp_set位圖

  table->mark_columns_used_by_index_no_reset(idx, &table->tmp_set); //這里設置位圖

  const bool overlapping= bitmap_is_overlapping(&table->tmp_set, fields); //比較索引位置和修改位置是否重合

  // Clear tmp_set so it can be used elsewhere

  bitmap_clear_all(&table->tmp_set);

  if (overlapping)

  return 1; //如果重合返回1

  ...

  

Searching rows for update狀態初探


  看到debug的結果變量,used_key_is_modified為true,那么進入如下判斷

  

Searching rows for update狀態初探


  然后就進入stage_searching_rows_for_update狀態,也就是我們一開始在show processlist中看到的狀態

  

Searching rows for update狀態初探


  而如果我們修改的是其他字段,那么進入的狀態便是Updating,對應的源碼為

  if (used_key_is_modified || order)

  {

  ...

  }

  ...

  thd->count_cuted_fields= CHECK_FIELD_WARN;

  thd->cuted_fields=0L;

  THD_STAGE_INFO(thd, stage_updating);

  ...

  廢話不多說,我們來測試驗證一下THD_STAGE_INFO(thd, stage_updating);處打上斷點,然后更新數據

  

Searching rows for update狀態初探


  實驗結果符合預期

  其他測試結果:

  case結果

  update主鍵直接進入stage_updating

  update唯一索引直接進入stage_updating

  update普通二級索引+limit進入stage_searching_rows_for_update,完成后進入stage_updating

  四、總結

  最后總結一下:

  Searching rows for update狀態出現的要求比較嚴格,當進行數據更新時,如果更新的字段為當前執行計劃用到的索引,并且該索引屬于普通二級索引(不能是主鍵也不能是唯一索引),那么就會出現Searching rows for update狀態,正因為出現了鎖等待,所以能看到這種狀態

  如果不是,那么直接進入Updating狀態,這個狀態也就是我們經常看到的狀態

  出現如上兩種狀態并且持續時間長,并不是造成數據庫性能下降的根本原因,而應該考慮其他原因,如本案例中的鎖等待問題


向AI問一下細節

免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。

AI

杭锦旗| 五家渠市| 西充县| 平度市| 湖北省| 三明市| 隆昌县| 上高县| 普兰店市| 福贡县| 建始县| 阳曲县| 昭苏县| 临邑县| 乌什县| 青浦区| 宜城市| 甘孜| 中阳县| 东安县| 普定县| 富川| 本溪| 嘉义市| 阿图什市| 泸西县| 石棉县| 陆川县| 渝北区| 鄱阳县| 饶河县| 峨边| 平果县| 江陵县| 盘锦市| 边坝县| 偃师市| 朝阳县| 大方县| 漾濞| 濉溪县|