2022.08.10

MySQL

MySQL NDB Cluster 8.0.30 GA版(リリース日:2022年7月26日)

追加・変更された機能

● 重要な変更; NDBレプリケーション: replica_allow_batchingシステム変数は、レプリカがエポックトランザクションを適用する効率に影響します。これがオフに設定されている場合、デフォルトでは、バイナリログ内の全ての個別のレプリケーションイベントが適用され、個別に実行されます。そのため、通常はパフォーマンスが低下します。

このリリースから、replica_allow_batchingのデフォルト値がOFFからONに変更されました。

● NDBレプリケーション: MySQL Clusterレプリケーションは、別の操作と同じプライマリキーを使用する場合に特定の操作を適用するかどうかを決定するために、循環レプリケーションのセットアップで使用する競合の検出と解決をサポートします。以前は、更新操作と削除操作のプライマリキーの競合を解決できましたが、同じプライマリキーを使用した書き込み操作の場合、実行された唯一の処理は、既存のものと同じプライマリキーを持つ書き込み操作を拒否し、同じプライマリキーを持つ書き込み操作が存在しない場合にのみ適用することでした。

このリリースでは、2つの新しい競合解決関数 NDB$MAX_INS()および NDB$MAX_DEL_WIN_INS()が導入されています。これらの各関数は、次に示す手順に従って、挿入(書き込み)操作間のプライマリキーの競合を処理します。

a. 競合する書き込みがない場合は、これを適用します(これは、NDB$MAX()およびNDB$MAX_DELETE_WIN()と同じ動作です)。

b. 競合が発生した場合は、次のように”最大のタイムスタンプ優先”の競合解決を適用します。

i. 着信書き込みのタイムスタンプが競合する書き込みのタイムスタンプよりも大きい場合は、着信書き込み操作を適用します。

ii. 着信書き込みのタイムスタンプがそれより大きくない場合は、着信書き込み操作を拒否します。

NDB$MAX_INS()は競合する更新および削除操作をNDB$MAX()と同じ方法で処理し、NDB$MAX_DEL_WIN_INS()はNDB$MAX_DELETE_WIN()と同じ方法で処理します。

この拡張機能により、競合するレプリケートされた書き込み操作を処理する時の競合検出を設定するためのサポートが提供されます。そのため、より高いタイムスタンプカラム値を持つレプリケートされたINSERTはべき等に適用され、より低いタイムスタンプカラム値を持つレプリケートされたINSERTは拒否されます。

他の競合解決関数と同様に、拒否された操作はオプションで例外テーブルに記録でき、拒否された操作はカウンターをインクリメントします。「より大きなタイムスタンプが勝つ」処理の場合、これはステータス変数 Ndb_conflict_fn_max_insであり、「同じタイムスタンプが勝つ」戦略の場合、インクリメントされるカウンターは Ndb_conflict_fn_max_del_win_insです。

(バグ #33398980)

● NDB レプリケーション: 以前は、レプリカNDB Clusterへの書き込み時に使用されるバッチのサイズは--ndb-batch-sizeによって制御され、BLOBデータをレプリカに書き込むために使用されるバッチサイズはndb-blob-write-batch-bytesによって決定されました。このスキームは、レプリカがこれらの変数のグローバル値を使用していたために、問題を引き起こしました。これは、レプリカでそれらのいずれかまたは両方を変更すると、他の全てのセッションで使用される値にも影響することを意味していました。この設定のもう1つの欠点は、レプリカアプライヤ専用のこれらのオプションに異なるデフォルトを設定できないことでした。なるべく他のセッションよりも高いデフォルト値を設定する必要があります。

このリリースでは、レプリカアプライヤに固有の2つの新しいシステム変数を追加することで、これらの問題を解決しています。現在は、ndb_replica_batch_sizeが、レプリカアプライヤに使用されるバッチサイズを制御します。ndb_replica_blob_write_batch_bytes変数が、レプリカでBLOBのバッチ書き込みを実行するために使用されるBLOB書き込みバッチサイズを決定します。

この変更により、デフォルト設定を使用したMySQL NDB Clusterレプリケーションの動作が改善され、SQLクエリの処理など、他のタスクを実行するユーザースレッドに影響を与えることなく、ユーザーがNDBレプリケーションを微調整できるようになります。

参照: バグ #21040523も参照してください。

● NDB Cluster API: Dictionary::getEvent()によって返される全てのイベントを管理するためにstd::uniqe_ptrを使用することにより、多くの潜在的なメモリリークが削除されました。

この修正の一環として、getEvent()で作成されたイベントを不要になった後にクリーンアップするreleaseEvent()メソッドをDictionaryに追加します。(バグ #33855045)

● NDB Cluster API: NDB Clusterに含まれるNode.JSパッケージがバージョン 16.5.0に更新されました。(バグ #33770627)

● CSVファイルの空の行が、ndb_import によって有効な入力として受け入れられるようになりました。(以前は、このようなファイルの空の行は常に拒否されていました。)現在は、単一のインポートされたカラムの値として空の値を使用できる場合、ndb_importはそれをLOAD DATAと同じ方法で使用します。(バグ #34119833)

● NDBは、BLOBカラムの値を他のタイプとは異なる方法で格納します。デフォルトでは、値の最初の256バイトのみがテーブルに(「インラインで」)格納され、残りは別のBLOBパーツテーブルに保持されます。これは、MySQLのタイプ BLOB、MEDIUMBLOB、LONGBLOB、TEXT、MEDIUMTEXT、およびLONGTEXTのカラムに当てはまります。(TINYBLOBとTINYTEXTは常にインラインのみであるため、例外です。)NDBはJSONカラムの値を同様の方法で処理します。唯一の違いは、JSONカラムの場合、値の最初の 4000バイトがインラインで格納されることです。

以前は、NDB API (Column::setInlineSize()メソッド) を使用することによってのみ、NDBテーブルのBLOBカラムのインラインサイズを制御することができました。これは、次のようなCREATE TABLEステートメントの一部として、BLOB_INLINE_SIZE仕様を含むNDB_COLUMN文字列で構成されるカラムコメントを使用して、mysqlクライアント(またはSQLインターフェースを提供する他のアプリケーション)で実行できるようになりました。

CREATE TABLE t (
a BIGINT NOT NULL AUTO_INCREMENT PRIMARY KEY,
b BLOB COMMENT 'NDB_COLUMN=BLOB_INLINE_SIZE=3000'
) ENGINE NDBCLUSTER;

上記のステートメントで作成されたテーブル tでは、カラム bはBLOBカラムであり、最初の256バイトだけではなく、最初の3000バイトがt自体に格納されます。これは、bに格納されている値の長さが3000バイトを超えない場合、カラムの値を格納または取得する時に、NDB BLOBパーツテーブルから余分なデータを読み書きするために余分な作業が必要ないことを意味します。これにより、BLOBカラムに対して多くの操作を実行する際のパフォーマンスが大幅に向上します。

このオプションの効果は、ndbinfo.blobsテーブルにクエリを行うか、ndb_descの出力を調べることで確認できます。

BLOB_INLINE_SIZEでサポートされている最大値は29980です。1未満の値に設定すると、デフォルトのインラインサイズがカラムに使用されます。

ALTER TABLEのコピーの一部としてカラムを変更することもできます。このような操作では、ALGORITHM=INPLACEはサポートされていません。

BLOB_INLINE_SIZEは、単独で使用することも、同じNDB_COMMENT文字列でMAX_BLOB_PART_SIZEと一緒に使用することもできます。MAX_BLOB_PART_SIZEの場合とは異なり、NDBテーブルのJSONカラムではBLOB_INLINE_SIZEの設定がサポートされています。

(バグ #33755627)

● 新しい --missing-ai-columnオプションがndb_importに追加されました。これにより、ndb_importはAUTO_INCREMENTカラムのデータが欠落しているCSVファイルを受け入れ、LOAD DATAと同じようにこれらの値自体を提供できます。これは、CSV表現にそのようなカラムの値が含まれていない1つ以上のテーブルで実行できます。

このオプションは、CSVファイルがインポートされるAUTO_INCREMENTカラムに空でない値を含まない場合にのみ機能します。(バグ #102730、バグ #32553029)

● このリリースでは、NDBCLUSTERによって使用されるトランザクションバッチメモリのパフォーマンススキーマインストゥルメンテーションが追加され、トランザクションによって使用されるメモリを監視できるようになりました。

主なバグ修正

● 重要な変更: ThreadConfigマルチスレッドデータノードパラメータを使用して、データノードで作成されるスレッドを指定する場合、場合によっては、受信スレッド(recv)が、DBLQH(0)やDBTC(0)などのブロックスレッドと同じワーカースレッドに配置されました。これはNDB 8.0.22以前からのリグレッションを表しており、このような場合に予想されるように、受信スレッドはTHRMANおよびTRPMANとのみ同じ場所に配置されていました。

現在、ThreadConfigの値を設定する時は、main、rep、recv、ldmを明示的に含める必要があります。main、rep、またはldmスレッドタイプを1つ以上使用しないようにするためには、該当するスレッドタイプごとにcount=0を明示的に設定する必要があります。

さらに、recvカウントに最小値1が適用されるようになりました。レプリケーションスレッド(rep)カウントを1に設定すると、メインスレッドもcount=1に設定する必要があります。

これらの変更は、以前のNDB Clusterリリースからのアップグレードに深刻な影響を与える可能性があります。(バグ #33869715)

参照: バグ #34038016、バグ #34025532も参照してください。

● macOS: ndbgeneralライブラリがLINK_LIBRARIESに明示的に含まれていなかったため、ndb_importをMacOS/ARMでコンパイルできませんでした。(バグ #33931512)

● NDB Disk Data: LGMANカーネルブロックは、ローカルの暗号化されたファイルシステムの状態を初期化せず、UNDOログファイルのEncryptedFileSystemをチェックしませんでした。そのため、それらの暗号化ステータスが実際に設定されることはありませんでした。

これは、リリースビルドの場合、一部のシステムでUNDOログファイルが暗号化されてはならないにもかかわらず、暗号化される可能性があることを意味していました。デバッグビルドでは、UNDOログファイルは常に暗号化されていました。これにより、Disk Dataテーブルを使用し、NDB 8.0.29へのアップグレードまたはNDB 8.0.29からのアップグレードをする時に問題が発生する可能性があります。(回避策は、その際にデータノードの初期再起動を実行することです。)

この問題は、UNDOログに書き込むDisk Dataの更新が非常に多い時、またはUNDOログの読み取り中にデータノードを起動した時に、I/Oスレッドの予期しないCPU負荷を引き起こす可能性もありました。

注意
NDB 8.0.29で導入されたEncryptedFileSystemパラメータは、実験的なものと見なされ、本番環境ではサポートされていません。

(バグ #34185524)

● NDB レプリケーション: ソースで非表示のプライマリキーのみを持つ(が、明示的なPKを持たない)NDBテーブルの行を更新すると、レプリカでSQLスレッドが停止する可能性がありました。(バグ #33974581)

● NDB Cluster API: 内部関数 NdbThread_SetThreadPrio()は、ThreadConfig設定パラメータの設定を適用する時に、特定のスレッドタイプのスレッド優先度(thread_prio)を設定します。この関数は、実際には成功した時にエラーを返す場合があり、一部のNDB APIアプリケーションのパフォーマンスに好ましくない影響を与える可能性がありました。(バグ #34038630)

● NDB Cluster API: 次のNdbInterpretedCodeメソッドは、ラベル引数にゼロ以外の値が使用された場合、正しく機能しませんでした:

・branch_col_and_mask_eq_mask()
・branch_col_and_mask_eq_zero()
・branch_col_and_mask_ne_mask()
・branch_col_and_mask_ne_zero()

(バグ #33888962)

● MySQL NDB ClusterJ: ARMベースのAppleシリコンを搭載したシステムに対するClusterJのサポートがデフォルトで有効になりました。(バグ #34148474)

● Debian 11およびUbuntu 22.04でのNDB Clusterのコンパイルは、ソースコードの警告がエラーとして処理されるために、リンク時間最適化フェーズ中に停止しました。(バグ #34252425)

● NDBは、カラムのデフォルト値のインプレース変更をサポートしていません。このような変更は、ALTER TABLEのコピーを使用することによってのみ行うことができます。このような場合のデフォルト値の変更は既に検出されていましたが、デフォルト値の追加または削除は検出されていませんでした。

ALTER TABLE中にデフォルト値が追加または削除されたことを検出し、その場での操作の実行を拒否することで、この問題を修正します。(バグ #34224193)

● SQLノード Aでユーザーを作成し、それにNDB_STORED_USER権限を付与した後、このユーザーをSQLノード Bから削除すると、結果に一貫性がなくなりました。場合によっては、その削除が分散されなかったため、削除後もユーザーがSQLノード Aに存在していました。

この問題の原因は、NDBがNDB_STORED_USERを使用して全てのローカルユーザーのキャッシュを保持しているが、ユーザーがSQLノード Bで作成された時に、このキャッシュが更新されなかったことです。その後、DROP USERを実行すると、SQLノード Bは削除が分散される必要がないと判断しました。新しい分散ユーザーが作成される度にこのキャッシュが更新されるようにすることで、これを修正します。(バグ #34183149)

● 内部のndbd_exit()関数がデータノードで呼び出された時、ndbd_exit()呼び出しの直前にイベントロガーに送信された情報とエラーメッセージが、期待どおりにログに出力されませんでした。(バグ #34148712)

● OpenSSL 3.0の変更により、MySQL ClusterはUbuntu 22.04で正しくコンパイルされませんでした。(バグ #34109171)

● Bisonフォールスルー処理の変更により、MySQL ClusterはGCC 8.4を使用して正しくコンパイルされませんでした。(バグ #34098818)

● ndbclusterプラグインまたはlibndbclientライブラリをコンパイルするためには、データノード(src/kernel)および管理サーバー(src/mgmsrv)に固有のディレクトリの下に保持される多数のファイルが必要でした。これらは、より適切な場所に移動されました。移動されたファイルのうち、興味深いものは次のとおりです。

・ndbd_exit_codes.cppはstorage/ndb/src/mgmapiに移動されました
・ConfigInfo.cppはstorage/ndb/src/common/mgmcommonに移動されます
・mt_thr_config.cppはstorage/ndb/src/commonに移動されました
・NdbinfoTables.cppはstorage/ndb/src/common/debuggerに移動されました

(バグ #34045289)

● スキーマトランザクションの開始フェーズでエラーが発生した時、トランザクションハンドルを解放せずにインデックス統計を自動的に更新しようとしたため、リークが発生しました。(バグ #34007422)

● パスの長さは、データノードによって常に正しく計算されるとは限りませんでした。(バグ #33993607)

● ndb_restoreがNDB API操作を実行し、同時NDB APIイベントが発生している時、DBUTILのリソースが制限されている場合に競合が発生する可能性がありました。これにより、NDBで一時的なエラーが発生しました。このような場合、ndb_restoreは失敗したNDB API操作を再試行するようになりました。(バグ #33984717)

参照: バグ #33982499も参照してください。

● 内部メソッド Dbtc::execSCAN_TABREQ()で見つかったテーブルポインターの重複チェックを削除しました。(バグ #33945967)

● GSN_TRANSID_AIシグナルからバッファからの属性値をアンパックする内部関数NdbReceiver::unpackRecAttr()は、属性サイズがバッファ内に収まるかどうかを確認しませんでした。これにより、バッファが破損し、バッファを超えて読み取られ、宛先バッファを超えてコピーされる可能性がありました。(バグ #33941167)

● 一部のコンパイラで採用されているフォーマット文字列検証がバイパスされないように、ログメッセージのフォーマットが改善されました。(バグ #33930738)

● 一部のNDB内部シグナルは、常に正しくチェックされるとは限りませんでした。(バグ #33896428)

● GCC 11.2でNDB Clusterをコンパイルする時に-Wunused-parameter警告を発生させたソースのいくつかの問題を修正しました。(バグ #33881953)

● SQLノードがまだNDBCLUSTERに接続されていない場合、SQLノードがNDBテーブルを検出できなかった時に、過剰な数の警告がMySQLエラーログに書き込まれました。(バグ #33875273)

● NDB API統計変数のNdb_api_wait_nanos_count、Ndb_api_wait_nanos_count_replica、Ndb_api_wait_nanos_count_sessionは、アプリケーションのCPU時間と待機時間を決定するために使用されます。これらのカウンターは、データノードからの応答の待機に費やされた時間を示すことを目的としていますが、キーリクエストの待機に費やされた時間が含まれていなかったため、完全に正確ではありませんでした。

(バグ #33840016)

参照: バグ #33850590も参照してください。

● 場合によっては、前のテーブル定義が削除される必要がある場合でも、重複したengine-se_private_idエントリがNDBテーブルのMySQLデータディクショナリにインストールされる可能性がありました。

データノードがクラスタから離脱し、再参加する必要がある時、各SQLノードは独自のデータディクショナリでスキーマ定義の同期を開始します。データディクショナリにインストールされたNDBテーブルのse_private_idは、そのNDBテーブルIDと同じです。ALTER TABLE、DROP TABLE、またはCREATE TABLEステートメントを実行する場合など、テーブルが異なるIDで更新されることはよくあります。schema.table形式でテーブルを参照することによって取得された以前のテーブル定義は、通常、削除に十分であり、したがって新しいテーブルを新しいIDでインストールするには十分です。これは、他のインストール済みテーブル定義がそのIDを使用していないと想定されるためです。これに対する例外が同期中に発生する可能性がありました。データノードのシャットダウンにより、インストールされるテーブル以外の同じIDを持つテーブルの以前のテーブル定義が残る可能性があった場合、その後、古い定義は削除されませんでした。

この問題を修正するために、データディクショナリにインストールされるテーブルのIDが以前のものと異なるかどうかを確認するようになりました。その場合、古いテーブル定義がそのIDで既に存在するかどうかも確認します。存在する場合は、続行する前に古いテーブルを削除します。(バグ #33824058)

● COPY_FRAGREQシグナルを受信した後、DBLQHは、シグナルオブジェクトを格納されたオブジェクトにコピーすることによって、シグナルをキューに入れることがあります。着信COPY_FRAGREQが保存される前に、このシグナルオブジェクトが別のシグナルを送信するために使用されると、問題が発生する可能性がありました。これにより、破損したシグナルが格納され、送信されるとシステムの再起動が完了しなくなりました。これを修正するために、元のシグナルオブジェクトではなく、シグナルの静的コピーを使用して格納と取得を行います。(バグ #33581144)

● NDB Clusterで提供されるmysqldバイナリがNDBサポートを有効にせずに実行された場合、ndbinfoおよびndb_transid_mysql_connection_mapプラグインは引き続き有効であり、例えば、SHOW PLUGINSの出力でステータスがACTIVEで表示されます。(バグ #33473346)

● REDOログページを取得しようとすると、間違ったバウンドエラーが原因で理論上失敗する可能性がありました。(バグ #32959887)

● データノードが--foregroundオプションを使用して開始された時、ノードIDが有効なホストから接続するように設定されていない場合、データノードはエラーを報告する代わりに強制的にシャットダウンされました。(バグ #106962、バグ #34052740)

● NDBテーブルはMySQLサーバーのアップグレードフェーズでスキップされ、代わりにndbclusterプラグインによって後の段階で移行されました。その結果、NDBテーブルに関連付けられたトリガーは、5.7ベースのバージョンからのアップグレード中に作成されませんでした。

これが発生したのは、全ての.TRGファイルが削除されるMySQL Serverアップグレードのアップグレード最終段階でトリガーに関するメタデータが失われるために、NDBテーブルがndbclusterプラグインによって移行される時にそのようなトリガーを作成できないためでした。

この問題を修正するために、次の変更を行います。

・トリガーを含むNDBテーブルの移行は、サーバーのアップグレードフェーズ中に延期されなくなりました。
・初期システム起動が検出された場合でも、トリガーを含むNDBテーブルがセットアップ中にデータディクショナリから削除されなくなりました。

(バグ #106883、バグ #34058984)

● ファイルを初期化する時、NDBFSは自動同期を有効にしましたが、do_sync_after_write()を呼び出すことはありませんでした(その後 sync_on_write()と呼び出しました)。そのため、ファイルは保存されるまでディスクに同期されませんでした。これは、ネットワークディスクがしばらく停止しているシステムの場合、ファイルがバッファリングされたファイルデータでシステムメモリを使い果たす可能性があることを意味しました。

NDBFSがファイルに書き込む度にdo_sync_after_write()を呼び出すことで、これを修正します。

この作業の一環として、ファイルの初期化時に自動同期のサイズを1MBから16MBに増やしました。

注意
NDBはO_SYNCを提供するプラットフォームでO_SYNCをサポートしますが、ファイルを開くためのOM_SYNCを実装しません。

(バグ #106697、バグ #33946801、バグ #34131456)


全ての変更点やバグ修正については、以下のページをご覧ください。
MySQL NDB Cluster 8.0.30リリースノート(MySQLウェブサイト):

https://dev.mysql.com/doc/relnotes/mysql-cluster/8.0/en/news-8-0-30.html


MySQL Editions

MySQL Editions
MySQLのサブスクリプションは、24時間365日体制でお客様をサポートいたします。さらに MySQL Enterprise Edition では、データベース管理者支援ツール MySQL Enterprise Monitor やバックアップツール MySQL Enterprise Backup をご利用いただけます。