使用MySQL复制表数据时疑似行缺失的问题咨询
问题分析与解答
咱们先梳理下你遇到的整个情况:
你执行了这条MySQL语句来迁移2017年的交易数据:
INSERT cash_transaction2017 SELECT * FROM cash_transaction WHERE created_at < "2018-01-01 00:00:00"
控制台提示插入了336,090行,但在phpMyAdmin浏览cash_transaction2017时只看到334,473行,按created_date升序排序后最后一行和原表不符,一开始怀疑有行缺失。而且不管用MySQL控制台、PHP代码,还是带--skip-tz-utc参数的mysqldump,结果都一致。
之后你做了两次关键验证:
- 执行
SELECT count(*)分别统计两张表符合条件的行数,结果完全相同; - 执行
SELECT SUM(amount)统计交易总额,两张表的总额也完全一致。
针对你的疑问,我来逐一解答:
1. 不存在行缺失
从你做的两个核心验证——行数完全一致和交易总额完全相同——可以100%确定:所有符合条件的行都已经成功插入到cash_transaction2017表中了。
你觉得“行数少、最后一行不符”的原因,大概率是这两点:
- phpMyAdmin的分页机制:phpMyAdmin默认会分页展示数据,你看到的334,473行只是当前加载的分页数据总和,并不是表的全部行数。你可以查看页面顶部/底部的表总行数统计,应该和
COUNT(*)的结果一致。 - 排序逻辑的误解:你按
created_date升序排序后觉得最后一行和原表不符,可能是因为原表的默认返回顺序不是created_date(InnoDB表默认按主键聚簇索引顺序返回数据),或者原表中存在多条created_date等于最大值的记录。你可以试试用ORDER BY created_at DESC LIMIT 10分别查询两张表,对比最新的10条记录,应该就能对应上了。
2. 该问题和InnoDB引擎无关
这个现象和InnoDB没有任何关系。InnoDB作为事务型存储引擎,只要INSERT语句执行成功(控制台返回了正确的插入行数),就会保证数据的完整性,绝对不会出现“部分插入成功、部分丢失”的情况。你后续的COUNT和SUM验证也直接佐证了这一点。
另外,--skip-tz-utc参数只是影响mysqldump时的时区处理逻辑,不会导致数据丢失,你用这个工具复制数据时出现同样的“疑似缺失”,只是因为它本质也是复制符合条件的数据,结果和INSERT操作一致而已。
内容的提问来源于stack exchange,提问作者Tommy Lee
相关产品推荐
相关产品推荐

