大数据运维之MySQL备份及恢复

本文涉及的产品
RDS MySQL Serverless 基础系列,0.5-2RCU 50GB
云数据库 RDS MySQL,集群系列 2核4GB
推荐场景:
搭建个人博客
云数据库 RDS PostgreSQL,集群系列 2核4GB
简介: 能够防止由于机械故障以及人为误操作带来的数据丢失,例如将数据库文件保存在了其它地方。 冗余: 数据有多份冗余,但不等备份,只能防止机械故障还来的数据丢失,例如主备模式、数据库集群。

一、MySQL备份概述


1、为什么要备份


能够防止由于机械故障以及人为误操作带来的数据丢失,例如将数据库文件保存在了其它地方。  冗余:  数据有多份冗余,但不等备份,只能防止机械故障还来的数据丢失,例如主备模式、数据库集群。


2、备份必须重视的内容


备份内容 databases Binlog my.conf


所有备份数据都应放在非数据库本地,而且建议有多份副本。测试环境中做日常恢复演练,恢复较备份更为重要。


3、备份过程中必须考虑因素:

数据的一致性


服务的可用性


4、MySQL 备份类型


1、物理备份


对数据库操作系统的物理文件(如数据文件、日志文件等)的备份。物理备份又可分为脱机备份(冷备  份)和联机备份(热备份)。这种类型的备份适用于出现问题时需要快速恢复的大型重要数据库。


1、热备(hot backup)


在线备份,数据库处于运行状态,这种备份方法依赖于数据库的日志文件


对应用基本无影响(应用程序读写不会阻塞,但是性能还是会有下降,所以尽量不要在主上做备份,在 从库上做)


2、冷备(cold backup)


备份数据文件,需要停机,是在关闭数据库的时候进行的


备份 datadir 目录下的所有文件


3、温备(warm backup)


针对myisam的备份(myisam不支持热备),备份时候实例只读不可写,数据库锁定表格(不可写入 但可读)的状态下进行的


对应用影响很大


通常加一个读锁


2、逻辑备份


对数据库逻辑组件(如表等数据库对象)的备份,表示为逻辑数据库结构create database、createtable等语句)和内容(insert  语句或分割文本文件)的信息。这种类型的备份适用于可以编辑数据值或表结构较小的数据量,或者在不同机器体系结构上重新创建数据。


3、物理和逻辑备份的区别


-

逻辑备份

物理备份

备份方式


备份数据库逻辑内容

备份数据库物理文件

优点

备份文件相对较小,只备份表中的数据与结构

恢复速度比较快(物理文件恢复基本已经完成恢复)

缺点

恢复速度较慢(需要重建索引,存储过程等)

备份文件相对较大(备份表空间,包含数据与索引,碎片)

对业务影响

缓冲池污染(把所有数据读一遍,读到bp ),I/O负载加大

I/O负载加大

代表工具

mysqldump

ibbackupxtrabackup, mysqlbackup


4、备份方式的选择


从以下几个维度考虑备份方式备份速度


恢复速度


备份大小对业务影响


5、MySQL 备份工具


1、ibbackup


官方备份工具收费


物理备份


2、xtrabackup


开源社区备份工具


开源免费,上面那东西的免费版本(老版本有问题,备份出来的数据可能有问题) 物理备份


3、mysqldump


官方自带备份工具 开源免费逻辑备份(速度慢)


不阻塞dml,阻塞ddl


4、mysqlbackup


mysql 官方备份工具


innodb 引擎的表mysqlbackup可以进行热备非innodb表mysqlbackup就只能温备


物理备份,备份还原速度快适合大规模数据使用


6、MySQL 备份策略


完全备份


每次对数据进行完整的备份,即对整个数据库的备份、数据库结构和文件结构的备份,保存的是备份完  成时刻的数据库,是差异备份与增量备份的基础。


优点:备份与恢复操作简单方便.  缺点:数据存在大量的重复;占用大量的空间;备份与恢复时间长。差异备份


备份那些自从上次完全备份之后被修改过的所有文件,备份的时间起点是从上次完整备份起,备份数据  量会越来越大。恢复数据时,只需恢复上次的完全备份与最近的一次差异备份。


b136075c03484ce5a1658bbe5f37065d.png


增量备份


只有那些在上次完全备份或者增量备份后被修改的文件才会被备份。以上次完整备份或上次的增量备份  的时间为时间点,仅备份这之间的数据变化,因而备份的数据量小,占用空间小,备份速度快。但恢复  时,需要从上一次的完整备份起到最后一次增量备份依次恢复,如中间某次的备份数据损坏,将导致数  据的丢失。


321f172ec3b34cc38810db37f36a4d50.png


二、MySQL逻辑备份mysqldump


1、mysqldump 简介


mysqldump 是 MySQL 自带的逻辑备份工具。可以保证数据的一致性和服务的可用性。


它的备份原理是通过协议连接到 MySQL 数据库,将需要备份的数据查询出来,将查询出的数据转换成对应的 insert 语句,当我们需要还原这些数据时,只要执行这些 insert 语句,即可将对应的数据还原。


2、备份命令


1、命令格式

mysqldump [选项] 数据库名 [表名] > 脚本名



mysqldump [选项] --数据库名 [选项 表名] > 脚本名



mysqldump [选项] --all-databases [选项] > 脚本名


2、选项说明


参数名

缩写

含义

--host

-h

服务器IP地址

--port

-P

服务器端口号

--user

-u

MySQL 用户名

--pasword

-p

MySQL 密码

--databases

-B

指定要备份的数据库

--all-databases

-A

备份mysql服务器上的所有数据库

--compact

压缩模式,产生更少的输出

--comments

添加注释信息

--complete-insert

输出完成的插入语句

--lock-tables

备份前,锁定所有数据库表

--no-create-db/--no-create- info

禁止生成创建数据库语句

--force

当出现错误时仍然继续备份操作

--default-character-set

指定默认字符集

--add-locks

备份数据库表时锁定数据库表

-single-transaction

保证数据的一致性和服务的可用性

--master-data=1|2

通常等于1,记录binlog日志位置与文件名,追加至备份文件中

--flush-logs

-F

备份之前刷新日志

--events

-E

备份事件调度器代码

--triggers

-T

备份触发器

--routines

-R

备份存储过程和存储函数


3、备份实例


备份所有数据库:


[root@qfedu.com ~]# mysqldump -uroot -p --all-databases >/backup/mysqldump/all.db


备份指定数据库:


[root@qfedu.com ~]# mysqldump -uroot -p test > /backup/mysqldump/test.db


备份指定数据库指定表(多个表以空格间隔)


[root@qfedu.com ~]# mysqldump -uroot -p mysql db event >/backup/mysqldump/2table.db


备份指定数据库排除某些表


[root@qfedu.com ~]# mysqldump -uroot -p test --ignore-table=test.t1 --ignore- table=test.t2 > /backup/mysqldump/test2.db


4、还原命令


1、系统行命令


[root@qfedu.com ~]# mysqladmin -uroot -p create db_name
[root@qfedu.com ~]# mysql -uroot -p db_name < /backup/mysqldump/db_name.db


在导入备份数据库前,db_name如果没有,是需要创建的;  而且与db_name.db中数据库名是一样的才可以导入。


2、soure 方法


mysql > use db_name
mysql > source /backup/mysqldump/db_name.db


3、MySQL 逻辑备份


1、MySQL 环境


系统版本

mysql版本

安装方式

centos7

5.7.28

YUM安装



2、完整备份与恢复


1、修改配置文件开启二进制日志


[root@qfedu.com ~]# vim /etc/my.cnf 
[mysqld]
basedir=/soft/mysql 
datadir=/soft/mysql/data 
default_password_lifetime=0
server-id = 2 # id是做标识,随便填写
log-bin=/var/log/mysql/bin-log  # 设置二进制日志存放的位置


2、创建存放二进制日志文件的目录并赋权限


[root@qfedu.com ~]# mkdir -p /var/log/mysql 
[root@qfedu.com ~]# chown -R mysql:mysql /var/log/mysql


3、创建全量备份文件存放目录并赋权限


[root@qfedu.com ~]# mkdir /backup/mysql -p 
[root@qfedu.com ~]# chown -R mysql:mysql /backup/mysql/


4、重启数据库


[root@qfedu.com ~]# systemctl restart mysqld


5、进入mysqld创建一个数据库 test1


[root@qfedu.com ~]# mysql -uroot -hlocalhost -p'‘Qfedu.123com’' mysql> create database test1;
mysql> show databases;
+--------------------+
| Database  |
+--------------------+
| information_schema |
| mysql |
| performance_schema |
| sys |
| test1 |
+--------------------+


6、进行全量备份


[root@localhost ~]# mysqldump -uroot -hlocalhost -p'Qfedu.123com' -P3306 --all- databases --triggers --routines --events --single-transaction --master-data=1 -- flush-logs --set-gtid-purged=OFF > /backup/mysql/$(date +%F%H)-mysql-all.sql


7、删除数据库文件


[root@qfedu.com ~]# systemctl stop mysqld
[root@qfedu.com ~]# rm -rf /var/lib/mysql/*


8、向全量备份文件里面追加不记录二进制日志的命令


[root@qfedu.com ~]# sed -i '23a SET sql_log_bin=0;' /backup/mysql/2019-11-2810- mysql-all.sql


向全量备份文件里面追加不记录二进制日志的命令的原因是因为我们在恢复的时候要重新执行一次


SQL语句,这个语句没有记录的必要,如果记录的话还可能会导致恢复失败。


9、重启初始化数据库、启动数据库、并修改密码


[root@qfedu.com ~]# systemctl restart mysqld
[root@qfedu.com ~]# mysql -uroot -hlocalhost -p'‘Qfedu.123com’' [root@qfedu.com ~]# grep 'temporary password' /var/log/mysqld.log [root@qfedu.com ~]# mysql -u root -p'U0ln8LE!ue=#'
mysql> alter user 'root'@'localhost' identified by 'Qfedu.123com'; mysql> show databases;
+--------------------+
| Database  |
+--------------------+
| information_schema |
| mysql |
| performance_schema |
| sys |
+--------------------+


由于这是一个新的数据库,里面只有默认的库,并没有 test1 数据库。


10、导入全备的数据


[root@qfedu.com ~]# mysql -u root -p'Qfedu.123com' < /backup/mysql/2019-11-2810- mysql-all.sql
[root@qfedu.com ~]# mysql -uroot -p'Qfedu.123com' mysql>  set sql_log_bin=1;
Query OK, 0 rows affected (0.00 se mysql> show databases;
+--------------------+
| Database  |
+--------------------+
| information_schema |
| mysql |
| performance_schema |
| sys |
| test1 |
+--------------------+


在数据库内部也可以进行恢复


mysql> set  sql_log_bin=0;
mysql> source /backup/mysql/2019-11-2810-mysql-all.sql mysql> set sql_log_bin=1;
Query OK, 0 rows affected (0.00 se


导入之后当前的密码会不变,当进入数据库 flush privileges 之后,密码又恢复到备份时的密码


mysql> flush privileges


3、增量备份与恢复


备份与恢复环境


数据库完整备份+数据库增量备份


新建数据表, 进行全量备份, 随着时间推移, 数据库突然奔溃


1、备份之前


mysql> create database test2;
mysql> create table test2.t1 (id int,name varchar(20)); mysql> insert into test2.t1 values (1,"test21"); mysql> insert into test2.t1 values (2,"test22"); mysql> select * from test2.t1;
+------+--------+
| id  | name  |
+------+--------+
| 1 | test21 |
| 2 | test22 |
+------+--------+
2 rows in set (0.00 sec)


2、基于当前状态做一次全备


[root@localhost ~]# mysqldump -uroot -hlocalhost -p'Qfedu.123com' -P3306 --all- databases --triggers --routines --events --single-transaction --master-data=1 -- flush-logs --set-gtid-purged=OFF > /backup/mysql/$(date +%F%H)-mysql-all.sql


3、进入数据库再插入数据


mysql> insert into test2.t1 values (3,"test23");
mysql> insert into test2.t1 values (5,"tt");
mysql> select * from test2.t1;


4、模拟数据库崩溃


重启初始化,启动数据库,更改默认密码


[root@qfedu.com ~]# systemctl stop mysqld [root@qfedu.com ~]# rm -rf /var/lib/mysql/* [root@qfedu.com ~]# systemctl start mysqld
[root@qfedu.com ~]# grep 'temporary password' /var/log/mysqld.log [root@qfedu.com ~]# mysql -u root -p'U0ln8LE!ue=#'
mysql> alter user 'root'@'localhost' identified by 'Qfedu.123com'; mysql> \q
[root@qfedu.com ~]# mysql -uroot -p'Qfedu.123com' mysql> show databases;
+--------------------+
| Database  |
+--------------------+
| information_schema |
| mysql |
| performance_schema |
| sys |
+--------------------+
4 rows in set (0.00 sec)


5、恢复全量数据


[root@qfedu.com ~]# sed -i "23aSET sql_log_bin=0;" /backup/mysql/2019-11-2810- mysql-all.sql
[root@qfedu.com ~]# mysql -uroot -p'Qfedu.123com' < /backup/mysql/2019-11-2810- mysql-all.sql
[root@qfedu.com ~]# mysql -u root -p'Qfedu.123com' -e "select * from test2.t1"
+------+--------+
| id  | name  |
+------+--------+
| 1 | test21 |
| 2 | test22 |
+------+--------+


6、恢复增量备份


1、获取全备截至点


查看一下全量备份,备份到哪个点了,如下所示是154这个点,000001这个日志文件**


[root@qfedu.com ~]# sed -n '22p' /backup/mysql/2019-11-2810-mysql-all.sql CHANGE MASTER TO MASTER_LOG_FILE='bin-log.000001', MASTER_LOG_POS=154;

全量仅备份到了154这个点,154后面的点全备文件里面就没有了,需要去000002以后的二进制文  件里面找


2、根据 MASTER_LOG_POS 恢复增量的数据


[root@qfedu.com mysql]# pwd
/log/mysql
[root@qfedu.com mysql]# mysqlbinlog --start-position=154 bin-log.000001 bin- log.000002 bin-log.000003 bin-log.000003 | mysql -uroot -pQfedu.123com; [root@mysql02 ~]# mysql -u root -pQfedu.123com -e "select * from test2.t1"

4、误操作删除了库(练习)


新来的开发删了库,这件事不想再回忆了,以后打死也不会把数据库的 root 权限轻易给别人了。今天把当时的场景用虚拟机还原一下,然后复现一下数据恢复的过程,就当是个总结吧!说多了都  是泪啊~


1、模拟环境准备


[root@qfedu.com ~]# mysql -uroot -p'Qfedu.123com' mysql> create database test2db;
mysql> use test2db;
mysql> create table t1 (id int,name varchar(20)); mysql> insert into t1 values (1,"ccr");
mysql> insert into t1 values (2,"tfr"); mysql> select * from t1;
+------+------+
| id  | name |
+------+------+
| 1 | ccr |
| 2 | tfr |
+------+------+


2、全备


[root@qfedu.com ~]# mysqldump -uroot -hlocalhost -p'Qfedu.123com' -P3306 --all- databases --triggers --routines --events --single-transaction --master-data=1 -- flush-logs --set-gtid-purged=OFF > /backup/mysql/$(date +%F%H)-mysql-all.sql


3、再次插入数据


[root@qfedu.com ~]# mysql -uroot -p'Qfedu.123com'
mysql> insert into test2db.t1 values(3,'tr1'),(4,'zx'),(5,'wq'),(6,'tj'), (7,'gwt');
mysql> select * from test2db.t1;
+------+------+
| id  | name |
+------+------+
| 1 | ccr |
| 2 | tfr |
| 3 | tr1 |
| 4 | zx  |
| 5 | wq  |
| 6 | tj  |
| 7 | gwt |
+------+------+


4、开发误操作


mysql> delete from test2db.t1 where id = '2';
mysql> drop database test2db;


5、恢复全备


[root@mysql02 ~]# sed -i '23aSET sql_log_bin=0;' /backup/mysql/2019-11-2812- mysql-all.sql
[root@mysql02 ~]# mysql -u root -p'Qfedu.123com' < /backup/mysql/2019-11-2812- mysql-all.sql
[root@mysql02 ~]# mysql -u root -p'Qfedu.123com' -e "select * from test2db.t1"
+------+------+
| id  | name |
+------+------+
| 1 | ccr |
| 2 | tfr |
+------+------+


6、跳过 DELETE 和 DROP 语句


下面的操作就要小心翼翼了,不能一下子把二进制日志里面全备以后的操作全部恢复,一旦全部恢  复了,那开发删除操作也会恢复,我们只能跳过误操作的地方。


[root@qfedu.com ~]# sed -n '22p' /backup/mysql/2019-11-2812-mysql-all.sql CHANGE MASTER TO MASTER_LOG_FILE='bin_log.000002', MASTER_LOG_POS=154;
[root@qfedu.com ~]# ls /log/mysql/  #全备之后只有一个` bin_log.000002`二进程日志文件
[root@mysql02 ~]# mysql -u root -p'Qfedu.123com' mysql> show binlog events in 'bin-log.000002';
+----------------+-----+----------------+-----------+-------------+-------------
--------------------------+
| bin-log.000008 |  4 | Format_desc | 2 | 123 | Server ver: 5.7.29-log, Binlog ver: 4 |
| bin-log.000008 | 123 | Previous_gtids | 2 | 154 |
|
| bin-log.000008 | 154 | Anonymous_Gtid | 2 | 219 | SET @@SESSION.GTID_NEXT= 'ANONYMOUS'  |
| bin-log.000008 | 219 | Query  | 2 | 294 | BEGIN
|
| bin-log.000008 | 294 | Table_map  | 2 | 345 | table_id:
179 (test2db.t1)  |
| bin-log.000008 | 345 | Write_rows | 2 | 422 | table_id:
179 flags: STMT_END_F |
| bin-log.000008 | 422 | Xid  | 2 | 453  |  COMMIT   /* xid=980 */  |
| bin-log.000008 | 453 | Anonymous_Gtid | 2 | 518 | SET @@SESSION.GTID_NEXT= 'ANONYMOUS'  |
| bin-log.000008 | 518 | Query  | 2 | 593 | BEGIN
|
| bin-log.000008 | 593 | Table_map  | 2 | 644 | table_id:
179 (test2db.t1)  |
| bin-log.000008 | 644 | Delete_rows  | 2 | 688 | table_id:
179 flags: STMT_END_F |
| bin-log.000008 | 688 | Xid  | 2 | 719  |  COMMIT   /* xid=982 */  |
| bin-log.000008 | 719 | Anonymous_Gtid | 2 | 784 | SET @@SESSION.GTID_NEXT= 'ANONYMOUS'  |
| bin-log.000008 | 784 | Query    | 2 | 885 | drop database test2db |
+----------------+-----+----------------+-----------+-------------+-------------
--------------------------+
[root@qfedu.com ~]# mysqlbinlog --start-position=154 --stop-position=453  bin- log.000002 | mysql -p'Qfedu.1234com'
[root@qfedu.com ~]# mysql -uroot -p'Qfedu.123com' -e "select * from test2db.t1"
+------+------+
| id  | name |
+------+------+
| 1 | ccr |
| 2 | tfr |
| 3 | tr1 |
| 4 | zx  |
| 5 | wq  |
| 6 | tj  |
| 7 | gwt |
+------+------+


相关实践学习
如何在云端创建MySQL数据库
开始实验后,系统会自动创建一台自建MySQL的 源数据库 ECS 实例和一台 目标数据库 RDS。
全面了解阿里云能为你做什么
阿里云在全球各地部署高效节能的绿色数据中心,利用清洁计算为万物互联的新世界提供源源不断的能源动力,目前开服的区域包括中国(华北、华东、华南、香港)、新加坡、美国(美东、美西)、欧洲、中东、澳大利亚、日本。目前阿里云的产品涵盖弹性计算、数据库、存储与CDN、分析与搜索、云通信、网络、管理与监控、应用服务、互联网中间件、移动服务、视频服务等。通过本课程,来了解阿里云能够为你的业务带来哪些帮助 &nbsp; &nbsp; 相关的阿里云产品:云服务器ECS 云服务器 ECS(Elastic Compute Service)是一种弹性可伸缩的计算服务,助您降低 IT 成本,提升运维效率,使您更专注于核心业务创新。产品详情: https://www.aliyun.com/product/ecs
目录
相关文章
|
1月前
|
分布式计算 关系型数据库 MySQL
大数据-88 Spark 集群 案例学习 Spark Scala 案例 SuperWordCount 计算结果数据写入MySQL
大数据-88 Spark 集群 案例学习 Spark Scala 案例 SuperWordCount 计算结果数据写入MySQL
49 3
|
1月前
|
消息中间件 分布式计算 关系型数据库
大数据-140 - ClickHouse 集群 表引擎详解5 - MergeTree CollapsingMergeTree 与其他数据源 HDFS MySQL
大数据-140 - ClickHouse 集群 表引擎详解5 - MergeTree CollapsingMergeTree 与其他数据源 HDFS MySQL
44 0
|
1月前
|
消息中间件 关系型数据库 MySQL
大数据-117 - Flink DataStream Sink 案例:写出到MySQL、写出到Kafka
大数据-117 - Flink DataStream Sink 案例:写出到MySQL、写出到Kafka
133 0
|
8天前
|
关系型数据库 MySQL Linux
Linux环境下MySQL数据库自动定时备份实践
数据库备份是确保数据安全的重要措施。在Linux环境下,实现MySQL数据库的自动定时备份可以通过多种方式完成。本文将介绍如何使用`cron`定时任务和`mysqldump`工具来实现MySQL数据库的每日自动备份。
26 3
|
8天前
|
监控 关系型数据库 MySQL
Linux环境下MySQL数据库自动定时备份策略
在Linux环境下,MySQL数据库的自动定时备份是确保数据安全和可靠性的重要措施。通过设置定时任务,我们可以每天自动执行数据库备份,从而减少人为错误和提高数据恢复的效率。本文将详细介绍如何在Linux下实现MySQL数据库的自动定时备份。
21 3
|
22天前
|
运维 关系型数据库 MySQL
运维|MySQL 数据库被黑,心力交瘁
前一阵有一个测试用的 MySQL 数据库被黑了,删库勒索的那种,这里记录一下事情经过,给自己也敲个警钟。
31 2
|
30天前
|
SQL 运维 关系型数据库
MySQL 运维 SQL 备忘
MySQL 运维 SQL 备忘录
46 1
|
9天前
|
SQL 关系型数据库 MySQL
go语言数据库中mysql驱动安装
【11月更文挑战第2天】
23 4
|
7天前
|
SQL 关系型数据库 MySQL
12 PHP配置数据库MySQL
路老师分享了PHP操作MySQL数据库的方法,包括安装并连接MySQL服务器、选择数据库、执行SQL语句(如插入、更新、删除和查询),以及将结果集返回到数组。通过具体示例代码,详细介绍了每一步的操作流程,帮助读者快速入门PHP与MySQL的交互。
22 1
|
16天前
|
监控 关系型数据库 MySQL
数据库优化:MySQL索引策略与查询性能调优实战
【10月更文挑战第27天】本文深入探讨了MySQL的索引策略和查询性能调优技巧。通过介绍B-Tree索引、哈希索引和全文索引等不同类型,以及如何创建和维护索引,结合实战案例分析查询执行计划,帮助读者掌握提升查询性能的方法。定期优化索引和调整查询语句是提高数据库性能的关键。
82 1