作者:贲绍华
爱可生研发中心工程师,负责项目的需求与维护工作。其他身份:柯基铲屎官。
本文来源:原创投稿
*爱可生开源社区出品,原创内容未经授权不得随意使用,转载请联系小编并注明来源。
一、问题现象:
使用RPM的方式部署proxy实例,部署之后使用OBclient进行连接,报错提示:
ERROR 2013 (HY000): Lost connection to MySQL server at ‘reading authorization packet’, system error: 11
二、介绍:
2.1 OceanBase介绍:
OceanBase是企业级开源分布式 HTAP(Hybrid Transaction/Analytical Processing)数据库,具有原生分布式架构,支持金融级高可用、透明水平扩展、分布式事务、多租户和语法兼容等企业级特性。
OceanBase 数据库采用 Shared-Nothing 架构,各个节点之间完全对等,每个节点都有自己的 SQL 引擎、存储引擎,运行在普通PC服务器组成的集群之上,具备可扩展、高可用、高性能、低成本、云原生等核心特性。
2.2 OBproxy介绍:
OceanBase Database Proxy(简称 ODP)是 OceanBase 数据库专用的代理服务器。OceanBase 数据库的用户数据以多副本的形式存放在各个 OBServer 上,ODP 接收用户发出的 SQL 请求,并将 SQL 请求转发至最佳目标 OBServer,最后将执行结果返回给用户。
三、相关说明:
3.1 版本与架构:
OceanBase:3.1.4
OceanBase proxy:3.2.3.5
OceanBase实例数:1 台(10.186.60.96)
OceanBase proxy实例数:1台 (172.20.134.5)
3.2 OBproxy的两种启动模式:
OBproxy配置代理的数据库集群是通过启动参数来设置的,目前支持如下两种形式进行指定数据库集群:
-
ConfigURL(代理多个数据库集群):
多集群启动方式,即该 OBProxy 集群可访问多个 OceanBase 集群。OCP管理平台自身已集成该服务,
如果是开源版的可以参考该仓库进行ConfigURL服务的部署:https://github.com/oceanbase/oceanbase/tree/master/tools/ob-configserver
-
RSList(仅代理单个数据库集群):
单集群启动方式,即该 OBProxy 集群仅可访问创建 OBProxy 集群时指定的那个 OceanBase 集群,OBProxy 实例启动成功后不可动态追加可连接的 OceabBase 数据库集群。配置形式为,OceanBase数据库集群的root service列表:192.168.0.1:2881,192.168.0.2:2881
四、操作流程:
以下操作均使用开源版本RPM手动部署部署的方式进行,未使用OBD与OCP。
1.登录OceanBase数据库内,新建proxyro用户并设置密码为123456,添加授权:
$ obclient -h10.186.60.96 -uroot@sys -P2881 -p -c -A
Enter password:
obclient> CREATE USER proxyro IDENTIFIED BY '123456';
Query OK, 0 rows affected
obclient> GRANT SELECT ON *.* TO proxyro;
Query OK, 0 rows affected
obclient> SHOW GRANTS FOR proxyro;
+----------------------------------+
| Grants for proxyro@% |
+----------------------------------+
| GRANT SELECT ON *.* TO 'proxyro' |
+----------------------------------+
1 row in set
2.使用RPM安装proxy:
SUDO rpm -ivh --force /tmp/obproxy-ce-3.2.3.5-2.el7.x86_64.rpm
3.启动proxy实例:
cd /home/admin/obproxy-3.2.3.5 && ./bin/obproxy -p 2883 -l 2884 -n test-proxy -o observer_sys_password=7c4a8d09ca3762af61e59520943dc26494f8941b -c ‘ob_xxxxxxxx’ -r “10.186.60.96:2882”
4.启动OBproxy进程,并为其增加守护进程:
# 返回当前proxy实例的进程数,如果为1则代表已启动
[root@localhost]# pgrep -c obproxy | xargs --no-run-if-empty
# 启动proxy守护进程shell,使用RPM的形式进行安装时。会在bin目录提供管理用的shell文件
[root@localhost]# bin/obproxyd.sh -c checkalive -r -n test-proxy -p 2883 -t 10.186.60.96:2882 -s ob_xxxxxxxx &
# 再次检测proxy实例进程数,如果为2则代表符合预期:实例进程 + checkealive守护进程
[root@localhost]# pgrep -c obproxy | xargs --no-run-if-empty
5.登入OBproxy查看配置是否正确,尝试通过proxy实例连接数据库集群,连接失败:
五、诊断过程:
5.1 检查实例进程:
进程运行正常,符合预期。且运行用户为admin(根据官方手册说明,如果在非部署目录或使用非admin用户运行会导致一些奇怪的问题出现)
5.2 root service list参数检查:
proxy要代理那台数据库实例是通过RSlist参数决定的,登入proxy实例,查看proxy内的root service list参数,存在10.186.90.63
5.3 日志检查
观察obproxy.log发现两条警告信息,意思为无法通过RSlist找到集群名为XXXX的数据库集群
5.4 确认数据库集群名称
登入OceanBase数据库集群,查看集群名称,确认与启动参数中指定的名称一致
SELECT * FROM `v$ob_cluster`
5.5 检查proxy连接账号:
检查OceanBase数据库集群内是否存在proxyro的连接账号(用户名必须为这个),且密码是否符合预期;
六、结论:
最后经过官方大佬——序风远程支持,定位到问题原因:
启动参数中root service list的IP:Port中的端口,应为OceanBase数据库的SQL port端口2881,而不是2882(RPC端口)
这次的问题引起的原因其实很好理解,但是排查起来比较费劲儿(进程能正常启动运行、日志只有找不到数据库集群名的错误、各项数据源确认也都符合预期),回头来看排查过程中遗漏了一个确认点,就是没有在数据库集群上验证RSlist参数的正确性。
七、其他:
使用过程中发现了两处缺陷,分别是:
a. obproxyd.sh脚本的启动参数说明有误
b. obproxyd.sh脚本结束符存在错误导致无法运行
已向官方提交了PR,感兴趣的可以关注一下:https://github.com/oceanbase/obproxy/pull/28
另外提一点建议:
在RSlist模式下,当启动参数出现错误时可以尝试在启动实例进程时尝试与数据库实例建立连接并校验参数正确性。如不符合预期可以退出进程将错误输出至STD上。或者在detail日志内增加一些描述,如:为什么找不到集群的cluster_name。这样会更方便定位问题。
最后祝OceanBase开源社区越办越红火,给你们的响应速度点赞!(社区工单有专人轮值,一般三小时内都有回复)