MySQL的备份和恢复


安装Xtrabackup

https://www.percona.com/

# 2.安装
[root@db02 ~]# yum localinstall -y percona-xtrabackup-24-2.4.29-1.el7.x86_64.rpm

[root@db02 ~]# innobackupex   ·	
[root@db02 ~]# xtrabackup

Xtrabackup

1)对于非innodb表(比如myisam)是直接锁表cp数据文件,属于一种温备。
2)对于innodb的表(支持事务),不锁表,cp数据页最终以数据文件方式保存下来,并且把redo和undo一并备走,属于热备方式。
3)备份/恢复时读取配置文件/etc/my.cnf

Xtrabckup 和 innobackupex区别

XtraBackup:
1)XtraBackup 是一个开源工具,专门用于 MySQL 数据库的 InnoDB 引擎的备份。它支持在线热备份,意味着在备份过程中,数据库仍然可以正常提供服务而不需要停机。
2)它直接与 InnoDB 存储引擎进行交互,创建物理备份,这使得备份速度快且性能开销低。
innobackupex:
1)innobackupex 是 XtraBackup 的一个 Perl 脚本封装器,旨在提供更友好的命令行接口和一些额外的功能。它不仅支持 InnoDB,还可以处理 MyISAM 和其他存储引擎的数据,同时管理 MySQL 配置文件和日志文件。
2)innobackupex 可以自动处理 MySQL 的各种引擎,包括非 InnoDB 引擎,它也负责生成备份日志,和将 XtraBackup 的备份与 MySQL 的非 InnoDB 数据一起进行备份。

全备

[root@db02 ~]# cat /etc/my.cnf
[mysqld]
socket=/opt/mysql.sock
[client]
socket=/opt/mysql.sock

## 热备   -------- 不锁表 备份
innobackupex --user=root --password='123' /backup
innobackupex -uroot  /backup

## 温备份  -------- 锁表备份
xtrabackup -uroot --backup --target-dir=/001

备份文件解读

-rw-r----- 1 backup-my.cnf
-rw-r----- 1 ibdata1
drwxr-x--- 2 mysql
drwxr-x--- 2 performance_schema
drwxr-x--- 2 test
-rw-r----- 1 xtrabackup_binlog_info # 本次备份二进制日志信息
-rw-r----- 1 xtrabackup_checkpoints # 本次备份sql记录点日志信息
-rw-r----- 1 xtrabackup_info        # 本次备份的一些版本信息
-rw-r----- 1 xtrabackup_logfile     # 本次备份的redolog文件

cat xtrabackup_binlog_info
mysql-bin.000001        120         #----记录当前二进制日志数据点点

cat xtrabackup_checkpoints
backup_type = full-backuped         #   这表示备份类型是完整备份(full backup)
from_lsn = 0                        #   备份的起始位置
to_lsn = 1626017                    #   备份的结束位置
last_lsn = 1626017                  #   备份期间的最后一个日志序列号
compact = 0                         #   是否使用了紧凑备份模式
recover_binlog_info = 0             #   是否在备份时收集了二进制日志信息
flushed_lsn = 1626017               #   表示已刷新到磁盘的 LSN。

cat xtrabackup_info 
uuid = 776597be-6051-11ef-9767-000c293e8325    ## 本次备份的UUID
name =                                         ## 备份的名称
tool_name = innobackupex                       ## 生成此次备份的工具名称
tool_command = -uroot /backup                  ## 命令
tool_version = 2.4.29                          ## 生成此次备份的 innobackupex 工具的版本号
ibbackup_version = 2.4.29                      ## XtraBackup 的版本号
server_version = 5.6.50-log                    ## MySQL 服务器版本          
start_time = 2024-08-22 14:40:46               ## 备份开始的时间
end_time = 2024-08-22 14:40:48                 ## 备份结束的时间
lock_time = 0                                  ## 备份期间用于表锁定的时间
binlog_pos = filename 'mysql-bin.000001', position '120'  ## 二进制日志位置。
innodb_from_lsn = 0                 ## 开始的 lsn
innodb_to_lsn = 1626017             ## 结束的 lsn
partial = N                         ## 表示是否为部分备份。
incremental = N                     ## 指明是否为增量备份
format = file                       ## 备份的存储格式
compact = N                         ## 表示是否使用了紧凑备份模式
compressed = N                      ## 表示备份是否经过压缩
encrypted = N                       ## 表示备份是否经过加密
###### 详解一些 ##########
LSN:日志序列号(Log Sequence Number, LSN)

backup_type的状态:
full-backuped ------ 完整备份
incremental   ------ 增量备份
prepared      ------ 已准备好恢复
incremental-prepared    ------ 增量备份已准备好恢复
backuping               ------ 备份正在进行中
apply-log			   ------ 正在应用日志到备份中
merged                  ------ 备份已合并。

全备的恢复

前提1:被恢复的目录是空的
前提2:被恢复的数据库的实例是关闭的
# 停库
[root@db02 ~]# /etc/init.d/mysqld stop
# redo中的数据 重做,undo中的数据 回滚
[root@db02 ~]# innobackupex --apply-log /backup/2024-08-22_10-25-34/
# 清空datadir
[root@db02 ~]# rm -fr /app/mysql/data
# 恢复数据
[root@db02 ~]# innobackupex --copy-back /backup/2024-08-22_10-44-56/
# 授权
[root@db02 ~]# chown -R mysql.mysql /app/mysql/data
# 启动
[root@db02 ~]# /etc/init.d/mysqld start

##----------------##  不建议的方法  ## ------------------------##
# redo中的数据 重做,undo中的数据 回滚
[root@db02 ~]# innobackupex --apply-log /backup/2024-08-22_10-25-34/
# 清空datadir
[root@db02 ~]# rm -fr /app/mysql/data
# 恢复数据
[root@db02 ~]# mv /backup/2024-08-22_10-25-34/ /app/mysql/data
# 授权
[root@db02 ~]# chown -R mysql.mysql /app/mysql/data
# 启动
[root@db02 ~]# /etc/init.d/mysqld start

增量备份

备份方式
1)基于上一次备份进行增量
2)增量备份无法单独恢复,必须基于全备进行恢复
3)所有增量必须要按顺序合并到全备当中
#### 增量备份命令详解
#--全量备份
innobackupex -uroot -p123 --no-timestamp /backup/full_$(date +%F)

#--后续增量备份
innobackupex -uroot -p --no-timestamp --incremental --incremental-basedir=/backup/full_2024-08-22/ /backup/inc1_$(date +%F-%H)

--no-timestamp
这个选项告诉 innobackupex 不要在备份目录名称中附加时间戳。如果不使用这个选项,innobackupex 默认会在生成的备份目录名后加上时间戳。

--incremental
这个选项表示创建增量备份。增量备份只会包含自上次备份以来的更改部分。

--incremental-basedir=/backup/full_2024-08-22/
指定此次增量备份的基准目录,也就是上一次备份的目录。innobackupex 将根据该基准目录中的 LSN(Log Sequence Number)确定自上次备份以来的更改。

/backup/inc1_$(date +%F-%H)
指定增量备份的目标目录

增量备份实战

##### 情况汇报 
有每日凌晨的全备
有每一小时的曾备
持续有数据写入
误删除数据

利用备份 和binlog 来恢复误删除的数据

select * from b.b;
+------+
| id   |
+------+
|    1 |
|    2 |
|    3 |
|    4 |
+------+

a.a 库中有持续写如的数据  
[root@db02 ~]# cat insql.sh 
#!/bin/bash
mysql -e 'create database if not exists a'
mysql -e 'create table if not exists a.a(id int)'
num=1
while true ;do
        mysql -e "insert into a.a values($((num++)))"
        sleep 3
done
cat xtrabackup_binlog_info xtrabackup_checkpoints
############ 开始模拟故障 #############
#-----01  凌晨的全备
innobackupex -uroot -p123 --no-timestamp /backup/full_$(date+%F)
起始lsn:			0
终止lsn:			2142395
binlog数据点:		13771

#-----02  每小时的增备一号
innobackupex --no-timestamp --incremental --incremental-basedir=/backup/full_2024-08-22/ /backup/inc1_$(date +%F-%H)
起始lsn:			 2142395
终止lsn:			 2200479
binlog数据点:		 25754

#-----03  每小时的增备二号
innobackupex --no-timestamp --incremental --incremental-basedir=/backup/inc1_2024-08-22-15/ /backup/inc2_$(date +%F-%H)
起始lsn:			 2200479
终止lsn:			 2250825
binlog数据点:		 42696

#-----04 每小时的增备三号
innobackupex --no-timestamp --incremental --incremental-basedir=/backup/inc2_2024-08-22-15/ /backup/inc3_$(date +%F-%H)
起始lsn:			2250825
终止lsn:			2270831
binlog数据点:		53728

#-----05 发生事故删表
drop table b.b;

#-----06  用户还在持续写入数据 到停止数据库服务
[root@db02 ~]# sh insql.sh 
^C
####### 增量备份恢复 ########
1)full+inc1+inc2
2)需要将inc1和inc2按顺序合并到full中
3)分步骤进行--apply-log
######## 开始操作 ######
# 停库
[root@db02 ~]# /etc/init.d/mysqld stop
# 清空datadir
[root@db02 ~]# mv /app/mysql/data /tmp/


### 增量备份的整合 ###     全备只做redo,不做undo
1) 先只提交全备的redo  
innobackupex --apply-log --redo-only /backup/full_2024-08-22/  
状态:log-applied
起始lsn:			0
终止lsn:			2142395
binlog数据点:		13771

2) 将备份1添加到全备中 只提交redo 
innobackupex --apply-log --redo-only --incremental-dir=/backup/inc1_2024-08-22-15/ /backup/full_2024-08-22/
状态:log-applied
起始lsn:			0
终止lsn:			2200479
binlog数据点:	    25754

3) 将备份2添加到全备中 只提交redo 
innobackupex --apply-log --redo-only --incremental-dir=/backup/inc2_2024-08-22-15/ /backup/full_2024-08-22/
状态:log-applied
起始lsn:			0
终止lsn:			2250825
binlog数据点:	    42696

4) 将备份3添加到全备中   只提交redo undo 
innobackupex --apply-log --redo-only --incremental-dir=/backup/inc3_2024-08-22-15/ /backup/full_2024-08-22/
状态:log-applied
起始lsn:			0
终止lsn:			2270831
binlog数据点:	    53728

5)将全备 redo 和 undo都做一遍
innobackupex --apply-log /backup/full_2024-08-22/
状态:full-prepared
起始lsn:			0
终止lsn:			2270831
binlog数据点:	    53728

6)将整合的备份恢复
innobackupex --copy-back /backup/full_2024-08-22/
b.b 已经恢复了
a.a 恢复到268

7) 截取binlog日志  备份 --- 删表
起始位置点:53728  # cat xtrabackup_binlog_inf
终止位置点:64366  # mysqlbinlog --base64-output=decode-rows -vvv mysql-bin.000001|grep -iC 10 'drop'
mysqlbinlog  --start-position=53728 --stop-position=64366 ./mysql-bin.000001 > /tmp/inc1.sql

8)  截取binlog日志  删表后 --- 停表
起始位置点:64477  # cat xtrabackup_binlog_inf
终止位置点:70607  # ll ./mysql-bin.000001
mysqlbinlog  --start-position=64477 --stop-position=70607 ./mysql-bin.000001 > /tmp/inc2.sql

9) 导入数据
set sql_log_bin=0  # 临时关闭 binlog
mysql < /tmp/inc1.sql 
mysql < /tmp/inc2.sql 

10) 数据库上线