社区所有版块导航
Python
python开源   Django   Python   DjangoApp   pycharm  
DATA
docker   Elasticsearch  
aigc
aigc   chatgpt  
WEB开发
linux   MongoDB   Redis   DATABASE   NGINX   其他Web框架   web工具   zookeeper   tornado   NoSql   Bootstrap   js   peewee   Git   bottle   IE   MQ   Jquery  
机器学习
机器学习算法  
Python88.com
反馈   公告   社区推广  
产品
短视频  
印度
印度  
Py学习  »  DATABASE

MySQL意外查不到数据,真相令人惊掉下巴

老叶茶馆 • 6 年前 • 302 次点击  

导读

刚刚导入了几千万数据,却意外的查不到,这是为何?

前几天,我的朋友小明同学火急火燎地找到我,说有个表刚导入了几千万数据,却怎么也查不到数据,很是抓狂,让我给看看。

下面是我到达现场后,亲自执行几个命令的结果:

先执行COUNT(*)统计总数

[root@yejr.me]> select count(*) from t1;
+----------+
| count(*) |
+----------+
| 0 |
+----------+
1 row in set (1 min 25.85 sec)

SQL运行的有点慢,结果的确是空的。

再任意查询一条记录看看:

[root@yejr.me]> select * from t1 limit 1;
Empty set (13.63 sec)

只查一条记录而已,这SQL运行的也忒慢了点,结果也还是空的。

好吧,再看看表的状态:(建议横屏观看)

[root@yejr.me]> show table status \G
*************************** 1. row ***************************
Name: t1
Engine: InnoDB
Version: 10
Row_format: Dynamic
Rows: 28159173
Avg_row_length: 45
Data_length: 1269825536
Max_data_length: 0
Index_length: 1308606464
Data_free: 1063256064
Auto_increment: 12851381
Create_time: 2019-06-04 10:49:44
Update_time: NULL
Check_time: NULL
Collation: utf8mb4_general_ci
Checksum: NULL
Create_options:
Comment:
1 row in set (0.00 sec)

[root@yejr.me]# ll
-rw-r----- 1 mysql mysql 67 Jun 4 10:34 db.opt
-rw-r----- 1 mysql mysql 8732 Jun 4 10:49 t1.frm
-rw-r----- 1 mysql mysql 2931818496 Jun 4 13:09 t1.ibd

看着明明是有数据的呀,真特么邪门,下巴都快掉了。

但是,可是,了解我的人应该都知道我是不信邪的。

作为老司机的我,还有其他大招没放出来呢。

再看看执行SELECT时的线程状态,发现是正常的Sending data,没啥特别的。

好吧,要真的放大招了,再看看InnoDB事务状态:(建议横屏观看)

------------
TRANSACTIONS
------------
Trx id counter 41220
Purge done for trx's n:o < 40288 undo n:o < 0 state: running but idle
History list length 44
LIST OF TRANSACTIONS FOR EACH SESSION:
---TRANSACTION 422164356356832, not started
0 lock struct(s), heap size 1136, 0 row lock(s)
---TRANSACTION 40199, ACTIVE 1361 sec recovered trx
ROLLING BACK 1 lock struct(s), heap size 1136,
0 row lock(s), undo log entries 3637207

注意到事务 40199 的状态是正在回滚中"ROLLING BACK",影响的undo log有3637207之多。

经过确认,原因确定了,事务 40199 在导入数据过程中,小明同学耐心不足,以为导入过程发生了啥问题,对导入线程贱贱的按了CTRL+C。

就问你意不意外,惊不惊喜吧。。。

结果就悲剧了,导入线程的事务被回滚,所以才看到了那么多的undo log entries,总共是几千万数据啊,只不过我们看到的时候还剩下300多万。

后来,小明又做了一次导入,这次又悲剧了,因为公司断网了,导入线程又一次被回滚(画外音,论远程操作时用screen的重要性)。

在上面这个例子中,可能有同学会奇怪,为什么导入还没结束,但却能看到表空间文件已经挺大的了,而且show table status也能看到rows值比较大。

首先,在本案例中,导入数据过程中,由于buffer pool有限,没办法把所有新数据都放在buffer pool中,部分数据会先写入到表空间磁盘文件中,所以才能看到表空间文件大小不为零。

其次,show table status看到的统计信息本身不是精确值,在本案中,随着导入数据增多(虽然导入事务还没提交),但统计信息也会更新。

和本案类似的场景还有,一个大表被执行全表delete了(不是直接truncate),这个事务产生的undo log还没被purge完毕,或者这个事务也被回滚了,在这个过程中,执行 COUNT(*) 的结果可能和预期的不一样。

好课推荐

最后,给大家介绍一个好课。

由知数堂联合冯光普老师共同打造的《深入浅出MySQL Group Replication》课程上线了。

本课程分成基础、进阶、实践三大模块,系统全面地从基本原理、实现细节、实践指导等多方面学习掌握MGR各个知识点,课程中还介绍了MGR的特性及限制、适用场景、冲突检测原理、流控机制、性能优化等内容。本课程系业界首发,可通过知数堂在线课堂在线学习。原价68元,现在报名可享受首月特价仅需48元。

冯老师是某大型电商数据库负责人,保障线上数据库集群的稳定高效运行,并负责数据库自动化运维平台建设,热衷开源数据库技术分享及交流。

扫描下方二维码开始学习

Python社区是高质量的Python/Django开发社区
本文地址:http://www.python88.com/topic/34487