オンラインDDLとは
MySQLでDBマイグレーション、テーブル構造を変更(ALTER TABLE)するときに
テーブルロックを最小限に抑えてサービスを止めずに実行できる DDL(データ定義言語) を
オンラインDDL(Online DDL)と呼びます。
オンラインDDLでは、ALTER TABLEの実行中でも
SELECT(読み取り)
INSERT / UPDATE / DELETE(書き込み)
ができるようになります。
とはいえ正確には “完全にノーロック” ではなく、一瞬だけ短いロックをとる
という方式に改善されています。
なぜオンラインDDLが重要なのか
通常の(オフライン)DDL ではこうなります
- ALTER TABLE実行中、テーブル全体がロックされる
- SELECT / INSERT / UPDATE / DELETE がブロックされる
- サービスが止まる or パフォーマンスが大きく低下する
- オワタ
つまり、DDL実行 = サービス停止につながるのでALTER TABLEをする際はかなり慎重に行わなくてはなりませんでした。。。
そこで登場したオンラインDDLについていくつかパターンがあるので順に解説します!
ALGORITHM
| ALGORITHM | 概要 |
|---|---|
| INSTANT | データディクショナリのメタデータのみを変更する。 |
| INPLACE | テーブル定義をインプレースで変更する。一部のDDLはテーブルの再構築を伴う。 |
| COPY | 新たにテーブルを作成し、既存のテーブルからデータをコピーした後に、テーブルを入れ替える。~ |
上記表の下に記載されているもの程サービスへの影響は高くなります。
では、全部INSTANTでええやん!となりますが、オンラインDDLで選択できるALGORITHMには条件があります。
詳しくはMySQLの公式ドキュメントにできるできないの表があるのでそちらを見ていただくイメージしやすいかと思います!
https://dev.mysql.com/doc/refman/8.0/ja/innodb-online-ddl-operations.html
例えばカラムの追加(条件あり)はINSTANTを指定できますが、カラム名の変更はINSTANTを指定できません!
都度要件に応じて上記ドキュメントを見て最適なALGORITHMを選択するのが良いかと思います!
オンラインDDLの実行例
カラムにINDEXを貼るケースを想定してみます(ALGORITHMはINPLACE)
ALTER TABLE users
ADD INDEX idx_created_at (created_at)
ALGORITHM=INPLACE
LOCK=NONE;
- ALGORITHM=INPLACE
→ テーブルコピーを避け、既存データを再作成しない - LOCK=NONE
→ 読み書き操作をブロックしない
動きは下記のようになります!
- ALTER TABLE 発行
- InnoDB 内部でバックグラウンドスレッドがインデックスを構築
- その間、INSERT/UPDATE/DELETE は “差分ログ” に書き込まれ、後でマージ
- 完了したら新インデックスと入れ替え
- 4.の際、一瞬だけメタデータロック(MDL)を取得して終了
終わりに
最後まで読んでいただきありがとうございました!
後からテーブル構造を変えることは日常的によく起こりうるため、オンラインDDLが使えそうな場合は必ず使うようにするのが良いかと思います!
参考