本記事では、テナント内のログストリームのレプリカ数を増やす方法について説明します。
Localityの変更によるレプリカの増加
クラスタ内の特定のテナントのLocalityを変更することで、そのテナント配下のログストリームのレプリカ数を増やすことができます。Localityの変更手順および注意事項の詳細については、Localityの変更を参照してください。
前提条件
レプリカを追加する前に、まず対象Zone上にテナントのリソースプールが存在するかどうかを確認する必要があります。存在しない場合は、既存のリソースプールのZoneリストを調整するか、テナントに新しいリソースプールを追加する必要があります。新しいリソースプールを追加する場合、そのリソースプールのUnit数はテナントが既に持っているリソースプールと一致している必要があります。リソースプールの調整または新規作成の詳細な操作については、リソースプールの属性の変更またはリソースプールの作成を参照してください。
同時に、変更対象のZone上の各ノードのリソース割り当て状況も確認する必要があります。Zone上のノードのリソースが不足しており、テナントが必要とするリソースUnitを配置できない場合は、Localityの変更を実行できません。
Zone上の各ノードのリソース割り当て状況については、テナントとリソース情報の確認を参照してください。
注意事項
テナントのLocalityは空にすることはできません。
テナントのLocalityが変更されると、そのテナント配下のすべてのテーブルのレプリカ分布も変更されます。
前回のテナントLocalityの変更が完了する前に、次のテナントLocalityの変更を実行することはできません。
Localityの変更では一度に1つの操作のみを実行できます。例えば、Zone3をZone4に直接置き換えることはできません。まずZone4を1つ追加し、その後Zone3を1つ削除する手順を踏む必要があります。
Localityを変更する際は、Primary Zoneへの影響に注意する必要があります。事前にPrimary Zoneを調整することを推奨します。
例:
zone3を削除する必要がある場合、zone3が第一優先順位のPrimary Zoneに属していると、Localityの調整処理がテナントの読み書きサービスに影響を与えます。
zone4を追加する際、Primary ZoneがRANDOMの場合、その後zone4も読み書きサービスを提供します。
手順
例:テナント mysql001 のローカリティを変更し、FULL{1}@zone1, FULL{1}@zone2 から FULL{1}@zone1, FULL{1}@zone2, FULL{1}@zone3 に変更することで、zone3に新しいレプリカを追加します。
説明
ここでは、1つのZoneを追加する例を示しています。実際の操作では、追加するZoneの数が多数派の原則を満たすように注意してください。
rootユーザーでクラスタのsysテナントにログインします。
obclient -h172.30.xxx.xxx -P2883 -uroot@sys#obdemo -pxxxx -Aoceanbaseデータベースに入ります。obclient(root@sys)[(none)]> use oceanbase;テナント
mysql001のローカリティを変更する前の状態を確認します。obclient(root@sys)[oceanbase]> SELECT TENANT_ID, TENANT_NAME, TENANT_TYPE, PRIMARY_ZONE, LOCALITY FROM oceanbase.DBA_OB_TENANTS;クエリ結果は次のとおりです:
+-----------+-------------+-------------+-------------------+---------------------------------------------+ | TENANT_ID | TENANT_NAME | TENANT_TYPE | PRIMARY_ZONE | LOCALITY | +-----------+-------------+-------------+-------------------+---------------------------------------------+ | 1 | sys | SYS | zone1;zone2;zone3 | FULL{1}@zone1, FULL{1}@zone2, FULL{1}@zone3 | | 1001 | META$1002 | META | zone1;zone2 | FULL{1}@zone1, FULL{1}@zone2 | | 1002 | mysql001 | USER | zone1;zone2 | FULL{1}@zone1, FULL{1}@zone2 | +-----------+-------------+-------------+-------------------+---------------------------------------------+ 3 rows in setテナント
mysql001は、zone1とzone2にそれぞれ1つずつフル機能レプリカを持っていることがわかります。テナント
mysql001のローカリティを変更します。obclient(root@sys)[oceanbase]> ALTER TENANT mysql001 locality="FULL{1}@zone1, FULL{1}@zone2, FULL{1}@zone3";ローカリティ変更タスクの実行状態を確認します。
obclient(root@sys)[oceanbase]> SELECT * FROM oceanbase.DBA_OB_TENANT_JOBS WHERE JOB_TYPE = 'ALTER_TENANT_LOCALITY';クエリ結果は次のとおりです:
+--------+-----------------------+------------+-------------+----------+----------------------------+----------------------------+-----------+------------------------------------------------------------------------------+---------------------------------------------+----------------+-------------+ | JOB_ID | JOB_TYPE | JOB_STATUS | RESULT_CODE | PROGRESS | START_TIME | MODIFY_TIME | TENANT_ID | SQL_TEXT | EXTRA_INFO | RS_SVR_IP | RS_SVR_PORT | +--------+-----------------------+------------+-------------+----------+----------------------------+----------------------------+-----------+------------------------------------------------------------------------------+---------------------------------------------+----------------+-------------+ | 1 | ALTER_TENANT_LOCALITY | SUCCESS | NULL | 0 | 2023-01-05 19:38:38.416011 | 2023-01-05 19:38:38.416011 | 1002 | ALTER TENANT mysql001 locality='FULL{1}@zone1, FULL{1}@zone2, FULL{1}@zone3' | FULL{1}@zone1, FULL{1}@zone2 | xx.xx.xx.237 | 2882 | +--------+-----------------------+------------+-------------+----------+----------------------------+----------------------------+-----------+------------------------------------------------------------------------------+---------------------------------------------+----------------+-------------+ 1 row in setJOB_STATUSがSUCCESSの場合、ローカリティ変更タスクは正常に実行されました。テナント
mysql001のローカリティを変更した後の状態を確認します。obclient(root@sys)[oceanbase]> SELECT TENANT_ID, TENANT_NAME, TENANT_TYPE, PRIMARY_ZONE, LOCALITY FROM oceanbase.DBA_OB_TENANTS;クエリ結果は次のとおりです:
+-----------+-------------+-------------+-------------------+---------------------------------------------+ | TENANT_ID | TENANT_NAME | TENANT_TYPE | PRIMARY_ZONE | LOCALITY | +-----------+-------------+-------------+-------------------+---------------------------------------------+ | 1 | sys | SYS | zone1;zone2;zone3 | FULL{1}@zone1, FULL{1}@zone2, FULL{1}@zone3 | | 1001 | META$1002 | META | zone1;zone2 | FULL{1}@zone1, FULL{1}@zone2, FULL{1}@zone3 | | 1002 | mysql001 | USER | zone1;zone2 | FULL{1}@zone1, FULL{1}@zone2, FULL{1}@zone3 | +-----------+-------------+-------------+-------------------+---------------------------------------------+ 3 rows in setステップ3とステップ6のクエリ結果を比較すると、テナント
mysql001のローカリティは元のFULL{1}@zone1, FULL{1}@zone2からFULL{1}@zone1, FULL{1}@zone2, FULL{1}@zone3に変更され、テナントmysql001はzone1、zone2、zone3にそれぞれ1つずつフル機能レプリカを持っています。
レプリカを追加すると、テナントのローカリティがテナントのプライマリゾーンと一致しなくなります。追加したゾーンがプライマリゾーン切り替えに参加する場合は、プライマリゾーンを変更する必要があります。プライマリゾーンの変更操作については、プライマリゾーンの調整を参照してください。追加したゾーンがプライマリゾーン切り替えに参加しない場合は、プライマリゾーンを変更する必要はありません。
レプリカの手動追加
Localityを変更してレプリカを増やす場合、通常はシステムが欠けているレプリカを自動的に補います。しかし、一部の異常な理由によりシステムが正常に動作しない場合は、ALTER SYSTEM ADD REPLICAコマンドを使用して、欠けているログストリームのレプリカを手動で追加できます。
使用上の制限
システムテナント(sysテナント)はすべてのテナントのログストリームに対してレプリカの追加操作を実行できますが、ユーザーテナントは自身のテナントのログストリームに対してのみレプリカの追加操作を実行できます。
テナント内の同一ログストリームについて、レプリカ移行タスクは複数並列実行可能ですが、その他のディザスタリカバリタスク(レプリカの追加、削除、レプリカタイプの変更、ログストリームの法定メンバー数の変更など)は、1回につき1つしか実行できません。
sysテナントはビュー
CDB_OB_LS_REPLICA_TASKSを参照することで、実行中のディザスタリカバリタスクがあるかどうかを確認できます。ユーザーテナントはビューDBA_OB_LS_REPLICA_TASKSを参照することで、実行中のディザスタリカバリタスクがあるかどうかを確認できます。
前提条件
レプリカの追加操作を実行する前に、現在のユーザーが
ALTER SYSTEM権限を持っていることを確認してください。持っていない場合はALTER SYSTEM ADD REPLICAコマンドを実行できません。ビューをクエリする前に、現在のユーザーが以下のビューに対する
SELECT権限を持っていることを確認してください。持っていない場合は関連情報をクエリできません。DBA_OB_TENANTSDBA_OB_LS/CDB_OB_LSGV$OB_UNITSDBA_OB_LS_LOCATIONS/CDB_OB_LS_LOCATIONS
レプリカの追加操作を実行する前に、ターゲットサーバー上にユーザーが利用可能なリソース、すなわちUnitが存在し、かつそのUnit上に該当ログストリームのレプリカが存在しないことを保証してください。
手順
現在、tenant1というテナントがあり、そのローカリティはF@zone1,F@zone2,F@zone3です。また、tenant1のログストリーム1001はzone1とzone3にそれぞれFタイプのレプリカを1つずつ持ち、zone2にはレプリカがありません。今回は手動でzone2にFタイプのレプリカを追加します。
クラスタに対応するテナントにユーザーがログインします。
接続例は以下のとおりです:
obclient -h172.30.xxx.xxx -P2883 -uroot@tenant1#obdemo -pxxxx -Aデータベースへの接続操作の詳細については、データベース接続の概要(MySQLモード)およびデータベース接続の概要(Oracleモード)を参照してください。
操作対象のテナントIDとローカリティ情報を取得します。
システムテナント
obclient(root@sys)[oceanbase]> SELECT TENANT_NAME, TENANT_ID, LOCALITY FROM oceanbase.DBA_OB_TENANTS WHERE TENANT_NAME='tenant1';ユーザーテナント
MySQLモードOracleモードMySQLモードで以下のステートメントを実行します。
obclient(root@tenant1)[oceanbase]> SELECT TENANT_NAME, TENANT_ID, LOCALITY FROM oceanbase.DBA_OB_TENANTS;Oracleモードで以下のステートメントを実行します。
obclient(SYS@tenant1)[SYS]> SELECT TENANT_NAME, TENANT_ID, LOCALITY FROM SYS.DBA_OB_TENANTS;クエリ結果の例は以下のとおりです:
+-------------+-----------+---------------------------------------------+ | TENANT_NAME | TENANT_ID | LOCALITY | +-------------+-----------+---------------------------------------------+ | tenant1 | 1002 | FULL{1}@zone1, FULL{1}@zone2, FULL{1}@zone3 | +-------------+-----------+---------------------------------------------+ 1 row in setクエリ結果によると、このテナントのテナントIDは
1002です。ビュー
DBA_OB_TENANTSの各フィールドの詳細については、DBA_OB_TENANTSを参照してください。
操作対象のテナントのすべてのログストリーム情報を取得します。
システムテナント
obclient(root@sys)[oceanbase]> SELECT * FROM oceanbase.CDB_OB_LS WHERE TENANT_ID=1002;ビュー
CDB_OB_LSの各フィールドの詳細については、CDB_OB_LSを参照してください。ユーザーテナント
MySQLモードOracleモードMySQLモードで以下のステートメントを実行します。
obclient(root@tenant1)[oceanbase]> SELECT * FROM oceanbase.DBA_OB_LS;Oracleモードで以下のステートメントを実行します。
obclient(SYS@tenant1)[SYS]> SELECT * FROM SYS.DBA_OB_LS;クエリ結果の例は以下のとおりです:
+-------+--------+-------------------+---------------+-------------+---------------------+----------+---------------------+---------------------+------+----------------+ | LS_ID | STATUS | PRIMARY_ZONE | UNIT_GROUP_ID | LS_GROUP_ID | CREATE_SCN | DROP_SCN | SYNC_SCN | READABLE_SCN | FLAG | UNIT_LIST | +-------+--------+-------------------+---------------+-------------+---------------------+----------+---------------------+---------------------+------+----------------+ | 1 | NORMAL | zone1;zone3;zone2 | 0 | 0 | NULL | NULL | 1712137184525565000 | 1712137184525565000 | | | | 1001 | NORMAL | zone1;zone3;zone2 | 1001 | 1001 | 1711951923021132001 | NULL | 1712137184292359002 | 1712137184292359002 | | 1001,1002,1003 | +-------+--------+-------------------+---------------+-------------+---------------------+----------+---------------------+---------------------+------+----------------+ 2 rows in setクエリ結果によると、tenant1テナントにはログストリーム1号とログストリーム1001号があります。
ビュー
DBA_OB_LSの各フィールドの詳細については、DBA_OB_LSを参照してください。
操作対象のテナントのUnitリソースを取得します。
システムテナント
obclient(root@sys)[oceanbase]> SELECT SVR_IP, SVR_PORT, UNIT_ID, TENANT_ID, ZONE, ZONE_TYPE, STATUS FROM oceanbase.GV$OB_UNITS WHERE TENANT_ID=1002;ユーザーテナント
MySQLモードOracleモードMySQLモードで以下のステートメントを実行します:
obclient(root@tenant1)[oceanbase]> SELECT SVR_IP, SVR_PORT, UNIT_ID, TENANT_ID, ZONE, ZONE_TYPE, STATUS FROM oceanbase.GV$OB_UNITS;Oracleモードで以下のステートメントを実行します。
obclient(SYS@tenant1)[SYS]> SELECT SVR_IP, SVR_PORT, UNIT_ID, TENANT_ID, ZONE, ZONE_TYPE, STATUS FROM SYS.GV$OB_UNITS;クエリ結果の例は以下のとおりです:
+----------------+----------+---------+-----------+-------+-----------+--------+ | SVR_IP | SVR_PORT | UNIT_ID | TENANT_ID | ZONE | ZONE_TYPE | STATUS | +----------------+----------+---------+-----------+-------+-----------+--------+ | 172.xx.xxx.226 | 2882 | 1001 | 1002 | zone1 | ReadWrite | NORMAL | | 172.xx.xxx.212 | 2882 | 1002 | 1002 | zone2 | ReadWrite | NORMAL | | 172.xx.xxx.192 | 2882 | 1003 | 1002 | zone2 | ReadWrite | NORMAL | +----------------+----------+---------+-----------+-------+-----------+--------+ 3 rows in setクエリ結果によると、現在のテナントは
172.xx.xxx.226:2882、172.xx.xxx.212:2882、172.xx.xxx.192:2882の3台のサーバーすべてで利用可能なUnitリソースを持っています。ビュー
GV$OB_UNITSの各フィールドの詳細については、GV$OB_UNITSを参照してください。
事前に取得したテナントのログストリーム情報に基づき、ログストリーム1001号のレプリカ分布を確認します。
システムテナント
obclient(root@sys)[oceanbase]> SELECT * FROM oceanbase.CDB_OB_LS_LOCATIONS WHERE LS_ID=1001 AND TENANT_ID=1002;ビュー
CDB_OB_LS_LOCATIONSの各フィールドの詳細については、CDB_OB_LS_LOCATIONSを参照してください。ユーザーテナント
MySQLモードOracleモードMySQLモードで以下のステートメントを実行します。
obclient(root@tenant1)[oceanbase]> SELECT * FROM oceanbase.DBA_OB_LS_LOCATIONS WHERE LS_ID=1001;Oracleモードで以下のステートメントを実行します:
obclient(SYS@tenant1)[SYS]> SELECT * FROM SYS.DBA_OB_LS_LOCATIONS WHERE LS_ID=1001;クエリ結果の例は以下のとおりです:
+----------------------------+----------------------------+-------+----------------+----------+----------+-------+----------+------------------------------------------------------------+----------------------+--------------+--------------+---------+ | CREATE_TIME | MODIFY_TIME | LS_ID | SVR_IP | SVR_PORT | SQL_PORT | ZONE | ROLE | MEMBER_LIST | PAXOS_REPLICA_NUMBER | REPLICA_TYPE | LEARNER_LIST | REBUILD | +----------------------------+----------------------------+-------+----------------+----------+----------+-------+----------+------------------------------------------------------------+----------------------+--------------+--------------+---------+ | 2024-04-03 17:23:06.381521 | 2024-04-03 17:32:49.079886 | 1001 | 172.xx.xxx.192 | 2882 | 2881 | zone3 | FOLLOWER | NULL | NULL | FULL | | FALSE | | 2024-04-01 14:12:08.589084 | 2024-04-03 17:32:49.124409 | 1001 | 172.xx.xxx.226 | 2882 | 2881 | zone1 | LEADER | 172.xx.xxx.192:2882:1712136186291857,172.xx.xxx.226:2882:1 | 2 | FULL | | FALSE | +----------------------------+----------------------------+-------+----------------+----------+----------+-------+----------+------------------------------------------------------------+----------------------+--------------+--------------+---------+ 2 rows in setクエリ結果によると、テナントのログストリーム1001は
172.xx.xxx.192:2882と172.xx.xxx.226:2882にそれぞれFタイプのレプリカを1つずつ持っています。さらに前のステップのクエリ結果と照合すると、テナントは
172.xx.xxx.226:2882、172.xx.xxx.212:2882、172.xx.xxx.192:2882の3台のサーバーすべてで利用可能なUnitリソースを持っていますが、172.xx.xxx.212:2882にはこのログストリームのレプリカがありません。172.xx.xxx.212:2882マシンにテナントのログストリーム1001号のFタイプレプリカを追加する必要があります。ビュー
DBA_OB_LS_LOCATIONSの各フィールドの詳細については、DBA_OB_LS_LOCATIONSを参照してください。
レプリカ追加コマンドを実行します。
SQLステートメントは以下のとおりです:
ALTER SYSTEM ADD REPLICA LS [=] ls_id SERVER [=] 'svr_ip:svr_port' REPLICA_TYPE [=] 'replica_type' [DATA_SOURCE [=] 'data_source'] [PAXOS_REPLICA_NUM [=] paxos_replica_num] [TENANT [=] 'tenant_name'];ステートメントの使用方法:
ls_id:レプリカを追加するログストリームIDを指定します。svr_ip:svr_port:レプリカを追加する対象サーバーのIPアドレスとポート番号を指定します。例:172.xx.xxx.212:2882。replica_type:追加するレプリカタイプを指定します。現在、以下のレプリカタイプをサポートしています:フル機能レプリカ:
FULLまたはFを使用して表します。読み取り専用レプリカ:
READONLYまたはRを使用して表します。カラムストアレプリカ:
COLUMNSTOREまたはCを使用して表します。
data_source:レプリカを追加するデータソースのアドレスを指定します。例:172.xx.xxx.192:2882。指定されたデータソースが利用不可の場合、システムはエラーを返します。
この値を明示的に指定しない場合、システムは利用可能なデータソースを自動的に選択します。
paxos_replica_num:変更後のログストリームの過半数メンバー数、つまりテナントのローカリティに含まれるフル機能(F)レプリカの数を指定します。同じログストリームのFレプリカ数は最大7個です。このパラメータの値を指定する場合、以下の条件を満たす必要があります:
変更後の
paxos_replica_numは過半数を満たす必要があります。paxos_replica_numの値は、現在のリーダーレプリカのMEMBER_LISTのメンバー数以上である必要があります。paxos_replica_numの値の絶対変化量は1を超えてはなりません。例えば、この例では現在のpaxos_replica_numは2なので、paxos_replica_numは3に変更できます。
指定した値が上記のいずれかの条件を満たさない場合、システムはエラーを返します。この値を明示的に指定しない場合、システムは現在のデフォルトの
paxos_replica_numを使用します。tenant_name:操作対象のテナントを指定します。システムテナントは他のテナントを指定できますが、ユーザーテナントは自身のテナントのみを指定できます。操作対象のテナントを明示的に指定しない場合、デフォルトのテナント名は現在のテナントになります。このステートメントでは、all、all_user、all_metaなどを使用してすべてのテナント、ユーザーテナント、およびすべてのMetaテナントを指定することはできません。このステートメントでは一度に1つのレプリカしか追加できません。複数のレプリカを追加する必要がある場合は、このステートメントを複数回実行する必要があります。
例:
obclient> ALTER SYSTEM ADD REPLICA LS= 1001 SERVER='172.xx.xxx.212:2882' REPLICA_TYPE='F' DATA_SOURCE='172.xx.xxx.192:2882' PAXOS_REPLICA_NUM=3;再度ログストリーム情報をクエリすると、このログストリームにFレプリカが1つ追加されていることが確認できます。
システムテナント
obclient(root@sys)[oceanbase]> SELECT * FROM oceanbase.CDB_OB_LS_LOCATIONS WHERE LS_ID=1001 AND TENANT_ID=1002;ユーザーテナント
MySQLモードOracleモードMySQLモードで以下のステートメントを実行します:
obclient(root@tenant1)[oceanbase]> SELECT * FROM oceanbase.DBA_OB_LS_LOCATIONS WHERE LS_ID=1001;Oracleモードで以下のステートメントを実行します:
obclient(SYS@tenant1)[SYS]> SELECT * FROM SYS.DBA_OB_LS_LOCATIONS WHERE LS_ID=1001;クエリ結果の例は以下のとおりです:
+----------------------------+----------------------------+-------+----------------+----------+----------+-------+----------+-------------------------------------------------------------------------------------------------+----------------------+--------------+--------------+---------+ | CREATE_TIME | MODIFY_TIME | LS_ID | SVR_IP | SVR_PORT | SQL_PORT | ZONE | ROLE | MEMBER_LIST | PAXOS_REPLICA_NUMBER | REPLICA_TYPE | LEARNER_LIST | REBUILD | +----------------------------+----------------------------+-------+----------------+----------+----------+-------+----------+-------------------------------------------------------------------------------------------------+----------------------+--------------+--------------+---------+ | 2024-04-03 17:23:06.381521 | 2024-04-03 17:48:08.982791 | 1001 | 172.xx.xxx.192 | 2882 | 2881 | zone3 | FOLLOWER | NULL | NULL | FULL | | FALSE | | 2024-04-03 17:48:05.812041 | 2024-04-03 17:48:09.985574 | 1001 | 172.xx.xxx.212 | 2882 | 2881 | zone2 | FOLLOWER | NULL | NULL | FULL | | FALSE | | 2024-04-01 14:12:08.589084 | 2024-04-03 17:48:09.030020 | 1001 | 172.xx.xxx.226 | 2882 | 2881 | zone1 | LEADER | 172.xx.xxx.192:2882:1712136186291857,172.xx.xxx.212:2882:1712137685774460,172.xx.xxx.226:2882:1 | 3 | FULL | | FALSE | +----------------------------+----------------------------+-------+----------------+----------+----------+-------+----------+-------------------------------------------------------------------------------------------------+----------------------+--------------+--------------+---------+ 3 rows in set