增量同步必须依赖不可篡改的递增标识(如version字段或cdc日志位点),仅靠updated_at易因时钟漂移、批量更新等失效;全量同步须原子切换+校验;python同步优先用psycopg2控制粒度,写入需幂等设计。

增量同步必须有可靠的时间戳或版本字段
没有可排序、不可篡改的递增标识,增量同步就等于猜数据。数据库里 updated_at 看似够用,但时钟漂移、批量更新、软删除补漏都会让它失效。真正能扛住生产压力的是 version 字段(配合 ON CONFLICT 或 REPLACE)或者数据库原生的 CDC 日志位点(如 PostgreSQL 的 LSN、MySQL 的 binlog position)。
常见错误现象:WHERE updated_at > '2024-01-01' 漏掉同一秒内多条更新;last_id 方式在删/插混合场景下直接丢数据。
- 优先用数据库自带的变更日志机制,不是自己拼
updated_at - 如果只能用时间字段,务必加
id > last_seen_id双重约束 - 应用层写入必须保证
updated_at由数据库生成(如DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP),不能靠 Python 的datetime.now()
全量同步不是“重跑一遍”,而是带校验的原子切换
全量看起来简单,实际最容易出问题的是中间态不一致——新旧数据混在一起,下游查到半截结果。关键不是“快”,是“可验证”和“可回滚”。
使用场景:表结构变更后首次同步、增量链路中断太久、发现增量累积误差已不可接受。
立即学习“Python免费学习笔记(深入)”;
- 不要直接
TRUNCATE + INSERT,先写入临时表(如mytable_new),校验行数、CHECKSUM或抽样比对关键字段 - 用
RENAME TABLE mytable TO mytable_old, mytable_new TO mytable原子切换,避免毫秒级不可用 - 保留
mytable_old至少 1 小时,确认无误再DROP - 注意事务隔离级别:
READ COMMITTED下全量导出可能看到不一致快照,必要时用SERIALIZABLE或快照读(如 MySQL 的START TRANSACTION WITH CONSISTENT SNAPSHOT)
Python 里选 psycopg2 还是 sqlalchemy 做同步?
不是语法优雅度问题,是控制粒度和错误恢复能力的问题。同步任务失败后要能精准续跑,而不是整个重来。
psycopg2 直接暴露游标和连接状态,适合做分块拉取 + 手动 commit 控制;sqlalchemy ORM 层会隐藏很多细节,比如自动 flush、隐式事务、对象状态缓存,反而让断点续传变困难。
- 用
psycopg2.extras.execute_batch批量写入,比executemany快 3–5 倍,且支持page_size控制内存 - 避免在同步逻辑里用
session.add_all(...),ORM 对象生命周期和脏检查会拖慢速度、干扰错误定位 - 如果非要用 SQLAlchemy,绕过 ORM,用 Core:直接操作
connection.execute(text("..."))和Result.fetchall() - 所有数据库操作必须显式
commit()或rollback(),别依赖上下文管理器自动收尾——同步中途崩溃时,连接可能卡在未提交事务里
网络中断或目标库拒绝写入时,怎么避免重复写入?
这是增量同步最隐蔽的坑:请求发出去了,但没收到响应,你重试,结果对方其实成功写了两次。解决方案不是靠“运气”,是靠幂等性设计。
性能影响:每条记录加唯一约束(如 (source_id, sync_version))几乎零成本;兼容性上,所有主流数据库都支持 ON CONFLICT DO NOTHING 或 INSERT IGNORE。
- 源端每条记录必须带业务唯一键(如订单号
order_id)+ 同步批次号(sync_batch_id),组合成目标表主键或唯一索引 - 写入语句统一用
INSERT ... ON CONFLICT (order_id) DO UPDATE SET ...,而不是先SELECT再决定是否INSERT - 不要用
REPLACE INTO(MySQL)或MERGE(PostgreSQL),它们在高并发下可能触发锁升级或死锁 - 日志里必须记录每次写入的
affected_rowcount,为后续审计留证据——不是“执行成功”,是“真的插入/更新了几行”
最复杂的地方往往不在逻辑多绕,而在于你默认信任的那个“写入成功”信号,其实根本不可靠。只要没拿到确定的、带行数的响应,就得按失败处理,并准备幂等重试。










