https://y-asaba.hatenablog.com/entry/2018/12/21/002811
この記事は裏freee developers Advent Calendar 2018の21日目の記事です。
freee株式会社でプロダクト基盤本部本部長をしています浅羽と申します。プロダクト基盤は文字通りプロダクトの基盤を作っており、SRE、分析基盤、アカウントアグリゲーション基盤を作っているチームになっています。コードを書く時間を減らして組織づくりにフォーカスしていますが、とはいえサービスを良くするためには技術も素振りする必要があると思っています。ということで、組織的な話ではなく技術的な話を書こうと思います。
サービスを運営しているとデータベースがだんだん大きくなってきて、RDBMSの性能がスローダウンするような場面があると思います。その引き金としてクエリが遅くなったり、大きめのテーブルに対してADD COLUMNをしてしまうなどがありえそうでしょうか。freeeではRDMBSはMySQLをメインに使っています。ADD COLUMNに関してはMySQLの場合はONLINE DDLも存在していますが、それでも結構気を使います。
2017年にAmazon AuroraでFast DDLなる機能がリリースされ、それとは全然実装が違うと思いますがMySQLでもInstant ADD COLUMNという機能が2018年にリリースされました。
これは文字通りに解釈すれば最高な機能なのですが、長くソフトウェアエンジニアをやっているとこういうgood newsを疑ってしまってなにか罠があるんじゃないか?と思ったので、ちゃんと調べてみようと思いました。ただ、実際にちゃんと調べてみると結構大変でまとまっているのかは怪しいですが、誰かが更に深掘りしてくれると信じて書いたものを出してみます。
MySQLのALTER TABLEは5.7ではCOPY方式とINPLACE方式の2つありました。詳細は以下のドキュメントを読んでいただきたいのですが、ざっくり書くとこんな感じです。
MySQL :: MySQL 5.7 Reference Manual :: 14.13.1 Online DDL Operations
MySQL5.7でALGORITHMを指定せずにADD COLUMNをした場合は大抵の場合はInplaceの挙動になります(詳しくはドキュメントをご覧ください)。ただ、以下の処理が裏で走るため
ちなみに、↑はMySQL5.6のONLINE DDLの処理を社内qiitaにまとめたときにコードを読んだ仕組みなので、もしかしたら5.7では挙動が変わっているかもしれません。観測している感じだと5.6と5.7でそんなに挙動は変わっていない気もします。
さて、やっと本題になりますが、MySQL 8.0.12からInstant ADD COLUMNという機能が追加されました。ALTER TABLEではALGORITHM=INSTANTです。
MySQL :: MySQL 8.0 Reference Manual :: 13.1.9 ALTER TABLE Syntax