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

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

划线反馈

# 迁移复制问题排查

更新时间：2024-07-23 05:41

适用版本： V2.1.x、V2.2.x、V3.1.x、V3.2.x 内容类型：Troubleshoot  

## 背景

通过以下手段，我们可以主动触发副本的迁移、复制、删除、类型变换等行为。

- admin 命令：`alter system change/drop/add/migrate` 命令。
 - locality 变更：支持 tenant/table/tablegroup 级别的 locality 变更。
 - unit 迁移：`alter system migrate unit` 命令。
 - delete server：主要是后台发起 unit 迁移操作。

通过相关命令会异步触发后台的相关 partition 的任务，下面给出相关 partition 任务执行问题的执行思路。

## 相关配置项

以下是控制迁移复制速度的相关配置项，可视实际情况进行调节。

| 参数 | 默认值 | 解释 |
| --- | --- | --- |
| data_disk_usage_limit_percentage | 90 | 允许迁入副本或者迁入 unit 的磁盘水位最大值，如果超过这个值，加副本或者迁移 unit 任务就会暂停，`__all_server` 表的那个 server 的 `block_migrate_in_time`会大于 0。 |
| migration_disable_time | 3600 | RS 在因为磁盘水位高暂停任务后重试任务的时间间隔，如果遇到 `data_disk_usage_limit_percentage` 过低需要调大的情况，那么调大 `data_disk_usage_limit_percentage`后，如果想 RS 尽快调度复制迁移，需要调小此值。 |
| sys_bkgd_net_percentage | 60 | 复制或者迁移使用本机带宽的百分比，如果本机是万兆，那么最多使用10000MB * 60%，如果是千兆，那么最多使用 1000MB * 60%。 |
| balancer_idle_time | 5m | 控制 RS 负载均衡任务调度间隔。 |
| server_data_copy_in_concurrency | 2 | 表示单个 OBServer，作为目标端(包括复制，迁移，类型转换的目标端)同时执行的任务数，主要是在 RS 端限流。 |
| server_data_copy_out_concurrency | 2 | 表示单个 OBServer，作为源端(包括复制，迁移，类型转换的源端)同时执行的任务数，主要是在 RS 端限流。 |
| data_copy_concurrency | 20 | 表示集群中同时执行的任务(包括复制，迁移，类型转换)的上限，主要是在 RS 端限流。 |
| server_permanent_offline_time | 3600s | 表示该机器上面的副本永久下线时间，时间未到的话，unit 迁移不了。 |
| migrate_concurrency | 10 | |
| enable_rebalance | true | 负载均衡开关，部分版本部分操作依赖该开关打开。 |
| enable_rereplication | true | 补副本开关，部分版本部分操作依赖该开关打开。 |
| __balance_controller | "" | 用于精细化控制 RS 负载均衡行为，一般为空。非空场合部分负载均衡会不运行   #### 注意    该配置项一旦打开，除配置项显示指定的负载均衡操作外，其余负载均衡操作一概无法发起。运维修改该配置项时，在相关运维操作结束后记得将该配置项重置为空。 |
| enable_auto_leader_switch | true | leader 均衡开关。 |

## 相关内部表

| 表名称 | 说明 |
| --- | --- |
| __all_server | 关注 `block_migrate_in_time`，如果大于 0 证明副本迁入已经卡住，需要释放空间或者调大 `data_disk_usage_limit_percentage`。关注 `status`、`start_service_time`：`status` 非 `active`，或者 `start_service_time`为 0，需要重点关注。 |
| __all_tenant | 关注 `primary_zone`、`locality`、`previous_locality`。若 `previous_locality`有值，说明当前的 `locality` 变更操作为`previous_locality->locality`。 |
| gv$unit / __all_unit | `gv$unit`可以看某个租户的 unit 分布。`__all_unit`可确认集群是否有 unit 迁移任务（`migrate_from_svr_ip`、`migrate_from_svr_port` 有值）。 |
| __all_rootservice_job | 记录迁移 unit、变 locality 等单条 SQL 对应的任务状态。 |
| __all_rootservice_event_history | RS 负载均衡任务基本上都会记录相关事件（可能缺失），可以看到相关负载均衡任务发起的时间及结果。 |
| __all_virtual_replica_task | RS 视图，该表有值说明需要发起相关 partition 副本的 `add`、`drop`、`type_transform`操作。缺副本、locality 变更场景可以查看待发起、完成的相关负载均衡任务。 |
| __all_virtual_rebalance_task_stat | 这个是 RS 的虚拟表，表示集群中当前已经生成的所有任务(复制，迁移，类型转换)。该表有一列 `is_scheduled`，`is_scheduled=Yes`表示任务已经下发到 OBServer 开始执行，`is_scheduled=No`表示任务还没有被下发到 OBServer 执行。 |
| __all_virtual_sys_task_status | 这个是 OBServer 的虚拟表，内容是已经下发到 OBServer 端执行的任务。 |

## 排查思路

负载均衡任务的通用排查思路大致有以下三步：

1. **确认配置项**。
      1. 需关注非缺省的配置项取值。
      2. 确认负载均衡逻辑相关开关是否打开：`enable_rebalance`、`enable_rereplication`、`__balance_controller`、`enable_auto_leader_switch`。
 2. **确认内部表**。
      1. 看集群分布、机器状态：`__all_server`、`__all_tenant`、`gv$unit`/`__all_unit`。
      2. 确定负载均衡任务类型：`__all_rootservice_job`。
      3. 确定分区是否无主（无主无法发起部分负载均衡任务）：`__all_virtual_partition_table`。
      4. 确定分区分布（是否缺副本、多副本）：`__all_replica_task`。
      5. 确定是否有正在执行的负载均衡任务（同一个分区只能有一个负载均衡任务）：`__all_rootservice_event_history`。
      6. 确定负载均衡任务是否调度：`__all_virtual_rebalance_task_stat`、`__all_virtual_sys_task_status`。
      7. 确定负载均衡任务结果：`__all_rootservice_event_history`。
 3. **看日志**。
      1. 排查 RS 没调度负载均衡的原因：`grep "balancer" rootservice.log` 并按线程号展开。
      2. 排查具体负载均衡任务执行报错的原因：按 pkey、错误码 `grep observer.log`。

### 确定问题 partition

无论是通过何种方式发起的负载均衡任务，如果怀疑有问题的话，需要先定位到有问题的 partition。根据不同的场景，我们通过不同的方式获取有问题的 partition。

#### Unit 迁移

执行如下命名查看当前是否有 unit 迁移任务，非空表示有。

```shell
select * from __all_unit where migrate_from_svr_ip != "" or migrate_from_svr_port != "";

```

```shell
select * from __all_virtual_partition_table where unit_id = xxx and svr_ip = "yyy";

```

- `unit_id` 填上条查询的 `unit_id`，以获取待迁移的 partition key。
 - `svr_ip` 填上条查询的 `migrate_from_svr_ip`。

#### Delete Server

执行如下命令查看 server 是否下线。非空表示server没有下线完成。

```shell
select * from __all_server where svr_ip = "xxx" and svr_port = yyy;

```

执行如下命令以获取待下线的 partition key。`svr_ip`/`svr_port`填上述 server 地址。

```shell
select * from __all_virtual_partition_table where svr_ip = "xxx" and svr_port = yyy;

```

#### Admin 命令

admin 命令通常需要显式指定 partition key，partition key 格式形如 `partition_id%partition_cnt@table_id`。

#### Locality 变更

执行如下命令，非空表示对应租户正在做 locality 变更。

```shell
select tenant_id, tenant_name, locality, previous_locality from __all_tenant where previous_locality != "";

```

执行如下命令获取需要增、删、类型转换的分区负载均衡任务。

```shell
select * from __all_virtual_replica_task where tenant_id = xxx;

```

#### 补副本

集群缺副本的时候，RS 会发起补副本操作，一个通用的检查租户副本分布和 locality 是否匹配的语句如下所示。

```shell
select * from __all_virtual_replica_task where tenant_id = xxx;
- cmd_type一般有以下几种可能的取值：
  - ADD_REPLICA：需要补副本。
  - MEMBER_CHANGE：需要将paxos成员移除。
  - REMOVE_NON_PAXOS_REPLICA：需要删除副本。
  - TYPE_TRANSFORM：需要发起副本类型转换任务。

```

### 查看 RS 任务调度状态

#### 查看 job 状态

外部发起的命令都会记录到 `__all_rootservice_job`中，可先确认任务是否发起及相关状态（该表状态可能不准）。

```shell
select * from __all_rootservice_job order by gmt_create desc limit 10;

```

#### 确认任务被调度或排队中

```shell
select * from __all_virtual_rebalance_task_stat;

```

`is_scheduled` : `yes` 表示任务正在调度，否则表示在排队。

若没看到负载均衡队列有任务，可以看相关配置项是否设置合理，及联系技术支持排查未调度的原因。

#### 确认负载均衡任务执行情况

执行如下语句定位到具体的分区负载均衡任务获得 `table_id`或 `partition_id`。

```shell
select * from __all_rootservice_event_history where value1 like "%table_id%partition_id%" order by gmt_create desc limit 10;

```

如下图所示，表示某个分区迁移失败报 -4029：

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

一般 `event` 表里有明确报错的，可以按 pkey、错误码搜 `source`、`destination` 机器对应时间点的 observer.log 或 rootservice.log，以获取更详细的报错信息。

终极的手段是去 RS 所在机器 `grep "root_balancer" rootservice.log` 拿到线程号 `LWP_ID` 后，`grep "LWP_ID" rootservice.log` 看 RS 的负载均衡线程正在做什么。

### 查看存储层调度状态

#### 查看 OBServer 任务调度状态

```shell
select * from __all_virtual_sys_task_status;
+----------------------------+---------------------------+-------------------------------+---------------+----------+-----------+---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+-----------+
| start_time                 | task_type                 | task_id                       | svr_ip        | svr_port | tenant_id | comment                                                                                                                                                                                                                                     | is_cancel |
+----------------------------+---------------------------+-------------------------------+---------------+----------+-----------+---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+-----------+
| 2019-03-01 00:01:01.710589 | group partition migration | YB420BE80B86-00057350CB72EC9F | 11.xxx.xxx.xx |     2882 |      1040 | group partition migration: group_task_id=YB420BE80B86-00057350CB72EC9F partition_count=1 partition_id=0 key={tid:1143492092937043, partition_id:0, part_cnt:0}, op_type=ADD_REPLICA_OP, src="11.xxx.xx.xx:2882", dest="11.xxx.xxx.xx:2882", |         0 |
| 2019-03-01 00:01:01.716896 | partition migration       | YB420BBEE129-000582EC67B0BBB5 | 11.xxx.xxx.xx |     2882 |      1040 | single partition migration: group_task_id=YB420BE80B86-00057350CB72EC9F key={tid:1143492092937043, partition_id:0, part_cnt:0}, op_type=ADD_REPLICA_OP, src="11.xxx.xx.xx:2882", dest="11.xxx.xxx.xx:2882",                                 |         0 |
+----------------------------+---------------------------+-------------------------------+---------------+----------+-----------+---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+-----------+
2 rows in set (0.06 sec)

```

## 其他常用 SQL

1. SQL：查询磁盘空间使用，OceanBase 数据库 V2.x 版本需要将内部表换成 `__all_virtual_meta_table`。

   ```shell
   SELECT a.zone, a.svr_ip,
       round(disk_in_use / 1024 / 1024 / 1024, 3) AS disk_used_G,
       round(disk_total / 1024 / 1024 / 1024, 3) AS disk_total_G,
       round(disk_in_use / disk_total, 4) * 100 AS disk_used_pct
   FROM   oceanbase.__all_meta_table a,
       oceanbase.__all_virtual_server_stat b
   WHERE a.svr_ip = b.svr_ip
   GROUP BY a.zone, a.svr_ip
   order by disk_used_pct desc , a.zone, a.svr_ip;

   +---------------+----------------+-------------+--------------+---------------+
   | zone          | svr_ip         | disk_used_G | disk_total_G | disk_used_pct |
   +---------------+----------------+-------------+--------------+---------------+
   | alipay.et2_9  | 11.190.xxx.xx  |   15460.984 |    17305.309 |       89.3400 |
   | alipay.et2_9  | 11.190.xxx.xx  |   15355.619 |    17305.309 |       88.7300 |
   | alipay.em14_4 | 10.55.xxx.xx   |   11304.959 |    12760.816 |       88.5900 |
   | alipay.et15_8 | 11.232.xx.xx   |    7156.662 |     8345.996 |       85.7500 |
   | alipay.em14_7 | 11.37.xx.xx    |    8413.848 |    10995.385 |       76.5200 |
   | alipay.em14_7 | 11.37.xx.xxx   |    8361.656 |    10995.385 |       76.0500 |
   | alipay.em14_7 | 11.35.x.xxx    |    8330.029 |    10995.385 |       75.7600 |
   | alipay.em14_7 | 11.35.xx.xxx   |    8243.814 |    10995.385 |       74.9800 |
   | alipay.em14_7 | 11.37.xx.xx    |    8215.531 |    10995.385 |       74.7200 |
   | alipay.em14_4 | 11.232.xx.xxx  |    9452.061 |    12760.816 |       74.0700 |
   | alipay.em14_4 | 10.55.xxx.xx   |    9436.119 |    12760.816 |       73.9500 |
   | alipay.em14_4 | 11.233.xx.xxx  |   11371.594 |    16176.600 |       70.3000 |
   | alipay.et15_8 | 11.144.xx.xx   |    8194.422 |    12519.936 |       65.4500 |
   | alipay.et15_8 | 11.232.xxx.xxx |    5412.559 |     8345.996 |       64.8500 |
   | alipay.et15_8 | 11.232.xx.xxx  |    5361.699 |     8345.996 |       64.2400 |
   | alipay.et15_8 | 11.232.xx.xx   |    5358.838 |     8345.996 |       64.2100 |
   | alipay.et2_9  | 11.190.xxx.xx  |   10656.492 |    17305.309 |       61.5800 |
   | alipay.et15_8 | 11.232.xx.xx   |    4147.432 |     8345.996 |       49.6900 |
   | alipay.et15_8 | 11.149.xxx.xxx |    5932.834 |    12519.936 |       47.3900 |
   +---------------+----------------+-------------+--------------+---------------+
   19 rows in set (0.04 sec)

   ```
 2. SQL: 查询 server 复制迁移是不是被 block 了。

   ```shell
   select * from __all_server where block_migrate_in_time > 0 \G

   ```

   如果 server 因为磁盘满禁止迁入了，这个 server 的 `block_migrate_in_time` 是非零，而是一个 `timestamp`，转化成实际时间可以看到具体的禁止迁入时间

   可以通过以下命令尽快解除 block 状态：

   ```shell
   alter system set migration_disable_time = "600s";

   ```

上一篇

[广播日志流生命周期问题](https://www.oceanbase.com/knowledge-base/oceanbase-database-1000000004436776)

下一篇

[OceanBase 数据库 V4.x 版本日志流副本运维命令使用的相关问题](https://www.oceanbase.com/knowledge-base/oceanbase-database-1000000000990094) ![有帮助](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) 咨询热线
