0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

mysqlをレストアしたときにViewの中身が空だったときに疑うこと

Last updated at Posted at 2025-02-05

結論

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 がおすすめのようです。また今度取り組んでみます。

0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?