MySQL数据库的物理备份逻辑备份和恢复

Posted handsomeboy-东

tags:

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

一、数据备份

  • 在生产环境中,数据的安全是最为重要的,任何数据的丢失都可能造成严重的后果,因此需要对数据进行备份来增加其安全性

1.1、数据备份的类别

 - 物理备份:对数据库操作系统的物理文件(如数据文件、日志文件等)的备份
方法:
(1)冷备份:在关闭数据库的时候进行
(2)热备份:数据库处于运行状态,依赖于数据库的日志文件
(3)温备份:数据库锁定表格(不可写入但可读)的状态下进行备份操作
 - 逻辑备份:对数据库逻辑组件(如:表等数据库对象)的备份
方法:
(1)完全备份:对数据库的整个内容进行备份,备份和恢复操作都非常简单方便,但是完全备份占用空间大,备份时间也长
(2)增量备份:只以上次完全备份或增量备份的时间点对后面修改的文件进行备份,备份数量小,占用空间小,备份速度快,但恢复需要从上一次的完整备份开始到最后一次增量备份之间的所有增量依次恢复,如果中间损坏了一次,则将导致数据的丢失
(3)差异备份;对上次完全备份后被修改过的所有文件进行备份,其备份数据量会越来越大,恢复数据只要恢复上次的完全备份和最佳的一次差异备份

1.2、mysql日志

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

1.2.1、日志类型和作用

  • redo:重做日志,确保日志的持久性,防止放生故障,重启数据库会进行redo log执行重做,达到事务一致性
  • undo:回滚日志,保证数据的原子性,记录事务发生之前的一个版本,用于回滚
  • errorlog:错误日志,记录发生的错误信息
  • slow query log:慢查询日志,记录执行时间过长的sql,只记录执行成功的,在于提醒优化
  • bin log:二进制日志,用于主从复制,实现主从同步,记录了数据库中执行的语句
  • relay log :中继日志,用于主从同步,将主库发来的bin log保存在本地,然后从库进行回放,在集群模式下需要使用
  • general log :普通日志,记录数据库操作明细,默认关闭,因为开启会降低数据库性能

1.2.2、配置文件

  • 设置错误日志
vim /etc/my.cnf			#修改配置文件
[musqld]
log-error=/usr/local/mysql/data/mysql_error.log			#在配置文件中mysqld下添加错误日志路径

#通用查询日志,用来记录MySQL的所有连接和语句,默认是关闭的
general_log=ON
general_log_file=/usr/local/mysql/data/mysql_general.log


#二进制日志,用来记录所有更新了数据或者已经潜在更新了数据的语句,记录了数据的更改,可用于数据恢复,默认已开启
log-bin=mysql-bin	

#慢查询日志,用来记录所有执行时间超过long_query_time秒的语句,可以找到哪些查询语句执行时间长,以便于优化,默认时关闭的
slow_query_log=ON
slow_query_log_file=/usr/local/mysql/data/mysql_slow_query_.log
long_query_time=5		#设置5秒执行的居于被记录,默认为10秒
  • 查询日志设置

mysql> show variables like 'general%';
+------------------+---------------------------------+
| Variable_name    | Value                           |
+------------------+---------------------------------+
| general_log      | OFF                             |
| general_log_file | /usr/local/mysql/data/mysql.log |
+------------------+---------------------------------+
2 rows in set (0.00 sec)

mysql> show variables like 'log_bin%';
+---------------------------------+-------+
| Variable_name                   | Value |
+---------------------------------+-------+
| log_bin                         | OFF   |
| log_bin_basename                |       |
| log_bin_index                   |       |
| log_bin_trust_function_creators | OFF   |
| log_bin_use_v1_row_events       | OFF   |
+---------------------------------+-------+
5 rows in set (0.00 sec)

mysql> show variables like '%slow%';
+---------------------------+--------------------------------------+
| Variable_name             | Value                                |
+---------------------------+--------------------------------------+
| log_slow_admin_statements | OFF                                  |
| log_slow_slave_statements | OFF                                  |
| slow_launch_time          | 2                                    |
| slow_query_log            | OFF                                  |
| slow_query_log_file       | /usr/local/mysql/data/mysql-slow.log |
+---------------------------+--------------------------------------+
5 rows in set (0.01 sec)

mysql> show variables like 'long_query_time';
+-----------------+-----------+
| Variable_name   | Value     |
+-----------------+-----------+
| long_query_time | 10.000000 |
+-----------------+-----------+
1 row in set (0.01 sec)
  • 添加日志

[root@mysql ~]# systemctl restart mysqld.service 
[root@mysql ~]# netstat -antp | grep 3306
tcp6       0      0 :::3306                 :::*                    LISTEN      24452/mysqld 
[root@mysql ~]# cd /usr/local/mysql/data/
[root@mysql data]# ls						#查看日志文件
auto.cnf        ibdata1      ib_logfile1  mysql             mysql-bin.index  mysql_slow_query.log  sys
ib_buffer_pool  ib_logfile0  ibtmp1       mysql-bin.000001  mysql_error.log  performance_schema    whd
##mysql-bin.000001 :二进制文件
##mysql-bin.index :二进制文件的索引文件
[root@mysql data]#  cat mysql-bin.index 
./mysql-bin.000001
[root@mysql data]# systemctl restart mysqld.service 
[root@mysql data]# ls
auto.cnf        ib_logfile0  mysql             mysql-bin.index       performance_schema
ib_buffer_pool  ib_logfile1  mysql-bin.000001  mysql_error.log       sys
ibdata1         ibtmp1       mysql-bin.000002  mysql_slow_query.log  whd

##每次重启都会产生个二进制日志文件
mysql> show variables like '%slow%';		#再查询二进制文件
+---------------------------+--------------------------------------------+
| Variable_name             | Value                                      |
+---------------------------+--------------------------------------------+
| log_slow_admin_statements | OFF                                        |
| log_slow_slave_statements | OFF                                        |
| slow_launch_time          | 2                                          |
| slow_query_log            | ON                                         |
| slow_query_log_file       | /usr/local/mysql/data/mysql_slow_query.log |
+---------------------------+--------------------------------------------+
5 rows in set (0.01 sec)

1.3、常见的备份方法

  • 物理备份:备份时数据库处于关闭状态,直接打包数据库文件,备份速度快,恢复时也是最简单的
  • 专用备份工具mysqldump或者mysqlhotcopy(仅能备份MyISAM和ARCHIVE表)
  • 启用二进制日志进行增量备份,需要刷新二进制日志
  • 第三方工具备份:免费的MySQL热备份软件Percona,XtraBackup,mysqlbackup

二、备份及其恢复

2.1、物理备份与恢复

  • 物理冷备份与恢复

  • mysqldump备份与恢复
    InnoDB存储引擎的数据库在磁盘上存储成三个文件,db.opt(表属性文件)、表名.frm(表结构文件)、表名.ibd(表数据文件)

1)完全备份一个或多个完整的库
mysqldump -u root -p --databases 库名1 库名2 > /备份路径/备份文件名.sql
mysql -uroot -p -e 'select * from 库名.表名;'		#可以不同进入mysql数据库进行操作mysql数据库命令 

2)完全备份mysql服务器整个库
mysqldump -uroot -p --all-databases > /备份路径/all.sql

3)完全备份指定库中的表
mysqldump -uroot -p 库名 表名1 表名2 >/备份路径/备份文件名.sql
[root@mysql mysql]# mysqldump -uroot -p --databases whd > /opt/whd.sql	#备份单个库
Enter password: ***
[root@mysql mysql]# ll /opt/whd.sql 
-rw-r--r--. 1 root root 1955 713 20:17 /opt/whd.sql
[root@mysql mysql]# mysqldump -uroot -p --all-databases > /opt/all.sql	#备份整个mysql所有库
Enter password: 
[root@mysql mysql]# ll /opt/all.sql 
-rw-r--r--. 1 root root 781887 713 20:20 /opt/all.sql
[root@mysql mysql]# mysqldump -uroot -p whd test > /opt/test.sql	#备份某个表,-p后面加-d表示只备份表结构
Enter password: 
[root@mysql mysql]# ll /opt/test.sql 
-rw-r--r--. 1 root root 1821 713 20:27 /opt/test.sql
  • mysqldump备份与恢复
[root@mysql mysql]# mkdir /bachup
[root@mysql mysql]# mysqldump -uroot -p --databases whd > /bachup/a-$(date +%F).sql
Enter password: 
[root@mysql mysql]# mysqldump -uroot -p --all-databases > /bachup/all-databases-$(date +%F).sql
Enter password: 
[root@mysql mysql]# cd /bachup
[root@mysql bachup]# ls
a-2021-07-14.sql  all-databases-2021-07-14.sql
mysql> show databases;
+--------------------+
| Database           |
+--------------------+
| information_schema |
| mysql              |
| performance_schema |
| sys                |
| whd                |
+--------------------+
5 rows in set (0.00 sec)

mysql> drop database whd;
Query OK, 1 row affected (0.02 sec)

mysql> show databases;
+--------------------+
| Database           |
+--------------------+
| information_schema |
| mysql              |
| performance_schema |
| sys                |
+--------------------+
4 rows in set (0.00 sec)

mysql> source /bachup/a-2021-07-14.sql;				#在数据库中恢复
Query OK, 0 rows affected (0.00 sec)

Query OK, 0 rows affected (0.00 sec)

Query OK, 0 rows affected (0.00 sec)

Query OK, 0 rows affected (0.00 sec)

Query OK, 0 rows affected (0.00 sec)

Query OK, 0 rows affected (0.00 sec)

mysql> show databases;
+--------------------+
| Database           |
+--------------------+
| information_schema |
| mysql              |
| performance_schema |
| sys                |
| whd                |
+--------------------+
[root@mysql bachup]# mysql -uroot -p < /bachup/a-2021-07-14.sql 	#也可以直接在命令行恢复

恢复表时source跟恢复库一样,用mysql命令的话需要指定数据库,并且该库必须存在

2.2、MySQL增量备份和恢复

  • 一般恢复:将所有备份的二进制日志文件全部恢复
  • 基于位置恢复:数据库在某一时间点可能既有错误的操作也有正确的操作,可以基于精准的位置跳过错误的操作,发生错误节点之前的一个节点,上一次正确操作的位置停止
  • 基于时间点恢复:跳过某个发生错误的时间点实现数据恢复,在错误时间点停止,在下一个正确时间点开始
[root@mysql bachup]# vim /etc/my.cnf		#开启二进制文件
log-bin=mysql-bin
binlog_fromat = MIXED

二进制日志有三种不同的记录格式:

  • statement:每一条涉及被修改的sql都会被记录在binlog中,缺点是日质量过大,

  • ROW:只记录变动的记录,不记录sql的上下文环境,缺点,如果遇到update set where true 那么binlog的数据量会越来越大

  • MIXED:一般的语句使用statement,函数使用ROW方式存储

  • 查看二进制文件

[root@mysql data]# mysqlbinlog --no-defaults --base64-output=decode-rows -v ./mysql-bin.000001
/*!50530 SET @@SESSION.PSEUDO_SLAVE_MODE=1*/;
/*!50003 SET @OLD_COMPLETION_TYPE=@@COMPLETION_TYPE,COMPLETION_TYPE=0*/;
DELIMITER /*!*/;
# at 4				##at这里表示位置点
#210713 19:09:04 server id 1  end_log_pos 123 CRC32 0x17d2d3ee 	Start: binlog v 4, server v 5.7.20-log created 210713 19:09:04 at startup
ROLLBACK/*!*/;
# at 123
#210713 19:09:04 server id 1  end_log_pos 154 CRC32 0x4b7d48dd 	Previous-GTIDs
# [empty]
# at 154  210713 19:09:04 server id 1  end_log_pos 177 CRC32 0x3c823e3e 	Stop
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*/;
  • 生成新的二进制文件,进行增量备份
mysqladmin -uroot -p flush-logs		
#刷新二进制文件,相当于将上一个二进制文件复制一份
  • 基于二进制文件进行恢复
[root@mysql data]# mysqlbinlog --no-defaults /usr/local/mysql/data/mysql-bin.000001 | mysql -uroot -p
##缺点:它是基于二进制文件全部内容进行恢复,他无法保证上一个二进制文件中内容的修改是否影响这次的恢复
如:上一个二进制文件中删除了一个库中的表,这里进行恢复的话就会报错,无法找到那张表
  • 基于位置点恢复
##仅恢复到位置点664之前的数据
mysqlbinlog --no-defaults --stop-position='663' /opt/mysql-bin.000001 | mysql -uroot -p

##仅恢复由664开始后的数据
mysqlbinlog --no-defaults --start-position='664' /opt/mysql-bin.000001 | mysql -uroot -p

##仅恢复由400开始到664为止的数据
mysqlbinlog --no-defaults --start-position='400' --stop-position='664' /opt/mysql-bin.000001 | mysql -uroot -p

总结

  • MySQL备份有物理备份(热备份、冷备份、温备份),逻辑备份(完全备份、差异备份,增量备份)

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

入门MySQL——备份与恢复

Mysql完全备份与恢复

MySQL系列——MySQL备份和恢复

MySQL备份与恢复

MySQL的备份与恢复具体解释

mysql完全备份与恢复