結論
mysqldump
時に information_schema を含めていませんか?
information_schema を mysqldump
することはできず、そのとき View の実体は dump されません
背景
前提として mysqldump
を実行して sql を出力するとviewを作成する部分は2段階でつくられます。
最初は全データ1のViewが次のように作成されます。
(注 /*!50503
とかは拡張コメントで MySQL 5.5.3以降でのみ読み込まれるという意味です)
DROP TABLE IF EXISTS `sample_view`;
/*!50001 DROP VIEW IF EXISTS `sample_view`*/;
SET @saved_cs_client = @@character_set_client;
/*!50503 SET character_set_client = utf8mb4 */;
/*!50001 CREATE VIEW `sample_view` AS SELECT
1 AS `product_id`,
1 AS `col1`,
1 AS `col2`*/;
SET character_set_client = @saved_cs_client;
ついで、あいだに別のテーブルの出力があってから View の実体が出力されます。
-- Final view structure for view `sample_view`
--
/*!50001 DROP VIEW IF EXISTS `sample_view`*/;
/*!50001 SET @saved_cs_client = @@character_set_client */;
/*!50001 SET @saved_cs_results = @@character_set_results */;
/*!50001 SET @saved_col_connection = @@collation_connection */;
/*!50001 SET character_set_client = utf8mb4 */;
/*!50001 SET character_set_results = utf8mb4 */;
/*!50001 SET collation_connection = utf8mb4_general_ci */;
/*!50001 CREATE ALGORITHM=UNDEFINED */
/*!50013 DEFINER=`user`@`%` SQL SECURITY DEFINER */
/*!50001 VIEW `sample_view` AS with `x` as (select `p`.`id` AS `product_id`,~中略~ from `x` */;
/*!50001 SET character_set_client = @saved_cs_client */;
/*!50001 SET character_set_results = @saved_cs_results */;
/*!50001 SET collation_connection = @saved_col_connection */;
ただ、 information_schema
を含んでいるとこの2段階目が出ません。
原因
mysqldump
のコードを読むと、 以下のような箇所があり、はじめに全データベースで dump_all_tables_in_db
してから改めて全データベースで dump_all_views_in_db
しています。
そしてその前に、 is_infoschema_db
なら die
する・・・。
for (db = db_names; *db; db++) {
if (is_infoschema_db(*db))
die(EX_USAGE, "Dumping \'%s\' DB content is not supported", *db);
if (dump_all_tables_in_db(*db)) result = 1;
}
if (!result && seen_views) {
for (db = db_names; *db; db++) {
if (dump_all_views_in_db(*db)) result = 1;
}
}
これはいろいろ条件をかえて dump して取り込む試行錯誤をして、 information_schema
があると変だ、と気づいてから mysql-casual という、感じの良い MySQL 愛好家たちが集まっている Slack にて相談したところ、有識者の yoku0825 さまにご教示いただきました。ありがとうございます!mysqldump のコードをみる発想ありませんでした。
あるいは、次のように、mysqldump
のエラーログをちゃんと出しておくと一発でわかったのですが、これまで mysqldump
で標準エラー出力をする習慣がなかったことが敗因です。これからはちゃんとエラーログとるようにします(あるいはそろそろ mysqlpump
を使っていくか → 追記 mysqlpump は deprecated になりました )。
mysqldump --databases データベース名 information_schema -u root > dump.sql 2> error.log
こうするとこんなログが記録される。
mysqldump: Dumping 'information_schema' DB content is not supported
今回の問題について、ユーザとしては、レプリケーションを開始して show replica status
なども問題ないにもかかわらず、 View が変ということにあとで気付き、また View が欠けているという問題を起点に検索しても原因にたどり着きにくいことと、無料Slackで情報が流れていくことはしのびなく Qiita に投稿いたしました。
追記
mysqlpump
は deprecated に なっていました。
https://dev.mysql.com/doc/refman/8.0/en/mysqlpump.html
mysqlpump is deprecated as of MySQL 8.0.34; expect it to be removed in a future version of MySQL. You can use such MySQL programs as mysqldump and MySQL Shell to perform logical backups, dump databases, and similar tasks instead.
MySQL Shell がおすすめのようです。また今度取り組んでみます。