Innodb parent table open时导致crash
case描述:
innodb中,父表和子表通过foreign constraint进行关联, 因为在更新数据时需要check 外键constraint,如果父表被大量的子表reference,
那么在open的时候,需要open所有的child table和所有的foreign constraint,导致时间过长,产生long semaphore wait 。
分析过程:
case 用例:
CREATE TABLE `t1` (
`f1` int() NOT NULL,
PRIMARY KEY (`f1`)
) ENGINE=InnoDB CREATE TABLE `fk_1` (
`f1` int() NOT NULL,
PRIMARY KEY (`f1`),
CONSTRAINT `pc1` FOREIGN KEY (`f1`) REFERENCES `t1` (`f1`) ON DELETE CASCADE ON UPDATE CASCADE
) ENGINE=InnoDB
...... 这里建了fk_[-]张表。
1. 背景:innodb数据字典
innodb使用系统表空间保存表相关的数据字典,系统的数据字典包括:
- SYS_TABLES
- SYS_INDEXES
- SYS_COLUMNS
- SYS_FIELDS
- SYS_FOREIGN
- SYS_FOREIGN_COLS
- SYS_STATS
在load某个表的时候,分别从这些表中把表相关的index,column, index_field, foreign, foreign_col数据保存到dictionary cache中。
对应的内存对象分别是:dict_col_struct,dict_field_struct,dict_index_struct,dict_table_struct,dict_foreign_struct。
这些对象全局唯一,在dictionary cache只保留一份,并使用dict_sys->mutex进行同步保护,所有open的handler引用到这些对象上。
注意:系统的数据字典同样是innodb的聚簇索引表,并受redo保护。
2. open过程
入口函数ha_innobase::open()
dict_load_table:
1. 通过sys_tables系统表,load table相关的定义
2. 通过sys_indexes系统表,根据table_id load 所有相关index
3. 通过sys_columns系统表,根据table_id load 所有的columns
4. 通过sys_fields系统表,根据index_id load 所有index的field
5. 通过sys_foreign系统表,load所有关联的表和foreign key
在load这些定义的时候,过程都是:
1. 通过某个字段,查找系统字典表
2. 根据查询的记录建立内存对象,并加入到全局cache中
但在load foreign的时候,会有一些不同,因为foreign key于两张表相关联。下面详细介绍下load foreign的过程。
3. load foreign的详细过程
如下图所示foreign的关联关系:

load的步骤:
3.1: 根据表名t1 查找sys_foreign. 而sys_foreign表上一共有三个索引:
index_1(id): cluster_index
index_2(for_name): secondary_index
index_3(ref_name): secondary_index
所以,根据for_name='t1', ref_name='t1'检索出来所有相关的foreign_id.
3.2: 根据3.1检索出来的foreign_id, load foreign对象,并打开相关fk_[1-10000]表。
3.3: 加入cache
因为没有专门的cache,foreign分别加入到for_name->foreign_list, ref_name->refence_list
问题的关键:因为foreign是全局唯一的,但foreign又与两个表关联,所以,有可能在open 其它表的时候
已经打开过,所以,create foreign对象后,需要判断以下四个list,是否已经存在,如果存在就直接使用。
dict_foreign_find:分别查询这四个list,如果已经存在,则free新建的foreign对象,引用已经存在的。
for_name->foreign_list
for_name->refence_list
ref_name->foreign_list
ref_name->refence_list
如果不存在,把新建的foreign加入到for_name->foreign_list,ref_name->refence_list链表中。
4. 问题的原因:
因为第一次load,所以find都没有找到,但这四个都是list,随着open的越来越多,检索的代价越来越大。
而整个过程中,都一直持有trx_sys->mutex,最终导致了long semaphore wait。
5. 问题改进方法:
在MySQL 5.5.39版本中,进行了修复,修复的方法就是,除了foreign_list,referenced_list。
另外又增加了两个red_black tree,如下源码所示:
struct dict_table_struct{
table_id_t id; /*!< id of the table */
mem_heap_t* heap; /*!< memory heap */
char* name; /*!< table name */
UT_LIST_BASE_NODE_T(dict_foreign_t)
foreign_list; /*!< list of foreign key constraints in the table; these refer to columns in other tables */
UT_LIST_BASE_NODE_T(dict_foreign_t)
referenced_list;/*!< list of foreign key constraints which refer to this table */
ib_rbt_t* foreign_rbt; /*!< a rb-tree of all foreign keys listed in foreign_list, sorted by foreign->id */
ib_rbt_t* referenced_rbt; /*!< a rb-tree of all foreign keys listed in referenced_list, sorted by foreign->id */
在初始化list的时候,初始化一份red_black tree. 在dict_foreign_find的过程中,直接查找rbt,这样查询的代价大大降低。
Innodb parent table open时导致crash的更多相关文章
- IE6 IE7: div中table宽度100%导致的宽度问题
问题现象:定义了DOCTYPE的页面 当表格的内容比div的高度还要高时,div会出现滚动条,同时在IE6和IE7下会出现问题: IE6:此时table的100%宽度还是没有滚动条那是的宽度,出现滚动 ...
- MySQL 5.6 解决InnoDB: Error: Table "mysql"."innodb_table_stats" not found.问题
在安装MySQL 5.6.30时,安装完成后,后台日志报如下警告信息:2016-05-27 12:25:27 7fabf86f7700 InnoDB: Error: Table "mysql ...
- 还原堆栈信息,分析地形系统使用ASTC格式的纹理导致Crash的问题
0x00 前言 在这篇文章中,我们选择了过去一周Unity官方社区交流群中比较有代表性的几个问题,总结在这里和大家进行分享.主要涵盖了IL2CPP.Scripting.Virtual Reality. ...
- 【MySQL】5.6.x InnoDB Error Table mysql.innodb_table_stats not found
[问题描述]: 检查error log的时候发现大量warnings: [Warning] InnoDB Error Table mysql.innodb_index_stats not found ...
- InnoDB: Error: Table "mysql"."innodb_table_stats" not found.
1,Mysqldump的时候报错例如以下: 2014-05-05 14:12:37 7f004a9a2700 InnoDB: Error: Table "mysql"." ...
- 使用vxe table组件时,edit-render配置$select',选中option后关闭cell的激活状态,显示选中option的value问题
在我的项目中使用vxe table组件时,edit-render配置{name: '$select', options: [{label:"脉搏",value:"maib ...
- [转]File Descriptor泄漏导致Crash: Too many open files
在实际的Android开发过程中,我们遇到了一些奇奇怪怪的Crash,通过sigaction再配合libcorkscrew以及一些第三方的Crash Reporter都捕获不到发生Crash的具体信息 ...
- @PathVariable出现点号"."时导致路径参数截断获取不全的解决办法
@PathVariable出现点号"."时导致路径参数截断获取不全的解决办法 比如,我路径是/test/{name},name的值是1.2.3.4,后台用@PathVariable ...
- iOS -- xxxViewController进行pop时直接crash进main.m,EXC_BAD_ACCESS(code=1,address=0x20)
今天在调试程序时,遇到了奇怪的错误.我从主页跳进(push)一个ViewController时一切正常,但是返回主页(pop)时却crash了,直接跳进了main.m(EXC_BAD_ACCESS(c ...
随机推荐
- JavaScript的语法要点 3 - Calling Context
上一篇讲了JavaScript的Scope Chain - 每一个函数都有一个scope chain与之关联,scope chain上有第一个对象维护着本地变量作为其属性.另外我们在JavaScrip ...
- PL/SQL Developer编码格式设置及中文乱码解决方案
1.PL/SQL Developer中文字段显示乱码 原因:因为数据库的编号格式和pl /sql developer的编码格式不统一造成的. 2.PL/SQL Developer编码格式设置详细的解决 ...
- Kinetic使用注意点--collection
new Collection() 扩展了数组,主要用于配合new Container().get()使用 方法: each(func):遍历数组,执行回调函数.回调函数接收两个值,节点和索引. toA ...
- C# 构造函数中调用虚方法的问题
请看下面代码: using System; public class A{ public A(){ M1(); } public virtual void M1(){} } public class ...
- ASP.NET MVC的约定
ASP.NET MVC 应用程序遵循以下3条约定: 所有的控制器的名称都以Controller结尾,如HomeController, AccountController 这些类默认在Controlle ...
- xcode 6.3 打包crash问题--参考
xcode升级6.3之后,有些项目会出现打包crash的问题,只要选择偏好设置,把source control全部禁用掉就可以了.
- GPS导航仪常见术语解释
摘自百度百科: 坐标(coordinate) 有2维.3维两种坐标表示,当GPS能够收到4颗及以上卫星的信号时,它能计算出本地的3维坐标:经度.纬度.高度,若只能收到3颗卫星的信号,它只能计算出2维坐 ...
- FlushMode属性与transaction(spring注入的事务)
一.参见hibernate的api http://tool.oschina.net/apidocs/apidoc?api=hibernate-3.6.10 http://tool.oschina.ne ...
- WPF 视图分组排序
视图分组排序 效果: 实现步骤: 第一步:为分组做一个标题头,就是效果图中的浅蓝色部分: <DataGrid.GroupStyle>标签部分: <DataGrid x:Name=&q ...
- ACM题集以及各种总结大全!
ACM题集以及各种总结大全! 虽然退役了,但是整理一下,供小弟小妹们以后切题方便一些,但由于近来考试太多,顾退役总结延迟一段时间再写!先写一下各种分类和题集,欢迎各位大牛路过指正. 一.ACM入门 关 ...