首批通过分布式安全可靠测评,为关键业务系统打造
删除 OBServer 的 SSTable 或者 clog 文件,为何不会立即发生故障
更新时间:2026-06-08 02:41
本文详细解释发生这种超预期现象的原因。
在高可用测试中,对一台 Primary Zone 中的 OBServer 节点进行磁盘故障测试,把 clog 目录删除,期望中因为日志写入错误导致的 OBServer 节点不可用并没有立刻发生,而是经过了一段时间后生成新的 clog 文件时发生了文件写入错误,导致 observer 进程异常退出。
假如 Primary Zone 的 clog 文件被删了,OceanBase 数据库应该写不进 clog 而报错并切主。但在实际的场景中,删完 clog 文件后,OceanBase 数据库并不会马上切主,而是过了一段时间后才切主。这个现象要从 Linux 删除文件的原理进行解释,Linux 系统中直接删除文件可能并不会导致对文件后续的读写错误。
Linux 系统下文件名是存在父目录的 block 里面,并指向这个文件的 inode 节点,这个文件的 inode 节点再指向存放这个文件的 block 数据块。 在进程正在读、写文件时(文件处于打开状态),删除文件的操作实际上是在这个文件的父目录里面的 block 中删除了这个文件的名字,从而使这个文件名消失,并不会清除 inode 节点和 block 数据块。当没有进程读、写该文件时,Linux 系统才会真正清除 inode 节点和 block 数据块,并更新 inode MAP 和 block MAP,让这些磁盘位置可以用于放置其他文件的数据。 本案例中,删除 clog 目录时,当前的 clog 文件依然处于打开状态,删除操作并没有将正在写入的 clog 文件的 block 清除,OBServer 依然可以做 clog 的写入。当 clog 文件被写满并切换到下一个时,OBServer 才会发现错误,导致 OBServer 异常退出。
[2021-01-07 16:27:06.468038] WARN [CLOG] create_next_file (ob_clog_file_writer.cpp: 342) [200088][0][Y0-0000000000000000] [lt=17] [dc=0] open file fail(ret==-4165,file_id=15127)
[2021-01-07 16:27:06.468057] ERROR LCLOG] inner_switch_file (ob_clog_writer.cp:305) [200088][0][Y0-0000000000000000] [lt=4] [dc=0] Fail to switch file,(ret=-4165,file_writer_->get_cur_file_id()=15217) BACKTRACE: 0x9419b9a 0x938fdc2 Ox3595e2d 0x454945 0x1d0ba5f
类似地,如果在 OBServer 运行时直接把 SSTable 所在的目录删除,OBServer 依然可以正常的操纵数据,交易正常执行,直到 OBServer 重启时才会发现 SSTable 文件不存在了。
适用版本
OceanBase 数据库所有版本。