1.物理备份
- 冷备份:关闭数据库时进行
- 热备份:数据库运行时进行,依赖于数据库日志文件
- 温备份:数据库不可写入但可读的状态下进行
2.逻辑备份
- 对数据库的表或者对象进行备份
3.备份策略
- 完全备份:每次都备份完整的数据库
- 差异备份:只备份上一次完全备份之后的更新数据
- 增量备份:每次备份只备份上一次完全备份或增量备份之后的更新数据
4.备份方法和工具
- 物理冷备份:备份时数据库关闭,直接打包数据库文件;备份速度块,恢复时也简单
- 备份工具:mysqldump或者mysqlhoocopy
mysqldump备份速度慢(如果数据库超过100G,不建议使用) - 使用二进制日志进行增量备份
- 使用第三方工具:XtraBackup
一、物理备份
使用物理冷备份
powershell
systemctl stop mysqld #先关闭主机的mysql服务
mkdir mysqlbackup #创建一个文件夹之后将数据库压缩包放入其中
tar -zcvf /usr/local/src/mysqlbackup/mysql_full_$(date -d "-1 day" +%Y%m%d).tar.gz /var/lib/mysql/data/ #备份 /var/lib/mysql/data下的所有
scp /usr/local/src/mysqlbackup/mysql_full_20240828.tar.gz 192.168.222.213:/usr/local/src/mysql/ #使用scp命令将数据库拷贝到要备份的主机上
之后在备份主机上进行压缩
powershell
systemctl stop mysqld #先停止mysql服务
tar -xf mysql_full_20240828.tar.gz #解压
mv /data/ /var/lib/mysql/ #再将压缩后的数据库复制到目标目录下即可
使用工具mysqldump进行冷备份
可以将指定的库、表导出为SQL脚本
powershell
1.完整备份一个或者多个完整的数据库(包含其中的表)
mysqldump -u root -p[密码] --databases 库名1 [库名2] ... > /备份路径/备份文件名.sql
mysqldump -u root -ppassword --databases exam_system > /usr/local/src/mysqlbackup/exam_system.sql
遇到的问题:mysqldump: [Warning] Using a password on the command line interface can be insecure
解决办法:在my.cnf中添加
[mysqldump]
user=root
password=password
然后不需要使用账号密码即可进行备份:
mysqldump --databases exam_system > /usr/local/src/mysqlbackup/exam_system.sql
如果不加 --databases ,只备份库中的表,不会备份库
2.备份整个数据库
mysqldump -u root -p[密码] --all-databases > /备份路径/备份文件名.sql
mysqldump --all-databases > /usr/local/src/mysqlbackup/all.sql
3.备份指定库中的部分表
mysqldump -u root -p[密码] 库名 [表名1] [表名2] ... > /备份路径/备份文件名.sql
mysqldump exam_system answer question > /usr/local/src/mysqlbackup/answerAndquestion.sql
备份成sql语句后进行恢复
1.通过source命令恢复
登录备份主机的mysql
mysql -uroot -p
执行命令:mysql> source /usr/local/src/mysql/exam_system.sql;
2.通过mysql命令恢复
mysql -u 用户名 -p[密码] < 库备份脚本的路径
mysql -uroot -ppassword < /usr/local/src/mysql/exam_system.sql
当备份的sql中只包含表的备份,而不是库的备份时,恢复的时候需要指定数据库,并且目标库必须存在
mysql -uroot -ppassword exam_system < /usr/local/src/mysqlbackup/answerAndquestion.sql
二、增量备份(需要用到mysql的二进制日志)
1.开启二进制日志功能:
vim /etc/my.cnf
[mysqld]
log-bin=mysql-bin
binlog_format = MIXED
#可选,指定二进制日志(binlog)的记录格式为 MIXED
server-id = 1
#二进制日志(binlog)有3种不同的记录格式:STATEMENT(基于SQL语句)、ROW(基于行)、MIXED(混合模式),默认格式是STATEMENT
通过刷新二进制日志文件实现增量备份(和上面同理,在my.cnf中添加 [mysqladmin] 的账号密码在此处就不需要使用账号密码了)
mysqladmin flush-logs
查看二进制文件内容
mysqlbinlog --no-defaults --base64-output=decode-rows -v 二进制文件(绝对路径)
mysqlbinlog --no-defaults --base64-output=decode-rows -v /var/lib/mysql/binlog.000001
2.进行增量备份操作
一般恢复手段
2.1.先对数据库exam_system中的answer表做完全备份
mysqldump exam_system answer > /usr/local/src/mysqlbackup/answer.sql
2.2.在answer中添加新数据
2.3.再刷新二进制日志文件
mysqladmin flush-logs
2.4.新增数据
2.5.再次刷新二进制日志文件
2.6.进行备份,备份的是倒数第二个二进制日志文件,不是最新的那个
mv -f /var/lib/mysql/binlog.000012 /usr/local/src/mysqlbackup/binlog.000012_backup
2.7.将其拷贝到目的主机上
scp /usr/local/src/mysqlbackup/binlog.000012_backup 192.168.222.213:/var/lib/mysql
2.8.通过管道符导入的方式进行增量备份
mysqlbinlog --no-defaults /usr/local/src/mysqlbackup/binlog.000012_backup | mysql -uroot -ppassword
断点恢复手段
2.1.删除一条id=7的数据
2.2 #查看二进制文件
mysqlbinlog --no-defaults --base64-output=decode-rows -v /usr/local/src/mysqlbackup/binlog.000012_backup
查询结果
# The proper term is pseudo_replica_mode, but we use this compatibility alias
# to make the statement usable on server versions 8.0.24 and older.
/*!50530 SET @@SESSION.PSEUDO_SLAVE_MODE=1*/;
/*!50003 SET @OLD_COMPLETION_TYPE=@@COMPLETION_TYPE,COMPLETION_TYPE=0*/;
DELIMITER /*!*/;
# at 4
#240829 22:20:58 server id 1 end_log_pos 126 CRC32 0x5a25dbb2 Start: binlog v 4, server v 8.0.39 created 240829 22:20:58
# at 126
#240829 22:20:58 server id 1 end_log_pos 157 CRC32 0xb00ab440 Previous-GTIDs
# [empty]
# at 157
#240829 22:21:43 server id 1 end_log_pos 236 CRC32 0x11b51759 Anonymous_GTID last_committed=0 sequence_number=1 rbr_only=yes original_committed_timestamp=1724941303404462 immediate_commit_timestamp=1724941303404462 transaction_length=330
/*!50718 SET TRANSACTION ISOLATION LEVEL READ COMMITTED*//*!*/;
# original_commit_timestamp=1724941303404462 (2024-08-29 22:21:43.404462 CST)
# immediate_commit_timestamp=1724941303404462 (2024-08-29 22:21:43.404462 CST)
/*!80001 SET @@session.original_commit_timestamp=1724941303404462*//*!*/;
/*!80014 SET @@session.original_server_version=80039*//*!*/;
/*!80014 SET @@session.immediate_server_version=80039*//*!*/;
SET @@SESSION.GTID_NEXT= 'ANONYMOUS'/*!*/;
# at 236
#240829 22:21:43 server id 1 end_log_pos 318 CRC32 0xc8f08fde Query thread_id=17 exec_time=0 error_code=0
SET TIMESTAMP=1724941303/*!*/;
SET @@session.pseudo_thread_id=17/*!*/;
SET @@session.foreign_key_checks=1, @@session.sql_auto_is_null=0, @@session.unique_checks=1, @@session.autocommit=1/*!*/;
SET @@session.sql_mode=1168113696/*!*/;
SET @@session.auto_increment_increment=1, @@session.auto_increment_offset=1/*!*/;
/*!\C utf8mb4 *//*!*/;
SET @@session.character_set_client=255,@@session.collation_connection=255,@@session.collation_server=255/*!*/;
SET @@session.lc_time_names=0/*!*/;
SET @@session.collation_database=DEFAULT/*!*/;
/*!80011 SET @@session.default_collation_for_utf8mb4=255*//*!*/;
BEGIN
/*!*/;
# at 318
#240829 22:21:43 server id 1 end_log_pos 392 CRC32 0x792677a7 Table_map: `exam_system`.`answer` mapped to number 148
# has_generated_invisible_primary_key=0
# at 392
#240829 22:21:43 server id 1 end_log_pos 456 CRC32 0x59ebb7ee Write_rows: table id 148 flags: STMT_END_F
### INSERT INTO `exam_system`.`answer`
### SET
### @1=6
### @2='因数'
### @3=NULL
### @4='因数'
### @5=2
### @6=NULL
# at 456
#240829 22:21:43 server id 1 end_log_pos 487 CRC32 0xe2a746e6 Xid = 1415
COMMIT/*!*/;
# at 487
#240829 22:22:03 server id 1 end_log_pos 566 CRC32 0x80070a3c Anonymous_GTID last_committed=1 sequence_number=2 rbr_only=yes original_committed_timestamp=1724941323438391 immediate_commit_timestamp=1724941323438391 transaction_length=348
/*!50718 SET TRANSACTION ISOLATION LEVEL READ COMMITTED*//*!*/;
# original_commit_timestamp=1724941323438391 (2024-08-29 22:22:03.438391 CST)
# immediate_commit_timestamp=1724941323438391 (2024-08-29 22:22:03.438391 CST)
/*!80001 SET @@session.original_commit_timestamp=1724941323438391*//*!*/;
/*!80014 SET @@session.original_server_version=80039*//*!*/;
/*!80014 SET @@session.immediate_server_version=80039*//*!*/;
SET @@SESSION.GTID_NEXT= 'ANONYMOUS'/*!*/;
# at 566
#240829 22:22:03 server id 1 end_log_pos 648 CRC32 0xd97b61d5 Query thread_id=17 exec_time=0 error_code=0
SET TIMESTAMP=1724941323/*!*/;
BEGIN
/*!*/;
# at 648
#240829 22:22:03 server id 1 end_log_pos 722 CRC32 0x066adb4a Table_map: `exam_system`.`answer` mapped to number 148
# has_generated_invisible_primary_key=0
# at 722
#240829 22:22:03 server id 1 end_log_pos 804 CRC32 0x23e50863 Write_rows: table id 148 flags: STMT_END_F
### INSERT INTO `exam_system`.`answer`
### SET
### @1=7
### @2='多音字,少银子'
### @3=NULL
### @4='少银子'
### @5=1
### @6=NULL
# at 804
#240829 22:22:03 server id 1 end_log_pos 835 CRC32 0xeb4d3e35 Xid = 1418
COMMIT/*!*/;
# at 835
#240829 22:22:07 server id 1 end_log_pos 879 CRC32 0x29dc8064 Rotate to binlog.000015 pos: 4
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*/;
2.3.基于位置恢复,恢复id=7的数据
mysqlbinlog --no-defaults --start-position='648' /var/lib/mysql/binlog.000014 | mysql -uroot -ppassword
或者
mysqlbinlog --no-defaults --start-position='648' --stop-position='835' /var/lib/mysql/binlog.000014 | mysql -uroot -ppassword
2.4.基于时间恢复
mysqlbinlog --no-defaults --start-datetime='2024-08-29 22:22:03' /var/lib/mysql/binlog.000014 | mysql -uroot -ppassword
bash
MySQL 的日志默认保存位置为 /usr/local/mysql/data
vim /etc/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
##慢查询日志,用来记录所有执行时间超过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 -u root -p
#查看通用查询日志是否开启
show variables like 'general%';
#查看二进制日志是否开启
show variables like 'log_bin%';
#查看二进制日志的格式
show variables like '%binlog_format%';
#查看慢查询日功能是否开启
show variables like '%slow%';
#查看慢查询时间设置
show variables like 'long_query_time';
#在数据库中设置开启慢查询的方法
set global slow_query_log=ON;
powershell
[root@localhost mysql]# cat backupmysqlbinlog.sh
#!/bin/bash
#增量备份mysql数据库
TODAY=$(date +%Y%m%d)
YESTERDAY=$(date -d '-1 day' +%Y%m%d)
DATA_HOME=/var/lib/mysql/
USERNAME=root
PASSWORD=password
##备份二进制日志索引文件 binlog.index
/usr/bin/cp -f $DATA_HOME/binlog.index /opt/backup/binlog-$TODAY.index
##判断是否存在前一天的日志索引文件,如果存在则通过反向查询获取今天生成的二进制日志文件
if [ -f /opt/backup/binlog-$YESTERDAY.index ]
then
COUNT=$(cat /opt/backup/binlog-$TODAY.index | grep -v `/opt/backup/binlog-$YESTERDAY.index` | awk -F '/' '{print $2}')
else
COUNT=$(cat /opt/backup/binlog-$TODAY.index | awk -F '/' '{print $2}')
fi
#刷新二进制日志文件
mysqldump -u"$USERNAME" -p"$PASSWORD" flush-logs &> /dev/null
#使用循环备份当天的二进制日志
for BINLOG in $COUNT
do
/usr/bin/mv -f "$DATA_HOME/$BINLOG" "/opt/backup/$BINLOG-$TODAY"
done