不能直接用,因主从复制会全量重演生产库所有操作(含误删),使测试库成为其镜像;须用ROW格式、read_only+super_read_only组合、专用账号,并避免库级过滤。
MySQL 主从复制能直接用于生产库到测试库同步吗
不能直接用,除非你清楚它会把
、
、误删的
也原样重放过去。主从复制是强一致性机制,不是“选同步”,而是“全量重演”,测试库一旦挂上从库角色,就等于成了生产库的镜像——包括所有线上事故。
实操建议:
禁用
这类库级过滤,它在语句级复制下不可靠,跨库操作容易漏同步或错同步
必须用基于行的复制(
),否则触发器、函数等上下文丢失会导致数据不一致
从库开启
,但要额外加
(否则无法执行
等管理命令)
如果只是单向同步测试库,建议用专用账号,权限仅限
和
,禁止写入
pg_dump + pg_restore 定时同步 PostgreSQL 测试库
适合中小规模(
导出小于 5GB)、对同步延迟不敏感(小时级)的场景。它本质是快照式覆盖,不是增量,所以不会把测试库里的临时表或调试数据带进生产逻辑。
常见错误现象:同步后测试库报
,或序列值重置回 1。
实操建议:
用
避免清空不该动的表
恢复前先
再
,防止字符集或 LC_COLLATE 不一致
加
而非默认的
,方便排查导入失败的具体行;但大数据量时改用
降低内存压力
定时任务里检查
的退出码,非 0 就发告警,别只看日志有没有 “done”
如何避免同步时阻塞测试库上的开发查询
同步过程本身会锁表(如
默认加
),而开发人员可能正连着测试库跑
调接口,一锁就是几分钟,体验极差。
实操建议:
同步目标不直连
,而是导到新库名如
,再原子切换:
切换前用
杀掉长连接,但跳过
状态(可能是开发正在调试事务)
如果用 MySQL,可用
做无锁替换,但它只适用于表结构变更,不适用整库同步
所有同步脚本开头加
,超时就退出,别死等
无损发布中“数据同步”和“服务更新”的边界在哪
很多人以为只要数据库同步完,代码一上线就万事大吉。其实关键断点在应用层:旧代码还在读
表,新代码已开始写
,此时同步脚本若把 v1 数据也刷进 v2,就会造成双写冲突或字段覆盖。
实操建议:
同步脚本必须明确知道当前发布阶段——是灰度前、灰度中、还是全量后,不同阶段同步范围不同(例如灰度中只同步白名单用户)
在应用配置里加
,同步脚本读这个开关决定是否执行、是否清理旧表
不要让同步逻辑耦合在发布脚本里,它应该独立部署、可观测(比如暴露
接口返回最近一次同步时间戳和行数)
最易被忽略的一点:时间戳字段(
)在同步时要不要保留原值?多数情况要,否则业务侧的“最后修改时间”会被覆盖成同步时间
drop tabletruncatedelete from usersreplicate-do-dbbinlog_format = ROWread_only = ONsuper_read_only = OFFSTOP SLAVEREPLICATION SLAVESELECTpg_dumprelation "xxx" does not existpg_dump --clean --no-owner --no-privileges --exclude-table-data='.*_tmp'DROP DATABASE testdbCREATE DATABASE testdb WITH TEMPLATE template0--insertsCOPY--column-insertspg_restorepg_restoreACCESS EXCLUSIVESELECT * FROM orders LIMIT 100testdbtestdb_nextALTER DATABASE testdb RENAME TO testdb_old; ALTER DATABASE testdb_next RENAME TO testdbSELECT pid, state, query FROM pg_stat_activity WHERE datname = 'testdb'idle in transactionpt-online-schema-changeSET lock_timeout = '5s';user_profile_v1user_profile_v2sync_mode: 'readonly' / 'migrate' / 'disabled'/health/syncupdated_at