0

0

mysqldump 逻辑备份的正确姿势_MySQL

php中文网

php中文网

发布时间:2016-05-30 17:10:49

|

1420人浏览过

|

来源于php中文网

原创

1. 利用mysqldump进行逻辑备份

 

Paraflow
Paraflow

AI产品设计智能体

下载

1)全逻辑备份:

 

mysqldump -uxxx -p --flush-logs --delete-master-logs --all-databases > alldb.sql (每天晚上进行一次全备)

 

2)增量备份:

 

mysqladmin flush-logs (每小时刷一下,保存起来,进行了一次增量备份)

 

3)缺点:

 

1> --all-databases 包含了 mysql 数据库,其中包含了权限的数据,所以我们应该加上 --flush-privileges,在恢复时,权限才能生效;

 

注意 --all-databases 包括了mysql数据库,但是不会包含 information_schema和performance_schema两个数据库。

 

2> 因为 mysqldump 默认启用了 --lock-tables,所以会导致在备份期间对所有表持有读锁: lock table tb read local,所以所有的update,delete语句

 

会被阻塞。但是select语句和insert语句不会被阻塞。

 

3> --delete-master-logs 备份之后,会执行 purge logs to 语句。删除了备份之后的master上的binary log. 一般而言,我们不建议随便删除binary log.

 

我们应该将它们保存起来,而不是直接删除。以防万一,要留条退路。

 

4> 该备份方式,虽然在整个备份过程中持有了 lock table tb read local,但是还是可以执行 insert 语句的。所以得到的不是一致性的备份。虽然得到的不是

 

一致性的备份,但是因为flush log之后,所有的操作 也会记入新的binary log,所以如果使用了所有新的binary log来进行完全恢复的话,最后恢复的数据

 

也是一致性的。当然不一致性的备份无法用于搭建slave。

 

如果要得到一致性的备份的话,需要使用 --lock-all-tables 或者使用 --single-transaction 选项。前者使用了全局读锁,不允许任何修改操作。后者使用

 

了事务的特性来得到一致性备份。

 

所以我们应该对上面的备份方式进行改良。

 

2. 使用mysqldump备份的最佳姿势

 

1)优化锁 和 得到一致性备份:

 

我们可以使用结合使用 --single-transaction 、--master-data=2 、--flush-logs 来达到将锁定时间大大减少的目的。同时有得到了一致性的备份,而且该一致性备份和 flush 的日志也是一致的;

 

2)去掉 --delete-master-logs 选项,改为在备份之后,将所有被刷新的 binary log 移到一个地方保存起来;

 

3)因为使用了 --single-transaction 选项,针对的只能是 innodb 数据,但是mysql数据是Myisam引擎的,所以我们最好将mysql数据库的备份分开来,

 

另外专门针对 mysql 数据库进行一次操作。当然不分开来备份,可能也没有问题。

 

4)还要加上 --routines 来备份存储过程和函数,触发器默认会备份。

 

优化之后,我们得到:

 

mysqldump -uxxx -p --single-transaction --master-data=2 --routines --flush-logs --databases db1 db2 db3 > alldb.sql;

 

mysqldump -uxxx -p --flush-privileges --databases mysql > mysql.sql;

 

如果将mysql也一起备份的话:

 

mysqldump -uxxx -p --single-transaction --master-data=2 --routines --flush-logs --flush-privileges --all-databases > alldb.sql;

 

3. 使用mysqldump来搭建slave环境

 

搭建slave环境,一般有两种方法,对于规模不大的库,可以采用mysqldump来搭建;对于规模很大的库,最好采用xtrabackup来搭建,速度要快很多。

 

1)首先 分别在master和slave上设置不同的server_id=1/101,启用master上的log-bin=1,启用slave上的relog-log=relay-bin; 在master上设置:

 

binlog_format=row;二进制日志的格式。maser上最好还设置sync_binlog=1 和 innodb_flush_log_at_trx_commit=1防止发生服务器崩溃时

 

导致复制破坏。在slave上最好还配置:read-only=1 和 skip-slave-start=1 前者可以防止没有super权限的用户在slave上进行写,后者防止在启动

 

slave数据库时,自动启动复制线程。以后需要手动start slave来启动复制线程。注意slave没有必要启用 log-bin=1,除非需要搭建二级slave。

 

2)在master上建立一个具有复制权限的用户:

 

grant replication slave, replication client on *.* to repl@’192.168.%.%’ identified by ‘123456’;

3)备份master上的数据库,迁移到slave上:

[root@localhost ~]# mysqldump -uroot -p --routines --flush-logs --master-data=2 --databases db2 db1>/root/backup.sql
Enter password:
[root@localhost ~]# scp /root/backup.sql 192.168.137.9:/tmp/backup.sql
The authenticity of host '192.168.137.9 (192.168.137.9)' can't be established.
RSA key fingerprint is a4:cd:c0:13:d1:8c:c0:a5:e7:c4:43:b5:95:17:af:d3.
Are you sure you want to continue connecting (yes/no)? yes
Warning: Permanently added '192.168.137.9' (RSA) to the list of known hosts.
[email protected]'s password:
backup.sql  

因为slave的搭建需要一致性的备份,所以需要启用 --lock-all-tables(master-data=1/2会自动启用--lock-all-tables)或者--single-transaction;

 

另外还需要知道该一致性备份的数据,对应的master上的binary log的文件名,以及在该文件中的position,所以必须启用 master-data选项。

 

因为--master-data会启用--lock-all-tables 所以数据才是一致性的;但是导致了全局锁,不能进行任何修改操作;下面我们使用--single-transaction进行优化:

 

mysqldump -uroot -p --routines --flush-logs --single-transaction --master-data=2 --databases db1 db2 > /root/backup.sql; (--flush-logs非必须)

 

这样全局锁仅仅在备份的开始短暂的持有。不会再备份的整个过程中持有全局锁。

 

4)在slave上执行备份的脚本,然后连上master,开启复制线程:

 

执行sql脚本:

 

mysql> source /tmp/backup.sql

找到 --master-data 输出的 binary log 的文件名和postion:

 

[root@localhost ~]# head -50 /tmp/backup.sql

......
/*!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 */;

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

-- CHANGE MASTER TO MASTER_LOG_FILE='mysql-bin.000010', MASTER_LOG_POS=809;

执行 change master to, start slave:

 

在salve上执行命令开始复制:

mysql> change master to master_host='192.168.137.8', master_user='repl', master_password='123456',

    -> master_log_file='mysql-bin.000010', master_log_pos=809;

Query OK, 0 rows affected, 2 warnings (0.09 sec)

 

mysql> start slave;

Query OK, 0 rows affected (0.04 sec)

 

最后在slave上查看复制线程的状态:

 

mysql> show slave status\G

... ...

   Slave_IO_Running: Yes

  Slave_SQL_Running: Yes

......

slave_IO_Runing 和 slave_sql_runing 状态都是yes表示搭建成功。

 

5)replication涉及到的三个线程:

1> master上的 binlog dump(dump线程),即读取master上的binlog,发送到slave上的线程。

2> slave上的IO线程:读取slave上的relay log。

3> slave上的sql线程:执行IO线程读取的relay log的线程。 

 

4. 使用mysqldump的备份进行 还原

 

下面使用 mysqldump 进行一个备份,然后删除 datadir, 然后使用备份sql脚本和binary log进行还原的过程。

 

1)首先进行一个全备:

 

mysqldump -uroot -p --single-transaction --master-data=2 --routines --flush-logs --databases gs ngx_lua > gs_ngx_lua_backup.sql;

数据库有两个库: gs , ngx_lua.

 

2)将 备份时刷新之后的 binary log 利用 mv 命令移动到安全的位置,也就是--master-data=2输出的日志文件,它之前的日志文件都存储到安全的位置:

 

[root@localhost ~]# head -n 50 gs_ngx_lua_backup.sql
-- MySQL dump 10.13  Distrib 5.6.26, for linux-glibc2.5 (i686)
--
-- Host: localhost    Database: gs
... ...--
-- Position to start replication or point-in-time recovery from
--

-- CHANGE MASTER TO MASTER_LOG_FILE='mysql-bin.000027', MASTER_LOG_POS=120;

 

 

也就是将 MASTER_LOG_FILE='mysql-bin.000027' 之前的日志都存储到其它位置。

 

然后执行:purge binary logs to 'mysql-bin.000027' 更新了 mysql-bin.index 中的索引信息,这里并没有删除binary log,因为它们已经被mv走了。

 

3)下面模拟一个 增量备份:

 

 

mysql> delete from user where id=5;
Query OK, 1 row affected (0.02 sec)

mysql> select * from user;
+----+----------+------+-------------+----------+
| id | name| sex  | phone  | addr|
+----+----------+------+-------------+----------+
|  1 | yuanfang |    1 | 14465463786 | hangzhou |
|  2 | Andy|    0 | 14465463786 | beijing  |
|  3 | peter    |    0 | 14465463786 | Hongkong |
|  4 | lexin    |    1 | 36565634    | shenzhen |
+----+----------+------+-------------+----------+
4 rows in set (0.00 sec)


mysql> flush logs;
Query OK, 0 rows affected (0.11 sec)

mysql> show binary logs;
+------------------+-----------+
| Log_name    | File_size |
+------------------+-----------+
| mysql-bin.000027 |  370 |
| mysql-bin.000028 |  120 |
+------------------+-----------+
2 rows in set (0.00 sec)

 

 

这里 flush logs 进行增量备份,然后将增量备份的 bianry log 文件 mysql-bin.000027 也存储起来。

 

然后在进行一条 delete 语句:

 

 

mysql> select * from user;
+----+----------+------+-------------+----------+
| id | name| sex  | phone  | addr|
+----+----------+------+-------------+----------+
|  1 | yuanfang |    1 | 14465463786 | hangzhou |
|  2 | Andy|    0 | 14465463786 | beijing  |
|  3 | peter    |    0 | 14465463786 | Hongkong |
+----+----------+------+-------------+----------+
3 rows in set (0.00 sec)

 

到这里数据库的最新状态是:user 表只有3条记录。

 

然后我们同样将 mysql-bin.000028 也存储起来。

 

4)然后我们删除 data-dir 目录中的所有文件,然后开始还原:

 

[root@localhost mysql]# pwd

/var/lib/mysql

[root@localhost mysql]# mv ./* /backup/before_delete/

此时 data-dir 目录是空的。然后我们试图使用 mysqladmin -uroot -p shutdown 来关闭mysqld,发现早不到 mysql.sock 无法关闭,我们只好使用

 

killall mysqld

 

来关闭。

 

5)然后进行数据库的初始化,然后开始还原:

 

进入到 /usr/local/mysql/script 目录,然后执行初始化:

 

./mysql_install_db  --user=mysql --datadir=/var/lib/mysql --basedir=/usr/local/mysql

 

 ./mysql_install_db

初始化成功之后,执行:

 

/usr/local/mysql/bin/mysql_secure_installation

 

来进行密码设置。这一步可能会报错:找不到 /tmp/mysql.sock 文,解决方法,在/etc/my.cnf 中的[client], [mysql], [mysqld] 都进行下面的设置:

 

socket=/tmp/mysql.sock

 

然后重新执行:/usr/local/mysql/bin/mysql_secure_installation 就行了。

 

初始化完成之后,我们使用备份的sql脚本来进行恢复:

 

[root@localhost ~]# mysql -uroot -p

执行完成之后,发现 gs 和 ngx_lua 数据库都还原出来了,但是他们的数据不是最新的数据:

 

 

mysql> use gs;
Reading table information for completion of table and column names
You can turn off this feature to get a quicker startup with -A

Database changed
mysql> select * from user;
+----+----------+------+----------------+----------+
| id | name| sex  | phone| addr|
+----+----------+------+----------------+----------+
|  1 | yuanfang |    1 | 14465463786    | hangzhou |
|  2 | Andy|    0 | 14465463786    | beijing  |
|  3 | peter    |    0 | 14465463786    | Hongkong |
|  4 | lexin    |    1 | 36565634  | shenzhen |
|  5 | lexin2   |    1 | 43563436565634 | aomao    |
+----+----------+------+----------------+----------+
5 rows in set (0.01 sec)

 

 

这是因为,我们还没有使用 mysql-bin.000027 和 mysql-bin.000028 两个binary log。mysql-bin.000027 是我们前面模拟的增量备份,而mysql-bin.000028 是 删除data-dir目录时,最新的binary log。依次应用了这两个binary log之后,数据库才能恢复到最新的状态。

 

6)应用 binary log:

 

[root@localhost backup]# pwd

/backup

[root@localhost backup]# mysqlbinlog mysql-bin.000027 > 27.sql

[root@localhost backup]# mysqlbinlog mysql-bin.000028 > 29.sql

mysqlbinlog mysql-bin.000027 > 27.sql 得到了 27.sql 和 28.sql 之后,使用 mysql 来执行:

 

mysql -uroot -p

 

然后查看数据:

 

mysql> mysql> select * from user;
+----+----------+------+-------------+----------+
| id | name| sex  | phone  | addr|
+----+----------+------+-------------+----------+
|  1 | yuanfang |    1 | 14465463786 | hangzhou |
|  2 | Andy|    0 | 14465463786 | beijing  |
|  3 | peter    |    0 | 14465463786 | Hongkong |
|  4 | lexin    |    1 | 36565634    | shenzhen |
+----+----------+------+-------------+----------+
4 rows in set (0.00 sec)

 

 

然应用 28.sql :

 

mysql -uroot -p

 

得到最新的状态:

 

mysql> select * from user;
+----+----------+------+-------------+----------+
| id | name| sex  | phone  | addr|
+----+----------+------+-------------+----------+
|  1 | yuanfang |    1 | 14465463786 | hangzhou |
|  2 | Andy|    0 | 14465463786 | beijing  |
|  3 | peter    |    0 | 14465463786 | Hongkong |
+----+----------+------+-------------+----------+
3 rows in set (0.00 sec)

 

 

可以看到,成功的还原到了删除 data-dir 目录之前的状态了。

 

5. mysqldump的 坑

 

如果对 mysqldump 的默认启用的选项不熟悉的话,可能会被默认启用的选项 --add-drop-table 给坑了。因为默认会生成 drop table if exist 语句。可能会导致数据的丢失。  --add-drop-database 默认没有启用。如果不想他生成 drop table 语句,可以加入 --skip-add-drop-table选项,或者 --add-ropt-table=0也可以。

 

6. 总结:

 

1)逻辑备份的最佳方法:

 

全备:

 

mysqldump -uxxx -p --single-transaction --master-data=2 --routines --flush-logs --databases db1 db2 db3 > alldb.sql;

 

mysqldump -uxxx -p --flush-privileges --databases mysql > mysql.sql;

 

如果将mysql也一起备份的话:

 

mysqldump -uxxx -p --single-transaction --master-data=2 --routines --flush-logs --flush-privileges --all-databases > alldb.sql;

 

有时,还需要加入:--default-character-set=utf8/utf8mb4 ,该选项一般也可以配置在/etc/my.cnf中。

 

增量备份:flush logs; 然后将binary log存储起来即可。

 

2)搭建slave时的最佳选项:

 

mysqldump -uxxx -p --single-transaction --master-data=2 --routines --databases db1 db2 db3 > alldb.sql;

 

搭建slave,没有必要 --flush-logs。当然搭建slave的最佳方式是使用 xtrabackup,物理备份。

 

3)使用mysqldump备份的sql脚本还原的方法:

 

先还原数据库,然后应用增量日志和最新日志,binary log在应用之前需要使用mysqlbinlog命令来处理。

热门AI工具

更多
DeepSeek
DeepSeek

幻方量化公司旗下的开源大模型平台

豆包大模型
豆包大模型

字节跳动自主研发的一系列大型语言模型

通义千问
通义千问

阿里巴巴推出的全能AI助手

腾讯元宝
腾讯元宝

腾讯混元平台推出的AI助手

文心一言
文心一言

文心一言是百度开发的AI聊天机器人,通过对话可以生成各种形式的内容。

讯飞写作
讯飞写作

基于讯飞星火大模型的AI写作工具,可以快速生成新闻稿件、品宣文案、工作总结、心得体会等各种文文稿

即梦AI
即梦AI

一站式AI创作平台,免费AI图片和视频生成。

ChatGPT
ChatGPT

最最强大的AI聊天机器人程序,ChatGPT不单是聊天机器人,还能进行撰写邮件、视频脚本、文案、翻译、代码等任务。

相关专题

更多
Golang 生态工具与框架:扩展开发能力
Golang 生态工具与框架:扩展开发能力

《Golang 生态工具与框架》系统梳理 Go 语言在实际工程中的主流工具链与框架选型思路,涵盖 Web 框架、RPC 通信、依赖管理、测试工具、代码生成与项目结构设计等内容。通过真实项目场景解析不同工具的适用边界与组合方式,帮助开发者构建高效、可维护的 Go 工程体系,并提升团队协作与交付效率。

1

2026.02.24

Golang 性能优化专题:提升应用效率
Golang 性能优化专题:提升应用效率

《Golang 性能优化专题》聚焦 Go 应用在高并发与大规模服务中的性能问题,从 profiling、内存分配、Goroutine 调度、GC 机制到 I/O 与锁竞争逐层分析。结合真实案例讲解定位瓶颈的方法与优化策略,帮助开发者建立系统化性能调优思维,在保证代码可维护性的同时显著提升服务吞吐与稳定性。

0

2026.02.24

Golang 面试题精选:高频问题与解答
Golang 面试题精选:高频问题与解答

Golang 面试题精选》系统整理企业常见 Go 技术面试问题,覆盖语言基础、并发模型、内存与调度机制、网络编程、工程实践与性能优化等核心知识点。每道题不仅给出答案,还拆解背后的设计原理与考察思路,帮助读者建立完整知识结构,在面试与实际开发中都能更从容应对复杂问题。

1

2026.02.24

Golang 运行与部署实战:从本地到云端
Golang 运行与部署实战:从本地到云端

《Golang 运行与部署实战》围绕 Go 应用从开发完成到稳定上线的完整流程展开,系统讲解编译构建、环境配置、日志与配置管理、容器化部署以及常见运维问题处理。结合真实项目场景,拆解自动化构建与持续部署思路,帮助开发者建立可靠的发布流程,提升服务稳定性与可维护性。

3

2026.02.24

Golang 疑难杂症解决指南:常见问题排查与优化
Golang 疑难杂症解决指南:常见问题排查与优化

《Golang 疑难杂症解决指南》聚焦开发过程中常见却棘手的问题,从并发模型、内存管理、性能瓶颈到工程化实践逐步拆解。通过真实案例与调试思路,帮助开发者定位问题根因,建立系统化排查方法。不只给出答案,更强调分析路径与工具使用,让你在复杂 Go 项目中具备持续解决问题的能力。

0

2026.02.24

Golang 入门学习路线:从零基础到上手开发
Golang 入门学习路线:从零基础到上手开发

Golang 入门路线涵盖从零到上手的核心路径:首先打牢基础语法与切片等底层机制;随后攻克 Go 的灵魂——接口设计与 Goroutine 并发模型;接着通过 Gin 框架与 GORM 深入 Web 开发实战;最后在微服务与云原生工具开发中进阶,旨在培养具备高性能并发处理能力的后端工程师。

0

2026.02.24

中国研究生招生信息网官方网站入口 研招网网页版在线入口
中国研究生招生信息网官方网站入口 研招网网页版在线入口

中国研究生招生信息网入口(https://yz.chsi.com.cn) 此网站是研究生报名入口的唯一官方网站

75

2026.02.24

苹果官网入口与在线访问指南_中国站点快速直达与iPhone查看方法
苹果官网入口与在线访问指南_中国站点快速直达与iPhone查看方法

本专题汇总苹果官网最新可用入口及中国站点访问方式,涵盖官网直达链接、iPhone官方页面查看方法与常见访问说明,帮助用户快速进入苹果官方网站,便捷了解产品信息与官方服务。

14

2026.02.24

Asianfanfics官网入口与访问指南_AFF官方平台最新登录地址
Asianfanfics官网入口与访问指南_AFF官方平台最新登录地址

本专题系统整理Asianfanfics(AFF)官方网站最新可用入口,涵盖官方平台最新直达地址、官网登录方式及中文访问指引,帮助用户快速、安全地进入AFF平台浏览与使用相关内容。

15

2026.02.24

热门下载

更多
网站特效
/
网站源码
/
网站素材
/
前端模板

精品课程

更多
相关推荐
/
热门推荐
/
最新课程
Java 教程
Java 教程

共578课时 | 71.6万人学习

国外Web开发全栈课程全集
国外Web开发全栈课程全集

共12课时 | 1万人学习

Go语言实战之 GraphQL
Go语言实战之 GraphQL

共10课时 | 0.9万人学习

关于我们 免责申明 举报中心 意见反馈 讲师合作 广告合作 最新更新
php中文网:公益在线php培训,帮助PHP学习者快速成长!
关注服务号 技术交流群
PHP中文网订阅号
每天精选资源文章推送

Copyright 2014-2026 https://www.php.cn/ All Rights Reserved | php.cn | 湘ICP备2023035733号