恢复后mysqldump数据丢失

时间:2014-04-01 13:54:22

标签: mysql innodb mysqldump

我尝试使用带有innodb默认存储引擎的系统A的mysqldump将大约40gb的数据库db1转储到sql文件中,并尝试在另一个系统B上恢复它。两者都有默认的存储引擎作为innodb和相同的mysql版本。我已经使用检查表状态检查了系统A上的任何表损坏,并且无法在其上找到任何表损坏。我使用下面的查询来计算系统A和系统B上的两个数据库(db1)上的表大小和每个表的行数,并发现系统B的db1上有大约6GB的数据丢失。

SELECT table_schema,
    -> SUM(data_length+index_length)/1024/1024 AS total_mb,
    -> SUM(data_length)/1024/1024 AS data_mb,
    -> SUM(index_length)/1024/1024 AS index_mb,
    -> COUNT(*) AS tables,
    -> CURDATE() AS today
    -> FROM information_schema.tables
    -> GROUP BY table_schema
    -> ORDER BY 2 DESC

当Innodb是默认存储引擎时,我们可以依靠信息模式来计算确切的行数,精确的表格大小(datalength + indexlength)吗?为什么使用mysql转储的转储导致系统B恢复时出现大量数据丢失?

2 个答案:

答案 0 :(得分:1)

InnoDB无法给出表中找到的记录的精确计数(使用SELECT COUNT()查询)。当您使用InnoDB引擎请求表上的记录计数时,您会注意到计数将会波动。

有关更多信息,我想向您推荐InnoDB的MySQL开发人员页面 http://dev.mysql.com/doc/refman/5.0/en/innodb-restrictions.html

  

InnoDB表的限制

     

ANALYZE TABLE通过对每个索引树进行八次随机潜水并相应地更新索引基数估计来确定索引基数(显示在SHOW INDEX输出的基数列中)。因为这些仅是估计,所以ANALYZE TABLE的重复运行可能产生不同的数字。这使得ANALYZE TABLE在InnoDB表上快速但不准确,因为它不会考虑所有行。

     

MySQL仅在连接优化中使用索引基数估计。如果某些连接未以正确的方式进行优化,则可以尝试使用ANALYZE TABLE。在少数情况下,ANALYZE TABLE不会为您的特定表生成足够好的值,您可以在查询中使用FORCE INDEX来强制使用特定索引,或者设置max_seeks_for_key系统变量以确保MySQL更喜欢在表上进行索引查找扫描。请参见第5.1.4节“服务器系统变量”和第C.5.6节“与优化程序相关的问题”。

     

SHOW TABLE STATUS没有提供有关InnoDB表的准确统计信息,除了表保留的物理大小。行计数只是SQL优化中使用的粗略估计。

     

InnoDB没有在表中保留行的内部计数,因为并发事务可能同时“看到”不同数量的行。为了处理SELECT COUNT(*)FROM t语句,InnoDB扫描表的索引,如果索引不完全在缓冲池中,则需要一些时间。如果您的表不经常更改,使用MySQL查询缓存是一个很好的解决方案。要快速计数,您必须使用自己创建的计数器表,并让应用程序根据插入和删除更新它。如果大概行数足够,可以使用SHOW TABLE STATUS。请参见第14.2.12.1节“InnoDB性能调整技巧”。

答案 1 :(得分:0)

检查数据是否丢失的最佳解决方案是比较数据库的内容。

mysqldump --skip-comments --skip-extended-insert -u root -p dbName1 > file1.sql
mysqldump --skip-comments --skip-extended-insert -u root -p dbName2 > file2.sql
diff file1.sql file2.sql

有关详细信息,请参阅this topic

此解决方案的另一个优点是,您可以看到存在差异的位置。