1.mysql的备份与恢复
数据备份的重要性
-
在生产环境中,数据的安全性至关重要
-
任何数据的丢失都可能产生严重的后果
-
造成数据丢失的原因
-
程序错误
-
人为操作错误
-
运算错误
-
磁盘故障
-
灾难(如火灾、地震)和盗窃
-
数据库备份的分类
从物理与逻辑的角度,备份可分为
- 物理备份:对数据库操作系统的物理文件(如数据文件、日志文件等)的备份
- 物理备份方法
- 冷备份(脱机备份):是在关闭数据库的时候进行的
- 热备份(联机备份):数据库处于运行状态,依赖于数据库的日志文件
- 温备份:数据库锁定表格(不可写入但可读)的状态下进行备份操作
- 物理备份方法
- 逻辑备份:对数据库逻辑组件(如:表等数据库对象)的备份
常见的备份方法
- 物理冷备
- 备份时数据库处于关闭状态,直接打包数据库文件
- 备份速度快,恢复时也是最简单的
- 专用备份工具mydump或mysqlhotcopy
- mysqldump常用的逻辑备份工具
- mysqlhotcopy仅拥有备份MylSAM和ARCHIVE表
- 启用二进制日志进行增量备份
- 进行增量备份,需要刷新二进制日志
- 第三方工具备份
- 免费的MvSQL热备份软件PerconaXtraBackup
冷备份
bash
# 备份(推荐写法)
[root@mysql01 ~]# systemctl stop mysqld # 先停止服务
[root@mysql01 ~]# cd /usr/local/mysql/data
[root@mysql01 data]# mkdir /mysql_bak
[root@mysql01 data]# tar czf /mysql_bak/mysql-backup-$(date +%F).tar.gz *
[root@mysql01 data]# systemctl start mysqld # 备份完成后启动服务
#测试服务正常
# 删除数据
[root@mysql01 ~]# systemctl stop mysqld # 先停止服务
[root@mysql01 ~]# rm -rf /usr/local/mysql/data/* # 清空数据目录(谨慎操作!)
#再次开启测试,发现数据库坏了
[root@mysql01 ~]# systemctl start mysqld
#停止数据库,恢复数据库
[root@mysql01 ~]# systemctl stop mysqld
[root@mysql01 ~]# tar xzf /mysql_bak/mysql-backup-2025-10-15.tar.gz -C /usr/local/mysql/data/
[root@mysql01 ~]# chown -R mysql:mysql /usr/local/mysql/data # 恢复权限
[root@mysql01 ~]# systemctl start mysqld # 启动服务
#再次测试,发现数据库恢复了
逻辑备份
bash
#备份数据库
[root@mysql01 ~]# systemctl start mysqld
[root@mysql01 ~]# mysqldump -u root -p school > /mysql_bak/school.sql
Enter password:
[root@mysql01 ~]# ls /mysql_bak/school.sql
mysql_bak/school.sql
[root@mysql01 ~]# cat /mysql_bak/school.sql
#备份多个数据库
[root@mysql01 ~]# mysqldump -u root -p --databases school mysql > /mysql_bak/school-mysql.sql
Enter password:
[root@mysql01 ~]# cat /mysql_bak/school-mysql.sql
#备份所有数据库
[root@mysql01 ~]# mysqldump -u root -p --opt --all-databases > /mysql_bak/all.sql
Enter password:
[root@mysql01 ~]# cat /mysql_bak/all.sql
#备份整个表
[root@mysql01 ~]# mysqldump -u root -p school info > /mysql_bak/info.sql
Enter password:
[root@mysql01 ~]# cat /mysql_bak/info.sql
恢复数据
bash
[root@mysql01 ~]# mysql -u root -p
Enter password:
mysql> use school
mysql> show tables;
+------------------+
| Tables_in_school |
+------------------+
| info |
+------------------+
1 row in set (0.00 sec)
mysql> drop table info;
Query OK, 0 rows affected (0.01 sec)
mysql> source /mysql_bak/info.sql
mysql> show tables;
+------------------+
| Tables_in_school |
+------------------+
| info |
+------------------+
1 row in set (0.00 sec)
增量备份
bash
[root@mysql01 ~]# vim /etc/my.cnf
------------------------
[mysqld]
log-bin=mysql-bin #这段下面最后加一行
[root@web-server ~]# systemctl restart mysqld.service
[root@mysql01 ~]# ls /usr/local/mysql/data/
auto.cnf client-cert.pem ibdata1 ibtmp1 mysql-bin.index public_key.pem server-key.pem
ca-key.pem client-key.pem ib_logfile0 mysql performance_schema school sys
ca.pem ib_buffer_pool ib_logfile1 mysql-bin.000001 private_key.pem server-cert.pem
#先进行完整性备份
[root@mysql01 ~]# mysqldump -uroot -p school > /opt/school.sql
Enter password:
#日志刷新生效
[root@mysql01 ~]# mysqladmin -uroot -p flush-logs
Enter password:
#新产生的mysql-bin.000002只记录上次刷新后的操作
[root@mysql01 ~]# ls /usr/local/mysql/data/
auto.cnf client-cert.pem ibdata1 ibtmp1 mysql-bin.000002 private_key.pem server-cert.pem
ca-key.pem client-key.pem ib_logfile0 mysql mysql-bin.index public_key.pem server-key.pem
ca.pem ib_buffer_pool ib_logfile1 mysql-bin.000001 performance_schema school sys
[root@mysql01 ~]# mysql -uroot -p
Enter password:
----------------------------------------
mysql> use school;
Reading table information for completion of table and column names
You can turn off this feature to get a quicker startup with -A
Database changed
mysql> select * from info;
+----+--------+-------+---------+-------+
| id | name | score | address | hobby |
+----+--------+-------+---------+-------+
| 1 | 唐三 | 90.00 | 广州 | 1 |
| 2 | 叶凡 | 91.00 | 伦敦 | 2 |
| 4 | 曹操 | 66.50 | 合肥 | 4 |
+----+--------+-------+---------+-------+
3 rows in set (0.00 sec)
#再次插入数据生产增量备份
mysql> insert into info (name,score,address,hobby) values ('美猴王',75,'武汉',1);
Query OK, 1 row affected (0.00 sec)
mysql> exit
Bye
[root@mysql01 ~]# mysqladmin -uroot -p flush-log
Enter password:
#新产生mysql-bin.000003日志记录insert操作
[root@mysql01 ~]# ls /usr/local/mysql/data/
auto.cnf client-cert.pem ibdata1 ibtmp1 mysql-bin.000002 performance_schema school sys
ca-key.pem client-key.pem ib_logfile0 mysql mysql-bin.000003 private_key.pem server-cert.pem
ca.pem ib_buffer_pool ib_logfile1 mysql-bin.000001 mysql-bin.index public_key.pem server-key.pem
[root@mysql01 ~]# mysql -uroot -p
Enter password:
---------------------------------------------------------------
mysql> use school;
Reading table information for completion of table and column names
You can turn off this feature to get a quicker startup with -A
Database changed
mysql> insert into info (name,score,address,hobby) values ('超人',83,'上海',2);
Query OK, 1 row affected (0.00 sec)
mysql> select * from info;
+----+-----------+-------+---------+-------+
| id | name | score | address | hobby |
+----+-----------+-------+---------+-------+
| 1 | 唐三 | 90.00 | 广州 | 1 |
| 2 | 叶凡 | 91.00 | 伦敦 | 2 |
| 4 | 曹操 | 66.50 | 合肥 | 4 |
| 5 | 美猴王 | 75.00 | 武汉 | 1 |
| 6 | 超人 | 83.00 | 上海 | 2 |
+----+-----------+-------+---------+-------+
5 rows in set (0.00 sec)
mysql> exit
Bye
#刷新日志生效
[root@mysql01 ~]# mysqladmin -uroot -p flush-log
Enter password:
#环境准备
[root@mysql01 ~]# mysql -uroot -p
Enter password:
--------------------------------------------------------------
mysql> use school;
Reading table information for completion of table and column names
You can turn off this feature to get a quicker startup with -A
Database changed
#删除内容
mysql> delete from info where id=6;
Query OK, 1 row affected (0.00 sec)
mysql> delete from info where id=5;
Query OK, 1 row affected (0.01 sec)
mysql> select * from info;
+----+--------+-------+---------+-------+
| id | name | score | address | hobby |
+----+--------+-------+---------+-------+
| 1 | 唐三 | 90.00 | 广州 | 1 |
| 2 | 叶凡 | 91.00 | 伦敦 | 2 |
| 4 | 曹操 | 66.50 | 合肥 | 4 |
+----+--------+-------+---------+-------+
3 rows in set (0.00 sec)
mysql> exit
Bye
[root@mysql01 ~]# ls /usr/local/mysql/data/
auto.cnf client-cert.pem ibdata1 ibtmp1 mysql-bin.000002 mysql-bin.index public_key.pem server-key.pem
ca-key.pem client-key.pem ib_logfile0 mysql mysql-bin.000003 performance_schema school sys
ca.pem ib_buffer_pool ib_logfile1 mysql-bin.000001 mysql-bin.000004 private_key.pem server-cert.pem
#查看日志文件,vim看日志是乱码
[root@mysql01 ~]# mysqlbinlog --no-defaults --base64-output=decode-rows -v /usr/local/mysql/data/mysql-bin.000003
[root@mysql01 ~]# mysqlbinlog --no-defaults --base64-output=decode-rows -v /usr/local/mysql/data/mysql-bin.000004
#恢复操作,恢复时如果被拒绝,是有其他mysql进程占用了
[root@mysql01 ~]# mysqlbinlog --no-defaults /usr/local/mysql/data/mysql-bin.000003 | mysql -uroot -p
Enter password:
#验证
[root@web-server ~]# mysql -uroot -p
Enter password:
---------------------------------------------------------------
mysql> select * from info;
+----+--------+-------+---------+-------+
| id | name | score | address | hobby |
+----+--------+-------+---------+-------+
| 1 | 唐三 | 90.00 | 广州 | 1 |
| 2 | 叶凡 | 91.00 | 伦敦 | 2 |
| 4 | 曹操 | 66.50 | 合肥 | 4 |
| 6 | 超人 | 83.00 | 上海 | 2 |
+----+--------+-------+---------+-------+
4 rows in set (0.00 sec)