AWS Aurora3系を使うときに気にしたい変更点まとめ
これはなに
ども、レバテック開発部のもりたです。
Aurora MySQLの2系が2024年10月31日にサポート終了となります。これに向けてどこもかしこも Aurora3系に移行していると思うので、Aurora2系(MySQL5.7)→ Aurora3系(MySQL8.0)の主だった変更点をまとめてみました。
前提と意図
- Aurora3系と書いてますが、LTSであるAurora3.04を想定しています
- Aurora3.04はMySQL8.0.28に相当するので、そこまでの変更点を書きます
- MySQL8.0.28までの変更点を網羅すると膨大すぎるので、網羅はしません
- 基本的な方針としては、先行するアップデートログ記事や公式ページを読み、重要そうだなと思ったものを分類して列挙しています
- これを全てやればOKってわけではないのでご了承ください
Aurora2系(MySQL5.7)→ Aurora3系(MySQL8.0)の主だった変更点
追加機能・改善されたもの
ここでは追加機能や改善された機能を紹介します。MySQL8.0を十分に使いこなすためのtipsとしてお読みください。
window関数
集計や分析でめっちゃ重宝するWindow関数がついにMySQLでも使えるようになりました。簡単に概要を説明すると、レコード群に順序をつけて、上から順番に処理させることができるようなものです。その処理において、対象とする行の前後を使った処理を記述できるため、例えば前日からの売り上げ推移などを簡単に表現できます。
さらに詳しい解説・使い方は下記の記事などを参照してください。
共通テーブル式(CTE)
SQLを切り貼りして再利用するのに役立つ機能です。みんな欲しかったやつですね。
こちらも使い方はgihyoさんの記事にお譲りします。
SQLの共通テーブル式(CTE)を使ってみよう - gihyo.jp
AUTO_INCREMENTが安全に
MySQL8.0より前のバージョンでは、AUTO_INCREMENTがうまく動作しない問題がありました。これが8.0を機についに解消しています。
MySQL 8.0でInnoDBのAUTO_INCREMENT問題解消を確認してみる - Qiita
JSON関数
いくつかの便利なJSON関数が導入されています。以下の記事等を参照してください。
MySQL8.0 : 新しく追加されたJSON関数サンプル - Database JUNKY
新しい種類のインデックス(不可視、降順、関数)
インデックスもいろんな種類が増えました。
-
8.3.12 不可視のインデックス - MySQL8.0リファレンスマニュアル
- 「不可視のインデックスを使用すると、インデックスが必要になった場合に元に戻す必要がある破壊的な変更を行わずに、クエリーのパフォーマンスに対するインデックスの削除の影響をテストできます。」
- インデックス自体は存在するので、削除した時どうなるのかを試せる
- 消すのが怖いからでこれ使ってると使ってないインデックスでメモリを圧迫しそうなのでそこは気をつけた方がいいかも。あくまでテスト用
- こちらも参照
-
8.3.13 降順インデックス - MySQL8.0リファレンスマニュアル
- これまで昇順インデックスを逆にスキャンしていたのが、降順インデックスで素直にスキャンできるようになったとのこと。あと複合インデックスに個別に昇順降順指定できるのがデカそう。
-
13.1.15 CREATE INDEX ステートメント - MySQL8.0リファレンスマニュアル(関数インデックス)
- 関数インデックスとは
- これまではカラムそのものに対してインデックスを貼っていたが、カラムを加工した値に対してもインデックスを貼れるようになった
- これまでインデックスを利用できなかった
WHERE col1 * 10 > 100
みたいな書き方もできるようになる - ただその分メモリは多く使うから、関数インデックスを回避できる場面は回避するのが良さそう
- 関数インデックスとは
SELECT ... FOR SHARE
文のNOWAIT
と SKIP LOCKED
句
「他のトランザクションによる行ロックの解放を待機しないように、
SELECT ... FOR UPDATE
またはSELECT ... FOR SHARE
のロック読取りステートメントでNOWAIT
およびSKIP LOCKED
オプションを使用できます。」
NOWAIT および SKIP LOCKED による読取り同時実行性のロック - MySQL8.0リファレンスマニュアル
とのこと。開発するアプリの要件次第ではだいぶ便利そう。
HASH JOIN
MySQL8.0.18からHASH JOINが使えます。いろんな技術書に「MySQLはNested Loop Joinしか使えない」って書いてあるんですが、ついにHASH JOINも使えるようになりました。
HASH JOINがNLJより有効な手となるのは「外部表(メインのTBL)が大きい場合、または内部表(メインのTBLに結合されるTBL)の対象件数が多い場合」と「結合条件の索引がなく、テーブルのフルスキャンが必要な場合」です。(『失敗から学ぶRDBの正しい歩き方』p33より引用)
ただし、ヒントなどで明示的に使用する方法は8.0.18のみで廃止されています。使われることがあるんだなあと思っておければ良いでしょう。
不具合やパフォーマンス問題を引き起こすもの
ここではこれまでとは使い方が異なっていたり廃止になったりして、放置しておくと問題になるものを紹介します。
collation問題
「文字コードとして utf8mb4 を使っている場合の照合順序のデフォルト値が utf8mb4_general_ci から utf8mb4_0900_ai_ci に変更されました。」
MySQL 8.0 への移行が完了しました ~さようなら全ての MySQL 5.7~ - Cybouzu Inside Out
collationについては以下の記事が詳しかったです。
MySQLのcollationの動作を体系的に理解する - shallowな暮らし
COUNT(*)が失速する
COUNT対象データがメモリ容量を超えると、COUNT(*)
が重たくなります。
本来はメモリに乗り切らなくなった際、使っていない領域を解放して対応するんですが、それさえできないらしいです。ちゃんと理解できてないのでこれ以上書かないですが、参考になりそうな記事を以下に紹介しておきます。
- MySQL 8.0.14でSELECT COUNT(*)が加速する!- 「innodb_parallel_read_threads」検証その1 - なからなLife
- MySQL 8.0 で SELECT COUNT(*) が失速する - Zenn
データソート時のメモリ不足
データソートのやり方が変わったことでメモリ不足のエラーが発生した、という報告があります。
以下の記事の「新しい方式」で説明されている方式が8.0から正式に採用されたため起きているようです。なお、インデックス貼れば解決します。
MySQLのソート処理について - gihyo.jp
外部キーを設定すると親テーブルへのメタデータロックをとる(ロック状態でALTERなどが失敗する)
yoku0825さんの記事で紹介されてますが、「外部キー制約を持っているテーブルにSELECTするとそのテーブルの親テーブルにもメタデータロック(MDL)を置くようになった」ため、親テーブルに対してALTER TABLEするとロック待ちになるそうです。
MySQL 8.0 vs 外部キー制約 vs ALTER TABLEでメタデータロック待ちになったら疑うこと - 日々の覚書
使えなくなった機能や変数
簡単に紹介します。
- GROUP BY a ASC
- これまで「GROUP BY col ASC」と書けばソートできていたものができなくなりました
- ちゃんと「ORDER BY col ASC」も書きましょう
- SQL_CALC_FOUND_ROWS と FOUND_ROWS()
- LIMITしない全件の件数を取れる関数が廃止になりました
- count(*)で対応なんですが、これやると重くなる問題もあるのでうーんという感じ
- NO_AUTO_CREATE_USERというSQLモード
- Laravel5.5ではこれが原因でエラーとなるので注意。修正パッチが出ています。
- 参考:All Aboutの基幹DBのMySQLバージョンを5.7から8.0に上げた話 - オールアバウトTech Blog
- infomation_schemaのいくつかのカラムが廃止され、performance_schemaに
- 同じような立ち位置の別のカラムになりました。監視などで使っている場合は修正が必要
おわりに
今回はAurora3系でのMySQLの変更点をまとめてみました。これで全てではないですが、Aurora3系を使い始めている皆さんのお役に立てれば幸いです。あと指摘事項等ありましたらぜひコメントください!!!!
参考にしたWeb上の記事
- AWS公式
- MySQL公式
- MySQL8.0の変更点, MySQL公式
- All about社の記事
- サイボウズのMySQL8.0移行記録
- SmartBankのAurora MySQL8.0移行記録
- その他たくさん
Discussion