Mysql备份方式与热温冷备份
备份技术:
https://cloud.tencent.com/developer/article/2096467
https://blog.csdn.net/qq_43108153/article/details/136790531
热备冷备:
热备份: 指的是当数据库进行备份时, 数据库的读写操作均不是受影响
温备份: 指的是当数据库进行备份时, 数据库的读操作可以执行, 但是不能执行写操作
冷备份: 指的是当数据库进行备份时, 数据库不能进行读写操作, 即数据库要下线
物理与逻辑备份:
物理备份: 一般就是通过tar,cp等命令直接打包复制数据库的数据文件达到备份的效果
逻辑备份: 一般就是通过特定工具从数据库中导出数据并另存备份(逻辑备份会丢失数据精度)
全量备份与增量备份:
全量备份:备份数据库中的所有数据和对象。这是最基本的备份类型。
增量备份:仅备份自上次备份以来发生变化的数据。这种方式可以节省存储空间,但恢复时需要依次应用所有增量备份。
备份工具
这里我们列举出常用的几种备份工具
mysqldump : 逻辑备份工具, 适用于所有的存储引擎, 支持温备、完全备份、部分备份、对于InnoDB存储引擎支持热备
cp, tar 等归档复制工具: 物理备份工具, 适用于所有的存储引擎, 冷备、完全备份、部分备份
lvm2 snapshot: 几乎热备, 借助文件系统管理工具进行备份
mysqlhotcopy: 名不副实的的一个工具, 几乎冷备, 仅支持MyISAM存储引擎
xtrabackup: 一款非常强大的InnoDB/XtraDB热备工具, 支持完全备份、增量备份, 由percona提供
https://cloud.tencent.com/developer/article/2096467
以上的几种解决方案分别针对于不同的场景:
如果数据量较小, 可以使用第一种方式, 直接复制数据库文件
如果数据量还行, 可以使用第二种方式, 先使用mysqldump对数据库进行完全备份, 然后定期备份BINARY LOG达到增量备份的效果
如果数据量一般, 而又不过分影响业务运行, 可以使用第三种方式, 使用
lvm2的快照对数据文件进行备份, 而后定期备份BINARY LOG达到增量备份的效果如果数据量很大, 而又不过分影响业务运行, 可以使用第四种方式, 使用
xtrabackup进行完全备份后, 定期使用xtrabackup进行增量备份或差异备份
mysql数据库备份脚本
service crond start //启动服务
service crond stop //关闭服务
service crond restart //重启服务
service crond reload //重新载入配置
service crond status //查看服务状态 简单版本
添加定时任务
# crontab –e
#添加环境变量
SHELL=/bin/bash
PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin
#再添加一条具体的任务
0 1 * * * . /etc/profile && /root/dump/backup.sh
#保存定时任务
#修改脚本执行权限
chmod +x /root/dump/backup.sh
#如果crontab未执行成功. 有可能是环境变量未设置
1.crontab的任务上增加PATH
2.执行的backup.sh中指定mysql绝对路径,
linux的crond服务不会将mysqldump的脚本在mysql安装路径bin下执行的。故需要在脚本前面手动指定mysql的bin路径,即:/usr/local/mysql/bin/mysqldump -uroot -pBroot_2020 tlj-ptmis_basic-b | gzip > /mysqlbackup/backupfiles/tlj-ptmis_basic-b_$(date +%Y%m%d_%H%M%S).sql.gz创建备份脚本
#创建backup.sh脚本
#!/bin/bash
curday=`date +%Y%m%d%H%M%S`
backname="feiyun.sql."
filename=$backname$curday
if [ ! -f "$filename" ];then
mysqldump -u root -p123456 feiyun > $filename
else
filename="${backname}${curday}-1"
mysqldump -u root -p123456 feiyun > $filename
fihttps://cloud.tencent.com/developer/article/1524079?from=15425
电银备份脚本
#!/bin/bash
/var/www/shdy-packages/mysql-5.7.43/bin/mysqldump -u root -ppass@word111 --set-gtid-purged=OFF --databases xpos_dyb | gzip > /var/www/pro/xpos_dyb`date +%Y%m%d%H%M%S`.dump.gz#!/bin/bash
# 数据库配置
DB_USER="your_db_user"
DB_PASS="your_db_password"
DB_NAME="your_db_name"
BACKUP_DIR="/path/to/backup/directory"
DATE=$(date +%Y%m%d%H%M%S)
# 创建备份目录
mkdir -p $BACKUP_DIR
# 执行备份
mysqldump -u$DB_USER -p$DB_PASS $DB_NAME > $BACKUP_DIR/$DB_NAME-$DATE.sql
# 压缩备份文件
gzip $BACKUP_DIR/$DB_NAME-$DATE.sql
# 删除7天前的备份文件
find $BACKUP_DIR -type f -mtime +7 -name "*.sql.gz" -exec rm {} \;增量恢复
适用场景:
只能基于上一次的全量数据,恢复上次时间点到本次指定时间点的binlog
根据binlog日志,生成指定操作的反向sql语句.
基于上一次的全量数据,恢复指定点位/时间段的binlog数据,跳过错误的sql位置.
打开binlog
修改配置文件:/etc/my.cnf
log-bin=mysql-bin
binlog_format=MIXED
#查看
SHOW VARIABLES LIKE 'log_bin';
mysql> SHOW VARIABLES LIKE 'log_bin';
+---------------+-------+
| Variable_name | Value |
+---------------+-------+
| log_bin | ON |
+---------------+-------+
1 row in set (0.01 sec)
重启服务
SHOW VARIABLES LIKE 'binlog_format';
将返回一个结果集,其中包含当前的binlog格式。可能的值有:
ROW: 表示使用行模式(row-based replication),这是推荐的设置,因为它提供了更好的数据一致性。
STATEMENT: 表示使用语句模式(statement-based replication),在这种模式下,可能会丢失一些数据,因为它仅记录执行的SQL语句。
MIXED: 表示混合模式(mixed-based replication),在这种模式下,MySQL会根据需要自动切换行模式和语句模式二进制文件所在目录:
/usr/local/mysql/data
查看二进制内容命令:
mysqlbinlog --no-defaults --base64-output=decode-rows -v mysql-bin.000002
利用binlog查询执行的sql记录
#查找binlog
> mysqlbinlog --no-defaults --start-datetime="2024-07-16 14:50:27" --stop-datetime="2024-07-16 14:50:28" --base64-output=DECODE-ROWS --verbose binlog.000034 > cjh_get_parsed_binlog_2024-07-16-17-05.sql
##--base64-output=DECODE-ROWS --verbose
##字段命令的作用是base64解码:是因为binlog是Base64 编码的二进制数据,需要解码
如下内容:
###update xxx.xx
###where
### @1 = 1
## @2 = 1623
###SET
### @1 = 1
### @2 = 1555
#保存日志记录
mysqlbinlog --no-defaults --start-datetime="2024-07-16 14:50:27" --stop-datetime="2024-07-16 14:50:28" --base64-output=DECODE-ROWS --verbose binlog.000034 > cjh_get_parsed_binlog_2024-07-16-17-05.sql
#根据update生成反向sql
UPDATE 数据库.表名 SET @2的字段名 = @2 WHERE @1的字段名 = @1;刷新命令:会新增一个二进制文件
mysqladmin -u root -p flush-logs
恢复:
mysqlbinlog --no-defaults --base64-output=decode-rows -v mysql-bin.000003
1、从某一个点开始恢复到最后
mysqlbinlog --no-defaults --start-position='位置点' 文件名 | mysql -u root -p123456
2、从开头一直恢复到某个位置
mysqlbinlog --no-defaults --stop-position='位置点' 文件名 | mysql -u root -p
3、从指定点开始———指定结束点
mysqlbinlog --no-defaults --start-position='位置点' --stop-position'位置点' 文件名 | mysql -u root -p
查看位置点:
at后面的数字就是位置点
选commit后面的位置点
恢复被删除的表
# 查看 binlog 已启用
SHOW VARIABLES LIKE 'log_bin';
如果返回值为 ON,则已启用。
# 查找 binlog 文件
SHOW BINARY LOGS;
# 使用 mysqlbinlog 工具读取 binlog 文件
mysqlbinlog --start-datetime="2023-10-01 00:00:00" --stop-datetime="2023-10-01 23:59:59" binlog.000001
# 查找删除表的操作
# 使用 grep 来筛选出 DROP TABLE 语句:
mysqlbinlog binlog.000001 | grep 'DROP TABLE'
# 重放删除之前的操作
#确认了删除表之前的状态后,提取出在删除之前的 CREATE TABLE 语句,然后手动重新创建该表。
# 恢复数据
# 如果在 binlog 中找到插入数据的操作,可以通过相应的 SQL 语句恢复数据。
#注意事项
#进行此操作时请确保停止对数据库的写入,以避免数据不一致。
#操作前最好备份当前数据库状态,以防万一。
闪回实战
真实的闪回场景中,最关键的是能快速筛选出真正需要回滚的SQL。
我们使用开源工具binlog2sql来进行实战演练。binlog2sql由美团点评DBA团队(上海)出品,多次在线上环境做快速回滚。
首先我们安装binlog2sql:
shell> git clone https://github.com/danfengcao/binlog2sql.git
shell> cd binlog2sql
shell> pip install -r requirements.txt
-- 安装pip
# wget https://bootstrap.pypa.io/get-pip.py
# python get-pip.py
# pip -V #查看pip版本
/usr/lib/python2.7/site-packages (python 2.7)
# pip install -r requirements.txt背景:小明在11:44时误删了test库user表大批的数据,需要紧急回滚。
test库user表原有数据
mysql> select * from users;
+----+--------+---------------------+
| id | name | addtime |
+----+--------+---------------------+
| 1 | 小赵 | 2013-11-11 00:04:33 |
| 2 | 小钱 | 2014-11-11 00:04:48 |
| 3 | 小孙 | 2016-11-11 20:25:00 |
| 4 | 小李 | 2013-11-11 00:00:00 |
.........
+----+--------+---------------------+
16384 rows in set (0.04 sec)11:44时,user表大批数据被误删除。与此同时,正常业务数据是在继续写入的
mysql> delete from users where addtime>'2014-01-01';
Query OK, 16128 rows affected (0.18 sec)
mysql> select count(*) from users;
+----------+
| count(*) |
+----------+
| 261 |
+----------+使用flashback用户执行sql
select, super/replication client, replication slave权限建议授权
mysql > GRANT SELECT ,REPLICATION SLAVE,REPLICATION CLIENT ON *.* to flashback@ 'localhost' identified by 'flashback';
基本用法
解析出标准SQL
shell> python binlog2sql.py -h127.0.0.1 -P3306 -uadmin -p'admin' -ddatabase -t table1 table2 --start-file='mysql-bin.000002' --start-datetime= '2017-01-12 18:00:00' --stop-datetime='2017-01-12 18:30:00' --start-pos=1240 解析出回滚SQL
shell> python binlog2sql.py --flashback -h127.0.0.1 -P3306 -uadmin -p'admin' -dtest -ttest3 --start-file='mysql-bin.000002' --start-position=763 --stop-position=1147示例:
解析出标准sql:
# python /usr/local/binlog2sql/binlog2sql/binlog2sql.py -uflashback -pflashback -dttt -tusers --start-file='mysql-bin.000034' --start-datetime='2017-07-11 15:10:00' --stop-datetime='2017-07-11 15:12:00'
DELETE FROM `ttt`.`users` WHERE `uid`='0e8e2609c748bbb052d7' AND `ip`='172.16.208.32' AND `sex`=0 AND `app_ver`='5.2.3' AND `device_type`=2 AND `guides`='' AND `last_login_time`=1481602129 AND `id`=1 AND `latitude`='' AND `add_time`=1481602080 AND `recharge_time`=0 AND `token_change_time`=1481602129 AND `expire_time`=0 AND `nickname`='阿超' AND `device_id`='cc0e154d9b5dd703eccc7d8a0dbc0f67d64b79e8' AND `push_key`='' AND `level`=0 AND `mobile`='18810895535' AND `settings`='' AND `longitude`='' AND `signature`='' AND `os_ver`='' LIMIT 1; #start 79078 end 83053 time 2017-07-11 15:11:50
解析出回滚sql
# python /usr/local/binlog2sql/binlog2sql/binlog2sql.py --flashback -uflashback -pflashback -dttt -tusers --start-file='mysql-bin.000034' --start-position=79078 --stop-position=83053> /data/backup/rollback.sql
# cat /data/backup/rollback.sql
`id`, `latitude`, `add_time`, `recharge_time`, `token_change_time`, `expire_time`, `nickname`, `device_id`, `push_key`, `level`, `mobile`, `settings`, `longitude`, `signature`, `os_ver`) VALUES ....
INSERT INTO `ttt`.`users`(`uid`, `ip`, `sex`, `app_ver`, `device_type`, `guides`, `last_login_time`, `id`, `latitude`, `add_time`, `recharge_time`, `token_change_time`, `expire_time`, `nickname`, `device_id`, `push_key`, `level`, `mobile`, `settings`, `longitude`, `signature`, `os_ver`) VALUES('77e50b4910a9389057ed','172.16.218.37', 0, '5.2.1.14'...); #start 79078 end 83053 time 2017-07-11 15:11:50解析模式
--realtime 持续同步binlog。可选。不加则同步至执行命令时最新的binlog位置。
--popPk 对INSERT语句去除主键。可选。
-B, --flashback 生成回滚语句。可选。与realtime或popPk不能同时添加。
解析范围控制
--start-file 起始解析文件。必须。
--start-pos start-file的起始解析位置。可选。默认为start-file的起始位置;
--end-file 末尾解析文件。可选。默认为start-file同一个文件。若解析模式为realtime,此选项失效。
--end-pos end-file的末尾解析位置。可选。默认为end-file的最末位置;若解析模式为realtime,此选项失效。
对象过滤
-d, --databases 只输出目标db的sql。可选。默认为空。
-t, --tables 只输出目标tables的sql。可选。默认为空。
注意:
insert、update、delete大部分时候可以解析出来标准sql和回滚sql
一种情况例外:insert、updete、delete操作之后,drop/truncate table。 此时虽然在binlog中记录了所有的event,但是使用binlog2sql生成标准sql、回滚sql的时候已经找不到了dml操作的相应的表
DDL无法使用binlog2sql闪回数据。