mysqldが起動できないバグなのか、「 avoid_temporal_upgrade なんてことすると将来的にサポート対象外だよ」がドキュメントに記載されてないのかどっちだか迷っている。
MySQL Bugs: #93101: Failed to Populate DD tables when table has OLD-Style DATETIME column (need Doc)
MySQL 5.6からDATETIME型のデータ構造が新しくなった。
MySQL 5.5とそれ以前で
CREATE TABLE
したテーブルは8バイトの旧DATETIME型、MySQL 5.6とそれ以降で CREATE TABLE
したテーブルは5バイトの新DATETIME型で、SQL上の扱いには互換性があり、これらを区別することはあんまりできない(切り替えるオプションもない)CREATE TABLE
した時のバージョンで決まるので、 mysqldump
を取ってリストアした時はリストアした時のバージョンのDATETIME型を使う。MySQL 5.5で
CREATE TABLE
しても、ダンプを取って5.6にリストアすると5.6の中で CREATE TABLE
されるので、リストア後のデータは新DATETIME型になる。なので、表題のようなことは「MySQL 5.5またはそれ以前からインプレースアップグレードのみで8.0に到達しようとしているインスタンス」でしか起こらない。
更に、MySQL 5.7の
mysql_upgrade
の中では、旧DATETIME型を新DATETIME型に書き換える処理が入っているので、これを素直にやっている場合も表題のケースには到達しない。
MySQL 5.7にインプレースアップグレードした時、
mysql_upgrade
でこの新旧DATETIMEの変換処理をスキップさせている場合にタイトルのケースに引っ掛かる。
思い付く限りでは、
mysql_upgrade --upgrade-system-tables
( mysql
, performance_schema
, sys
あたりのみアップグレードし、ユーザーが作ったテーブルには触らない)もしくは mysqld
の avoid_temporal_upgrade オプションを有効にしている場合、くらいか。
エラーログに大した情報もなくいきなり「データディクショナリー(= DD)への引っ越しに失敗した。大佐、中断する( ー
дー´)」と言われてmysqldが起動しないので、
Table upgrade required. Please do “REPAIR TABLE ..” or dump/reload to fix it!` もへったくれもないのである。2018-11-06T07:58:54.851647Z 0 [System] [MY-010116] [Server] /usr/mysql/8.0.13/bin/mysqld (mysqld 8.0.13) starting as process 1585
2018-11-06T07:58:58.491844Z 2 [ERROR] [MY-010923] [Server] Table upgrade required. Please do "REPAIR TABLE `t1`" or dump/reload to fix it!
2018-11-06T07:58:59.067735Z 2 [Warning] [MY-010772] [Server] db.opt file not found for test database. Using default Character set.
2018-11-06T07:58:59.424516Z 0 [ERROR] [MY-010022] [Server] Failed to Populate DD tables.
2018-11-06T07:58:59.424562Z 0 [ERROR] [MY-010119] [Server] Aborting
2018-11-06T07:59:00.712682Z 0 [System] [MY-010910] [Server] /usr/mysql/8.0.13/bin/mysqld: Shutdown complete (mysqld 8.0.13) Source distribution.
mysqld
には —no-dd-upgrade なんていう如何にもこれを回避できそうなオプションがあるんだけど、これは「データディクショナリーのアップグレード後に、必要なら再起動を行うのがデフォルトだけどそれをしない」ためのオプションらしく、これを加えてもやっぱり同じエラーで止まった。
なのでワークアラウンドは5.7で起動しなおして、
ALTER TABLE .. FORCE
で新旧DATETIME型の返還を走らせるなり mysqldump
とリストアの手順で8.0にアップグレードするなり…といったところか。
ちなみに、MySQL 5.7にアップグレードしていないdatadirをそのままインプレースアップグレードで8.0にしようとすると、「5.7じゃないよ!」というエラーで落ちるのでこっちはわかりやすい。
旧DATETIME型のカラムがあるかどうかはMySQL ShellのUpgrade Checkerを使えばちゃんと検出できるので、良い子はちゃんとこれを使ってからバージョンアップしよう。
0 件のコメント :
コメントを投稿