近期,我们的数据库团队对原生复制的多个方面进行了深度优化,提升了UDB高可用数据库的功能和性能。今天借社区这个平台跟大家分享一二。1.UDB高可用数据库架构UDB采用虚拟IP、HAProxy、单节点UDB数据库搭建双节点高可用架构:双节点UDB数据库保证了数据库数据的全冗余和数据库的可用性数据库;HAProxy同时只连接一个UDB节点,避免多点写入造成的数据冲突;双节点HAProxy保证代理的可用性;虚拟IP在HAProxy宕机时通过IP漂移切换HAProxy,用户无需再次修改IP。在上述架构中,从节点UDB的数据是否完整,是否保证与主库的数据一致性是整个高可用架构的关键,因此数据传输的半同步复制起到了至关重要的作用角色。对于原生半同步复制,我们在内核层面做了深度优化。2、UDB数据库深度优化UDB以开源数据库MySQLCommunityServer5.7.16为基线版本,围绕高可用架构进行内核深度优化。复制过程,如上图所示,主要经过以下步骤:MySQLServer执行SQL成功后,记录binlog;Dump线程读取binlog后,发送给slaveIO线程;IO线程将接收到的binlog记录到relaylog中,同时在master.info中记录接收进度;SQL读取relaylog中的日志内容进行复现,并在relay-log.info中记录复制日志的进度。在原生复制的基础上,我们对内核进行了深度优化,对上述过程中的部分步骤进行了功能和性能的改进,使UDB更加稳定。1、Binlog日志复制优化存在的问题原生半同步复制存在降级问题。当网络抖动导致超时或者从库赶上主库日志的进度时,复制就会从半同步复制退化为异步复制。相对于可靠的半同步复制,异步复制时,从库无法感知接收到的relaylog是否与主库的binlog一致。如果出现宕机,则无法确认从库数据是否与主库一致,是否会发生数据库切换。这种不确定的情况是我们不愿意看到的。优化方案建立双通道复制,在原有半同步复制的基础上增加一个UDB复制通道:与原复制并行建立新的复制通道,两个通道相互独立;新的复制通道不传输数据,只传输主库的SQL执行进度(binlog文件名和位置);新的复制通道使用半同步复制协议,但不退化,超时重连,只接收最新的SQL执行进度;新的复制通道没有赶上数据问题,只要网络正常,从库总能感知到SQL的执行进度。如上图所示,当从库宕机或网络故障时,主从复制停止。当从库复制恢复正常后,native复制通道通过异步复制进行数据补充,UDB复制通道只接收最新的binlog记录位置,可以最大限度减少主从之间异步复制的时间。即在联网的情况下,每当出现宕机时,从库就知道自己是否处于与主库数据一致的状态(或者落后多少)。2、Relaylog文件记录优化存在的问题在MySQL中,binlog是以event为基本单位进行记录的。以MySQL5.7ROW格式(启用GTID)的binlog为例,一个DML(insert)会使用5个event格式记录在binlog中(其他操作由一个或多个event组成,不再一一列举分别为:GTID_EVENT:记录当前事务的GTIDQUERY_EVENT:启动事务TABLE_MAP_EVENT:操作对应的表WRITE_ROW_EVENT:插入记录XID_EVENT:提交事务的所有事件组成一个完整的事务,完整的事务将SQL线程正确复制到从库。当前IO线程收到binlog时,以事件为单位接收,即接收到一个事件,记录在relaylog中,然后继续接收下一个。这种方式效率低下,没有充分利用MySQL自身的文件缓存。优化方案优化了IO线程记录relaylog的方式,将以事件为单位记录改为以事务为单位记录。将IO操作与小IO线程合并,以提高IO性能。将单个事件写操作合并为多个事件统一写操作,将小的IO操作合并为更大的IO操作,提高IO性能。3、Master.info文件记录优化问题。Master.info文件在建拷贝时记录了主库连接的IP、PORT等相关信息。在复制过程中,记录IO线程从主库接收到的binlog。的文件名和位置,每次relaylog记录成功时都会更新文件和位置。设置了基于GTID的复制后,master.info中记录的binlog文件和location不再作为复制的依据,所以master.info中记录的binlog文件和location不再是有效数据,不需要执行更新。优化方案在IO线程记录relaylog成功后,更新master.info文件前增加判断。如果启用了GTID并使用GTID作为复制的基础(auto_position=1),那么master.info中的binlog文件和位置将不再更新。其他master.info操作还是保留的,比如changemaster,shutdown等操作。4.Relaylog锁优化中的问题当IO线程和SQL线程有相似的复制进度时,操作relaylog时会使用相同的文件缓存。在读写文件缓存时,需要加锁来保证操作的正确性。但是IO线程和SQL线程需要频繁读写这块公共内存,需要频繁竞争同一个锁,导致性能下降。优化方案将IO线程和SQL线程对relaylog的操作分开,不再使用同一个文件缓存。虽然这样做会导致SQL线程增加一个读IO操作。但是消除了锁的竞争,IO线程和SQL线程的整体性能有了很大的提升。3.总结优化后的复制流程图如下:数据库原生复制过程包括记录binlog、记录relaylog、记录master.info、relay-log.info等,针对上述过程中的部分步骤和其他优化没有上市后,为提升功能和性能,UDB高可用数据库在功能和性能上有了显着提升。
