本文约 1500 字,预计阅读需要 5 分钟。
OceanBase 的 OMS 迁移工具功能很丰富,但实际运维中可能会遇到形形色色的问题,服务器内部错误 是比较 "令人头疼" 的一种报错(界面上往往无多余的有效信息提供排查),那么该如何着手呢?
本文将分享一例 OMS 关联 OCP 报 服务器内部错误 的诊断过程与思路。
涉及的软件版本如下:
该案例属于实际客户场景触发报错,故障时 OMS 能够正常访问到 OCP ,但是 OMS 白屏界面操作 添加关联 OCP 该步骤时将报错 服务器内部错误 ,如下图所示。
由于 OMS 白屏界面除 服务器内部错误 外无其它报错信息帮助诊断问题,所以第一时间准备登到 OMS 容器上查看 OMS-Console 组件日志。
题外话,OMS 界面相关的例如显示问题、点击按钮报错等首选查看 Console 组件日志
收集到的有效信息是 SQL 执行报错 “插入的数据没有指定 ocp_proxy_host
列或者该字段没有默认值”。
### 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;
继续沿着上文线索进入 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 ...
"Field 'ocp_proxy_host' doesn't have a default value."
的原因是表结构 ocp_info
中字段 ocp_proxy_host
属性是 NOT NULL,并且没有 default 值。排查到这里,咨询 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 库?
沿着安装部署溯源,通过 OAT 排查到该 OMS 是 7月1日 15:39 部署的,如下图。
比对 OMS metadb 中 ocp_info
表的创建日期和该 OMS 集群的部署日期。
查询
oceanbase.__all_virtual_table
表,关注gmt_create
和gmt_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 个问题点:
ALTER TABLE ocp_info DROP COLUMN ...
执行失败?通过排查,DROP Column 失败是因为 DDL 执行的时间点,OMS 所在 metadb Cluster 处于运维状态 (其中一个 OBServer 宕机),导致 DROP Column 的DDL 无法执行,这个不太重要,关键在于 问题 2 OAT 未抛出报错。
OAT 中初始化 DDL 调用的 SQL 执行失败了按理应该抛出报错,需要人工介入才是,为啥 OAT 还显示 start_first_batch_oms_container 步骤正常完成呢,这点比较重要得继续排查。
逐个翻阅 start_first_batch_oms_container 任务的调用步骤,发现问题大概出在这一步:
[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 "
首先,OAT 只能判断 DDL init 脚本的执行结果,OAT start_first_batch_oms_container 任务中展示的实际是容器里的DDL init 脚本执行的输出 (例如 SQL 的执行是否报错)。
然而,当指定了 " -f " 参数时,将忽略 init 脚本中的 SQL 执行报错。
所以,OAT 获取到 init 脚本执行的报错码是 0,OAT 判断任务正常完成。
# 示例
[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
进入 OMS 容器,按 OMS 容器初始化脚本提示(下图所示),单独重新执行【步骤二】OMS 元信息库初始化步骤即可(该步骤幂等性,可反复执行)。
python -m omsflow.scripts.units,oms_init_manager --init-db
本文关键字:#OceanBase# #OMS# #OCP#