Transfer:将一组 Tablet 从源端日志流转移到目的端日志流的过程。
Transfer 基础知识
负载均衡与 Transfer 各任务之间的关系

视图中三种任务的关联:

注意
这三张视图仅记录当前正在运行的任务,任务结束后会被移动到对应 HISTORY 表中。
确认租户角色及相关配置项
select tenant_id, tenant_role from oceanbase.DBA_OB_TENANTS;

select * from oceanbase.GV$OB_PARAMETERS where tenant_id =1002 and name in ("enable_rebalance", "balancer_idle_time", "partition_balance_schedule_interval");
enable_rebalance
LS 负载均衡开关。关闭时无法扩缩容,无法变更 primary_zone 的第一优先级,无法修改 primary_zone 里第一优先级相关 Zone 的 locality 。
partition_balance_schedule_interval
分区均衡的间隔。设置为0时无法做分区均衡。还会影响 tablegroup 中分区的分布情况。
balancer_idle_time
负载均衡任务生成的间隔,数值过大会导致
balance_job/balance_task调度过慢。
根据视图中 STATUS、COMMENT、RESULT 列初步判断问题
| 常见问题 | 是否为备租户 | 视图信息 | 原因 | 排查方法 |
|---|---|---|---|---|
| 卡在 INIT 状态 | 否 | COMMENT: Wait for member list to be same | src_ls 和 dest_ls 的 member_list 不一致,一般是对应 LS 迁移异常导致的。 | 详见 Transfer 常见问题 这一节中的第一小节 INIT 状态 Wait for member list to be same 的内容。 |
| HISTORY 表大量相同任务 | 否 | COMMENT: Task completed as no valid partition | Transfer 加锁持续锁冲突,一般是对应表上残留着表锁 /online ddl 锁。 | 详见 Transfer 常见问题 这一节中的第二小节 HISTORY 表中大量 Task completed as no valid partition 的内容。 |
| 卡在 START/DOING 状态 | 否 | result: XXX | 存储层对 Tablet 执行 Transfer 时卡住。 | 按下述 4、5 小节查日志。 |
| 历史表报错超时 | 否 | result: -4664/-4012/-7123 | 需根据日志判断超时阶段,可能是 start 阶段事务超时。 | 按下述 根据 TRACE_ID 查找日志、根据线程查找日志 这二节内容查日志。 |
| 备租户 transfer 卡住 | 是 | — | 备租户 transfer 依赖日志回放,备租户 transfer 卡住基本和日志同步相关。 | 详见 备租户 Transfer Task 卡 INIT 状态 这一节的内容。 |
| 历史表中 transfer 持续失败 | 否 | result: -7114 | 活跃事务导致 transfer 失败 | 详见 历史表中 Transfer 持续失败,报错-7114 这一节的内容。 |
| 其他 | 否 | 按下述 根据 TRACE_ID 查找日志、根据线程查找日志 这二节内容查日志。 |

根据 TRACE_ID 查找日志
注意
仅适用于主库。
视图中 Task 都注明了对应 trace_id、create_time 以及 status,根据 Transfer 任务状态判断去哪台 server 上找日志。
RS 相关 Transfer 状态:需要到 用户租户下1号日志流 leader 所在 server 查找对应时间的 observer.log (不是 rootservice.log ) 。
存储相关 Transfer 状态:需要到 用户租户下源端日志流(SRC_LS)和目标端日志流(SRC_LS)的leader 所在 server 查找对应时间的 observer.log 。
select svr_ip, svr_port from __all_virtual_log_stat where tenant_id = 1002 and ls_id = 1 and role = 'LEADER';
根据线程查找日志
注意
仅适用于主库。
如果根据 TRACE_ID 无法找到有效日志,可以根据关键线程去对应 server 上查找observer.log (不是 rootservice.log ) 。
| 线程名称(xxxx为tenant_id) | 说明 | 位置 | 责任组 |
|---|---|---|---|
| Txxxx_TntTransf | Transfer 任务管理线程 | 用户租户1号日志流 Leader | RS |
| Txxxx_TBalance | 均衡任务管理线程 | 用户租户1号日志流Leader | RS |
| Txxxx_TransferS | Transfer任务执行线程 | 用户组 SRC_LS/DEST_LS 的 leader | 存储-高可靠 |
找到日志后,如果确认非预期,可以根据报错线程找对应,请联系 OceanBase 技术支持人员协助排查分析。
若找不到任务管理线程日志,排查 Leader 是否上任
注意
仅适用于主库。
如果你确认了目标租户不是备租户,且用户租户下1号日志流的 Leader 是对的,但日志中找不到RS组负责的任务管理线程,需要考虑 Leader 没有上任的情况。
select * from __all_virtual_ha_diagnose where tenant_id = 1028 and ls_id = 1;

日志流 leader 上任包含 election 层、palf 层、RCS(role change service) 层共三层的上任,如果 RCS 上任失败,会导致负载均衡、Transfer 任务管理线程无法启动,从而使任务卡住,没有线程日志。
无主问题根据以下手册排查,详细参见 V4.0 无主问题排查手册。
Transfer 常见问题
INIT 状态 Wait for member list to be same
问题现象
Transfer 任务长期卡在INIT状态,COMMENT列显示 Wait for member list to be same 。

问题原因
由于 Transfer 底层实现机制的限制,Transfer Task 执行前,会由负载均衡线程调度LS迁移,保证 task 中 src_ls 和 dest_ls 的 member_list 完全一致,且 Leader 在同一台机器上。Transfer task 在 INIT 状态会持续等待 LS 迁移完成。Task 长期卡在 INIT 阶段等待 member_list 一致,那么基本是 LS 迁移出了问题。
排查方法
查询
src_ls和dest_ls的当前分布和目标分布情况,确认分布不正常的 LS 。select svr_ip,svr_port,ls_id,B.status,B.primary_zone,B.unit_group_id from oceanbase.DBA_OB_UNITS A join oceanbase.CDB_OB_LS B on A.unit_group_id = B.unit_group_id where B.tenant_id = 1004 and B.ls_id = 1001;select svr_ip,svr_port,ls_id,role,paxos_member_list from oceanbase.__all_virtual_log_stat where tenant_id = 1004 and ls_id = 1001;
正常情况下 LS 副本分布一致。
查询 RS 端 LS 迁移的调度情况。
select * from oceanbase.DBA_OB_ROOTSERVICE_EVENT_HISTORY where module like "%disaster%" and value1 = 1004 and value2 = 1001;LS 迁移卡住的场景,一般会有明显报错。
查询底层 LS 迁移执行情况。
select * from oceanbase.DBA_OB_SERVER_EVENT_HISTORY where module like 'storage_ha' and value1 = 1004 and value2 = 1001;一般会有明显报错。
确定 LS 迁移问题后,可按照下述指南排查,请联系 OceanBase 技术支持人员协助排查。
详细指南:V4.0迁移/复制/Rebuild 排查指南。
HISTORY 表中大量 Task completed as no valid partition
问题现象
HISTORY 表中有大量 COMMENT 为 Task completed as no valid partition 的任务,且 LOCK_CONFLICT_PART_LIST 不为空。同时一直能看到有 INIT 状态的任务生成。

问题原因
Transfer 任务执行时,要在 INIT 阶段对目标分区加表锁和 Online DDL 锁,与 DDL 互斥,以保证 Transfer 的正确性。当发生锁冲突时,Transfer 任务管理线程会将分区记录到 LOCK_CONFLICT_PART_LIST 列中,并跳过该分区去处理后续其他分区。持续出现 LOCK_CONFLICT_PART_LIST 不为空,一般是有 DDL 正在执行/卡住。
排查方法
确定锁冲突的表和分区对应
tablet lock_conflict_part_list中记录锁冲突分区的格式为:table_id1:part_object_id1,table_id2:part_object_id2。
如上图所示,发生冲突的有两个分区,分别是 table_id=614259 的分区 part_object_id=614359,和 table_id=618511 的分区 part_object_id=618541。然后根据下面 SQL 确认分区对应 tablet_id 。
select data_object_id as tablet_id from oceanbase.CDB_OBJECTS where con_id = 1002 and object_id = 614359; // Oracle 视图,con_id 对应 tenant_id 。查看 table_id 和 tablet_id 上的锁。
select * from oceanbase.__all_virtual_obj_lock where tenant_id = 1002 and obj_id in (614259,614359, 244469); // 包括 table_id, part_object_id, tablet_id 。
上图中 op_type 显示在 table_id=614259 上有
OUT_TRANS_LOCK的锁残留。查看是否有对应 DDL 。
select * from oceanbase.__all_virtual_ddl_task_status where tenant_id = 1002 and object_id in (614259,614359,244469) or target_object_id in (614259,614359,244469); // 包括table_id,part_object_id,tablet_id
可以看到有 DDL 卡住。根据环境分析该 DDL 执行是否符合预期。有关 DDL 排查参见:V4.x DDL 排查文档。
任务报错 -4664/-4012/-7123
问题现象
HISTORY 表中有大量 Transfer 任务保持 -4664/-4012/-7123

问题原因
存储层在 transfer start 阶段默认设置了事务超时时间 _transfer_start_trans_timeout = 1s,transfer 任务 start 阶段耗时超 10s,执行 inner_sql 时正好超时,符合预期。
调大租户级配置项 _transfer_start_trans_timeout 可以绕过。
alter system set _transfer_start_trans_timeout = '10s' tenant xxxx;
排查方法
在 SRC_LS/DEST_LS 的 Leader 所在机器搜索 observer.log,关键字 Txxxx_TransferS,查看报错。
备租户 Transfer Task 卡 INIT 状态
问题现象
备租户 Transfer task 一直卡 INIT 状态。

问题原因
备租户的 Transfer 任务是通过日志回放出来的,备租户 Clog 盘使用达到 80%,触发备库停止拉日志。
排查方法
查看备库回放点、日志同步点,确认同步点最小的日志流。需和备库相关同学确认。
select * from oceanbase.DBA_OB_TENANTS;
select * from oceanbase.__all_virtual_ls_recovery_stat;
select * from oceanbase.__all_virtual_log_stat where tenant_id =1002 and ls_id = 1;

详细内容请参见:V4.2 网络备库同步卡主问题排查
历史表中 Transfer 持续失败,报错-7114
问题现象
Transfer 历史表中大量 -7114 的失败记录。

问题原因
没有开启 transfer 杀事务时(_enable_balance_kill_transaction),transfer 要等待活跃事务完成(默认 100ms)。当活跃事务本身持续时间较长,且业务侧持续开启新事务时,transfer 等不到活跃事务结束,导致 transfer 持续失败。
排查方法
查看持续失败的 transfer 任务中,src_ls 和 dest_ls 上是否有活跃事务:
select * from __all_virtual_trans_stat where tenant_id=1002 and ls_id=1001;
一般可通过以下方法解决:
方法1: 减少业务侧压力/等到压力小的时候再执行 transfer 。
Tranfser 需要等待日志流上没有活跃事务的间隙才可以处理。业务侧存在大事务时,需等待其完成后再发起 transfer。
方法2: 开启 transfer 杀事务。(会造成业务抖动!)
警告
开启后 transfer 杀事务后,transfer 会更长时间阻塞新开事务,正在执行的冲突事务会被杀掉,导致预期内的事务报错、事务回滚、业务侧抖动。操作前请谨慎确认。
必要参数:开启 transfer 杀事务。
默认冲突的活跃事务执行超过 100ms 不结束就尝试杀掉。杀事务耗时 100ms,杀不完就报错重试,命令如下:
alter system set _enable_balance_kill_transaction = true tenant = my_tenant;优化参数一(可选):杀活跃事务的超时时间。
当目标 LS 上活跃事务过多时,100ms 可能杀不完,需要调成 10s。该参数同时增加阻塞新开事务的时间,命令如下:
alter system set _balance_wait_killing_transaction_end_threshold = '10s' tenant = my_tenant;优化参数二(可选):只杀掉执行超过 10s 的冲突事务。也会同时增加 10s 阻塞新开事务的时间,命令如下:
alter system set _balance_kill_transaction_threshold = '10s' tenant = my_tenant;
注意
调大可选优化参数均会增加阻塞业务侧新开事务的时间!,最差情况下业务流量可能跌零。
磁盘满时扩容,transfer 报错 -4184
问题现象
用户通过 GV$OB_SEVERS 发现 server 磁盘占用量在 95% 以上,添加同规格机器发起 unit 扩容操作。unit 扩容在新机器上成功新增 unit,但旧机器上数据未迁移至新 unit。发现 CDB_OB_BALANCE_TASKS 中有 LS_SPLIT 任务卡在 DOING 阶段,CDB_OB_TRANSFER_TASK_HISTORY 中 transfer 任务持续报错 -4184 磁盘空间不足。
问题原因
在 OceanBase 数据库 V4.2 各个版本中,扩容操作需要现在旧 unit 中分裂出一个LS,带走部分 tablet,然后迁移到新 unit 中(LS 分裂过程 = 新建 LS + transfer tablet)。问题场景下,新建 LS 成功,但 transfer 大量 tablet 时,存储层需要额外空间处理数据。当本地磁盘空间不足时,transfer 任务执行报错 -4184 ,一直无法成功,进而也无法扩容。存储层优化中。
排查方法
a. 通过 CDB_OB_BALANCE_JOBS 看到有 LS balance by expand 的任务卡住。
obclient> select * from oceanbase.CDB_OB_BALANCE_JOBS where tenant_id=1002;
输出结果如下:
+-----------+---------+----------------------------+----------------------------+----------------------+------------+-----------------+-------------------------+--------+---------+
| TENANT_ID | JOB_ID | CREATE_TIME | MODIFY_TIME | BALANCE_STRATEGY | JOB_TYPE | TARGET_UNIT_NUM | TARGET_PRIMARY_ZONE_NUM | STATUS | COMMENT |
+-----------+---------+----------------------------+----------------------------+----------------------+------------+-----------------+-------------------------+--------+---------+
| 1002 | 2024502 | 2023-11-30 20:19:17.468736 | 2023-11-30 20:19:17.468736 | LS balance by expand | LS_BALANCE | 2 | 1 | DOING | NULL |
+-----------+---------+----------------------------+----------------------------+----------------------+------------+-----------------+-------------------------+--------+---------+
1 row in set (0.00 sec)
b. 通过 CDB_OB_TRANSFER_TASK_HISTORY 看到 transfer 任务持续报错 -4184。
MySQL [oceanbase]> select * from oceanbase.CDB_OB_TRANSFER_TASKS where tenant_id = 1002\G;
*************************** 1. row ***************************
TENANT_ID: 1002
TASK_ID: 109669064
CREATE_TIME: 2023-11-30 21:46:53.012975
MODIFY_TIME: 2023-11-30 21:46:53.458133
SRC_LS: 1001
DEST_LS: 1004
PART_LIST: 500009:500108,500009:500109,500009:500110,500009:500111,500009:500112,500009:500113,500009:500114,500009:500115,500009:500117,500009:500118,500009:500119,500009:500120,500009:500123,500009:500124,500009:500143,500009:500157,500010:500471
PART_COUNT: 17
NOT_EXIST_PART_LIST: NULL
LOCK_CONFLICT_PART_LIST: NULL
TABLE_LOCK_TABLET_LIST: 200062,200063,200064,200065,200066,200067,200068,200069,200071,200072,200073,200074,200077,200078,200097,200111,200125
TABLET_LIST: 200062:0,200063:0,200064:0,200065:0,200066:0,200067:0,200068:0,200069:0,200071:0,200072:0,200073:0,200074:0,200077:0,200078:0,200097:1,200111:1,200125:1,1152921504606847047:0,1152921504606847048:0,1152921504606847049:0,1152921504606847050:0,1152921504606847051:0,1152921504606847052:0,1152921504606847053:0,1152921504606847054:0,1152921504606847056:0,1152921504606847057:0,1152921504606847058:0,1152921504606847059:0,1152921504606847062:0,1152921504606847063:0,1152921504606847082:1,1152921504606847096:1,1152921504606847147:0,1152921504606847148:0,1152921504606847149:0,1152921504606847150:0,1152921504606847151:0,1152921504606847152:0,1152921504606847153:0,1152921504606847154:0,1152921504606847156:0,1152921504606847157:0,1152921504606847158:0,1152921504606847159:0,1152921504606847162:0,1152921504606847163:0,1152921504606847182:1,1152921504606847196:1,1152921504606847247:0,1152921504606847248:0,1152921504606847249:0,1152921504606847250:0,1152921504606847251:0,1152921504606847252:0,1152921504606847253:0,1152921504606847254:0,1152921504606847256:0,1152921504606847257:0,1152921504606847258:0,1152921504606847259:0,1152921504606847262:0,1152921504606847263:0,1152921504606847282:1,1152921504606847296:1,1152921504606847310:1,1152921504606847772:0,1152921504606847773:0,1152921504606847774:0,1152921504606847775:0,1152921504606847776:0,1152921504606847777:0,1152921504606847778:0,1152921504606847779:0,1152921504606847781:0,1152921504606847782:0,1152921504606847783:0,1152921504606847784:0,1152921504606847787:0,1152921504606847788:0,1152921504606847807:1,1152921504606847821:1,1152921504606847957:1,1152921504606848164:1,1152921504606848321:0,1152921504606848322:0,1152921504606848323:0,1152921504606848324:0,1152921504606848325:0,1152921504606848326:0,1152921504606848327:0,1152921504606848328:0,1152921504606848330:0,1152921504606848331:0,1152921504606848332:0,1152921504606848333:0,1152921504606848336:0,1152921504606848337:0,1152921504606848356:1,1152921504606848370:1
TABLET_COUNT: 100
START_SCN: 0
FINISH_SCN: 0
STATUS: FAILED
TRACE_ID: YB42AC155229-0006099FB2FEC5E8-0-0
RESULT: -4184
BALANCE_TASK_ID: 107943232
TABLE_LOCK_OWNER_ID: 109669077
COMMENT:
c. 通过 GV$OB_SEVERS 或者 __all_virtual_disk_stat 看到 server 磁盘空间占用率超 95% 。
即可认为是该问题存在 OceanBase 数据库 V4.2 各个版本。
解决方案一(推荐):磁盘扩容。
解决方案二:调参(集群情况可能存在差异,请联系 OceanBase 技术支持咨询具体方法)。
alter system set sys_bkgd_net_percentage = '100'; //默认值 60 。
alter system suspend merge tenant=all;//设置为 false,停止合并。
alter system set data_disk_usage_limit_percentage = 97; //默认值为 90 。
观察到 transfer 顺利进行,且 balance_job 扩容任务顺利完成后还原参数。
alter system set sys_bkgd_net_percentage = '60'; //默认值 60 。
alter system resume merge tenant=all; //恢复合并
alter system set data_disk_usage_limit_percentage = 90; //默认值为 90 。
alter system set _enable_balance_kill_transaction = false tenant = <tenant_name>;
Transfer 相关常用 SQL
查询某个 tablet 的 Transfer 历史。
select create_time,finish_time,src_ls,dest_ls,status from oceanbase.CDB_OB_TRANSFER_TASK_HISTORY where tenant_id = 1002 and tablet_list like "%209515%";查询表锁 online DDL 锁残留。
select * from oceanbase.__all_virtual_obj_lock where tenant_id = 1002 and obj_id = 209515;查询 DDL 状态。
select * from oceanbase.__all_virtual_ddl_task_status where tenant_id = 1002;
适用版本
OceanBase 数据库 V4.2 所有版本。