在线添加索引遇到的错误:Table definition has changed, please retry transaction

现象:在线上环境,一条慢查询没有用到索引,表大小适中,加索引实际在3-5S内,决定在线添加。

mysql版本:5.1.56-community-log ,plugin innodb版本:1.0.15。

在添加索引的过程中,有原来的慢查询对此表进行访问,程序端返回错误:

"1412: Table definition has changed, please retry transaction (172.16.0.100)".

检查错误日志,里面也记录了相应的错误信息:

130324  3:55:55 [ERROR] Got error 159 when reading table './DB1/TB1'

130324  3:55:55 [ERROR] Got error 159 when reading table './DB1/TB1'

130324  3:55:55 [ERROR] Got error 159 when reading table './DB1/TB1'

分析159,1412错误,错误信息显示说表定义已经改变了,要重做事务。

[root@devdb7 ~]# perror 159

MySQL error code 159: The table changed in storage engine

[root@devdb7 ~]# perror 1412

MySQL error code 1412 (ER_TABLE_DEF_CHANGED): Table definition has changed, please retry transaction

 

分析:
Alter table tbname add index idx_X(column_name);是一个标准的Alter table 流程,引擎内部操作流程是:

1 If a transaction is open on this thread, commit it. 

2 Acquire a read lock for the table. 

3 Make a temporary table with new structure 

4 Copy the old table to the temporary table row by row changing the structure of the rows on the fly. 

5 Rename the original table out of the way 

6 Rename the temporary table to the original table name. 

7 Drop the original table. 

8 Release the read lock. 

在1-4步的过程中,别的session可以正常访问这个表,到5的时候,会阻塞别的访问,状态提示是:“Waiting for tables”,然后等待。
前面1412的错误并不是这个。考虑到innodb 不是built in,而是plugin innodb,它实现了Fast Index Creation,是不是这个新特性造成的?

mysql官方文档可以看到

Prior to InnoDB storage engine 1.0.4, unexpected results could occur if a query attempts to use an index created after the start of the transaction containing the query. If an old transaction attempts to access a “too new” index, 
InnoDB storage engine 1.0.4 and later reports an error: ERROR HY000: Table definition has changed, please retry transaction As the error message suggests, committing (or rolling back) the transaction, and restarting it, cures the problem.

在1.0.4或之后的innodb plugin里面,事务访问新索引会提示1412信息,然后事务中断。此错误并没造成多大的影响,相对1.0.4之前的返回异常结果,已经做了优化了。
对于这样的错误信息的处理方法是:As the error message suggests, committing (or rolling back) the transaction, and restarting it, cures the problem.

你可能感兴趣的:(transaction)