MySql 8.0.24:转储/恢复失败,嵌套视图在 DISTINCT 组上具有 ROLLUP

Posted

技术标签:

【中文标题】MySql 8.0.24:转储/恢复失败,嵌套视图在 DISTINCT 组上具有 ROLLUP【英文标题】:MySql 8.0.24: Dump/Restore fails with nested VIEWS having ROLLUP over DISTINCT groups 【发布时间】:2021-05-04 16:57:23 【问题描述】:

问题

假设以下 2 个视图

CREATE VIEW v2 AS SELECT 4711 AS XYZ;
CREATE VIEW v1 AS
  SELECT  
    1                   AS A  
   ,COUNT(DISTINCT (1)) AS B
FROM v2
  GROUP BY A WITH ROLLUP;

转储,恢复转储文件并调用 SHOW CREATE VIEW v1; 导致以下错误:

FAILS with ERROR 1064 (42000) at line 1: You have an error in your SQL syntax; check the manual that corresponds to your mysql server version for the right syntax to use near 'distinct count(distinct 4711)) AS `B` from `dbfail`.`v2` group by `A` with rollu' at line 1

据我了解,转储文件看起来不错。我假设导入/恢复无法处理它。

当然,上面的例子在商业上没有意义。它已简化为我们面临的问题的本质!

效果很好

在 8.0.18 中 没有 ROLLUP 修饰符 或没有 DISTINCT 计数 或者当 v2 是一个表时 或者令人惊讶的是,实际上是这篇文章的原因...... 失败取决于视图的名称。 更准确地说,是它们在转储文件中的出现! 如果我们切换视图的名称 v1v2 它的OK

如何重复

我在 macOS Catalina 上使用 MySql 8.0.24。

这是在终端(在 Mac 上)测试事实的便捷方法。 (随意打包成脚本)

第一部分是正常的,第二部分由于切换视图名称而失败。

SCHEMA=dbok
INNERVIEWNAME=v1
OUTERVIEWNAME=v2
mysql -e "DROP DATABASE IF EXISTS $SCHEMA; \
          CREATE DATABASE $SCHEMA; \
          USE $SCHEMA; \
          CREATE VIEW $INNERVIEWNAME AS SELECT 4711 AS anything; \
          CREATE VIEW $OUTERVIEWNAME AS SELECT 4711 AS A, COUNT(DISTINCT(4711)) AS B FROM $INNERVIEWNAME GROUP BY A WITH ROLLUP; \
          SHOW CREATE VIEW $OUTERVIEWNAME;"
rm -rf ./$SCHEMA.mysql
mysqldump $SCHEMA > ./$SCHEMA.mysql
mysql $SCHEMA < ./$SCHEMA.mysql
mysql -e "USE $SCHEMA; SHOW CREATE VIEW $OUTERVIEWNAME;"
SCHEMA=dbfail
INNERVIEWNAME=v2
OUTERVIEWNAME=v1
mysql -e "DROP DATABASE IF EXISTS $SCHEMA; \
          CREATE DATABASE $SCHEMA; \
          USE $SCHEMA; \
          CREATE VIEW $INNERVIEWNAME AS SELECT 4711 AS anything; \
          CREATE VIEW $OUTERVIEWNAME AS SELECT 4711 AS A, COUNT(DISTINCT(4711)) AS B FROM $INNERVIEWNAME GROUP BY A WITH ROLLUP; \
          SHOW CREATE VIEW $OUTERVIEWNAME;"
rm -rf ./$SCHEMA.mysql
mysqldump $SCHEMA > ./$SCHEMA.mysql
mysql $SCHEMA < ./$SCHEMA.mysql
mysql -e "USE $SCHEMA; SHOW CREATE VIEW $OUTERVIEWNAME;"

我该如何克服这个问题?

当然,除了重命名!。其他人也面临这个问题吗?是否有适当的解决方案(例如转储恢复参数)?我还没有找到关于这个问题的任何评论...

【问题讨论】:

如果可以重复,请提交错误报告 听从您的建议,谢谢! link 到 MySql 错误报告 【参考方案1】:

在 mysql 8.0.23 中,mysqldump 如下所示,我在其中看不到正确的 CREATE VIEW 语句。

也许您发现了一个错误,应该将其报告给:https://bugs.mysql.com/?

编辑:哎呀,我一直认为哪里有(很多)cmets,但是:WHOA! These aren't really comments even though they look that way. They are conditional-execution tokens.

-- MySQL dump 10.13  Distrib 8.0.23, for Win64 (x86_64)
--
-- Host: localhost    Database: test
-- ------------------------------------------------------
-- Server version   8.0.23

/*!40101 SET @OLD_CHARACTER_SET_CLIENT=@@CHARACTER_SET_CLIENT */;
/*!40101 SET @OLD_CHARACTER_SET_RESULTS=@@CHARACTER_SET_RESULTS */;
/*!40101 SET @OLD_COLLATION_CONNECTION=@@COLLATION_CONNECTION */;
/*!50503 SET NAMES utf8mb4 */;
/*!40103 SET @OLD_TIME_ZONE=@@TIME_ZONE */;
/*!40103 SET TIME_ZONE='+00:00' */;
/*!40014 SET @OLD_UNIQUE_CHECKS=@@UNIQUE_CHECKS, UNIQUE_CHECKS=0 */;
/*!40014 SET @OLD_FOREIGN_KEY_CHECKS=@@FOREIGN_KEY_CHECKS, FOREIGN_KEY_CHECKS=0 */;
/*!40101 SET @OLD_SQL_MODE=@@SQL_MODE, SQL_MODE='NO_AUTO_VALUE_ON_ZERO' */;
/*!40111 SET @OLD_SQL_NOTES=@@SQL_NOTES, SQL_NOTES=0 */;

--
-- Temporary view structure for view `v1`
--

DROP TABLE IF EXISTS `v1`;
/*!50001 DROP VIEW IF EXISTS `v1`*/;
SET @saved_cs_client     = @@character_set_client;
/*!50503 SET character_set_client = utf8mb4 */;
/*!50001 CREATE VIEW `v1` AS SELECT 
 1 AS `A`,
 1 AS `B`*/;
SET character_set_client = @saved_cs_client;

--
-- Final view structure for view `v1`
--

/*!50001 DROP VIEW IF EXISTS `v1`*/;
/*!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      = cp850 */;
/*!50001 SET character_set_results     = cp850 */;
/*!50001 SET collation_connection      = cp850_general_ci */;
/*!50001 CREATE ALGORITHM=UNDEFINED */
/*!50013 DEFINER=`luuk`@`%` SQL SECURITY DEFINER */
/*!50001 VIEW `v1` AS select rollup_group_item(1,0) AS `A`,rollup_sum_switcher(distinct count(distinct 1)) AS `B` from `v2` group by `A` with rollup */;
/*!50001 SET character_set_client      = @saved_cs_client */;
/*!50001 SET character_set_results     = @saved_cs_results */;
/*!50001 SET collation_connection      = @saved_col_connection */;
/*!40103 SET TIME_ZONE=@OLD_TIME_ZONE */;

/*!40101 SET SQL_MODE=@OLD_SQL_MODE */;
/*!40014 SET FOREIGN_KEY_CHECKS=@OLD_FOREIGN_KEY_CHECKS */;
/*!40014 SET UNIQUE_CHECKS=@OLD_UNIQUE_CHECKS */;
/*!40101 SET CHARACTER_SET_CLIENT=@OLD_CHARACTER_SET_CLIENT */;
/*!40101 SET CHARACTER_SET_RESULTS=@OLD_CHARACTER_SET_RESULTS */;
/*!40101 SET COLLATION_CONNECTION=@OLD_COLLATION_CONNECTION */;
/*!40111 SET SQL_NOTES=@OLD_SQL_NOTES */;

-- Dump completed on 2021-05-04 19:37:14

【讨论】:

【参考方案2】:

问题已在 8.0.26 中修复。见MySQL Bug #103583

【讨论】:

经过测试:确实,上述方案适用于 macOS Catalina (10.15.7) 上的 MySQL 8.0.26 安装。

以上是关于MySql 8.0.24:转储/恢复失败,嵌套视图在 DISTINCT 组上具有 ROLLUP的主要内容,如果未能解决你的问题,请参考以下文章

使用命令行恢复 MYSQL 转储文件

使用命令行恢复 MYSQL 转储文件

使用命令行恢复 MYSQL 转储文件

使用命令行恢复 MYSQL 转储文件

MySQL:如何在忽略几个数据库的情况下恢复转储

如何将 MySQL 转储从主机恢复到 Docker 容器