エラーメッセージ
mysqldump
コマンドでMySQL上のデータのバックアップを取ろうとしたとき、下記のようなエラーが出た。
mysqldump: Couldn't execute 'SELECT COLUMN_NAME, JSON_EXTRACT(HISTOGRAM, '$."number-of-buckets-specified"') FROM information_schema.COLUMN_STATISTICS WHERE SCHEMA_NAME = '$db_name' AND TABLE_NAME = '$table_name';': Unknown table 'COLUMN_STATISTICS' in information_schema (1109)
原因
MySQL 8以降に付属するmysqldumpでそれ以前のMySQL 5.7とかのサーバに対してダンプを実行したらこの問題が起こるらしい。
MySQL 8以降ではオプティマイザがヒストグラム統計というものを考慮するようになったため、mysqldumpもdumpをloadする際にヒストグラム統計をリセットさせる目的でANALYZE TABLE文を自動生成しようとする。そのときinformation_schema.COLUMN_STATISTICSを参照するが、そのテーブルがあるのはMySQL 8.0以降なのでそれ以前のバージョンのMySQLだと怒られが発生する、という具合のようだ。
対策
この問題はmysqldumpコマンドに --skip-column-statistics
というオプションを設定して、ANALYZE TABLE文の自動生成をやめさせることで回避できる。
$ mysqldump --version mysqldump Ver 8.0.16 for osx10.14 on x86_64 (Homebrew) $ mysqldump --help ... --column-statistics Add an ANALYZE TABLE statement to regenerate any existing column statistics. (Defaults to on; use --skip-column-statistics to disable.) ...
このように、先のオプションをつけたら確かにエラーが出なくなった 。
$ mysqldump --skip-column-statistics --host ...
先の対策の副作用
dumpのloadした際にヒストグラム統計を更新しない副作用としては、dumpをloadした先がMySQL 5.7以下なら特に無く、MySQL 8.0以降なら分析系のクエリでオプティマイザの判断が少し狂うかもしれない、ということらしい (日本男児さんブログからの受け売り)。
テーブル統計情報のヒストグラム MySQL 8.0では、オプティマイザがテーブル統計情報のヒストグラムを活用できるようになった。WHERE句の条件にマッチする行が、テーブルスキャンによってどの程度に絞り込まれるかということを見積もることによって、敢えてスキャンを選ぶべきかどうかが分かる。リアルタイム性が高い処理ではインデックスをバッチリ使用するように最適化することが多いのでヒストグラムの出番は無いだろうが、分析系の処理では重宝することもあるだろう。