優化 rds 碎片
優化 RDS 碎片
之前資料庫雖然持續在刪除 log,但實際占用空間並沒有減少。問題在於 InnoDB 刪除資料後不會自動釋放空間,必須執行 OPTIMIZE TABLE 才能回收碎片。但這個操作會鎖表,而遊戲伺服器需要不停服維護,所以無法直接使用。
改用 pt-online-schema-change 進行線上遷移,整個過程不影響業務讀寫。
安裝 Percona Toolkit
sudo yum -y install https://downloads.percona.com/pub/percona/release/percona-release-latest.noarch.rpm
sudo percona-release enable tools release
sudo yum install percona-toolkit -y
pt-online-schema-change --version
# pt-online-schema-change 3.6.0
查詢各資料表碎片大小
SELECT
table_name,
data_free / 1024 / 1024 AS data_free_mb
FROM information_schema.tables
WHERE table_schema = '****_game'
AND table_name IN (
't_****_cards',
't_****_coins',
't_*****_credits',
't_****_record_one',
't_****_record_coin',
't_***_record'
);

查詢結果發現 t_****_record 碎片異常龐大,進一步確認:
SELECT
table_name,
data_length / 1024 / 1024 AS data_mb,
data_free / 1024 / 1024 AS free_mb
FROM information_schema.tables
WHERE table_schema = '****_game' AND table_name = 't_****_record';

結果顯示實際資料約 45 GB,碎片卻高達 147 GB,碎片比資料本身還大三倍以上,非常值得清理。
執行 pt-online-schema-change
pt-online-schema-change \
--alter="ENGINE=InnoDB" \
--user=csmj_root \
--password="你的密码" \
h=rm-***********.mysql.rds.aliyuncs.com,P=3306,D=****_****,t=t_****_record \
--chunk-size=1000 \
--execute
一直顯示錯誤
Cannot connect to P=3024,h=,p=...,u=csmj_root: DBI connect(';host=;port=3024;mysql_read_default_group=client','csmj_root',...) failed: Can't connect to local MySQL server through socket '/var/lib/mysql/mysql.sock' (2) at /usr/bin/pt-online-schema-change line 2345.
Can't call method "selectrow_array" on an undefined value at /usr/bin/pt-online-schema-change line 4391.
查了 claude 跟 豆包都不行,後來查了 google AI 改成這個版本終於可以了
$ pt-online-schema-change --alter="ENGINE=InnoDB" --user=****_**** --password="********" --chunk-size=1000 --recursion-method=none --no-version-check --execute h=rm-uf*********.mysql.rds.aliyuncs.com,P=3306,D=nszmj_game,t=t_game_record
問題在於
- --recursion-method=none
告訴 pt-osc 不要嘗試尋找備庫,跳過備庫檢查。沒加這個就會報 Can't use an undefined value as an ARRAY reference 的錯誤。 - DSN 放最後
h=...,P=3306,D=...,t=... 移到指令最末尾,避免參數解析時 host 被吃掉,這是之前一直報 h= 為空的根本原因。 - --no-version-check
跳過版本檢查,避免連線到 Percona 伺服器做版本驗證,在某些網路環境下會卡住。
開始進行數據遷移

大約執行了 20 分鐘完成
2026-04-23T03:59:14 Copied rows OK.
2026-04-23T03:59:14 Analyzing new table...
2026-04-23T03:59:14 Swapping tables...
2026-04-23T03:59:14 Swapped original and new tables OK.
2026-04-23T03:59:14 Dropping old table...
2026-04-23T03:59:15 Dropped old table nszmj_game._t_game_record_old OK.
2026-04-23T03:59:15 Dropping triggers...
2026-04-23T03:59:15 Dropped triggers OK.
Successfully altered ****_***.t_****_record.
原本使用量到了 630G,最終優化結果為 476G

碎片从 147 GB 降到 6 MB