天天看點

活久見,為什麼SHOW TABLE STATUS總是不更新23. 總結

那我們再看看文檔中關于

IFS.TABLES

的描述吧:

25.36 The INFORMATION_SCHEMA TABLES Table

The TABLES table provides information about tables in databases.

Columns in TABLES that represent table statistics hold cached values. The information_schema_stats_expiry system variable defines the period of time before cached table statistics expire. The default is 86400 seconds (24 hours). If there are no cached statistics or statistics have expired, statistics are retrieved from storage engines when querying table statistics columns. To update cached values at any time for a given table, use ANALYZE TABLE. To always retrieve the latest statistics directly from storage engines, set information_schema_stats_expiry to 0. For more information, see Section 8.2.3, “Optimizing INFORMATION_SCHEMA Queries”.      

看到這裡,真相基本上呼之欲出了。

IFS.TABLES表中看到的資料是有cache的,預設cache時長是 86400秒(即1天),修改參數 information_schema_stats_expiry 即可調整時長。也就是說,除非cache過期了,或者手動執行

ANALYZE TABLE

更新統計資訊,否則不會主動更新。

這個參數(功能)是MySQL 8.0後新增的,是以這個問題在8.0之前的版本不存在。

參數 information_schema_stats_expiry 還影響其 IFS.STATISTICS 表。

此外,該參數還可以在session級動态修改。

我們嘗試修改session級配置:

[[email protected]]>set session information_schema_stats_expiry = 0;

# 修改完後就可以看到Rows資料變了
[[email protected]]>show table status like 'ttxx'\G
*************************** 1. row ***************************
           Name: ttxx
         Engine: InnoDB
        Version: 10
     Row_format: Dynamic
           Rows: 795064
 Avg_row_length: 57
...

[[email protected]]>set session information_schema_stats_expiry = 86400;
# 把session配置改回預設值,尴尬的發現Rows值又恢複成0了
[[email protected]] [test]>show table status like 'ttxx'\G
*************************** 1. row ***************************
           Name: ttxx
         Engine: InnoDB
        Version: 10
     Row_format: Dynamic
           Rows: 0
...      

看來,如果應用程式中有需要讀取 table status 概要資訊的時候,最好還是先手動執行

ANALYZE TABLE

或者修改參數值,也可以用下面這樣的SQL:

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

這是MySQL 8.0後新增的HINT文法。

另外,文檔中還有一段注釋:

If the innodb_read_only system variable is enabled, ANALYZE TABLE may fail because it cannot update statistics tables in the data dictionary, which use InnoDB. For ANALYZE TABLE operations that update the key distribution, failure may occur even if the operation updates the table itself (for example, if it is a MyISAM table). To obtain the updated distribution statistics, set information_schema_stats_expiry=0.      

意思是,當啟用參數

innodb_read_only

後再執行

ANALYZE TABLE

就會失敗,哪怕要更新統計資訊的表是MyISAM引擎,因為所有InnoDB表都被設定為隻讀,更新統計資訊後無法回寫到對應的InnoDB字典表裡了。

3. 總結

遇到詭異問題時,總是習慣性地先去查閱官方手冊,通常都是可以得到答案的,耐心點,再耐心點。