昨天我遇到了一个新问题,我的一个 MySQL 5.5 从数据库在 AWS 的 EC2 上运行。数据库是从另一个从站的快照创建的。数据是正确的,但至少对于一个表,二级索引返回的结果不完整。通过父 id 查询子表返回 498 行,而它应该返回 504。通过主键查询丢失的 6 行工作,并且返回了正确的父 id,所以问题出在二级索引上。
这个问题对我来说非常重要,因为据推测,即使从站上的所有数据都与主站匹配,我仍然会从在从站上运行的某些查询中得到不正确的结果。
我的蛮力解决方案是像这样重建整个表:
alter table my_table engine = innodb;
Run Code Online (Sandbox Code Playgroud)
这解决了这个特定表的问题,但我还有以下问题:
1) How can I determine if other tables have similar index corruption?
2) What's the most efficient way to fix the corrupt indexes?
Run Code Online (Sandbox Code Playgroud)
我在网上找到了一些很好的资源来查找和修复 InnoDB 数据损坏,但没有找到任何与 InnoDB 索引损坏相关的资源。
我查看了 MySQL 错误日志并没有找到确凿的证据。我确实发现了一些令人不安的 InnoDB 错误。我假设这是一个单独的问题,但它可能是相关的:
130109 9:46:41 InnoDB: unable to find a record to delete-mark
InnoDB: tuple DATA TUPLE: 2 fields;
0: len 4; hex 04af1f21; asc !;;
1: len 4; hex 0a1c03bd; asc ;;
InnoDB: record PHYSICAL RECORD: n_fields 2; compact format; info bits 0
0: len 4; hex 04af1f21; asc !;;
1: len 4; hex 0a052a77; asc *w;;
Run Code Online (Sandbox Code Playgroud)
Ike*_*ker 15
感谢 Rolando 和 Michael 的回复。
为了结束循环,这是我为我的原始问题想出的答案:
答:使用CHECK TABLE
。我运行mysqlcheck -c
了所有相关的 InnoDB 表以找出哪些表有索引损坏
问:修复损坏索引的最有效方法是什么?
OPTIMIZE TABLE
到rebuid有损坏的索引的InnoDB表。这会导致完整的表重建,从而修复损坏。您可能有最简单的解决方案。但是,我想澄清一些事情:
使用正在运行的 MySQL 实例制作快照可能会影响负责二级索引操作的一个文件:ibdata1。
系统表空间ibdata1
是7类InnoDB信息的家
我会担心的关键类是双写缓冲区和插入缓冲区。使用其中任何一个未正确编写的实时快照都会导致数据损坏。
这样做FLUSH TABLES WITH READ LOCK;
不会像人们想象的那样停止对 ibdata1 的写入。我之前写过关于这个主题的文章。我曾经认为它确实如此,直到它被DBA.SE 成员 @ShlomiNoach指出。
想想 InnoDB 缓冲池。您必须清除其中的每个脏页才能将所有内容静默到磁盘。以下强制基于每个表的所有脏页:
SET GLOBAL innodb_fast_shutdown = 0;
其次是 service mysql stop
SET GLOBAL innodb_max_dirty_pages_pct = 0;
等待 1% 的缓冲池变脏另外,不要忘记二进制日志和中继日志依赖于操作系统进行刷新。
在这些方面,EC2 快照不支持 MySQL,就像 LVM 快照一样。这就是为什么像 CDP 的 R1Soft 这样的备份软件有一个 MySQL 模块用于这种场合。
相反,Amazon RDS MYSQL 实例是为此类以 InnoDb 为中心的场景而构建的。仅当 RDS 实例中有活动的 MyISAM 表时才FLUSH TABLES WITH READ LOCK;
需要手动执行。
关于您的原始问题,当您运行时,ALTER TABLE my_table ENGINE=InnoDB;
您只需重建从表的数据页读取的索引页,很可能绕过 ibdata1 插入缓冲区。这就是为什么这对你有用。
如果你可以做一个mysqldump --single-transaction --master-data=1
在主服务器上,将 mysqldump scp 到从服务器,并且没有财务费用,那将是设置 EC2 从服务器的更安全的方法。
如果您必须执行快照操作,请在 Slave 上执行此操作:
SET GLOBAL innodb_fast_shutdown = 0;
service mysql stop
service mysql start
/etc/my.cnf
附加信息:ib_logilfe0 和 ib_logfile1 越小,关闭速度越快。
我希望这能解释很多。
你最近在评论区问过
如何判断数据库是否有索引损坏?
请记住,您使用的是 EC2 而不是 RDS。对于 RDS,Amazon 负责 VM 和 MySQL 实例的整体状态。对于 EC2,Amazon 只负责 VM。MySQL 实例的整体状态现在取决于您。您可能希望将数据库移植到 RDS,因为它带有额外的花哨功能来防止此类损坏。
归档时间: |
|
查看次数: |
41226 次 |
最近记录: |