在一些业务中存在需要在周末进行测试的场景:在周末期间,需要将 OceanBase 的主备库角色切换,切换后直接在物理备库上进行应用升级及升级后验证的真实场景测试。由于应用往往由几十个甚至更多的微服务组成,重启所有的微服务耗时往往以小时计算。因此,整个周末测试的过程中,希望能够保持应用配置的数据库连接串信息不变,这样可以跳过耗时的微服务重启流程。
在 OceanBase 数据库 V2.x/V3.x 版本中,可以通过 OceanBase 的主备 OceanBase 数据库集群角色切换+网络侧修改 DNS 服务器上 VIP 域名解析地址的方式来实现上述需求。
OceanBase V4.x 版本上不再具有集群级主备角色的概念,只有租户级别的主备库。因此,在 OceanBase 数据库 V4.2.x/V4.3.x 的高版本中引入了 Service Name 服务名的概念,也可以实现上述的需求。
本文主要介绍 OceanBase 数据库 V4.x 版本中如何通过 Service Name 来实现周末测试演练的需求。
有关 Service Name 的详细说明
Service Name 是 OceanBase 提供的一种新的数据库访问方式,可以视其为集群 & 租户名的别名,实现应用程序通过如 mysql -h192.168.100. xxx-P2883 -uroot@SERVICE:<Service_Name> 的连接串访问数据库。从 OceanBase 数据库 V4.1 版本开始高可用解决方式变更为租户级主备库,集群级不再有主备角色的概念,集群名仅用于唯一标识一个集群,主备角色下放到租户级别,主备租户所属的集群可能不同,主备租户名也可能不同。从 OCP V4.3.1 版本开始支持主备租户 Service Name 创建、编辑、删除、校验以及为主备租户所在的集群绑定同一 OBProxy 集群的功能,支持用户通过设置主备租户为同一 Service Name,达到主备租户切换时 Session 自动切换的能力,同时用户也可以依据业务具体场景,如在非主备租户场景下使用 Service Name 代替集群名&租户名的连接方式以及提供灵活性支持主备租户场景下主备租户使用不同的 Service Name 等,从而帮助用户更方便地使用 Service Name 特性。
测试目的
通过 Service Name 来实现生产租户的应用升级的测试演练。
测试环境
OCP V4.3.2 BP1 版本。
OceanBase 数据库 V4.2.1 BP9 版本,1F-1F-1F 三节点 OceanBase 数据库集群。
主租户:Oracle 模式租户
<oracle>。备租户:Oracle 模式租户
<oracle_standby>。
测试流程简介
模拟生产环境为主租户创建备库和添加服务名。
切换主备租户。
验证数据库连接是否自动切换到新主租户了。
保持应用连接串信息不变,在新主租户上进行 DDL 和 DML 变更以模拟应用升级。
业务验证。
解耦主备租户。
删除并重建备租户和服务名。
测试步骤
通过 OCP Web 页面为主租户创建好备租户,并确保备租户跟主租户的同步延迟在 1s 以内。

进入到主租户或备租户的主页,为该租户添加服务名,同时开启同步变更主备租户服务名。

添加完成后在主租户和备租户上都可以查看到该服务名。
主租户上:

备租户上:

说明
- 在主租户上创建
Service Name时,如果打开了同步变更主备租户服务名,那么,生成的任务会自动在所有备租户上创建该Service Name。 - 在备租户上创建
Service Name时,如果打开了同步变更主备租户服务名,那么,生成的任务会自动在对应主租户和所有其它备租户上创建该Service Name。 - 在主租户上删除
Service Name时,只会影响当前主租户本身,不会影响相关的备租户;在备租户上删除Service Name也不会影响主租户的Service Name。 - 主备租户解耦时,OCP 会自动将新主租户及其下游租户的服务名设置为空。
使用 OCP Web 页面上提供的租户服务名连接串连接到主租户,并执行一些 DDL 和 DML 操作。

使用 SYS 用户登录到集群的 SERVICE:test_svc_name 租户。
$ obclient -h11.166.xxx.xxx -P2883 -uSYS@SERVICE:test_svc_name -pxxx -A -c Welcome to the OceanBase. Commands end with ; or \g. Your OceanBase connection id is 585 Server version: OceanBase 4.2.1.9 (r109010022024101120-45c3c04b7bd9a2070784456c39484ce45e9f9d2c) (Built Oct 11 2024 20:36:32) Copyright (c) 2000, 2018, OceanBase and/or its affiliates. All rights reserved. Type 'help;' or '\h' for help. Type '\c' to clear the current input statement.查看当前租户的 ID。
obclient [SYS]> select effective_tenant_id() from dual;输出结果如下:
+-----------------------+ | EFFECTIVE_TENANT_ID() | +-----------------------+ | 1016 | +-----------------------+ 1 row in set (0.002 sec)查询当前会话的 SID。
obclient [SYS]> select userenv('sid') as session_id from dual;输出结果如下:
+------------+ | SESSION_ID | +------------+ | 3221511421 | +------------+ 1 row in set (0.002 sec)创建表 t1。
obclient [SYS]> create table t1 (id int); Query OK, 0 rows affected (0.158 sec)向表 t1 中插入数据。
obclient [SYS]> insert into t1 values (1),(2),(3); Query OK, 3 rows affected (0.014 sec) Records: 3 Duplicates: 0 Warnings: 0提交插入的数据。
obclient [SYS]> commit; Query OK, 0 rows affected (0.001 sec)查询表 t1 的内容。
obclient [SYS]> select * from t1;输出结果如下:
+------+ | ID | +------+ | 1 | | 2 | | 3 | +------+ 3 rows in set (0.017 sec)
在主租户上点击右上角的 ... -> 日常切换,将主备租户的角色切换。

等日常切换成功完成后,在步骤 3 (使用 OCP Web 页面上提供的租户服务名连接串连接到主租户,并执行一些 DDL 和 DML 操作)的同一个 OBClient 连接会话中执行如下 select 查询,检查当前实际连接的租户。
查看当前租户的 ID。
obclient [SYS]> select effective_tenant_id() from dual;输出结果如下:
+-----------------------+ | EFFECTIVE_TENANT_ID() | +-----------------------+ | 1022 | +-----------------------+ 1 row in set (0.004 sec)查询当前会话的 SID。
obclient [SYS]> select userenv('sid') as session_id from dual;输出结果如下:
+------------+ | SESSION_ID | +------------+ | 3221599967 | +------------+ 1 row in set (0.002 sec)查询表 t1 的内容。
obclient [SYS]> select * from t1;输出结果如下:
+------+ | ID | +------+ | 1 | | 2 | | 3 | +------+ 3 rows in set (0.015 sec)
可以发现实际连接的租户 ID 已经从 1016 切换为 1022 了。
进入到新主租户或新备租户的拓扑图页面,点击备租户右边的 ...-> 暂停同步,人为将新备租户和新主租户之间的同步链路暂停掉。

新开一个 OBClient 连接(或者也可以继续使用步骤 3 有关 使用 OCP Web 页面上提供的租户服务名连接串连接到主租户,并执行一些 DDL 和 DML 操作中的同一个 OBClient 连接会话),在新主租户上执行一些 DDL 和 DML 操作,模拟客户的应用升级场景。
使用 SYS 用户登录到集群的 SERVICE:test_svc_name 租户。
$ obclient -h11.166.xxx.xxx -P2883 -uSYS@SERVICE:test_svc_name -pxxx -A -c Welcome to the OceanBase. Commands end with ; or \g. Your OceanBase connection id is 596 Server version: OceanBase 4.2.1.9 (r109010022024101120-45c3c04b7bd9a2070784456c39484ce45e9f9d2c) (Built Oct 11 2024 20:36:32) Copyright (c) 2000, 2018, OceanBase and/or its affiliates. All rights reserved. Type 'help;' or '\h' for help. Type '\c' to clear the current input statement.查看当前租户的 ID。
obclient [SYS]> select effective_tenant_id() from dual;输出结果如下:
+-----------------------+ | EFFECTIVE_TENANT_ID() | +-----------------------+ | 1022 | +-----------------------+ 1 row in set (0.002 sec)查询当前会话的 SID。
obclient [SYS]> select userenv('sid') as session_id from dual;输出结果如下:
+------------+ | SESSION_ID | +------------+ | 3222079208 | +------------+ 1 row in set (0.001 sec)向表 t1 中插入数据。
obclient [SYS]> insert into t1 values (4),(5),(6); Query OK, 3 rows affected (0.006 sec) Records: 3 Duplicates: 0 Warnings: 0创建表 t2。
obclient [SYS]> create table t2 (name varchar(100)); Query OK, 0 rows affected (0.288 sec)向表 t2 中插入数据。
obclient [SYS]> insert into t2 values ('a'),('b'),('c'); Query OK, 3 rows affected (0.036 sec) Records: 3 Duplicates: 0 Warnings: 0提交插入的数据。
obclient [SYS]> commit; Query OK, 0 rows affected (0.002 sec)查询表 t1 的内容。
obclient [SYS]> select * from t1;输出结果如下:
+------+ | ID | +------+ | 1 | | 2 | | 3 | | 4 | | 5 | | 6 | +------+ 6 rows in set (0.001 sec)查询表 t2 的内容。
obclient [SYS]> select * from t2;输出结果如下:
+------+ | NAME | +------+ | a | | b | | c | +------+ 3 rows in set (0.004 sec)
同步检查新备租户当前的数据最新同步情况,可以发现暂停同步后在新主租户上所做的更新均未同步到新备租户上,符合预期。

使用 SYS 用户登录到集群的 oracle#oio_cluster 租户。
$ obclient -h11.166.xxx.xxx -P2883 -uSYS@oracle#oio_cluster -pxxx -A -c Welcome to the OceanBase. Commands end with ; or \g. Your OceanBase connection id is 657 Server version: OceanBase 4.2.1.9 (r109010022024101120-45c3c04b7bd9a2070784456c39484ce45e9f9d2c) (Built Oct 11 2024 20:36:32) Copyright (c) 2000, 2018, OceanBase and/or its affiliates. All rights reserved. Type 'help;' or '\h' for help. Type '\c' to clear the current input statement.查看当前租户的 ID。
obclient [SYS]> select effective_tenant_id() from dual;输出结果如下:
+-----------------------+ | EFFECTIVE_TENANT_ID() | +-----------------------+ | 1016 | +-----------------------+ 1 row in set (0.001 sec)查询表 t1 的内容。
obclient [SYS]> select * from t1;输出结果如下:
+------+ | ID | +------+ | 1 | | 2 | | 3 | +------+ 3 rows in set (0.001 sec)查询表 t2 的内容。
obclient [SYS]> select * from t2; ORA-00942: table or view 'SYS.T2' does not exist
等周末测试完成后,继续保持主备租户之间同步暂停的状态,将新备租户解耦成独立的主租户。

上面的两个租户会解耦成两个独立的主租户。
租户名 oracle :

租户名 oracle_standby :

最后需要删除掉
<oracle_standby>租户,并参考步骤 1(通过 OCP Web 页面为主租户创建好备租户,并确保备租户跟主租户的同步延迟在 1s 以内)和步骤 2(进入到主租户或备租户的主页,为该租户添加服务名,同时开启同步变更主备租户服务名)重建备租户和租户服务名<test_svc_name>即可。
备注一
- OceanBase 数据库版本要求为 V4.2.4(oceanbase-4.2.4.0-100000252024070621)及之后版本 ~ V4.3.0(oceanbase-4.3.0.0-100000072024020200)之前版本或 V4.2.1 BP9(oceanbase-4.2.1.9-109000092024091919)及之后版本 ~ V4.2.2 GA(oceanbase-4.2.2.0-100000082024011317)之前版本或 V4.3.3 GA(oceanbase-4.3.3.0-100000362024093001)及之后版本。
- OBProxy 版本要求不低于 V4.3.1。
- OCP 版本要求不低于 V4.3.1(OCP V4.3.1 对支持 Service Name 的 OBServer 版本判断有问题,已经在 OCP V4.3.2 版本修复了。)
- 目前
Service Name在单个 OCP 集群(包含多集群模式)内须保持唯一。 - OBProxy 使用
rs_list的方式启动时,不支持使用Service_Name功能。
备注二
OceanBase 数据库 V4.x 版本中提供的 Servcie Name 提供了较大的测试灵活性,这边用户也可以在应用升级测试前就将主备库彻底解耦掉,大致的测试流程如下:
- 模拟生产环境为主租户创建备库和添加服务名。
- 解耦主备租户(会自动删除相关的服务名)。
- 重新为新主租户(即解耦后的原备租户)创建同名的服务名。
- 验证数据库连接是否自动切换到新主租户了。
- 保持应用连接串信息不变,在新主租户上进行 DDL 和 DML 变更以模拟应用升级。
- 业务验证。
- 删除新主租户并重建备租户和服务名。
详细的操作步骤类似,这边就不赘述了。
适用版本
OceanBase 数据库 V4.2.1 BP9(oceanbase-4.2.1.9-109000092024091919)版本 ~ V4.2.2 GA(oceanbase-4.2.2.0-100000082024011317)之前版本、V4.2.4(oceanbase-4.2.4.0-100000252024070621)版本 ~ V4.3.0(oceanbase-4.3.0.0-100000072024020200)之前版本、OceanBase 数据库 V4.3.3 GA(oceanbase-4.3.3.0-100000362024093001)及之后版本。
OBProxy V4.3.1 及更高版本。
OCP V4.3.2 及更高版本。