在線添加索引遇到的錯誤: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.


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM