mysql新增参数未传异常_难道发现了mysql的bug?show table status 命令不起作用了

60433197d762a88cb16f2b17aa7670a0.png

作为mysql运维开发人员,show table status命令还是比较经常用的,但是换了新版本8.0之后,似乎不大好用了,好像出问题了,更新不了表信息了,是不是有bug,我们试试吧。

环境准备,问题复现

数据库版本:mysql 8.0.19,我们新增一个空表(test),简单点,就id和name字段,建好之后

ed7547870241e3aaf979ecc6a1720a0a.png

# 第一次执行

show table status where name  = 'test'

看到 Rows = 0,没问题

926d3e6a6fdc83c9ea320bc06ff276c7.png

这时候随便插入3条数据并提交,然后再执行一下

show table status where name  = 'test'
6c4b02e0129019e707e4cabaf710cf5e.png
c87d135bf3ba7991c5fca920155df2bb.png

依旧没有更新,换句话说,就是执行 SHOW TABLE STATUS 时无法及时查看到该表的最新统计信息。如果不更新的话,你肯定想,那这个命令还有什么存在的必要,或者根本就是bug。但是你可能会怀疑,然后就会去查看 mysql.innodb_table_stats 和 mysql.innodb_index_stats 两个表,却又可以看到该表的统计信息已经更新了,但是结果可能又不是你想要的,我们先看看结果

select * from mysql.innodb_table_stats where database_name ='***' and table_name ='test';
a61404398dc01d81e87b992b73265b13.png

数据更新了,但是显示只有2行数据。再看看下面

select * from mysql.innodb_index_stats where database_name ='***' and table_name ='test';
38e72ec9a77005ab2cb25ba768dfdae7.png

这个表倒是正确了,3个ID索引记录。

什么原因及解决方法

1、因为mysql升到8.0之后。TABLES表中看到的数据是有缓存的,默认缓存时长是 86400秒(即1天),修改参数 information_schema_stats_expiry 即可调整时长。也就是说,除非cache过期了,或者手动执行 ANALYZE TABLE 更新统计信息,否则不会主动更新。
这个参数(功能)是MySQL 8.0后新增的,所以这个问题在8.0之前的版本不存在。
参数 information_schema_stats_expiry 还影响其 IFS.STATISTICS 表。

我们手工执行下表分析,在执行show table status,即可看到更新行数据了

 ANALYZE TABLE test show table status where name  = 'test'
0abc8e210de414be80d3e747c717f797.png

2、为什么innodb_table_stats 显示数据不正确呢?这个其实是存储引擎的关系!

就是说MyISAM表的Rows是精确值,但InnoDB表则只是大概值,甚至有可能只是真实值的40% ~ 50% 之间。这个官方文档有说明:

• Rows
The number of rows. Some storage engines, such as MyISAM, store the exact count. For other storage engines, such as InnoDB, this value is an approximation, and may vary from the actual value by as much as 40% to 50%. In such cases, use SELECT COUNT(*) to obtain an accurate count.
The Rows value is NULL for INFORMATION_SCHEMA tables.

3、我们也可以使用更改会话级别的参数来使得show table status 生效

set session information_schema_stats_expiry = 0;

看来,如果应用程序中有需要读取 table status 概要信息的时候,最好还是先手动执行 ANALYZE TABLE 或者修改参数值,也可以用下面这样的SQL:

select /* set_var(information_schema_stats_expiry = 1) */ * from information_schema.tables where table_schema='***' and table_name = 'test'

这是MySQL 8.0后新增的HINT语法。

执行以上语句之后,再执行 show table status 之后,就能实时看到更新了。

  • 2
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值