スマートスタイル TECH BLOG

データベース&クラウド技術情報

PXCのNon-Blocking Operations方式の紹介

はじめに

Percona XtraDB Cluster(PXC) 8.0.25からOnline Scheme Upgradesの新方式としてNon-Blocking Operations(NBO)方式が追加されました。

本記事ではこのNBO方式について紹介したいと思います。
なお、NBO方式はTech Previewです。変更される可能性があり、テスト目的での使用が推奨されています。

現行のOnline Scheme Upgradesの方式

現在PXCでは、次の2つの方法のOnline Scheme Upgrades(OSU)をサポートしています。

  • Total Order Isolation(TOI)
  • Rolling Schema Upgrade(RSU)

それぞれの詳しい特徴は以前にも本ブログで取り上げているため、こちらの記事をご参照ください。
簡単にまとめると次のような特徴を持ちます。

  • TOI
    • DDLを実行した時に全ノードで整合性が保たれる
    • DDLが完了するまでの間は全てのトランザクションが待機、またはロールバックされる
    • DDLは全ノードに適用される
  • RSU
    • DDLを実行するノードはクラスターとの同期を解除する
    • 全ノードに手動でDDLを実行する必要がある
    • ノード間で不整合が発生する可能性がある

どちらの方式にもメリット・デメリットがありますが、特に時間がかかるDDLをTOIで実行する場合は、その間クラスタが更新を受け付けなくなってしまいPXCにおける懸念事項の1つでした。

Non-Blocking Operations

NBO方式は、TOI方式、RSU方式に続く、第3のOSUの方式です。
DDL操作の最終段階でテーブルまたはスキーマのメタデータロックを取得します。 より効率的なロック戦略を提供するため、TOIで長時間更新がブロックされる問題を回避することが可能です。
これまでは一貫性を重視する場合はTOI方式で、全ノードで全ての更新をブロックする必要がありましたが、NBOでは一貫性を保証しつつ、DDL操作を行っていないテーブルにはDDL中も更新ができるようになりました。

  • NBO
    • 操作中のテーブル以外への変更はブロックされない
    • DDLは全ノードに適用される
    • 一部のDDLのみサポート

サポートされているDDLは以下の3つです。

  • ALTER TABLE
  • CREATE INDEX
  • DROP INDEX

デモ

NBO方式でDDLを実行してみます。デモの内容は過去の記事で行ったTOIのデモと同じことを行います。

また、今回は最新リリースのPXC8.0.26を使用します。

1. 大きなテストテーブルを作成する

2. もう1つ同様のテストテーブルを作成する

3. wsrep_osu_method=NBOの状態で、インデックスを追加するDDLを実行する

4. ALTER実行中に新しいクライアントを開いて、test.large_tblに対して SELECT / UPDATE を実行する

TOIと同様SELECTはDDL中にも実行でき、UPDATEはDDLが完了した後に完了します。

5. ALTER実行中に新しいクライアントを開いて、large_tbl_2に対して SELECT / UPDATE を実行

TOIとは異なり、別のテーブルへのUPDATEがDDL中でも完了します。

NBOの制限

NBO方式にもいくつかの制限があります。

サポートされていないDDL

サポートされていないDDL(ALTER TABLE,CREATE INDEX,DROP INDEX以外のDDL)を実行した場合は、DDLの実行時にエラーとなります。

同じテーブルへの同時DDL

NBO方式は、同じテーブルでロックが競合する2つのDDLステートメントの実行をサポートしていません。

The NBO method does not support running two DDL statements with conflicting locks on the same table. For example, you cannot run two ALTER TABLE statements for an employees table.

Non-Blocking Operations (NBO) method for Online Scheme Upgrades (OSU) | Limitations

実際に試してみるとエラーなりました。

test.large_tblにDDLを実行します。

別のクライアントでも同じタイミングでtest.large_tblにDDLを実行します。

片方のクライアントはDeadlockエラーとなりました。

NBO中のSST

NBOの実行中のState Snapshot Transfer(SST)は、失敗します。

Attempting a State Snapshot Transfer (SST) fails during the NBO operation.

Non-Blocking Operations (NBO) method for Online Scheme Upgrades (OSU)

node2が起動するタイミングでnode1でDDLを実行してみます。

node2はしばらくすると以下のような起動に失敗したことを示すメッセージを返します。

node2のエラーログでは以下のようなメッセージが確認できました。

まとめ

TOIと異なり、DDL実行中ではないテーブルは更新し続けられるというのは、非常に便利です。OSU実行時の有力な方式となりそうです。
また、「NBOの制限」で確認した通り、サポートされていないDDLは実行できないため、GLOBALではTOIまたはRSUに設定し、NBO方式でDDLを実行したいときだけSET SESSION wsrep_OSU_method='NBO';で設定するという運用方法がいいのではないかと思います。
サポートされているDDLが増えるのかなど、今後の機能改善には注目していきたいです。

Return Top