title: MySQL · myrocks · myrocks 复制优化
myrocks 依然采用 mysql 原有的基于 binlog 的复制方式。目前由于 myrocks 不支持 gap lock, 因此在 statement 格式的 binlog 下进行复制,主备可能出现不一致。myrocks 建议在复制时设置 binlog 格式为 row。 myrocks 在 rocksdb 引擎层为复制做了一些卓有成效的优化,例如 skip unique check , read free replication。
skip unique check 忽略唯一性检查,此特性开启时需确保我们写入的数据不会违反唯一性约束。在正常的主备复制环境下, 备库是只读的,主库的写入是经过了唯一性检查的,写入 binlog 后,备库应用这些 binlog 时理论上是不需要再检查唯一性的。 基于以上假设,备库开 skip unique check,可以减少唯一性检查的开销,并保证主备数据的一致性。
skip unique check 有以下参数可以控制,
在备库环境中,我们一般只设置以下三个参数 (rocksdb_skip_unique_check 参数设置为 true 后,下面三个参数不管怎么设置都会忽略唯一性检查)
- rocksdb_skip_unique_check_tables unique_check_lag_threshold unique_check_lag_reset_threshold
备库开启 skip unique check 时,还有一个优化是写入数据时不需要加锁,省去了锁的开销 (get_blind_write_batch)。
read free replication 优化思路来源于。
tokudb 是基于 Fractal-Trees,数据都是先写入到内节点 message buffer, 最后再 apply 到叶子节点。这种延迟写入特性有益于 read free replication。
read free replication 必须工作在 row 格式的 binlog 下,基于 row 格式的 binlog 包括 row 的前镜像和后镜像。read free replication 利用前镜像来直接更新数据,从而减少了一次读取行操作。
引入 read free replication 之前,备库复制线程是这样工作的
引入 read free replication 之后,备库复制线程是这样工作的
对于 insert,read free replication 实际不起作用。
因此,要想真正的做到 read free replication 即复制 sql 线程只管写入不需要读取行, read free replication 是需要和 skip unique check 一起配合使用的
问题来了,innodb 可以做到 read free replication 吗?
read free replication 使用是在一定前提下的
- binlog格式为row复制所在的备库必须是只读的
这里列了两个违反规则使用 read free replication 导致出问题的,转帖如下
- create table t(id int primary key, i1 int, i2 int, value int, index(i1), index(i2)) engine = rocksdb;
- insert into t values(1, 1, 1, 1),
- (2, 2, 2, 2),
- (3, 3, 3, 3);
- s: delete from t where id <= 2;
- m: update t set i2 = 100,
- value = 100 where id = 1;
- s: mysql > select count( * ) from t force index(primary); + ----------+|count( * ) | +----------+|2 | +----------+1 row in set(0。00 sec) mysql > select count( * ) from t force index(i1); + ----------+|count( * ) | +----------+|1 | +----------+1 row in set(0。00 sec) mysql > select count( * ) from t force index(i2); + ----------+|count( * ) | +----------+|2 | +----------+1 row in set(0。00 sec) mysql > select * from t where id = 1; + ----+------+------+-------+|id | i1 | i2 | value | +----+------+------+-------+|1 | 1 | 100 | 100 | +----+------+------+-------+1 row in set(0。00 sec) mysql > select i1 from t where i1 = 1;
- Empty set(0。00 sec) mysql > select i2 from t where i2 = 100; + ------+|i2 | +------+|100 | +------+1 row in set(0。00 sec)
- M: create table t(id int primary key, i1 int, i2 int, value int, index(i1), index(i2)) engine = rocksdb;
- insert into t values(1, 1, 1, 1),
- (2, 2, 2, 2),
- (3, 3, 3, 3);
- S: update t set i1 = 100 where id = 1;
- M: delete from t where id = 1;
- S: mysql > select count( * ) from t force index(primary); + ----------+|count( * ) | +----------+|2 | +----------+1 row in set(0。00 sec) mysql > select count( * ) from t force index(i1); + ----------+|count( * ) | +----------+|3 | +----------+1 row in set(0。00 sec) mysql > select count( * ) from t force index(i2); + ----------+|count( * ) | +----------+|2 | +----------+1 row in set(0。00 sec) mysql > select i1 from t where i1 = 100; + ------+|i1 | +------+|100 | +------+1 row in set(0。00 sec)
这篇介绍了 tokudb read free replicatio 的应用场景,同样适用于 rocksdb read free replication。
总之,read free replicatio 大大提高了复制的效率,同时结合 rockedb 的高效压缩和低写入放大特性,使得 myrocks 非常适用于只读库的扩展,或作为 mysql 其他引擎实例的备用实例。
myrocks 在复制方面作了有益的优化,但这些优化并不是银弹。我们通过这些优化得到高的回报的同时,也要明确知道这些优化的风险,严格遵守优化的前置条件,从而保证安全性和高性能。
来源: https://yq.aliyun.com/articles/65166