thinkphp多库同步必须采用预定义连接+分片拉取+批量写入+持久化checkpoint方案;需在database.php的connections中完整配置source_db和backup_db,显式声明type、charset等字段,禁用db::connect([])动态传参,分片按主键或时间字段控制单次≤5000行,insertall每批≤2000条,并对日期、布尔等字段做显式类型转换,同步进度写入sync_checkpoint表防中断丢失。

ThinkPHP 多库同步不能靠临时连接或一次性全量 dump,必须走预定义连接 + 分片拉取 + 批量写入 + 持久化断点的组合路径,否则高并发下 MySQL 连接数会爆、内存会 OOM、数据还容易丢。
database.php 里必须预定义两个完整连接,不能用 Db::connect([]) 动态传参
动态传配置每次调用都新建 PDO 实例,不走连接池,Too many connections 错误几乎是必然的。正确做法是给两个库起唯一连接名(比如 source_db 和 backup_db),并在 config/database.php 的 connections 数组里各自配全字段:
-
type必须显式写成'mysql'(不是dbms或空值),否则报Class 'PDO' not found -
charset要分别指定,比如源库是utf8mb4、备份库是gbk,不写就会乱码或截断 - 端口、前缀、时区这些看似可选的字段,只要实际环境用了,就必须写进配置,别依赖默认值
- 改完记得运行
php think clear:config,不然新连接名根本识别不到
同步逻辑必须分片,不能 select * from table 全查再 insertAll
单次拉取超过 5000 行就容易触发 PHP 内存限制或 MySQL max_allowed_packet,更别说事务锁表风险。分片依据优先选自增主键或时间字段:
- 按主键范围:先查
SELECT MIN(id), MAX(id) FROM source_table,再用WHERE id BETWEEN ? AND ?分段拉取 - 按时间字段:比如
created_at > '2026-09-01' AND created_at ,适合日志类表 - 每次
insertAll最多塞 2000 条,再多会触发 MySQL 的Packet too large - 每处理完一批,立刻写 checkpoint 到一张独立的
sync_checkpoint表里,记录已同步的最大id或时间戳
跨库写入前必须做显式类型转换,尤其日期和布尔字段
MySQL 不同版本对 TINYINT(1) 是否当布尔处理、DATETIME 是否自动补零等行为不一致,直接 insertAll($rows) 容易在目标库报错或存错值:
-
created_at字段从源库取出来是字符串,写入前要date('Y-m-d H:i:s', strtotime($row['created_at'])) -
is_active是TINYINT(1),得转成(int)$row['is_active'],不能直接传'1'字符串 - NULL 值要保留,但空字符串
''往INT或DATE字段写会变成0或'0000-00-00',需提前过滤或转为null - 如果目标库有严格模式(
STRICT_TRANS_TABLES),没转类型的字段基本都会被拒绝插入
多应用模式下,每个应用的 database.php 必须独立配置,不能共用
开了 app_multi => true 后,app/admin/config/database.php 和 app/api/config/database.php 是完全隔离的。常见翻车点:
- 只在根目录
config/database.php配了backup_db,结果app/admin里调Db::connect('backup_db')报Connection not found: backup_db - 连接名含大写字母(如
BackupDB)或点号(如db.backup),框架直接忽略,不报错也不连上 - 模型里写
protected $connection = 'backup_db',只对当前应用生效;app/api/model/User.php必须单独写一遍,不会继承 admin 的配置 - 跨应用同步(比如从 admin 同步到 api)只能手动查一次、再连另一个库写一次,框架不做自动路由
最常被跳过的其实是 checkpoint 持久化——没这一步,服务重启或异常中断后,你根本不知道上次同步到哪了,只能全量重跑或者手动修数据。
php免费学习视频:立即使用
踏上前端学习之旅,开启通往精通之路!从前端基础到项目实战,循序渐进,一步一个脚印,迈向巅峰!











