
MySQL 读写分离和分库分表能直接协同吗?
不能。MySQL 本身不提供原生的读写分离 + 分库分表一体化方案。这两个能力分属不同层级:读写分离靠代理或客户端路由(如 ProxySQL、ShardingSphere-JDBC),分库分表靠中间件做 SQL 解析与改写。硬凑在一起,容易路由错乱、事务失效、主从延迟被放大。
为什么 mysqldump 或 SELECT ... INTO OUTFILE 在分库分表后失效?
因为这些命令只作用于单个物理库表,而分库分表后,逻辑表 order 可能散落在 db0.order_00、db1.order_01 等多个实例中。执行 mysqldump order 只会导出当前连接库里的同名表,漏数据是常态。
- 备份必须走中间件提供的全量导出命令(如
shardingsphere-scaling的迁移任务) - 若用
SELECT ... INTO OUTFILE,得先确认当前连接的是哪个分片库,再手动拼路径,且无法跨库聚合 - 主从延迟高时,
INTO OUTFILE可能读到过期快照,尤其在READ COMMITTED隔离级别下更隐蔽
INSERT ... SELECT 跨分片失败的典型表现和绕过方式
错误信息通常是 ERROR 1105 (HY000): Cannot route multi-table statement 或直接提示“表不存在”——因为中间件无法解析含 JOIN 或子查询的跨库语句,或目标表不在当前路由上下文中。
- 禁止在分片键不一致的表之间用
INSERT INTO t1 SELECT * FROM t2 - 如果
t1和t2都按user_id分片,且语句里明确写了WHERE user_id = ?,部分中间件(如 ShardingSphere-Proxy 5.3+)可支持,但需开启sql-show: true并检查日志中的实际路由结果 - 更稳的方式是拆成两步:先
SELECT到应用层,再按分片键组织批量INSERT,虽然慢,但可控
主从延迟如何影响读写分离 + 分库分表的组合使用?
影响被双重放大:写请求打到主库 A,读请求可能路由到从库 B,而 B 的延迟又因跨库同步链路(A→B→C)变得更长;更麻烦的是,分片路由依赖主库最新位点,一旦延迟超阈值,中间件可能误判分片位置。
- 不要依赖
SELECT后立刻SELECT来验证写入——加SLEEP(0.1)不解决问题,得用SELECT MASTER_POS_WAIT()或中间件提供的强一致性读开关(如/*+ FORCE_MASTER */) - 分库分表中间件一般不自动感知主从延迟,
maxReplicaDelay这类配置只在纯读写分离场景生效,合用时得自己在应用层埋点监控Seconds_Behind_Master - 最常被忽略的一点:分片算法如果用了
NOW()或UUID_SHORT(),而主从时钟不同步,会导致同一逻辑 SQL 在主从上计算出不同分片,直接写丢或读错库










