MySQL的数据备份与恢复

Posted Howl

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了MySQL的数据备份与恢复相关的知识,希望对你有一定的参考价值。

Thu Oct 21 13:10:35 CST 2021 —— 记录下高光的删库瞬间,后面给恢复了



1. 什么是数据库备份

备份就是在数据库发生宕机的情况下保证数据不丢失,或者最小程度丢失的解决方法。mysql 提供了 mysqldump、ibbackup、replication 工具来备份,当然也有第三方工具,如 xtrabacup、LVM快照等


1.1 备份分类

下面的备份分类中,并不是所有都适配了 Mysql 和 Innodb引擎,所以部分是没有真正的方案,也有些是交叉分类的(比如在热备又在逻辑文件中)

按备份类型:

  • 热备:在数据库运行过程中直接备份
  • 冷备:在数据库停止的情况下备份,一般直接复制相关的物理文件即可
  • 温备:在数据库运行过程中备份,但对数据库操作有影响,如加个全局读锁以保证备份数据一致性

按备份文件:

  • 逻辑文件:指备份出的文件可读,一般指 SQL 语句(适用库升级,迁移,但恢复时间较长需要执行 SQL 语句)
  • 物理文件:指复制数据库的物理文件

按备份内容:

  • 日志备份:主要备份 bin-log 日志,然后 replay 来完成 point-in-time
  • 完全备份:对数据库一个完整的备份
  • 增量备份:在上次完全备份的基础上对更改部分进行备份(MySQL 没真正的增量备份,一般通过 bin-log 完成,要借助第三方工具才能实现)


1.2 备份的一致性

数据库备份的一致性要求在备份的时候数据在这一时间点上是一致的,比如银行转账,A 转给 B 现金100 RMB,这个事务过程先扣 A 100元,再去 B 加100元,确保前后数据一致,否则会发生恢复数据后金钱对不上的情况

对于 Innodb 引擎来说,因为其支持 MVCC 功能,所以可以先开启一个事务,然后导出一组相关的表,最后提交来实现一致的备份,当然隔离级别要设置为 REPEATABLE READ

对于 mysqldump 备份工具可以添加 --single-transaction 选项来实现备份一致性(开启事务,设置隔离级别)

下面来说明备份的途径







2. mysqldump

mysqldump 是属于逻辑备份,也是最常见的备份工具了,缺点在于备份和恢复速度不是特别快


2.1 备份

$mysqldump [arguments] > dump.sql

--all-databases:备份所有数据库
--databases:备份指定数据库
--single-transaction:备份一致性
--add-drop-database:添加语句 DROP DATABASE IF EXISTS(默认是 CREATE DATABASE IF NOT EXISTS)
--hex-blob:binary、blog、bit是十六进制不可见,会以十六进制来展示


2.2 恢复

mysqldump 导出的是逻辑文件,即 SQL 语句,可以直接执行

  • source /home/mysql/backup.sql
  • mysql -uroot -p < backup.sql

mysqldump 导出不包括视图,所以得自己手动导出







3. bin-log

bin-log 是 Mysql 的日志文件


3.1 备份

先要在 my.cnf 中增加下面一句话,之后会自动记录,名字按 name.00001 格式来递增滚动

[mysqld]
# 不赋值默认为主机名
log-bin=my-binlog-name


3.2 恢复

使用 Mysql 自带的 mysqlbinlog 命令,其作用将二进制的记录转成可见的文本格式(即 SQL 语句),然后交给 mysql 执行可恢复数据

$mysqlbinlog [option] log_file
--start-position:指定某个偏移量来恢复
--stop-positon:指定某个偏移量来恢复

$mysqlbinlog binlog.000001 > backup.sql
$source backup.sql

在备份binlog之前,先 FLUSH LOGS,会自动滚动文件,备份滚动后的文件即可







4. 冷备

Innodb 冷备是最简单的,通常只需写个脚本来复制 MySQL 的文件,然后将这些文件放到对应数据库的目录下即可实现数据恢复:

  • .frm结构文件
  • .idb独立表空间文件
  • redo重做日志文件
  • 共享表空间文件
  • my.cnf配置文件

缺点是:冷备文件比逻辑文件大,因为存放了很多其他数据,而且不能轻易跨平台(SQL 是标准语句,可跨平台)


4.1 备份

首先关闭数据库,然后执行下面的命令

# 1. 查看mysql数据存放的目录
# 	 /var/lib/mysql/data
$show variables like "%datadir%"

# 2. 备份物理文件
$cd /var/lib/mysql/
$tar -zcvf mysqlDataBacku.tar.gz  data/


4.2 恢复

# 1. 恢复只需将上面的包解压到对应数据库的数据存放目录下
# 2. 恢复前将原数据备份一下
# 3. 重启mysql即可
$cd /var/lib/mysql/
$mv data/ data_20211027/
$tar -zxvf mysqlDataBacku.tar.gz






5. XtraBackup

Innodb 官方有提供热备工具 ibbackup 的收费软件。不过可以借用 XtraBackup 开源的热备工具,备份和恢复速度比 mysqldump 快,具体的安装过程这里不说明了


5.1 全量备份

# 1. 备份
$innobackupex 
	--defaults-file=/etc/my.cnf  # 有数据存放地址
	--user=root 
	--password="123456" 
	--databases=test
	--backup /mysqlBackup/		 # 目录下生成日期命名的目录

# 2. 备份一致性,回滚未提交的事务及同步已经提交的事务至数据文件使数据文件处于一致性
$innobackupex 
	--apply-log /mysqlBackup/2021-10-27_20-09-29/

# 3. 恢复,要保证原数据目录是空的,因为目录里有binlog日志
$innobackupex 
	--defaults-file=/etc/my.cnf 
	--copy-back /mysqlBackup/2021-10-27_20-09-29/


5.2 增量备份

当数据量比较大的时候(10G),每次都全量备份不太实际,可采用周末全量备份,其余时间增量备份的策略

原理:

  • 首先执行完全备份,并记录下此时检查点 LSN
  • 随后的增量备份中,比较表空间每页 LSN 是否大于上次备份的检查点 LSN,是则备份该页并更新当前检查点 LSN

# 1. 先做一次全量备份,不指定数据库
$innobackupex 
	--defaults-file=/etc/my.cnf
	--user=root 
	--password="123456" 
	--backup /mysqlBackup/
	
# 2. 增量备份
$innobackupex 
 	--defaults-file=/etc/my.cnf 
 	--user=root 
 	--password=123456 
 	--incremental /backup/ 			# 增量备份文件目录
	--incremental-basedir=/mysqlBackup/2021-10-27_20-09-29/		# 上次全备或增量备份的目录


# 3. 恢复,保证原数据目录为空
$innobackupex 
	--apply-log /mysqlBackup/2021-10-27_20-09-29/
	--incremental-dir=/mysqlBackup/2021-10-28_20-09-29/






6. LVM

Mysql 本身不知道 LVM 快照功能,而是通过文件系统来实现的。备份的前提是所以数据库文件放入同一个文件分区中,然后通过命令 lvcreate 来创建一个快照,需要恢复时将这个还原到这个快照即可,采用了写时复制的策略





7. 备份脚本

#!/bin/bash

#保存备份个数,备份31天数据
number=31

#备份保存路径
backup_dir=/root/mysqlbackup

#日期
dd=`date +%Y-%m-%d-%H-%M-%S`

#备份工具
tool=mysqldump

#用户名
username=root

#密码
password=TankB214

#将要备份的数据库
database_name=edoctor

#如果文件夹不存在则创建
if [ ! -d $backup_dir ];
then     
    mkdir -p $backup_dir;
fi

#简单写法 mysqldump -u root -p123456 users > /root/mysqlbackup/users-$filename.sql
$tool -u $username -p$password $database_name > $backup_dir/$database_name-$dd.sql

#写创建备份日志
echo "create $backup_dir/$database_name-$dd.dupm" >> $backup_dir/log.txt

#找出需要删除的备份
delfile=`ls -l -crt $backup_dir/*.sql | awk \'{print $9 }\' | head -1`

#判断现在的备份数量是否大于$number
count=`ls -l -crt $backup_dir/*.sql | awk \'{print $9 }\' | wc -l`

if [ $count -gt $number ]
then
  #删除最早生成的备份,只保留number数量的备份
  rm $delfile
  #写删除文件日志
  echo "delete $delfile" >> $backup_dir/log.txt
fi

脚本抄袭 程序猿DD






参考:

《MySQL技术内幕 InnoDB存储引擎》

MySQL备份与恢复

一.数据备份的重要性

(1)在生产环境中,数据的安全性至关重要
(2)任何数据的丢失都可能产生严重的后果
(3)备份的主要目的是灾难恢复
(4)造成数据丢失的原因
①程序错误
②人为操作错误
③运算错误
④磁盘故障
⑤灾难(如火灾,地震)和盗窃

二.MySQL日志

2.1日志保存位置

MysQL的日志默认保存位置为/usr/local/mysql/ data

2.2 日志类型与作用

1 .redo 重做日志:达到事务一致性(每次重启会重做)
作用:确保日志的持久性,防止在发生故障,脏页未写入磁盘。重启数据库会进行redolog执行重做,达到事务一致性
2.undo回滚日志
作用:保证数据的原子性,记录事务发生之前的一个版本,用于回滚,innodb事务可重复读和读取已提交。隔离级别就是通过mvcc+undo实现
3.errorlog错误日志
作用:Mysql本身启动,停止,运行期间发生的错误信息
4 .slow auery log 慢查询日志
作用:记录执行时间过长的sql,时间阈值可以配置,只记录执行成功
另一个作用:在于提醒优化
5.bin log二进制日志
作用:用于主从复制,实现主从同步
记录的内容是:数据库中执行的sql语句

6.relay log中继志
作用:用于数据库主从同步,将主库发来的bin log保存在本地,然后从库进行回放
7 .general log普通日志
作用:记录数据库的操作明细,默认关闭,开启后会降低数据库性能

2.3在MySQL配置文件中实现日志日志功能

vim letc/ my.cnf[
 mysqld]
#错误日志,用来记录当MySQL启动、停止或运行时发生的错误信息,默认已开启
log_error=/usr/local/mysql/data/mysql_error.log
#指定日志的保存位置和文件名

#通用查询日志,用来记录MySQL的所有连接和语句,默认是关闭的
general_log=ON
general_log_file=/usr/local/mysql/data/mysql_general.log
#二进制日志(binlog),用来记录所有更新了数据或者已经潜在更新了数据的语句,记录了数据的更改,可用于数据恢复,默认己开启
log-bin=mysql-bin

log_bin=mysql-bin


#中继日志
一般情况下它在Mysql主从同步(复制)、读写分离集群的从节点开启。主节点一般不需要这个日志


#慢查询日志,用来记录所有执行时间超过long _guery_time秒的语句,可以找到哪些查询语句执行时间长,以便提醒优化,默认是关闭的
slow_query_log=ON
slow_query_log_file=/usr/local/mysql/data/mysql_slow_query
long_query_time=5 #设置超过5秒执行的语句被记录,缺省时为10

2.4日志查询

show variables like 'general%';
#查看通用查询日志是否开启
show variables like 'log_bin%';
#查看二进制日志是否开启
show variables like '%slow% ' ;
#查看慢查询日功能是否开启
show variables like 'long_query_time' ; #查看慢查询时间设置
set global slow_query _log=ON;
#在数据库中设置开启慢查询的方法(临时)
Ps : variables表示变量 like表示模糊查询
#XXX(字段)
XXX%以XXX为开头的字段
%XXX以XXX为结尾的字段
%XXX%只要出现XXX字段的都会显示出来
XXX 精准查询

修改配置文件开启日志

vim /etc/my.cnf

log-error=/usr/local/mysql/data/mysql_error.log
log-bin=mysql-bin
slow_query_log=ON
slow_query_log_file=/usr/local/mysql/data/mysql_slow_query.log
long_query_time=5

在这里插入图片描述

#二进制日志开启后,重启mysql会在目录中查看到二进制日志(在每次重启的时候会刷新这个文件)
cd/usr/local/mysql/ data
ls
mysql-bin.000001
#开启二进制日志时会产生一个索引文件及一个索引列表
mysql-bin.index  这个会记录二进制文件的位置(二进制文件的索引)
索引文件:记录更新语句
索引文件刷新方式:
1、重启mysql的时候会更新索引文件,用于记录新的更新语句
2、刷新二进制日志

在这里插入图片描述
登录数据库查询
在这里插入图片描述

三.备份类型

3.1物理备份

数据库备份可以分为物理备份和逻辑备份。物理备份是对数据库操作系统的物理文件(如数据文件、日志文件等的备份。这种类型的备份适用于在出现问题的时候需要快速恢复的大型重要数据库。
物理备份又可以成为冷备份(脱机备份)、热备份(连接备份)和温备份
①冷备份(脱机备份):是在关闭数据库的时候进行的( t如tar方式)
②热备份(联机备份):数据库处于运行状态,依赖于数据库的日志文件(mysqldump)
③温备份:数据库锁定表格(不可写入但可读)的状态下进行备份操作

3.2逻辑备份

逻辑备份是对数据库逻辑组件的备份。表示为逻辑数据库结构
这种类型的备份适用于可以编辑数据值或表结构
从数据库的备份策略角度来看,备份又可分为完全备份、差异备份和增量备份

①完全备份
每次对数据进行完整备份,即对整个数据库、数据库结构和文件结构的备份,保存的是备份完成时刻的数据库,是差异备份与增量备份的基础完全备份的备份与恢复操作都非常简单方便,但是数据存在大量的重复并且会占用大量的磁盘空间,备份的时间也很长
优点:
备份与恢复操作简单方便
缺点:
数据存在大量的重复,占用大量的备份空间,备份与恢复时间长

②差异备份
备份那些自从上次完全备份之后被修改过的所有文件,备份的时间节点是从上次完整备份起,备份数据量会越来越大。恢复数据时只需要恢复上次的完全备份与最佳的一次差异备份
③增量备份
只有那些在上次完全备份或者增量备份后被修改的文件才会被备份以上次完整备份或上次增量备份的时间为时间点,仅备份期间内的数据变化,因而备份的数据量小,占用空间小,备份速度快。但恢复时,需要从上一次的完整备份开始到最后一次增量备份之间的所有增量依次恢复,如中间某次的备份数据损坏,将导致数据的丢失(基于上一次判断表的结果,而不是中间发生多少次的sql语句)

如何选择逻辑备份策略(频率)合理值区间?
一周一次的全备,全备的时间需要在不提供业务的时间区间进行 PM 10点、AM 5:00之间进行全备
增量:3天/2天/1天一次增量备份
差异:选择特定的场景进行备份
日积月累的情况,备份越来越多,需要做一个处理就是用NFS提供额外空间给予MySQL服务器用。

3.3常见的备份方法

1、物理冷备
备份时数据库处于关闭状态,直接打包数据库文件(tar)

备份速度快,恢复时也是最简单的
2、专用备份工具 mysqldump或mysqlhotcopy
mysqldump常用的逻辑备份工具
mysqlhotcopy 仅拥有备份MyISAM 和 ARCHIVE表

3、启用二进制日志进行增量备份
进行增量备份,需要刷新二进制日志

4、第三方工具备份
免费的MysQL热备份软件 Percona xtraBackup mysqlbackup

四.备份与恢复的相关操作

4.1物理冷备份与恢复

systemctl stop mysqld
yum install -y xz

①压缩备份

tar jcvf /opt/mysql_all_$(date +%F).tar.xz /usr/local/mysql/data;

②登录数据库,做删除test库操作,退出

drop database test;
exit
mv /usr/local/mysql/data/  /root

③解压恢复

tar jxvf /opt/mysql_all_2021-07-11.tar.xz  -C /usr/local/mysql/
mv /usr/local/mysql/usr/local/mysql/data/  /usr/local/mysql/
[root@localhost mysql]# rm -rf usr/

④重启服务,再次登录数据库

systemctl restart mysqld

在这里插入图片描述

4.2mysqldump 备份与恢复

在命令行查看库和表(可用于脚本操作,-e的方式进行交互)

[root@localhost data]# mysql -uroot -p123456 -e 'show databases;'
mysql -uroot -p123456 -e 'select * from test.info'

在这里插入图片描述
(1)、完全备份一个或多个完整的库(包括其中所有的表)

mysqldump -u root -p[密码] --databases 库名1 库名2 ...  > /备份路径/备份文件名.sql

#导出的就是数据库脚本文件
例:
mysqldump -u root -p --databases test >/opt/test.sql
#备份一个kgc库
mysqldump -u root -p --databases mysql test >/opt/mysql-test.sql 备份mysql与 test两个库
mysqldump -uroot -p123456 --databases test  > /opt/mysql_all.sql

以上是关于MySQL的数据备份与恢复的主要内容,如果未能解决你的问题,请参考以下文章

mysql备份与恢复

MySQL数据库 数据备份与恢复

详解Mysql自动备份与恢复的几种方法(图文教

MySQL备份与恢复

mysql之备份与恢复

MySQL备份与恢复