GX博客

分享个人 Full-Stack JavaScript 项目开发经验

使用mysqldump备份和恢复数据库

在 MySQL 的官方说明文档中已经对数据库的备份和恢复作了详细介绍,亦详细介绍了 mysqldump 工具的使用。本文主要整理 mysqldump 的常用指令,并结合具体的场景介绍它的操作步骤(MySQL 和 mysqldump 版本为 8.0.16)。



重要概念

物理备份:将数据库、表结构、数据、存储例程、触发器、事件等导出到一组可以再次执行的 SQL 文件中。(数据亦可单独保存到 .txt 文件中。)

逻辑备份:备份数据库用于存储所有数据库的实体系统的所有文件。

完全备份:可从完整备份中恢复所有数据。

增量备份:基于二进制日志,恢复在给定时间跨度内所做的更改。通常先通过完全备份还原所有数据到备份时的状态,然后将完全备份点后新的二进制日志文件作为增量重做数据修改,使服务器达到所需的时间点状态。

二进制日志:包含数据库的数据和结构的所有更改记录。


mysqldump 常用指令

登录相关

指令说明
--user=user_name用于连接服务器的 MySQL 帐户的用户名。
--password[=password]用于连接服务器的 MySQL 帐户的密码。使用该指令直接指定密码会存在安全问题,详细可参阅密码安全指南
--host=host_name从给定主机上的 MySQL 服务器转储数据,默认为 localhost。

指定数据库或表

指令说明
--all-databases转储所有数据库中的所有表。但不包含事件和存储例程,不包含 performance_schema、sys、information_schema 等内置数据库。
--databases转储所有数据库中的所有表。但不包含事件和存储例程。通常,mysqldump 将命令行上的第一个名称参数视为数据库名称,将后续名称视为表名称。该指令用于指定一个或多个数据库,名称使用空格隔开。CREATE DATABASE 和 USE 语句会包含在每个新数据库的输出之前。
--tables用于指定转储的表,指令后面的名称均被视为表名称。

指定表定义和数据

指令说明
--no-data不转储表内容。
--no-create-info不输出 CREATE TABLE 语句。
--tab=dir_name生成文本格式数据文件,该指令需要 FILE 权限。--databases 或 --all-databases 不能与 --tab 一并使用,亦即只能导出单个数据库时候使用。

其它 DDL 数据定义

指令说明
--add-drop-database在每个 CREATE DATABASE 语句之前添加 DROP DATABASE 语句。
--add-drop-table在每个 CREATE TABLE 语句之前添加 DROP TABLE 语句。
--no-create-db不添加 CREATE DATABASE 语句。

转储存储的程序

指令说明
--events转储事件计划程序的事件
--routines转储存储过程和函数
--triggers转储表的触发器(默认启用)
--skip-events跳过事件计划程序的事件
--skip-routines跳过存储过程和函数
--skip-triggers跳过表的触发器

一致性相关指令

指令说明
--add-locks在每个表转储时使用 LOCK TABLES 和 UNLOCK TABLES 语句。
--lock-tables对于每个转储的数据库,在转储之前锁定要转储的所有表。
--lock-all-tables锁定所有数据库中的所有表。
--single-transaction在转储数据前,设置事务隔离级别为 REPEATABLE READ(同一个事务中,读取一致的快照。),并发送一个 START TRANSACTION 语句。
该选项可以为 InnoDB 表提供一致状态转储,但要确保没有其它的连接使用了 ALTER TABLE、CREATE TABLE、DROP TABLE、RENAME TABLE、TRUNCATE TABLE 等语句,以确保转储正确的表的内容和二进制日志坐标。
--flush-logs在开始转储之前刷新MySQL服务器日志文件。该选项需要 RELOAD 权限。
--flush-privileges在转储 mysql 数据库后,添加 FLUSH PRIVILEGES 语句。
--master-data[=value]在转储中使用 CHANGE MASTER TO 语句,该选项需要 RELOAD 权限。如果 --master-data=2,将会把 CHANGE MASTER TO 语句写入注释,默认值为 1。

场景分析

场景1:数据库服务器作初始化部署,需要迁移多个数据库及其初始化数据,还有对应的数据库用户?

分析:这种情况下,被导出的数据库处于脱机状态,我们只需要导出的相应的数据库,并在新库上重新创建对应的用户即可。

1、使用以下命令导出初始化数据:

mysqldump --user=your_user_name --password --databases your_db_name1 your_db_name2 --add-drop-database --events --routines > /run/bk/init_db.sql

2、把创建用户,授权用户的 SQL 存放于 .sql 文件中,如 create_grant_app_user.sql。

3、导入初始化数据库及数据:

mysql -u your_user_name -p < init_db.sql

4、执行创建和授权用户 SQL:

mysql -u your_user_name -p < create_grant_app_user.sql

5、运行应用程序,检查数据库的可访问性。


场景2:数据库服务器在部署后,需要作完全备份和增量备份,并在突发情况下恢复到特定时间点的状态?

每次都做完全备份是耗费时间的,一般的折中方案是,先进行完全备份,然后后面在完全备份的基础上基于二进制日志作增量备份。

MySQL 默认是开启二进制日志的,默认值为 log_bin=binlog,即二进制日志文件保存在 datadir=/var/lib/mysql 中。要查看详细配置信息可以:

cat /etc/my.cnf

要显示服务器的所有二进制日志,可以登录 MySQL 后:

SHOW BINARY LOGS;
mysqldump --user=your_user_name --password --single-transaction --flush-logs --master-data=2 --all-databases --events --routines --delete-master-logs > backup_20191004_0130.sql

指令 --flush-logs --delete-master-logs 会删除 MySQL 的二进制文件,并重新刷新日志。

因为使用了 --master-data=2,所以可以在导出 sql 中看到注释如:

-- CHANGE MASTER TO MASTER_LOG_FILE='binlog.000066', MASTER_LOG_POS=155;

如果服务器为主复制服务器时,使用 --delete-master-logs 指令可能很危险,因为从属服务器可能尚未完全处理二进制日志的内容。你可以使用PURGE BINARY LOGS语句安全地清除二进制日志。

最后是使用备份来恢复数据。

mysql -u your_user_name -p < backup_20191004_0130.sql
mysqlbinlog binlog.000066 | mysql -u your_user_name -p

要查看 MySQL 8.0 参考手册中的 MySQL 备份和恢复摘录,请点击这里
要查看官方文档中使用 mysqldump 进行备份章节,请点击这里
要了解更多 mysqldump 指令介绍,请点击这里

版权声明:

本文为博主原创文章,若需转载,须注明出处,添加原文链接。

https://leeguangxing.cn/blog_post_65.html