Oceanbase 设置归档目标为 Cloudflare R2 对象存储报证书错误问题。

【 使用环境 】生产环境
【 OB or 其他组件 】Oceanbase CE
【 使用版本 】 4.3.5.2
【问题描述】
设置 Oceanbase 的日志归档路径为 Cloudflare R2 对象存储时:

ALTER SYSTEM SET LOG_ARCHIVE_DEST='LOCATION=s3://oceanbase-TENANT-backup/backup/log?host=CLOUDFLARE-R2-ID.r2.cloudflarestorage.com/&access_id=CLOUDFLARE——ACCESS_ID&access_key=CLOUDFLARE——ACCESS_KEY&delete_mode=delete&checksum_type=md5&addressing_model=path_style' TENANT=TENANT;

出现:
ERROR 9129 (HY000): object storage io error

查看observer.log 日志,给出报错是证书错误:

[2025-06-20 07:59:39.141688] WDIAG Log (ob_storage_s3_base.cpp:116) [1607194][T1_L0_G0][T1][YB42C4800102-000637377BFE570B-0-0] [lt=10][errcode=-9129] [S3] module=CurlHttpClient, msg=Curl returned error
 code 77 - Error
[2025-06-20 07:59:39.141736] WDIAG Log (ob_storage_s3_base.cpp:116) [1607194][T1_L0_G0][T1][YB42C4800102-000637377BFE570B-0-0] [lt=8][errcode=-9129] [S3] module=AWSXmlClient, msg=HTTP response code: -1
Resolved remote host IP address: 172.66.1.46
Request ID: 
Exception name: 
Error message: curlCode: 77, Error
9 response headers:
cache-control : max-age=3600
cf-ray : 9529ba5d79377cf5-LAX
connection : keep-alive
content-length : 167
content-type : text/html
date : Fri, 20 Jun 2025 07:59:39 GMT
expires : Fri, 20 Jun 2025 08:59:39 GMT
location : https://CLOUDFLARE-R2-ID.r2.cloudflarestorage.com/oceanbase-TENAT-backup?max-keys=1000&prefix=backup%2Flog%2F
server : cloudflare
[2025-06-20 07:59:39.141760] WDIAG Log (ob_storage_s3_base.cpp:116) [1607194][T1_L0_G0][T1][YB42C4800102-000637377BFE570B-0-0] [lt=5][errcode=-9129] [S3] module=AWSClient, msg=If the signature check failed. This could be because of a time skew. Attempting to adjust the signer.
[2025-06-20 07:59:39.141779] WDIAG is_timeout_ (ob_object_storage_base.h:111) [1607194][T1_L0_G0][T1][YB42C4800102-000637377BFE570B-0-0] [lt=6][errcode=-4012] request reach time limit(start_time_us_=1750406357549931, timeout_us_=20000000, cur_time_us=1750406379141779, attempted_retries=11)
[2025-06-20 07:59:39.141786] WDIAG log_s3_status (ob_storage_s3_base.cpp:843) [1607194][T1_L0_G0][T1][YB42C4800102-000637377BFE570B-0-0] [lt=5][errcode=-9129] S3 info(request_id="", code=-1, exception="", err_msg="curlCode: 77, Error")
[2025-06-20 07:59:39.141790] WDIAG do_list_ (ob_storage_s3_base.cpp:1298) [1607194][T1_L0_G0][T1][YB42C4800102-000637377BFE570B-0-0] [lt=3][errcode=-9129] failed to list s3 objects(ret=-9129, bucket=oceanbase-TENANT, object=backup/log/, max_list_num=1000, delimiter=NULL)
[2025-06-20 07:59:39.141798] WDIAG list_files_ (ob_storage_s3_base.cpp:1861) [1607194][T1_L0_G0][T1][YB42C4800102-000637377BFE570B-0-0] [lt=6][errcode=-9129] fail to list s3 objects(ret=-9129, uri=s3://oceanbase-TENANT-backup/backup/log/)
[2025-06-20 07:59:39.141804] WDIAG [STORAGE] list_files (ob_storage.cpp:945) [1607194][T1_L0_G0][T1][YB42C4800102-000637377BFE570B-0-0] [lt=2][errcode=-9129] fail to list files(ret=-9129, uri=s3://oceanbase-TENANT-backup/backup/log)
[2025-06-20 07:59:39.141808] WDIAG [STORAGE] print_access_storage_log_ (ob_i_storage.cpp:912) [1607194][T1_L0_G0][T1][YB42C4800102-000637377BFE570B-0-0] [lt=3][errcode=-9129] access object storage cost too much time: list_files (ob_storage.cpp:928), uri=s3://oceanbase-TENAT-backup/backup/log, size=0 byte, start_time=1750406357549303, cost_ts=21592505 us, speed=0.00 MB/s, is_slow=1
[2025-06-20 07:59:39.141816] WDIAG inner_scan_dir_ (ob_object_device.cpp:790) [1607194][T1_L0_G0][T1][YB42C4800102-000637377BFE570B-0-0] [lt=6][errcode=-9129] fail to do list/dir scan!(ret=-9129, dir_name=s3://oceanbase-TENAT-backup/backup/log, is_dir_scan=false, is_marker_scan=false)
[2025-06-20 07:59:39.141824] WDIAG is_empty_directory (ob_backup_io_adapter.cpp:1281) [1607194][T1_L0_G0][T1][YB42C4800102-000637377BFE570B-0-0] [lt=6][errcode=-9129] fail to scan dir!(ret=-9129, ret="OB_OBJECT_STORAGE_IO_ERROR", uri=s3://oceanbase-TENAT-backup/backup/log, storage_info={endpoint "host=CLOUDFLARE-R2-ID.r2.cloudflarestorage.com/", access_id:"access_id=CLOUDFLARE-ACCESS-ID", extension "delete_mode=delete&checksum_type=md5&addressing_model=path_style", type:"S3", checksum_type:1, max_iops:0, max_bandwidth:0, role_arn:0x13a9db3a2a38, external_id:0x13
a9db3a2b38, enable_worm:false}, device_guard={device_handle_:0x13abbfd8dea0, uri_cstr_:s})
[2025-06-20 07:59:39.141846] WDIAG [SHARE] check_dest_validity (ob_backup_store.cpp:449) [1607194][T1_L0_G0][T1][YB42C4800102-000637377BFE570B-0-0] [lt=6][errcode=-9129] fail to check dest is empty dir
ctory(ret=-9129, backup_dest={root_path:"s3://oceanbase-TENAT-backup/backup/log", storage_info:{endpoint:"host=CLOUDFLARE-R2-ID.r2.cloudflarestorage.com/", access_id:"access_id=CLOUDFLARE-ACCESS-ID", extension:"delete_mode=delete&checksum_type=md5&addressing_model=path_style", type:"S3", checksum_type:1, max_iops:0, max_bandwidth:0, role_arn:0x13a9db390a38, external_id:0x13a9db390b38, enable_worm:false}})
[2025-06-20 07:59:39.141851] WDIAG [SHARE] check_before_update_inner_config (ob_backup_config.cpp:673) [1607194][T1_L0_G0][T1][YB42C4800102-000637377BFE570B-0-0] [lt=3][errcode=-9129] fail to update archive dest config(ret=-9129, tenant_id=1006)
[2025-06-20 07:59:39.141858] WDIAG [SHARE] update_inner_config_table (ob_backup_config.cpp:359) [1607194][T1_L0_G0][T1][YB42C4800102-000637377BFE570B-0-0] [lt=5][errcode=-9129] fail to check before update inner config(ret=-9129)
[2025-06-20 07:59:39.141860] WDIAG [RS] admin_set_backup_config (ob_root_service.cpp:11292) [1607194][T1_L0_G0][T1][YB42C4800102-000637377BFE570B-0-0] [lt=1][errcode=-9129] fail to update inner config table(ret=-9129)
[2025-06-20 07:59:39.142187] WDIAG [RS] admin_set_config (ob_root_service.cpp:8681) [1607194][T1_L0_G0][T1][YB42C4800102-000637377BFE570B-0-0] [lt=3][errcode=-9129] fail to set backup config(ret=-9129, arg={items:[{name:"log_archive_dest", value:"LOCATION=s3://oceanbase-TENAT-backup/backup/log?host=CLOUDFLARE-R2-ID.r2.cloudflarestorage.com/&access_id=CLOUDFLARE-ACCESS-ID&access_key=CLOUDFLARE-ACCESS-KEYf&delete_mode=delete&checksum_type=md5&addressing_model=path_style", comment:"", zone:"", server:"0.0.0.0:0", tenant_name:"TENANT", exec_tenant_id:1, tenant_ids:[], want_to_set_tenant_config:false}], is_inner:false})
[2025-06-20 07:59:39.142214] INFO  [SHARE] add_event (ob_event_history_table_operator.h:266) [1607194][T1_L0_G0][T1][YB42C4800102-000637377BFE570B-0-0] [lt=10] event table add task(ret=0, event_table_name="__all_rootservice_event_history", sql=INSERT INTO __all_rootservice_event_history (gmt_create, module, event, name1, value1, name2, value2, name3, value3, value4, value5, value6, rs_svr_ip, rs_svr
_port) VALUES (usec_to_time(1750406379142199), 'root_service', 'admin_set_config', 'ret', -9129, 'arg', '{name:"log_archive_dest", value:"LOCATION=s3://oceanbase-TENAT-backup/backup/log?host=CLOUDFLARE-R2-ID.r2.cloudflarestorage.com/&access_id=CLOUDFLARE-ACCESS-ID&access_key=CLOUDFLARE-ACCESS-KEYf&delete_mode=delete&checksum_type=md5&addressing_model=path_style", comment:"", zone:"", server:"0.0.0.0:0", tenant_name:"sitegroup", exec_tenant_id:1, tenant_ids:[], want_to_set_tenant_config:false}', 'is_inner', 0, '', '', '',
 '192.168.1.1', 2882))

使用 s3 客户端访问没问题,aws-sdk-cpp 的证书不是读取系统的吗?但是看前面的curl已经返回 cloduflare 的 server 头应该访问也没问题。
【复现路径】问题出现前后相关操作
【附件及日志】推荐使用OceanBase敏捷诊断工具obdiag收集诊断信息,详情参见链接(右键跳转查看):

【SOP系列 22 】——故障诊断第一步(自助诊断和诊断信息收集)

【备注】基于 LLM 和开源文档 RAG 的论坛小助手已开放测试,在发帖时输入 [@论坛小助手] 即可召唤小助手,欢迎试用!

2 个赞

根因分析场景: 日志归档问题
根因分析命令: obdiag rca run --scene=log_error
日志采集场景: 日志归档问题
日志采集命令: obdiag gather scene run --scene=observer.log_archive

为了更好地帮助您解决归档路径配置到 Cloudflare R2 对象存储时出现的证书错误问题,建议您使用上述 obdiag 命令进行日志采集和根因分析。这些命令将帮助我们收集与日志归档相关的详细信息,并定位可能的证书验证失败原因。

请您执行上述命令后,将生成的日志压缩包提供给我们以便进一步分析。

另外,在此需要您提供一些额外的信息以帮助我们更准确地诊断问题:

  1. 您是否已经正确配置了 Cloudflare R2 的访问密钥和相关权限?
  2. 您使用的 SSL/TLS 证书是否为受信任的 CA 签发?如果是自签名证书,请问是否已将其添加到系统的信任库中?
  3. 是否可以提供具体的错误日志片段(例如完整的 curl 错误信息)?
  4. 您是否尝试过通过其他工具(如 curl 或 wget)访问 Cloudflare R2 存储以验证网络连接和证书配置?
  5. OceanBase 集群运行的操作系统版本是什么?是否安装了最新的根证书更新?

附上敏捷诊断工具 obdiag 使用帮助链接

1 个赞

插眼

https://www.oceanbase.com/docs/common-oceanbase-database-cn-1000000002016161
麻烦参考这篇文档使用test_io_device测试一下

这个问题应该是 AWS CPP SDK 问题,参考这个 Issue。 OceanBase 的包是在 CentOS 下面编译的,所以根证书的路径是 /etc/pki/tls/certs/ca-bundle.crt , 而在 Ubuntu 中根证书的路径是 /etc/ssl/certs/ca-certificates.crt 。 如果其他 Debian 系的操作系统可以参考这个解决方案,复制或者软连接证书路径到 /etc/pki/tls/certs/ca-bundle.crt

mkdir -p /etc/pki/tls/certs && cp /etc/ssl/certs/ca-certificates.crt /etc/pki/tls/certs/ca-bundle.crt

但是 Cloudflare R2 的 S3 还是有兼容性问题,报400错误,请求参数错误。这个应该是 CheckSum 参数不支持。我现在在本地使用 JuiceFS 挂载来做归档和备份。

1 个赞

根据您的补充信息,问题的根源可以分为两个部分:


第一部分:证书路径不匹配

您提到的问题确实是由于 AWS SDK 在不同操作系统中查找根证书的路径不同导致的。OceanBase 社区版(CE)基于 CentOS 编译,因此默认会从 /etc/pki/tls/certs/ca-bundle.crt 路径读取根证书。而在 Ubuntu 或其他 Debian 系统中,默认路径为 /etc/ssl/certs/ca-certificates.crt

解决方案:

正如您提到的,可以通过以下命令解决路径不匹配问题:

mkdir -p /etc/pki/tls/certs && cp /etc/ssl/certs/ca-certificates.crt /etc/pki/tls/certs/ca-bundle.crt

或者创建软链接:

ln -s /etc/ssl/certs/ca-certificates.crt /etc/pki/tls/certs/ca-bundle.crt

这一步确保了 AWS SDK 能够正确找到根证书,从而避免 SSL/TLS 验证失败的问题。


第二部分:Cloudflare R2 的 S3 兼容性问题

即使解决了证书路径问题,您仍然遇到了 Cloudflare R2 的 S3 兼容性问题,具体表现为 400 Bad Request 错误,提示请求参数错误。经过分析,可能的原因如下:

  1. CheckSum 参数不支持
    根据您的描述,Cloudflare R2 的 S3 实现可能存在对某些参数(如 checksum_type=md5)的支持不足或不兼容的情况。OceanBase 默认在归档配置中添加了 checksum_type=md5 参数,而 Cloudflare R2 可能无法识别或处理该参数。

  2. S3 API 的实现差异
    Cloudflare R2 的 S3 兼容性并非完全遵循 AWS S3 的标准,可能存在一些细微的差异,导致 OceanBase 的 S3 客户端与 Cloudflare R2 之间的交互出现问题。

解决方案:

针对上述问题,您可以尝试以下方法:

  1. 移除 checksum_type=md5 参数
    修改归档路径配置时,去掉 checksum_type=md5 参数,例如:

    ALTER SYSTEM SET LOG_ARCHIVE_DEST='LOCATION=s3://oceanbase-TENANT-backup/backup/log?host=CLOUDFLARE-R2-ID.r2.cloudflarestorage.com/&access_id=CLOUDFLARE-ACCESS-ID&access_key=CLOUDFLARE-ACCESS-KEY&delete_mode=delete&addressing_model=path_style' TENANT=TENANT;
    

    这样可以避免因 CheckSum 参数不支持而导致的兼容性问题。

  2. 使用 JuiceFS 挂载本地存储
    如果 Cloudflare R2 的 S3 兼容性问题无法完全解决,您可以继续使用 JuiceFS 将对象存储挂载为本地文件系统,然后将归档和备份路径指向挂载点。这种方法可以绕过 S3 兼容性问题,同时保持功能正常运行。

  3. 联系 Cloudflare 支持团队
    如果您希望直接使用 Cloudflare R2 作为归档目标,建议联系 Cloudflare 支持团队,确认其 S3 实现是否支持 OceanBase 所需的所有参数,并获取进一步的技术支持。


总结

  • 证书路径问题:通过复制或软链接的方式统一证书路径即可解决。
  • Cloudflare R2 兼容性问题:尝试移除 checksum_type=md5 参数,或者使用 JuiceFS 挂载对象存储作为替代方案。
  • 如果仍有问题,建议收集更多日志信息(如 observer.logobdiag 输出),并联系 OceanBase 技术支持团队以获取进一步帮助。

希望以上解决方案能够帮助您顺利解决问题!

检索到的文档如下:

  1. RPC 连接认证
  2. DBMS_TRUSTED_CERTIFICATE_MANAGER 概述
  3. ADD_TRUSTED_CERTIFICATE
  4. 4000 ~ 4499
  5. 4500 ~ 4999
  6. 9000 ~ 9499
  7. UPDATE_TRUSTED_CERTIFICATE
  8. 8000 ~ 8999
  9. 10000 ~ 12000

(小助手的答复已结束,如未能解决您的问题,请继续提问并等待其他同学的回复,谢谢!)