关于我们

质量为本、客户为根、勇于拼搏、务实创新

< 返回新闻公共列表

2026 MySQL 主从复制与读写分离服务器租用配置:主库从库规格、复制延迟与切换避坑

发布时间:2026-09-17

开篇摘要

单库扛不住的那一刻通常很突然:昨天还好好的,今天活动一上,CPU 跑到 90%,慢查询堆成山,业务方在群里问"是不是数据库挂了"。多数人的第一反应是加配置——8 核换 16 核,32G 加到 64G。能顶一阵,但顶不久,因为单机纵向扩容有天花板,而且写压力和读压力混在一台机器上,你没法只给读流量买单

更划算的思路是把读和写拆开:写操作全部打主库,读请求分摊到若干台从库,主库通过 binlog 把变更同步给从库。这就是主从复制加读写分离。这篇文章只解决一个问题——业务量上来之后,主库和从库分别该租什么规格的服务器,以及这套架构里哪些坑会让你半夜被叫起来

  • 读写分离只分摊读压力,不分摊写压力。写 QPS 该优化 SQL 还是得优化,该分库分表还是得分库分表,加十台从库也救不了写入瓶颈。
  • 从库配置不能低于主库,这是实际部署里最常见、也最致命的一个错误。从库同时干三件事:承接读请求、接收 relay log、回放主库所有写操作,压力并不比主库小。
  • 复制延迟是必然存在的,架构要默认"从库数据慢半拍"。写完立刻读的场景必须单独设计兜底,不能指望延迟为零。
  • 生产环境 binlog 格式一般选 row,配合 GTID 做故障切换和从库重建,能省掉大量人工比对文件位点的苦活。
  • 备份和报表放到专用从库上做,主库只管写,职责越单一越稳;恢复演练要定期真跑,别等到真出事才发现备份不可用。

概念解析

读写分离解决什么,解决不了什么

先说能解决的。绝大多数在线业务,读请求量是写请求量的几倍到几十倍——商品详情页、用户信息查询、订单列表、排行榜、搜索联想,全是读。主库把数据变更写进 binlog,从库拉过去重放一遍,就能拿到一份几乎一致的数据副本,然后承担读流量。你有 3 台从库,理论上读容量就接近原来的 3 倍(实际要打折,后面会讲为什么打折)。从库还能各司其职:一台专门跑报表,一台专门做备份,一台承接线上读,互不干扰。

再说解决不了的。这部分比能解决的部分更重要,很多人是栽在这里。

第一,写压力一点都没减少。所有写操作仍然全部落到主库,主从架构下主库的写 QPS 上限,就是整个系统的写 QPS 上限。如果瓶颈是每秒上万次 UPDATE 打爆了主库 CPU 和 redo 刷盘,加十台从库也没用。写入瓶颈要靠 SQL 优化、批量合并、异步化削峰,或者真正的分库分表来解决,读写分离在这件事上帮不上忙。

第二,主从延迟会让"刚写完立刻读"读到旧数据。用户提交订单后马上跳转订单详情页,如果这次读被路由到从库,而 binlog 还没回放完,用户就会看到"订单不存在"。这是读写分离最典型的线上事故,没有之一。处理办法后面会详细讲,但你得先在心理上接受这件事:从库的数据天然比主库慢半拍,架构必须围绕这个事实去设计,而不是假装它不存在

第三,从库挂了不等于业务无损。从库掉线,读流量要能自动摘掉这台实例,否则连接池会一直往死掉的实例上发请求,拖垮整个线程池。而如果主库挂了,从库上的数据可能并不完整——到底有没有丢数据、能不能切、该切哪一台,取决于你用的是 GTID 还是传统文件位点,以及切换时有没有做一致性校验。

复制原理的人话版:binlog、relay log 和两个线程

MySQL 主从复制的流程其实就三步,用人话说一遍,理解了这三步,后面所有故障现象都能对号入座。

第一步,主库记账。主库上任何会改数据的操作(INSERT、UPDATE、DELETE、DDL),在事务提交时都会被写进一个叫 binlog(二进制日志)的文件里。binlog 可以粗略理解成主库的"流水账",记的是"哪张表哪一行被改成什么样",或者"执行了哪条 SQL",取决于你选的格式。binlog 是在事务提交阶段写的,所以它同时也是 MySQL 做崩溃恢复与时点恢复(PITR)的基础。

第二步,从库取账本。从库上有一个 IO 线程,主动连到主库说"把我还没拿到的那段 binlog 给我"。主库端有个 dump 线程把 binlog 事件推过去,从库收到后原样写到本地磁盘上一个叫 relay log(中继日志)的文件里。这一步是纯粹的网络传输加顺序写盘,通常不是瓶颈,但跨地域、跨运营商复制时网络往返延迟会叠加进来。

第三步,从库重放。从库上的 SQL 线程读 relay log,把里面的事件一条条执行一遍,让自己的数据和主库保持一致。这一步才是真正的瓶颈——重放本质上是在从库上把主库做过的写操作再做一遍,从库要付出和主库几乎一样的写入代价,而且在早期版本里默认是单线程干的。

顺着这个模型,很多现象就解释得通了:为什么从库 CPU 会先于主库打满(单线程重放跟不上主库多线程并发写);为什么从库磁盘 IO 会爆(重放写数据、写 relay log、承接业务读查询三份压力叠加);为什么大事务会导致延迟飙升(主库上一个事务删 500 万行,从库上也得一个事务完整跑完,中间不能插队);为什么主库 CPU 明明还有余量,业务却因为从库延迟被拖慢。

binlog 的三种格式:statement、row、mixed 到底差在哪

binlog 记什么内容,由 binlog_format 这个参数决定,三种取值直接影响数据一致性、日志体积和从库回放性能。

statement(SBR)记的是 SQL 语句原文,比如"UPDATE orders SET status=1 WHERE create_time < '2026-01-01'"。最大的好处是体积小——一条 SQL 改十万行也只占几十字节,主库磁盘、网络传输、从库回放全都轻松。坏处是致命的:某些语句在从库上重放的结果和主库并不一致。用到 UUID()、NOW()、RAND()、自增主键高并发插入,或者带 LIMIT 但没有 ORDER BY 的 UPDATE/DELETE,主从执行顺序、执行时刻不同,就可能产生不同的结果集。在订单、账务、库存这类业务里,这是不可接受的风险。

row(RBR)记的是行的前后镜像,比如"表 orders 主键 12345 这一行,status 从 0 改成 1"。好处是绝对一致:从库不需要重新执行 SQL,直接按行应用变更,不存在"重放结果不一样"的问题,排查问题时也能直接看到改了哪行。坏处是体积大——一条 UPDATE 改十万行,就会记十万条行变更记录,binlog 可能瞬间涨几个 GB,主库磁盘、网络传输、从库回放压力全部跟着涨。

mixed是折中方案:MySQL 自己判断,认为安全的语句记 statement,不安全的记 row。听起来很美,实际生产用得不多,原因在于判断逻辑复杂、行为不够可预测。排查问题时你还得先搞清楚这条语句最终按哪种格式记的,反而增加心智负担。

所以生产环境的主流选择是 row:牺牲一点磁盘和带宽,换来确定的一致性和便利的排查体验。如果确实遇到批量更新导致 binlog 暴涨,正确的做法是把大事务拆成小批次(比如按主键范围每次更新 1000 行,循环执行,批次之间留一点间隔),而不是退回到 statement 格式。具体的参数行为、默认值与版本差异,请以 MySQL 官方文档对应版本为准。

GTID 是什么,为什么切换时更省事

传统复制位点长这样:主库的 binlog 文件名加位置偏移,比如 mysql-bin.000047 的 position 8934210。从库说"我同步到了这个文件这个位置"。问题在于这个坐标是"主库本地"的——一旦主库挂掉,你要把从库 A 提升为新主,其它从库 B、C 要改成指向 A,就得先搞清楚"B 已经同步的内容对应到 A 的哪个文件哪个位置"。跨机器的位点换算非常痛苦,容易算错,算错的后果就是数据不一致或者事务重复执行。

GTID(Global Transaction Identifier,全局事务标识)换了个思路:每个事务在提交时被分配一个全局唯一 ID,格式大致是 server_uuid 加事务序号,比如 3e11fa47-71ca-11e1-9e33-c80aa9429562:1-5。从库记录的是"我已经执行了哪些 GTID 集合"。切换时,新主库自己知道手上有哪些 GTID,从库也知道自己缺哪些,MySQL 能自动算出该从哪儿继续,不需要人工去比对文件和偏移量

这就是为什么现在新搭主从基本都开 GTID(gtid_mode=ON、enforce_gtid_consistency=ON)。它带来的好处不只是切换省事:从库重建、主从互换、判断某台从库是否落后(对比 GTID 集合的差集,比盯着 Seconds_Behind_Master 那个数字靠谱得多),全都更直观。代价是对 SQL 写法有约束,比如不允许 CREATE TABLE ... SELECT 这类一条语句产生两类行为的写法,部分老业务迁移时需要改造。具体限制清单以官方文档为准,别凭印象配置。

复制延迟的真实成因,以及那个最常见的致命错误

先讲最常见的那个错误:主库买高配,从库买低配。这个决策的心理逻辑很通顺——"从库只是读嘛,压力小,省点钱"。实际结果完全相反。

从库要干三件事:承接业务读查询、接收并落盘 relay log、回放主库的所有写操作。第三件意味着主库上产生的写压力,从库一份不落要重做一遍。更要命的是,主库是多连接并发写的,从库在早期版本里是单线程回放的——你用 32 核的机器并发写,用 8 核的机器单线程重放,延迟不飙升才怪。再叠加从库还要同时处理读请求,实际压力经常超过主库。省下来的那点机器钱,最后会以延迟告警、切换失败、业务投诉的形式加倍还回来。

所以一条硬性原则:从库规格应当不低于主库,尤其是内存和磁盘 IOPS。内存最好与主库持平或更高(Buffer Pool 要能装下同样规模的热数据,否则读查询会大量打磁盘),磁盘写能力不能弱于主库。这一点在租用服务器时特别容易被忽略,因为按"从库 = 低配"的思路下单,报价单看起来能省不少。

然后是几个具体成因,排查延迟时可以逐一对照。

大事务。一次 DELETE 掉几百万行,或者一条 UPDATE 扫了半张表,主库上几秒完成,从库单线程回放可能要几分钟甚至更久。这期间延迟直线上升,从库上的读查询还会被阻塞。对策是拆分批量操作,按主键范围分批,每批控制在几千行以内,批次之间留出让复制追上的时间。

无主键表。这是 row 格式下的经典陷阱。binlog 记的是行变更前后的镜像,从库回放时要靠索引定位到对应的行。如果表没有主键、也没有合适的唯一索引,从库每应用一行都要全表扫描一次。一张 500 万行的无主键表更新 1 万行,从库可能要跑几个小时,而主库只要几秒。所以建表规范里强制要求主键,这不是形式主义,是在给未来的自己省事。已经存在的无主键表,应当评估后补建,补建过程本身也要控制对复制的影响。

单线程回放瓶颈。MySQL 5.6 与 5.7 引入了基于库、基于组提交的并行复制(涉及 slave_parallel_workers 等参数),8.0 引入了基于 write set 的并行回放,能够把主库上并行提交、互不冲突的事务在从库上并行重放,吞吐提升相当明显。具体参数名、默认值、生效条件与版本强相关,请以 MySQL 官方文档对应版本为准,不要照抄别人的配置文件。另外要清楚,并行复制解决的是"并发事务组"的回放效率问题,一个巨大的单事务本身仍然是单点,拆不散。

磁盘 IO 跟不上。从库的写放大很严重:relay log 要写、数据文件要改、undo 与 redo 要写,还要处理读查询的随机 IO,几份压力叠加在同一块盘上。机械盘在从库上基本不可行,SATA SSD 在高写压下也容易成为瓶颈,NVMe SSD 应当作为从库的基本配置。租服务器时别只看容量,要问清是 NVMe 还是 SATA、有没有掉电保护、随机写 IOPS 大概什么水平。

网络与跨地域。跨机房、跨地域复制会引入网络往返延迟,主库写入密集时 binlog 传输本身可能成为瓶颈。反过来,把从库和主库放在同一台宿主机或者同一个机柜,看起来省了网络,实际上共享了 IO 和故障域——主库所在物理机出问题,从库大概率一起受影响,灾备意义归零,得不偿失。

对比表格

下面这张表按部署角色给出主库与从库的选型对照。价格全部取自一万网络官网公示的裸金属与地区起步价(A 类官网明示价),实际租用请以官网实时价与签约报价为准。

部署角色 建议规格(CPU/内存/磁盘) 主要压力 官网价格参考 价格性质 来源/时间
主库(写 + 少量强一致读) 双路多核,如 E5-2698v4×2;内存按热数据规模往上加;系统盘与数据盘分离,数据盘 NVMe 写 QPS、事务提交 fsync、binlog 落盘、锁竞争 裸金属 E5-2698v4×2 32G/1T ¥3999 起/月 A 类·官网明示价 一万网络官网裸金属页,2026-09-17
从库(线上读副本) 规格不低于主库,内存建议与主库持平或更高;数据盘 NVMe,写 IOPS 不弱于主库 读 QPS 分摊 + relay log 落盘 + 写操作回放 与主库同档,裸金属 E5-2698v4×2 32G/1T ¥3999 起/月 A 类·官网明示价 一万网络官网裸金属页,2026-09-17
从库(备份 / 报表 / 慢查询专用) 中等 CPU,大内存优先;独立数据盘,避免与线上读副本共享 IO 全表扫描、大聚合查询、备份期间 IO 抖动 裸金属 E5-2620 32G/1T ¥999 起/月 A 类·官网明示价 一万网络官网裸金属页,2026-09-17
测试 / 预发环境主库 入门机型即可,重点是与生产同版本同参数,用于验证复制与切换流程 低写 QPS、功能与切换演练 华西 ¥599 / 华东 ¥699 / 华南 ¥799 / 华北 ¥899 起 A 类·官网明示起步价 一万网络官网首页,2026-09-17
跨境 / 免备案场景的读副本 入门至中档机型,放在访客侧就近节点,承接海外读请求 海外读延迟、跨区复制网络往返 香港 ¥1500 起 A 类·官网明示起步价 一万网络官网香港服务器页,2026-09-17

推荐配置详解

主库怎么选:CPU、内存、磁盘与 binlog 空间

CPU 核数与写 QPS:给的是经验口径,不是公式

写入型负载吃 CPU 的地方主要在几处:事务提交时的 redo 刷盘与组提交协调、二级索引维护、行锁与间隙锁的竞争、以及 binlog 事件的生成与落盘。核数不够的典型表现不是"CPU 100% 然后优雅地变慢",而是CPU 打满的同时锁等待暴增、响应时间呈指数级恶化

给一个经验口径供参考(这是经验区间,不是精确公式,务必用自己的业务做压测校准):日活十万量级、写 QPS 在几百到一两千之间的电商或订单类业务,8 到 16 核通常够用;写 QPS 到几千,建议 16 到 32 核起步;再往上,就该认真考虑拆分而不是继续堆核了。另外,主库的 CPU 还要留出余量给 binlog dump 线程——每个从库都会占一个连接和一个 dump 线程,从库数量多时这部分开销不能被忽略。

内存与 InnoDB Buffer Pool:按热数据规模估

InnoDB 的 Buffer Pool 缓存数据页和索引页,命中率高就意味着绝大多数读根本不碰磁盘。怎么估大小?一个常用的经验口径是:让 Buffer Pool 能装下核心业务表的全量索引加高频访问的数据页。如果整个库不大(几十 GB),直接让 Buffer Pool 覆盖全量数据最省事;如果库已经几百 GB 甚至 TB 级,就按访问频次估算热数据占比,比如活跃用户最近三个月的数据、近期订单、商品主表,这部分通常能占到总访问量的绝大部分。

参数上,innodb_buffer_pool_size 一般设为物理内存的 50% 到 70%(经验口径),剩下的留给连接缓冲、临时表、排序缓冲、操作系统 page cache 和 binlog 相关内存。别把内存全部分给 Buffer Pool,连接数一上来就容易 OOM。判断够不够,看监控里的 Buffer Pool 命中率:命中率长期低于 99%,读查询就在频繁打磁盘,这时候加内存比加 CPU 有效得多。

系统盘与数据盘分离,以及 NVMe 的 IOPS 与 fsync

系统盘装操作系统、MySQL 程序、错误日志和慢日志;数据盘放 datadir、binlog、redo 日志。分开的好处有两个:一是 IO 隔离,慢日志、错误日志的突发写入不会和 redo 的 fsync 抢带宽;二是安全边界,binlog 或临时文件暴涨时撑爆的是数据盘,系统盘还能正常登录排查,不至于连 SSH 都进不去。

磁盘类型上,事务提交要刷 redo(innodb_flush_log_at_trx_commit=1 时每次提交都要 fsync),这是写延迟的主要来源之一。NVMe SSD 的随机写 IOPS 和 fsync 延迟表现,明显优于 SATA SSD 和机械盘,在写密集场景下差距会被放大得非常明显。租服务器时除了问盘型,还应关注是否配置了带掉电保护的 SSD 或 RAID 卡缓存——因为 fsync 的持久化语义依赖硬件层面的落盘保证,这部分能力直接决定了崩溃后数据是否完整。具体参数行为请以 MySQL 官方文档为准。

binlog 保留周期与空间占用:一个能把主库写挂的细节

binlog 保留多久,取决于两件事:一是从库重建需要多长的历史(从库挂了要重新拉全量加增量,太短的保留期会让你只能重做全量),二是时点恢复(PITR)需要回溯多久。常见的保留期是 3 到 7 天,合规要求严格的业务会更长。相关参数在不同版本里叫法不同(如 expire_logs_days 与 binlog_expire_logs_seconds),具体参数名与行为请以官方文档对应版本为准

空间估算的思路是:写峰值 QPS × 每条变更的平均 binlog 体积 × 保留时长。row 格式下每条变更的体积远大于 statement 格式,宽表更新、大字段更新尤其夸张。实操建议是给 binlog 单独挂一个分区或一块盘,容量按估算值的 2 到 3 倍预留,并且必须配磁盘使用率告警。因为 binlog 所在磁盘写满的后果非常严重:主库无法写 binlog,事务就无法提交,整个库的写入会直接挂掉,而不只是变慢。这类事故在运维圈子里反复出现,原因几乎都是"没监控那块盘"。

从库怎么选:数量、内存、写放大与专用从库

读副本数量与读 QPS 分摊:别一次上五台

单机能承接多少读 QPS,取决于查询复杂度、索引质量、Buffer Pool 命中率,只能靠压测得到,不能靠猜。比较稳妥的节奏是先上 1 到 2 台从库,跑一段时间收集监控数据,再决定是否扩容。

为什么不建议一次上很多台?因为从库不是免费的:每台从库都要主库单独推一份 binlog,主库的网络出口和 dump 线程开销随从库数量线性增长;从库越多,运维成本、监控成本、切换时的决策复杂度都上去了。而且从库数量多了之后,各从库延迟不一致,读写分离中间件还要处理"哪些从库延迟超阈值要摘掉"的逻辑,规则越复杂越容易出问题。

内存最好不低于主库,磁盘要扛住写放大

这一点前面强调过,这里给出具体理由。从库的内存同样要装 Buffer Pool,如果从库内存比主库小,热数据装不下,读查询就会大量落到磁盘上,响应时间恶化,进而拖慢整个回放与查询的循环。从库内存应与主库持平,条件允许时更大——因为从库还要额外承担报表类大查询所需的临时内存。

磁盘方面,从库的写放大比主库更严重:relay log 顺序写、数据文件随机改、undo 与 redo 持续写,再叠加读查询的随机读。从库的数据盘必须是 NVMe SSD,写 IOPS 不能低于主库。容量上,从库的数据文件体积和主库基本一致,但还要额外预留 relay log 的空间(大事务回放期间 relay log 会瞬间膨胀),预留比例建议比主库更宽松一些。

专用从库:让脏活累活别碰线上

把不同用途的从库分开,是花小钱买大安稳的做法。

备份专用从库:备份动作(无论是逻辑备份还是文件系统快照)都会带来 IO 抖动和额外的锁,放在承接线上读的从库上会直接影响业务响应时间。单独一台从库做备份,抖动影响范围就限制在这一台上。

报表与慢查询分析专用从库:报表查询通常是全表扫描加大量聚合,吃 CPU、吃内存、吃临时表空间,放在线上读副本上很容易把正常查询拖死。给报表单独一台,参数上还可以针对性地调大排序缓冲、临时表上限,互不干扰。

延迟容忍度分级:不同用途的从库可以设不同的延迟告警阈值。线上读副本要求延迟秒级,超过阈值立刻摘流量;报表从库允许延迟几分钟;备份从库只要在备份窗口前追上即可。统一用一个阈值告警,结果是告警泛滥,最后没人看。

读写分离怎么落地:中间件还是应用层路由

两条路各自的取舍

中间件方案(如 ProxySQL、ShardingSphere-Proxy、MySQL Router 等):应用只连中间件,由中间件决定这条 SQL 走主库还是从库。优点是对应用透明,规则集中管理,支持连接池复用、查询重写、从库健康检查与自动摘除,多语言栈的公司尤其受益。缺点也很实在:多一跳网络、多一个必须自身高可用的组件、还有 SQL 兼容性问题——临时表、会话变量、预处理语句、某些函数在代理层的行为可能与直连不同。具体能力与限制,请以各项目官方开源文档为准,不要凭博客文章下结论。

应用层数据源路由:在代码或 ORM 框架里配置主从两个数据源,通过注解、方法命名约定或自定义规则决定路由。优点是没有额外组件,可控性最好,出问题直接看代码。缺点是改造成本随服务数量增长,多语言多框架要各自实现一遍,规则散落在各处难以统一治理。

怎么选?中小团队、技术栈单一,用应用层路由起步最划算,少一个中间件就少一个要半夜维护的东西;服务多、语言杂、需要统一治理,再上中间件。无论走哪条路,下面几个能力都必须有:事务内的读强制走主库、支持 Hint 强制走主库、从库故障自动摘除、延迟超阈值自动摘除。

连接池、事务内强制主库,以及"写完立刻读"

连接池要按实例分别配置,主库和每台从库各自一个池,别把所有从库塞进同一个池——那样你就没法单独摘掉某台延迟高的从库了。连接数上限也要分别评估:主库连接数通常远小于从库总和。

事务内的读必须走主库,原因有两条:一是事务里的读必须能看到自己尚未提交的修改,从库根本看不到;二是事务提交之前,变更还没写进 binlog,从库无论如何都不可能有这份数据。很多读写分离中间件默认就是"开启事务后所有语句走主库",如果自己实现路由,这条规则要写死。

写完立刻读是读写分离最容易踩的坑,三种常见处理办法:

  • 读主库:最简单也最常用。对一致性要求高的那几个接口(提交订单后查详情、修改资料后刷新、支付结果查询),直接在代码里指定走主库。缺点是主库多承担一点读压力,但通常这部分接口占比很小。
  • 等待 GTID 追上:写操作返回主库当前 GTID,读之前在从库上等待该 GTID 执行完成(相关函数如 WAIT_FOR_EXECUTED_GTID_SET,具体语法与版本支持情况以官方文档为准)。好处是仍然能利用从库容量,代价是这次读要等待复制延迟的时间,需要设超时,超时后降级走主库。
  • 缓存兜底:写入成功后同时写一份缓存,读的时候先读缓存,缓存没有再回源。这本质上是把一致性问题交给缓存层处理,适合读多写少、对短暂不一致不敏感的内容。

一万网络机型怎么比选:大内存加 NVMe 的组合

落到实际租用上,数据库服务器选型的关键词只有两个:内存够大、磁盘够快。CPU 反而是最容易补的短板,内存和 IO 一旦不够,加 CPU 也救不回来。

主库优先挑双路多核、内存可扩展的裸金属机型。一万网络裸金属标准档从 E5-2620 32G/1T ¥999 起,一直到 E5-2698v4×2 32G/1T ¥3999 起(A 类官网明示价,以官网实时价为准),中间跨度足够覆盖从测试环境到中型生产主库的需求。订单、账务这类写密集业务,我一般直接建议上到双路档,因为主库的 CPU 余量还要分给 binlog dump 线程。一万网络深耕 IDC 19 年(成立于 2007 年),7×24 中文工单平均 5 分钟响应、硬件故障 10 分钟内自动迁移,对数据库这种不能随便重启的服务来说,故障时的响应速度本身就是可用性的一部分。

从库按前面的原则,规格不低于主库,所以报价上通常就是主库同档再来一份或两份。如果预算确实紧张,至少保证内存和磁盘不缩水,CPU 可以略低——因为回放瓶颈在多数场景下先出现在 IO 和单线程回放上,而不是纯粹的 CPU 算力。一万网络官网明示其存储为纯 SSD 架构(Sas3 SSD,随机读写 50000 IOPS、吞吐 800Mb/s),具体机型可选哪些 NVMe 盘型、能否定制大内存配置,需以实时咨询为准,下单前把"盘型是 NVMe 还是 SATA""能不能带掉电保护"这两个问题问清楚,比纠结 CPU 主频有意义得多。

还有一点值得单独说:一万网络的免费系统盘每日 3 份快照、30 秒回滚,对数据库从库非常好用。你可以在报表从库或备份从库上,借系统盘快照快速拉起一个"克隆实例"来做恢复演练、慢查询复现、大表 DDL 预演,出问题 30 秒就能回滚到快照点,不用占用额外的备份存储空间,也不用担心把线上从库搞脏。恢复演练这件事,有没有现成的快照能力,直接决定了团队愿不愿意真的定期去跑——毕竟演练成本高了,大家就会一直拖着。

地区上,如果业务主要在国内,主库和线上读副本建议放在同一区域,一万网络大陆节点起步价为华西 ¥599、华东 ¥699、华南 ¥799、华北 ¥899 起(A 类官网明示起步价,以官网实时价为准)。华东、华南节点对国内大部分访客的网络条件更友好,主库与从库同区可以把复制延迟压到最低。如果业务涉及海外访客或者需要免备案的读副本,香港节点 ¥1500 起,可作为就近读的补充节点,但要注意跨区复制会引入额外的网络往返延迟,不适合对延迟极敏感的强一致读场景。

避坑指南

坑一:从库配置比主库低,省小钱赔大钱

问题表现:主库监控一切正常,但从库延迟从几十秒一路涨到几分钟甚至几小时,业务侧反馈"刚改的资料刷新不出来",告警响个不停。

为什么会这样:从库要把主库的所有写操作重放一遍,而且回放线程数远少于主库的并发写入连接数。主库 32 核并发写,从库 8 核单线程追,物理上就追不上。再叠加从库自己的读查询,压力只会更大。

怎么判断:对比主库和从库的 CPU 使用率、磁盘 IO 利用率、Buffer Pool 命中率。如果从库这几项长期接近饱和而主库还有余量,基本就是规格问题,不是参数问题。

怎么规避下单时就把从库按主库同规格配置,内存和磁盘至少持平。如果已经踩坑,扩容从库内存和换 NVMe 盘通常比调参数见效更快。同时确认并行复制相关参数是否已按当前版本启用并合理配置。

坑二:无主键表加 row 格式,从库回放慢到怀疑人生

问题表现:主库上一个几秒完成的批量更新,从库跑了几十分钟还没完,延迟曲线是一条陡峭上升的斜线,而且迟迟不回落。

为什么会这样:row 格式下从库回放要按行定位,没有主键也没有合适唯一索引时,每应用一行都要全表扫描一次。数据量越大,差距越夸张。

怎么判断:在从库上看正在执行的回放语句、观察 handler_read_rnd_next 之类的读行数指标是否异常飙升;或者直接盘点业务库里哪些表没有主键。

怎么规避建表规范强制主键,代码评审时卡住。存量无主键表评估后补建,补建过程选择业务低峰,并提前确认对复制延迟和磁盘空间的影响。别指望靠加从库配置来掩盖这个问题,数据量再翻一倍,配置也救不了。

坑三:binlog 所在磁盘写满,整个库写不进去

问题表现:主库突然无法提交任何事务,应用侧报大量写入超时,但 CPU、连接数看起来都不算特别高。

为什么会这样:binlog 落不下去,事务就无法提交。这是硬阻塞,不是性能下降。常见诱因是保留期设置过长、批量操作产生超大 binlog、或者 binlog 和数据文件共用一块盘被数据文件挤爆。

怎么判断:直接看 binlog 目录所在分区的使用率,以及错误日志里与 binlog 写入相关的报错。

怎么规避binlog 单独分区或单独盘,配磁盘使用率告警(建议 70% 就开始报警);保留期按实际需要设置,不要无脑设 30 天;大批量操作拆小批次执行。清理过期 binlog 请使用数据库自身提供的机制,不要手工到文件系统里删文件,那样会让复制位点和实际文件状态不一致。

坑四:只盯 Seconds_Behind_Master,被 0 骗了

问题表现:监控面板上延迟是 0,但业务侧明显读到了旧数据;或者反过来,延迟显示几百秒,实际复制早就断了。

为什么会这样:Seconds_Behind_Master 的含义是从库当前时间与正在回放的事件时间戳之差。它有几个著名缺陷:复制线程断掉时它可能显示 NULL 而不是变大;主库空闲时没有新事件产生,这个值会归零,但不代表之前的积压已经消化完;大事务回放期间这个值会突然跳高;级联复制场景下它也不能反映与最顶层主库的真实差距。

怎么判断:不要只看这一个指标。同时看 IO 线程与 SQL 线程是否都在运行、看 relay log 是否有积压、看主库 binlog 位置与从库已执行位点的差值。

怎么规避用 GTID 集合差来衡量真实滞后量(对比主库已产生的 GTID 集合与从库已执行的 GTID 集合,差集大小就是落后的事务数);再加一张心跳表——主库定时往一张小表里写当前时间戳,从库上读这张表的时间戳与主库当前时间做差,得到端到端的真实延迟。两个手段配合,比单看 Seconds_Behind_Master 可靠得多。另外,延迟告警必须联动读写分离策略:延迟超阈值自动把该从库摘出读流量池。

坑五:切换时的双写、脑裂与数据不一致

问题表现:主库故障后切了新主,但老主恢复后仍然有应用连着它写数据,两边都接受了写入,数据冲突,最后只能人工对账。

为什么会这样:这就是典型的脑裂。老主可能只是网络分区被误判为宕机,它自己仍然认为自己是主库并接受写入。如果没有任何机制阻止它继续提供写服务,就会出现两个"主库"同时写入。此外,如果切换时选择的从库并不是数据最完整的那台,一旦老主无法恢复,未同步的事务就永久丢失了。

怎么判断:切换后立刻核对老主与新主的 GTID 集合,看老主是否有新主没有的事务;同时检查是否仍有应用连接指向老主。

怎么规避:从架构层面想办法,而不是靠人肉操作——选新主时对比各从库的 GTID 集合,选已执行事务最完整的那台(这正是不开 GTID 时最容易出错的一步);切换入口要收敛,应用通过统一的数据源配置或中间件访问数据库,切换时改一处配置或由中间件自动切换,避免各服务各自为政;对老主做写隔离,在确认其状态之前,通过网络层面或只读设置阻止它继续接受写入(具体做法依实际环境与厂商能力而定,本文不提供破坏性操作步骤);切换前把复制拓扑、GTID 状态、各从库延迟情况完整记录一遍,切换后逐项核对。DNS 切换与 VIP 切换的区别也要提前想清楚:DNS 切换实现简单、跨机房方便,但受 TTL 影响,客户端可能长时间缓存旧地址,收敛慢;VIP 或代理层切换收敛快,但通常要求主备在同二层网络内,跨机房场景受限。选哪种,取决于你的切换收敛时间要求有多大。

坑六:备份做了,但从没恢复过

问题表现:真的需要恢复时才发现,备份文件损坏、备份脚本早就悄悄失败了几个月、或者恢复出来的数据缺了最近几小时的 binlog。

为什么会这样:备份是一套流程,不是一个命令。备份任务失败没有告警、备份文件没有校验、binlog 保留期和全量备份周期对不上,任何一个环节断了,恢复时才会暴露。

怎么判断:问自己三个问题——上一次完整恢复演练是什么时候?从备份恢复到可用状态需要多长时间,有没有被量化过?备份文件有没有做过恢复校验,而不只是检查文件存在?

怎么规避把备份放在从库上做,避免备份动作影响主库写入;用快照加 binlog 做时点恢复(PITR)——先恢复一份快照作为基线,再回放快照之后的 binlog 到指定时间点,这样能精确到秒级恢复,也就能应对"误删了一张表"这类逻辑错误;定期做真实恢复演练,把恢复流程写成可执行的步骤文档,演练结果记录恢复耗时。前面提到的一万网络免费系统盘每日 3 份快照、30 秒回滚,用来做演练环境的快速拉起和回滚非常顺手——演练成本降下来,团队才愿意真的定期跑。

常见问题 / FAQ

Q1:从库能不能比主库配置低一点,省点预算?

A1:不建议,这是我见过最普遍的省钱误区。从库要同时承接读请求、接收 relay log、还要把主库的所有写操作重放一遍,实际压力经常不低于主库。主库是多线程并发写,从库回放线程数少得多,你用低配机器去追高配机器的写入量,延迟必然累积。真要省,也只能在 CPU 上稍微让步,内存和磁盘 IOPS 必须与主库持平:内存小了热数据装不进 Buffer Pool,读查询就会大量打磁盘;磁盘慢了写放大扛不住,回放直接成为瓶颈。省下来的机器钱,最后会以延迟告警、切换失败和业务投诉的形式还回来。

Q2:上了读写分离,写压力还是很大怎么办?

A2:这是正常的,因为读写分离从头到尾就没打算解决写压力。所有写仍然只落到主库,主库的写上限就是系统上限。真正的出路有四条:一是优化 SQL 和索引,把慢写变成快写,很多场景下光是补对索引就能砍掉一半写耗时;二是合并写入,把高频的单条 UPDATE 攒成批量提交,减少事务提交次数和 fsync 次数;三是异步化,把非核心的写操作放进消息队列削峰填谷;四是分库分表,把数据真正拆到多个主库上,这才是对写压力的横向扩展。做之前先用慢查询日志和性能视图定位到底是哪类写在吃资源,别凭感觉下手。

Q3:复制延迟多少算正常,告警阈值怎么设?

A3:没有一个通用数值,取决于业务对一致性的容忍度。经验上,同机房、规格对等的实例,稳态延迟在 1 秒以内算健康;超过 5 秒要开始关注;持续超过 30 秒基本说明存在结构性问题(大事务、无主键表、从库规格不足、磁盘 IO 瓶颈)。告警建议分级:线上读副本 10 秒预警、30 秒严重告警并联动从读流量池摘除;报表和备份从库可以放宽到几分钟。更关键的是不要只看 Seconds_Behind_Master,配合 GTID 集合差和心跳表时间戳一起判断,前者反映落后多少事务,后者反映端到端的真实延迟。

Q4:binlog 该选 row 还是 statement?

A4:生产环境一般选 row。statement 记 SQL 原文,体积小是唯一明显优势,但遇到 UUID、NOW、RAND,或者带 LIMIT 却没有 ORDER BY 的更新删除,主从重放结果可能不一致,在订单、账务、库存这类业务里这个风险无法接受。row 记行前后镜像,重放不依赖 SQL 语义,一致性有保障,问题排查时也直观。代价是体积大,批量更新会让 binlog 暴涨,应对办法是把大事务按主键范围拆成小批次,而不是退回到 statement。mixed 理论上折中,实际行为不够可预测,生产用得不多。参数行为与默认值请以官方文档对应版本为准。

Q5:读写分离用中间件还是应用层自己做?

A5:看团队规模和语言栈。技术栈单一、服务数量不多的中小团队,应用层数据源路由起步最划算,少一个中间件就少一个要高可用、要半夜维护的组件,出问题直接看代码。服务多、语言杂、需要统一治理和集中规则管理的,再上中间件(如 ProxySQL、ShardingSphere-Proxy、MySQL Router 等,具体能力与限制以各项目官方开源文档为准)。但要注意中间件不是银弹:多一跳网络、SQL 兼容性有差异(临时表、会话变量、预处理语句在代理层的行为可能不同)、自身还要做高可用。无论选哪种,事务内强制走主库、Hint 强制主库、从库故障与延迟超阈值自动摘除,这四个能力必须有。

Q6:主库宕机怎么选新主,会不会丢数据?

A6:可能丢,取决于复制是异步还是半同步,以及切换时的处理。异步复制下,主库已提交但从库还没拉到的 binlog 会丢失,这是架构层面的固有取舍。选新主时,正确做法是对比各从库已执行的 GTID 集合,选择包含事务最完整的那台;用传统文件位点切换时,跨机器换算位点容易出错,这正是强烈建议开启 GTID 的原因。切换入口要收敛,让应用通过统一配置或代理访问数据库,改一处即可生效。切换后务必做两件事:核对老主是否有新主缺失的事务,以及确认老主已被写隔离,避免两边同时接受写入造成脑裂。具体操作步骤因环境而异,建议先在测试环境完整演练。

Q7:备份能不能只在主库做?放从库做稳吗?

A7:放从库做更稳,这是主流做法。原因是主库只管写,职责单一最不容易出问题;备份动作会带来 IO 抖动和额外的锁,放在线上读副本上会直接影响业务响应时间,放在主库上影响更大。做法上,单独准备一台备份专用从库,自动化备份脚本跑在这台上,抖动影响范围被限制在一台机器上。恢复思路用快照加 binlog 做时点恢复:先恢复一份快照作为基线,再回放快照之后的 binlog 到目标时间点,可以精确到秒,也能应对误删表这类逻辑错误。重点提醒:备份不等于能恢复,必须定期做真实恢复演练,并记录实际耗时,否则备份只是心理安慰。

Q8:到底要租几台服务器,预算怎么估?

A8:最小可用形态是两台:一台主库、一台从库。从库既承担读分流,又承担高可用备机和备份职责,适合业务量中等、预算有限的团队。业务再往上,建议三到四台:一台主库、两台线上读副本、一台备份或报表专用机,这样任意一台从库故障时读流量还有承接能力,备份也不污染线上。预算上,按"主库一台加 N 台同规格从库"的思路估最稳妥,因为从库规格不应低于主库。以一万网络官网明示价为例,裸金属 E5-2698v4×2 32G/1T ¥3999 起/月(A 类官网价,以官网实时价为准),两台对等配置就是这个数目的两倍;测试或预发环境可以用大陆节点起步机型,华西 ¥599、华东 ¥699、华南 ¥799、华北 ¥899 起。磁盘是否可选 NVMe、内存能扩到多少,需以实时咨询为准。

总结

回到最开始的问题:主库和从库分别该租什么规格。我的结论很明确——按同一档规格租,内存和磁盘不许缩水,CPU 可以从库略低一点作为让步。主库看写 QPS 定核数、按热数据规模定内存、数据盘必须 NVMe 且 binlog 单独留空间并配告警;从库数量按读 QPS 压测结果逐步加,别一次上五台,同时按用途拆出备份专用和报表专用的机器。这两条做到了,读写分离的绝大多数延迟问题就不会发生。

还有两件事必须提前做,而不是等出事再补:一是开启 GTID,把切换和从库重建从"人工比对位点"变成"自动计算差集";二是延迟监控别只看 Seconds_Behind_Master,用 GTID 集合差加心跳表时间戳,并把延迟超阈值与读流量摘除联动起来。写完立刻读的场景,直接强制走主库,简单粗暴但有效,别为了多用一点从库容量去赌复制延迟。

最后说服务商。数据库服务器不是租完就不管的东西,硬件故障时能不能快速迁移、磁盘是什么盘型、内存能不能扩、有没有现成的快照能力做恢复演练,这些都直接影响这套架构的实际可用性。一万网络深耕 IDC 19 年(成立于 2007 年),裸金属从 E5-2620 32G/1T ¥999 起到 E5-2698v4×2 32G/1T ¥3999 起(A 类官网明示价,以官网实时价为准),大陆节点华西 ¥599、华东 ¥699、华南 ¥799、华北 ¥899 起,香港 ¥1500 起;7×24 中文工单平均 5 分钟响应、硬件故障 10 分钟自动迁移、免费系统盘每日 3 份快照 30 秒回滚,这几项对数据库场景都算得上实用。具体的 NVMe 盘型、大内存定制与实时报价,建议直接咨询确认,别照着文章里的数字下单。

数据来源

本文涉及的 MySQL 复制机制、binlog 格式、GTID、并行复制与相关参数说明,均属 MySQL 官方公开文档范畴,具体参数名、默认值、行为与版本差异请以 MySQL 官方文档对应版本为准;读写分离中间件(ProxySQL、ShardingSphere-Proxy、MySQL Router 等)的能力与限制,请以各项目官方开源文档为准。

价格与产品信息来自一万网络官网公开页面(裸金属服务器页、香港服务器页、官网首页地区起步价),抓取时间为 2026-09-17,均为官网明示价(A 类),以官网实时价为准;文中涉及的配置建议、容量估算与延迟阈值为经验口径,非官方承诺,需结合自身业务压测校准。具体配置、可选盘型、内存上限与最终价格,以签约时最新报价与合同为准。


上一篇:2026 服务器迁移怎么做到不停机:网站与数据库平滑迁移流程、回滚方案与避坑指南

下一篇:2026 服务器快照与镜像备份怎么配:自动快照周期、异地副本与恢复演练避坑指南