MySQL5.5索引数在InnoDB引擎内与索引数在mysql中定义的数量是不一致问题
2016-09-09 16:34
609 查看
在查看MySQL错误日志的时候发现这样的错误,如下:
160322 21:42:59 [ERROR] Table baby/baby_order contains 12 indexes inside InnoDB, which is different from the number of indexes 11 defined in the My
SQL
大概意思是说表baby_order的索引数在InnoDB引擎内与索引数在mysql中定义的数量是不一致的
为什么会出现这样的错误呢?
参考了这篇文章的解释 https://www.percona.com/blog/2011/11/29/innodb-vs-mysql-index-counts/
I had a customer recently who a few strange errors in their mysqld.err log:
[ERROR] Table database_name/table_name contains 8 indexes inside InnoDB, which is different from the number of indexes 7 defined in the MySQL
1
[ERROR] Table database_name/table_name contains 8 indexes inside InnoDB, which is different from the number of indexes 7 defined in the MySQL
This customer was running Percona Server 5.1 and they got this error on two tables during a maintenance window when they were adding indexes to the same tables.
We had a suspicion that it had something to do with Fast index creation in Innodb, and that it had been corrected when the ALTER TABLE completed because the errors had not recurred.
Reproducing the error on a test system is simple:
复现这个错误的方法:
create an Innodb table
make a copy of the .frm file
do an ALTER TABLE to add an index
then copy the old .frm file back into place
re-open the table (Might need a FLUSH TABLES or mysqld restart here)
From my testing, I saw that the error only happened when the table was opened and not on every table access. So, it was a possibility that the indexes were out of sync and we weren’t seeing new errors in the log simply because the table hadn’t been re-opened.
But, before getting too crazy, how can we verify the problem still exists? We need a way to compare the output of SHOW CREATE TABLE to what Innodb thinks. What Innodb thinks is in the Innodb Data dictionary.
The first recommendation I got was to simply use the INFORMATION_SCHEMA.INNODB_SYS_INDEXES table, which exists in Percona Server 5.1, but doesn’t appear in MySQL until 5.6 (if the manual is to be trusted). I’d probably consider this on a newer version of Percona Server or MysqL 5.6.
Another person (I’m looking at you, Baron) was adverse to trusting INNODB_SYS_INDEXES from some bad experiences with it, and suggested the Innodb Table monitor instead, see my next post for how that turned out, but this basically will regurgitate the entire Innodb Data dictionary to the mysqld error log file.
可以通过flush table1 table2 强制表关闭,然后重新打开表
If I had to do it over again, I think I’d simply try doing: FLUSH TABLES table1, table2; to force the tables to close and be reopened and simply see if the error message comes back. That might something of a performance impact, but it seems to be the most stable.
In this case, it turned out that the indexes were not out of sync, so I didn’t have to do anything to fix it.
However if I did have to fix it, I found on my test table that the extra index in Innodb could be removed by doing:
修复这个问题可以执行如下的语句更改表引擎为innodb
ALTER TABLE table_name ENGINE=Innodb;
This, of course, rebuilds the whole table based on the .frm table definition and removes the existing index in Innodb, which might not be desirable, but at least you can re-add it later. However, it’s not the greatest thing to do on a live production database master if you can help it.
Another solution might be to figure out what index was missing via the Innodb data dictionary (more on that in a minute), create a separate table identical to the existing .frm, add that index to it, and copy the new .frm back over the original. Kind of scary.
My advice is to ensure the error still exists before trying to fix it.
160322 21:42:59 [ERROR] Table baby/baby_order contains 12 indexes inside InnoDB, which is different from the number of indexes 11 defined in the My
SQL
大概意思是说表baby_order的索引数在InnoDB引擎内与索引数在mysql中定义的数量是不一致的
为什么会出现这样的错误呢?
参考了这篇文章的解释 https://www.percona.com/blog/2011/11/29/innodb-vs-mysql-index-counts/
I had a customer recently who a few strange errors in their mysqld.err log:
[ERROR] Table database_name/table_name contains 8 indexes inside InnoDB, which is different from the number of indexes 7 defined in the MySQL
1
[ERROR] Table database_name/table_name contains 8 indexes inside InnoDB, which is different from the number of indexes 7 defined in the MySQL
This customer was running Percona Server 5.1 and they got this error on two tables during a maintenance window when they were adding indexes to the same tables.
We had a suspicion that it had something to do with Fast index creation in Innodb, and that it had been corrected when the ALTER TABLE completed because the errors had not recurred.
Reproducing the error on a test system is simple:
复现这个错误的方法:
create an Innodb table
make a copy of the .frm file
do an ALTER TABLE to add an index
then copy the old .frm file back into place
re-open the table (Might need a FLUSH TABLES or mysqld restart here)
From my testing, I saw that the error only happened when the table was opened and not on every table access. So, it was a possibility that the indexes were out of sync and we weren’t seeing new errors in the log simply because the table hadn’t been re-opened.
But, before getting too crazy, how can we verify the problem still exists? We need a way to compare the output of SHOW CREATE TABLE to what Innodb thinks. What Innodb thinks is in the Innodb Data dictionary.
The first recommendation I got was to simply use the INFORMATION_SCHEMA.INNODB_SYS_INDEXES table, which exists in Percona Server 5.1, but doesn’t appear in MySQL until 5.6 (if the manual is to be trusted). I’d probably consider this on a newer version of Percona Server or MysqL 5.6.
Another person (I’m looking at you, Baron) was adverse to trusting INNODB_SYS_INDEXES from some bad experiences with it, and suggested the Innodb Table monitor instead, see my next post for how that turned out, but this basically will regurgitate the entire Innodb Data dictionary to the mysqld error log file.
可以通过flush table1 table2 强制表关闭,然后重新打开表
If I had to do it over again, I think I’d simply try doing: FLUSH TABLES table1, table2; to force the tables to close and be reopened and simply see if the error message comes back. That might something of a performance impact, but it seems to be the most stable.
In this case, it turned out that the indexes were not out of sync, so I didn’t have to do anything to fix it.
However if I did have to fix it, I found on my test table that the extra index in Innodb could be removed by doing:
修复这个问题可以执行如下的语句更改表引擎为innodb
ALTER TABLE table_name ENGINE=Innodb;
This, of course, rebuilds the whole table based on the .frm table definition and removes the existing index in Innodb, which might not be desirable, but at least you can re-add it later. However, it’s not the greatest thing to do on a live production database master if you can help it.
Another solution might be to figure out what index was missing via the Innodb data dictionary (more on that in a minute), create a separate table identical to the existing .frm, add that index to it, and copy the new .frm back over the original. Kind of scary.
My advice is to ensure the error still exists before trying to fix it.
相关文章推荐
- 巧用MySQL InnoDB引擎锁机制解决死锁问题
- Mysql5.5数据库的MyISAM和InnoDB引擎配置优化
- 关于不正常地定义参数对象。提供了不一致或不完整的信息或者MySQL server has gone away的问题总结
- Mysql5.5 InnoDB存储引擎配置和优化
- [MySQL生产环境] Innodb存储引擎内存报警问题处理过程
- Mysql innodb引擎和myisam引擎使用索引区别
- 巧用MySQL InnoDB引擎锁机制解决死锁问题
- mysql5.5―InnoDB 和mysql5.1-myIAM 引擎区别
- MySQL5.5 MyISAM与InnoDB 引擎读写性能对比
- Centos 7 mysql 5.5 启用innodb引擎
- MYSQL 级联删除配置Innodb引擎问题?
- mysql dba系统学习(11)管理innodb引擎的redo log日志的一个问题
- mysql 索引长度tips innodb和myisam引擎
- 关于MySQL InnoDB表的二级索引是否加入主键列的问题解释
- Mysql innodb引擎和myisam引擎 使用索引区别
- MySQL5.5数据库innodb_change_buffering怪异问题分析
- MySQL线上600W纪录的MyISAM表,要把存储引擎改为innoDB,一alter表就立马锁死的问题探讨
- MySQL里使用Innodb引擎自增主键不连续的问题
- 解决最近遇到的高并发下,mysql innodb引擎的死锁问题
- MySQL线上600W纪录的MyISAM表,要把存储引擎改为innoDB,一alter表就立马锁死的问题探讨