(十一)读写分离,过期读,判断数据库出现问题

24 读写分离

由于从库延迟是不能100%避免的,因此客户端执行完一个更新事务后马上发起查询,如果查询选择的是从库的话,就有可能读到刚刚的事务更新之前的状态,即过期读

过期读的解决方案:

  1. 强制走主库方案

将查询请求分为这么两类:
1)对于必须要拿到最新结果的请求,强制将其发到主库上。
2)对于可以读到旧数据的请求,才将其发到从库上。

该方案是用的最多的,但这个方案最大的问题在于,有时候你会碰到“所有查询都不能是过期读”的需求,比如一些金融类的业务。这样的话,你就要放弃读写分离,所有读写压力都在主库,等同于放弃了扩展性。

  1. sleep方案

主库更新后,读从库之前先 sleep 一下。
具体的方案就是,类似于执行一条 select sleep(1) 命令。
这个方案的假设是,大多数情况下主备延迟在 1 秒之内,做一个 sleep 可以有很大概率拿到最新的数据。

  1. 判断主备无延迟方案

每次从库执行查询请求前,先判断 seconds_behind_master 是否已经等于 0。如果还不等于 0 ,那就必须等到这个参数变为 0 才能执行查询请求。

但是,从 binlog 在主备之间状态的分析中,不难看出还有一部分日志,处于客户端已经收到提交确认,而备库还没收到日志的状态。

如果这时候你在从库 B 上执行查询请求,按照我们上面的逻辑,从库认为已经没有同步延迟,但还是查不到 trx3 的。严格地说,就是出现了过期读。

  1. 配合 semi-sync

semi-sync 做了这样的设计:事务提交的时候,主库把 binlog 发给从库;从库收到 binlog 以后,发回给主库一个 ack,表示收到了;主库收到这个 ack 以后,才能给客户端返回“事务完成”的确认。

  1. 等主库位点方案

1)trx1 事务更新完成后,马上执行 show master status 得到当前主库执行到的 File 和 Position;
2)选定一个从库执行查询语句;
3)在从库上执行 select master_pos_wait(File, Position, 1);
4)如果返回值是 >=0 的正整数,则在这个从库执行查询语句;
5)否则,到主库执行查询语句。

  1. 等待GTID 方案

25 如何判断一个数据库是不是出问题了

  1. select 1
  2. 查表判断 select * from mysql.health_check;
  3. 更新判读 update mysql.health_check set t_modified=now();

mysql> CREATE TABLE `health_check` (
  `id` int(11) NOT NULL,
  `t_modified` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP,
  PRIMARY KEY (`id`)
) ENGINE=InnoDB;

/* 检测命令 */
insert into mysql.health_check(id, t_modified) values (@@server_id, now()) on duplicate key update t_modified=now();
  1. 内部统计 增加检测 performance_schema统计内部每一次 IO 请求的时间,如果超过阈值则认为出问题了
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值