手元で検証していてハマった。ロック待ちを短くしてmetadata lock待ちを短くしてひたすらALRTERをループさせるとどうなるんだ?というのをやりたくてinnodb_lock_wait_timeoutをずっと変えていたが全然変わらなくてmy.cnfか?globalで設定されていない???という状態になっていた。innodb_lock_wait_timeout は行ロック時にタイムアウトするための設定でした。はい。
というかどんだけタイムアウトあるんだ...
gh-ostは、GitHubが開発したMySQLデータベース用のオープンソースツールです。gh-ostは「GitHub's Online Schema Migrations」の略で、MySQLのテーブルに対するスキーマ変更を実行時にサービスのダウンタイムを最小限に抑えつつ行うことができるというもの。実装はMySQL系のツールとしては珍しくGoとなっている。InnoDB用にはオンラインDDLありますが、それら方法との違いは バイナリログでテーブルの変更を補足しながらマイグレーションするという点です。
上記の記事から抜粋。
1. 変更したいテーブル(基テーブル)の空のコピーテーブル(ゴーストテーブル)を作成 2. ゴーストテーブルに対して指定したALTERステートメント実行 3. 基テーブルの既存データをゴーストテーブルにコピー 4. マイグレーション実行中、基テーブルへの新規DMLはバイナリログから抽出し、ゴーストテーブルへ適用 ※ 3と4は並列で稼働します 5. 3と4が終わると、基テーブルとゴーストテーブルを入替(カットオーバー)
pt-oscではトリガーを用いてテーブルデータのコピーをするがgh-ostではバイナリログを用いている点が違う。またバイナリログの取得先はレプリカになるためプライマリには負荷がかかりにくいとのこと。CREATE TRIGGERは対象のテーブルに対してメタデータロックを取りに行くという動作をするのでテーブルの読み書きが多い場合には失敗するケースがあったがgh-oscではその心配すらいらないのが便利。ただ5でRENAME TABLEを打つだろうからそこはどっちにしろ気にする必要はありそう。(MySQL 8.0からの子テーブルへの参照で親にもMDLを取る話の回避策にならんかなと思ったけどまあ無理ですよね...)とはいえカットオーバーフェーズは大分短いだろうからそれだけでも嬉しい。
仕組み上そうなのでbinlogを取れないみたいな環境だと使えなくなってしまう。Auroraってそういえばbinlogないようなと思って調べたら設定することは可能とのことだった。Auroraからレプリケーションを組みたいケースとかで使えるっぽい。(リードレプリカの仕組みだけが頭にあったのでないだろうと思ったらそういう用途があったのかとなった)
動くけどGitHubはRDS使ってないからコミュニティでやってね!とのこと。