MySQL能否无需脚本实现指定表仅今日数据的部分复制?
在MySQL Slave实例仅复制单表今日数据的无脚本方案
可以实现,以下是两种无需编写外部脚本的原生MySQL方案:
方案一:利用MySQL 8.0+的行级复制过滤规则
这是最直接的方式,通过Slave端配置实现仅复制符合条件的行:
- 确保主库的binlog格式为行级(
binlog_format=ROW),这是行过滤的前提 - 在Slave的配置文件(my.cnf/my.ini)中添加以下规则:
replicate-do-table=你的数据库名.目标表名 replicate_rows_filter=你的数据库名.目标表名:WHERE 日期字段名 = CURDATE() - 重启Slave的MySQL服务使配置生效
- 初始化Slave的目标表:仅从主库导入今日的数据(可通过
mysqldump加--where参数实现,比如mysqldump -u用户 -p 数据库名 目标表名 --where="日期字段名=CURDATE()" > today_data.sql,然后在Slave执行导入),之后启动复制即可
注意:CURDATE()会使用Slave本地的系统日期,需确保主从服务器时间同步。
方案二:基于分区表的复制+Slave端自动清理
如果主库的目标表可以改造成按天分区,也能实现需求:
- 主库将目标表改为按日期字段的RANGE分区,每天创建一个独立分区(例如按
date_column字段,每个分区对应一天的数据) - Slave配置仅复制该表(
replicate-do-table=你的数据库名.目标表名) - 在Slave上开启事件调度器(
SET GLOBAL event_scheduler = ON;,可写入配置文件持久化),创建一个每日执行的事件,自动删除非今日的分区:CREATE EVENT delete_old_partitions ON SCHEDULE EVERY 1 DAY STARTS '2024-01-01 00:05:00' DO BEGIN DECLARE part_name VARCHAR(100); DECLARE cur CURSOR FOR SELECT PARTITION_NAME FROM INFORMATION_SCHEMA.PARTITIONS WHERE TABLE_SCHEMA='你的数据库名' AND TABLE_NAME='目标表名' AND PARTITION_NAME != CONCAT('p_', DATE_FORMAT(CURDATE(), '%Y%m%d')); DECLARE CONTINUE HANDLER FOR NOT FOUND SET part_name = NULL; OPEN cur; read_loop: LOOP FETCH cur INTO part_name; IF part_name IS NULL THEN LEAVE read_loop; END IF; SET @sql = CONCAT('ALTER TABLE 你的数据库名.目标表名 DROP PARTITION ', part_name); PREPARE stmt FROM @sql; EXECUTE stmt; DEALLOCATE PREPARE stmt; END LOOP; CLOSE cur; END;
这种方案依赖主库的分区设计,但对主库性能影响较小,适合数据量极大的场景。
内容的提问来源于stack exchange,提问作者Andrea Mason
相关产品推荐
相关产品推荐

