百度360必应搜狗淘宝本站头条
当前位置:网站首页 > 技术资源 > 正文

关于mysqldump,这个参数你可能还不知道

moboyou 2025-03-06 13:07 16 浏览

前言:

在前面文章中,有提到过 mysqldump 备份文件中记录的时间戳数据都是以 UTC 时区为基础的,在筛选恢复单库或单表时要注意时区差别。后来再次查看文档,发现 tz-utc、skip-tz-utc 参数与此有关,本篇文章我们一起来看下此参数的作用吧。

1.tz-utc与skip-tz-utc参数介绍

这两个参数可以作用于 mysqldump 备份过程中,互为相反参数。顾名思义可以看出,一个参数是将时间戳改为 UTC 时区,另一个是跳过时区变动。

在 mysql 服务器上执行 mysqldump --help 的命令,可以看到下面一段话。

[root@host ~]# mysqldump --help
mysqldump  Ver 10.13 Distrib 5.7.23, for Linux (x86_64)
Copyright (c) 2000, 2018, Oracle and/or its affiliates. All rights reserved.
...省略很多内容
  --tz-utc            SET TIME_ZONE='+00:00' at top of dump to allow dumping of
                      TIMESTAMP data when a server has data in different time
                      zones or data is being moved between servers with
                      different time zones.
                      (Defaults to on; use --skip-tz-utc to disable.)

--tz-utc 参数是 mysqldump 的默认参数,会使得 mysqldump 的导出文件的顶部加上一个设置时区的语句 SET TIME_ZONE='+00:00' ,这个时区是格林威治时间,也就是0时区。这样当导出 timestamp 时间戳字段时,会把在服务器设置的当前时区下显示的 timestamp 时间值转化为在格林威治时间下显示的时间。比如我们数据库采用北京时间东八区,mysqldump 导出的文件当中显示的 timestamp 时间值相对于通过数据库查询显示的时间倒退了8个小时。

知道了 --tz-utc ,那么 --skip-tz-utc 的含义就是当 mysqldump 导出数据时,不使用格林威治时间,而使用当前 mysql 服务器的时区进行导出,这样导出的数据中显示的 timestamp 时间值也和表中查询出来的时间值相同。

2.实验参数具体作用

为了更清楚了解这对参数的作用,下面我们来具体测试下,我们知道 mysqldump 后可以跟 where 条件来备份部分数据,若根据 timestamp 字段来备份部分数据,这对参数是否有影响呢?我们一并来验证下:

先来看下我的环境设置及测试数据:

mysql> select version();
+------------+
| version()  |
+------------+
| 5.7.23-log |
+------------+
1 row in set (0.00 sec)
# 时区采用北京时间东八区
mysql> show variables like 'time_zone'; 
+---------------+--------+
| Variable_name | Value  |
+---------------+--------+
| time_zone     | +08:00 |
+---------------+--------+
1 row in set (0.00 sec)

# 测试表 有datetime字段和timestamp字段 共10条数据 两个时间显示是相同的
mysql> show create table test_tb\G
*************************** 1. row ***************************
       Table: test_tb
Create Table: CREATE TABLE `test_tb` (
  `increment_id` int(11) NOT NULL AUTO_INCREMENT COMMENT '自增主键',
  `stu_id` int(11) NOT NULL COMMENT '学号',
  `stu_name` varchar(20) DEFAULT NULL COMMENT '学生姓名',
  `dt_time` datetime NOT NULL,
  `create_time` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间',
  PRIMARY KEY (`increment_id`)
) ENGINE=InnoDB AUTO_INCREMENT=11 DEFAULT CHARSET=utf8 COMMENT='测试表'
1 row in set (0.00 sec)

mysql> select * from test_tb;
+--------------+--------+----------+---------------------+---------------------+
| increment_id | stu_id | stu_name | dt_time             | create_time         |
+--------------+--------+----------+---------------------+---------------------+
|            1 |   1001 | fgds     | 2020-07-10 09:43:28 | 2020-07-10 09:43:28 |
|            2 |   1002 | fgsw     | 2020-10-10 09:43:28 | 2020-10-10 09:43:28 |
|            3 |   1003 | vffg     | 2020-10-10 02:00:00 | 2020-10-10 02:00:00 |
|            4 |   1004 | wdsd     | 2020-10-31 23:43:28 | 2020-10-31 23:43:28 |
|            5 |   1005 | grdb     | 2020-11-01 00:00:00 | 2020-11-01 00:00:00 |
|            6 |   1006 | sdfv     | 2020-11-01 02:00:00 | 2020-11-01 02:00:00 |
|            7 |   1007 | fgfg     | 2020-11-06 02:00:00 | 2020-11-06 02:00:00 |
|            8 |   1008 | tyth     | 2020-11-10 09:43:28 | 2020-11-10 09:43:28 |
|            9 |   1009 | ewer     | 2020-11-10 09:43:28 | 2020-11-10 09:43:28 |
|           10 |   1010 | erre     | 2020-11-11 15:17:03 | 2020-11-11 15:17:03 |
+--------------+--------+----------+---------------------+---------------------+

mysqldump 默认开启 tz-utc ,先来看下默认情况下的备份结果:

# 为更明显看出结果 我们使用skip-extended-insert来一行行展现数据
# 全库备份
[root@host ~]# mysqldump -uroot -pxxxx  --skip-extended-insert --databases testdb > utc_testdb.sql
mysqldump: [Warning] Using a password on the command line interface can be insecure.
[root@host ~]# more utc_testdb.sql 
-- MySQL dump 10.13  Distrib 5.7.23, for Linux (x86_64)
--
-- Host: localhost    Database: testdb
-- ------------------------------------------------------
-- Server version       5.7.23-log

...省略
/*!40103 SET @OLD_TIME_ZONE=@@TIME_ZONE */;
/*!40103 SET TIME_ZONE='+00:00' */;
# 先保存老时区 然后将此会话时区改为0时区
...省略
--
-- Dumping data for table `test_tb`
--

LOCK TABLES `test_tb` WRITE;
/*!40000 ALTER TABLE `test_tb` DISABLE KEYS */;
INSERT INTO `test_tb` VALUES (1,1001,'fgds','2020-07-10 09:43:28','2020-07-10 01:43:28');
INSERT INTO `test_tb` VALUES (2,1002,'fgsw','2020-10-10 09:43:28','2020-10-10 01:43:28');
INSERT INTO `test_tb` VALUES (3,1003,'vffg','2020-10-10 02:00:00','2020-10-09 18:00:00');
INSERT INTO `test_tb` VALUES (4,1004,'wdsd','2020-10-31 23:43:28','2020-10-31 15:43:28');
INSERT INTO `test_tb` VALUES (5,1005,'grdb','2020-11-01 00:00:00','2020-10-31 16:00:00');
INSERT INTO `test_tb` VALUES (6,1006,'sdfv','2020-11-01 02:00:00','2020-10-31 18:00:00');
INSERT INTO `test_tb` VALUES (7,1007,'fgfg','2020-11-06 02:00:00','2020-11-05 18:00:00');
INSERT INTO `test_tb` VALUES (8,1008,'tyth','2020-11-10 09:43:28','2020-11-10 01:43:28');
INSERT INTO `test_tb` VALUES (9,1009,'ewer','2020-11-10 09:43:28','2020-11-10 01:43:28');
INSERT INTO `test_tb` VALUES (10,1010,'erre','2020-11-11 15:17:03','2020-11-11 07:17:03');
# 可以看出timestamp时间值减去了8小时 而datetime时间值不变
UNLOCK TABLES;
/*!40103 SET TIME_ZONE=@OLD_TIME_ZONE */;
# 再将时区改为原时区
/*!40101 SET SQL_MODE=@OLD_SQL_MODE */;
-- Dump completed on 2020-11-11 15:34:21

# 使用where条件备份单表部分数据 备份11月份以来的数据
# 数据库中查询
mysql> select * from test_tb where create_time >= '2020-11-01 00:00:00';
+--------------+--------+----------+---------------------+---------------------+
| increment_id | stu_id | stu_name | dt_time             | create_time         |
+--------------+--------+----------+---------------------+---------------------+
|            5 |   1005 | grdb     | 2020-11-01 00:00:00 | 2020-11-01 00:00:00 |
|            6 |   1006 | sdfv     | 2020-11-01 02:00:00 | 2020-11-01 02:00:00 |
|            7 |   1007 | fgfg     | 2020-11-06 02:00:00 | 2020-11-06 02:00:00 |
|            8 |   1008 | tyth     | 2020-11-10 09:43:28 | 2020-11-10 09:43:28 |
|            9 |   1009 | ewer     | 2020-11-10 09:43:28 | 2020-11-10 09:43:28 |
|           10 |   1010 | erre     | 2020-11-11 15:17:03 | 2020-11-11 15:17:03 |
+--------------+--------+----------+---------------------+---------------------+
6 rows in set (0.00 sec)
# mysqldump导出
[root@host ~]# mysqldump -uroot -pxxxx  --skip-extended-insert testdb test_tb --where "create_time >= '2020-11-01 00:00:00' " > utc_testdb2.sql
mysqldump: [Warning] Using a password on the command line interface can be insecure.
[root@host ~]# more utc_testdb2.sql 
-- MySQL dump 10.13  Distrib 5.7.23, for Linux (x86_64)
--
-- Host: localhost    Database: testdb
-- ------------------------------------------------------
-- Server version       5.7.23-log
...
/*!40103 SET @OLD_TIME_ZONE=@@TIME_ZONE */;
/*!40103 SET TIME_ZONE='+00:00' */;
...省略
--
-- Dumping data for table `test_tb`
--
-- WHERE:  create_time >= '2020-11-01 00:00:00' 

LOCK TABLES `test_tb` WRITE;
/*!40000 ALTER TABLE `test_tb` DISABLE KEYS */;
INSERT INTO `test_tb` VALUES (7,1007,'fgfg','2020-11-06 02:00:00','2020-11-05 18:00:00');
INSERT INTO `test_tb` VALUES (8,1008,'tyth','2020-11-10 09:43:28','2020-11-10 01:43:28');
INSERT INTO `test_tb` VALUES (9,1009,'ewer','2020-11-10 09:43:28','2020-11-10 01:43:28');
INSERT INTO `test_tb` VALUES (10,1010,'erre','2020-11-11 15:17:03','2020-11-11 07:17:03');
# 发现只导出4条
UNLOCK TABLES;
/*!40103 SET TIME_ZONE=@OLD_TIME_ZONE */;

-- Dump completed on 2020-11-11 15:58:56

建议各位仔细看下上面导出结果,说实话,笔者原来也没做过详细测试,现在看到结果也是稍微有点吃惊的。默认情况下,全备出来的数据是没问题的,虽然将 timestamp 时间值转为0时区显示,但当你导入数据库时还会以你的数据库时区来展示 timestamp 时间。但使用 where 条件导出部分数据时,却出现了数据库中查询得出的结果与dump导出的结果不同的情况,这个时候 mysqldump 只导出了转化成0时区后的时间值符合 where 条件的数据,与直接查询出的结果有出入,这是我原来没注意到的。

再来看下使用 --skip-tz-utc 参数,看下这个参数是否符合我们的预期:

# 使用skip-tz-utc全备
[root@host ~]# mysqldump -uroot -pxxxx  --skip-extended-insert --skip-tz-utc --databases testdb > skiputc_testdb.sql
mysqldump: [Warning] Using a password on the command line interface can be insecure.
[root@host ~]# more skiputc_testdb.sql 
-- MySQL dump 10.13  Distrib 5.7.23, for Linux (x86_64)
--
-- Host: localhost    Database: testdb
-- ------------------------------------------------------
-- Server version       5.7.23-log
..省略 未见时区更改语句
--
-- Dumping data for table `test_tb`
--

LOCK TABLES `test_tb` WRITE;
/*!40000 ALTER TABLE `test_tb` DISABLE KEYS */;
INSERT INTO `test_tb` VALUES (1,1001,'fgds','2020-07-10 09:43:28','2020-07-10 09:43:28');
INSERT INTO `test_tb` VALUES (2,1002,'fgsw','2020-10-10 09:43:28','2020-10-10 09:43:28');
INSERT INTO `test_tb` VALUES (3,1003,'vffg','2020-10-10 02:00:00','2020-10-10 02:00:00');
INSERT INTO `test_tb` VALUES (4,1004,'wdsd','2020-10-31 23:43:28','2020-10-31 23:43:28');
INSERT INTO `test_tb` VALUES (5,1005,'grdb','2020-11-01 00:00:00','2020-11-01 00:00:00');
INSERT INTO `test_tb` VALUES (6,1006,'sdfv','2020-11-01 02:00:00','2020-11-01 02:00:00');
INSERT INTO `test_tb` VALUES (7,1007,'fgfg','2020-11-06 02:00:00','2020-11-06 02:00:00');
INSERT INTO `test_tb` VALUES (8,1008,'tyth','2020-11-10 09:43:28','2020-11-10 09:43:28');
INSERT INTO `test_tb` VALUES (9,1009,'ewer','2020-11-10 09:43:28','2020-11-10 09:43:28');
INSERT INTO `test_tb` VALUES (10,1010,'erre','2020-11-11 15:17:03','2020-11-11 15:17:03');
# timestamp时间值显示与datetime显示一样 未做转换
UNLOCK TABLES;
-- Dump completed on 2020-11-11 16:23:32

# 使用skip-tz-utc备份部分数据
[root@host ~]# mysqldump -uroot -pxxxx  --skip-extended-insert --skip-tz-utc testdb test_tb --where "create_time >= '2020-11-01 00:00:00' " > skiputc_testdb2.sql
mysqldump: [Warning] Using a password on the command line interface can be insecure.
[root@host ~]# more skiputc_testdb2.sql 
-- MySQL dump 10.13  Distrib 5.7.23, for Linux (x86_64)
--
-- Host: localhost    Database: testdb
-- ------------------------------------------------------
-- Server version       5.7.23-log
.. 省略
--
-- Dumping data for table `test_tb`
--
-- WHERE:  create_time >= '2020-11-01 00:00:00' 

LOCK TABLES `test_tb` WRITE;
/*!40000 ALTER TABLE `test_tb` DISABLE KEYS */;
INSERT INTO `test_tb` VALUES (5,1005,'grdb','2020-11-01 00:00:00','2020-11-01 00:00:00');
INSERT INTO `test_tb` VALUES (6,1006,'sdfv','2020-11-01 02:00:00','2020-11-01 02:00:00');
INSERT INTO `test_tb` VALUES (7,1007,'fgfg','2020-11-06 02:00:00','2020-11-06 02:00:00');
INSERT INTO `test_tb` VALUES (8,1008,'tyth','2020-11-10 09:43:28','2020-11-10 09:43:28');
INSERT INTO `test_tb` VALUES (9,1009,'ewer','2020-11-10 09:43:28','2020-11-10 09:43:28');
INSERT INTO `test_tb` VALUES (10,1010,'erre','2020-11-11 15:17:03','2020-11-11 15:17:03');
# 6条数据 和数据库中查询一致
UNLOCK TABLES;
-- Dump completed on 2020-11-11 16:28:39

从上面结果可以看出,使用 --skip-tz-utc 参数后,timestamp 时间戳字段值不会转换,导出部分数据也符合预期。

3.一些小建议

那么这个参数的意义何在呢?当你的数据库服务器处于不同时区时。假设一个服务器在北京(东八区),一个服务器在东京(东九区),现在需要将北京服务器里的数据导入至东京服务器。当导入按照默认不加 --skip-tz-utc 参数的dump文件,查询的 timestamp 时间数据相对于在之前的东八区服务器的时间值多了一个小时,但由于东八区服务器里的13点和东九区服务器里的14点代表的是同一时刻,所以,在东九区的服务器里显示的多出的一个小时,这样显示是正确的。而如果增加 --skip-tz-utc 参数,dump文件导入东九区服务器后,尽管显示的时间值和之前东八区服务器显示的时间值相同,但两者代表的时刻却已经不同。

关于这个参数应该如何使用,我们首先应该明白,是否加上 --skip-tz-utc 参数,只会影响 timestamp 字段的导入导出,对 datetime 时间字段不会影响。

这里笔者建议首先对 timestamp 字段使用作出规范。比如 timestamp 字段只用于创建时间和更新时间需求,只代表该行数据的创建及更新时间,做到与业务弱相关,其他时间字段尽量使用 datetime 。这样即使 mysqldump 采用不同参数,实际产生影响也不大。

如果你的服务器处于不同时区,那建议还是按照默认来,这样导入导出的数据都是正确的。如果你的服务器都是处于同一时区,那么是否使用 --skip-tz-utc 参数区别不大,我们只需知道默认情况 mysqldump 会将 timestamp 时间值转为0时区存储即可。当备份部分数据且以 timestamp 字段来筛选时,这时候建议增加 --skip-tz-utc 参数。这里再次提醒下,从全备中筛选单库或单表的备份时,也要注意下 timestamp 字段数据。

参考:

  • https://zhuanlan.zhihu.com/p/99395517

相关推荐

声学EI要完稿?十步速写法

【推荐会议】国际声学与振动会议(ICAV)会议号:CFP23112A截稿时间:2025年4月20日召开时间/地点:2025年8月15-17日·新加坡论文集上线:会后3个月提交EiComp...

结构力学!EI会议图表规范秘籍

推荐会议:国际结构与材料工程进展大会(ISME2026)会议编号:EI#73521截稿时间:2026年3月10日召开时间/地点:2026年8月15-17日·德国柏林论文集上线:会后4...

傅里叶级数物理意义的直观理解:利用傅里叶级数逼近方波信号

上篇文章将向大家介绍频谱的概念,对傅里叶级数、傅里叶积分、傅里叶变换进行了数学的推导,并解释了它们各自的物理意义。推导过程见我的上一篇文章:频谱分析——频谱概念(傅里叶变换、级数、积分及物理意义)如下...

通过对航空发动机整机振动进行分析,有何控制方法?

前言针对航空发动机整机振动问题的复杂性和多样性,以整机振动的振源分析为出发点,总结国内外关于转子系统故障、气流激振、轴承故障、齿轮故障和结构局部共振等引起的整机振动的研究情况。结合航空发动机整机结构动...

MATLIB中使用PCA

主成分分析PCA(PrincipalComponentsAnalysis),奇异值分解SVD(Singularvaluedecomposition)是两种常用的降维方法降维致力于解决三类问题:降维...

数据处理|软件:让科研更简单2

书接上回,继续介绍免费的数据处理软件。eGPS一款热图绘制专用软件,热图就是用颜色代表数字,让数据呈现更直观,对比更明显。优点:小巧方便,基本功能齐全,包括数据转换、聚类分析、颜色调整等等缺点:常见的...

电力系统常用的通讯协议及其在Speedgoat系统中的实现

在电力系统中,IEC61850协议、DNP3协议、ModbusTCP广泛应用于远程终端设备(RTU)、智能电子设备(IED)交互以及监控和数据采集(SCADA)系统。一、IEC61850协议IE...

电子工程师的常用仿真软件

不知道从事电子行业的工程师,有没有使用模拟仿真工具,仿真软件网上又有很多,初学者,可能只知道Multisim和Proteus。一般Multisim适合在学习模拟电路和电路分析原理课程时使用,便于理解电...

技术论文|异结构混沌系统的组合同步控制及电路实现

欢迎引用[1]李贤丽,马赛,樊争先,王壮,马文峥,于婷婷.异结构混沌系统的组合同步控制及电路实现[J].自动化与仪器仪表,2022,No.276(10):80-84.DOI:10.14016/j.cn...

现场︱某110KV主变事故过程仿真分析

三峡电力职业学院、河南省电力公司洛阳供电公司的研究人员李莉、任幼逢、徐金雄、王磊,在2016年第6期《电气技术》杂志上撰文,针对某110KV变电站主变差动保护跳闸事故,结合事故相关检测数据,通过MAT...

光伏发电系统篇:单级式并网系统实时仿真

在全球积极推动清洁能源转型的大背景下,光伏发电作为重要的可再生能源利用方式,得到了广泛关注和迅猛发展。目前常用的光伏并网及光伏电站主要拓扑结构有单级式和双级式。相较于传统的多级式系统,单级式光伏发电并...

光伏发电系统篇:三电平并网逆变器实时仿真

一、三电平并网逆变器在能源转型加速的当下,分布式能源接入电网需求大增。三电平并网逆变器凭借低谐波、高功率密度等优势,有效提升电能转换效率,于新能源并网发电中担当关键角色。常见的三电平电路拓扑结构包括二...

自制3.5KW大功率逆变器,很简单,看过这个电路原理就懂了

前言拿下8000元奖金的项目,是什么水平?本项目经过联合湖南科技大学光伏逆变以及电力电子研究生团队共同探讨方案。项目成本:1200元,获得奖金:8000元!参加赛事:立创开源硬件平台_星火计划·外包赛...

圈内分享:电容式加速度计接口电路非线性建模与仿真设计

摘要:非线性是Sigma-Delta(ΣΔ)加速度计系统的关键指标之一。基于一个五阶ΣΔ加速度计结构,分析了其主要的非线性模块,在MATLAB中建立了整体结构的行为级模型,并利用根轨迹法进行了稳...

基于Matlab/Simulink建立一种Thevenin/RC电池模块仿真模型

本文以锂电池数学模型为基础,在Matlab/Simulink的仿真系统中,建立了一种Thevenin/RC电池模块仿真模型,通过实际工况试验,测试精度在允许误差范围内,为电池SOC/SOH研究提供了极...