MySQL(五)

        备份

使用数据库的过程中,有多种原因造成数据的丢失:

  • 程序错误:指对数据库操作的程序难免有些错误,造成数据丢失
  • 人为错误:指由于使用人员的误操作造成的数据被破坏,还有可能是黑客对系统攻击造成的数据丢失等
  • 计算机故障:指运行数据库的服务器操作系统或软件损坏,有可能造成数据的损坏
  • 磁盘故障:指硬盘等存储数据的硬件设备,长时间运行后可能损坏,造成数据丢失
  • 灾难(如火灾、地震)和偷窃:指自然灾害等的发生,有可能造成数据丢失

一个合理的数据库备份方案,能够在数据丢失时,有效地恢复数据,实现数据的一致性,服务可用性,而且也需要考虑技术实现难度和有效地利用资源。

备份技术

物理备份/冷备份

直接复制数据库文件,适用于大型数据库环境,不受存储引擎的限制,但不能恢复到不同的MySQL版本;拷贝数据,速度快,但是需要关闭MySQL服务

逻辑备份/热备份

备份的内容是 建库、建表、更新数据等操作所执行的SQL语句(DDL,DML,DCL),适用于中小型数据库;效率相对较低,MySQL服务可正常运行。

温备

读操作可执行;写操作不可执行

备份种类

完全备份

完全备份是对整个数据库的备份、数据库结构和文件结构的备份,保存的是备份完成时刻的数据库,是增量备份的基础。

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

增量备份(incremental backup)

针对于上一次备份(无论是哪种备份):备份上一次备份后,所有发生变化的文件。

差异备份(DifferentialBackup)

记录自上次完全数据库备份之后对数据库的更改的数据库备份。

备份目标

  • 数据
  • 二进制日志、InnoDB的事务日志
  • 用户账号,权限设置,程序代码(存储过程、函数、触发器、事件调度器)
  • 服务器配置文件

备份注意

  • 能容忍最多丢失多少数据
  • 备份产生的负载
  • 备份过程的时长
  • 温备的持锁多久
  • 恢复数据需要在多长时间内完成
  • 需要备份和恢复哪些数据

还原要点

  • 备份后要做还原测试,用于测试备份的可用性
  • 还原演练,写成规范的技术文档

备份工具

  • cp, tar等复制归档工具:物理备份工具,适用所有存储引擎;只支持冷备;完全和部分备份
  • LVM的快照:先加读锁,做快照后解锁,几乎热备;借助文件系统工具进行备份
  • mysqldump:逻辑备份工具,适用所有存储引擎,对MyISAM存储引擎进行温备;支持完全或部分备份;对InnoDB存储引擎支持热备,结合binlog的增量备份
  • xtrabackup:由Percona提供支持对InnoDB做热备(物理备份)的工具,支持完全备份、增量备份
  • MariaDB Backup: 从MariaDB 10.1.26开始集成,基于Percona XtraBackup 2.3.8实现
  • mysqlbackup:热备份, MySQL Enterprise Edition 组件
  • mysqlhotcopy:PERL 语言实现,几乎冷备,仅适用于MyISAM存储引擎,使用LOCK TABLES、FLUSH TABLES和cp或scp来快速备份数据库

mysqldump备份工具

mysqldump是MySQL的客户端命令,通过mysql协议连接至mysql服务器进行备份

常见选项

-u:指定用户名

-p:指定密码

-A:备份所有数据库,包括create database语句

-B:指定要备份的数据库,包括create database语句

-E:备份相关所有的event scheduler 事件调度器

-R:备份所有存储过程和自定义函数

--triggers:备份表相关触发器,默认启用;用--skip-triggers不备份触发器

--default-character-set=utf8:指定字符集

--master-data= :此项在MySQL8.0.26版后,变为--source-data。使用此选项要启用二进制日志。

        为1(默认)时,所备份的数据之前加一条 CHANGE MASTER TO语句;适合主从复制多机使用。

        为2时,增加的 CHANGE MASTER TO语句被注释;适合单机使用、备份还原。

-F:备份前滚动日志,生成新的二进制日志;配合 -A 或 -B 时会导致多次滚动日志,建议和--single-transaction、--master-data一起使用,可实现只刷新一次二进制日志。

--hex-blob:使用十六进制符号转储二进制列,当有包括BINARY,VARBINARY,BLOB,
BIT的数据类型的列时使用,避免乱码。

--flush-privileges:此选项会刷新MySQL的权限系统,确保新的权限设置立即生效

关于MyISAM存储引擎相关的备份选项

MyISAM不支持事务,只能支持温备;不支持热备,所以必须先锁定要备份的库,再备份。

-x,--lock-all-tables:加全局读锁,锁定所有库的所有表,同时加--single-transaction或--
lock-tables选项会关闭此选项功能。注意:数据量大时,可能会导致长时间无法并发访问数据库

-l,--lock-tables:对于需要备份的每个数据库,在启动备份之前分别锁定其所有表,默认为on,--
skip-lock-tables选项可禁用,对备份MyISAM的多个库,可能会造成数据不一致

这两项对InnoDB表一样生效,实现温备,但不推荐使用。

关于InnoDB存储引擎相关的备份选项

--single-transaction:推荐使用,不适用MyISAM。此项会在开始备份前开启事务。

生产环境实战备份策略

InnoDB

mysqldump -uroot -p密码 -A -F -E -R --triggers --single-transaction --master-data=1 --flush-privileges --default-character-set=utf8 --hex-blob > ${BACKUP}/fullbak_${BACKUP_TIME}.sql

MyISAM

mysqldump -uroot -p -A -F -E -R -x --master-data=1 --flush-privileges  --triggers  --default-character-set=utf8  --hex-blob > ${BACKUP}/fullbak_${BACKUP_TIME}.sql

percona-xtrabackup

地址:Software Downloads - Percona

它是开源免费的支持MySQL 数据库热备份的软件,它能对InnoDB和XtraDB存储引擎的数据库非阻塞地备份。它能不暂停服务创建Innodb热备份;

percona-xtrabackup-2x 版本支持MySQL5.x版本;percona-xtrabackup-8x 版本支持MySQL8.x版本。

由于Oracle在2020年4月底发布的MySQL 8.0.20的变化,Percona XtraBackup 8.0,最高版本为8.0.11,与MySQL 8.0.20或更高版本,或基于它的Percona产品不兼容: Percona Server for MySQL 和 Percona XtraDB Cluster。

常见选项

--target-dir:备份文件保存的目录

完全备份

创建

xtrabackup --backup --target-dir=/data/backups/

准备

xtrabackup --prepare --target-dir=/data/backups/

恢复

恢复前数据库服务必须是停止状态;数据目录必须为空;

xtrabackup --copy-back --target-dir=/data/backups/

增量备份

--incremental-basedir:指定本次增量备份的基础备份

--incremental-dir:指定增量备份存放的目录

创建一个完全备份

xtrabackup --backup --target-dir=/data/backups/base

创建第一个增量备份

xtrabackup --backup --target-dir=/data/backups/inc1 --incremental-basedir=/data/backups/base

在第一个增量备份基础上创建第二个增量备份

xtrabackup --backup --target-dir=/data/backups/inc2 --incremental-basedir=/data/backups/inc1

准备基本备份

现在应该有 /data/backups/base、/data/backups/inc1、/data/backups/inc2 这三个文件

xtrabackup --prepare --apply-log-only --target-dir=/data/backups/base

将第一次增量备份应用于完全备份

xtrabackup --prepare --apply-log-only --target-dir=/data/backups/base --incremental-dir=/data/backups/inc1

将第二次增量备份应用于完全备份

最后一次应用增量备份不要加 --apply-log-only

xtrabackup --prepare --target-dir=/data/backups/base --incremental-dir=/data/backups/inc2

恢复

恢复前数据库服务必须是停止状态;数据目录必须为空;

xtrabackup --copy-back --target-dir=/data/backups/

记录一(2023.09)

环境

mysql 8.0.19   yum方式安装

Percona XtraBackup 8.0.10   yum方式安装

安装mysql

[root@wenzi ~]# ls
anaconda-ks.cfg  mysql-8.0.19-1.el7.x86_64.rpm-bundle.tar  original-ks.cfg  percona-xtrabackup-80-8.0.10-1.el7.x86_64.rpm
[root@wenzi ~]# tar -x -f mysql-8.0.19-1.el7.x86_64.rpm-bundle.tar
[root@wenzi ~]# ls
anaconda-ks.cfg                                 mysql-community-devel-8.0.19-1.el7.x86_64.rpm            mysql-community-server-8.0.19-1.el7.x86_64.rpm
mysql-8.0.19-1.el7.x86_64.rpm-bundle.tar        mysql-community-embedded-compat-8.0.19-1.el7.x86_64.rpm  mysql-community-test-8.0.19-1.el7.x86_64.rpm
mysql-community-client-8.0.19-1.el7.x86_64.rpm  mysql-community-libs-8.0.19-1.el7.x86_64.rpm             original-ks.cfg
mysql-community-common-8.0.19-1.el7.x86_64.rpm  mysql-community-libs-compat-8.0.19-1.el7.x86_64.rpm      percona-xtrabackup-80-8.0.10-1.el7.x86_64.rpm2

#提前卸载mariadb的lib包,不然会和mysql-community-libs冲突
[root@wenzi ~]# yum -y remove mariadb-libs.x86_64 1:5.5.68-1.el7
#提前安装,避免出错提示
[root@wenzi ~]# yum -y install libaio net-tools
#按照以下安装顺序
[root@wenzi ~]# rpm -ivh mysql-community-common-8.0.19-1.el7.x86_64.rpm && rpm -ivh mysql-community-libs-8.0.19-1.el7.x86_64.rpm && rpm -ivh mysql-community-client-8.0.19-1.el7.x86_64.rpm && rpm -ivh mysql-community-server-8.0.19-1.el7.x86_64.rpm && rpm -ivh mysql-community-libs-compat-8.0.19-1.el7.x86_64.rpm && yum -y install  percona-xtrabackup-80-8.0.10-1.el7.x86_64.rpm

[root@wenzi ~]# systemctl enable --now mysqld
[root@wenzi ~]# grep "password" /var/log/mysqld.log
2023-09-08T17:44:30.120757Z 5 [Note] [MY-010454] [Server] A temporary password is generated for root@localhost: OYph_Xz4H:zK
mysql> alter user 'root'@'localhost' identified by 'Admin.123';
Query OK, 0 rows affected (0.01 sec)
mysql> quit
Bye

[root@wenzi ~]# echo "log_bin" >> /etc/my.cnf
[root@wenzi ~]# systemctl restart mysqld

[root@wenzi ~]# mysql -uroot -p'Admin.123'
mysql> create database test;
Query OK, 1 row affected (0.00 sec)

mysql> use test;
Database changed
mysql> create table student (id int,name varchar(20));
Query OK, 0 rows affected (0.01 sec)

mysql> insert into student values (1,'liubei');
Query OK, 1 row affected (0.00 sec)

mysql> select * from test.student;
+------+--------+
| id   | name   |
+------+--------+
|    1 | liubei |
+------+--------+
1 row in set (0.00 sec)

完整备份

创建备份
[root@wenzi ~]# ls /var/lib/mysql
auto.cnf       ca-key.pem       client-key.pem  ib_logfile0  #innodb_temp  mysql.sock          private_key.pem  server-key.pem  undo_001          wenzi-bin.000002
binlog.000001  ca.pem           ib_buffer_pool  ib_logfile1  mysql         mysql.sock.lock     public_key.pem   sys             undo_002          wenzi-bin.index
binlog.index   client-cert.pem  ibdata1         ibtmp1       mysql.ibd     performance_schema  server-cert.pem  test            wenzi-bin.000001

[root@wenzi ~]# mkdir -p /data/backups
[root@wenzi ~]# xtrabackup --backup --user=root --password='Admin.123' --target-dir=/data/backups/`date +'%F-%H-%M-%S'`

[root@wenzi ~]# ls /data/backups/2023-09-09-21-05-16/
backup-my.cnf   ibdata1  mysql.ibd           sys   undo_001  wenzi-bin.000002  xtrabackup_binlog_info  xtrabackup_info     xtrabackup_tablespaces
ib_buffer_pool  mysql    performance_schema  test  undo_002  wenzi-bin.index   xtrabackup_checkpoints  xtrabackup_logfile
#查看二进制日志文件位置
[root@wenzi ~]# cat /data/backups/2023-09-09-21-05-16/xtrabackup_binlog_info
wenzi-bin.000002        155

--target-dir=备份存储目录

--databases=要备份的数据库

--tables=要备份的实际表名称

模拟数据库损坏
[root@wenzi ~]# systemctl stop mysqld
[root@wenzi ~]# rm -rf /var/lib/mysql/*
[root@wenzi ~]# rm -f /var/log/mysqld.log
恢复数据
#还原前先进行一致性检查
[root@wenzi ~]# xtrabackup --prepare --target-dir=/data/backups/2023-09-09-21-05-16/
#恢复数据
[root@wenzi ~]# xtrabackup --copy-back --target-dir=/data/backups/2023-09-09-21-05-16/
#恢复权限
[root@wenzi ~]# chown -R mysql:mysql /var/lib/mysql
[root@wenzi ~]# systemctl start mysqld
检查数据
[root@wenzi ~]# mysql -uroot -p'Admin.123'
mysql> select * from test.student;
+------+--------+
| id   | name   |
+------+--------+
|    1 | liubei |
+------+--------+
1 row in set (0.01 sec)

增量备份

数据库新增数据
mysql> insert into test.student values (2,'zhaoyun');
Query OK, 1 row affected (0.00 sec)

mysql> select * from test.student;
+------+---------+
| id   | name    |
+------+---------+
|    1 | liubei  |
|    2 | zhaoyun |
+------+---------+
2 rows in set (0.00 sec)
第一次增量备份

第一次增量备份是基于<完整备份实验>的完整备份

[root@wenzi ~]# xtrabackup --backup -uroot -p'Admin.123' --target-dir=/data/backups/inc01 --incremental-basedir=/data/backups/2023-09-09-21-05-16/
[root@wenzi ~]# ls /data/backups/inc01/
backup-my.cnf   ibdata1.meta     mysql.ibd.meta      test            undo_002.delta    wenzi-bin.index         xtrabackup_info
ib_buffer_pool  mysql            performance_schema  undo_001.delta  undo_002.meta     xtrabackup_binlog_info  xtrabackup_logfile
ibdata1.delta   mysql.ibd.delta  sys                 undo_001.meta   wenzi-bin.000004  xtrabackup_checkpoints  xtrabackup_tablespaces
数据库新增数据
mysql> insert into test.student values (3,'guanyu');
Query OK, 1 row affected (0.01 sec)

mysql> select * from test.student;
+------+---------+
| id   | name    |
+------+---------+
|    1 | liubei  |
|    2 | zhaoyun |
|    3 | guanyu  |
+------+---------+
3 rows in set (0.00 sec)
第二次增量备份

第二次增量备份是基于第一次增量备份

多次增量备份时指定的增量备份存储目录应该不同

[root@wenzi ~]# xtrabackup --backup -uroot -p'Admin.123' --target-dir=/data/backups/inc02 --incremental-basedir=/data/backups/inc01/
[root@wenzi ~]# ls /data/backups/inc02
backup-my.cnf   ibdata1.meta     mysql.ibd.meta      test            undo_002.delta    wenzi-bin.index         xtrabackup_info
ib_buffer_pool  mysql            performance_schema  undo_001.delta  undo_002.meta     xtrabackup_binlog_info  xtrabackup_logfile
ibdata1.delta   mysql.ibd.delta  sys                 undo_001.meta   wenzi-bin.000005  xtrabackup_checkpoints  xtrabackup_tablespaces
模拟数据库损坏
[root@wenzi ~]# systemctl stop mysqld
[root@wenzi ~]# rm -rf /var/lib/mysql/*
[root@wenzi ~]# rm -f /var/log/mysqld.log
恢复数据
#检查一致性
#先回滚 完整备份
[root@wenzi ~]# xtrabackup --prepare --apply-log-only  --target-dir=/data/backups/2023-09-09-21-05-16/
#接着回滚第一次增量备份
[root@wenzi ~]# xtrabackup --prepare --apply-log-only  --target-dir=/data/backups/2023-09-09-21-05-16/ --incremental-dir=/data/backups/inc01/
#再回滚第二次增量备份
[root@wenzi ~]# xtrabackup --prepare --apply-log-only  --target-dir=/data/backups/2023-09-09-21-05-16/ --incremental-dir=/data/backups/inc02/

#此时所有备份文件已合并在完整备份文件中
#开始恢复
[root@wenzi ~]# xtrabackup --copy-back --target-dir=/data/backups/2023-09-09-21-05-16/
[root@wenzi ~]# chown -R mysql:mysql /var/lib/mysql*
[root@wenzi ~]# systemctl start mysqld
检查数据
[root@wenzi ~]# mysql -uroot -p'Admin.123'
mysql> select * from test.student;
+------+---------+
| id   | name    |
+------+---------+
|    1 | liubei  |
|    2 | zhaoyun |
|    3 | guanyu  |
+------+---------+
3 rows in set (0.02 sec)

差异备份

数据库改变数据
mysql> update test.student set name='zhangfei' where id=2;
Query OK, 1 row affected (0.00 sec)
Rows matched: 1  Changed: 1  Warnings: 0

mysql> select * from test.student;
+------+----------+
| id   | name     |
+------+----------+
|    1 | liubei   |
|    2 | zhangfei |
|    3 | guanyu   |
+------+----------+
3 rows in set (0.00 sec)
第一次差异备份

第一次差异备份是基于<完整备份实验>的完整备份

[root@wenzi ~]# xtrabackup --backup -uroot -p'Admin.123' --target-dir=/data/backups/cy01/ --incremental-basedir=/data/backups/2023-09-09-21-05-16/
[root@wenzi ~]# ls /data/backups/cy01/
backup-my.cnf   ibdata1.meta     mysql.ibd.meta      test            undo_002.delta    wenzi-bin.index         xtrabackup_info
ib_buffer_pool  mysql            performance_schema  undo_001.delta  undo_002.meta     xtrabackup_binlog_info  xtrabackup_logfile
ibdata1.delta   mysql.ibd.delta  sys                 undo_001.meta   wenzi-bin.000007  xtrabackup_checkpoints  xtrabackup_tablespaces
数据库改变数据
mysql> update test.student set name='huangzhong' where id=1;
Query OK, 1 row affected (0.00 sec)
Rows matched: 1  Changed: 1  Warnings: 0

mysql> select * from test.student;
+------+------------+
| id   | name       |
+------+------------+
|    1 | huangzhong |
|    2 | zhangfei   |
|    3 | guanyu     |
+------+------------+
3 rows in set (0.00 sec)
第二次差异备份

第二次差异备份是基于<完整备份实验>的完整备份

[root@wenzi ~]# xtrabackup --backup -uroot -p'Admin.123' --target-dir=/data/backups/cy02/ --incremental-basedir=/data/backups/2023-09-09-21-05-16/
[root@wenzi ~]# ls /data/backups/cy02/
backup-my.cnf   ibdata1.meta     mysql.ibd.meta      test            undo_002.delta    wenzi-bin.index         xtrabackup_info
ib_buffer_pool  mysql            performance_schema  undo_001.delta  undo_002.meta     xtrabackup_binlog_info  xtrabackup_logfile
ibdata1.delta   mysql.ibd.delta  sys                 undo_001.meta   wenzi-bin.000008  xtrabackup_checkpoints  xtrabackup_tablespaces
模拟数据库损坏
[root@wenzi ~]# systemctl stop mysqld
[root@wenzi ~]# rm -rf /var/lib/mysql/*
[root@wenzi ~]# rm -f /var/log/mysqld.log
恢复数据
[root@wenzi ~]# xtrabackup --prepare --apply-log-only --target-dir=/data/backups/2023-09-09-21-05-16/
[root@wenzi ~]# xtrabackup --prepare --apply-log-only --target-dir=/data/backups/2023-09-09-21-05-16/ --incremental-dir=/data/backups/cy02/
[root@wenzi ~]# xtrabackup --copy-back --target-dir=/data/backups/2023-09-09-21-05-16/
[root@wenzi ~]# chown -R mysql:mysql /var/lib/mysql*
[root@wenzi ~]# systemctl start mysqld
检查数据
[root@wenzi ~]# mysql -uroot -p'Admin.123'
mysql> select * from test.student;
+------+------------+
| id   | name       |
+------+------------+
|    1 | huangzhong |
|    2 | zhangfei   |
|    3 | guanyu     |
+------+------------+
3 rows in set (0.00 sec)

mysqldump + binlog

mysqldump是MySQL数据库中用于备份和导出数据库的命令行工具。它允许你导出整个数据库或仅导出特定的表。通过使用mysqldump,你可以生成一个SQL脚本文件,该文件可以用于还原已导出的数据库

优势:自动记录日志position位置;可用性,一致性;备份时的锁表机制;

常见用法:

导出所有数据库 mysqldump -uroot -p‘密码’ -A > all.sql

导出单个数据库 mysqldump -uroot -p’密码’ test1 > test1.sql

导出多个数据库 mysqldump -uroot -p’密码’ --databases test1 test2 > 2.sql

导出单张表 mysqldump -uroot -p’密码’ mysql user > mysql.user.sql;

导出多张表 mysqldump -uroot -p’密码’ mysql user db > mysql.userdb.sql;

只导出表结构 mysqldump -uroot -p’密码’ --all-databases --no-data > all.d.sql

--single-transaction 保持数据一致性,仅限innodb引擎

--master-data=1或2 将记录binlog的日志位置与文件名并追加到文件中,2是添加注释

--flush-logs 截断日志。备份之后产生新binlog。

-R 导出存储过程和自定义函数

--triggers 导出触发器,默认启用,可用--skip-triggers禁用

–opt 等同于--add-drop-table, --add-locks, --create-options, --quick, --extended-insert, --lock-tables, --set-charset, --disable-keys 该选项默认开启,可以用--skip-opt禁用

环境

mysql 8.0.19   yum方式安装

此实验需要两套密码,密码一:Admin.123  密码二:aDMIN.123

安装mysql

[root@wenzi ~]# ls
anaconda-ks.cfg  mysql-8.0.19-1.el7.x86_64.rpm-bundle.tar  original-ks.cfg
[root@wenzi ~]# tar -x -f mysql-8.0.19-1.el7.x86_64.rpm-bundle.tar && yum -y remove mariadb-libs.x86_64 1:5.5.68-1.el7 && yum -y install libaio net-tools && rpm -ivh mysql-community-common-8.0.19-1.el7.x86_64.rpm && rpm -ivh mysql-community-libs-8.0.19-1.el7.x86_64.rpm && rpm -ivh mysql-community-client-8.0.19-1.el7.x86_64.rpm && rpm -ivh mysql-community-server-8.0.19-1.el7.x86_64.rpm && rpm -ivh mysql-community-libs-compat-8.0.19-1.el7.x86_64.rpm  && echo "log_bin" >> /etc/my.cnf && systemctl enable --now mysqld && grep "password" /var/log/mysqld.log


[root@wenzi ~]# mysql -uroot -p'an+1PuHi6g92'
mysql> alter user 'root'@'localhost' identified by 'Admin.123';
Query OK, 0 rows affected (0.00 sec)
mysql> quit
[root@wenzi ~]# mysql -uroot -p'Admin.123'
mysql> create database one;
Query OK, 1 row affected (0.00 sec)

mysql> use one;
Database changed
mysql> create table emp (id int,name varchar(20));
Query OK, 0 rows affected (0.00 sec)

mysql> insert into emp values (1,'a');
Query OK, 1 row affected (0.01 sec)

mysql> select * from one.emp;
+------+------+
| id   | name |
+------+------+
|    1 | a    |
+------+------+
1 row in set (0.00 sec)

mysql> quit
Bye

[root@wenzi ~]# mkdir -p  /data/backups

备份数据

mysqldump语句会切割一次二进制日志,产生了wenzi-bin.000003

[root@wenzi ~]# mysqldump -h localhost -uroot -p'Admin.123' -A --single-transaction --master-data=2 --flush-logs  > /data/backups/`date +'%F-%H-%M-%S'`_all.sql
[root@wenzi ~]# ls /data/backups/
2023-09-10-01-46-50_all.sql

查看备份详细

[root@wenzi ~]# vim /data/backups/2023-09-10-03-15-51_all.sql

在此次备份时产生的新日志名称为wenzi-bin.000003,新日志中POS155之前是已经备份过的,从155往后是未备份过的内容

[root@wenzi mysql]# mysqlbinlog -v wenzi-bin.000003
/*!50530 SET @@SESSION.PSEUDO_SLAVE_MODE=1*/;
/*!50003 SET @OLD_COMPLETION_TYPE=@@COMPLETION_TYPE,COMPLETION_TYPE=0*/;
DELIMITER /*!*/;
# at 4
#230910  4:44:19 server id 1  end_log_pos 124 CRC32 0x1fa24712  Start: binlog v 4, server v 8.0.19 created 230910  4:44:19
# Warning: this binlog is either in use or was not closed properly.
BINLOG '
I9n8ZA8BAAAAeAAAAHwAAAABAAQAOC4wLjE5AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAEwANAAgAAAAABAAEAAAAYAAEGggAAAAICAgCAAAACgoKKioAEjQA
CgESR6If
'/*!*/;
# at 124                                从at155开始往后都是新产生的变化,未备份过的
#230910  4:44:19 server id 1  end_log_pos 155 CRC32 0xf4f29efe  Previous-GTIDs
# [empty]  
SET @@SESSION.GTID_NEXT= 'AUTOMATIC' /* added by mysqlbinlog */ /*!*/;
DELIMITER ;
# End of log file
/*!50003 SET COMPLETION_TYPE=@OLD_COMPLETION_TYPE*/;
/*!50530 SET @@SESSION.PSEUDO_SLAVE_MODE=0*/;

在备份时锁表,可读不可写

 备份后数据变动

mysql> insert into one.emp values (2,'b');
Query OK, 1 row affected (0.00 sec)

mysql> select * from one.emp;
+------+------+
| id   | name |
+------+------+
|    1 | a    |
|    2 | b    |
+------+------+
2 rows in set (0.00 sec)

备份二进制日志

[root@wenzi ~]# mkdir -p /data/backups/binlog/ && cp /var/lib/mysql/*bin* /data/backups/binlog/
[root@wenzi ~]# ls /data/backups/binlog/
wenzi-bin.000001  wenzi-bin.000002  wenzi-bin.000003  wenzi-bin.index

此时查看二进制日志,变动的数据存在于 binlog.000003 中

[root@wenzi ~]# mysqlbinlog -v /data/backups/binlog/wenzi-bin.000003

...

# at 361
#230910  3:31:30 server id 1  end_log_pos 403 CRC32 0x48bd867c  Write_rows: table id 174 flags: STMT_END_F

BINLOG '
Esj8ZBMBAAAAOAAAAGkBAAAAAK4AAAAAAAEAA29uZQADZW1wAAIDDwJQAAMBAQACA/z/ANFoIYk=
Esj8ZB4BAAAAKgAAAJMBAAAAAK4AAAAAAAEAAgAC/wACAAAAAWJ8hr1I
'/*!*/;
### INSERT INTO `one`.`emp`
### SET
###   @1=2
###   @2='b'

...

模拟数据损坏

[root@wenzi ~]# systemctl stop mysqld && rm -rf /var/lib/mysql/* && rm -f /var/log/mysqld.log

mysql恢复数据

启动数据库,使用默认密码登录mysql,将密码修改为准备的第二套密码 aDMIN.123

[root@wenzi ~]# systemctl start mysqld
[root@wenzi ~]# grep "password" /var/log/mysqld.log
2023-09-09T18:27:22.298328Z 5 [Note] [MY-010454] [Server] A temporary password is generated for root@localhost: !5GHJT*dlh5e
#修改为预先准备的第二个密码
[root@wenzi ~]# mysql -uroot -p'!5GHJT*dlh5e'
mysql> alter user 'root'@'localhost' identified by 'aDMIN.123';
Query OK, 0 rows affected (0.00 sec)

将备份数据导入数据库,刷新权限,此时使用的密码为 aDMIN.123

[root@wenzi ~]# mysql -uroot -p'aDMIN.123' < /data/backups/2023-09-10-01-46-50_all.sql
[root@wenzi ~]# mysql -uroot -p'aDMIN.123' -e 'flush privileges'

登录数据库,发现密码 aDMIN.123 失效,因为原先的数据库已被恢复,应使用原密码 Admin.123。同时发现数据只恢复了备份前的数据,备份后的数据变动没有恢复成功

[root@wenzi ~]# mysql -uroot -p'aDMIN.123'
mysql: [Warning] Using a password on the command line interface can be insecure.
ERROR 1045 (28000): Access denied for user 'root'@'localhost' (using password: YES)

[root@wenzi ~]# mysql -uroot -p'Admin.123'
mysql> show databases;
+--------------------+
| Database           |
+--------------------+
| information_schema |
| mysql              |
| one                |
| performance_schema |
| sys                |
+--------------------+
5 rows in set (0.00 sec)

mysql> select * from one.emp;
+------+------+
| id   | name |
+------+------+
|    1 | a    |
+------+------+
1 row in set (0.00 sec)

二进制日志恢复数据

二进制日志恢复的起始即 wenzi-bin.000003的POS155。

若后续还有新产生的日志 wenzi-bin.000004、wenzi-bin.000005......,应在全写入在命令中

mysqlbinlog /data/backups/binlog/wenzi-bin.000003 /data/backups/binlog/wenzi-bin.000004 /data/backups/binlog/wenzi-bin.000005 --start-position=155 | mysql -uroot -p'Admin.123'

[root@wenzi ~]# mysqlbinlog /data/backups/binlog/wenzi-bin.000003 --start-position=155 | mysql -uroot -p'Admin.123'
[root@wenzi ~]# mysql -uroot -p'Admin.123'
mysql> select * from one.emp;
+------+------+
| id   | name |
+------+------+
|    1 | a    |
|    2 | b    |
+------+------+
2 rows in set (0.00 sec)

备份后产生的数据变化已恢复

记录二(2024.01)

冷备及还原

将CentOS8(192.168.28.30)中yum安装的mysql8.0.26的所有数据备份至Rocky8(192.168.28.40)上,并还原   

192.168.28.30
登录数据库,查看数据
[root@wenzi ~]$mysql -uroot -pAdmin.
mysql> use cs;
mysql> select * from student;
+----+-------+
| id | name  |
+----+-------+
|  1 | zhao  |
|  2 | qian  |
|  3 | sun   |
|  4 | li    |
|  5 | zhou  |
|  6 | wu    |
|  7 | zheng |
|  8 | wang  |
+----+-------+
8 rows in set (0.00 sec)

停止mysqld,备份数据及配置文件至192.168.28.40
[root@wenzi ~]$systemctl stop mysqld
[root@wenzi ~]$rsync -a /var/lib/mysql root@192.168.28.40:/data/
[root@wenzi ~]$rsync -a /etc/{my.cnf,my.cnf.d} root@192.168.28.40:/data/etc/

-------------------------------------------------------------------------------------------

192.168.28.40
yum安装mysql,不启动
[root@wenzi ~]$yum -y install mysql-server

将备份的数据复制到指定位置
[root@wenzi ~]#rsync -a /data/etc/* /etc
[root@wenzi ~]#rsync -a /data/mysql/* /var/lib/mysql/

启动mysqld,登录数据库验证
[root@wenzi ~]#systemctl enable --now mysqld
[root@wenzi ~]#mysql -uroot -pAdmin.
mysql> select * from cs.student;
+----+-------+
| id | name  |
+----+-------+
|  1 | zhao  |
|  2 | qian  |
|  3 | sun   |
|  4 | li    |
|  5 | zhou  |
|  6 | wu    |
|  7 | zheng |
|  8 | wang  |
+----+-------+
8 rows in set (0.01 sec)

mysqldump实现分库备份,定时执行

CentOS8   yum安装   mysql8.0.26

其中mysql:[Warning]是警告用户使用了明文密码;此条告警是个错误输出。information_schema表、performance_schema表是虚拟表,不用备份。

[root@wenzi ~]$vim backup_db.sh
#!/bin/bash
#********************************************************************
#FileName:     backup_db.sh
#Version:      1.0
#Date:         2024-01-21
#Author:       wenzi
#Description: 分库备份
#********************************************************************
time=`date +%F_%H-%M-%S`
bakdir=/backup
passwd=Admin.

[ -d ${bakdir} ] || mkdir ${bakdir}

for i in `mysql -uroot -p${passwd} -e 'show databases;' 2>/dev/null | grep -Ev "^Database|.*schema$"`;do
    mysqldump -uroot -p${passwd} -B ${i} -F -E -R --triggers --single-transaction --master-data=1 --flush-privileges --default-character-set=utf8 --hex-blob > ${bakdir}/${i}_${time}.sql
    if [ $? -eq 0 ];then
        echo "数据库$i备份完毕!"
    else
        echo "备份出错!"
        exit 1
    fi
done

设置定时任务
[root@wenzi ~]$crontab -e
PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/root/bin
30 2 * * * /root/backup_mysql.sh
修改时间
[root@wenzi ~]$date -s '2024-01-21 02:29:30'
观察定时任务日志
[root@wenzi ~]$tail /var/log/cron
Jan 21 02:30:25 wenzi CROND[29078]: (root) CMD (/root/backup_mysql.sh)

mysqldump实现完全备份及还原

将CentOS8(192.168.28.30)中yum安装的mysql8.0.26的所有数据备份至Rocky8(192.168.28.40)上,并还原   

192.168.28.30
[root@wenzi ~]$mysql -uroot -pAdmin. -e 'select * from cs.student;'
mysql: [Warning] Using a password on the command line interface can be insecure.
+----+-------+
| id | name  |
+----+-------+
|  1 | zhao  |
|  2 | qian  |
|  3 | sun   |
|  4 | li    |
|  5 | zhou  |
|  6 | wu    |
|  7 | zheng |
|  8 | wang  |
+----+-------+

[root@wenzi ~]$mysqldump -uroot -pAdmin. -A -F --triggers --single-transaction --master-data=2 > all_`date +%F`.sql
[root@wenzi ~]$ls
all_2024-01-21.sql
[root@wenzi ~]$rsync -a all_2024-01-21.sql root@192.168.28.40:/root/

-------------------------------------------------------------------------------------------

192.168.28.40
[root@wenzi ~]#mysql
mysql> set sql_log_bin=0;
mysql> source all_2024-01-21.sql;
mysql> select * from cs.student;
+----+-------+
| id | name  |
+----+-------+
|  1 | zhao  |
|  2 | qian  |
|  3 | sun   |
|  4 | li    |
|  5 | zhou  |
|  6 | wu    |
|  7 | zheng |
|  8 | wang  |
+----+-------+
8 rows in set (0.00 sec)

mysql> set sql_log_bin=1;

mysqldump实现完全备份+通过binlog还原

1、记录二进制日志POS位置,并完全备份
[root@wenzi ~]$mysql -uroot -pAdmin.
mysql> select * from cs.student;
+----+-------+
| id | name  |
+----+-------+
|  1 | zhao  |
|  2 | qian  |
|  3 | sun   |
|  4 | li    |
|  5 | zhou  |
|  6 | wu    |
|  7 | zheng |
|  8 | wang  |
+----+-------+
8 rows in set (0.00 sec)

mysql> show master logs;
+---------------+-----------+-----------+
| Log_name      | File_size | Encrypted |
+---------------+-----------+-----------+
| binlog.000001 |      3369 | No        |
+---------------+-----------+-----------+


[root@wenzi ~]$mysqldump -uroot -pAdmin. -A -E -R -F --triggers --single-transaction --master-data=2 --flush-privileges --default-character-set=utf8 --hex-blob > /data/all.sql
[root@wenzi ~]$ls /data/
all.sql

2、修改数据库数据
mysql> insert into student(name) values ('ABCD');
Query OK, 1 row affected (0.00 sec)

mysql> select * from student;
+----+-------+
| id | name  |
+----+-------+
|  1 | zhao  |
|  2 | qian  |
|  3 | sun   |
|  4 | li    |
|  5 | zhou  |
|  6 | wu    |
|  7 | zheng |
|  8 | wang  |
|  9 | ABCD  |
+----+-------+
9 rows in set (0.00 sec)

3、备份二进制日志
[root@wenzi ~]$mysqlbinlog /var/lib/mysql/binlog.000001 /var/lib/mysql/binlog.000002 --start-position=3369 > /data/inc.sql

4、模拟数据库损坏
[root@wenzi ~]$systemctl stop mysqld
[root@wenzi ~]$rm -rf /var/lib/mysql/*

5、先还原完全备份,再还原二进制备份
[root@wenzi ~]$systemctl start mysqld
[root@wenzi ~]$mysql
mysql> set sql_log_bin=0;
mysql> source /data/all.sql
mysql> source /data/inc.sql
mysql> set sql_log_bin=1;
mysql> use cs;
Database changed
mysql> select * from student;
+----+-------+
| id | name  |
+----+-------+
|  1 | zhao  |
|  2 | qian  |
|  3 | sun   |
|  4 | li    |
|  5 | zhou  |
|  6 | wu    |
|  7 | zheng |
|  8 | wang  |
|  9 | ABCD  |
+----+-------+

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值