部分 MySQL 系統變數(如 log_slave_updates)屬於「唯讀」,SET GLOBAL 會報錯 ERROR 1238 (HY000): Variable 'xxx' is a read only variable。當生產環境不允許重啟時,可使用 GDB 直接修改運行中進程記憶體實現熱更改。
mysql> SHOW VARIABLES LIKE 'log_slave_updates';
+-------------------+-------+
| Variable_name | Value |
+-------------------+-------+
| log_slave_updates | OFF |
+-------------------+-------+
mysql> SET GLOBAL log_slave_updates = 1;
ERROR 1238 (HY000): Variable 'log_slave_updates' is a read only variable
# 直接在 shell 執行 (需 root 權限)
gdb -p $(pidof mysqld) -ex "set opt_log_slave_updates=1" -batch
# 驗證
mysql> SHOW VARIABLES LIKE 'log_slave_updates';
+-------------------+-------+
| Variable_name | Value |
+-------------------+-------+
| log_slave_updates | ON |
+-------------------+-------+
原理: MySQL 內部全域變數對應 C 代碼中的 opt_xxx 結構體成員,GDB 直接修改進程記憶體生效。
場景:replicate_do_db 非動態參數,需修改內部結構體 rpl_filter。
# 1. 查看當前狀態
mysql> SHOW SLAVE STATUS \G
...
Replicate_Do_DB: test
...
# 2. GDB 調用內部函數新增過濾庫
gdb -p $(pidof mysqld) \
-ex 'call rpl_filter->add_do_db(strdup("hehehe"))' \
-batch
# 3. 驗證生效
mysql> SHOW SLAVE STATUS \G
...
Replicate_Do_DB: test,hehehe
...
| 維度 | 說明 |
|---|---|
| 權限 | 需 root 或 mysql 進程擁有者權限 |
| 版本相容 | 內部符號名 (opt_xxx, rpl_filter) 可能隨版本變更,操作前必須在測試環境驗證 |
| 持久化 | 僅記憶體生效,重啟後失效!必須同步修改 my.cnf 確保重啟後生效 |
| 風險等級 | 高風險:可能導致進程崩潰、資料不一致、複制中斷。僅限緊急情況、無維護窗口、經專家評估後使用 |
| 替代方案 | 優先考慮:滾動重啟、藍綠部署、變更管理流程、MySQL 8.0+ SET PERSIST 持久化配置 |
-- 8.0 支援持久化配置至 mysqld-auto.cnf,重啟生效
SET PERSIST log_slave_updates = ON;
-- 查看持久化配置
SHOW VARIABLES LIKE 'log_slave_updates';
SELECT * FROM performance_schema.variables_info WHERE variable_name='log_slave_updates'\G
GDB 熱修改是「核武級」手段,原理是直接操作進程記憶體。生產環境務必遵循:有維護窗口走變更流程、無窗口評估風險並備妥回滾方案、事後同步配置檔案、記錄變更審計日誌。