第19章 数据库备份与恢复【4.日志与备份篇】【MySQL高级】1

本文涉及的产品
云数据库 RDS MySQL Serverless,0.5-2RCU 50GB
云数据库 RDS MySQL Serverless,价值2615元额度,1个月
简介: 第19章 数据库备份与恢复【4.日志与备份篇】【MySQL高级】1

前言


2022/8/14 11:16


暑假学习ing


推荐

【MySQL数据库教程天花板,mysql安装到mysql高级,强!硬!-哔哩哔哩】

尚硅谷MySQL学习笔记

MySQL笔记:第19章_数据库备份与恢复

第19章 数据库备份与恢复

在任何数据库环境中,总会有不确定的意外情况发生,比如例外的停电、计算机系统中的各种软硬件故障、人为破坏、管理员误操作等是不可避免的,这些情况可能会导致数据的丢失、服务器瘫痪等严重的后果。存在多个服务器时,会出现主从服务器之间的数据同步问题。


为了有效防止数据丢失,并将损失降到最低,应定期对MySQL数据库服务器做备份。如果数据库中的数据丢失或者出现错误,可以使用备份的数据进行恢复。主从服务器之间的数据同步问题可以通过复制功能实现。

1. 物理备份与逻辑备份

物理备份:备份数据文件,转储数据库物理文件到某一目录。物理备份恢复速度比较快,但占用空间比较大,MySQL中可以用 xtrabackup 工具来进行物理备份。
逻辑备份:对数据库对象利用工具进行导出工作,汇总入备份文件内。逻辑备份恢复速度慢,但占用空间小,更灵活。MySQL 中常用的逻辑备份工具为 mysqldump 。逻辑备份就是 备份sql语句 ,在恢复的时候执行备份的sql语句实现数据库数据的重现。

2. mysqldump实现逻辑备份

mysqldump是MySQL提供的一个非常有用的数据库备份工具

2.1 备份一个数据库

mysqldump命令执行时,可以将数据库备份成一个文本文件,该文件中实际上包含多个CREATEINSERT语句,使用这些语句可以重新创建表和插入数据。

  • 查出需要备份的表的结构,在文本文件中生成一个CREATE语句
  • 将表中的所有记录转换成一条INSERT语句。

基本语法:

mysqldump –u 用户名称 –h 主机名称 –p密码 待备份的数据库名称[tbname, [tbname...]]> 备份文件名称.sql

说明:

备份的文件并非一定要求后缀名为.sql,例如后缀名为.txt的文件也是可以的。

举例:使用root用户备份atguigu数据库:

mysqldump -uroot -p atguigu>atguigu.sql #备份文件存储在当前目录下
mysqldump -uroot -p atguigudb1 > /var/lib/mysql/atguigu.sql

备份文件剖析:

--  MySQL dump 10.13  Distrib 8.0.26, for Linux (x86_64)
--  
-- Host: localhost  Database: atguigu
-- ------------------------------------------------------ -- Server version 8.0.26
/*!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 */;
--
--  Current Database: `atguigu`
--  
CREATE DATABASE /*!32312 IF NOT EXISTS*/ `atguigu` /*!40100 DEFAULT CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci */ /*!80016 DEFAULT ENCRYPTION='N' */;
USE `atguigu`;
--
-- Table structure for table `student`
--
DROP TABLE IF EXISTS `student`;   
/*!40101  SET @saved_cs_client  = @@character_set_client */;
/*!50503  SET character_set_client =  utf8mb4 */;
CREATE TABLE `student` (
`studentno` int NOT NULL,
`name` varchar(20) DEFAULT NULL,
`class` varchar(20) DEFAULT NULL,
PRIMARY KEY (`studentno`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb3;
/*!40101 SET character_set_client = @saved_cs_client */;
INSERT INTO `student` VALUES (1,'张三_back','一班'),(3,'李四','一班'),(8,'王五','二班'), (15,'赵六','二班'),(20,'钱七','>三班'),(22,'zhang3_update','1ban'),(24,'wang5','2ban'); /*!40000 ALTER TABLE `student` ENABLE KEYS */;
UNLOCK TABLES;
.
.
.
.
/*!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 2022-01-07 9:58:23

演示

#创建目录
[root@centos7-mysql-1 ~]# mkdir /var/lib/mysql/backup
[root@centos7-mysql-1 ~]# cd /var/lib/mysql/backup
[root@centos7-mysql-1 backup]# ll
总用量 0
#备份
[root@centos7-mysql-1 backup]# mysqldump -uroot -p atguigudb33>/var/lib/mysql/backup/atguigudb33.sql
Enter password: 
#查看
[root@centos7-mysql-1 backup]# ll
总用量 4
-rw-r--r--. 1 root root 2128 8月  14 11:32 atguigudb33.sql
[root@centos7-mysql-1 backup]# vim atguigudb33.sql 
-- MySQL dump 10.13  Distrib 8.0.25, for Linux (x86_64)
--
-- Host: localhost    Database: atguigudb33
-- ------------------------------------------------------
-- Server version 8.0.25
/*!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 */;
--
-- Table structure for table `student`
--
DROP TABLE IF EXISTS `student`;
/*!40101 SET @saved_cs_client     = @@character_set_client */;
/*!50503 SET character_set_client = utf8mb4 */;
CREATE TABLE `student` (
  `id` int NOT NULL,
  `name` varchar(20) DEFAULT NULL,
  `class` varchar(10) DEFAULT NULL,
  PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb3;
/*!40101 SET character_set_client = @saved_cs_client */;
--
-- Dumping data for table `student`
--
LOCK TABLES `student` WRITE;
/*!40000 ALTER TABLE `student` DISABLE KEYS */;
INSERT INTO `student` VALUES (1,'张三3','一班'),(3,'李四1','一班'),(6,'jerry','一班'),(8,'王五','二班'),(11,'Tim','一班'),(15,'赵六','二班'),(17,'Tom1','三班'),(18,'Jerry','四班'),(20,'钱七','三班'),(22,'bbb','No.1'),(23,'aaa','No.1');
/*!40000 ALTER TABLE `student` ENABLE KEYS */;
UNLOCK TABLES;
/*!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 2022-08-14 11:32:06
[root@centos7-mysql-1 backup]# 

2.2 备份全部数据库

若想用mysqldump备份整个实例,可以使用 --all-databases 或 -A 参数:

mysqldump -uroot -pxxxxxx --all-databases > all_database.sql 
mysqldump -uroot -pxxxxxx -A > all_database.sql

2.3 备份部分数据库

使用 --databases 或 -B 参数了,该参数后面跟数据库名称,多个数据库间用空格隔开。如果指定databases参数,备份文件中会存在创建数据库的语句,如果不指定参数,则不存在。语法如下:

mysqldump –u user –h host –p --databases [数据库的名称1 [数据库的名称2...]] > 备份文件名称.sql

举例:

mysqldump -uroot -p --databases atguigu atguigu12 >two_database.sql

mysqldump -uroot -p -B atguigu atguigu12 > two_database.sql

2.4 备份部分表

比如,在表变更前做个备份。语法如下:

mysqldump –u user –h host –p 数据库的名称 [表名1 [表名2...]] > 备份文件名称.sql

举例:备份atguigu数据库下的book表

mysqldump -uroot -p atguigu book> book.sql

book.sql文件内容如下

mysqldump -uroot -p atguigu book> book.sql^C
[root@node1 ~]# ls
kk  kubekey kubekey-v1.1.1-linux-amd64.tar.gz README.md test1.sql two_database.sql [root@node1 ~]# mysqldump -uroot -p atguigu book> book.sql
Enter password: [root@node1 ~]# ls
book.sql kk kubekey kubekey-v1.1.1-linux-amd64.tar.gz README.md test1.sql two_database.sql
[root@node1 ~]# vi book.sql
-- MySQL dump 10.13  Distrib 8.0.26, for Linux (x86_64)
--
-- Host: localhost  Database: atguigu
-- ------------------------------------------------------ -- Server version 8.0.26
/*!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 */;
--
--  Table structure for table `book`
--  
DROP TABLE IF EXISTS `book`;
/*!40101 SET @saved_cs_client = @@character_set_client */;
/*!50503 SET character_set_client = utf8mb4 */; CREATE TABLE `book` (
`bookid` int unsigned NOT NULL AUTO_INCREMENT, `card` int unsigned NOT NULL,
`test` varchar(255) COLLATE utf8_bin DEFAULT NULL,
PRIMARY KEY (`bookid`),
KEY `Y` (`card`)
) ENGINE=InnoDB AUTO_INCREMENT=101 DEFAULT CHARSET=utf8mb3 COLLATE=utf8_bin; /*!40101 SET character_set_client = @saved_cs_client */;
--
--  Dumping data for table `book`
--  
LOCK TABLES `book` WRITE;
/*!40000 ALTER TABLE `book` DISABLE KEYS */;
INSERT INTO `book` VALUES (1,9,NULL),(2,10,NULL),(3,4,NULL),(4,8,NULL),(5,7,NULL),
(6,10,NULL),(7,11,NULL),(8,3,NULL),(9,1,NULL),(10,17,NULL),(11,19,NULL),(12,4,NULL),
(13,1,NULL),(14,14,NULL),(15,5,NULL),(16,5,NULL),(17,8,NULL),(18,3,NULL),(19,12,NULL),
(20,11,NULL),(21,9,NULL),(22,20,NULL),(23,13,NULL),(24,3,NULL),(25,18,NULL),
(26,20,NULL),(27,5,NULL),(28,6,NULL),(29,15,NULL),(30,15,NULL),(31,12,NULL),
(32,11,NULL),(33,20,NULL),(34,5,NULL),(35,4,NULL),(36,6,NULL),(37,17,NULL),
(38,5,NULL),(39,16,NULL),(40,6,NULL),(41,18,NULL),(42,12,NULL),(43,6,NULL),
(44,12,NULL),(45,2,NULL),(46,12,NULL),(47,15,NULL),(48,17,NULL),(49,2,NULL),
(50,16,NULL),(51,13,NULL),(52,17,NULL),(53,7,NULL),(54,2,NULL),(55,9,NULL),
(56,1,NULL),(57,14,NULL),(58,7,NULL),(59,15,NULL),(60,12,NULL),(61,13,NULL),
(62,8,NULL),(63,2,NULL),(64,6,NULL),(65,2,NULL),(66,12,NULL),(67,12,NULL),(68,4,NULL),
(69,5,NULL),(70,10,NULL),(71,16,NULL),(72,8,NULL),(73,14,NULL),(74,5,NULL),
(75,4,NULL),(76,3,NULL),(77,2,NULL),(78,2,NULL),(79,2,NULL),(80,3,NULL),(81,8,NULL),
(82,14,NULL),(83,5,NULL),(84,4,NULL),(85,2,NULL),(86,20,NULL),(87,12,NULL),
(88,1,NULL),(89,8,NULL),(90,18,NULL),(91,3,NULL),(92,3,NULL),(93,6,NULL),(94,1,NULL),
(95,4,NULL),(96,17,NULL),(97,15,NULL),(98,1,NULL),(99,20,NULL),(100,15,NULL);
/*!40000 ALTER TABLE `book` ENABLE KEYS */;
UNLOCK TABLES;
/*!40103 SET TIME_ZONE=@OLD_TIME_ZONE */;

可以看到,book文件和备份的库文件类似。不同的是,book文件只包含book表的DROP、CREATE和INSERT语句。

备份多张表使用下面的命令,比如备份book和account表:

#备份多张表
mysqldump -uroot -p atguigu book account  > 2_tables_bak.sql

2.5 备份单表的部分数据

有些时候一张表的数据量很大,我们只需要部分数据。这时就可以使用 --where 选项了。where后面附带需要满足的条件。

举例:备份student表中id小于10的数据:

mysqldump -uroot -p atguigu student --where="id < 10 " > student_part_id10_low_bak.sql

内容如下所示,insert语句只有id小于10的部分

LOCK TABLES `student` WRITE;
/*!40000 ALTER TABLE `student` DISABLE KEYS */;
INSERT INTO `student` VALUES (1,100002,'JugxTY',157,280),(2,100003,'QyUcCJ',251,277), (3,100004,'lATUPp',80,404),(4,100005,'BmFsXI',240,171),(5,100006,'mkpSwJ',388,476), (6,100007,'ujMgwN',259,124),(7,100008,'HBJTqX',429,168),(8,100009,'dvQSQA',61,504), (9,100010,'HljpVJ',234,185);

2.6 排除某些表的备份

如果我们想备份某个库,但是某些表数据量很大或者与业务关联不大,这个时候可以考虑排除掉这些表,同样的,选项 --ignore-table 可以完成这个功能。

mysqldump -uroot -p atguigu --ignore-table=atguigu.student > no_stu_bak.sql

通过如下指定判定文件中没有student表结构:

grep "student"  no_stu_bak.sql

2.7 只备份结构或只备份数据

只备份结构的话可以使用 --no-data 简写为 -d 选项;只备份数据可以使用 --no-create-info 简写为 -t 选项。

  • 只备份结构
mysqldump -uroot -p atguigu --no-data > atguigu_no_data_bak.sql
#使用grep命令,没有找到insert相关语句,表示没有数据备份。
grep "INSERT" atguigu_no_data_bak.sql 
  • 只备份数据
mysqldump -uroot -p atguigu --no-create-info > atguigu_no_create_info_bak.sql
#使用grep命令,没有找到create相关语句,表示没有数据结构。
 grep "CREATE" atguigu_no_create_info_bak.sql 

2.8 备份中包含存储过程、函数、事件

mysqldump备份默认是不包含存储过程,自定义函数及事件的。可以使用 --routines 或 -R 选项来备份存储过程及函数,使用 --events 或 -E 参数来备份事件。


举例:备份整个atguigu库,包含存储过程及事件:


使用下面的SQL可以查看当前库有哪些存储过程或者函数

SELECT SPECIFIC_NAME,ROUTINE_TYPE ,ROUTINE_SCHEMA FROM information_schema.Routines WHERE ROUTINE_SCHEMA="atguigu";
/*
+---------------  +-------------- +---------------- +
| SPECIFIC_NAME | ROUTINE_TYPE  | ROUTINE_SCHEMA |
+---------------  +-------------- +---------------- +
| rand_num      | FUNCTION  | atguigu |
| rand_string | FUNCTION  | atguigu |
| BatchInsert | PROCEDURE | atguigu |
| insert_class  | PROCEDURE | atguigu |
| insert_order  | PROCEDURE | atguigu |
| insert_stu  | PROCEDURE | atguigu |
| insert_user | PROCEDURE | atguigu |
| ts_insert     | PROCEDURE | atguigu |
+---------------  +-------------- +---------------- +
9 rows in set (0.02 sec)
*/

下面备份atguigu库的数据,函数以及存储过程。

mysqldump -uroot -p -R -E --databases atguigu > fun_atguigu_bak.sql 

查询备份文件中是否存在函数,如下所示,可以看到确实包含了函数。

grep -C 5 "rand_num" fun_atguigu_bak.sql
--
--
--  Dumping routines for database 'atguigu'
--  
/*!50003 DROP FUNCTION IF EXISTS `rand_num` */;
/*!50003 SET @saved_cs_client = @@character_set_client */ ; /*!50003 SET @saved_cs_results = @@character_set_results */ ; /*!50003 SET @saved_col_connection = @@collation_connection */ ; /*!50003 SET character_set_client = utf8mb3 */ ; /*!50003 SET character_set_results = utf8mb3 */ ; /*!50003 SET collation_connection = utf8_general_ci */ ; /*!50003 SET @saved_sql_mode = @@sql_mode */ ; /*!50003 SET sql_mode =
'ONLY_FULL_GROUP_BY,STRICT_TRANS_TABLES,NO_ZERO_IN_DATE,NO_ZERO_DATE,ERROR_FOR_DIVISIO N_BY_ZERO,NO_ENGINE_SUBSTITUTION' */ ;
DELIMITER ;;
CREATE DEFINER=`root`@`%` FUNCTION `rand_num`(from_num BIGINT ,to_num BIGINT) RETURNS bigint
BEGIN
DECLARE i BIGINT DEFAULT 0;
SET i = FLOOR(from_num +RAND()*(to_num - from_num+1)) ;
RETURN i;
END ;;
--
BEGIN
DECLARE i INT DEFAULT 0;
SET autocommit = 0;
REPEAT
SET i = i + 1;
INSERT INTO class ( classname,address,monitor ) VALUES (rand_string(8),rand_string(10),rand_num());
UNTIL i = max_num
END REPEAT;
COMMIT;
END ;;
DELIMITER ;
--
BEGIN
DECLARE i INT DEFAULT 0;
SET autocommit = 0; #设置手动提交事务
REPEAT  #循环
SET i = i + 1;  #赋值
INSERT INTO order_test (order_id, trans_id ) VALUES
(rand_num(1,7000000),rand_num(100000000000000000,700000000000000000));
UNTIL i = max_num
END REPEAT;
COMMIT; #提交事务
END ;;
DELIMITER ;
--
BEGIN
DECLARE i INT DEFAULT 0;
SET autocommit = 0; #设置手动提交事务
REPEAT  #循环
SET i = i + 1;  #赋值
INSERT INTO student (stuno, name ,age ,classId ) VALUES ((START+i),rand_string(6),rand_num(),rand_num()); UNTIL i = max_num
END REPEAT;
COMMIT; #提交事务
END ;;
DELIMITER ;
--
BEGIN
DECLARE i INT DEFAULT 0;
SET autocommit = 0;
REPEAT
SET i = i + 1;
INSERT INTO `user` ( name,age,sex ) VALUES ("atguigu",rand_num(1,20),"male"); UNTIL i = max_num
END REPEAT;
COMMIT;
END ;;
DELIMITER ;
相关文章
|
2天前
|
关系型数据库 MySQL Shell
备份 MySQL 的 shell 脚本(mysqldump版本)
【4月更文挑战第28天】
9 0
|
1天前
|
弹性计算 关系型数据库 MySQL
|
2天前
|
弹性计算 关系型数据库 MySQL
备份MySQL(mysqldump 版本)
【4月更文挑战第29天】
7 0
|
5天前
|
SQL 调度 数据库
【Database】Sqlserver如何定时备份数据库和定时清除
【Database】Sqlserver如何定时备份数据库和定时清除
15 2
|
7天前
|
监控 关系型数据库 MySQL
Percona Xtrabackup快速备份MySQL
Percona Xtrabackup快速备份MySQL
|
SQL Java 数据库连接
MySQL---数据库从入门走向大神系列(十五)-Apache的DBUtils框架使用
MySQL---数据库从入门走向大神系列(十五)-Apache的DBUtils框架使用
136 0
MySQL---数据库从入门走向大神系列(十五)-Apache的DBUtils框架使用
|
SQL 关系型数据库 MySQL
MySQL---数据库从入门走向大神系列(六)-事务处理与事务隔离(锁机制)
MySQL---数据库从入门走向大神系列(六)-事务处理与事务隔离(锁机制)
102 0
MySQL---数据库从入门走向大神系列(六)-事务处理与事务隔离(锁机制)
|
存储 SQL 关系型数据库
MySQL---数据库从入门走向大神系列(五)-存储过程
MySQL---数据库从入门走向大神系列(五)-存储过程
111 0
MySQL---数据库从入门走向大神系列(五)-存储过程
|
数据库
MySQL---数据库从入门走向大神系列(四)-子查询、表与表之间的关系(3)
MySQL---数据库从入门走向大神系列(四)-子查询、表与表之间的关系
166 0
MySQL---数据库从入门走向大神系列(四)-子查询、表与表之间的关系(3)
|
SQL 关系型数据库 MySQL
MySQL---数据库从入门走向大神系列(二)-用Java对MySQL进行增删改查
MySQL---数据库从入门走向大神系列(二)-用Java对MySQL进行增删改查
179 0
MySQL---数据库从入门走向大神系列(二)-用Java对MySQL进行增删改查