我的编程空间,编程开发者的网络收藏夹
学习永远不晚

Searching rows for update状态初探

短信预约 -IT技能 免费直播动态提醒
省份

北京

  • 北京
  • 上海
  • 天津
  • 重庆
  • 河北
  • 山东
  • 辽宁
  • 黑龙江
  • 吉林
  • 甘肃
  • 青海
  • 河南
  • 江苏
  • 湖北
  • 湖南
  • 江西
  • 浙江
  • 广东
  • 云南
  • 福建
  • 海南
  • 山西
  • 四川
  • 陕西
  • 贵州
  • 安徽
  • 广西
  • 内蒙
  • 西藏
  • 新疆
  • 宁夏
  • 兵团
手机号立即预约

请填写图片验证码后获取短信验证码

看不清楚,换张图片

免费获取短信验证码

Searching rows for update状态初探

  一、背景说明

  最近有位朋友咨询说为何如此多线程处于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)

  {

  

  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状态,这个状态也就是我们经常看到的状态

  出现如上两种状态并且持续时间长,并不是造成数据库性能下降的根本原因,而应该考虑其他原因,如本案例中的锁等待问题


免责声明:

① 本站未注明“稿件来源”的信息均来自网络整理。其文字、图片和音视频稿件的所属权归原作者所有。本站收集整理出于非商业性的教育和科研之目的,并不意味着本站赞同其观点或证实其内容的真实性。仅作为临时的测试数据,供内部测试之用。本站并未授权任何人以任何方式主动获取本站任何信息。

② 本站未注明“稿件来源”的临时测试数据将在测试完成后最终做删除处理。有问题或投稿请发送至: 邮箱/279061341@qq.com QQ/279061341

Searching rows for update状态初探

下载Word文档到电脑,方便收藏和打印~

下载Word文档

猜你喜欢

python 初探状态机transiti

偶然接触一个python的关于状态机的库,简单demo如下:# coding=utf-8############################################################### 目标:"solid",
2023-01-31

编程热搜

目录