PolarDB for MySQL の Multi-master Cluster (Limitless) 機能は、クラスターをシングルライター、マルチリーダーアーキテクチャからマルチライター、マルチリーダーアーキテクチャにアップグレードします。この機能により、異なるコンピューティングノード上の異なるデータベースまたはデータオブジェクトへの同時データ書き込みが可能になります。また、数秒で完了する切り替えによるノード間でのデータベースとデータオブジェクトの動的スケジューリングもサポートしており、これによりクラスター全体の同時読み取りおよび書き込み機能が大幅に向上します。データオブジェクトには、テーブル、ビュー、トリガー、イベント、ストアドプロシージャ、および関数が含まれます。このトピックでは、Multi-master Cluster (Limitless) の使用方法について説明します。
前提条件
Multi-master Cluster (Limitless) クラスターを購入済みです。詳細については、「カスタム購入」および「サブスクリプションクラスターの購入」をご参照ください。
特権アカウントを作成済みである必要があります。詳細については、「特権アカウントの作成」をご参照ください。
データベースクラスターに接続済みである必要があります。詳細については、「データベースクラスターへの接続」をご参照ください。
PolarDB for MySQL のカーネルバージョン 8.0 以降は、Multi-master Cluster (Limitless) をサポートしています。
制限事項
各データベースまたはデータオブジェクトのデータは、単一のプライマリノードを介してのみ書き込むことができます。そのオブジェクトが割り当てられていないノードでは、書き込み操作を実行できません。デフォルトでは、操作はデータベースレベルで実行されます。データオブジェクトレベルで操作を実行するには、特定の構文を使用してモードを切り替える必要があります。
プライマリノードをまたいだクエリはサポートされていません。クエリに異なるプライマリノード上にあるデータベースまたはデータオブジェクトが含まれる場合、システムはエラーを返します。クエリを実行する前に、関連するすべてのデータベースまたはデータオブジェクトのエンドポイントを単一のプライマリノードに移動することを推奨します。
提供されるのは、クラスターエンドポイントのみです。プライマリエンドポイントはサポートされていません。
エンドポイントの切り替えは、次の条件に従います。
データベース分離レベルを使用する場合、データベースエンドポイントを切り替える必要があります。
データオブジェクト分離レベルを使用する場合、データオブジェクトのエンドポイントを切り替える必要があります。
プライマリノードをまたいだ DDL 操作はサポートされていません。現在の接続が、データベースまたはデータオブジェクトの所有者ではないプライマリノード上にあるときに DDL ステートメントを実行すると、システムは
Failed to get global lock for table 'xxx' on master Nというエラーを返します。この問題を解決するには、次の手順を実行します。次のコマンドを実行して、ターゲットテーブルを所有するプライマリノードを照会します。
SELECT * FROM INFORMATION_SCHEMA.INNODB_CC_GLOBAL_LOCK_INFO WHERE LOCK_MODE = 'SLS_X';クエリ結果で、ターゲットテーブルに対応する
master_idを見つけます。次のコマンドを実行して、現在のセッションをターゲットテーブルを所有するプライマリノードに切り替えます。
ALTER SESSION POLARDB_WRITE_NODE <master_id>;<master_id>を、前の手順で取得した実際のプライマリノード番号に置き換えます。切り替えが完了した後、DDL ステートメントを再実行します。
データベースのプライマリノードの指定
指定したプライマリノード上にデータベースを作成します。構文は次のとおりです。
CREATE DATABASE name [POLARDB_WRITE_NODE master_id];データベース分離レベルを使用する場合、各データベースのデータは単一のプライマリノードを介してのみ書き込むことができます。
構文で
[POLARDB_WRITE_NODE master_id]を省略した場合、システムは loose_innodb_mm_default_master_id パラメーターの値を使用して、データベースを作成するためのプライマリノードを指定します。loose_innodb_mm_default_master_id パラメーターの値が 0 の場合、システムはデータベースを作成するプライマリノードをランダムに選択します。PolarDB コンソールに移動し、 ページで クラスターまたはノードのパラメーターを表示および変更することができます。ノード間のデータベースの分散を表示するには、「データベースの分散の照会」をご参照ください。
例: プライマリノード 1 に、db1 という名前のデータベースを作成します。
CREATE DATABASE db1 POLARDB_WRITE_NODE 1;プライマリノード 2 でデータベース db1 を作成するには、前のステートメントの 1 を 2 に変更します。
データベースの削除
指定したプライマリノードに作成されたデータベースを削除するには、次の構文を使用します。
DROP DATABASE name;例:プライマリノード 1 で作成されたデータベース db1 を削除します。
DROP DATABASE db1;データベースを削除する際に、プライマリノードを指定する必要はありません。
データベースエンドポイントの切り替え
データベースエンドポイントを別のプライマリノードに切り替えるには、次の構文を使用します。
ALTER DATABASE name POLARDB_WRITE_NODE master_id;例:データベース db1 のエンドポイントをプライマリノード 2 に切り替えます。
ALTER DATABASE db1 POLARDB_WRITE_NODE 2;エンドポイントの切り替えは、時間のかかる操作になる場合があります。実行時間は次の要因によって決まります。
データベースに含まれるテーブルが多いほど、切り替えは遅くなります。
切り替え中のデータベースに対する DML ワークロードが重いほど、操作は遅くなります。
データオブジェクト分離への切り替え
デフォルトでは、マルチマスタークラスターの分離レベルはデータベースレベルです。これは、同じデータベース内のすべてのデータオブジェクトが、単一のプライマリノード上でのみ書き込み可能であることを意味します。同じデータベース内のすべてのデータオブジェクトを複数のプライマリノード経由でアクセスできるようにしたい場合は、データベース分離レベルをデータオブジェクト分離レベルに変更する必要があります。構文は次のとおりです。
ALTER DATABASE name TO TABLE_LOCK POLARDB_WRITE_NODE master_id;このステートメントでは、name はデータベース名を指定し、master_id はデータオブジェクトのエンドポイントを指定します。
例: データベース db1 の分離レベルをデータオブジェクト分離レベルに変更し、そのエンドポイントをプライマリノード 2 に設定します。
ALTER DATABASE db1 TO TABLE_LOCK POLARDB_WRITE_NODE 2;分離レベルの切り替えは、時間のかかる操作になる場合があります。実行時間は次の要因によって決まります。
データベースに含まれるオブジェクトが多いほど、切り替えは遅くなります。
切り替え中のデータベースに対する DML ワークロードが重いほど、操作は遅くなります。
データベース分離への切り替え
データベースがデータオブジェクト分離レベルに設定されている場合、管理を容易にするためにデータベース分離レベルに戻すことができます。次のステートメントを使用します。
ALTER DATABASE name TO DB_LOCK POLARDB_WRITE_NODE master_id;このステートメントでは、name はデータベース名を指定し、master_id はデータベースのエンドポイントを指定します。
例: データベース db1 の分離レベルをデータベース分離レベルに戻し、そのエンドポイントをプライマリノード 1 に設定します。
ALTER DATABASE db1 TO DB_LOCK POLARDB_WRITE_NODE 1;分離レベルの切り替えは、時間のかかる操作になる場合があります。実行時間は次の要因によって決まります。
データベースに含まれるオブジェクトが多いほど、切り替えは遅くなります。
切り替え中のデータベースに対する DML ワークロードが重いほど、操作は遅くなります。
データオブジェクトエンドポイントの切り替え
クラスターがデータオブジェクト分離レベルにある場合、データベースにはテーブル、ビュー、トリガー、関数、ストアドプロシージャ、イベントなど、さまざまなオブジェクトタイプを含めることができます。これらのオブジェクトのエンドポイントを切り替えるには、次の構文を使用します。
ALTER obj_type name POLARDB_WRITE_NODE master_id;このステートメントでは、obj_type は TABLE、VIEW、TRIGGER、FUNCTION、PROCEDURE、または EVENT のいずれかです。name はデータオブジェクトの名前です。
例 1: データベース db1 内のテーブル t1 のエンドポイントをプライマリノード 3 に切り替えます。
ALTER TABLE db1.t1 POLARDB_WRITE_NODE 3;例 2:現在のデータベースのビュー t2 のエンドポイントをプライマリノード 2 に切り替えます。
ALTER VIEW t2 POLARDB_WRITE_NODE 2;例 3: データベース db2 内の関数 f1 および f2 のエンドポイントをプライマリノード 1 に切り替えます。
ALTER FUNCTION db2.f1, db2.f2 POLARDB_WRITE_NODE 1;エンドポイントの切り替えは、時間のかかる操作になる場合があります。実行時間は次の要因によって決まります。
切り替え中のデータオブジェクトに対する DML ワークロードが重いほど、操作は遅くなります。
依存関係のあるオブジェクトは、同じプライマリノードに配置されていない場合、無効になる可能性があります。
たとえば、
VIEW1という名前のビューがt1という名前のテーブルに依存しているとします。VIEW1のエンドポイントがプライマリノード 1 にあり、t1のエンドポイントがプライマリノード 2 にある場合、プライマリノード 1 でVIEW1をクエリするとエラーが発生します。同様に、関数、ストアドプロシージャ、またはイベントが参照するオブジェクトが異なるプライマリノードにある場合、それらの呼び出しは失敗します。トリガーも、エンドポイントが異なるノードにある場合、テーブルの変更に失敗します。t1とt2など、2 つのテーブル間に外部キー制約が存在する場合、一方のテーブルのエンドポイントを変更すると、もう一方のテーブルのエンドポイントも自動的に変更されます。
SQL のプライマリノードの指定
この機能は、information_schema やステータス変数に対するクエリなどのメタデータクエリにのみ適用されます。 たとえば、SELECT * FROM table1 を実行してデータをクエリする必要がある場合、データベースプロキシがクエリを正しいプライマリノードに自動的にルーティングするため、プライマリノードを指定する必要はありません。
特定のプライマリノードに SQL ステートメントを送信するには、次の SQL ステートメントを実行して、セッションをそのノードにロックします。
ALTER SESSION POLARDB_WRITE_NODE master_id;例:プライマリノード 1 で innodb_buffer_pool_size 変数の値を照会します。
ALTER SESSION POLARDB_WRITE_NODE 1; # SQL ステートメントをプライマリノード 1 に送信します。
SHOW VARIABLES LIKE 'innodb_buffer_pool_size'; # プライマリノード 1 の innodb_buffer_pool_size の値を照会します。SQL ステートメントを実行する際にプライマリノードを指定しない場合、データベースプロキシはランダムにプライマリノードを選択してステートメントを実行します。
次のコマンドを実行して、指定したプライマリノードからセッションのロックを解除します。
RESET SESSION POLARDB_WRITE_NODE;データベースの分散の照会
PolarDB コンソールで、 ページに移動して、クラスター全体でのすべてのデータベースの分散状況を確認できます。[MasterID] 列には、各データベースが属する RW ノード番号が表示されます (たとえば、MasterID 1 はデータベースが RW1 ノード上にあることを示し、MasterID 2 は RW2 ノード上にあることを示します)。
次のコマンドを実行して、特定のプライマリノード上のデータベースの分散を照会します。
ALTER SESSION POLARDB_WRITE_NODE master_id; SELECT * FROM INFORMATION_SCHEMA.INNODB_MASTER_GLOBAL_LOCK_INFO WHERE LOCK_MODE = 'SLS_X';例:プライマリノード 1 のデータベースの分散を照会します。
ALTER SESSION POLARDB_WRITE_NODE 1; SELECT * FROM INFORMATION_SCHEMA.INNODB_MASTER_GLOBAL_LOCK_INFO WHERE LOCK_MODE = 'SLS_X';次の出力が返されます。
SELECT * FROM INFORMATION_SCHEMA.INNODB_MASTER_GLOBAL_LOCK_INFO WHERE LOCK_MODE = 'SLS_X'; +------------+---------------------+----------+--------------+-----------+----------+-------------+-------------+---------------------+-----------------+ | table_name | table_id | space_id | s_lock_count | lock_mode | object | current_lsn | hold_thread | hold_start_time | hold_total_time | +------------+---------------------+----------+--------------+-----------+----------+-------------+-------------+---------------------+-----------------+ | test3/f1 | 9149389368458135753 | 0 | 0 | SLS_X | function | 28076635 | 17 | 2024-07-10 21:35:20 | 214 | | test3/e1 | 9149389368458332874 | 0 | 0 | SLS_X | event | 28077248 | 17 | 2024-07-10 21:35:30 | 204 | | test3/v1 | 9149389368457234649 | 0 | 0 | SLS_X | view | 28075972 | 17 | 2024-07-10 21:35:08 | 226 | | sbtest | 2107518311328629409 | 0 | 0 | SLS_X | db | 28034927 | 4294967295 | 2024-07-07 23:04:41 | 254053 | | test | 7190879906290573778 | 0 | 0 | SLS_X | db | 28034927 | 4294967295 | 2024-07-10 11:20:57 | 37077 | | test2 | 3381728963524265351 | 0 | 0 | SLS_X | db | 28034927 | 4294967295 | 2024-07-10 11:13:09 | 37545 | +------------+---------------------+----------+--------------+-----------+----------+-------------+-------------+---------------------+-----------------+ 6 rows in set (0.00 sec)列名は
table_nameですが、結果の各行にはデータベースまたはデータオブジェクトに関する情報が含まれています。この例では、sbtest、test、およびtest2はデータベース分離レベルを使用します。オブジェクトtest3/f1 (関数)、test3/e1 (イベント)、およびtest3/v1 (ビュー)はデータオブジェクト分離レベルを使用します。また、結果にはオブジェクトタイプがテーブルの mysql/global_ddl_lock という名前のオブジェクトが含まれる場合があります。これは内部で使用されるため、無視してかまいません。次のコマンドを実行して、クラスター内のすべてのデータベースの分散を照会します。
説明このクエリは特権アカウントでのみ実行できます。
SELECT * FROM INFORMATION_SCHEMA.INNODB_CC_GLOBAL_LOCK_INFO WHERE LOCK_MODE = 'SLS_X';次の出力が返されます。
mysql> SELECT * FROM INFORMATION_SCHEMA.INNODB_CC_GLOBAL_LOCK_INFO WHERE LOCK_MODE = 'SLS_X'; +-----------+------------+---------------------+-----------+-----------+-------------+---------------------+-----------------+ | master_id | table_name | table_id | lock_mode | object | current_lsn | hold_start_time | hold_total_time | +-----------+------------+---------------------+-----------+-----------+-------------+---------------------+-----------------+ | 1 | test3/v1 | 9149389368457234649 | SLS_X | view | 28075972 | 2024-07-10 21:35:08 | 754 | | 2 | test5/t1 | 9149389447232697561 | SLS_X | table | 7256175 | 2024-07-10 21:46:36 | 66 | | 1 | test2 | 3381728963524265351 | SLS_X | db | 28034927 | 2024-07-10 11:13:09 | 38073 | | 2 | test4 | 3381728963524272009 | SLS_X | db | 7255352 | 2024-07-10 21:46:27 | 75 | | 1 | test3/f1 | 9149389368458135753 | SLS_X | function | 28076635 | 2024-07-10 21:35:20 | 742 | | 1 | test3/e1 | 9149389368458332874 | SLS_X | event | 28077248 | 2024-07-10 21:35:30 | 732 | | 1 | test | 7190879906290573778 | SLS_X | db | 28034927 | 2024-07-10 11:20:57 | 37605 | | 2 | test5/p1 | 9149389447233473757 | SLS_X | procedure | 7257051 | 2024-07-10 21:46:45 | 57 | | 1 | sbtest | 2107518311328629409 | SLS_X | db | 28034927 | 2024-07-07 23:04:41 | 254581 | +-----------+------------+---------------------+-----------+-----------+-------------+---------------------+-----------------+ 9 rows in set (0.00 sec)列名は
table_nameですが、結果の各行にはデータベースまたはデータオブジェクトと、それに対応するプライマリノードに関する情報が含まれています。 結果には、オブジェクトタイプが table の mysql/global_ddl_lock という名前のオブジェクトが含まれる場合もあります。 これは内部で使用されるため、無視できます。
バイナリログの設定
マルチマスタークラスター (Limitless) は、MySQL バイナリログと完全に互換性があります。クラスター内のすべてのプライマリーノードから操作ログを統合し、グローバルに統一され、論理的に順序付けられたバイナリログを生成します。
loose_polar_log_bin を使用して マルチマスタークラスター (リミットレス)のバイナリログ機能を有効にし、binlog_expire_logs_seconds を使用して マルチマスタークラスター (リミットレス)のバイナリログの保持期間を設定できます。 詳細については、「バイナリログを有効にする」をご参照ください。
マルチマスタークラスター (制限なし) は、Data Transmission Service (DTS) のソースおよび宛先として、一方向または双方向のデータ同期を実行できます。