OB 运维 | 一则 OMS 关联 OCP 报内部错误的诊断案例

2024-09-14 16:26:07 浏览数 (2)

作者:任仲禹,爱可生数据库高级工程师,擅长故障分析和性能优化。 爱可生开源社区出品,原创内容未经授权不得随意使用,转载请联系小编并注明来源。

本文约 1500 字,预计阅读需要 5 分钟。


OceanBase 的 OMS 迁移工具功能很丰富,但实际运维中可能会遇到形形色色的问题,服务器内部错误 是比较 "令人头疼" 的一种报错(界面上往往无多余的有效信息提供排查),那么该如何着手呢?

本文将分享一例 OMS 关联 OCP 报 服务器内部错误 的诊断过程与思路。

1背景信息

涉及的软件版本如下:

  • OMS 402bp2
  • OCP 410

该案例属于实际客户场景触发报错,故障时 OMS 能够正常访问到 OCP ,但是 OMS 白屏界面操作 添加关联 OCP 该步骤时将报错 服务器内部错误 ,如下图所示。

2问题诊断

1. 日志分析

由于 OMS 白屏界面除 服务器内部错误 外无其它报错信息帮助诊断问题,所以第一时间准备登到 OMS 容器上查看 OMS-Console 组件日志。

题外话,OMS 界面相关的例如显示问题、点击按钮报错等首选查看 Console 组件日志

  • OMS 容器内日志路径:/home/admin/logs/ghana/Ghana/comon-error.log
  • 过滤 ERROR 关键字

收集到的有效信息是 SQL 执行报错 “插入的数据没有指定 ocp_proxy_host 列或者该字段没有默认值”。

代码语言:javascript复制
### The error occurred while setting parameters
### SQL: INSERT INTO ocp_info ( id, ocp_domain, ocp_api_user, ocp_api_password, ocp_charset, ocp_version, region, ocp_name) VALUES (?, ?, ?, ?, ?, ?, ?, ?)
### Cause: java.sql.SQLTransientConnectionException: (conn=783124) Field 'ocp_proxy_host' doesn't hava d default value;

2.元数据库排查

继续沿着上文线索进入 OMS 的 metadb 元数据库中,查询 oms_rm 库下的 ocp_info 表结构,如下图所示。

目前可知 OMS 关联 OCP 时需要向表 ocp_info 中插入一条数据,如果 SQL 执行报错或其它原因就导致了页面触发 服务器内部错误

  • 插入的语句:INSERT INTO ocp_info ( id, ocp_domain, ocp_api_user, ocp_api_password, ocp_charset, ocp_version, region, ocp_name) VALUES ...
  • SQL 执行报错 "Field 'ocp_proxy_host' doesn't have a default value." 的原因是表结构 ocp_info 中字段 ocp_proxy_host 属性是 NOT NULL,并且没有 default 值。
  • 这里的疑问:OMS 为啥下发一条“注定”会执行报错的 SQL ? 难道是 BUG?

排查到这里,咨询 OB 产研得到的反馈是这个 ocp_info 表的 ocp_proxy_host、ocp_proxy_port、ocp_meta_user、ocp_meta_password、ocp_meta_db 字段已经在 OMS 402 版本中被去除了,所以还得继续分析为啥 ocp_info 的表结构不符合预期。

是否是部署的 OMS 402 版本读取了老版本的 metadb 库?

3.OAT 部署排查

沿着安装部署溯源,通过 OAT 排查到该 OMS 是 7月1日 15:39 部署的,如下图。

比对 OMS metadb 中 ocp_info 表的创建日期和该 OMS 集群的部署日期。

查询 oceanbase.__all_virtual_table 表,关注 gmt_creategmt_modified 字段。

发现 ocp_info 表创建更晚于 OMS 创建,所以先排除读取到了老版本的 metadb 库。

继续分析 OAT 的部署流程,在 start_first_batch_oms_container 步骤中发现了 ERROR 信息,如下图。

OAT 部署任务中,start_first_batch_oms_container 步骤记录了 OMS metadb 相关的 DDL init 脚本导入记录。

上图中的报错结合 OMS 容器中( /root/omsflow/meta_init/drc_rm_schema.sql )文件发现 ocp_info 表对应字段的 DROP 操作在 OAT 中显示全部执行失败。

这里的 2 个问题点:

  • 问题 1:为啥 ALTER TABLE ocp_info DROP COLUMN ... 执行失败?
  • 问题 2:SQL 执行失败为啥 OMS 初始化元数据成功,OAT 没有报错?

问题 1

通过排查,DROP Column 失败是因为 DDL 执行的时间点,OMS 所在 metadb Cluster 处于运维状态 (其中一个 OBServer 宕机),导致 DROP Column 的DDL 无法执行,这个不太重要,关键在于 问题 2 OAT 未抛出报错。

问题 2

OAT 中初始化 DDL 调用的 SQL 执行失败了按理应该抛出报错,需要人工介入才是,为啥 OAT 还显示 start_first_batch_oms_container 步骤正常完成呢,这点比较重要得继续排查。

逐个翻阅 start_first_batch_oms_container 任务的调用步骤,发现问题大概出在这一步:

代码语言:javascript复制
[2023-07-01T15:49:20.785 0800] INFO -  mysql -h 'xxxxx' -P2883 -u 'root@oms_meta#xxxxxx' --password='xxxxxx'   -f -D 'oms_rm' < /root/omsflow/meta_init/drc_rm_schema.sql " 
  • 上文将 DDL init 脚本(drc_rm_schema.sql )导入 OMS 元数据库时,加了 " -f " ,该参数是 mysql 客户端忽略报错的行为。
  • 问题 3:为啥加了 " -f " 参数会有问题?

问题 3

首先,OAT 只能判断 DDL init 脚本的执行结果,OAT start_first_batch_oms_container 任务中展示的实际是容器里的DDL init 脚本执行的输出 (例如 SQL 的执行是否报错)。

然而,当指定了 " -f " 参数时,将忽略 init 脚本中的 SQL 执行报错。

所以,OAT 获取到 init 脚本执行的报错码是 0,OAT 判断任务正常完成。

代码语言:javascript复制
# 示例
[root@10-186-58-75 ~]# cat 1.sql
select 11 from bbbb;
select 13,a from renzy.t;
[root@10-186-58-75 ~]# mysql -h10.186.58.75 -P8001 -uroot -proot  -f < 1.sql
ERROR 1046 (3D000) at line 1: No database selected
ERROR 1049 (42000) at line 4: Unknown database 'renzy'
[root@10-186-58-75 ~]# echo $?
0

3临时修复

进入 OMS 容器,按 OMS 容器初始化脚本提示(下图所示),单独重新执行【步骤二】OMS 元信息库初始化步骤即可(该步骤幂等性,可反复执行)。

代码语言:javascript复制
python -m omsflow.scripts.units,oms_init_manager --init-db

4结论

  1. 本次案例 OMS 无法关联 OCP (报“服务器内部错误”)是由于要往 OMS 的 metadb 中注册一条信息(insert SQL),而这条 SQL 因为 metadb 中表结构不正确导致执行失败。
  2. 表结构不正确是由于 OAT 安装 OMS 时调用了 oms_init metadb 脚本, oms_init 脚本中导入 SQL 时忽略了报错,导致元数据库表结构和预期不符。
  3. 第 2 条结论笔者已提 OB 官方,产研已确认为缺陷,并反馈将修复在 OMS 421 版本。

本文关键字:#OceanBase# #OMS# #OCP#

0 人点赞