SHOW TABLE STATUS 是掌握表級存儲、統計、索引、碎片狀態的核心命令。本文逐字段解析 18 欄含義、數據類型、典型異常值判讀,並給出自動化巡檢 SQL 與告警閾值建議。
SHOW TABLE STATUS; -- 當前庫所有表
SHOW TABLE STATUS LIKE 'tbl_name'; -- 單表(支援通配符 % _)
SHOW TABLE STATUS FROM db_name; -- 指定庫
SHOW TABLE STATUS FROM db_name LIKE 'prefix_%';
| # | 字段 | 含義 | 關鍵判讀 | 典型異常值 |
|---|---|---|---|---|
| 1 | Name | 表名 | 對照命名規範 | 含大寫/特殊字符 |
| 2 | Engine | 存儲引擎 | InnoDB/MyISAM/MEMORY | 業務表非 InnoDB |
| 3 | Version | 表定義版本號 | 每次 ALTER 遞增 | 短期內暴增 → 頻繁 DDL |
| 4 | Row_format | 行格式 | Dynamic/Compressed/Compact/Redundant | 老表仍為 Redundant |
| 5 | Rows | 預估行數 | InnoDB 為採樣估算,誤差 ±10% | 與 COUNT(*) 差距 > 20% |
| 6 | Avg_row_length | 平均行長度(字節) | Data_length / Rows | 異常大 → 大字段/碎片 |
| 7 | Data_length | 數據文件大小(字節) | 聚簇索引 + 數據 | 突增 → 大批量導入/膨脹 |
| 8 | Max_data_length | 最大數據容量 | MyISAM 受限,InnoDB 為 0 (無上限) | MyISAM 接近上限 |
| 9 | Index_length | 索引文件大小(字節) | 非聚簇索引 | Index_length > Data_length * 2 |
| 10 | Data_free | 已分配未使用空間(字節) | 碎片空間,含已刪除行 | > 100MB 或 > Data_length * 0.3 |
| 11 | Auto_increment | 下一個自增值 | 監控自增耗盡風險 | 接近 2^32-1 (INT) 或 2^64-1 (BIGINT) |
| 12 | Create_time | 創建時間 | 資產管理 | 未授權表突然出現 |
| 13 | Update_time | 最後修改時間 | InnoDB 不更新(NULL),MyISAM 更新 | 長期不變 → 僵尸表 |
| 14 | Check_time | 最後 CHECK TABLE 時間 | 巡檢追蹤 | 超過 30 天未檢查 |
| 15 | Collation | 字符集校對規則 | utf8mb4_general_ci 等 | 非標準字符集 |
| 16 | Checksum | 校驗和 | MyISAM 支持,InnoDB 為 NULL | - |
| 17 | Create_options | 創建時額外選項 | PARTITION BY、ROW_FORMAT 等 | 意外的壓縮/分區選項 |
| 18 | Comment | 備註/視圖標識 | InnoDB 顯示剩餘表空間;視圖含 VIEW | 備註為空 → 文檔缺失 |
SELECT
TABLE_SCHEMA, TABLE_NAME,
ROUND(Data_free/1024/1024, 2) AS free_mb,
ROUND(Data_free/NULLIF(Data_length,0)*100, 2) AS frag_pct
FROM information_schema.TABLES
WHERE TABLE_SCHEMA NOT IN ('mysql','information_schema','performance_schema','sys')
AND Data_free > 100*1024*1024
AND Data_free > Data_length * 0.3
ORDER BY frag_pct DESC;
處置: OPTIMIZE TABLE 或 ALTER TABLE ... ENGINE=InnoDB 重建表。
SELECT
TABLE_SCHEMA, TABLE_NAME,
Auto_increment,
CASE
WHEN Auto_increment > 2147483647 THEN 'INT_EXHAUST'
WHEN Auto_increment > 9223372036854775807 THEN 'BIGINT_EXHAUST'
ELSE 'OK'
END AS risk_level
FROM information_schema.TABLES
WHERE Auto_increment IS NOT NULL
AND Auto_increment > 1000000000
ORDER BY Auto_increment DESC;
處置: 變更列類型為 BIGINT、重置自增值(需停寫)、業務邏輯改用 UUID/Snowflake。
SELECT TABLE_SCHEMA, TABLE_NAME, Engine
FROM information_schema.TABLES
WHERE TABLE_SCHEMA NOT IN ('mysql','information_schema','performance_schema','sys')
AND TABLE_TYPE = 'BASE TABLE'
AND Engine != 'InnoDB'
ORDER BY Engine, TABLE_SCHEMA;
SELECT TABLE_SCHEMA, TABLE_NAME, TABLE_COLLATION
FROM information_schema.TABLES
WHERE TABLE_SCHEMA NOT IN ('mysql','information_schema','performance_schema','sys')
AND TABLE_COLLATION NOT LIKE 'utf8mb4%'
AND TABLE_TYPE = 'BASE TABLE';
#!/bin/bash
# 每日 02:00 執行,結果入庫/推送告警
mysql -uroot -p'***' -e "
-- 碎片率
SELECT ... FROM information_schema.TABLES WHERE ...;
-- 自增風險
SELECT ... FROM information_schema.TABLES WHERE ...;
-- 非 InnoDB
SELECT ... FROM information_schema.TABLES WHERE ...;
" | tee /var/log/table_status_$(date +%F).log
Rows 在 InnoDB 中不可信,精確行數必須 SELECT COUNT(*)(或緩存計數表)。Update_time 在 InnoDB 中始終為 NULL,勿用於判斷表活躍度。Data_free 包含可重用空間,不等於「可釋放給 OS 的空間」,OPTIMIZE TABLE 才會真正歸還。information_schema.TABLES 中每個分區為一行,聚合分析需按 TABLE_NAME 前綴分組。將 SHOW TABLE STATUS 18 字段內化為巡檢指標體系,是從「被動滅火」轉向「主動預防」的關鍵一步。建議納入每日巡檢、變更前後對比、容量規劃輸入三大場景。