腾讯云数据库团队:MySQL语句复制(SBR)的缺陷列举

做者介绍: 赵伟 腾讯云TDSQL数据库开发者mysql

MySQL (这里的MySQL是指广义的mysql,包括oracle,mysql,percona,mariadb等)的Statement Based Replication (SBR)是一个暗坑无数的功能,可能致使主备机数据不一致,以及其它问题,因此在TDSQL中咱们使用RBR。这里就列举几条SBR的坑。sql

在此以前,先说说SBR的有点。与Row based Replication (RBR)相比,它能够避免传输大量的binlog日志从而减少网络和存储系统(binlog文件)的负载。另外,某些时候在备机上面从新执行SQL语句反而会比逐条执行RBR的binlog要快,一个极端的例子是,若是一个表没有主键,而后一个delete/update语句须要删除/更新大量的行,那么使用RBR将是噩梦,由于备机处理每一条这样的binlog都会致使全表扫描从而大大下降备机的性能(因此在TDSQL中咱们默认强制建立含有主键的表)。可是使用SBR的话,一次执行便可更新/删除所有行,这样就快了不少。数据库

下面正式开始批评SBR了。网络

首先,因为SBR模式下,SQL语句到了备机须要被从新执行,与RBR相比,就增长了从新执行SQL语句的额外开销,包括解析,优化和执行SQL语句。RBR则直接调用mysql的存储引擎接口(handler API)来执行行的插入、删除和更新,彻底跳过了mysql的优化器的处理逻辑。架构

SQL语句到了备机须要被从新执行,在多种状况下就会致使主备机数据不一致,好比一个SQL语句调用了用户定义的函数,调用了返回随机值的函数,在数据表中使用了自增列,以及使用了上下文数据(context data,好比用一个表的行数做为某个插入字段值,或者在update/delete语句中使用了limit子句)等等。并发

另外一个一致性陷阱在于使用MyISAM等非事务存储引擎。在彻底使用innodb等事务存储引擎的状况下,MySQL replication是crash safe的,也就是说,不管任什么时候刻mysql server crash了,或者OS crash了,或者机器断电了,mysql server均可以恢复数据到crash以前的状态,确保事务的持久性和一致性,确保全部以前提交的事务的改动都存在,由于innodb自身支持事务,能够恢复,而且在近年版本的mysql和mariadb中,innodb可使用到binlog数据来完成恢复。(尽管组提交时候并无刷盘commit日志) 可是一旦使用了非事务存储引擎,那么一个事务的完整性就不存在了,也不是crash safe的了。在master和slave上面都是这样。虽然mysql的各个分支和版本在replication实现中作了不少努力来避免一些问题,而且给用户强制了一大堆暗坑无数的DOs&DONTs,可是没法彻底解决这个问题。当发生了crash以后,只要一个事务读取 而且/或者 写入到了MyISAM表,那么这个事务的改动可能部分存在,部分消失,而且binlog与数据表也可能会有各类不一样,而后,用户的数据就没法使用了。oracle

第三,在使用innodb/xtradb而且隔离级别是read committed时候,若是设置binlog_format为statement,那么mysql会拒绝后续的插入/更新/删除操做,错误信息是:函数

ERROR 1665 (HY000): Cannot execute statement: impossible to write to binary log since BINLOG_FORMAT = STATEMENT and at least one table uses a storage engine limited to row-based logging. InnoDB is limited to row-logging when transaction isolation level is READ COMMITTED or READ UNCOMMITTED.性能

可是在设置这两个变量的时候却并无报错。这个组合也是会致使slave在并发执行时候的数据一致性问题。 因此,仍是推荐你们使用RBR和INNODB(或者其余支持事务的存储引擎)的搭配,咱们一直用它:)优化

相关推荐

MySQL AHI 实现解析

腾讯云TDSQL数据库系统架构介绍


此文已由做者受权腾讯云技术社区发布,转载请注明文章出处,获取更多云计算技术干货,可请前往腾讯云技术社区

欢迎你们关注腾讯云技术社区-博客园官方主页,咱们将持续在博客园为你们推荐技术精品文章哦~

相关文章
相关标签/搜索