Mysql读写分离的过期读问题

在数据库高可用架构中,读写分离是提升系统吞吐量的核心手段。其基本逻辑是:主库(Master)负责所有写入操作,从库(Slave)分担查询压力。然而,由于主从同步存在物理延迟,客户端可能在备库读到尚未同步的旧数据,这种现象被称为"过期读" 。

一、 读写分离的实现架构

实现读写分离主要有两种主流方案:

  1. 客户端直连 (Client-side)
  • 执行逻辑:应用代码内部实现负载均衡,配置主库和多个从库的 IP,根据请求类型分发。
  • 特点:性能损耗极低,架构简单;但运维成本高,主备切换时需要修改所有客户端配置 。
  1. 带 Proxy 的中间件架构 (Proxy-side)
  • 执行逻辑:应用只连接 Proxy,由 Proxy 负责 SQL 解析、路由分发和后端存活检测。
  • 特点:对应用透明,运维方便;但增加了网络延迟,且 Proxy 自身需要考虑高可用 。

二、 解决"过期读"的六种方案

为了在提升性能的同时保证数据准确,需要针对不同业务场景选择合适的"过期读"解决方案。

  1. 强制走主库方案
  • 策略:将查询请求分为"允许延迟"和"必须实时"两类。
  • 示例:用户刚修改完个人资料,其"个人中心"页面必须强制查主库以保证可见性;而其他用户浏览该资料时可走备库。
  1. Sleep 方案
  • 策略 :在写操作后,读操作前让客户端执行一次短时间的 sleep
  • 评价:这是一种不严谨的概率性方案。如果延迟超过 sleep 时间,依然会读到旧数据;反之则会浪费响应时间。
  1. 判断主备延迟方案
  • 在查询备库前,先通过以下方式确认同步进度:
    • 监控 SBM :确保 seconds_behind_master 为 0。
    • 对比位点 :确保已收到的日志位点 Read_Master_Log_Pos 等于已执行位点 Exec_Master_Log_Pos
    • 对比 GTID 集合 :确保备库已执行的集合 Executed_Gtid_Set 包含已收到的集合 Retrieved_Gtid_Set
  1. 配合半同步复制 (Semi-Sync) 方案
  • 策略:利用半同步复制保证主库返回成功前,至少有一个备库收到了 binlog。
  • 配合:结合"对比位点"法。只要备库收到的位点等于主库最新的位点,代表数据已到。
  • 局限:在一主多从架构下,如果请求落到了那个恰好没收到日志的备库,方案会失效 。
  1. MASTER_POS_WAIT 等位点方案
  • 物理流程
    1. 写操作完成后,通过 SHOW MASTER STATUS 获取主库当前的 FilePosition
    2. 客户端去备库执行 SELECT MASTER_POS_WAIT(File, Position, timeout)
    3. 如果函数返回 ≥0\ge 0≥0,说明备库已追平该点,可以安全读取。
  1. WAIT_FOR_EXECUTED_GTID_SET 等 GTID 方案
  • 这是目前最先进且精确的方案,基于 MySQL 5.7+ 的 GTID 机制
  • 物理流程
    1. 主库写入成功后返回该事务的 gtid 给客户端。
    2. 客户端去备库执行 SELECT WAIT_FOR_EXECUTED_GTID_SET(gtid, timeout)
    3. 备库会阻塞等待,直到该 GTID 被本地执行完成。
  • 优化 :设置 session_track_gtids=OWN_GTID,主库会在响应报文里自动带上最新的 GTID,简化开发逻辑 。
相关推荐
IvorySQL2 小时前
PG 日报|新增 VACUUM 全维度统计信息补丁迭代
数据库·人工智能·postgresql·ivorysql
白露与泡影5 小时前
Redis 缓存实战:雪崩、穿透、击穿一次讲透
数据库·redis·缓存
赵渝强老师6 小时前
【赵渝强老师】使用Oracle可传输的表空间迁移数据
数据库·oracle
IpdataCloud7 小时前
跨区服玩家延迟高怎么办?用IP离线库自动分配到最近服务器
数据库·tcp/ip·github·php·ip
wuqingshun3141598 小时前
MYSQL默认的事务隔离级别是什么?为什么选择这个级别?
数据库·mysql
空中湖8 小时前
电池简史(五):极限之梦与终章——锂硫、锂空气、量子电池,以及你该知道的电池投资与生活指南
数据库·程序人生
蓝胖子酱9 小时前
在 Electron 中用 electron-store 实现加密存储与自定义格式文件
前端·javascript·数据库
snow@li10 小时前
Redis:数据库语法速查表 / 全景梳理
数据库·redis·缓存
Devlive 开源社区10 小时前
Nebula 1.6.0 发布:跨区域桶自动路由、秒传、文本/PDF 预览一次到位
数据库·sql
这个DBA有点耶11 小时前
导个数据中文全变问号?字符集这事儿真没那么简单
数据库·mysql·代码规范