MySQL深入——19

读写分离有哪些坑??

一主多从结构就是基本的读写分离结构,主要目的在于分摊主库的压力。

其中一种架构是将数据库的连接信息放在客户端,由客户端选择后端数据库进行查询。

还有一个架构是MySQL与客户端之间有一个中间代理层proxy,客户端只连proxy由proxy决定分发路径。

第一种架构来说,结构金丹,便于维护,只出现主备切换,库迁移时,只需要在客户端调整数据库连接信息

proxy的架构,对客户端较为友好,因为连接是由proxy决定的,proxy的维护成本高,proxy需要高架构。

不论使用什么架构,都有可能碰到主从延迟的事件,这种从从库上读到系统上过期状态的现象,称之为"过期读"。

我们可以通过一下操作来处理

强制走主库

将查询请求做分类,对于需拿到最新结果的请求,就走主库,对于读到旧数据的请求就走从库。

问题在于,在碰到金融类的项目时,要求所有读都不能为过期读,这就得全走主库,导致主库压力过大。

Sleep方案

主库更新后,将从库sleep一下,这个方案假设大多数主备延迟在一秒之内,做一个sleep有很大概率拿到新的数据,但是这个不是很靠谱,因为如果更新的延迟大于一秒就得读旧数据了。

判断主备无延迟方案

1.判断seconds_behind_master是否为0

2.对比位点

Master_log_file和read_master_log_pos(读到主库的最新位点)

Relay_Master_log_file和Exec_Master_log_pos(备库执行的最新位点)

这两组值相同的时候代表同步完成

3.GTID集合

Auto_Position=1 主备使用了GTID协议

Retriered_Gtid_Set(备库收到的GTID集合)和Executed_Gtid_Set(备库已经执行的GTID集合)两个集合相同,代表同步完成。

相比于sleep方案这样的精准度更高,但是还是会出现问题。

有一种情况为主库执行完后写入binlog,返回给客户端的这一刻,还没有将binlog传给备库。

我们可以使用semi_sync来解决

semi_sync做了这样的设计

1.事务提交之后主库binlog给从库

2.从库收到之后,返回一个ack给主库

3.主库收到ack之后才给客户端返回事务已经完成的确认。

一主一备的情况下是成立的,但是一主多从就会出现两种情况

1.查询落到ack从库,相安无事

2.查询的不是ack从库,就有可能出现过期读的情况

其实同步位点的判断还存在着一个问题,比如业务高峰期,主库的GTID更新极快,等到等值判断的时候,是必然不相同的,会造成长时间不响应查询的情况。

等主库位点

看条命令

复制代码
select master_pos_wait(file , pos[,timeout])

file pos指主库上的文件名和位置

timeout可选,设置为正整数N,表示函数做多等多少秒。

正常结果返回一个正整数M,表示从开始执行到现在应用完file和pos表示的binlog位置,执行了多少事务。

其他结果返回:1.执行过程当中,备库同步线程异常,返回Null

2.超出N,返回-1

3.刚开始执行过这个位置返回0

对于在主库上刚执行完的更新语句,马上执行show master status,得到当前主库的file和position

若返回值为大于等于0的整数,则在这个备库执行查询语言,否则到主库当中执行查询语言。

那么如果超时了,是不是还得去主库呢,其实可以做两个选择:1.超时放弃2.去主库查。

GTID方案

MySQL当中提供了一个类似的命令

select wait_for_executed_gtid_set(gtid_set,1)

这条命令的逻辑是

1.等待1秒,直到这个库执行的事务传给gtid_set,返回0

2.超时返回1

在GTID当中变成

1.trx1事务更新完成后,从返回包当中获取这个事务的GTID记为gtid1

2.选择一个从库进行查询语句

3.在该从库上执行上面那条命令

4.若返回值为0,在这个从库执行查询语句

5.否则就去主库

MYSQL在执行事务后带上GTID需要将参数 session_track_gtids设为OWN_GTID通过API接口msyql_session_track_get_first从返回包查询即可。

相关推荐
likangbinlxa2 小时前
【Oracle11g SQL详解】UPDATE 和 DELETE 操作的正确使用
数据库·sql
r i c k2 小时前
数据库系统学习笔记
数据库·笔记·学习
野犬寒鸦3 小时前
从零起步学习JVM || 第一章:类加载器与双亲委派机制模型详解
java·jvm·数据库·后端·学习
IvorySQL3 小时前
PostgreSQL 分区表的 ALTER TABLE 语句执行机制解析
数据库·postgresql·开源
·云扬·4 小时前
MySQL 8.0 Redo Log 归档与禁用实战指南
android·数据库·mysql
IT邦德4 小时前
Oracle 26ai DataGuard 搭建(RAC到单机)
数据库·oracle
惊讶的猫4 小时前
redis分片集群
数据库·redis·缓存·分片集群·海量数据存储·高并发写
不爱缺氧i4 小时前
完全卸载MariaDB
数据库·mariadb
纤纡.4 小时前
Linux中SQL 从基础到进阶:五大分类详解与表结构操作(ALTER/DROP)全攻略
linux·数据库·sql
jiunian_cn5 小时前
【Redis】渐进式遍历
数据库·redis·缓存