---
title: 归档问题排查-OceanBase数据库使用指南
description: 了解OceanBase数据库在实际应用中关于 归档问题排查相关的常见问题和使用技巧，帮助您快速解决 归档问题排查的难题。
---
切换语言

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

划线反馈

# 归档问题排查

更新时间：2025-06-23 08:26

适用版本： V4.0.x 内容类型：TechNote  

此文档提供 OceanBase 数据库开启和关闭归档的流程，以及归档过程中可能涉及的内部表查询方法，帮助用户进行问题定位和排查。以下查询 SQL 以 SYS 租户执行。

## 开启或关闭归档

执行如下 SQL 为用户租户配置归档目的端。

```shell
obclient> alter system set log_archive_dest='LOCATION=file:///data/1';

```

执行如下 SQL 开启归档。

```shell
obclient> alter system archivelog;

```

**开启归档流程**

1. 用户执行 `alter system archivelog` 后，由 RS 添加一行记录到该表，并且设置初始 `status` 为 `PREPARE`。
 2. RS 在做初步检查等操作成功后，会将状态推到 `BEGINNING`。
 3. OBServer 通过监控该表状态为 `BEGINNING`或 `DOING` 感知到需要开启归档，会持续为日志流归档日志，并将日志流归档进度更新到另外一张日志流级别视图 `CDB_OB_LS_LOG_ARCHIVE_PROGRESS`，并标示状态为 `DOING`。
 4. RS 检测日志流状态表 `CDB_OB_LS` 以及 `CDB_OB_LS_LOG_ARCHIVE_PROGRESS` 表，当所有日志流归档状态都是 `DOING`，则 RS 将该表状态推到 `DOING`。
 5. RS 检测到 `CDB_OB_LS_LOG_ARCHIVE_PROGRESS` 中日志流归档状态为 `INTERRUPT`，会将租户级归档视图 `CDB_OB_ARCHIVELOG` 状态置为 `INTERRUPT`。

执行如下 SQL 关闭归档。

```shell
obclient> alter system noarchivelog;

```

**关闭归档流程**

1. 用户执行 `alter system noarchivelog`，首先 RS 将该行记录状态设置为 `STOPPING`。
 2. OBServer 检测到该表状态为 `STOPPING`，结束为日志流归档，并将 `__all_ls_log_archive_progress` 表已存在日志流的状态置为 `STOP`。
 3. RS 检查到 `CDB_OB_LS_LOG_ARCHIVE_PROGRESS` 表所有日志流归档状态都是 `STOP`，将该表归档状态置为 `STOP`。

## 内部表

问题排查涉及到内部表都是普通租户对应 meta 租户下的内部表。

### CDB_OB_ARCHIVE_DEST

该表保存归档路径，也是可以发起归档的前置条件。如果该表为空，则该租户无法归档。

查询示例如下：

```shell
obclient> select * from CDB_OB_ARCHIVE_DEST where tenant_id = 100X;
+-----------+---------+-----------------------+--------------------------------------------------------+
| TENANT_ID | DEST_NO | NAME                  | VALUE                                                  |
+-----------+---------+-----------------------+--------------------------------------------------------+
|      1002 |       0 | binding               | OPTIONAL                                               |
|      1002 |       0 | dest_id               | 1002                                                   |
|      1002 |       0 | lag_target            | 1d                                                     |
|      1002 |       0 | path                  | file:///data/1/shuning//ob_backup_mysql_tenant/archive |
|      1002 |       0 | piece_switch_interval | 1d                                                     |
|      1002 |       0 | state                 | ENABLE                                                 |
+-----------+---------+-----------------------+--------------------------------------------------------+

```

### CDB_OB_ARCHIVELOG

该表为租户级归档进度表。

查询示例如下：

```shell
obclient> select * from oceanbase.CDB_OB_ARCHIVELOG where tenant_id = 1002\G;
*************************** 1. row ***************************
                   TENANT_ID: 1002
                     DEST_ID: 1001
                    ROUND_ID: 1
                 INCARNATION: 1
                     DEST_NO: 0
                      STATUS: STOP
                   START_SCN: 1706670992366131000
           START_SCN_DISPLAY: 2024-01-31 11:16:32.366131
              CHECKPOINT_SCN: 1706682875884361003
      CHECKPOINT_SCN_DISPLAY: 2024-01-31 14:34:35.884361
                  COMPATIBLE: 1
               BASE_PIECE_ID: 1
               USED_PIECE_ID: 1
       PIECE_SWITCH_INTERVAL: 86400000000
                   UNIT_SIZE: 1
                 COMPRESSION: none
                 INPUT_BYTES: 85090352
         INPUT_BYTES_DISPLAY: 81.15MB
                OUTPUT_BYTES: 85090352
        OUTPUT_BYTES_DISPLAY: 81.15MB
           COMPRESSION_RATIO: 1.00
         DELETED_INPUT_BYTES: 0
 DELETED_INPUT_BYTES_DISPLAY: 0.00MB
        DELETED_OUTPUT_BYTES: 0
DELETED_OUTPUT_BYTES_DISPLAY: 0.00MB
                     COMMENT:
                        PATH: file:///home/admin/mwxarvg
1 row in set (0.041 sec)

```

其中:

- `status` 表示该租户归档状态，包括正常状态 `PREPARE`、`BEGINNING`、`DOING`、`STOPPING`、`STOP` 以及异常状态 `INTERRUPT`。
 - `start_scn` 为租户归档起始时间，普通租户下所有日志流 `log_scn` 大于等于该值的日志都需要被归档出去。
 - `checkpoint_scn` 为租户归档进度，为所有日志流归档进度的最小值。

### CDB_OB_LS_LOG_ARCHIVE_PROGRESS

该表为日志流级别归档进度表，开启归档后，每个日志流每个 piece 一行记录，其中状态包括正常 `DOING`、`STOP` 以及异常状态 `INTERRUPT`。

查询示例如下：

```shell
obclient [oceanbase]> select * from oceanbase.CDB_OB_LS_LOG_ARCHIVE_PROGRESS where tenant_id = 1002\G;
*************************** 1. row ***************************
     TENANT_ID: 1002
       DEST_ID: 1001
         LS_ID: 1
      ROUND_ID: 1
      PIECE_ID: 1
   INCARNATION: 1
     START_SCN: 1706670992366131000
       MIN_LSN: 3086819328
       MAX_LSN: 3113961131
CHECKPOINT_SCN: 1706682875884361003
        STATUS: STOP
       FILE_ID: 47
   FILE_OFFSET: 27141803
   INPUT_BYTES: 27141803
  OUTPUT_BYTES: 27141803

```

其中：

- `start_scn` : 表示日志流该 piece 下已归档最小日志的 `log_scn`，其中第一个 piece 比较特殊，是租户归档起始时间。
 - `max_lsn` : 表示日志流该 piece 下已归档日志最大 `lsn`。
 - `checkpoint_scn` :表示该日志流该 piece 下已归档日志最大 `log_scn`。
 - `file_id` 或 `file_offset` :表示归档介质上该日志流该 piece 下最大归档文件编号以及文件内偏移。
 - piece：由于 clog 需要源源不断归档到存储介质并需要长时间保存，因此无法像 clog 文件一样平铺在一级目录下，而 piece 即按照时间维度做的归档日志文件的切片，一个 piece 包含一段时间的日志。

在 `__all_ls_log_archive_progress` 中，每个 piece（通常为一天）一行记录，当更大 `piece_id` 的记录产生，旧的 piece 行记录不再修改。（例外，当关闭归档时，所有 piece 状态变为 `STOP`）。

```shell
obclient> select * from CDB_OB_LS_LOG_ARCHIVE_PROGRESS where piece_id = 2;
+-----------+---------+-------+----------+----------+-------------+---------------------+---------+----------+---------------------+--------+---------+-------------+-------------+--------------+
| TENANT_ID | DEST_ID | LS_ID | ROUND_ID | PIECE_ID | INCARNATION | START_SCN           | MIN_LSN | MAX_LSN  | CHECKPOINT_SCN      | STATUS | FILE_ID | FILE_OFFSET | INPUT_BYTES | OUTPUT_BYTES |
+-----------+---------+-------+----------+----------+-------------+---------------------+---------+----------+---------------------+--------+---------+-------------+-------------+--------------+
|      1002 |    1002 |     1 |        1 |        2 |           1 | 1691115152597490000 | 9693359 | 10186648 | 1691115272257855453 | DOING  |       1 |      493289 |      493289 |       493289 |
|      1002 |    1002 |  1001 |        1 |        2 |           1 | 1691115152597490000 |  151094 |   294108 | 1691115272257855453 | DOING  |       1 |      143014 |      143014 |       143014 |
+-----------+---------+-------+----------+----------+-------------+---------------------+---------+----------+---------------------+--------+---------+-------------+-------------+--------------+

```

### __all_virtual_archive_stat

日志流级别归档状态虚拟表，展示归档各个模块实时进度。其中 `max_issued_log_lsn` 为下文中 `sequencer` 模块进度(已产生读取日志任务 LSN)，`max_prepared_lsn` 为 `fetcher` 模块进度(已读取日志最大 LSN)，`archive_lsn` 为 `sender` 模块进度(已归档到介质日志最大 LSN)。

```shell
obclient> select * from __all_virtual_archive_stat \G
*************************** 1. row ***************************
            tenant_id: 1002
                ls_id: 1
               svr_ip: 100.83.xx.xxx
             svr_port: 42924
              dest_id: 1002
          incarnation: 1
             round_id: 1
            dest_type: Location
           dest_value: DefaultDestLocation
             lease_id: 0
      round_start_scn: 1691115032597490972
   max_issued_log_lsn: 738152448
    issued_task_count: 1
     issued_task_size: 28944113
max_prepared_piece_id: 3731
     max_prepared_lsn: 709208335
     max_prepared_scn: 1691562735282634001
 wait_send_task_count: 0
     archive_piece_id: 3731
          archive_lsn: 709208335
          archive_scn: 1691562735282634001
      archive_file_id: 11
  archive_file_offset: 156828

```

## OBServer 开启归档

1. 当 OBServer 周期性刷新 `__all_log_archive_progress` 表，感知到 RS 已经进入 `BEGINNING` 或 `DOING` 状态，会进入归档状态，这由 `ObArchiveService` 线程执行。

   通过 OBServer 日志监测归档是否成功开启：

   开启关闭或归档由普通租户 `ObArchiveService` 线程执行，比如 `T1002_ArcSrv`。

   ```shell
   grep “T1002_ArcSrv” observer.log

   ```

   以下皆为该线程关键日志打印。

      - 检查 OBServer 是否需要开启或关闭归档。

       ```shell
       grep "check_if_need_switch_log_archive_" observer.log

       ```
      - 检查是否将归档信息设置到本机。

       ```shell
       grep "set log archive info succ" observer.log

       ```
      - 检查开启归档是否成功。

       ```shell
       grep "start archive succ" observer.log

       ```
      - 检查关闭归档是否完成。

       ```shell
       grep "switch log archive status from in_stopping to stopped succ" observer.log

       ```
 2. 当 OBServer 进入归档状态，会为本机 `palf role` 为 LEADER 的日志流开启归档。开启归档是指确认日志流在本机上归档的起点，并添加日志流到归档管理任务中。确定归档起点包括该日志流第一次开启归档，也可能是开启归档后切主继续归档。

   #### 说明

   如果是第一次开启归档，从 palf 定位第一条大于等于归档起点的日志作为开启归档的起点。  
    如果是切主后继续归档，会从 `__all_ls_log_archive_progress` 表获取最新归档进度作为继续归档的起点。 可以查询虚拟表 `__all_virtual_archive_stat`，或者 `grep` 日志 `add ls archive task succ` 检查该日志流开启归档的起点。

   下述的日志搜索需要以租户前缀过滤，如 `T1002_Arc`，以下省略该过滤。

      - 检查日志流开启归档成功。

       ```shell
       grep "add ls archive task succ" observer.log

       ```
      - 查看第一次开启归档起点。

       ```shell
       grep "locate_round_start_archive_point_ succ" observer.log

       ```
      - 继续开启归档。

       ```shell
       grep "fetch exist archive progress succ" observer.log

       ```
 3. sequencer 模块为所有本 OBServer 服务日志流定序。

      - 产生归档调度任务。

       ```shell
       grep "generate log fetch task succ" observer.log

       ```
      - 提交读取日志任务

       ```shell
       grep "submit log fetch task succ" observer.log

       ```
 4. fetcher 支持并行读取日志。

   具体流程如下：

      1. 获取读取任务并进行处理。

             - 如果没有读取日志任务，会周期性打印日志，可以通过如下命令查询相关日志。（该日志为 TRACE 级别日志）

              ```shell
              grep "no task exist, just skip" observer.log

              ```
             - 日志读取任务需要 delay 处理, 比如没有聚合足够大小的块，可以通过如下命令查询相关日志。

              ```shell
              grep "need delay" observer.log

              ```
      2. 初始化日志迭代器以及 helper。

             - 执行如下命令，查询是否初始化成功。

              ```shell
              grep "init helper succ" observer.log

              ```
      3. 开始迭代读取日志。
      4. 将任务 push 到 LSArchiveTask 并排序。

             - 读取日志成功后会打印相关日志，可以通过如下命令查询。

              ```shell
              grep "append log entry succ" observer.log

              ```
             - 处理读取日志任务成功后会打印相关日志，可以通过如下命令查询。

              ```shell
              grep "handle log fetch task succ" observer.log

              ```
             - 将日志块提交排序成功后会打印相关日志，可以通过如下命令查询。

              ```shell
              grep "push fetch log succ" observer.log

              ```
             - 提交排序后的日志块成功后会打印相关日志，可以通过如下命令查询。

              ```shell
              grep "try consume task status succ" observer.log

              ```
      5. 顺序将日志提交到 sender 模块。

             - 提交 send task 任务成功后会打印相关日志，可以通过如下命令查询。

              ```shell
              grep "push succ" observer.log | grep sender

              ```
 5. sender 归档日志。

   如果归档介质有问题，会报错并打印相关日志，可以通过如下命令查询。

   ```shell
   grep "push log failed" observer.log

   ```

   创建归档目录成功，仅在目录不存在时创建。

   ```shell
   grep "archive dir make succ" observer.log

   ```

## 归档进度持久化

`ObArchiveService` 线程会周期性将归档进度持久化到内部表 `__all_ls_log_archive_progress` 表，如果虚拟表归档进度更新正常，而持久化到该表进度卡住，则可以查看日志分析。

查看持久化相关日志。

```shell
grep ob_archive_persist_mgr.cpp observer.log

```

根据 `ObArchiveService` 线程 `grep` 日志。

```shell
grep "T1002_ArcSrv" observer.log

```

## 日志流开启归档

第一次开启归档或者切主，都会为 LEADER 日志流开启归档，当遇到某个日志流没有归档任务或者落后，可以按照如下排查：

1. 确认日志流是否有主。

   ```shell
   select * from oceanbase.__all_virtual_log_stat where tenant_id = 1002 and ls_id = 1001;

   ```
 2. 根据虚拟表确认日志流是否在做归档。

   ```shell
   select * from oceanbase.__all_virtual_archive_stat where tenant_id = 1002 and ls_id = 1001;

   ```
 3. 如果没有归档任务，找到 leader 所在 OBServer，`grep` 日志。

   ```shell
   grep "ob_start_archive_helper.cpp" observer.log

   ```

## 切 piece

归档按照 piece 组织目录，切 piece 是很关键也容易出现问题的地方。

1. 关键日志，关键字 `ARCHIVE`，日志 observer.log。

   ```sql
   # fetcher 关键日志
   # 发现新piece

     "set next piece succ"

   # sender 关键日志
   # 前一个 piece 持久化进度未刷新到本地，需要等待本地进度更新成功

     "pre piece archive progress not persist, just wait"

   # 前一个 piece 最大进度未持久化成功，需要等待。

     "persist lsn not equal with send task"

   # 补偿空 piece

     "persist lsn equal with send task and gap of persist piece id"

   ```
 2. 基本流程

      1. fetcher 消费日志，发现并产生新 piece，并结束旧 piece。
      2. sender 模块归档日志，当发现新 piece，1) 等旧的 piece 最大归档进度持久化到内部表成功，并刷新到本地；2) 如果发现 piece id 不连续，会补空 piece。
      3. sender 模块发现旧 piece 归档进度已经持久化成功，则开始归档新 piece 所属日志。
      4. 新的 piece 的进度更新到 `__all_ls_log_archive_progress` 表。
      5. rs 监控 `__all_ls_log_archive_progress` 表，并发现新 piece，更新租户级 piece 进度。

## 归档断流

归档断流，即归档状态为 `INTERRUPT` 状态，按照以下方式排查：

1. 查询断流时间以及可能得原因：

   ```sql
   select * from __all_server_event_history where event like 'mark_fatal_error' order by gmt_create desc limit 30;

   ```

如图是由于未归档完成 CLOG 已回收导致：

![image01.png](https://obbusiness-private.oss-cn-shanghai.aliyuncs.com/doc/img/knowledge-base/database/sql/20240819restore001.png)

该记录的生成时间是断流时间，`svr_ip` 或 `port` 是断流 OBServer，查询断流附近日志。找到导致断流的线程日志上下文，大致可以了解是何原因导致的断流。

```sql
grep TXXXX_Arc observer.log

```

如图是某个归档到 OSS 环境 observer 日志信息：

![image02.png](https://obbusiness-private.oss-cn-shanghai.aliyuncs.com/doc/img/knowledge-base/database/sql/20240819restore002.png)

其中 `statistic` 信息展示了归档 Sender 现场一些统计，比如单个 IO 耗时 17s，带宽仅 1.9M/s 等。 根据这些指标评估断流是不是因为归档速度跟不上 clog 写入速度。

## 典型问题

### NFS hang

如果归档介质是 NFS，Docker 环境挂载 NFS 容易遇到 hang 的问题。NFS hang 直接表现为某个日志流或者全部日志流归档进度**不推或者断流**。在所有 OBServer 节点执行以下命令查看是否 hang。

```sql
cat /proc/`pidof observer`/task/*/stack|grep nfs

```

### 归档盘满

归档盘满体现为租户以及所有日志流归档进度**不推或者断流**。在租户日志流 leader 节点 `grep` 如下日志：

```sql
grep Txxxx_ArcSend observer.log | less

```

如果已经断流，则选择断流前附近一段日志，如果当前是卡住，可以看最新的几个 OBServer 日志文件。`grep` 如下日志，可以看到明显如下报错 `**Disk quota exceeded**`：

```sql
observer.log.20230927031011904:[2023-09-27 03:09:50.879969] WDIAG [STORAGE] pwrite (ob_storage_file.cpp:747) [130479][T1002_ArcSender][T1002][xxxxx-xxxxx-xxxxx-xxxxx] [lt=10][errcode=-4009] failed to write file(ret=-4009, one_write_size=-1, errno=122, path_=/archive/piece_d1001r1p1/logstream_1/log/1.obarc, errno_str="Disk quota exceeded"

```

上一篇

[停止归档后归档卡在 stopping 状态](https://www.oceanbase.com/knowledge-base/oceanbase-database-1000000000089873)

下一篇

[强关归档场景下物理恢复卡住](https://www.oceanbase.com/knowledge-base/oceanbase-database-1000000001427077) ![有帮助](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) 咨询热线
