關於 OB 4.2.x 新增副本隨機拉取問題的解決方案

爱可生开源社区發表於2024-12-09

作者:鄭增權,愛可生 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 節點(深圳機房)依然滿足多數派,可以對外提供服務。此時新增副本只會從深圳機房拉取資料(生產環境需謹慎評估風險!!!)。

相關文章