MySQLのオンラインDDLとpt-online-schema-change

技術本部 サービスリライアビリティグループ(SRG)の鬼海(@fat47)です。
#SRG(Service Reliability Group)は、主に弊社メディアサービスのインフラ周りを横断的にサポートしており、既存サービスの改善や新規立ち上げ、OSS貢献などを行っているグループです。
本記事は、SRG 内にある DBWG(DBワーキンググループ)が全社内向けに提供しているデータベースに関する資料を公開します。
なにかの役に立てば幸いです。
 
 

概要


サービスの仕様追加や新規開発で、既存テーブルへのカラムの追加やインデックスの追加などのDDL(Data Definition Language)操作が必要になることがあります。
その時にサービス稼働中に普通にDDL操作を行ってしまうと、テーブルロックが発生し重大なサービス障害に繋がる可能性があります。
下記の方法を利用することでテーブルのロックを防いで、オンラインでDDL操作を行うことが可能です。
 

結論


💡
AWS Auroraの場合 - MySQL公式機能のオンラインDDLを使う - 後述の理由で使えないなら次点でpt-online-schema-change RDS(MySQL) 、もしくは素のMySQL(5.5~5.7)の場合 - pt-online-schema-changeを使う
 

方法


MySQLの公式機能を使う(MySQL5.6~)

MySQL5.6から実装されたオンラインDDL機能により、操作の一部がロック不要で実行できるようになりました。
抜粋すると下記のような操作がオンラインで実行可能です。
  • OPTIMIZE TABLE
  • ADD INDEX
  • CREATE INDEX
  • DROP INDEX
  • カラムの追加
  • カラムの削除(コスト高注意)
  • 外部キー制約の追加・削除
 
また、MySQL8.0.12からはINSTANT DDLという機能が加わり、メタデータのみを更新することで高速にDDL操作を行うことができるようになりました。
⚠️
ただしALGORITHM=INSTANTで実行するためには下記のような制約があります。
  • カラムの追加は、ALGORITHM=INSTANT をサポートしない他の ALTER TABLE アクションと同じステートメントで組み合せることはできません。
  • カラムは、テーブルの最後のカラムとしてのみ追加できます。 他のカラム間の他の位置へのカラムの追加はサポートされていません。
  • ROW_FORMAT=COMPRESSED を使用するテーブルにはカラムを追加できません。
  • FULLTEXT インデックスを含むテーブルにはカラムを追加できません。
  • カラムは一時テーブルに追加できません。 一時テーブルでは、ALGORITHM=COPY のみがサポートされます。
  • データディクショナリテーブルスペースに存在するテーブルにはカラムを追加できません。
  • 行サイズ制限は、カラムの追加時には評価されません。 ただし、行サイズ制限は、テーブルの行を挿入および更新する DML 操作中にチェックされます。
 
8.0.29以降ではALTER文を実行した際、INSTANTをサポートしている操作の場合はALGORITHM未指定でもデフォルトでINSTANTが使用されます。
また、下記のような機能の追加がありました
  • 末尾にカラム追加だけではなく他の位置へのカラム追加も可能
  • DROP COLOMNに対応
詳しくは公式ドキュメントのオンラインDDLの項目をご参照ください。
 
このオンラインDDLの機能を利用する際の注意点は、
ALGORITHM=INSTANTが実行できない状況でデータサイズの大きいテーブルで実行するとそのままレプリケーション遅延する
という点です。
マスターDBでDDL実行したものが20分掛かった場合、マスターで実行完了後にスレーブDBで実行されるので、
それがそのまま20分のレプリケーション遅延となります。
💡
実行環境がAmazon RDS Auroraの場合はアーキテクチャが異なるためこの通りではありません
 
これを防ぐにはスレーブで先にDDL実行したあとに、マスターDBでbinlogを一時的に吐かない状態にしてDDLを実行します。
これを一般的にRolling Schema Upgradeと呼びます。ただこの方法にもデメリットはあります。
スレーブで先にカラムの型変更やカラム追加が行われている状態となるため、
その状態でもアプリケーションのつくりは問題ないかを事前に確認しておく必要があります。
これらの点が許容できない場合は後述のpercona製のツールを利用する方法があります。

pt-online-schema-changeを利用する

pt-online-schema-change(以下pt-osc)はPercona ToolKitに同梱されているツールで、通常テーブルロックがかかってしまうALTER文をロック無しで実行してくれるツールです。
このツールのアーキテクチャや詳細は下記のページで解説しているのでご参照ください。
『オンラインで安全にスキーマ変更可能なpt-online-schema-change』
Amebaのソーシャルゲーム全般のインフラを担当しつつ賃貸マンションの間取りを眺めたり、戸境壁の工法による防音性の違いについて日夜研究しています。 いつか D値 が60以上のマンションに住みたいです。 さて、今回はWebサービスを運用しているとたびたび発生する「新機能開発の為にINDEX追加やカラム追加を行いたい」 数年前まではそういった変更の際は、ゲームをメンテナンス状態にしてからスキーマ変更を行っていました。 しかしゲームをメンテナンス状態にする事は、各方面への調整や利用者への影響が大きいため そこで私達のチームではオンラインでスキーマ変更が可能なpt-online-schema-change(pt-osc)を導入することにしました。 pt-online-schema-changeとは「 Percona-Toolkit 」に同梱されているツールで、 通常はロックが掛かってしまうALTER TABLEクエリをロックなしで実行することが可能になります。 が実装されましたが、MySQL5.6からは無停止でINDEX追加やカラム追加ができるオンラインDDL 運用しているゲームのデータベースはMySQL5.5の為、このツールによりスキーマ変更を実現させています。 3.トリガーを3つ作成し、対象テーブルAへの挿入・削除・更新が作業用テーブルBに反映されるようにする インストールは簡単です(例:CentOSに導入する場合) # yum install http://www.percona.com/downloads/percona-release/redhat/0.1-3/percona-release-0.1-3.noarch.rpm # yum install percona-toolkit # pt-online-schema-change --execute --alter="ADD INDEX idx_hogehoge(hoge_id)" h=localhost,D=DB_NAME,t=TABLE_NAME,u=root 動作の仕組み上、テーブルのコピーやトリガーの処理が走るため、実行中は普段より高負荷になりやすいです。 そのためpt-online-schema-changeには本番環境へ悪影響が出ないように、リソース状況をチェックしながら動作を制御できる便利なオプションが存在しています このように色々な機能がある便利なツールですが、運用で利用できなかったパターンや事故が発生したこともあります。 あまりこのような事例がネットの記事になかったのでいくつかご紹介したいと思います。 # pt-online-schema-change --execute --alter="ADD INDEX idx_hoge(id_hoge)" h=localhost,D=d1,t=t_1,u=root You did not specify --alter-foreign-keys-method, but there are foreign keys that reference the table.
 
percona toolkitのインストール方法などは公式ドキュメントをご参照ください。
 
pt-oscを利用することでオンラインDDLの機能がないMySQL5.5でのオンラインDDL実行や、
実行時間が長いDDLも比較的レプリケーション遅延がしづらいように実行することが可能です。
 
カラム追加の場合の実行サンプル
 
このツールも制約などがあるため、すべての状況で利用できるわけではありません。
事前に検証環境でテストした上でご確認ください。
 

終わりに


SRG では一緒に働く仲間を募集しています。 ご興味ありましたらぜひこちらからご連絡ください。
このエントリーをはてなブックマークに追加