---
title: "转储和合并 | OceanBase 文档中心"
description: 转储和合并 转储 转储包含三个过程：Mini Compaction、Mini Minor Compaction 和 Minor Compaction。 Mini Compaction 当 MemTable 的大小超过一定的阈值时，需要将 MemTable 中的数据转存到 Mini SSTable 中以释放内存，该过程…
---
切换语言

- 中文站 - 简体中文
- International - English
- 日本站 - 日本語

文档反馈![](https://mdn.alipayobjects.com/huamei_22khvb/afts/img/A*P8CuR4UJ_FkAAAAAAAAAAAAADiGDAQ/original) OceanBase 数据库分布式版 - V 3.2.1 企业版

# 转储和合并

更新时间：2025-07-17 16:37:33

## 转储

转储包含三个过程：Mini Compaction、Mini Minor Compaction 和 Minor Compaction。

### Mini Compaction

当 MemTable 的大小超过一定的阈值时，需要将 MemTable 中的数据转存到 Mini SSTable 中以释放内存，该过程称为 Mini Compaction。

Mini Compaction 的核心就是释放内存和数据日志。内存中的 Frozen MemTable 通过 Mini Compaction 变成磁盘上的 Mini SSTable，是数据日志的一个 checkpoint。Mini Compaction 结束后，其对应的 Frozen MemTable 和 Log 可以被释放。

### Mini Minor Compaction

随着用户数据的写入，Mini SSTable 的数量会逐渐增多，在查询时需要访问的 Mini SSTable 数量就会增多，会影响查询的性能。Mini Minor Compaction 就是将多个 Mini SSTable 合成一个 Mini SSTable，其主要目的是减少 Mini SSTable 的数量。

![L0-L0](https://obbusiness-private.oss-cn-shanghai.aliyuncs.com/doc/img/observer-enterprise/V4.2.1/600.manage/L0TOL0.png)

### Minor Compaction

随着 Mini SSTable 的数量越来越多，当 Mini SSTable 的数量超过阈值时，后台会自动触发 Minor Compaction，将若干个 Mini SSTable 与 Minor SSTable 合成一个新的 Minor SSTable。

![L0-L1](https://obbusiness-private.oss-cn-shanghai.aliyuncs.com/doc/img/observer-enterprise/V4.2.1/600.manage/L0TOL1.png)

## 转储触发

转储有两种触发方式：自动触发与手动触发。

当一个租户的 MemTable 内存的使用量达到 `memstore_limit_percentage * freeze_trigger_percentage` 所限制使用的值时，就会自动触发冻结（转储的前置动作），然后系统内部会再调度转储。

您也通过以下的运维命令手动触发转储。

```sql
ALTER SYSTEM MINOR FREEZE [zone] | [server_list] | [tenant_list] | [replica]

tenant_list:
    TENANT [=] (tenant_name_list)

tenant_name_list:
    tenant_name [, tenant_name ...]

replica:
    PARTITION_ID [=] 'partition_idx%partition_count@table_id'

server_list:
    SERVER [=] ip_port_list

```

示例：

- 集群级别转储

  ```sql
  obclient> ALTER SYSTEM MINOR FREEZE;

  ```
 - Server 级别转储

  ```sql
  obclient> ALTER SYSTEM MINOR FREEZE SERVER='10.10.10.1:2882';

  ```
 - 租户级别转储

  ```sql
  obclient> ALTER SYSTEM MINOR FREEZE TENANT=('prod_tenant');

  ```
 - Replica 级别转储

  ```sql
  obclient> ALTER SYSTEM MINOR FREEZE ALTER PARTITION_ID = '8%1@1099511627933';

  ```

需要注意的是，尽管允许只针对单个分区手动触发 Minor Freeze，但由于多个不同的分区可能共用相同的内存块，因此对单个分区的 Minor Freeze 可能并不能有效地释放内存，而针对租户的 Minor Freeze 可以有效地释放对应租户 MemTable 的内存。

## 合并

合并操作（Major Compaction）是将动静态数据做归并，会比较费时。当转储产生的增量数据积累到一定程度时，通过 Major Freeze 实现合并。

转储和合并的最大区别在于，合并是集群上所有的分区在一个统一的快照点和全局静态数据进行合并的行为，是一个全局的操作，最终形成一个全局快照。

转储和合并的对比如下表所示：

| 转储（Mini Compaction） | 转储（Mini Minor Compaction） | 转储（Minor Compaction） | 合并（Major Compaction） |
| --- | --- | --- | --- |
| 分区或租户级别，只是 MemTable 的物化 | 分区级别 | 分区级别 | 全局级别，产生一个全局快照。 |
| 每个 OBServer 节点的每个租户独立决定自己 MemTable 的冻结操作，主备分区不保持一致 | 每个分区根据当前 Mini SSTable 的数量来执行分区内的 Mini Minor Compaction | 每个分区根据当前 Minor SSTable 的数量来执行分区内的 Minor Compaction | 全局分区一起做 MemTable 的冻结操作，要求主备 Partition 保持一致，在合并时会对数据进行一致性校验。 |
| 可能包含多个不同版本的数据行 | 可能包含多个不同版本的数据行 | 可能包含多个不同版本的数据行 | 只包含快照点的版本行 |
| 将一个或多个 MemTable 持久化为 Mini SSTable | 将多个 Mini SSTable 合成一个 Mini SSTable。仅包含增量数据，最终被删除的行需要特殊标记。 | 将多个 Mini SSTable 与一个 Minor SSTable 合并产生一个新的 Minor SSTable，仅包含增量数据，最终被删除的行需要特殊标记。 | 合并会把当前大版本的 SSTable 和 MemTable 与前一个大版本的全量静态数据进行合并，产生新的全量数据。 |

合并有很多种不同的方式，具体的描述如下。

**全量合并**

全量合并是 OceanBase 数据库的一种合并算法，和 HBase 与 Rocksdb 的 Major Compaction 过程是类似的。顾名思义，在全量合并过程中，会把当前的基线数据都读取出来，和增量数据合并后，再写到磁盘上去作为新的基线数据。在这个过程中，会把所有数据都重写一遍。全量合并会极大的耗费磁盘 IO 和空间，如非必要或者 DBA 强制指定，OceanBase 数据库一般不会主动做全量合并。

OceanBase 数据库发起的全量合并一般发生在列类型修改等 DDL 操作之后。DDL 变更是实时生效的，不阻塞读写，也不会影响到多副本间的 Paxos 同步，将对存储数据的变更延后到合并的时候来做，这时就需要将所有数据重写一遍。

**增量合并**

增量合并是相对于全量合并而言的概念，同样是 OceanBase 数据库的一种合并算法。大多数情况下，当需要进行合并时并不是所有的宏块都需要被修改，当一个宏块没有增量修改时，直接重用它，而不是重写它，这种方式称之为增量合并。相对于全量合并的把所有的宏块的重写一遍而言，增量合并只重写发生了修改的宏块。增量合并极大地减少了合并的工作量，也是 OceanBase 数据库目前默认的合并算法。

更进一步地，对于宏块内部的微块，很多情况下也并不是所有的微块都会被修改。当发现宏块有行被修改过时，在处理每一个微块时，会先判断这个微块是否有行被修改过，如果没有，只需要把这个微块的数据直接拷贝到新的宏块上，这样没被修改过的微块就省去了解析行、选择编码规则、对行进行编码以及计算列 Checksum 等操作。微块级增量合并进一步减少了合并的时间。

**渐进合并**

在执行某些 DDL 操作时，例如执行表的加列、减列、修改压缩算法等操作后，可能需要将数据重写一遍。OceanBase 数据库并不会立即对数据执行重写操作，而是将重写动作延迟到合并时进行。基于增量合并的方式，无法完成对未修改数据的重写，为此 OceanBase 数据库引入了"渐进合并"，即把数据的重写分散到多次合并中去做，在一次合并中只进行部分数据的重写。

通过以下命令可以控制一张表的渐进轮次：

```sql
ALTER TABLE [table_name] SET progressive_merge_num=?

```

例如：

```sql
obclient> ALTER TABLE mytest SET progressive_merge_num=60;

```

将表 `mytest` 的渐进轮次设置为 `60`，当执行加列或减列操作后的 60 次合并过程中，每一次合并会重写 60 分之一的数据，在 60 轮合并过后，数据就被整体重写了一遍。

当未对表的 `progressive_merge_num` 进行设置时，其默认值为 `0`，目前语义为在执行需要重写数据的 DDL 操作之后，做渐进轮次为 100 的渐进合并。当表的 `progressive_merge_num` 被设置为 1 时，表示强制走全量合并。

**轮转合并**

一般来说合并会在业务低峰期进行，但并不是所有业务都有业务低峰期。在合并期间，会消耗比较多的 CPU 和 IO，此时如果有大量业务请求，势必会对业务造成影响。为了规避合并对业务的影响。借助 OceanBase 数据库的多副本分布式架构，引入了轮转合并的机制。

一般配置下，OceanBase 数据库会同时有 3 个数据副本，当一个数据副本在进行合并时，可以将这个副本上的查询流量切到其他没在合并的副本上面，这样业务的查询就不受每日合并的影响。等这个副本合并完成后，再将查询流量切回来，继续做其他副本的合并，这一机制称之为轮转合并。

为了避免流量切过去后，Cache 较冷造成的 RT 波动，在流量切换之前，OceanBase 数据库还会做 Cache 的预热，通过参数可以控制预热的时间。

**合并触发**

合并触发有三种触发方式：自动触发、定时触发与手动触发。

- 当集群中任一租户的 Minor Freeze 次数超过 `minor_freeze_times` 指定的阈值时，就会自动触发整个集群的合并。
 - 也可以通过设置参数来在每天的业务低峰期定时触发合并。

  ```sql
  obclient> ALTER SYSTEM SET major_freeze_duty_time = '02:00';

  ```
 - 也通过以下的运维命令手动触发合并。

  ```sql
  obclient> ALTER SYSTEM MAJOR FREEZE;

  ```

 上一篇 下一篇 ![有帮助](https://gw.alipayobjects.com/mdn/ob_asset/afts/img/A*y6ocSqN8cqsAAAAAAAAAAAAAARQnAQ)![无帮助](https://gw.alipayobjects.com/mdn/ob_asset/afts/img/A*BG9IQJyLHF8AAAAAAAAAAAAAARQnAQ)![反馈](https://gw.alipayobjects.com/mdn/ob_asset/afts/img/A*eTWdQKCRKHwAAAAAAAAAAAAAARQnAQ)[AI](https://www.oceanbase.com/obi) 咨询热线
