Amazon Web Services ブログ

Amazon RDS for MySQLでMySQLエンジンバージョンを5.5から5.7へアップグレードする方法

Amazon Web Servicesでは、フルマネージド型のリレーショナルデータベースサービスとして、Amazon Relational Database Service (Amazon RDS) および Amazon Aurora を提供しています。Amazon RDS for MySQLを利用することで、AWSクラウド上でMySQLを容易にデプロイし、運用管理を行うことができるようになります。
Amazon RDSでは、定期的にメジャーまたはマイナーエンジンバージョンの廃止を行います。メジャーバージョンについては、コミュニティ版の対象バージョンがEOLを迎え、ソフトウェアの修正やセキュリティアップデートが行われなくなった場合に廃止を行います。メジャーバージョンのアップグレードには、既存のアプリケーションと互換性のないデータベースの変更が含まれる場合があります。そのため、DB インスタンスのメジャーバージョンアップグレードは、事前に十分な検証を行うことを推奨致します。

この記事では、アップグレードの必要性と、その方法についてご説明します。

 

Amazon RDS for MySQL 5.5の廃止

Amazon RDS for MySQL 5.5 は、UTC 協定世界時間の 2021 年 2 月 9 日 00:00:01 (JST 日本標準時間の 2021 年 2 月 9 日(火) 09:00:01) に廃止されます。Amazon RDS for MySQL 5.6 は、2021 年前期に廃止を予定しております。2021 年 2 月 9 日までに MySQL メジャーバージョン 5.5 を実行しているデータベースを、メジャーバージョン 5.7 以降にアップグレードすることを強くお勧めします。MySQL 5.7 には、JSON データ型のネイティブサポート、ネイティブ InnoDB 空間インデックスを使用した GIS、SYSスキーマを使用した新しいパフォーマンスメトリクスのパフォーマンススキーマなどの主要な機能強化、不具合やセキュリティに関する修正も含まれています。

※ MySQLバージョン5.6へのアップグレードを行った場合、Amazon RDS for MySQL 5.6廃止予定の2021年前期に再度アップグレード対応が必要になります。

※ Amazon RDS for MySQL 5.5廃止日時をすぎると、MySQLバージョン 5.7 に順次自動にアップグレードされます。詳細は「Amazon RDS for MySQL バージョン 5.5 のサポート終了のお知らせ」をご確認ください。

 

MySQLバージョン5.5から5.7へのアップグレード注意点

MySQLのメジャーバージョン5.5から5.7へのアップグレードに関して、注意事項をご説明いたします。

 

MySQLレプリケーションの制限

メジャーバージョンのアップグレード方法として、レプリケーションを利用する方法があります(詳細は後述)。その場合の注意点として、MySQLは1つのメジャーバージョンから次のメジャーバージョンへのレプリケーションをサポートしていますが、2つ上のメジャーバージョンへのレプリケーションはサポートされていません。詳しくはこちらをご覧ください。

 

時間・日付型の非互換な変更

MySQL バージョン 5.6.4 から、datetimetimetimestamp 列で、日付と時刻の値に小数部を使用できる新しい日付と時刻の形式が導入されました。Amazon RDSインスタンスを MySQL バージョン5.5から5.7にアップグレードすると、内部的にmysql_upgradeを実行してすべてのdatetimetimetimestampの列のタイプを新しい形式に変換します。この変換作業により、アップグレード時間が長くなる可能性があります

このような場合は、DB インスタンスを MySQL バージョン 5.7 にアップグレードする前に、データベース内の datetimetime、および timestamp 列を変換するために、この列を含む各テーブルで、ALTER TABLE <table_name> FORCE; コマンドを実行することをお勧めします。リードレプリカで事前に変換処理をしておくことにより MySQL バージョン 5.7 へのアップグレードに必要な時間を大幅に削減することが可能です。

※ MySQLバージョン5.6.4以降で作成されたテーブルでは変換作業が不要

datetimetime、または timestamp 列を含むすべてのテーブルをデータベース内で検索し、各テーブルの ALTER TABLE <table_name> FORCE; クエリを作成するには、「MySQL バージョン 5.7 へのアップグレードは遅くなる場合がある」のクエリを実行することで実現出来ます。
以下は、そのクエリを実行し、各テーブルの ALTER TABLE <table_name> FORCE; クエリを作成した例です。


MySQL [testdb]> SELECT DISTINCT CONCAT('ALTER TABLE `',
    ->       REPLACE(is_tables.TABLE_SCHEMA, '`', '``'), '`.`',
    ->       REPLACE(is_tables.TABLE_NAME, '`', '``'), '` FORCE;')
    ->     FROM information_schema.TABLES is_tables
    ->       INNER JOIN information_schema.COLUMNS col ON col.TABLE_SCHEMA = is_tables.TABLE_SCHEMA
    ->         AND col.TABLE_NAME = is_tables.TABLE_NAME
    ->       LEFT OUTER JOIN information_schema.INNODB_SYS_TABLES systables ON
    ->         SUBSTRING_INDEX(systables.NAME, '#', 1) = CONCAT(is_tables.TABLE_SCHEMA,'/',is_tables.TABLE_NAME)
    ->       LEFT OUTER JOIN information_schema.INNODB_SYS_COLUMNS syscolumns ON
    ->         syscolumns.TABLE_ID = systables.TABLE_ID AND syscolumns.NAME = col.COLUMN_NAME
    ->     WHERE col.COLUMN_TYPE IN ('time','timestamp','datetime')
    ->       AND is_tables.TABLE_TYPE = 'BASE TABLE'
    ->       AND is_tables.TABLE_SCHEMA NOT IN ('mysql','information_schema','performance_schema')
    ->       AND (is_tables.ENGINE = 'InnoDB' AND syscolumns.MTYPE = 6);
+----------------------------------------------------------------------------------------------------------------------------------------------+
| CONCAT('ALTER TABLE `',
      REPLACE(is_tables.TABLE_SCHEMA, '`', '``'), '`.`',
      REPLACE(is_tables.TABLE_NAME, '`', '``'), '` FORCE;') |
+----------------------------------------------------------------------------------------------------------------------------------------------+
| ALTER TABLE `testdb`.`testtable` FORCE;                                                                                                           |
+----------------------------------------------------------------------------------------------------------------------------------------------+
1 row in set (0.19 sec)

なお、ALTER TABLEは、内部的にテーブル内のデータをコピーする処理が発生するため、以下の点を注意する必要があります。

  • データ量が多いほどALTER TABLEの時間が長くなる
  • 処理中は排他ロックが発生する
  • 元のテーブルサイズと同等のストレージの空き容量が必要

MySQL ALTER TABLEの仕組み イメージ図

これらを踏まえ、サービスのワークロードへの影響と作業の複雑性の観点から、本ブログではアップグレードプランを以下3案に絞ってまとめました。

 

Amazon RDS for MySQLのバージョン5.5から5.7へのアップグレードプラン

プランは大きく2種類あります

① 同一インスタンス上でアップグレードを実施するIn-Placeプラン(プラン1)
② リードレプリカを作成し利用するプラン(プラン2, 3)

MySQL DB インスタンスが本番稼働しているアプリケーションで使用されているなどの理由で、長時間のダウンタイムが許容されない場合は、リードレプリカを用いたアップグレードプラン(プラン2, 3)を実施することでダウンタイムの時間を短縮できます。これは前途の、datetimetime、および timestamp 列の形式変換作業によって長期化が懸念されるアップグレード作業を、本番稼働DBとは別のDB(リードレプリカインスタンス)で実施できるためです。
アップグレード作業を行ったリードレプリカインスタンスの昇格後、アプリケーションなどが接続するDBを変更することで、切替を実施します。
※ リードレプリカの「昇格」は、プライマリインスタンスとは別のインスタンスとして独立します。昇格前のプライマリインスタンスとの入れ替わりが発生するわけではありません。

(例) プライマリインスタンス「mysql-5-5-46-3」、リードレプリカインスタンス「mysql-5-5-46-3-rr-up」の場合、AWSマネジメントコンソール上では以下の表記となる
昇格前 レプリカ作成
昇格後 リードレプリカの昇格

 

また、リードレプリカを用いたアップグレードプラン(プラン2, 3)の場合、MySQL バージョン5.6へアップグレードしたリードレプリカインスタンスを、そのままIn-Place方式でMySQL バージョン5.7にアップグレードすることも可能です。しかし、その場合はMySQL バージョン5.5のプライマリインスタンスからMySQL バージョン5.7のリードレプリカへのレプリケーションとなるため、メジャーバージョン差分が2つ以上あるレプリケーションが発生してしまいます。前途の通り、MySQLでは2つ上のメジャーバージョンへのレプリケーションはサポートされていないため、この方法は利用できません。

どのプランを採用されるかはお客様のワークロードや状況に合わせてご検討頂く必要があります。各プランの作業内容をご確認の上、最終的な判断が必要です。

各プランの手順をご紹介する前に、重要な作業をピックアップしてご紹介します。
なお、本ブログではテストに関する詳細情報は対象外としておりますが、メジャーバージョンのアップグレードでは、非互換な仕様変更があります。アップグレード後のDBインスタンスで十分なテストを行い、アプリケーションが問題なく動作することを必ず確認してください。

 

レプリケーションの遅延状態を確認する

リードレプリカを使ったアップグレードプランを実施する場合、レプリケーションの同期が完了していることを確認した後、リードレプリカインスタンスを昇格させる必要があります。

リードレプリカインスタンスをプライマリインスタンスとして昇格する際、元のプライマリインスタンスとのレプリケーションの関係性は無くなります。データの欠損を発生させないためには、レプリケーション遅延が解消されていることを確認した上で、リードレプリカインスタンスの昇格作業を行う必要があります。

Amazon RDS for MySQLではデフォルトで、バイナリログファイルの位置ベースのレプリケーションで リードレプリカへのデータ連携を行います。SHOW MASTER STATUS; コマンド、及び SHOW SLAVE STATUS; コマンドを利用してレプリケーション状況を確認することが可能です。詳しくは「Amazon Relational Database Service (Amazon RDS) for MySQL を使用時に、レプリカの遅延を確認」をご確認ください。

※ GTID ベースのレプリケーションは、Amazon RDS for MySQL バージョン 5.7.23 以降の MySQL 5.7 バージョンでサポートされています。GTIDベースのレプリケーションを使用したい場合は「Amazon RDS MySQL の GTID ベースレプリケーションを使用する」を参照ください。

 

DBインスタンスのエンドポイント切替作業

リードレプリカを使ってアップグレード作業を行った場合、アプリケーションから接続するDBインスタンスを、プライマリインスタンスへ昇格させた(旧リードレプリカ)インスタンスへ変更する必要があります。

DB インスタンスの「DB 識別子(DB instance identifie)」を変更すると、DB インスタンスのエンドポイント名が変わります。DBインスタンスの名前を変更することにより、DB インスタンスを参照するアプリケーションコードを変更せずに DB インスタンスを置き換えることができます。

DBインスタンスの名前は、AWS アカウントが現在の AWS リージョンで所有している全ての DB インスタンスにおいて一意である必要があります。従って、既存のDBインスタンスと同名に変更したい場合は、既存のDBインスタンスの名前を一度テンポラリー名に変更する必要があります。詳しい手順は「DB インスタンスの名前を変更する」「名前を変更して既存の DB インスタンスを置き換える」をご参照ください。

 

プライマリインスタンスがマルチAZ構成の場合のパーフォーマンス影響低減作業

プライマリインスタンスがマルチAZ構成である場合、最終的に昇格させるリードレプリカインスタンスもマルチAZ構成にする必要があります。リードレプリカを使ってアップグレード作業を行った場合、リードレプリカのMySQLバージョンを5.7へアップグレードした際にマルチAZ構成に設定してからプライマリインスタンスへ昇格することで、パーフォーマンス影響を抑えることが可能です。

 

切り戻し作業

十分な計画・準備・テストを実施していたとしても、当日問題が発生しないとは限りません。重要なことは、

① 問題が発生したと判断する基準
② 問題が発生したと判断した場合に実施する作業

を事前に準備することです。

①に関しては、アプリケーションやサービスの状況に大きく左右されます。「何が」「どこで」「どのくらい発生した場合」「誰が判断する」といった項目を、サービス毎に整理する必要があります。

②に関してAmazon RDSでは、切り戻し作業を簡易化できる仕組みを提供しています。
Amazon RDSによって、アップグレードプロセス中に 2 つの DB スナップショットが作成されます。最初の DB スナップショットは、アップグレードの変更が行われる前の DB インスタンスから作成されます。アップグレードが完了すると、2 番目の DB スナップショットが作成されます。

切り戻し作業を行うには、アップグレード前に作成されたスナップショットを復元して、アップグレード前のバージョンを実行するDBインスタンスを作成し、必要に応じてエンドポイントの切替を行います。
ただし、Amazon RDS for MySQL バージョン 5.5 の廃止後は、MySQLバージョン5.5 のスナップショットの復元が出来なくなるためご注意ください。

※ Amazon RDSのインスタンスはアップグレードが完了したら、データベースエンジンを前のバージョンに戻すことはできません。

 

各プランの概要手順

ここから、各プランの手順をご紹介します。
なお、テストの工程は省いています。テストに関してはアップグレードをテストするをご参照ください。

 

プラン1「In-Place」の概要手順

プラン1は、同一インスタンス上でアップグレードを実施するIn-Placeプランです。プラン2, 3と比べ、作業内容はシンプルになります。
一方、サービスが直接利用しているDBインスタンスをアップグレードするため、サービスのワークロードへの影響は大きくなります。

  1. MySQL バージョン5.6, MySQL バージョン5.7用のパラメータグループを作成し、それぞれアプリケーションに合わせた設定を行う
  2. MySQL バージョン5.5のスナップショットを作成※ スナップショットから作成したDBでアップグレードテストを実施するために実施
  3. DB書き込みを停止(メンテナンス開始)
  4. MySQL バージョン5.5をMySQL バージョン5.6へアップグレード
  5. DB書き込み開始(メンテナンス終了)
  6. MySQL バージョン5.6のスナップショットを作成※ スナップショットから作成したDBでアップグレードテストを実施するために実施
  7. DB書き込みを停止(メンテナンス開始)
  8. MySQL バージョン5.6に「ALTER TABLE <table_name> FORCE; 」を実行
  9. MySQL バージョン5.6をMySQL バージョン5.7へアップグレード
  10. DB書き込み開始(メンテナンス終了)

 

プラン2「RRのリプレイス」の概要手順

プラン2は、リードレプリカインスタンスを作成し利用するプランです。
プラン1と異なり、サービスが直接利用していないDBインスタンスでアップグレード作業を行い、アップグレード完了後にDBインスタンスを置き換える手順のため、サービスのワークロードへの影響が少なくなります。
一方、リードレプリカインスタンスの作成、レプリケーション状況の確認、リードレプリカインスタンスをプライマリインスタンスへ昇格する作業が必要です。

  1. MySQL バージョン5.6, MySQL バージョン5.7用のパラメータグループを作成し、それぞれアプリケーションに合わせた設定を行う
  2. リードレプリカインスタンスを作成(MySQL バージョン5.5DBインスタンスから)
  3. リードレプリカインスタンスのアップグレード(MySQL バージョン5.5→MySQL バージョン5.6)
  4. DB書き込みを停止(メンテナンス開始)
  5. レプリケーション遅延が解消されていることを確認(「レプリケーションの遅延状態を確認する」を参照)
  6. リードレプリカインスタンスを昇格
  7. プライマリインスタンスのエンドポイント名とリードレプリカインスタンスのエンドポイント名を置き換える
    1. 旧プライマリインスタンスの名前を、プライマリインスタンスではなくなったことを示す名前に変更
    2. 旧リードレプリカインスタンス(昇格後のリードレプリカインスタンス)の名前を、旧プライマリインスタンスの名前に変更し、アクセスできることを確認
    3. 旧プライマリインスタンスを削除
  8. DB書き込み開始(メンテナンス終了)
  9. リードレプリカインスタンスを作成(MySQL バージョン5.6のDBインスタンスから)
  10. MySQL バージョン5.6から作成したリードレプリカインスタンスに設定しているパラメータグループの「read_only」パラメータを0に設定※ リードレプリカインスタンスに「ALTER TABLE」による書き込み処理を行うために実施
  11. MySQL バージョン5.6から作成したリードレプリカインスタンスのDBインスタンスに「ALTER TABLE <table_name> FORCE; 」を実行
  12. リードレプリカインスタンスのアップグレード(MySQL バージョン5.6→MySQL バージョン5.7)
  13. プライマリインスタンスがマルチAZ構成の場合、リードレプリカインスタンスをマルチAZ構成に変更※ プライマリインスタンスへ昇格する前にこの工程を実施することで、マルチAZ構成変換時のパフォーマンス影響を少なくすることが可能
  14. DB書き込みを停止(メンテナンス開始)
  15. レプリケーション遅延が解消されていることを確認(「レプリケーションの遅延状態を確認する」を参照)
  16. リードレプリカインスタンスを昇格
  17. プライマリインスタンスのエンドポイント名とリードレプリカインスタンスのエンドポイント名を置き換える(手順7と同作業)
  18. DB書き込み開始(メンテナンス終了)

 

プラン3「孫RRのリプレイス」の概要手順

プラン3は、リードレプリカインスタンスを作成し利用するプランです。リードレプリカインスタンスから、更にリードレプリカインスタンスを作成(多段レプリケーション)して、バージョンアップ作業を実施します。
プラン2より「DBインスタンスのエンドポイント切替作業」が1度で済むため、サービスのワークロードへの影響が少なくなります。
一方、多段レプリケーションを実施しているので、レプリケーション遅延の解消まで時間が必要な場合があります。プライマリインスタンスのバイナリログ保持期間を十分に確保するといった注意が必要です。

  1. MySQL バージョン5.6, MySQL バージョン5.7用のパラメータグループを作成し、それぞれアプリケーションに合わせた設定を行う
  2. リードレプリカインスタンスを作成(MySQL バージョン5.5のDBインスタンスから)
  3. リードレプリカインスタンスのアップグレード(MySQL バージョン5.5→MySQL バージョン5.6)
  4. MySQL バージョン5.6の自動バックアップを有効化 ※ リードレプリカインスタンスを作成するためには、自動バックアップを有効化する必要有り
  5. リードレプリカインスタンスを作成(MySQL バージョン5.6リードレプリカインスタンスから) (例) プライマリインスタンス「mysql-5-5-46-4」、リードレプリカインスタンス「mysql-5-5-46-4-rr」、孫リードレプリカインスタンス「mysql-5-5-46-4-rr56-rr57」の場合、AWSマネジメントコンソール上では以下のような表記となる
  6. MySQL バージョン5.6リードレプリカインスタンスのパラメータグループ「read_only」パラメータを0に設定 ※ リードレプリカインスタンスに「ALTER TABLE」による書き込み処理を行うために実施
  7. MySQL バージョン5.6に「ALTER TABLE <table_name> FORCE; 」を実行
  8. リードレプリカインスタンスのアップグレード(MySQL バージョン5.6→MySQL バージョン5.7)
  9. プライマリインスタンスがマルチAZ構成の場合、リードレプリカインスタンスをマルチAZ構成に変更 ※ プライマリインスタンスへ昇格する前にこの工程を実施することで、マルチAZ構成変換時のパフォーマンス影響を少なくすることが可能
  10. DB書き込みを停止(メンテナンス開始)
  11. レプリケーション遅延が解消されていることを確認(「レプリケーションの遅延状態を確認する」を参照)
  12. リードレプリカインスタンスを昇格
  13. プライマリインスタンスのエンドポイント名とリードレプリカインスタンスのエンドポイント名を置き換える
    1. 旧プライマリインスタンスの名前を、プライマリインスタンスではなくなったことを示す名前に変更
    2. 旧リードレプリカインスタンス(昇格後のリードレプリカインスタンス)の名前を、旧プライマリインスタンスの名前に変更し、アクセスできることを確認
    3. 旧プライマリインスタンスを削除
  14. DB書き込み開始(メンテナンス終了)

 

まとめ

今回ご紹介した内容の他にも、MySQLエンジンバージョンの仕様変更箇所がいくつかございます。詳細については、MySQL公式ドキュメントを参照ください。

DBのメジャーバージョンアップグレードは、事前の計画・準備・テストを念入りに実施することで、問題が発生するリスクの低減や、万一発生した場合のダウンタイムを最小化することが出来ます。
本記事が皆様のバージョンアップ作業のお役に立てれば幸いです。

 


 

著者について

asaimomo

浅井ももこ(Momoko Asai) 
データベースが好きなソリューションアーキテクト。お客様の技術支援を行っています。好きなサービスは Amazon Timestream と Amazon Aurora です。