MYSQL截断引发数据表损坏案例分析

  

最近发布到市场的版本频繁出现数据库表损坏的情况,具体的现象是选择表提示表不存在,但是查看数据文件,对应表的ibd和纳文件都在。

  

通过对多个故障的统计,找到几个频繁出现损坏的表,在分析过程中,发现这些数据表都使用了截断清除数据,所以怀疑是截断操作的问题。

  

设计如下过程来验证这个分析结果:

  

1,创建存储过程如下,对一张表模拟频繁调用截断

  

下降过程中如果存在prcTest5;
创建过程prcTest5 (ic int)

开始宣布我int;
设置i=0;
,
(i<5)做截断表alarmtest5;
插入alarmtest5 select * from端口限制ic;
设置我=+ 1,
结束时,

  

结束;   

2,使用肥皂UI创建压力测试用例
 MYSQL截断引发数据表损坏案例分析

  

发起的线程为5
测试时间间隔0.5 s

  

3,使用蝙蝠脚本周期taskkill mysqld进程并重新启动

  

@echo了
:
循环回声杀死
taskkill/f/im mysqld。exe
回声RegMysqlServer
RegMysqlServer打电话。蝙蝠
电话:20000年睡眠
::调用方法叫:睡眠(毫秒](1秒=1000毫秒)

  

goto循环   睡眠

:
设置tmp=? % \ temp tmp.vbs"
wscript回响。睡眠% 1在% tmp %和% tmp %,德尔% tmp %
goto: eof

  

4,启动测试,持续5 - 10分钟,关闭测试,打开数据库,发现数据表损坏。

  

select * from alarmtest5;

  

提示表不存在,实际到数据目录下看,纳和ibd文件都在。

  

5,怀疑是多线程导致问题,将线程数降为1,运行5 - 10分钟后,依然出现数据库表损坏现象。
6,将存储过程修改为使用删除语句,测试线程数5,没有出现数据库表损坏的情况。

  

下降过程中如果存在prcTest4;
创建过程prcTest4 (ic int)

开始宣布我int;
设置i=0;
,
(i<5)做删除从alarmtest4;
插入alarmtest4 select * from端口限制ic;
设置我=+ 1,
结束时,

  

,
7日查看MySQL官方文档,当表被截断时,它被删除并重新创建一个新的.ibd文件,结合自测的情况,怀疑是我们每张表使用一个ibd文件,截断表是重建ibd文件过程中MySQL进程中断,导致ibd文件损坏。
 MySQL截断引发数据表损坏案例分析

  

7日重新创建一个数据库,将innodb_file_per_table=1参数去掉,所有表共享一个ibd文件。
重复上面的测试,运行15分钟没有出现数据库表损坏的情况。

  

分析结论

  

innodb_file_per_table=1,使用截断会重新创建ibd文件,如果这个过程中mysqld进程意外中断,有很大概率出现数据库表损坏的现象。

MYSQL截断引发数据表损坏案例分析