对于分区数多、写入压力大的集群,如果转储慢(卡住)、或者租户 unit 规格异构,那么可能导致部分副本的 clog 回收不及时导致盘空间达到 95%,此时 OBServer 会自动停写,进而导致这台机器上会有大量副本不同步。
分析原因
正常情况下,clog 盘空间会维持在 80% 左右,一旦超过 80%,说明日志文件回收慢或者卡住了。
clog 文件回收的条件是:该文件中所有分区日志对应的数据都已经转储到 SSTable 中。因此通常导致 clog 盘满的原因是部分分区转储卡住。
在 clog 盘空间开始报警之后,根据下面的步骤确认阻塞回收的分区:
执行如下命令,从日志中查找
need_record为true的记录,里面有partition_key,表示这个分区的日志无法回收。 从报警日志附近时间点开始搜索,搜索结果中的分区就是当前阻塞回收的分区,拿到其中的partition_key。grep can_skip_base observer.log利用上面的
partition_key去搜索该分区的日志。grep partition_key observer.log通过日志分析它转储位点未推进的原因。 目前常见的转储位点未推进的原因主要有以下两种:
- 转储因数据盘盘满无法写盘。
- 转储本身失败。V3.1.x 版本之后转储依赖于写 clog,这里可能存在循环依赖。。
运维方法
转储因数据盘盘满失败,进而导致 clog 盘满
通过如下命令修改配置项动态调大数据盘大小:
alter system set datafile_size ='XXG' server='svr_ip:svr_port';
转储因依赖于写 clog,产生循环依赖导致 clog 盘满
OceanBase 数据库 V3.1.x 及之后的版本在开发转储未提交事务的时候引入了写 clog 的依赖。在极端场景下,例如写入很猛,freeze_trigger_percentage 和 memstore_limit_percentage 均设置的很大(触发转储的门槛较高),同时 clog 盘的空间并不是特别充裕的场景下,会触发循环依赖,导致转储无法进行,clog 盘满。 如果在 clog 盘满时,租户的 MEMStore 内存未爆,可以尝试如下方式进行恢复:
指定配置项的方式重启 OBServer 进程, 其中将
freeze_trigger_percentage设置为 40,memstore_limit_percentage设置为 50。重启后观察 OBServer 机器的状态,如果 clog 盘的水位持续回落到 80%,则说明该恢复方式生效,如果该恢复方式未生效,则尝试用下一节 通用运维手段 中描述的方式来尝试恢复。
通用运维手段
clog 盘达到 95% 之后自动停写,无法再接收日志,这个阈值是 OceanBase 数据库的一个配置项控制的,我们可以通过如下方法调大它到 98,可以指定只修改盘被占满的 server。
alter system set clog_disk_usage_limit_percentage = 98 server ='xxx:2882';改完之后,落后的副本会立即触发追日志,如果落后很多会触发 rebuild(从 leader 拷贝 data 和 clog),可以通过如下方式观察恢复过程:
执行如下 SQL 检查 clog 不同步的分区数是否有减少。
select svr_ip, count(*) from __all_virtual_clog_stat where is_offline = 0 and is_in_sync = 0 group by 1;如果没有快速减少,可能有副本触发了 rebuild(rebuild 是一种落后太多情况下追赶的方式,会拷贝基线+增量),继续执行如下 SQL 查询是否有正在做 rebuild 的副本。
select svr_ip, count(*) from __all_virtual_partition_migration_status where action != 'END' group by 1;若上述查询结果非 0,则继续检查 rebuild 任务并发相关的配置项。
show parameters like "%data_copy%";如果
server_data_copy_in_concurrency、server_data_copy_out_concurrency都还是默认值 2,那么将二者均调整为 10,加快多个副本 rebuild 的并发。alter system set server_data_copy_in_concurrency = 10; alter system set server_data_copy_out_concurrency = 10;
观察之前盘满的 server 的 clog 盘空间(df -lh )是否又达到了 98%,若是则说明这次调整没有恢复成功,需要明确 clog 无法回收的原因(比如转储卡住或报错了)。 如果通过调整
clog_disk_usage_limit_percentage为 98 之后,还没有恢复,则可以继续通过如下手段尝试恢复:移动 clog 文件到其他磁盘上,具体步骤是从 clog 目录下文件名字最小的文件开始,连续移动一部分文件(移动文件数:clog 盘容量 * 10% / 64M )到其他磁盘,让 clog 盘的水位降到 95% 以下。
注意
移动文件后在文件能够正常回收之前,不能重启 OBServer 进程,否则启动会失败。之后观察 clog 盘是否能自动开始回收。需要注意这里是移动,不是删除,被移动的日志后续可能还需要移动回来。
如果 clog 盘空间使用率缓慢下降,并回落到 80%。则说明 OBServer 恢复顺利,继续等待所有副本达到
sync状态即可。同时最好对集群发起一次转储操作,避免被移走的 clog 还被依赖。如果观察到 clog 盘中的 clog 文件持续被回收中(在有数据持续写入的场景下),则说明之前移走的 clog 文件已不再需要。
is_in_sync= 0的副本数量降为 0 之后,将上述所有改过的配置项恢复为原值。
共享内存文件中记录 flush_pos_ 大于 clog 最后一个文件的有效位置
典型报错日志如下:
[2021-05-31 15:05:40.789026] ERROR [CLOG] load_file (ob_clog_file_writer.cpp:155) [3133][0][Y0-0000000000000000] [lt=7] [dc=0]** The clog start pos is unexpected,** (ret=-4016, **file_id=1018, offset=51658630**,** shm_buf_->file_flush_pos_={file_id:1018, file_offset:51663293}**, shm_buf_->file_write_pos_={file_id:1018, file_offset:51667058}, shm_buf_->log_dir_="/home/admin/oceanbase/store/ob2r2uojeodxj4/clog_shm") BACKTRACE:0xcc279ca 0xcb46db2 0x7372324 0x7372bf7 0x73671a1 0x7363164 0x7518eaa 0x72f8e62 0x72f8fd1 0x72f9057 0x725489e 0x8050c4e 0x93aec0e 0x31a9088 0x7f886a0b0b15 0x3196029
恢复方式:删除 store 目录下的 clog_shm 文件之后重新启动。
迭代 clog 文件出错
迭代 clog 文件出错,通常是由于 clog 文件本身出现了问题。
典型报错日志如下:
[2021-08-02 16:56:42.340821] ERROR [CLOG] notify_scan_finished_ (ob_log_scan_runnable.cpp:660) [3710][1861][Y0-0000000000000000] [lt=6] [dc=0]** invalid scan_confirmed_log_cnt(ret=-4016, **ret="OB_ERR_UNEXPECTED", scan_confirmed_log_cnt=2, next_ilog_id=22, last_replay_log_id=16, pkey={tid:1099511627971, partition_id:14, part_cnt:0}) BACKTRACE:0x771c1ba 0x7653a12 0x1a51854 0x1a51f65 0x5acec7c 0x5aca534 0x5acda8a 0x2f426ea 0x1e90dec 0x74ff497 0x74faf5f 0x74f366f
[2021-08-02 16:56:42.340958] INFO [CLOG]** **ob_log_scan_runnable.cpp:682 [3710][1861][Y0-0000000000000000] [lt=133] [dc=0]** notify_scan_finished_ finished(**ret=-4016, cost_time=154)
[2021-08-02 16:56:42.340965] ERROR [CLOG] do_scan_log_ (ob_log_scan_runnable.cpp:216) [3710][1861][Y0-0000000000000000] [lt=6] [dc=0] **notify_scan_finished_ failed(ret=-4016) **BACKTRACE:0x771c1ba 0x7653a12 0x1a00088 0x1a006d2 0x1a02aca 0x5acdc97 0x2f426ea 0x1e90dec 0x74ff497 0x74faf5f 0x74f366f
[2021-08-02 16:56:42.341025] ERROR [CLOG] do_scan_log_ (ob_log_scan_runnable.cpp:223) [3710][1861][Y0-0000000000000000] [lt=59] [dc=0] **log scan runnable exit error(ret=-4016) **BACKTRACE:0x771c1ba 0x7653a12 0x1a00088 0x1a006d2 0x1a02aca 0x5acdbf4 0x2f426ea 0x1e90dec 0x74ff497 0x74faf5f 0x74f366f
恢复方式
如上的报错通常是因为 clog 文件出了问题,或者迭代 clog 文件出了问题,对于少数派副本出现如上问题,可以通过删除出错副本恢复。
告警
只有当少数派副本出现这样的问题后,可以通过该方式恢复。如果多数派出现了上述问题,请联系技术支持同学,切勿私自操作。例如 3 副本的环境中,其中一个副本出错。
恢复方式一
找一台类似机器快速加入到 OBServer 集群中,OBServer 自动补齐第三副本。需要确认配置项
enable_rereplication处于打开状态。出问题的机器最终会永久下线。恢复方式二
出问题的机器走永久下线流程;清空故障机器上的数据,以新的机器方式重新加入集群。
永久下线,执行如下命令下线故障机器。
alter system delete server '$obs0_ip:$obs0_port';查询
__all_server, 没有下线机器对应记录,则说明下线操作完成。清空故障机器上的数据。
以新机器的方式重新加入集群。
alter system add server '$obs0_ip:$obs0_port';之后集群会发起补副本操作,补齐第三副本,同样需要确认
enable_rereplication处于打开状态。