MySQL系统表故障探究 Error: Table "mysql"."innodb_table_stats" not found.

电玩女神 2022-05-24 04:50 283阅读 0赞
  1. 最近在巡检的时候,发现mysql错误日志中,报如下错误:
  2. 1779986 2015-10-06 00:06:37 7f5215214700 InnoDB: Error: Table "mysql"."innodb_table_stats" not found.
  3. 1779987 2015-10-06 00:06:37 7f5215214700 InnoDB: Recalculation of persistent statistics requested for table "xxxx"."xxxxxx" but the required persistent statistics storage is not present or is corrupted. Using transient stats instead.
  4. 经过排查,发现是mysql 的几张系统表不见了,到底是那几张呢?

MySQL 5.6的ibdata1表空间包含了5个InnoDB基础表,如下:

  1. mysql> select table_name from information_schema.tables where table_schema='mysql' and engine='InnoDB';
  2. +----------------------+
  3. | table_name |
  4. +----------------------+
  5. | innodb_index_stats |
  6. | innodb_table_stats |
  7. | slave_master_info |
  8. | slave_relay_log_info |
  9. | slave_worker_info |
  10. +----------------------+
  11. 5 rows in set (0.00 sec)
  12. MySQL 5.6之前,如果关闭MySQL后删除ibdata1,再重新启动MySQL的时候ibdata1会被重新创建, 但从MySQL 5.6开始,这5个表不会被重建,究其缘由是因为这几张表的存储引擎是innodb,而且在MySQL5.5 中并没有这几张表。大致来看看5.65.5系统表的区别:
  13. MySQL 5.5 系统表
  14. +---------------------------+
  15. | columns_priv |
  16. | db |
  17. | event |
  18. | func |
  19. | help_category |
  20. | help_keyword |
  21. | help_relation |
  22. | help_topic |
  23. | host |
  24. | ndb_binlog_index |
  25. | plugin |
  26. | proc |
  27. | procs_priv |
  28. | proxies_priv |
  29. | servers |
  30. | tables_priv |
  31. | time_zone |
  32. | time_zone_leap_second |
  33. | time_zone_name |
  34. | time_zone_transition |
  35. | time_zone_transition_type |
  36. | user |
  37. +---------------------------+
  38. 22 rows in set (0.00 sec)
  39. MySQL 5.6 系统表
  40. +---------------------------+
  41. | Tables_in_mysql |
  42. +---------------------------+
  43. | columns_priv |
  44. | db |
  45. | event |
  46. | func |
  47. | general_log |
  48. | help_category |
  49. | help_keyword |
  50. | help_relation |
  51. | help_topic |
  52. | innodb_index_stats |
  53. | innodb_table_stats |
  54. | ndb_binlog_index |
  55. | plugin |
  56. | proc |
  57. | procs_priv |
  58. | proxies_priv |
  59. | servers |
  60. | slave_master_info |
  61. | slave_relay_log_info |
  62. | slave_worker_info |
  63. | slow_log |
  64. | tables_priv |
  65. | time_zone |
  66. | time_zone_leap_second |
  67. | time_zone_name |
  68. | time_zone_transition |
  69. | time_zone_transition_type |
  70. | user |
  71. +---------------------------+
  72. 28 rows in set (0.00 sec)
  73. 由上述统计可以看到,在mysql5.6 中,除了增加了上述5张表,还添加了general\_log slow\_log 表,并且将5.5中的host表合到了5.6中的user表中。
  74. 在错误日志中追溯原因,发现是在一次故障迁移中,删除过ibdata1文件,在重启之后,自动创建的ibdata1文件,但这几张innodb系统表并没加载到表空间中。这些错误虽然并不影响业务,但很影响备份,在错误日志中大量出现,也是很烦的。

那么对于这样的错误,我们该如何处理?

1、如果是slave备机,停止复制,记录pos等信息(对于不复制mysql库来说,也没有必要做这一步)

  1. mysql>stop slave ;

2、删除上述系统表

  1. drop table mysql.innodb\_index\_stats;
  2. drop table mysql.innodb\_table\_stats;
  3. drop table mysql.slave\_master\_info;
  4. drop table mysql. slave\_relay\_log\_info;
  5. drop table mysql. slave\_worker\_info ;

3、删除相关的.frm与 .ibd 文件

  1. rm -rf innodb\_\*\_stats\*
  2. rm -rf slave\_\*

4、重新创建上述系统表

  • 从其他机器上,使用mysqldump将这几张表的表结构备份出来,放到该机器上重新执行,备份脚本如下:

    1. #!/bin/sh
    2. TABLELIST="innodb_index_stats"
    3. TABLELIST="${TABLELIST} innodb_table_stats"
    4. TABLELIST="${TABLELIST} slave_master_info"
    5. TABLELIST="${TABLELIST} slave_relay_log_info"
    6. TABLELIST="${TABLELIST} slave_worker_info"
    7. mysqldump -uroot -p mysql ${TABLELIST} > mysql_innodb_tables.sql
  • 将 mysql_innodb_tables.sql拷贝到出现坏表错误的那台数据库机器,并将其导入到系统库mysql库中.

    1. # mysql -uroot -p mysql < mysql_innodb_tables.sql
  • 运行FLUSH TABLES(可选)

5、重启数据库

6、启动slave,如果报错,重新change master

7、重新确定错误日志中有无类似报错

注意 :不要轻易删除ibdata1文件,在不同的版本、不同的分支,系统表都有可能不太一样,如mysql 5.6 与 MariaDB 10.0的系统表,mysql5.5 与mysql 5.6 的 系统表等等,在做迁移或升级时,很容易忽略掉这些细节,所以在做之前,一定要备份,不要任性而为。

参考文章:http://bugs.mysql.com/bug.php?id=67179

发表评论

表情:
评论列表 (有 0 条评论,283人围观)

还没有评论,来说两句吧...

相关阅读