前言
當你半路接手一個生產業務庫時,可能會發現其中很多的表命名很像廢棄表、備份表或者歸檔表,比如以 “tmp”、“copy”、“backup” 和日期等等後綴的表名。當然這些都是最直觀的判斷,可能依然會有很多因爲歷史遺留問題產生的垃圾表,然而直接通過表命名無法準確判斷是否可以清理,那麼如果長時間不清理會帶來什麼問題嗎?
首先按照生產環境的標準,這些或測試,或臨時備份的表都不應該保留,並且在分析元數據時會增加額外的工作量。
其次有些表的體積過於龐大,浪費大量存儲空間,最後因爲這些歷史遺留問題沒有及時解決,隨着時間的流逝導致問題會越來越複雜,越來越難以追溯。
綜上所述,我需要一種可靠的技術手段去統計到底哪些表長時間沒有訪問過,這時有些人會說 general log 可以統計,但是生產數據庫不會開啓此項參數,畢竟比較影響磁盤的性能。
Proxysql 作爲一款優秀的中間件,stats_mysql_query_digest 表默認記錄着所有的數據庫請求,可以從此表分析出從未使用過的表(時間越久分析越準確,畢竟不排除有些表的訪問週期比較長)。
實現方法
-
導出全量表
mysql -uroot -pxxx -s -e "SELECT TABLE_NAME FROM information_schema.TABLES WHERE TABLE_SCHEMA in ('test');" > table_name.txt
-
循環打印最後一次訪問時間和從未使用過的表名稱
for i in `cat table_name.txt`;do mysql -u admin -p'xxx' -h 127.0.0.1 -P6032 --default-auth=mysql_native_password -s -e "select ifnull((SELECT from_unixtime(last_seen+28800) FROM stats_mysql_query_digest where digest_text like '%${i}%'),'${i}');";done > ./unused.txt
查看文件輸出如下:
2021-03-23 13:42:37
2021-03-23 14:43:56
tb2
tb3
-
刪除最後一次訪問時間
sed '/:/d' unused.txt (不修改文件)
sed -i '/:/d' unused.txt (修改文件)
刪除後如下圖所示:
tb2
tb3
-
人工確認是否可以清理
此篩選出的表需要與項目負責人確認是否可以清理,如果確認可以清理,也不是直接物理刪除,需要 rename 統一的後綴名,並且再觀察一段時間是否有人反饋因爲訪問不到表產生的問題,如果不再出現任何問題,那麼就可以放心地清理了。
附批量生成 rename 語句:
SELECT
CONCAT( 'ALTER TABLE ', TABLE_NAME, ' RENAME ', TABLE_NAME, '_unused;' )
FROM
INFORMATION_SCHEMA.TABLES
WHERE
table_schema IN ( 'unused' ) AND TABLE_TYPE='BASE TABLE';
SELECT
CONCAT( 'ALTER TABLE ', TABLE_NAME, ' RENAME ', TABLE_NAME, '_unused;' )
FROM
INFORMATION_SCHEMA.TABLES
WHERE
table_name IN ( 'table1', 'table2' …) AND TABLE_TYPE='BASE TABLE';
注:如果篩選出的表過多,可以新建一個數據庫 “unused” 包含所有未使用的表,或者使用文本編輯工具批量生成 “'table1', 'table2' …”,反之手動複製粘貼即可。
文章推薦:
技術分享 | MySQL binlog 分析工具 analysis_binlog 的使用介紹
社區近期動態
本文分享自微信公衆號 - 愛可生開源社區(ActiontechOSS)。
如有侵權,請聯繫 [email protected] 刪除。
本文參與“OSC源創計劃”,歡迎正在閱讀的你也加入,一起分享。