首批通过分布式安全可靠测评,为关键业务系统打造
列存副本
更新时间:2026-06-06 14:23:45
列存副本(C 副本) 是 OceanBase 的一种只读副本类型,主要用于承载 分析型(AP)只读查询。数据在 C 副本上以 列存 存储,与全能副本(F)、只读副本(R)等配合使用:TP 写入与常规强读仍主要落在 F/R;AP 扫描可在 C 副本上获得更合适的存储形态。在 C 副本上,所有的用户表(包括复制表、不包括索引表、内部表、系统表)均为列存格式存储。OLAP 业务通过独立的 proxy 入口访问 C 副本,并以弱读方式执行决策分析类业务。
列存副本主要具备以下特点:
包含完整的日志、MemTable 和 SSTable 等。
基线(major sstable):同一日志流上的用户表在 C 副本上,基线数据以列存组织,便于大范围扫描与 AP 计算。
增量与融合:MemTable、转储(minor)等增量仍以行存组织;C 副本通过日志(clog)异步追平源副本并在本地回放。
不可构成 Paxos 成员组,它不作为 Paxos 成员参与日志的投票,而是作为一个观察者实时追赶 Paxos 成员的日志,并在本地回放,故不会造成投票成员增加导致事务提交延时的增加。
在业务对读取数据的一致性要求不高的时候可提供只读服务。
在同一个日志流上,用户表在 Major SSTable 层次以列存模式存储。
不能转换为其他副本类型。
更多特性及其说明如下表所示。
| 特性项 | 描述 |
|---|---|
| 副本名称及缩写 | COLUMNSTORE(C) |
| 是否有 LOG | 有,是异步日志,但不属于 Paxos 组,只是 Listener (ASYNC_CLOG) |
| 是否有 MemTable | 有(WITH_MEMSTORE) |
| 是否有 SSTable | 有(WITH_SSSTORE) |
| 数据安全 | 中 |
| 恢复为 Leader 的时间 | 不支持 |
| 资源成本 | 高 |
| 服务 | 可非一致性读 |
| 副本类型转换限制 | 不能转换为其他副本类型 |
C 副本上暂为行存的几种场景
在 OceanBase 数据库中,如果一张表在被创建时为行存表,则系统会在 C 副本上创建对应的纯列存表;如果一张表在被创建时为列存表,则在 C 副本上的存储方式将与 F 副本保持一致。故,对于 C 副本而言,仅负责将 F 副本上行存的用户表的用户分区转换为列存存储,且该描述仅表示 “最终” 状态为列存。在 C 副本上,并非任意时刻分区均表现为列存形式,在以下场景中, C 副本上的用户表分区会暂时为行存,需要系统自发调度行转列任务,将最新的基线数据转换为列存。
| 场景 | 描述 |
|---|---|
| 补副本(增加副本) | 以修改 Locality 使得 F@z1, F@z2 变更为 F@z1, F@z2, C@z3 为例:
|
| 日志流 Rebuild | 当触发 C 副本上日志流的 Rebuild 时,系统将会从源端拉取相应的基线到 C 副本。若基线数据为行存,则暂时为行存,待后台调度行转列任务后再转为列存。 |
| 补副本与 Offline DDL 并发场景 | 当 C 副本在日志流成员列表中时,若执行 Offline DDL,系统将会直接在 C 副本上构建列存基线。然而,当补副本与 Offline DDL 并发时,C 副本对执行 DDL 任务的日志流 Leader 不可见,此时系统在 C 副本上将会先构建出行存的基线,待后台调度行转列任务后再转为列存。 |
| 全量旁路导入 | 全量旁路导入当前仅支持先向 C 副本上导入行存,待后台调度行转列任务后转为列存。 |
| 表级恢复 | 由于当前列存表暂不支持表级恢复,因此 C 副本上的表级恢复仅支持先恢复为行存,待后台调度行转列任务后再转为列存。 |
上述场景下,在进行行存转列存的过程中,尽管当前优化器生成的是列存查询计划,但实际执行的仍然是对行存基线的查询。用户可以通过视图 CDB_OB_CS_REPLICA_STATS(系统租户)和 DBA_OB_CS_REPLICA_STATS(用户租户)来查询 C 副本的可用信息及行转列的进度,待行转列任务完全结束后,再进行 C 副本上的查询。
sys 租户下,查询所有租户 C 副本日志流中 Tablet 行转列进度的示例如下:
obclient[oceanbase]> SELECT * FROM oceanbase.CDB_OB_CS_REPLICA_STATS;
查询结果如下:
+-----------+----------------+----------+-------+------------------+----------------------+-----------------------+---------------------------+-----------+
| TENANT_ID | SVR_IP | SVR_PORT | LS_ID | TOTAL_TABLET_CNT | AVAILABLE_TABLET_CNT | TOTAL_MACRO_BLOCK_CNT | AVAILABLE_MACRO_BLOCK_CNT | AVAILABLE |
+-----------+----------------+----------+-------+------------------+----------------------+-----------------------+---------------------------+-----------+
| 1004 | xx.xxx.xxx.212 | 63000 | 1001 | 1019 | 1019 | 10706 | 10706 | TRUE |
| 1006 | xx.xxx.xxx.212 | 63000 | 1001 | 133 | 133 | 875 | 875 | TRUE |
+-----------+----------------+----------+-------+------------------+----------------------+-----------------------+---------------------------+-----------+
2 rows in set
从第一行查询结果可知,租户 ID 为 1004 的租户,其 C 副本所在的服务器为 xx.xxx.xxx.212,端口号为 63000; C 副本日志流的 ID 为 1001;当前需要转换为列存的分区总数为 1019,可用的分区总数为 1019;当前总的基线宏块数为 10706,可用的基线宏块数为 10706。用户可以通过 AVAILABLE_TABLET_CNT / TOTAL_TABLET_CNT 或者 AVAILABLE_MACRO_BLOCK_CNT /TOTAL_MACRO_BLOCK_CNT 来大致估算行转列的进度。仅当日志流上的所有 Tablet 均可用时,该日志流才完全可用。