1. 背景
あるECプロジェクトで、AWS Aurora MySQLを利用しています。テーブルの主キー(IDカラム)をINT
型のAUTO_INCREMENT
に設定していましたが、購買履歴テーブルのレコード数がINT
型の上限(2,147,483,647)に迫る状況に直面しました。
この上限に達すると、新規レコードの追加ができなくなり、サービス停止という重大な事態につながる可能性があります。そのため、カラムの型をINT
型からBIGINT
型に変更し、上限を引き上げる必要がありました。
本記事では、Aurora のBlue/Green Deploymentを用いてINT
型のカラムをBIGINT
へ変更する過程で直面した課題とその解決策についてまとめます。この経験が誰かの役に立てば幸いです。
なぜINTからBIGINTへの変更は大変なのか?については以下の記事をご参考ください。
2. INTからBIGINTへの変更を行う案の概要
当初は以下の2種類の案を調査、整理しました:
-
pt-online-schema-change
を利用する案(同じインスタンス、同じDBで新しいテーブル作成) - レプリケーションを利用するBlue/Green Deploymentの案(完全に新しい環境/インスタンスを作成し、レプリケーションを通じてリアルタイムにデータ同期)
さらにこちらは以下の案に分けられます:- 手動
binlog
レプリケーション - RDS read replica利用
- AWS DMS
- RDS Blue/Green Deployment
- 手動
Auroraを使用しているため、Blue/Green Deployment方式であればフルサポートが可能なRDS Blue/Green Deploymentが最適と判断し、それ以外の3つの案は除外しました。
今回はpt-online-schema-change
案とRDS Blue/Green Deployment
案の2つに絞って比較しました。
3. pt-online-schema-change利用の案
3.1 pt-online-schema-changeの概要
pt-online-schema-change(pt-osc)はPercona Toolkitの一部で、MySQLテーブルの構造を変更する際にダウンタイムを最小限に抑えるツールです。
pt-online-schema-change --alter "MODIFY COLUMN id BIGINT" D=database,t=table
3.2 動作原理
pt-online-schema-change (pt-osc)の動作原理について、主要なポイントを詳しく解説します:
-
新しいテーブルの作成:
- pt-oscは元のテーブルと同じ構造を持つ新しいテーブルを作成します。
- 新しいテーブル名は通常、元のテーブル名の前に "_" を付けたものになります。
- 非常に短時間(通常はミリ秒単位)のメタデータロック、この間、DDL操作はブロックされますが、SELECT/INSERT/UPDATE/DELETEは影響を受けません
-
新テーブルへのALTER文の適用:
- 指定されたALTER文(この場合は
MODIFY COLUMN id BIGINT
)を新しいテーブルに適用ALTER TABLE table_name MODIFY COLUMN column_name BIGINT;
- この時点では新テーブルにはデータがないため、高速に完了します。
- 指定されたALTER文(この場合は
-
トリガーの作成:
-
元のテーブルにINSERT、UPDATE、DELETEの3つのトリガーを作成します。
-
これらのトリガーは、元のテーブルへの変更を新テーブルにリアルタイムで反映させます。
-
-
データのコピー:
- 元のテーブルから新テーブルへデータをチャンク(小さな単位)でコピーします。
- コピー中も元のテーブルへの書き込みは可能で、トリガーによって新テーブルに反映されます。
-
テーブルの入れ替え:
- データコピーが完了したら、RENAME TABLE文を使用して新旧テーブルを瞬時に入れ替えます。
- 入れ替える際に短時間(通常は1秒未満)のロックが発生
- すべての書き込み操作がブロック
- 読み取り操作は通常影響を受けません)
-
クリーンアップ:
- 古いテーブルの削除とトリガーの削除を行います。
レプリケーションへの対応:
pt-oscはレプリケーション環境を考慮して設計されています。マスターでの操作がスレーブに正しくレプリケートされるよう、以下の対応をしています。これにより、マスターでの変更がスレーブに正確に反映され、データの整合性が保たれます。
- バイナリログの形式をROWに設定することを推奨
- トリガーの作成・削除をバイナリログに記録
- RENAME TABLE操作をバイナリログに記録
3.3 注意点
- 非常に単純で、コマンド一つで実行可能ですが、同じインスタンス上で大規模なデータコピーが発生するため、本番データベースのパフォーマンスに影響を与える可能性があります。実施する前に、一時的にインスタンスのスペックを上げることなどの必要性を検討したほうがよいでしょう。
- コスト面:
ツール自体は無料ですが、実行中のパフォーマンス影響を考慮してインスタンスのスペックアップが必要な場合があります。
例:一時的にインスタンスタイプをr5.2xlargeからr5.4xlargeにアップグレードする場合、数時間から数日の追加コストが発生する可能性があります。 - 非常に大規模なテーブルの場合、処理時間が長くなる可能性があります。
この方法により、pt-oscはテーブルへのアクセスを維持しながら、大規模なスキーマ変更を安全に実行することができます。
参考記事:
3.4 replicationを利用するBlue/Green Deploymentの案
Blue/Green Deployment
は新しい概念でも Aurora 専用の手法でもありません。
これは、アプリケーションの新バージョンをリリースする際に広く使用される一般的なデプロイメント戦略です。
最近はインフラエンジニアにとってはもはや当たり前になってきました。
Blue/Green Deploymentsでは、本番環境をコピーしてグリーン環境を作成し、そこで変更をテストすることができます。この手法を用いることで、本番環境に影響を与えることなく、データベースのメジャーまたはマイナーバージョンのアップグレードやデータベースパラメータの変更を行うことができます。グリーン環境での変更をテストし、問題がなければ、グリーン環境を新しい本番環境としてプロモートすることができます。
3.5 2つの案の比較
特性 | pt-online-schema-change | Aurora Blue/Green Deployment |
---|---|---|
処理場所 | 同一インスタンス、同一DB、新しいtable | 別々の環境(別々のインスタンス) |
複雑さ | 低 - 単一コマンドで実行可能 |
中 - AWS設定が必要 |
実装時間 | 短い - 自動化された処理 | 中 - 環境構築に時間要 |
リスク | 中 - 短時間ロックあり - 同一インスタンスでの処理によるオーバーヘッドあり |
低 - 切り替え前環境維持、別環境で処理、切り替え時のみ影響 |
コスト | 低 - ツール無料、一時的なインスタンス増強の必要性あり |
高 - 環境複製で一時的にコスト倍増 |
データ整合性 | 高 - ツールが自動管理 |
高 - AWS管理で保証 |
ロールバック容易性 | 中 - 現環境に対して修正するため、手動復旧が必要な場合あり |
高 - 切り替え前環境が維持されるため容易 |
アプリケーション変更 | 不要 | 不要 |
プラットフォーム依存性 | 低 - MySQL環境であれば基本的に使用可能 |
高 - AWS MySQL専用 |
バイナリログ影響 | なし | あり - 有効化が必要で若干のオーバーヘッドあり |
大規模データベース対応 | 中 - 大規模DBでは時間がかかる可能性あり | 高 - 大規模DBでも効率的に処理可能 |
この比較表から、以下のような結論が導き出せます:
-
pt-online-schema-changeは、シンプルさ、コスト効率、柔軟性において優れています。特に小規模から中規模のデータベース、またはAWS以外の環境でも使用可能です。
-
Blue/Green Deploymentは、完全に別のGreen環境で作業するため、安全性、スケーラビリティ、大規模データベース対応において優れています。特にAWS Aurora MySQLを使っているので、最後にRDS Blue/Green Deploymentを使うことにしました。
4. Aurora Blue/Green Deploymentsを利用してみる
4.1 利用の条件
- バイナリログの有効化: Blue環境でバイナリログを有効にする必要があります。バイナリログのフォーマットはROWが推奨されますが、以下のことが注意したほうがよい。
- ログの肥大化やディスク容量の増加
- I/O速度(パフォーマンスへの影響):通常5%未満
- クラスタの再起動が必要:
クラスターパラメータグループの変更が適用されていないと、グリーン環境を作成できない。変更後はクラスタの再起動が必要です。 - 一時的に2つの環境を維持する必要があるため、コストが倍増する期間がある。
4.2 切替までの流れ
-
バイナリログの有効化:Aurora再起動が必要なので注意
-
AuroraにRDS Blue/Green Deploymentsを有効化して、新Aurora Cluster(Green環境)を作成
Green環境作成時にBlue環境DBの停止は発生するか?
検証結果としてはライター(読み書き)、リーダー(読み込み)どちらも停止がなかった。
CPU利用率については、ライターのCPU使用率5%ほど1分間増えただけで、後は平常と変わっていない。
: -
Green環境で
ALTER TABLE
を実行して、int
型をbigint
型に変更SHOW CREATE TABLE purchase_history; CREATE TABLE `purchase_history` ( `purchase_id` int(11) NOT NULL AUTO_INCREMENT, `user_id` int(10) unsigned NOT NULL, `product_id` int(10) unsigned NOT NULL, `quantity` int(10) unsigned NOT NULL, `purchase_date` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP, PRIMARY KEY (`purchase_id`) ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci
ALTER TABLE purchase_history MODIFY COLUMN purchase_id BIGINT AUTO_INCREMENT;
Green環境でのALTER TABLE操作には約60時間を要しましたが、この間も現行Aurora(Blue環境)は通常通りにトラフィックを処理し続けたため、長時間のサービス停止を回避できました。
-
ALTER TABLE実行完了後、以下の点を慎重に観察:
-
Green環境で一通り機能テストを実施
-
本番切替時にRDS Blue/Green DeploymentsのSwitch Overを実行し、Green環境を新本番環境に昇格させました。この操作には以下の特徴がありました:
-
アプリケーション側の変更不要:
元のデータベースエンドポイントが自動的にGreen環境に向けられたため、アプリケーション側のコード変更や設定変更は一切必要ありませんでした。 -
短時間のサービス中断:
- 切替に要した時間は約2分でした。この間、データベースへの接続が一時的に中断されるため、サービスは利用できません。
- 2分間の切替時間以外は、サービスは通常通り利用可能でした。つまり、全体のプロセスの中で、実際のサービス中断時間は非常に短く抑えられました。
-
サービスのダウンタイムを測定:
サービスのダウンタイムを正確に測定するために、APIのエンドポイントへcurlコマンドを継続的に実行してみます。$ while true; do date; curl http://***/api/path ; date; sleep 1; done | tee -a /tmp/tee.log
-
切り替え後に切り戻しはできるか?
切り替え後もBlue環境は保持されますが、Green環境からのレプリケーションが切断された、読み取り専用(Read-only)のクラスターとなります。
Blue環境には切り替え時点のデータしか残っておらず、ユーザーからのトラフィックを停止しない限り、Blue環境とGreen環境の間にデータの差分が発生します。そのため、切り替え後に簡単にBlue環境に戻すことはできません。
-
アプリケーション側の変更不要:
-
旧環境を別途削除
5. まとめと考察
-
pt-online-schema-change
とRDS Blue/Green Deployment
の比較:
pt-online-schema-change
は興味深いツールですが、同一インスタンス上で新しいテーブルを作成してデータをコピーする方式であるため、既存の本番環境へのパフォーマンス影響が懸念されました。一方、RDS Blue/Green Deployment
はマネージドサービスとして提供されており、より安全性と信頼性が高いと判断し、最終的にこちらを選択しました。 - Auroraでの
binlog
有効化の影響:
Auroraではbinlog
を有効にする必要があり、これによってBlue環境に対して若干のパフォーマンス影響が生じる可能性があります。そのため、実施中は環境の状態を入念に監視し、必要に応じて対応を取ることが重要です。 - 短時間のダウンタイムは避けられませんでしたが、全体としてはサービスへの影響を最小限に抑えつつ、大規模なデータベース変更を安全に実施できました。この点を考慮すると、RDS Blue/Green Deploymentの採用は非常に効果的な選択だった。
この方法により、技術的な複雑さを抑えつつ、ビジネス継続性を維持しながら重要なインフラストラクチャの更新を実現できました。今後同様の作業を行う際の有効な参考事例になると幸いです。