首批通过分布式安全可靠测评,为关键业务系统打造
物理恢复报错-4016
更新时间:2026-05-13 01:51
问题现象
物理恢复报错 -4016。
在客户端通过查询
CDB_OB_RESTORE_HISTORY视图确定问题,执行语句如下。obclient> SELECT * FROM oceanbase.CDB_OB_RESTORE_HISTORY where tenant_name = 'tenant_xxx';其中 tenant_xxx 为物理恢复目标租户名,查询结果中
info字段关键信息如下。CLOG: OB_ERR_UNEXPECTED(-4016) on "xxx.xxx.xxx.xxx:xxx" with traceid xxxxx-xxxxx-xxxxx-xxxxx在客户端通过
__all_server_event_history视图字段event获得关键信息。执行查询语句如下。
obclient> SELECT * FROM oceanbase.__all_server_event_history WHERE module='clog_restore' AND event not like 'report_io_stat';其中查询结果中字段
info关键信息如下。clog accum_checksum is not match witch archived log在客户端通过
__all_virtual_column视图获得table_id字段查询结果。执行语句如下。
obclient > SELECT d.tenant_name, c.database_name, b.table_id, b.table_name, a.column_name FROM (SELECT tenant_id, table_id, column_name FROM oceanbase.__all_virtual_column where rowkey_position > 0 AND data_type IN (37, 38) AND tenant_id IN (SELECT tenant_id FROM oceanbase.__all_virtual_tenant_parameter_info WHERE name='tde_method' AND value !='none' AND value !='internal')) as a JOIN oceanbase.__all_virtual_table as b ON a.table_id = b.table_id AND a.tenant_id = b.tenant_id JOIN oceanbase.__all_virtual_database as c ON b.database_id = c.database_id AND b.tenant_id = c.tenant_id JOIN oceanbase.__all_tenant as d ON c.tenant_id = d.tenant_id WHERE b.encryption!='';其中查询结果中字段
table_id为步骤 2 中查询结果中value1字段中的{tid:xxx}值。+-------------+---------------+----------+------------+-------------+ | tenant_name | database_name | table_id | table_name | column_name | +-------------+---------------+----------+------------+-------------+ | xxx | xxx |{tid:xxx} | xxx |xxx | +-------+------------+-------+--------------+---------+-------------+
集群物理恢复 clog 报错累计校验和不一致。
物理恢复过程中报错信息如下。
errorMessage: *log_task and confirmed_info's accum_checksum not match(ret=-4016, partition_key={tid:xxxxx, partition_id:0, part_cnt:0}, log_id=xxxxx, log_task={log_type_:202, proposal_id_:{time_to_usec:xxxxxx, server:"xxx.xxx.xxx.xxx:xxxx"}, log_buf_len_:0, generation_timestamp:xxxxx, submit_timestamp_:xxxxx, next_replay_log_ts_:xxxxx, data_checksum:xxxxxx, epoch_id_:xxxxx, accum_checksum_:xxxxx, state_map:{val:xxxxx}, ack_list:0, submit_cb:null, majority_cnt:2, log_cursor:{file_id:xxxxx, offset:xxxxx, size:xxxxx}}, confirmed_info={data_checksum:xxxxx, epoch_id:xxxxx, accum_checksum:xxxxx})
问题原因
若被更新的表中主键包含
TIMESTAMP或者TIMESTAMP WITH LOCAL TIME ZONE类型的列,更新事务产生的 clog 中,MutatorRow中保存的主键列的ObObj对象的cs_level_被序列化为0x02(这个是ColumnConvert统一设置的)。由于集群开启了 clog 加密,且归档开启了压缩。因此在归档 clog 的时候, 会先读取解密后的 clog,先压缩再加密后归档出去。读取解密后的 clog 日志这一步涉及到反序列化原始 clog 内容,再解密内部的MutatorRow,并重新序列化的过程。在解密MutatorRow获取未加密的 Row 的操作中,会反序列化后主键列,在反序列化函数中,将内存中的cs_level_重置为0x05,并将0x05序列化。正是这一步导致了备份和恢复上同一个字节的值不一致,进而导致data_checksum不一致。触发条件为开启
TDE加密后, Oracle 租户下有使用TIMESTAMP或者TIMESTAMP WITH LOCAL TIME ZONE类型作为主键的表,这些表有写入,产生的 clog 被归档出去。物理恢复时,需恢复 clog。
问题的风险及影响
该问题会导致物理恢复失败。
潜在风险集群巡检。
在 sys 租户下连接执行如下语句查询集群中开启了 TDE 加密的租户。忽略结果中的系统租户,系统租户不会被归档。
obclient > SELECT table_id, table_name FROM __all_virtual_table WHERE tenant_id IN (SELECT tenant_id FROM oceanbase.__all_virtual_tenant_parameter_info WHERE name='tde_method' AND value !='none' AND value !='internal') AND encryption !='';判断是否有表包含
TIMESTAMP或者TIMESTAMP WITH LOCAL TIME ZONE类型。在 sys 租户下连接执行如下语句。
obclient > SELECT table_id, column_id, column_name FROM __all_virtual_column WHERE tenant_id IN (SELECT tenant_id FROM oceanbase.__all_virtual_tenant_parameter_info WHERE name='tde_method' AND value !='none' AND value !='internal') AND rowkey_position > 0 AND data_type in (37, 38);
影响的版本
- OceanBase 数据库企业版 V3.2.4 BP4 Hotfix2 (oceanbase-3.2.4.4-104020012023070316) 及之前的版本、V3.2.3 BP8 Hotfix3 (oceanbase-3.2.3.3-108030022023051915) 及之前的版本、V3.1.2 BP11 (oceanbase-3.1.2-111000052023010412) 及之前的版本。
- OceanBase 数据库社区版 V3.1.5 CE Hotfix1 (oceanbase-ce-3.1.5-100010012023060910) 及之前的版本。
注意
OceanBase 数据库企业版 V2.x 无影响版本。
解决方法及规避方式
升级至问题已修复版本。目前已修复如下版本:
- OceanBase 数据库企业版 V3.2.3 BP8 Hotfix4 (oceanbase-3.2.3.3-108040052023060909)。
- OceanBase 数据库社区版 V3.1.5 CE Hotfix2。
出现该问题后,可以尝试恢复失败租户清理后,选取基线备份附近的时间点进行恢复,有概率能恢复成功。