sod_song_log_2014_1_22_13_18_20)在當前會話設置 SET @@session.sql_log_bin=0,後續 DDL **不寫入 Binlog**,Slave 不會同步執行,從而實現「主刪備留」。
⚠️ 嚴禁 使用
SET GLOBAL sql_log_bin=0,會導致主庫所有寫入停止同步,引發主從數據不一致災難!
DELIMITER $$
CREATE PROCEDURE drop_old_log_tables()
BEGIN
DECLARE t_name VARCHAR(64);
DECLARE done INT DEFAULT FALSE;
DECLARE cur CURSOR FOR
SELECT TABLE_NAME
FROM information_schema.TABLES
WHERE TABLE_SCHEMA = 'EDMOND'
AND TABLE_NAME LIKE 'sod_song_log_%';
DECLARE CONTINUE HANDLER FOR NOT FOUND SET done = TRUE;
OPEN cur;
read_loop: LOOP
FETCH cur INTO t_name;
IF done THEN LEAVE read_loop; END IF;
-- 從表名解析日期:sod_song_log_2014_1_22_13_18_20
-- 簡化假設:表名格式固定,REPLACE 移除前綴後直接 DATEDIFF
IF DATEDIFF(NOW(), REPLACE(t_name, 'sod_song_log_', '')) > 30 THEN
SET @@session.sql_log_bin = 0;
SET @sql = CONCAT('DROP TABLE ', t_name);
PREPARE stmt FROM @sql;
EXECUTE stmt;
DEALLOCATE PREPARE stmt;
SET @@session.sql_log_bin = 1;
END IF;
END LOOP;
CLOSE cur;
END$$
DELIMITER ;
mysql> CALL drop_old_log_tables();
Query OK, 0 rows affected (0.28 sec)
mysql> SHOW TABLES;
+---------------------------------+
| Tables_in_edmond |
+---------------------------------+
| sod_song_log_2014_4_22_13_18_20 | -- 僅保留最近表
+---------------------------------+
mysql> SELECT NOW();
+---------------------+
| 2014-04-22 17:58:24 |
+---------------------+
Binlog 中無任何 DROP TABLE 記錄,備庫分表完整保留。
# 每天凌晨 2 點執行
0 2 * * * mysql -h -u -p -e "CALL drop_old_log_tables();"
YYYY_MM_DD,避免字符串替換錯誤RENAME TABLE t TO t_to_drop; DROP TABLE t_to_drop; 降低鎖持有時間innodb_file_per_table=ON 確保空間真正釋放給 OS