复制表是 OceanBase 数据库为应对小表广播场景并结合自身架构形成的解决方案。本文主要介绍 OceanBase 数据库中复制表的特性。
适用版本
OceanBase 数据库 V2.x 及后续版本。
复制表
业务上存在一些表,这些表的更新的频率很低,但是访问的频率非常高,并且要求总是能够访问到最新的数据。OceanBase 数据库中,强一致性读只能通过访问 leader 副本的数据实现,但是由于表的访问频率很高,leader 副本容易成为性能瓶颈。为了解决性能问题,提升上述场景的访问效率,实现备副本的强一致性读,引入了复制表功能。
OceanBase 数据库中,复制表的实现方式是将表的副本复制到表所属租户的所有 OBServer,这些副本称为复制副本。复制副本描述的是副本的属性,复制副本可以是一个全功能副本,也可以是一个只读副本。事务在提交时,数据会同步到多数派的全功能副本及全部复制副本,确保在更新事务提交成功之后,复制到的表所属租户的任意 OBServer 上都能读取该事务修改的数据。
复制表具有以下特性:
leader 副本的日志同步到多数派 paxos 组成员后,就认为日志同步成功。但只有 leader 副本将日志同步到所有复制副本后才能返回客户端。
复制副本可以提供强一致性读。
复制副本需要定期向 leader 副本申请 lease,只有在 lease 有效时间窗口内,复制副本才能提供强一致性读服务。
复制表具有以下优势:
提高 SQL 的强一致性读的查询性能。这是由于在生成执行计划时,parser 模块可以根据复制表的副本分布来生成更优的执行策略,查询计划会将远程或分布式执行计划优化为本地执行计划。
减轻 leader 副本上的 I/O 负载,这是由于普通表只能由 leader 表提供强一致性读。
但复制表具有以下劣势:
会导致修改复制表的事务(INSERT、UPDATE 和 DELETE 语句)的 commit latency 提高。
由于副本的数量增加了,会导致磁盘的使用增加。
使用复制表
创建复制表
通过在创建表的时候,指定 DUPLICATE_SCOPE 字段的方式,将表创建为复制表。其中,DUPLICATE_SCOPE 字段默认为 NONE,可选的取值为 NONE、CLUSTER。
各取值的含义为:
NONE:表示该表是一个普通表。
CLUSTER:将表的副本复制到表所属租户的集群中所有的 OBServer。
创建复制表的示例如下。
obclient> CREATE TABLE bmsql_item (
i_id integer not null,
i_name varchar2(24),
i_price decimal(5,2),
i_data varchar2(50),
i_im_id integer,
PRIMARY KEY (i_id)
)use_bloom_filter=true compress locality='F,R{all_server}@zone1, F,R{all_server}@zone2, F,R{all_server}@zone3' primary_zone='zone1' duplicate_scope='cluster';
删除复制表
复制表的删除与普通表无差异。
obclient> DROP TABLE bmsql_item;
说明
删除复制表后,后台日志会出现 ret=-5019 的错误。这是由于表的副本在别的服务器上没有被同步删除,GC 后这个错误信息就会自动消失,该问题可忽略。