OneSQL :: 如何保证数据库主备一致,RealSync比SemiSync要更高效!

虽然OneSQL可以将备库SQL回放的速度提升5倍,主库上的事务仍有可能比从库高很多,单线程很难比得过并发处理,从库仍可能远远落后于主库,从而造成主从数据的大量不一致,对于关键业务场景这一点是很致命的,宁愿选择事务处理慢一点,也要保证主备数据完全一致。如何保证意外切换到备库后,数据不会有丢失?MySQL引入了同步复制功能(SemiSync),只有当至少一个从库已经接到到主库的Binlog后,才能告知客户端事务已经成功。但并不检查备库上是否已经回放对应的Binlog,依旧存在数据丢失的风险,这种模式下具有较好的性能。

下图是不配置任何同步机制时对主库的一个事务性能压测,可以看到每秒钟产生了4MB日志(“Blog”列)。

onesql_async_performance

OneSQL中同样可以启用和同步复制一样的日志保护机制,称之为RealSync功能,客户端会在一台备库接收到对应的Binlog后才告诉客户端事务成功了,但并不等待备库回放Binlog完成。这时从库仍有可能落后于主库而读到脏数据,在设计和实施读写分离方案时必须要注意到这一点。

在OneSQL的从库端进行如下设置:

mysql> set global tcc_binlog_realsync_affirm=dump;
Query OK, 0 rows affected (0.00 sec)

在OneSQL的主库端进行如下设置:

mysql> set global tcc_binlog_realsync=on;
Query OK, 0 rows affected (0.00 sec)

mysql> set global tcc_binlog_realsync_affirm=dump;
Query OK, 0 rows affected (0.00 sec)

再次启动一务压测,发现主库的事务处理性能会有一定的下降,从每秒钟产生4MB日志变成每秒钟3MB左右。

onesql_after_sync_performance

虽然有性能下降,但要比官方MySQL版本的同步复制(SemiSync)高效,这个模式下可以少担心数据丢失了,你可以至少找到一台拥有最新数据的备库来进行切换。为了性能考虑虑,OneSQL只保证日志同步到多台备库中的一台,而不是全部,对于重要业务场景,平民软件建议在共享存贮上运行OneSQL或MySQL数据库。

OneSQL还有一种更有效的数据保护模式,需要等到其中一个备库接收到并回放相应的Binlog日志,才告知客户端事务完成。这个模式下,性能虽然受限制备库的恢复速度,但主备之间可以保证不会有复制延时。

在OneSQL的从库端进行如下设置:

mysql> set global tcc_binlog_realsync_affirm=apply;
Query OK, 0 rows affected (0.00 sec)

在OneSQL的主库端进行如下设置:

mysql> set global tcc_binlog_realsync=on;
Query OK, 0 rows affected (0.00 sec)

mysql> set global tcc_binlog_realsync_affirm=apply;
Query OK, 0 rows affected (0.00 sec)

再次启动一务压测,发现主库的事务处理性能会有进一步的下降,从每秒钟产生3MB日志变成每秒钟2MB左右,但仍可以支持每秒1万个小事务左右。

onesql_after_apply_performance

虽然性能有较大的下降,但如果在读写分离方案中使用OneSQL的这个数据保护策略,就可以不用担心备库时延。而官方的同步复制(SemiSync)则无法做到这一点,而且备库恢复的速度还可以通过开启并行复制来得到进一步的优化,可以让这个数据保护模式变得非常实用。