一.概述
通过分析,我们发现MySQL原声半同步复制缺陷:
1、MySQL半同步复制支持退化成异步复制,在严格的金融场景不一定合适。
2、MySQL在Slave在收到Master的binlog时,默认情况下无法保证relay log实时落盘,即sync_relay_log=0,如果需要保证relay log实时落盘,即sync_relay_log=1,则每个event会调用一次fsync,数据库性能大幅下降。
3、MySQL在等待Slave返回ACK时工作线程是阻塞状态的,若长时间收不到ACK,用户提交被挂起,
1>如果要提高并发则要会开启更多的线程,而线程越多,时耗就越不稳定,性能达到某个值之后会下降.
2>在跨IDC等延时比较大的情况下,MySQL半同步复制性能下降比较厉害。
因此,TDSQL强同步复制主要改造如下:
1、如果Master等待Slave ACK出现超时,则返回给客户端失败,但不可退化模式下强同步复制不退化成异步复制,确保主备数据强一致,主备切换事物0丢失,满足金融场景的需求。
2、增加rpl_slave_ack_thread线程,循环取出io_thread接收到的binlog 和pos等信息,且只处理最后一个,如果对列为空,则等待,可以通过组的机制来实现,性能与异步相当,
1> 启用该功能后,从库io_thread不是在接收主库的event之后立即写入磁盘(也不是 fsync),而是将 binlog 文件名和偏移量插入一个队列。
2> 使用rpl_slave_ack_thread线程从队列中获取binlog位置信息,然后写入binlog_cache,并fsync,然后给强同步主库回ACK消息。
3、强同步复制采用线程池+业务线程易步化,充分利用资源,性能接近异步
1> 在Master等待Slave ACK的过程中,会将会话保存起来,然后线程切换到其他的的会话处理,不用无谓的等待。
2> 性能提升的同时响应时间会增加,但在高并发场景下TPS不下降。
二、强同步复制的原理:
首先Master上一笔写请求到达,线程池分配连接处理该请求,当收到commit之后先写binlog,这时继续往下应该回吐客户端信息,但对于开启了强同步的服务来说,此时会先hold住这个操作,在内存保存会话信息。
然后可以继续处理其链接的请求。此时客户端还不能收到应答,啥时候能收到应答呢?Master启动之后,会先启动一个udp服务器,用来接受Slave收到binlog的ACK请求,同时再启动16个工作线程,当收到ACK请求时,这16个线程其中之一去唤醒刚刚保存的会话,执行下半段(如执行引擎层提交等)并对客户端返回应答信息。
所以,在Master上新开了两组线程,一组为接受ACK应答线程(Dump ACK Thread),另外一组为唤醒hang住的客户端连接线程(User ACK Thread)。Slave这里比较简单,就是在io线程刷盘relay log时给Master的udp线程发一个应答包。、
三、核心参数
sqlasyn=ON
● 是否开启强同步模式。Master和Slave需同时开启该参数,强同步才能正常工作。
● 注意:强同步必须和thread pool一起使用;针对使用extra port或者socket连接(没有使用thread pool),强同步模式失效。 sqlasyntimeout=30
● 强同步下Master等待Slave ACK最大时间;如果超时之后会报超时的错误并断开连接 。 tdsql_allow_async=OFF
● 如果Master没有收到Slave ACK,则允许降级为异步复制。 sqlasync_after_sync=OFF
● 如果为ON,则Master的用户线程在收到Slave ACK后进行engine commit,即AFTER_SYNC模式。如果为OFF,则AFTER_COMMIT模式。 sqlasynwarntimeout=3
● Master接收Slave ACK超过配置的时间,将会在error日志里打印信息,便于在网络、备机等异常的时候分析日志既可以发现一些线索。日志格式如下:
[ERROR] [MY-000000] [Server] session waiting for ack of binlog pos (2,5780) cost [6] sec,exceed 3 sec relay_log_sync_threshold=20000
● 在同步中继日志并将ACK发送给Master之前要累积的字节数。 relay_log_sync_timeout=1000
● 如果自从上次从IO线程fsync&ACK中继日志以来已经过去了这么多微秒,则IO线程无论如何都将fsync&ACK中继日志,而与relay_log_sync_threshold无关。此超时应该短于sqlasyntimeout,否则客户端在提交事务时将获得ER_RBTIMEOUT错误,然后断开连接。 relay_log_sync_txn_count=10
● 如果IO线程自上次fsync&ACK中继日志以来已接收到这么多事务的二进制日志,则无论其他限制如何,它将仍然fsync&ACK中继日志。 tdsql_relay_log_opt=OFF
● 如果为ON,始终在事务结束时刷relay log,以使relay log可靠。sqlasync_group_slave_ack=TRUE
● 是否开启slave节点使用group ack(merge fsync),保证数据持久化,减少IO。
标签:同步,Slave,log,relay,ACK,TDSQL,复制,线程,Master From: https://blog.51cto.com/u_15721050/6386308