本文介绍在 OceanBase 数据库中 Delete Server 的操作流程和相关问题的排查方法。
Delete Server 流程
OceanBase 数据库 Delete Server 操作由两阶段完成。
第一阶段:
检查被 Delete 的 Server 上所有的 partition,是否有足够多的 F 副本、paxos 副本等信息。
预检查该 Server 上 unit 是否能够迁移到其他的 Server 上,查看其他机器上是否有充足的资源来存放该Server 上的 Unit。
将
__all_server表中,对应的 status 状态置成deleting。同时在__all_rootservice_job中记录一条 job_type 为DELETE_SERVER,job_status 为INPROGRESS的记录。
该阶段检查完成后,会返回语句执行成功。
如下所示。
obclient> select * from oceanbase.__all_server where svr_ip = '$DELETE_SERVER_IP' and svr_port = '$DELETE_SERVER_PORT';
+----------------------------+----------------------------+----------------+----------+----+------+------------+-----------------+----------+-----------------------+-------------------------------------------------------------------------+-----------+--------------------+--------------+----------------+-------------------+
| gmt_create | gmt_modified | svr_ip | svr_port | id | zone | inner_port | with_rootserver | status | block_migrate_in_time | build_version | stop_time | start_service_time | first_sessid | with_partition | last_offline_time |
| 2021-03-18 20:35:46.550891 | 2021-03-18 21:47:44.682902 | 11.160.xxx.xxx | 34451 | 6 | z2 | 34486 | 0 | deleting | 0 | 2.2.77_1-3002b6578cf1a91a3a2a95a3b5e1df761f3bda5d(Mar 18 2021 12:00:15) | 0 | 1616070959230656 | 0 | 1 | 0 |
+----------------------------+----------------------------+----------------+----------+----+------+------------+-----------------+----------+-----------------------+-------------------------------------------------------------------------+-----------+--------------------+--------------+----------------+-------------------+
obclient> select * from oceanbase.__all_rootservice_job where job_type = 'DELETE_SERVER';
+----------------------------+----------------------------+--------+-------------------------------+------------+-------------+----------+-----------+-------------+-------------+---------------+----------+------------+--------------+----------------+----------+---------+----------------+-------------+----------+-----------------+------------------+---------------+-----------------+
| gmt_create | gmt_modified | job_id | job_type | job_status | return_code | progress | tenant_id | tenant_name | database_id | database_name | table_id | table_name | partition_id | svr_ip | svr_port | unit_id | rs_svr_ip | rs_svr_port | sql_text | extra_info | resource_pool_id | tablegroup_id | tablegroup_name |
| 2021-03-18 21:47:46.669400 | 2021-03-18 21:47:46.669400 | 4 | DELETE_SERVER | INPROGRESS | NULL | 0 | NULL | NULL | NULL | NULL | NULL | NULL | NULL | 11.160.xxx.xxx | 34451 | NULL | 100.88.xxx.xxx | 34447 | NULL | NULL | NULL | NULL | NULL |
+----------------------------+----------------------------+--------+-------------------------------+------------+-------------+----------+-----------+-------------+-------------+---------------+----------+------------+--------------+----------------+----------+---------+----------------+-------------+----------+-----------------+------------------+---------------+-----------------+
第二阶段:
语句执行成功后,负载均衡会调度 Server 上的 Unit,将该 Server 上的 Unit 迁移到同 Zone 的其他 Server 上,当 Server 上的全部 Unit 被迁移完成后,会将该 Server 信息从 __all_server 表中清除,同时__all_rootservice_job 中 job_status 的状态置成 SUCCESS。
obclient> select * from oceanbase.__all_rootservice_job where job_type = 'DELETE_SERVER';
+----------------------------+----------------------------+--------+-------------------------------+------------+-------------+----------+-----------+-------------+-------------+---------------+----------+------------+--------------+----------------+----------+---------+----------------+-------------+----------+-----------------+------------------+---------------+-----------------+
| gmt_create | gmt_modified | job_id | job_type | job_status | return_code | progress | tenant_id | tenant_name | database_id | database_name | table_id | table_name | partition_id | svr_ip | svr_port | unit_id | rs_svr_ip | rs_svr_port | sql_text | extra_info | resource_pool_id | tablegroup_id | tablegroup_name |
| 2021-03-18 21:47:46.669400 | 2021-03-18 21:50:00.958066 | 4 | DELETE_SERVER | SUCCESS | 0 | 100 | NULL | NULL | NULL | NULL | NULL | NULL | NULL | 11.160.xxx.xxx | 34451 | NULL | 100.88.xxx.xxx | 34447 | NULL | NULL | NULL | NULL | NULL |
+----------------------------+----------------------------+--------+-------------------------------+------------+-------------+----------+-----------+-------------+-------------+---------------+----------+------------+--------------+----------------+----------+---------+----------------+-------------+----------+-----------------+------------------+---------------+-----------------+
相关参数
让机器永久下线进行删除副本,默认会两小时之后操作,如果紧急删除,可以调整 server_permanent_offline_time 和 replica_safe_remove_time 参数,让该机器副本尽可能的删除。
相关问题
注意
由于 Delete Server 需要进行 Unit 迁移等操作,因此需要 enable_rebalance 开关打开。
检查方法:
obclient> show parameters like 'enable_rebalance';
若 value 值为 True 代表打开,若为 False,则打开开关,方法如下。
obclient> alter system set enable_rebalance = true;
第一阶段问题
问题一
遇到如下报错:
ret = 4179; "not enough member or quorum mismatch, delete servers"
此时通常是 Server 上对应的 partition 副本数不足多数派或 F 副本数为 0 导致。或者是其他 zone 上存在 stop 的 Server,导致副本数少于多数派。
可以通过以下方法排查。
执行如下命令,获得 Server 上对应的 tenant 列表。
select tenant_id from oceanbase.__all_resource_pool where resource_pool_id in (select resource_pool_id from oceanbase.__all_unit where svr_ip = '$DELETE_SERVER_PORT.210.101' and svr_port = '$DELETE_SERVER_PORT');若不为 0,那么此时还在进行 Unit 迁移以及副本的迁移。可以执行如下命令查看
__all_virtual_rebalance_task_stat表。select count(*) from oceanbase.__all_virtual_rebalance_task_stat where task_type = 'ADD_REPLICA' and tenant_id in '$tenant_list';若返回值不为 0,那么证明还存在着补副本任务,需要等待补副本完成。
问题二
遇到如下报错:
ret = 4624; "machine resource is not enough to hold a new unit"
此时通常是没有足够的资源放置该 Server 上的 Unit 导致。由于机器状态是动态变化的,该阶段的检查并不一定准确,如下原因都不是的话,可以尝试再执行一下。
该问题可能是由以下原因引起的。
该 zone 上只有一台 Server,此时不允许进行 Delete Server 操作。
该 zone 上没有空闲机器,此时可以将该 Server 上对应的
resource_pool的unit_num调小,然后将该 Server 给 Delete 掉。(这样操作存在风险:会使调小后的 Server 上的负载变高)。
例子如下图
下掉 29 机器,但是 Zone 只有一个 29 机器,1001 租户和 1 租户还有一个 R 副本引用这个 Zone,所以 __all_server 中状态是 deleting,一直卡着
下掉这个 Zone 的解决方法:
变更 locality,删除 R 副本。
解绑
resource_pool,让租户不引用resource_pool,删除resource_pool之后,相当于就没有 Unit。Delete Server 恢复正常。


调小方法:
alter system delete server '11.160.xxx.xxx:3xxxx';
ERROR 4624 (HY000): machine resource is not enough to hold a new unit
原本 resource_pool pool1 的 unit_num为 3,现将其 unit_num 调整为 2。
alter resource pool pool1 unit_num = 2;
alter system delete server '11.160.210.101:34451';
成功执行。
问题三
报如下错误,该问题存在于 OceanBase 数据库 V2.2.3 BP9(oceanbase-2.2.77-20211119120733) 和 V2.2.50 版本。
ret = 4018; "Entry not exist"
当 Server 中无副本是时,Delete Server 报 4018 错误。
查看日志:在 rootservice.log 文件中搜索 delete_server,根据该 delete_server 中报的 trace,搜寻相关日志信息:fail to get loads by server(ret=-4018)。
解决方法:
首先判断该 Server 上是否还存在着 partition。
执行如下两条命令,当两者都返回 0 时代表该 Server 上没有 partition。
select count(*) from oceanbase.__all_virtual_partition_info where svr_ip = '$DELETE_SERVER_IP' and svr_port = '$DELETE_SERVER_PORT'; select count(*) from __all_virtual_pg_partition_info where svr_ip = '$DELETE_SERVER_IP' and svr_port = '$DELETE_SERVER_PORT';若不为 0,那么此时还在进行 Unit 迁移以及副本的迁移。可以查看
__all_virtual_rebalance_task_stat表。select count(*) from oceanbase.__all_virtual_rebalance_task_stat where task_type = 'MIGRATE_REPLICA' and tenant_id in '$tenant_list';若返回值不为 0,那么证明还存在着迁移任务,需要等待迁移完成。 您可以调整如下配置项,加快迁移任务:
alter system set server_data_copy_out_concurrency = 50; alter system set server_data_copy_in_concurrency = 50; alter system set data_copy_concurrency = 50;若无 partition,那么先将该 Server
kill掉。kill -9 observer随后将 __all_server 表中的 deleting 状态的 server 记录删除掉。
DELETE __all_server where svr_ip = '$DELETE_SERVER_IP' and svr_port = '$DELETE_SERVER_PORT';reload一下内存状态。Alter system reload server;此时
deleting状态的 Server 就从 Server 列表中去除了,该 Server 也成功下线。注意
删除内部表是高危操作,需要明确该 Server 上已经没有副本信息,否则直接下掉 Server 会造成副本缺失,极端情况可能会造成数据丢失。请务必不要自行操作,如果需要进行该操作,请联系 OceanBase 技术支持确认。
第二阶段问题
此时由后台负载均衡线程调度 Unit 的迁移操作。当分区数多,有负载均衡任务同时执行时,有可能导致该 Server 上 Unit 的迁移任务变慢。 查看方法如下:
select count(*) from oceanbase.__all_virtual_rebalance_task_stat;若返回值不为 0,那么证明还存在这迁移任务,需要等待迁移完成。
加快迁移任务的执行可以通过调整如下配置项完成。
alter system set server_data_copy_out_concurrency = 50; alter system set server_data_copy_in_concurrency = 50; alter system set data_copy_concurrency = 50;(调大数据的并行度) alter system set balancer_idle_time = 1s;(缩短 balance 的 idle 时间)该 Server 上 partition 数量已经为 0(判断方法见上),可能是该 Server 上的 Unit 仍然被其他的
resource_pool所引用导致。该问题通常是,创建了一个resource_pool后,并没有将 pool 赋予 tenant,导致 Unit 一直被占用不能被删除。排查方法如下:
select * from oceanbase.__all_resource_pool where resource_pool_id in (select resource_pool_id from __all_unit where svr_ip = '100.83.15.51' and svr_port = '34448'); +----------------------------+----------------------------+------------------+-------+------------+----------------+-----------+-----------+--------------+--------------------+ | gmt_create | gmt_modified | resource_pool_id | name | unit_count | unit_config_id | zone_list | tenant_id | replica_type | is_tenant_sys_pool | +----------------------------+----------------------------+------------------+-------+------------+----------------+-----------+-----------+--------------+--------------------+ | 2021-03-19 09:51:32.228242 | 2021-03-19 09:51:32.315968 | 1001 | pool1 | 3 | 1001 | z1;z2;z3 | -1 | 0 | 0 | +----------------------------+----------------------------+------------------+-------+------------+----------------+-----------+-----------+--------------+--------------------+此时
tenant_id为-1,证明该 pool 没有分配给任何 tenant,直接将该resource_pool删除即可。后续负载均衡会负责更新 Server 的状态。删除方法如下:
drop resource pool pool_1;确认没有副本和 Unit 在这台机器上,那就有可能是 meta 表上有一些残留信息没有回收。
排查方法如下:
select * from oceanbase.__all_virtual_core_meta_table where svr_ip = '$DELETE_SERVER_IP' and svr_port = '$DELETE_SERVER_PORT'; select * from oceanbase.__all_root_meta_table where svr_ip = '$DELETE_SERVER_IP' and svr_port = '$DELETE_SERVER_PORT'; select * from oceanbase.__all_virtual_meta_table where svr_ip = '$DELETE_SERVER_IP' and svr_port = '$DELETE_SERVER_PORT';如果上述存在数据,OBServer 的线程还在,那可能是汇报线程卡住了,需要排查汇报卡住的原因,但是也可以不排除,直接
kill掉 OBServer,走永久下线,让 RS 去删除 meta 表。如果 OBServer 不在了,meta 表还没有清理,是因为没到永久下线时间,查询下面两个配置项,并且调整到合适的大小。
show parameters like "%server_permanent_offline_time%"; show parameters like "%replica_safe_remove_time%";meta 表的清理逻辑出现问题(V2.2.1 版本)
正常情况下,meta 表是由 OBServe 汇报删除,但是在 OBServe 已经下线时,RS 在超过永久下线时间后可以主动清理 meta 表,V2.2.1 版本在清理
__all_tenant_meta_table时,如果清理对象是一个 binding 的 tablegroup,需要去清理这个 tablegroup 下面的 partition信息,需要去清理__all_tenant_partition_meta_table。再去迭代 tablegroup 下所有 partition 信息时,没有去掉局部索引,局部索引是没有 partition 的,所以这个迭代就出错了,就会导致 meta 表清理不掉。遇到这个问题,可以直接去 rootservice.log 中去搜类似下面这个
-4016的日志。
解决方法:
如果遇到上述问题,我们需要手动删除 meta 表,协助 Delete Server 完成。
直连 OBServer,不能通过 proxy 连接。
确认出问题的租户,可以从日志中获取,拿到
table_id右移 40 位就是tenant_id。执行如下命令修改
tenant_id。alter system change tenant tenant_id = 1024;执行如下命令确认 change tenant 成功。
select effective_tenant_id();确认出问题的 R 副本。
select distinct replica_type from oceanbase.__all_tenant_meta_table where svr_ip = '$DELETE_SERVER_IP' and svr_port = '$DELETE_SERVER_PORT';删除这部分副本。
delete from oceanbase.__all_tenant_meta_table where svr_ip = '$DELETE_SERVER_IP' and svr_port = '$DELETE_SERVER_PORT';回到系统租户,确认是否还有问题。
alter system change tenant tenant_id = 1;
常见问题
空 Unit 无法迁移或 Delete,详情参考 空 Unit 迁移无法完成。