```
【本节主题:MySQL备份与恢复】
回顾
1、冷备份:需要停止服务,一般使用cp、tar等复制归档工具
2、热备份
3、热备份
备份工具
复制归档工具
LVM快照
#
fdisk /dev/sda
partprobe
#
pvcreate /dev/sda6
#
vgcreate vg0 /dev/sd6
#
lvcreate -L 5G -n lv_mysql vg0
lvcreate -L 3G -n lv_binlog vg0
#
mkfs.xfs /dev/vg0/lv_mysql
mkfs.xfs /dev/vg0/lv_binlog
# /dev/vg0/lv_mysql 挂载到 /data/mysql
# /dev/vg0/lv_binlog 挂载到 /data/binlog
#更改父目录权限
chown -R mysql.mysql /data/
#修改配置文件
vim /etc/my.cnf
[mysqld]
datadir=/data/mysql
log_bin=/data/binlog/mysql-bin
skip_networking
#
systemctl restart mariadb
#
mysql < hellodb_innodb.sql
#
mysql
-- 加写锁
flush tables with read lock;
--
show master logs;
-- 刷新日志,生成新的日志文件
flush logs;
#
lvcreate -L 1G -n lv_mysql_snap -s -p r /dev/vg0/lv_mysql
-- 释放锁
unlock tables;
#
mount -o nouuid,norecovery /dev/vg0/lv_mysql_snap /mnt
注意:生成的LVM快照UUID与原来的LVM逻辑卷的UUID是一样的!但是系统不允许有相同的UUID设备同时挂载!
解决方法是:挂载时忽略UUID
# 复制归档备份文件
# 取消LVM快照挂载
mount /mnt
# 删除LVM快照
lvremove /dev/vg0/lv_mysql_snap
注意:备份完数据库之后,建议赶紧删除LVM快照,避免数据库读写变慢
原因:LVM快照的工作原理“当LVM逻辑卷的数据发生更改时,LVM会自动将旧数据推送到快照中,这时会导致LVM逻辑卷读写速度变慢”
# 保留原有权限,拷贝备份文件恢复
cp -av /backup/* /data/mysql/
--
#
mysqlbinlog --start-position=245 mysql-bin.000004 > /backup/bin.sql
#
mysqlbinlog mysql-bin.000005 >> /backup/bin.sql
#
实现步骤总结
一、备份过程
1、实现LVM
mkdir /data/{mysql,binlog}
vim /etc/fstab
mount /dev/vg0/lv_mysql /data/mysql
mount /dev/vg0/lv_binlog /data/binlog
chown -R mysql.mysql /data/
vim /etc/my.cnf
[mysqld]
datadir=/data/mysql
log_bin=/data/binlog/mysql-bin
skip_networking
systemctl restart mariadb
mysql
2、加读锁
-- 切换日志
flush tables with read lock;
--
flush logs;
-- 记录文件名和position,例如mysql-bin.000004,245
show master logs;
3、生成快照
# 指定大小
# 指定对谁的快照
# 指定只读属性
lvcreate -n lv_mysql_snap -L 1G -s -p r /dev/vg0/lv_mysql
4、解开读锁
--
unlock tables;
5、备份快照里的内容
mount -o nouuid,norecovery /dev/vg0/lv_mysql_snap /mnt
cp -a /mnt/ /backup
umount /mnt
lvremove /dev/vg0/lv_mysql_snap
二、还原过程
1、系统损坏
rm -rf /data/mysql/*
systemctl stop mariadb
2、还原备份的数据文件
cp -av /backup/* /data/mysql/
3、禁止用户连接(两种方法)
# 方法一:修改主配置文件
vim /etc/my.cnf
[mysqld]
skip_networking # 添加此行
# 需要重启服务才能生效
systemctl start mariadb
# 方法二:通过防火墙规则阻止用户连接
iptables ?????
4、恢复binlog中最新日志
mysqlbinlog --start-position=245 mysql-bin.000004 > /backup/bin.sql
mysqlbinlog mysql-bin.000005 >> /backup/bin.sql
mysql < /backup/bin.sql
5、恢复用户访问
#
vim /etc/my.cnf
skip_networking # 删除此行
systemctl start mariadb
mysqldump 常见选项
-F --flush-logs 刷新滚动日志,备份所有数据库时是逐个分别加锁,有可能会造成备份完第一个数据库时,其他的数据库已经被修改过了,数据库的时间戳不一致!
-x --lock-all-tables 对MyISAM有效,加全局锁
--single-transaction
事务日志的回滚
只能撤销DML操作:表数据的增删改
不能撤销DDL操作:表结构的ALTER、DROP、RENAME、TRUNCATE(默认隐式提交)
生产环境实战备份策略
InnoDB建议备份策略
mysqldump -uroot -A -F -E -R --single-transaction --master-data=1 --flush-privileges --triggers --hex-blob > $BACKUP/fullbak_$BACKUP_TIME.sql
MyISAM建议备份策略
mysqldump -uroot -A -F -E -R -x --master-data=1 --flush-privileges --triggers --hex-blob > $BACKUP/fullbak_$BACKUP_TIME.sql
实验:数据库数据文件损坏,如何还原到最新状态?
mysqldump -A -F --single-transaction --master-data=2 > /backup/fullbak_`data +%F`.sql
rm -rf /data/mysql/*
systemctl stop mariadb
# 提前备份二进制文件和备份文件
scp /data/binlog/mysql-bin.000012 /backup/fullbak_2018-06-13.sql 192.168.30.17:/
恢复:在192.168.30.17上
vim /etc/my.cnf
[mysql]
skip_networking
systemctl restart mariadb
mysql < /fullbak_2018-06-13.sql
mysqlbinlog --start-position=245 mysql-bin.000004 >> /fullbak_2018-06-13.sql
mysql < /fullbak_2018-06-13.sql
#
vim /etc/my.cnf
skip_networking # 删除此行
systemctl start mariadb
实验:表的误删除如何恢复?
# 做完全备份
mysqldump -A -F --single-transaction --master-data=2 > /backup/full.sql
mysql
-- 加读锁
flush tables with read lock;
-- 切换日志,使新发生的事件记录到新的日志中
flush logs;
#
mysqlbinlog --start-position=245 /data/binlog/mysql-bin.000004 > /backup/bin.sql
删除/backup/bin.sql中出错的“删表语句”
rm -rf /data/mysql/*
systemctl restart mariadb
mysql < /backup/full.sql
mysql < /backup.bin.sql
注意:恢复数据时必须停止服务,此过程中用户无法操作
总结:误删除表,如何还原到最新状态?
0、前提!!!必须启用binlog
vim /etc/my.cnf
[mysqld]
datadir=/data/mysql
log_bin=/data/binlog/mysql-bin
systemctl restart mariadb
--
show master logs;
二进制文件是增量备份
恢复时:先恢复全备份,然后再恢复增量备份
1、全备份
mysqldump -A -F --single-transaction --master-data=2 > /backup/full.sql
2、加读锁
--
flush tables with read lock;
--
show master logs;
3、刷新二进制日志
--
flush logs;
4、确定全备份到目前状态之间的所有日志文件及position(举例:/data/binlog/mysql-bin.000019 起始位置 245)
head /backup/full.sql
5、
mysqlbinlog --start-position=245 /data/binlog/mysql-bin.000019 > /backup/bin.sql
6、删除/backup/bin.sql中出错的“删表语句”
vim /backup/bin.sql
7、恢复时:先恢复全备份,然后再恢复增量备份
rm -rf /data/mysql/*
systemctl restart mariadb
mysql < /backup/full.sql
mysql < /backup.bin.sql
如何备份还原单表?
# 备份单表
???
# 还原单表
mysql hellodb < /backup/students.sql
FTWRL : Flush Table With Read Lock 加全局读锁
主配置文件建议格式
/etc/my.cnf
[mysqld]
datadir=/var/lib/mysql # 默认的数据库文件存放位置
log_bin # 启用二进制日志文件
innodb_file_per_table # 分库分表
skip_name_resolve=ON # 禁止名称解析
redo:将未做完的事务执行完毕
undo:撤销未做完的事务
事务的整理:redo和undo
--redo-only :只做提交事务,不封口
# 复制
innobackupex --user=root ????
#
chown -R mysql.mysql /var/lib/mysql/*
#
systemctl start mariadb
复习:二进制安装mariadb
1、创建用户
useradd -r -s /sbin/nologin -d /data/mysql -m mysql
2、解压缩
tar xvf mariadb-10.2.15-linux-x86_64.tar.gz /usr/local/
3、创建软连接
cd /usr/local/
ln -s mariadb-10.2.15-linux-x86_64 mysql
4、更改属主属组
cd /usr/local/
chown -R mysql.mysql mysql/*
5、添加PATH变量
echo PATH=/usr/local/mysql/bin:$PATH > /etc/profile.d/mysql.sh
6、跑一个脚本生成数据库(必须在/usr/local/mysql/目录下执行)
cd /usr/local/mysql
./scripts/mysql_install_db --user=mysql --datadir=/data/mysql
7、拷贝模板作为配置文件
cp support-files/my-huge.cnf /etc/my.cnf
8、修改my.cnf
[mysqld]
datadir=/data/mysql
log-bin=/data/binlog/mysql-bin
9、拷贝启动脚本
cp support-files/mysql.server /etc/init.d/mysqld
10、添加开机启动,并且立即启动服务
chkconfig --add mysqld
service mysqld start
11、跑一遍安全脚本
???
innobackupex --include="hellodb.students" ???
#
mysql hellodb < students.sql
#
mysql -e 'alter table hellodb.students import tablespace'
读写分离
一主多从
主:负责写
从:负责读,相当于热备份
主服务器:必须开启二进制日志功能
级联复制
垂直分区
水平分片
主从复制方式:异步复制
主服务器:dump线程
从服务器:io线程
从服务器越多,对主服务器的压力就越大
主服务器
1、改配置文件
vim /etc/my.cnf
[mysqld]
server_id=1
systemctl restart mariadb
2、授权
--
grant replication slave on *.* to repliuser@'192.168.30.%' identified by 'centos';
--
show master logs;
从服务器
1、改配置文件
vim /etc/my.cnf
[mysqld]
server_id=2
systemctl restart mariadb
2、更改主服务器指向
--
CHANGE MASTER MASTER_HOST='192.168.30.17' , MASTER_PASSWORD='centos' , MASTER_PORT=3306 , MASTER_LOG_FILE='master-bin.000001' , MASTER_LOG_POS=245;
3、
create table testlog (id int auto_increment primary key , name char(10) , age int default 20);
delimiter $$
create procedure pro_testlog()
begin
declare i int;
set i = 1;
while i < 100000
do insert into testlog(name,age) values (concat('wang' , i) , i);
set i = i + 1;
end while;
end $$
delimiter ;
实验:事先已经有主服务器,并且主服务器存放了大量数据,现在想要建立新的从服务器,如何创建从服务器
(一)在主节点上备份
1、修改主配置文件
vim /etc/my.cnf
[mysqld]
server_id=1
log_bin
innodb_file_per_table
2、创建账号并授权
grant replication slave on *.* to repliuser@'192.168.30.%' identified by 'centos';
3、主节点备份
mysqldump -A -F -single-transaction --master-data=1 > /backup/all.sql
4、传送到从节点
scp /backup/all.sql 192.168.30.27:/backup/
(二)在从节点上还原
4、修改从配置文件
vim /etc/my.cnf
[mysqld]
server_id=2
read_only
systemctl restart mariadb;
5、修改 all.sql
vim /backup/all.sql
CHANGE MASTER TO MASTER_HOST='192.168.30.17' , MASTER_USER='repluser' , MASTER_PASSWORD='centos' , MASTER_PORT=3306 , MASTER_LOG_FILE='master-bin.000002' , MASTER_LOG_POS=245 ;
6、执行导入备份
mysql < all.sql
7、启动从服务器
mysql
--
set global read_only=ON;
--
select count(*) from testlog;
-- 启动从服务器
start slave;
--
show slave status;
```