mysqldump 适用于较旧的 mysql 版本,从 mysql 8 到 mysql 5.7

标签 mysql mysql-8.0

如果我使用 mysql dump 工具备份旧版本的 MySql 数据库,是否存在任何已知风险?例如,如果我在生产机器上使用 mysql dump 8 来备份 MySql 5.7 数据库。

最佳答案

不知道为什么没有人回答这个有效的问题。让我们解决这个问题。

首先,免责声明:最佳实践始终是使用与 MySQL 数据库相同版本的 mysqldump。即使小版本有差异,仍然建议使用相同版本。话虽如此,让我们深入探讨一下问题。

总的来说,简短的答案是:这取决于情况。现在,长版本。有两个问题。首先,mysqldump 在转储数据时收集一些附加信息。例如,我们测试的最新版本的 Percona Server for MySQL 8.0 (8.0.30) 执行以下查询:

SELECT COLUMN_NAME, JSON_EXTRACT(HISTOGRAM, '$."number-of-buckets-specified"') FROM information_schema.COLUMN_STATISTICS WHERE SCHEMA_NAME = 'mysql' AND TABLE_NAME = 'columns_priv';

显然,这在 MySQL 5.7 上不起作用,因为 information_schema 数据库中没有这样的表。这并不意味着旧版本的 mysqldump 无法工作。也许你很幸运,你的 mysqldump 没有使用这样的查询?另一个潜在的问题是 mysqldump 向转储文件引入了一些命令:

-- MySQL dump 10.13  Distrib 8.0.30-22, for Linux (x86_64)
--
-- Host: localhost    Database:
-- ------------------------------------------------------
-- Server version       8.0.30-22

/*!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' */;
/*!50606 SET @OLD_INNODB_STATS_AUTO_RECALC=@@INNODB_STATS_AUTO_RECALC */;
/*!50606 SET GLOBAL INNODB_STATS_AUTO_RECALC=OFF */;
/*!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 */;
/*!50717 SELECT COUNT(*) INTO @rocksdb_has_p_s_session_variables FROM INFORMATION_SCHEMA.TABLES WHERE TABLE_SCHEMA = 'performance_schema' AND TABLE_NAME = 'session_variables' */;
/*!50717 SET @rocksdb_get_is_supported = IF (@rocksdb_has_p_s_session_variables, 'SELECT COUNT(*) INTO @rocksdb_is_supported FROM performance_schema.session_variables WHERE VARIABLE_NAME=\'rocksdb_bulk_load\'', 'SELECT 0') */;
/*!50717 PREPARE s FROM @rocksdb_get_is_supported */;
/*!50717 EXECUTE s */;
/*!50717 DEALLOCATE PREPARE s */;
/*!50717 SET @rocksdb_enable_bulk_load = IF (@rocksdb_is_supported, 'SET SESSION rocksdb_bulk_load = 1', 'SET @rocksdb_dummy_bulk_load = 0') */;
/*!50717 PREPARE s FROM @rocksdb_enable_bulk_load */;
/*!50717 EXECUTE s */;
/*!50717 DEALLOCATE PREPARE s */;
SET @MYSQLDUMP_TEMP_LOG_BIN = @@SESSION.SQL_LOG_BIN;
SET @@SESSION.SQL_LOG_BIN= 0;

--
-- GTID state at the beginning of the backup
-- (origin: Binlog_snapshot_gtid_executed)
--

SET @@GLOBAL.GTID_PURGED=/*!80000 '+'*/ '5339ac74-6ccb-11ed-9c89-080027a26bfd:1-6';

--
-- Position to start replication or point-in-time recovery from
--

它们在注释中标记为支持它们的 MySQL 版本,因此从理论上讲,这应该是后台兼容的。不过,其中一些内容没有被注释,具体取决于您用来执行 mysqlbinlog 的标志。

在上面的示例中,您可以看到 GTID_PURGED 全局变量已设置。在未使用 GTID 的数据库上执行 mysqldump 可能会出现问题。正如你所看到的,很难明确地回答这个问题 - 8.0 myqldump 用在 5.7 上?可能不会。 5.7 对 5.6?不确定,也许这会起作用。一般来说,正如一开始提到的,最佳实践是全面使用相同的版本。

关于mysqldump 适用于较旧的 mysql 版本,从 mysql 8 到 mysql 5.7,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/56491930/

相关文章:

mysql - 如何有效地仅在WITH RECURSIVE语句中保留最新行?

php - 如何使用 mysql 8 docker 测试 laravel 5.6

MySQL5.7组复制问题?

php - laravel mysql 8连接超时

mysql - 在 DB-Fiddle (MySQL 8.0) 中使用定界符

统计记录的 SQL 查询

mysql - 如何使用 MySQL 8 在 JSON 数组上创建索引

php - 登录后不重定向到下一页

mysql - 两种类型的数据,那么两种类型的数据库?

mysql开关大小写