- 集群部署并启动集群
- 部署操作
- 排错流程
- 时钟同步测试
- 集群数据库测试
- MySQL 报文和 RPC 流量监控
- 抓包分析
集群部署并启动集群
部署操作
选择使用 OBD 部署 OB 数据库并启动集群,首先使用 “name -m” 命令查看 Linux 的处理器架构,例如我的虚拟机查出来是 “x86_64”。

接着到 OB 官网下载对应版本的 OceanBase All in One,将下载好的文件复制到虚拟机上。


接着进入安装包所在的目录,键入如下命令解压文件,运行安装脚本。
$ tar -xzf oceanbase-all-in-one-*.tar.gz
$ cd oceanbase-all-in-one/bin/
$ ./install.sh
$ source ~/.oceanbase-all-in-one/bin/env.sh

键入命令后等待安装完成,终端输出“Install Finished”信息说明已经完成操作。

安装好 obd 后,运行命令启动部署界面。
obd web


点击配套工具进行部署,选择第一项“OceanBase 及配套工具”。

例如集群名称取名为“AIGC”,其他配置使用默认的选项。

在节点配置界面设置 3 个节点,此处我是使用一台服务器同时开了 3 台 Ubuntu 虚拟机,使用 192.168.195.131 作为 OCP Express 和 OBProxy 节点。

用户配置方面,3 台虚拟机都设置了一个相同的用户 lzk,用于虚拟机之间的 SSH 连接。

保存生成的 root@sys 密码,其他的目录、日志和端口配置都默认。


设置完之后进行预检查,根据预检查的结果进行排错直到预检查通过。


等待部署直到成功,将访问地址和账密信息记录下来。


排错流程
接下来汇总一下排错过程,第一次配置的时候先报了一个“OBD-1013”,从报错信息和官方错误码文档中得出是 SSH 配置有问题,主机和从机之间无法用 SSH 连接。


因为忘了安装 SSH 服务,先进行安装。
apt-get install openssh-server

等待 SSH 安装完成后启用 SSH,查看 SSH 已经服务成功启动。
service ssh start
ps -e | grep ssh

解决完“OBD-1013”之后再次进行预检查,报了“OBD-2003”和“OBD-1007”两个新的错误。

“OBD-2003”比较简单,就是磁盘空间开得不够大。

这台原来配的虚拟机只分配了 20G,虽然可以扩展磁盘空间到满足要求,但是扩容后还需要进行挂接和分区。这个要搞还是比较费劲的,而且原来配的这个虚拟机也不是 Ubuntu20 以上,我就干脆直接重新起一台新的虚拟机了,也不怎么费时。

接着是“OBD-1007”,主要原因是系统的 ulimits 配置不满足要求,我碰到了"open files”和"max user processes"两个参数不满足运行条件。open files 参数指定了能同时运行的句柄的数量,max user processes 顾名思义是最大的用户进程数量。也不难理解,OB需要同时运行大量句柄和进程。

OBD-1007: (192.168.195.131) The value of the ulimit parameter "open files" must not be less than 20000 (Current value: 1024)

OBD-1007: (192.168.195.131) The value of the ulimit parameter "max user processes" must not be less than 120000 (Current value: 36054)

直接修改“/etc/security/limits.conf”文件,按照OB的运行要求进行相应的设置即可。
sudo vi /etc/security/limits.conf

对 192.168.195.131 主机进行相应的设置之后,该虚拟机通过了预检查。接下来只需要对其他两台虚拟机进行相同的设置,或者直接克隆两台新的虚拟机就行。

时钟同步测试
OB 集群中的服务器时间必须保持一致,否则会导致 OB 集群无法启动,运行时也会出现故障。物理机与时钟服务器的误差在 50ms 以下可认为时钟是同步状态,最大容忍误差不能超过 100ms,否则会出现无主情况。恢复时钟同步后,重启 OB 集群可以恢复正常。
首先使用“obd cluster list”查看已经运行的集群,从下图可见上文中配置的 aigc 集群已经正常运行。
obd cluster list

使用“obd cluster stop aigc”命令停止 aigc 集群的运行。
obd cluster stop aigc

接着在 192.168.195.132 主机上修改时间,我这边比较简单,直接进入设置修改。


接着使用“obd cluster start aigc”命令在 192.168.195.131 主机上启用集群,此时 OB 报错“OBD-2008”,通过报错信息可知是集群时钟没有同步。
obd cluster start aigc

对 192.168.195.132 主机设置自动对时,恢复为正确的时间后再次启动集群,就能成功启动,验证了 OB 的时钟同步机制。



集群数据库测试
集群启动之后直接键入 OB 数据库连接命令进行连接,然后启用数据库。
obclient -h192.168.195.131 -P2881 -uroot -p'QuWhpyGVA]{r1K1j' -Doceanbase -A
USE oceanbase;

接着键入用于测试的查询语句,OB 返回 3 个节点的基本信息,完成集群测试。
SELECT * FROM __all_server;

MySQL 报文和 RPC 流量监控
查看 OB 的官方文档,在租户类型介绍中提到系统租户使用 1 号日志流。进行测试时也是使用系统租户进行登录,因此日志被记录在1号日志流中。


查询 OB 的 “GV$SYSSTAT” 视图的官方文档,租户 ID 的字段为“CON_ID”,因此在对视图查询时可以指定该字段的值为 1 进行过滤。

运行这个查询语句,得到对 GV$SYSSTAT 视图的 1 号日志流的查询结果。可以看到返回的结果有 1521 条记录,非常多不利于进一步分析。
SELECT * FROM oceanbase.gv$sysstat WHERE CON_id = '1';


对于 MySQL 的报文数量和 RPC 的流量进行查看并分析,主要的字段有下表所示的 8 个。
| 统计事件的名称 | 说明 | 统计值类型 |
|---|---|---|
| rpc packet in | RPC包接收的数量 | ADD累加 |
| rpc packet in bytes | RPC包接收的bytes数量 | ADD累加 |
| rpc packet out | RPC包发送的数量 | ADD累加 |
| rpc packet out bytes | RPC包发送的bytes数量 | ADD累加 |
| mysql packet in | MySQL包接收的数量 | ADD累加 |
| mysql packet in bytes | MySQL包接收的bytes数量 | ADD累加 |
| mysql packet out | MySQL包发送的数量 | ADD累加 |
| mysql packet out bytes | MySQL包发送的bytes数量 | ADD累加 |
要把这些事件的记录挑出来只需要在查询语句中对“NAME”字段加上正则表达式匹配“rpc packet”和“mysql packet”两个字符串即可,键入查询语句得到查询结果。可以看到返回的结果的行数不多,将这份数据作为初始状态,便于后续的分析。
SELECT * FROM oceanbase.gv$sysstat WHERE (CON_id = '1') and (NAME like '%rpc packet%' or NAME like '%mysql packet%');

首先进行本地连接测试,在 192.168.195.131 主机上连接 OB 并进行查询操作,然后再次运行对 GV$SYSSTAT 视图的查询语句得到更新后的结果。


整理一下两次的查询结果,对查询得到的值作差。可见进行的 OB 连接和数据库查询操作产生了非常多的数据包和流量,并且主机会和从机之间也进行了一些 RPC 和 MySQL 操作。
| CON_ID | SVR_IP | NAME | 操作前的VALUE | 操作后的VALUE | 差值 |
|---|---|---|---|---|---|
| 1 | 192.168.195.131 | rpc packet in | 2026676 | 2074981 | 48305 |
| 1 | 192.168.195.131 | rpc packet in bytes | 733790323 | 748814659 | 15024336 |
| 1 | 192.168.195.131 | rpc packet out | 1216061 | 1244042 | 27981 |
| 1 | 192.168.195.131 | rpc packet out bytes | 816951427 | 831640451 | 14689024 |
| 1 | 192.168.195.131 | mysql packet in | 19234 | 19757 | 523 |
| 1 | 192.168.195.131 | mysql packet in bytes | 2589328 | 2655645 | 66317 |
| 1 | 192.168.195.131 | mysql packet out | 302409 | 310658 | 8249 |
| 1 | 192.168.195.131 | mysql packet out bytes | 30268 | 31240 | 972 |
| 1 | 192.168.195.133 | rpc packet in | 1444553 | 1482035 | 37482 |
| 1 | 192.168.195.133 | rpc packet in bytes | 607358406 | 619800141 | 12441735 |
| 1 | 192.168.195.133 | rpc packet out | 1184841 | 1215355 | 30514 |
| 1 | 192.168.195.133 | rpc packet out bytes | 671060424 | 687553526 | 16493102 |
| 1 | 192.168.195.133 | mysql packet in | 16101 | 16409 | 308 |
| 1 | 192.168.195.133 | mysql packet in bytes | 2314886 | 2367916 | 53030 |
| 1 | 192.168.195.133 | mysql packet out | 209850 | 213824 | 3974 |
| 1 | 192.168.195.133 | mysql packet out bytes | 6748 | 6832 | 84 |
| 1 | 192.168.195.132 | rpc packet in | 1981569 | 2035527 | 53958 |
| 1 | 192.168.195.132 | rpc packet in bytes | 1225534403 | 1253386684 | 27852281 |
| 1 | 192.168.195.132 | rpc packet out | 1570138 | 1610747 | 40609 |
| 1 | 192.168.195.132 | rpc packet out bytes | 979736827 | 1000317809 | 20580982 |
| 1 | 192.168.195.132 | mysql packet in | 22649 | 23367 | 718 |
| 1 | 192.168.195.132 | mysql packet in bytes | 2691989 | 2771550 | 79561 |
| 1 | 192.168.195.132 | mysql packet out | 283683 | 292675 | 8992 |
| 1 | 192.168.195.132 | mysql packet out bytes | 10284 | 10580 | 296 |
接着进行远程连接测试,在 192.168.195.132 主机上连接 OB 并进行查询操作,然后再次运行对 GV$SYSSTAT 视图的查询语句得到更新后的结果。


将此次查询到的结果和本地连接测试的结果进行汇总,并计算差值。可以看出和本地连接其实很接近,由于主机和从机之间本身就会进行频繁的交互,两次查询的差值还是很大。
| CON_ID | SVR_IP | NAME | 操作前的VALUE | 操作后的VALUE | 差值 |
|---|---|---|---|---|---|
| 1 | 192.168.195.131 | rpc packet in | 2074981 | 2134993 | 60012 |
| 1 | 192.168.195.131 | rpc packet in bytes | 748814659 | 767443314 | 18628655 |
| 1 | 192.168.195.131 | rpc packet out | 1244042 | 1279343 | 35301 |
| 1 | 192.168.195.131 | rpc packet out bytes | 831640451 | 849754822 | 18114371 |
| 1 | 192.168.195.131 | mysql packet in | 19757 | 20332 | 575 |
| 1 | 192.168.195.131 | mysql packet in bytes | 2655645 | 2738354 | 82709 |
| 1 | 192.168.195.131 | mysql packet out | 310658 | 319080 | 8422 |
| 1 | 192.168.195.131 | mysql packet out bytes | 31240 | 32020 | 780 |
| 1 | 192.168.195.133 | rpc packet in | 1482035 | 1530249 | 48214 |
| 1 | 192.168.195.133 | rpc packet in bytes | 619800141 | 636096895 | 16296754 |
| 1 | 192.168.195.133 | rpc packet out | 1215355 | 1254313 | 38958 |
| 1 | 192.168.195.133 | rpc packet out bytes | 687553526 | 709203660 | 21650134 |
| 1 | 192.168.195.133 | mysql packet in | 16409 | 16804 | 395 |
| 1 | 192.168.195.133 | mysql packet in bytes | 2367916 | 2440172 | 72256 |
| 1 | 192.168.195.133 | mysql packet out | 213824 | 219150 | 5326 |
| 1 | 192.168.195.133 | mysql packet out bytes | 6832 | 6932 | 100 |
| 1 | 192.168.195.132 | rpc packet in | 2035527 | 2127011 | 91484 |
| 1 | 192.168.195.132 | rpc packet in bytes | 1253386684 | 1329913533 | 76526849 |
| 1 | 192.168.195.132 | rpc packet out | 1610747 | 1681328 | 70581 |
| 1 | 192.168.195.132 | rpc packet out bytes | 1000317809 | 1057959447 | 57641638 |
| 1 | 192.168.195.132 | mysql packet in | 23367 | 24263 | 896 |
| 1 | 192.168.195.132 | mysql packet in bytes | 2771550 | 2871048 | 99498 |
| 1 | 192.168.195.132 | mysql packet out | 292675 | 303863 | 11188 |
| 1 | 192.168.195.132 | mysql packet out bytes | 10580 | 10960 | 380 |
抓包分析
键入如下命令启动 Tcpdump,先抓本地连接的包,另起一个终端键入 OB 连接语句和查询语句,然后终止连接并停止抓包,将结果保存为 local.cap 文件。
tcpdump tcp -vvv and port 2881 -w ./local.cap

发往本地的包不会通过以太网进行传输,而是通过 Loopback 回到本地。在192.168.195.131 主机上安装 Wireshark,直接在“Loopback: lo”网卡上进行抓包,同样键入 OB 连接语句和查询语句后停止抓包并保存结果为“local3.pcapng”。


接着对结果进行分析,由于即使不进行 OB 连接的操作,主机和从机之间也会进行频繁的交互行为,而且其他进程也会在环回口做很多操作,产生的流量包非常多。因此需要先找出相关的数据包,然后通过 Wireshark 的流汇聚功能进行分析。
我的操作也比较简单,由于建立连接后 OB 会返回服务器的版本号给终端,因此我直接在 Wireshark 对版本号中选择“分组字节流”和“字符串”,对字符串“r10000”进行查询,经过排查后看到 Frame 733 的 Data 包含了这些信息。
Server version: OceanBase_CE 4.3.0.1(r100000242024032211- 0193a343bc60b4699ec47792c3fc4ce 166a182f9) (Built Mar 22 2024 13:19:48)

接着对 Frame 733 追踪 TCP 流,结果如下图所示,可以看到汇聚后可以大致分为 4 个部分。第一部分连接方向OB发出连接请求,然后第二部分 OB 返回了相关的连接信息(包括 OB 版本号),同时也能看到连接方查询了数据库版本信息。接着也可以看到我们键入的“SELECT *FROM __all_serverc”语句,然后 OB 返回了查询后的结果信息,这些与查询结果得到的结果是一样的。

将“显示和保存数据为”设置为“YAML”,可以看到在 TCP 流 53 中通过了 Packet 725、728、731、732、733、734、743、1454、1457、1864(最后一个没截图出来)几个数据包进行交互。Packet 728 为发送方发起了 OB 连接的请求,然后 OB 在 Packet 731 发回了建立连接的响应信息。接着在 Packet 732 中发送方发出“select @@version_comment, @@version limit 1”查询相关版本信息,Packet 733 为 OB 对该查询得到的响应信息。然后在 Packet 732 中发送方发出“select @@version_comment limit 1”进行查询,Packet 743 为 OB 对该查询得到的响应信息,这些就构成了建立连接后终端显示出来的信息。
前面这几个数据包是连续发出的,因此 Packet 的序号比较接近,距离我键入查询语句之间有一个反应时间,因此 Packet 1454 是我输入的“SELECT * FROM __all_serverc”查询语句。然后 OB 完成查询操作后,在 Packet 1457 发回了查询的结果。


接着抓远程连接的包,在 192.168.195.132 主机上起一个终端键入OB连接语句和查询语句,然后终止连接并停止抓包,将结果保存为 remote.cap 文件。
tcpdump tcp -vvv and port 2881 -w ./remote.cap

用 Wireshark 打开 remote.cap 文件,使用相同的方法找到一个相关的分组 Frame 37。

接着对 Frame 37 追踪 TCP 流,结果如下图所示,同样可以看到“select @@version_comment, @@version limit 1”、“select @@version_comment limit 1”、“SELECT *FROM __all_serverc”语句。然后 OB 返回了查询后的结果信息,这部分查询的结果一样,就不再赘述了。

将“显示和保存数据为”设置为“YAML”,可以看到在 TCP 流 5 中连接语句通过了Packet 31、33、35、36、37、38、39 几个数据包进行交互,查询语句通过118、119、206(最后一个没截图出来)几个数据包进行交互。此处的分析也和本地连接的包一致,就不再赘述了。

