Amazon Aurora MySQL v1(5.6 互換)→ v3(8.0 互換)移行を計画する(7)パラメータ・コード確認
これは
の続きです。
詳細調査結果を実際のパラメータグループやアプリケーション・コード(SQL 文)などと突き合わせて確認してみます。
パラメータグループの検討
こちらと実際に使用しているパラメータグループ(クラスタと DB)を比較して、対応が必要な点を見付けます。
私が関わっているサービスでは、以下の点が出てきました。
innodb_strict_mode
のデフォルトが 厳密モード に
これは正確には Aurora MySQL v2(MySQL 5.7)の時点でデフォルトが変わっています。
一部の SQL 文の実行で、従来は警告(Warning)で済ませていたのをエラーで止める動作に変わりました。ほぼ問題にならない見込みですが、念のため従来の設定に合わせて厳密モードを OFF にします。
innodb_autoinc_lock_mode
のデフォルトが1
から2
に
AUTO_INCREMENT
値 生成時のロックモードです。
2
のほうが性能上有利なのですが、私が関わっているサービスでは、MySQL Connector/J の rewriteBatchedStatements
オプション を使ったバッチINSERT
と LAST_INSERT_ID() を組み合わせた処理を行っている部分があったので、動作の問題が生じる可能性を考えて従来と同じ1
に戻します。
一方、以下の点については特に問題にならないことがわかりました。
tx_isolation
がtransaction-isolation
に変わった
これはパラメータグループというよりも、アプリケーションから DB に接続する部分の実装やライブラリのオプション設定に関わる問題ですが、以前触れた サイボウズのブログ記事 ではこの変更の影響を受けていました。
私が関わっているサービスではこのパラメータをアプリケーションから変更していないので、対応は不要です。
アプリケーション・コードとテーブル定義の検討
ライブラリ
DB 接続用のライブラリ(MySQL Connector/J など)を MySQL 8.0 対応バージョンに変更します。
その際、TLS 接続(TLS バージョンが合わない、非 SSL では接続できない等)の問題が生じる可能性がある点を留意しておきます。
TLS 接続の場合
TLS バージョンの問題が生じる可能性があります(Aurora MySQL 移行より前に新しいバージョンのライブラリに更新する場合)。
非 TLS 接続の場合
ライブラリのバージョンによっては、接続パラメータにsslMode=DISABLED
が必要になる場合があります。
その他
パラメータグループでデフォルトどおりexplicit_defaults_for_timestamp
に1
(有効)を指定した状態で、
- MySQL Connector/J のプリペアドステートメントを使って
-
NOT NULL
かつDEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP
のTIMESTAMP
・DATETIME
列に対して -
null
でUPDATE
したとき
の挙動が、
- Aurora MySQL v1・MySQL Connector/J 5.1 の組み合わせ:
UPDATE
時のタイムスタンプで更新 - Aurora MySQL v3・MySQL Connector/J 8.0 の組み合わせ:「
NOT NULL
列にnull
でUPDATE
することはできない」旨のエラーが発生
のように変化するケースがあります。
同様の事象が発生した場合はnull
ではなくNOW()
などでUPDATE
する形に SQL 文(プリペアドステートメント)を書き換えます。
また、Connector/J 8.0.29 でrewriteBatchedStatements=true
のときにROW_COUNT()
の結果が不正な事象も見つかっています(8.0.28 に戻して回避)。
SQL 文とテーブル定義
こちらもいくつか検討事項が出てきましたが、結局、事前改修の対象は予約語とのバッティング箇所だけになりそうです。
予約語
既存コードではOF
とRANK
のバッティングが確認されました。この結果をふまえて、今回は一旦以下の対応とします。
- 既存コードについてはバッティング箇所のみ直す(「`」で括る)
- 新規コードについてはバッティングの有無に関わらずデータベース(スキーマ)名・テーブル名・カラム名・インデックス名やエイリアスを「`」で括る
-
.
で連結する形式で書かれている箇所は必ずしも「`」で括る必要がないが、ミス防止のため全て「`」で括る
-
ビルトイン関数
サイボウズのブログ記事 にもあった、FOUND_ROWS()
(およびSQL_CALC_FOUND_ROWS
)が見つかりました。
こちらはページャ機能の実装で使っていますが、
- 先に改修してから Aurora MySQL v3 に移行すると、Aurora MySQL v1 運用中の性能低下の恐れがあること
- 今後ページャ機能からスクロールなど別の UI に切り替える検討を進めていること
などから、移行前の改修は見送ることにします。
文字セット・照合順序
一部utf8
(utf8mb3
のエイリアス)が残っていますが、現時点ではまだ「非推奨」なので、都合上今回の移行とは別のタイミングで対応します。
データ型
DOUBLE(M,D)
がありました。こちらも現時点では「非推奨」であり、一旦別タイミングでの対応とします。
その他 SQL ステートメントなど
サイボウズのブログ記事 にもあったGROUP BY 【列名】 ASC/DESC
ですが、 暗黙の昇順ソート (ASC
が省略されているもの)が比較的多数見つかりました。
これは見逃しやすいので注意が必要です。
実際に動かしてみないとわからないものもある
ここまでは調査資料から判別できましたが、一部、それが難しい項目もあります。
RIGHT JOIN
の修正(MySQL 8.0.22)
MySQL 8.0.22 のリリースノートの Optimizer Notes に、
When using a RIGHT JOIN, some internal objects, were not converted to those suitable for use with a LEFT JOIN as intended. These included some lists of tables built at parse time, but which did not have their order reversed. This required maintaining code to handle instances in which a LEFT JOIN was originally a RIGHT JOIN as special cases, and was the source of several bugs. Now the server performs any necessary reversals at parse time, so that after parsing, a RIGHT JOIN is in fact, in all respects, a LEFT JOIN. (Bug #30887665, Bug #30964002)
References: See also: Bug #12567331, Bug #21350125.
という項目があります。RIGHT JOIN
実行時、内部的にLEFT JOIN
に書き換える処理に不適切な部分があったのを改修したという趣旨ですが、これらのバグトラッキング番号の情報がクローズされてしまい内容が読めないので、こちらは実際に動作を確認してみる必要がありそうです。
UNION
の構文解析と動作の変更(MySQL 8.0.19 など)
マニュアルの UNION 句のページ中、
ここから下の各項目については内容を読む限りでは問題はなさそうですが、カッコの記述などが動作に影響する可能性があるため、念のため実際の動作確認の際に変化が生じないか気を付ける必要がありそうです。
に続きます。
Discussion