作者:郑增权,爱可生 DBA 团队成员,OceanBase 和 MySQL 数据库技术爱好者。

爱可生开源社区出品,原创内容未经授权不得随意使用,转载请联系小编并注明来源。

本文约 1400 字,预计阅读需要 4 分钟。

背景及问题

背景

某客户对容灾架构进行变更,由“两地两中心三副本”变更为“两地三中心五副本”(如图)。变更后在同城可形成多数派,避免跨城网络性能抖动带来影响。

容灾架构变更

注意:深圳两机房之间为万兆网络专线,深圳两机房到广州机房为千兆网络专线。

  • 版本:OceanBase 4.2.1.4

问题

在为业务租户增加副本(新增副本位置位于深圳 A 机房)时发现,拉取数据时的数据源居然是随机的!可能是深圳的,也可能是广州的。

然而,鉴于广州机房为千兆网络带宽,当新增副本随机到从广州机房拉取数据时,会致使网络带宽被完全占用,从而引发拥堵状况。

问题复现

笔者的测试环境资源有限,仅以深圳“双机房两副本”变更为“双机房三副本”为例复现问题,解决方案可在背景环境复用。

容灾架构变更(简化版)

1. 查看 ZONE 信息

  • 深圳南山机房:10.186.64.61
  • 深圳光明机房:10.186.64.10
MySQL [oceanbase]> select svr_ip,a.zone,name,info from __all_zone a, __all_server b where a.name in ('region','idc','status','info') and a.zone=b.zone;
+--------------+-------+--------+-----------+
| svr_ip       | zone  | name   | info      |
+--------------+-------+--------+-----------+
| 10.186.64.61 | zone1 | idc    | NanShan   |
| 10.186.64.61 | zone1 | region | ShenZhen  |
| 10.186.64.61 | zone1 | status | ACTIVE    |
| 10.186.64.10 | zone2 | idc    | GuangMing |
| 10.186.64.10 | zone2 | region | ShenZhen  |
| 10.186.64.10 | zone2 | status | ACTIVE    |
+--------------+-------+--------+-----------+
6 rows in set (0.00 sec)

2. 查看租户角色信息

  • Leader 节点:10.186.65.61
  • Follower 节点:10.186.64.10
MySQL [oceanbase]> select b.tenant_name,a.tenant_id,a.ls_id,a.zone,a.svr_ip,a.role from cdb_ob_table_locations  a join __all_tenant b on a.tenant_id = b.tenant_id where b.tenant_name = 'mysql_ob'group by svr_ip,role order by zone;
+-------------+-----------+-------+-------+--------------+----------+
| tenant_name | tenant_id | ls_id | zone  | svr_ip       | role     |
+-------------+-----------+-------+-------+--------------+----------+
| mysql_ob    |      1002 |     1 | zone1 | 10.186.64.61 | LEADER   |
| mysql_ob    |      1002 |     1 | zone2 | 10.186.64.10 | FOLLOWER |
+-------------+-----------+-------+-------+--------------+----------+
2 rows in set (0.19 sec)

3. 添加一个 Zone

  • IP:10.186.64.62
  • 地区:深圳南山机房

添加 Zone

4. 查看添加 Zone 后的信息

MySQL [oceanbase]>  select svr_ip,a.zone,name,info from __all_zone a, __all_server b where a.name in ('region','idc','status','info') and a.zone=b.zone;
+--------------+-------+--------+-----------+
| svr_ip       | zone  | name   | info      |
+--------------+-------+--------+-----------+
| 10.186.64.61 | zone1 | idc    | NanShan   |
| 10.186.64.61 | zone1 | region | ShenZhen  |
| 10.186.64.61 | zone1 | status | ACTIVE    |
| 10.186.64.10 | zone2 | idc    | GuangMing |
| 10.186.64.10 | zone2 | region | ShenZhen  |
| 10.186.64.10 | zone2 | status | ACTIVE    |
| 10.186.64.62 | zone3 | idc    | NanShan   |
| 10.186.64.62 | zone3 | region | ShenZhen  |
| 10.186.64.62 | zone3 | status | ACTIVE    |
+--------------+-------+--------+-----------+
9 rows in set (0.01 sec)

5. 为 mysql_ob 租户新增副本

新增副本

6. 查看正在运行中的 Replica 级别的容灾任务

  • 源端:10.186.64.10
  • 目标端:10.186.64.62
MySQL [oceanbase]> SELECT TENANT_ID,LS_ID,TASK_TYPE,TASK_STATUS,PRIORITY,SOURCE_REPLICA_SVR_IP,TARGET_REPLICA_SVR_IP FROM CDB_OB_LS_REPLICA_TASKS;
+-----------+-------+-------------+-------------+----------+-----------------------+-----------------------+
| TENANT_ID | LS_ID | TASK_TYPE   | TASK_STATUS | PRIORITY | SOURCE_REPLICA_SVR_IP | TARGET_REPLICA_SVR_IP |
+-----------+-------+-------------+-------------+----------+-----------------------+-----------------------+
|      1001 |     1 | ADD REPLICA | INPROGRESS  | HIGH     | 10.186.64.10          | 10.186.64.62          |
|      1002 |     1 | ADD REPLICA | INPROGRESS  | HIGH     | 10.186.64.10          | 10.186.64.62          |
|      1002 |  1001 | ADD REPLICA | INPROGRESS  | HIGH     | 10.186.64.10          | 10.186.64.62          |
+-----------+-------+-------------+-------------+----------+-----------------------+-----------------------+
3 rows in set (0.00 sec)

此时可以看到,在新增副本时,虽然新副本 10.186.64.62 和租户当前的 Leader 节点在同深圳南山机房,但是却从深圳光明机房的节点拉取数据。

猜测:由于 10.186.64.10 是 Follower 节点,优先从 Follower 节点拉取数据(下文继续验证)。

7. 删除新增副本

删除副本

8. 调整用户的 primary_zone

MySQL [oceanbase]> alter tenant mysql_ob primary_zone = 'zone2;zone1';
Query OK, 0 rows affected (0.15 sec)

MySQL [oceanbase]> select tenant_name,primary_zone,status from __all_tenant where tenant_name = 'mysql_ob';
+-------------+--------------+--------+
| tenant_name | primary_zone | status |
+-------------+--------------+--------+
| mysql_ob    | zone2;zone1  | NORMAL |
+-------------+--------------+--------+
1 row in set (0.01 sec)

9. 确认 Leader 节点切换

确认 Leader 节点已经切换至 10.186.64.10

MySQL [oceanbase]> select b.tenant_name,a.tenant_id,a.ls_id,a.zone,a.svr_ip,a.role from cdb_ob_table_locations  a join __all_tenant b on a.tenant_id = b.tenant_id where b.tenant_name = 'mysql_ob'group by svr_ip,role order by zone;
+-------------+-----------+-------+-------+--------------+----------+
| tenant_name | tenant_id | ls_id | zone  | svr_ip       | role     |
+-------------+-----------+-------+-------+--------------+----------+
| mysql_ob    |      1002 |     1 | zone1 | 10.186.64.61 | FOLLOWER |
| mysql_ob    |      1002 |     1 | zone2 | 10.186.64.10 | LEADER   |
+-------------+-----------+-------+-------+--------------+----------+
2 rows in set (0.10 sec)

10. 再次尝试新增副本

新增副本

11. 再次查看正在运行中的 Replica 级别的容灾任务

依然是从 10.186.64.10 拉取数据。选择数据源的判断与租户的角色不存在强关联。

MySQL [oceanbase]> SELECT TENANT_ID,LS_ID,TASK_TYPE,TASK_STATUS,PRIORITY,SOURCE_REPLICA_SVR_IP,TARGET_REPLICA_SVR_IP FROM CDB_OB_LS_REPLICA_TASKS;
+-----------+-------+-------------+-------------+----------+-----------------------+-----------------------+
| TENANT_ID | LS_ID | TASK_TYPE   | TASK_STATUS | PRIORITY | SOURCE_REPLICA_SVR_IP | TARGET_REPLICA_SVR_IP |
+-----------+-------+-------------+-------------+----------+-----------------------+-----------------------+
|      1001 |     1 | ADD REPLICA | INPROGRESS  | HIGH     | 10.186.64.10          | 10.186.64.62          |
|      1002 |     1 | ADD REPLICA | INPROGRESS  | HIGH     | 10.186.64.10          | 10.186.64.62          |
|      1002 |  1001 | ADD REPLICA | INPROGRESS  | HIGH     | 10.186.64.10          | 10.186.64.62          |
+-----------+-------+-------------+-------------+----------+-----------------------+-----------------------+
3 rows in set (0.03 sec)

总结

综上,OceanBase 4.2.1.4 版本在为租户新增副本时,拉取数据在选择数据源时存在随机性,可能发生“舍近求远”的问题。

解决方案

方法一【推荐】

参数 choose_migration_source_policy 用于指定迁移选择源端副本的优先策略,配置迁移源端副本优先从同 IDC 的副本中选择。

ALTER SYSTEM SET choose_migration_source_policy='idc';
  • 版本:OceanBase 4.2.1 BP7 及以上

方法二【推荐】

手动执行添加副本命令:

// 指定 data_source
ALTER SYSTEM ADD REPLICA LS XXX;
  • 版本:OceanBase 4.2.1 BP8 及以上

方法三【不推荐,临时规避】

以客户环境为例,当初始架构为“两地两中心三副本”时,暂停广州机房的 OBServer 服务,剩余的两个 OBServer 节点(深圳机房)依然满足多数派,可以对外提供服务。此时新增副本只会从深圳机房拉取数据(生产环境需谨慎评估风险!!!)。

分类: OceanBase