🌃

AWS Aurora3系を使うときに気にしたい変更点まとめ

2024/03/24に公開

これはなに

ども、レバテック開発部のもりたです。

Aurora MySQLの2系が2024年10月31日にサポート終了となります。これに向けてどこもかしこも Aurora3系に移行していると思うので、Aurora2系(MySQL5.7)→ Aurora3系(MySQL8.0)の主だった変更点をまとめてみました。

前提と意図

Aurora2系(MySQL5.7)→ Aurora3系(MySQL8.0)の主だった変更点

追加機能・改善されたもの

ここでは追加機能や改善された機能を紹介します。MySQL8.0を十分に使いこなすためのtipsとしてお読みください。

window関数

集計や分析でめっちゃ重宝するWindow関数がついにMySQLでも使えるようになりました。簡単に概要を説明すると、レコード群に順序をつけて、上から順番に処理させることができるようなものです。その処理において、対象とする行の前後を使った処理を記述できるため、例えば前日からの売り上げ推移などを簡単に表現できます。
さらに詳しい解説・使い方は下記の記事などを参照してください。

WINDOW関数を使ってみる - gihyo.jp

共通テーブル式(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(*)が重たくなります。
本来はメモリに乗り切らなくなった際、使っていない領域を解放して対応するんですが、それさえできないらしいです。ちゃんと理解できてないのでこれ以上書かないですが、参考になりそうな記事を以下に紹介しておきます。

データソート時のメモリ不足

データソートのやり方が変わったことでメモリ不足のエラーが発生した、という報告があります。
以下の記事の「新しい方式」で説明されている方式が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モード
  • infomation_schemaのいくつかのカラムが廃止され、performance_schemaに
    • 同じような立ち位置の別のカラムになりました。監視などで使っている場合は修正が必要

おわりに

今回はAurora3系でのMySQLの変更点をまとめてみました。これで全てではないですが、Aurora3系を使い始めている皆さんのお役に立てれば幸いです。あと指摘事項等ありましたらぜひコメントください!!!!

参考にしたWeb上の記事

記事作成のログ

Aurora3系アプデでなにが変わったか記事のログ - Zenn

レバテック開発部

Discussion