前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >MySQL意外查不到数据,真相令人惊掉下巴

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

作者头像
田帅萌
发布2019-07-05 10:31:03
1.3K0
发布2019-07-05 10:31:03
举报
文章被收录于专栏:「3306 Pai」社区「3306 Pai」社区

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

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

先执行COUNT(*)统计总数

代码语言:javascript
复制
[root@yejr.me]> select count(*) from t1;
+----------+
| count(*) |
+----------+
|        0 |
+----------+
1 row in set (1 min 25.85 sec)

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

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

代码语言:javascript
复制
[root@yejr.me]> select * from t1 limit 1;
Empty set (13.63 sec)

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

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

代码语言:javascript
复制
[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事务状态:(建议横屏观看)

代码语言:javascript
复制
------------
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(*) 的结果可能和预期的不一样。

本文参与 腾讯云自媒体分享计划,分享自微信公众号。
原始发表:2019-07-02,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 3306pai 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档