Amazon Web Services ブログ

Amazon Aurora MySQL バージョン 2 (MySQL 5.7 互換) からバージョン 3 (MySQL 8.0 互換) へのアップグレードのチェックリスト、パート2

本記事は、Amazon Aurora MySQL version 2 (with MySQL 5.7 compatibility) to version 3 (with MySQL 8.0 compatibility) upgrade checklist, Part 2 を翻訳したものです。

最初のパートでは、 Amazon Aurora MySQL互換エディション v2 から v3 へのアップグレードの事前チェックが失敗する原因となる最も一般的な問題を説明しました。この投稿ではアップグレードが長引いて失敗する最も一般的な原因について説明します。

クラスターにプリペアード状態のXA トランザクションがある

Amazon Aurora MySQL はアップグレード中にデータベース内でプリペアード状態の XA トランザクションを検出した場合、アップグレードをキャンセルします。データベースをフェイルオーバーまたは再起動しても、プリペアード XA トランザクションは削除されません。アップグレード前にプリペアード XA トランザクションを見つけてコミットまたはロールバックする必要があります。次のコードはその方法を示す簡単な例です。

セッションを開きXA トランザクションを開始し、その後セッションを閉じます。

mysql> USE sakila;
Reading table information for completion of table and column names
You can turn off this feature to get a quicker startup with -A
Database changed

mysql> XA START 'gtridtest','bqualtest',123456;
Query OK, 0 rows affected (0.00 sec)

mysql> UPDATE actor SET first_name='testname' WHERE actor_id=3;
Query OK, 1 row affected (0.00 sec)
Rows matched: 1 Changed: 1 Warnings: 0

mysql> XA END 'gtridtest','bqualtest',123456;
Query OK, 0 rows affected (0.00 sec)

mysql> XA PREPARE 'gtridtest','bqualtest',123456;
Query OK, 0 rows affected (0.00 sec)

mysql> exit;

xid は XA トランザクションの識別子です。これはどのトランザクションにステートメントが適用されるかを示します。xid の値はクライアントから与えられるか MySQL サーバーが生成します。xid の値はgtrid [, bqual [, formatID]]のように1から3のパートからなります。gtrid はグローバルトランザクション識別子、bqual はブランチ修飾子、formatIDgtrid および bqual の値で使用されるフォーマットを識別する番号です。 bqualformatID はオプションです。指定しない場合、デフォルトの bqual の値は ‘ ‘ です。指定しない場合、デフォルトの formatID の値は 1 です。

この時点でデータベース内にプリペアード XA トランザクションがあります。次のコマンドは、プリペアード XA トランザクションを発見します。

mysql> XA RECOVER CONVERT xid;
+----------+--------------+--------------+----------------------------------------+
| formatID | gtrid_length | bqual_length | data |
+----------+--------------+--------------+----------------------------------------+
| 123456 | 9 | 9 | 0x677472696474657374627175616C74657374 |
+----------+--------------+--------------+----------------------------------------+
1 row in set (0.00 sec)

出力列は次の意味を持ちます。:

  • formatID はトランザクションxidformatID パートです
  • gtrid_lengthxidgtrid パートのバイト長です
  • bqual_lengthxidbquoalパートのバイト長です
  • dataxidgtridパートとbqualパートを連結したものです

これらの値から、次のdataフィールドのパートを抜き出せます。

  • gtrid = 0x677472696474657374
  • bqual = 0x627175616C74657374

ロールバックするには、XA ROLLBACK コマンドを使用します。

mysql> XA ROLLBACK 0x677472696474657374,0x627175616C74657374,123456;
Query OK, 0 rows affected (0.01 sec)

クラスターに多数のテーブルがある

Aurora MySQL は公開ドキュメントで概要が説明されているように、メジャーバージョンのアップグレードを多段階のプロセスとして実行します。クラスター内に多数のテーブルがあると、事前チェックとエンジンバージョンアップグレードのステップの時間が長くなる可能性があります。エンジンバージョンのアップグレードステップは、データディクショナリのアップグレードとサーバーのアップグレードの 2 つのステップで行われます。

MySQL 8.0 と MySQL 5.7 では、MySQL データディクショナリの保存方法に大きな変更があります。MySQL 5.7 以前では、MySQL ディクショナリデータはデータファイル(.frm ファイル、.par ファイル、.trn ファイル) に保存されていました。たとえば、デフォルト値である innodb_file_per_table =1 の場合、各 InnoDB テーブルにはそれぞれの .frm ファイルが存在します。しかし MySQL 8.0 では、MySQL ディクショナリデータは mysql スキーマ内のテーブルに集中的に保存されます。これによりMySQL ドキュメントで確認できる利点がもたらされます。上記のデータディクショナリのアップグレードステップでは、サーバーは更新された定義でデータディクショナリテーブルを作成し、永続化されたメタデータを新しいテーブルにコピーし、古いテーブルを新しいテーブルにアトミックに置き換えて、データディクショナリを再初期化します。したがって、クラスターに多数のテーブルが含まれている場合、多数のメタデータファイルの削除、テーブルへの移行により、アップグレード全体の時間が長くなる可能性があります。 Amazon Aurora MySQL のバージョンアップグレードも非常に似ているため、多数のテーブルがあることによる影響も同様に当てはまります。

サーバーのアップグレードステップでは、サーバーは必要に応じてユーザースキーマ内のテーブルを処理します。テーブルをチェックして問題が見つかった場合は修復しようとしますが、クラスター内に多数のテーブルがある場合、特に大きなテーブルの場合は時間がかかる可能性があります。

v2 から v3 へのアップグレードにおいて、テーブル数の多さの影響を軽減するため、バックアップテーブルや古いテーブルパーティションなど未使用のテーブルを確認して削除することをお勧めします。 多数のテーブルを含むクラスターのメジャーバージョンをアップグレードすると、リソースが大量に消費され、日々のワークロードを超える可能性があります。 テストアップグレード中にリソースの競合が発生した場合は、本番環境のインスタンスクラスを一時的にスケールアップし、アップグレード完了後にスケールダウンすることを検討してください。CPU 競合に対して CPUUtilization、メモリ負荷に対して FreeableMemorySwapUsage、インスタンスのスループットに対して NetworkThroughputStorageNetworkThroughput など、主要な Amazon CloudWatch メトリクスを監視する必要があります。 次のクエリを実行して、クラスター内のテーブルの数を取得できます。

SELECT count(*) AS TOTAL_NUMBER_OF_TABLES FROM INFORMATION_SCHEMA.TABLES;

本番環境への影響を最小限に抑えるために、クローンクラスターでこのクエリを実行することをお勧めします。本番環境の負荷を伴う多数のテーブルを含む本番環境のインスタンスでこのクエリを実行すると、時間がかかり、データベースのパフォーマンスが低下する可能性があります。

クラスターに多数のundo レコードがある

インプレースアップグレードメカニズムには、処理の実行中に DB クラスターをシャットダウンすることが含まれます。 Amazon Aurora MySQL はクリーンシャットダウンを実行し、undo パージなどの特別な処理を完了させます。 RDS Blue/Green デプロイメントスナップショットリストアを使用した場合でも、パージする undo レコードが多数ある場合、アップグレードに時間がかかる可能性があります。

クラスターのライターインスタンスの Amazon Aurora MySQL CloudWatch メトリクス RollbackSegmentHistoryListLength (HLL) の値は、マルチバージョン同時実行制御 (MVCC) を実行するためにデータベースによって保存されている undo レコードの数を示します。 SHOW ENIGNE INNODB STATUS を実行して、TRANSACTIONS セクションの History list length の値を探すこともできます。History list length が小さくなってからのみ、アップグレードを実行することを検討してください。 一般に許容される History list length の値は 100,000 以下です。ただし、HLL の減少速度は、アプリケーションのワークロード、スキーマのプロパティ、インスタンスクラスターの設定などの多くの要因に依存します。高い HLL の問題に対処する必要がある場合は「Amazon Aurora MySQL DB クラスターで SELECT クエリの実行が遅いのはなぜですか?」「InnoDB 履歴リストの長さが大幅に増加しました。」、および「パージ設定」を参照してください。 Amazon RDS Blue/Green デプロイメントを使用して、高い HLL の問題を回避することもできます。グリーンのクラスターでのアップグレード時間は短縮されませんが、アプリケーションのダウンタイムを最小限に抑えるのに役立ちます。 ただし、長引いたアップグレードのためにグリーンクラスターが同期されるまでに時間がかかる可能性があることに注意してください。

クラスターに実行中の大きな書き込みトランザクションがある(多数の行への未コミットの変更)

undo パージと同様に、トランザクションのロールバックがクリーンシャットダウン中に発生するため、ロールバックする行が多数ある場合はアップグレードに時間がかかる可能性があります。 未完了のトランザクションをロールバックするのにかかる時間は、サーバーの負荷に応じて、トランザクションが中断されるまでのアクティブな時間の 3 倍または 4 倍になる場合があることに注意してください。 ロールバック時間を見積もる簡単な方法はありません。 ロールバック中のトランザクションをキャンセルすることはできません。 単にデータベースを再起動したりクラスターをフェールオーバーしただけでは、トランザクションのロールバックは高速化されず、一部のデータがディスクからメモリに再ロードされるため、場合によっては速度が低下する可能性があります。.

そのため、アップグレードを進める前に次のクエリを実行して未コミットの行の合計数を確認する必要があります。:

SELECT * FROM INFORMATION_SCHEMA.INNODB_TRX ORDER BY TRX_ROWS_MODIFIED DESC;

このテーブルにはトランザクションごとに 1 行が含まれます。 TRX_ROWS_MODIFIED 列にはトランザクションによって変更または挿入された行の数が含まれます。すべての大規模なトランザクションがコミットまたはロールバックされた後にのみアップグレードを実行することを検討してください。

クラスターに長時間実行中、または未コミットなアイドルトランザクションがある

長時間実行されている読み取り専用または読み書きトランザクションや、未コミットのアイドル状態のトランザクションはテーブルロックを保持する可能性があるため、アップグレードの事前チェックの完了をブロックする可能性があります。 その結果、アップグレードに非常に時間がかかったり、停止しているようにさえ見える場合があります。この問題が発生した場合、select * from information_schema.processlist where USER='rdsadmin' を実行すると、FLUSH LOCAL TABLE コマンドが Waiting for table flush の状態で待機しているか、CHECK TABLE コマンドが Waiting for table metadata lock の状態で待機していることが表示されることがあります。この場合、次のクエリを使用してブロックしているトランザクションを特定し、可能であれば状況に応じてそれらをコミット、ロールバック、またはキルできます。

SELECT * FROM information_schema.innodb_trx\G
SELECT * FROM information_schema.processlist where id=<# trx_mysql_thread_id from innodb_trx table above>;

CALL mysql.rds_kill(#id from processlist table above);

この問題を解決するには、アップグレードプロセスを開始する前に、長時間実行中のトランザクションまたは未コミットのアイドル状態のトランザクションを特定してください。これを行うには次のクエリを実行します。

SELECT a.trx_id,a.trx_state,a.trx_started,
TIMESTAMPDIFF(SECOND, a.trx_started, now()) as "Seconds Transaction Has Been Open",
a.trx_rows_modified,b.id,b.USER,b.host,b.db,b.command,b.time,b.state

from
information_schema.innodb_trx a,information_schema.processlist b

where
a.trx_mysql_thread_id = b.id
order bytrx_started;

そしてそれらが完了するまで待つか、可能であればキルします。 大規模な書き込みトランザクションをキルした場合、上記のセクションで説明したようにロールバックに時間がかかる可能性があることに注意してください。

CALL mysql.rds_kill(#id from processlist table above);

同じクエリを使用して、クラスターがデータ定義言語 (DDL) ステートメントを処理しているかどうかを確認できます。 すべての DDL ステートメント (CREATE、DROP、ALTER、RENAME および TRUNCATE) が完了してからアップグレードを実行してください。そうしないと Amazon Aurora MySQL はアップグレードをキャンセルします。 DDL の実行中に中断することはお勧めできません。関連テーブルでデータディクショナリの不整合の問題が発生する可能性があります。

結論

この記事では、アップグレードが長引いて失敗する最も一般的な原因について説明しました。 Amazon Aurora MySQL バージョン 2 は 2024 年 10 月 31 日にサポート終了となるため、Aurora MySQL v3 で利用可能な新しい機能と最適化を利用できるよう、Aurora MySQL バージョン 2 クラスターを Aurora MySQL v3 のデフォルトのマイナーバージョン以上にできるだけ早くアップグレードすることをお勧めします。


著者について

Huy Nguyen は AWS サポートのシニアエンジニアで、Amazon RDS、Amazon Aurora を専門としています。彼は AWS クラウドにおいてスケーラブルで、可用性が高くかつ安全なソリューションを構築できるよう、顧客にガイダンスと技術支援を提供しています。

Leevon Abuan はAWS サポートのデータベースエンジニアです。彼は Amazon RDS と Amazon Aurora に重点を置き、クラウドにてデータベースを実行する際の複雑な技術的問題の解決のため、顧客を支援してきました。

本記事の翻訳はクラウドサポートエンジニアの吉村悠が担当しました。