一、MariaDB简介及新特性
MariaDB数据库管理系统是MySQL的一个分支,主要由开源社区在维护,采用GPL授权许可 MariaDB的目的是完全兼容MySQL,包括API和命令行,使之能轻松成为MySQL的代替品。在存储引擎方面,使用XtraDB来代替MySQL的InnoDB。MariaDB基于事务的Maria存储引擎,替换了MySQL的MyISAM存储引擎。
MariaDB的一个独特特性是它的连接到Cassandra后端的引擎。引擎本身只是一个加入到Cassandra服务器中单独运行中介(Cassandra是一个NoSQL类型的键-值存储,由Facebook创建后来成为了Apache的项目;它可用于集群且没有单点故障,它同样不是完全ACID的)。
二、MariaDB日志介绍
查询日志 query log |
记录查询操作 ;默认不开启 |
慢查询日志 slow_query_log |
查询语句查询时间超出指定执行时间 指定时长--long_query_time; |
错误日志 log_error |
mysqld启动或关闭过程中输出的事件信息 ;运行中产生的错误信息;时间调度器产生的日志信息;主从复制架构从服务器启动线程时产生的信息 |
二进制日志 log_bin |
是mariadb数据库最重要的日志,用于时间点还原一定要开启; 记录导致数据改变或潜在导致数据改变的SQL语句 |
事务日志 transaction log |
redo log:记录事务修改后的数据,提交的(commit),需要同步至数据文件中 undo log:记录事务前的原始数据,回滚的(role back) |
中继日志 relay_log |
复制架构中,从服务器用于保存从主服务器的二进制日志中读取到的事件 |
三、MariaDB备份类型、备份工具及相关的备份策略介绍
① 备份的类型 |
|
根据数据集划分 |
完全备份:整个数据集 部分备份:只备份数据子集 |
根据时间轴变化情况划分 |
完全备份、增量备份、差异备份 增量备份:仅备份最近一次完全备份或增量备份(如果存在增量)以来变化的数据 差异备份:仅备份最近一次完全备份以来的变化的数据 |
根据备份服务是否在线划分 |
热备份、温备份、冷备份
热备:读写操作均可执行 温备:读操作可执行;但写操作不成 冷备:读写操作均不可执行 |
根据备份模式的角度划分 |
物理备份:直接复制数据文件进行备份 ,需要结合复制工具(cp、tar、rsync) 逻辑备份:从数据库中”导出“数据另存而进行的备份; 需专用的协议客户端 注:逻辑备份与存储引擎无关 |
② 备份工具的选择 +备份方案 | |
1、 mysqldump + 复制binlog mysqldump:安全备份;客户端命令,通过mysql协议连接至mysqld服务器 复制二进制日志指定时间范围内event;增量备份 |
|
2、lvm2-snapshot + 复制binlog 基于lvm2-snapshot:使用cp或tar等工具做物理备份,完全备份 复制二进制日志指定时间范围内event;增量备份 |
|
3、xtrabackup Xtrabackup是由percona提供的mysql数据库备份工具;xtrabackup仅对innodb存储引擎的数据库热备;MyISAM不支持热备和增量备份 |
四、上述复制方案的实现过程:
①mysqldump + 复制binlog
<1> mysqldump是mysql数据库自带的一种逻辑备份工具,适用于所有存储引擎,支持温备;完全备份,部分备份;对innodb存储引擎支持热备
使用语法: mysqldump [options] [db_name [tbl_name ...]]
常用选项:
--databases : 备份指定的数据库
--all-databases:备份所有的数据库
--lock-all-tables:锁定 所有数据库的所有表,在MyISAM,InnoDB引擎的数据温备时使用
--lock-tables:锁定指定数据库的指定表,在MyISAM,InnoDB引擎的数据温备时使用
--single-transaction:锁定数据库 ,在InnoDB引擎的数据热备时使用
--flush-logs:滚动日志
--master-data=[0|1|2] : 是否记录二进制日志事件的位置
0:不记录
1 :记录为CHANGE MASTER TO 语句,此语句不被注释
2:记录为注释的CHANGE MASTER TO 语句
其它选项:
-E, --events : 备份指定数据库相关的所有事件调度器
-R,--routines:备份指定数据库相关的所有存储过程和存储函数
--triggers : 备份表相关的触发器
<2> 备份策略; 完全备份+增量备份+定时计划任务
增量备份每周一~周六凌晨的2点执行 ;记录备份日志中
完全备份每周日凌晨的2点执行,并删除本周的增量备份(?);记录备份日志中
完全备份脚本
~~~~DBfullbak.sh#!/bin/bash
# use mysqldump to full backup mysql data on sunday!
# 2015-11-6
BakDir=/mariadb_bak
Logfile=$BakDir/DBbak.log
Date=`date +%F`
Begin_time=`date +"%F %T"`
#备份开始的时间
DumpFile=$Date.sql
mysqldump=`which mysqldump`
mkdir -pv $BakDir
cd $BakDir
$mysqldump -uroot --all-databases --single-transaction --master-data=2 > $DumpFile
#完全备份所有数据库,innodb引擎数据热备,注释 CHANGE MASTER TO(二进制日志的位置信息)
Last_time=`date +"%F %T"`
echo "Start_time:$Begin_time End_time:$Last_time | $DumpFile succ" >> $Logfile
#记录完全备份完成时间至备份日志文件中
cd $BakDir/increment
rm -rf *
#删除一周内的增量备份的二进制日志(这个需要考虑)
增量备份脚本
~~~~DBincrementbak.sh #!/bin/bash# use copy binlog to increment backup mysql data on monday-Saturday!# 2015-11-6 BakDir=/mariadb_bak/incrementBinDir=/var/lib/mysqlLogFile=$BakDir/DBbak.logBinFile=$BinDir/mysql-bin.indexmysqladmin=`which mysqladmin`mkdir -pv $BakDir$mysqladmin -uroot flush-logs #执行日志滚动操作Counter=`wc -l $BinFile |awk '{print $1}'`NextNum=0#这个for循环用于比对$Counter,$NextNum这两个值来确定文件是不是存在或最新的。for file in `cat $BinFile`; do base=`basename $file` #basename用于截取mysql-bin.00000*文件名,如去掉./mysql-bin.000004前面的./ let NextNum++ if [ $NextNum -eq $Counter ]; then echo $base skip! >> $LogFile #新滚动的二进制日志跳过不复制 else dest=$BakDir/$base if (test -e $dest); then echo $base exist! >> $LogFile#存在的二进制日志不复制 else cp $BinDir/$base $BakDir echo $base copying >> $LogFile #复制不存在的二进制日志,并记录日志 fi fidoneecho "`date +"%F %T"` Copy $(($NextNum-1))个mysql-bin succ" >> $LogFile#记录日志:从周一至周六一共复制了几个二进制日志
计划任务
# crontab -l0 2 * * 1-6 /root/DBincrementbak.sh &> /dev/null0 2 * * 7 /root/DBfullbak.sh &> /dev/null
②lvm2-snapshot + 复制binlog
实现步骤: |
(1)请求锁定所有表 mysql -e 'flush tables with read lock;' ( 2 ) 记录二进制日志及事件位置 mysql -e ‘flush logs;show master status; ' ( 3 ) 创建快照卷 lvcreate -L # -p r -s -n snapshot_name /dev/vg_name/lv_name (4)释放锁 mysql -e 'unlock tables;' ( 5 ) 挂载快照卷,执行数据备份 ; mount -r /dev/vg_name/snapshot_name /mnt cp -a = 数据文件的属主属组都是mysql (6)备份完成后,删除快照卷 umount /mnt && lvremove -f /dev/vg_name/snapshot_name (7)制定好策略,通过原卷备份二进制日志 复制二进制日志的事件做增量备份 |
<1> lvm创建过程,并让mysql数据库的datadir使用逻辑分区!
[root@node1 ~]# pvcreate /dev/sda5 [root@node1 ~]# vgcreate myvg /dev/sda5 [root@node1 ~]# lvcreate -L +5G -n mydata myvg [root@node1 ~]# lvs LV VG Attr LSize Pool Origin Data% Meta% Move Log Cpy%Sync Convert mydata myvg -wi-a----- 5.00g [root@node1 ~]# mke2fs -t ext4 /dev/myvg/mydata [root@node1 ~]# mount /dev/myvg/mydata /data/[root@node1 ~]# mkdir /data/mysql[root@node1 ~]# chown -R mysql.mysql /data/mysql/[mysqld]datadir=/data/mysqllog_bin=mysql-bininnodb_file_per_table=1skip_name_resolve=1[root@node1 ~]# systemctl start mariadb[root@node1 ~]# ss -tanlState Recv-Q Send-Q Local Address:Port Peer Address:Port LISTEN 0 50 *:3306 *:*
<2> 完全备份脚本;增量备份脚本使用上面的即可,同样可以结合计划任务来完成相关的备份策略;还原的时候要使用lvm2-snapshot中的完全备份及mysqlbinlog工具读取二进制日志相关位置的事件做时间点还原~
#!/bin/bash# use lvm2-snapshot to full backup mysql data on sunday!# 2015-11-7BakDir=/mariadb_bak //备份目录Full_BakDir=$BakDir/full //完全备份目录Logfile=$BakDir/DBbak.log //备份产生的日志Date=`date +"%F-%T"` mkdir -p $BakDir mkdir -p $Full_BakDir Begin_time=`date +"%F %T"` //备份开始的时间 //使用lvm2-snapshot完全备份的过程 mysql -e 'flush tables with read lock;' //给所有表施加读锁mysql -e 'flush logs;show master status;' > $BakDir/pos.$Date //滚动二进制日志并记录位置lvcreate -L 1G -p r -s -n mysql_sp /dev/myvg/mydata &> /dev/null//对mysql数据目录创建快照mysql -e 'unlock tables;' //释放锁mount -r /dev/myvg/mysql_sp /mnt //挂载快照//复制数据到完全备份目录mkdir $Full_BakDir/$Date && cd $Full_BakDir/$Date && cp -a /mnt/* ./ umount /mnt && lvremove -f /dev/myvg/mysql_sp &> /dev/null //卸载快照并删除即可 Last_time=`date +"%F %T"`echo "Start_time : $Begin_time End_time : $Last_time backup succ" >> $Logfile
③ xtrabackup
<1> Xtrabackup是由percona提供的mysql数据库备份工具,支持在线热备份;Xtrabackup有两个主要的工具:xtrabackup、innobackupex 。
注解:
(1).xtrabackup只能备份InnoDB和XtraDB 两种数据表
(2).innobackupex则封装了xtrabackup,同时可以备份MyISAM数据表
Innobackupex完整备份后生成了几个重要的文件:
xtrabackup_binlog_info:记录当前最新的二进制日志Position
xtrabackup_checkpoints: 备份的类型,LSN(日志序列号)范围信息
<2> xtrabackup特点
(1)备份过程快速、可靠
(2)备份过程不会打断正在执行的事务
(3)能够基于压缩等功能节约磁盘空间和流量
(4)自动实现备份检验
(5)还原速度快
<3> xtrabackup安装
[root@node1 ~]# yum install -y percona-xtrabackup-2.3.2-1.el7.x86_64.rpm ========================================================================================= Package Arch Version Repository Size=========================================================================================Installing:percona-xtrabackup x86_64 2.3.2-1.el7 /percona-xtrabackup-2.3.2-1.el7.x86_64 21 MInstalling for dependencies: libev x86_64 4.15-3.el7 epel 43 k rsync x86_64 3.0.9-15.el7 centos7 359 kTransaction Summary //依赖包 libev
<4>xtrabackup常用选项(参考)
--apply-log:同xtrabackup的--prepare参数,一般情况下,在备份完成后,数据尚且不能用于恢复操作,因为备份的数据中可能会包含尚未提交的事务或已经提交但尚未同步至数据文件中的事务。因此,此时数据 文件仍处理不一致状态。--apply-log的作用是通过回滚未提交的事务及同步已经提交的事务至数据文件使数据文件处于一致性状态。 |
--copy-back:做数据恢复时将备份数据文件拷贝到MySQL服务器的datadir |
--stream=[tar]:备份文件输出格式, 该文件可在XtarBackup binary文件中获得. 在使用参数 stream=tar备份的时候,你的xtrabackup_logfile可能会临时放在/tmp目录下,如果你备份的时候并发写入较大的话,xtrabackup_logfile可能会很大,很可能会撑满你的/tmp目录,可以通过参数--tmpdir指定目录来解决这个问题. |
--tmpdir=DIRECTORY:当有指定--remote-host or --stream时, 事务日志临时存储的目录, 默认采用MySQL配置文件中所指定的临时目录tmpdir |
--remote-host=HOSTNAME: 通过ssh将备份数据存储到远程服务器上 |
--redo-only --apply-log:强制备份日志时只redo,跳过rollback,这在做增量备份时非常必要 |
--use-memory=#:该参数在prepare的时候使用,控制prepare时innodb实例使用的内存 |
--databases=LIST:列出需要备份的databases,如果没有指定该参数,所有包含MyISAM和InnoDB表的database都会被备份 |
--socket=SOCKET:指定mysql.sock所在位置,以便备份进程登录mysql. |
<5> 使用innobackupex实现数据库备份
1、完全备份及恢复
#备份某一指定数据库
[root@node1 ~]# mysql -e 'show databases;'+--------------------+| Database |+--------------------+| information_schema || mysql || performance_schema || test |+--------------------+[root@node1 ~]# mkdir /backup //创建备份目录[root@node1 ~]# innobackupex --databases=test /backup/ &> /backup/$(date +"%F-%T").log[root@node1 ~]# ll /backup/total 12drwx------ 3 root root 4096 Nov 8 18:15 2015-11-08_18-15-54-rw-r--r-- 1 root root 7824 Nov 8 18:15 2015-11-08-18:15:54.log //备份过程日志[root@node1 ~]# ll /backup/2015-11-08_18-15-54/ //可以看到只有1个test数据库total 18456-rw-r----- 1 root root 385 Nov 8 18:15 backup-my.cnf-rw-r----- 1 root root 18874368 Nov 8 18:15 ibdata1drwx------ 2 root root 4096 Nov 8 18:15 test-rw-r----- 1 root root 21 Nov 8 18:15 xtrabackup_binlog_info-rw-r----- 1 root root 113 Nov 8 18:15 xtrabackup_checkpoints-rw-r----- 1 root root 462 Nov 8 18:15 xtrabackup_info-rw-r----- 1 root root 2560 Nov 8 18:15 xtrabackup_logfile
#备份所有数据库
[root@node1 ~]# innobackupex /backup/ &> /backup/$(date +"%F-%T").log[root@node1 ~]# ll /backup/total 32drwx------ 3 root root 4096 Nov 8 18:15 2015-11-08_18-15-54-rw-r--r-- 1 root root 7824 Nov 8 18:15 2015-11-08-18:15:54.logdrwx------ 5 root root 4096 Nov 8 18:17 2015-11-08_18-17-46-rw-r--r-- 1 root root 16156 Nov 8 18:17 2015-11-08-18:17:46.log[root@node1 ~]# ll /backup/2015-11-08_18-17-46/ //可以看到是所有的数据库total 18464-rw-r----- 1 root root 385 Nov 8 18:17 backup-my.cnf-rw-r----- 1 root root 18874368 Nov 8 18:17 ibdata1drwx------ 2 root root 4096 Nov 8 18:17 mysql drwx------ 2 root root 4096 Nov 8 18:17 performance_schemadrwx------ 2 root root 4096 Nov 8 18:17 test-rw-r----- 1 root root 21 Nov 8 18:17 xtrabackup_binlog_info-rw-r----- 1 root root 113 Nov 8 18:17 xtrabackup_checkpoints-rw-r----- 1 root root 445 Nov 8 18:17 xtrabackup_info-rw-r----- 1 root root 2560 Nov 8 18:17 xtrabackup_logfile
# 注:还原时,需要清空数据目录,所以建议备份的话,执行全库备份
# 备份完成后,应用日志,是备份的数据保持一致[/backup/2015-11-08_18-17-46];注:确保没有做任何的数据库操作;否则还要读取二进制日志的相关事件来做时间点还原
# 直接在一台MySQL服务器上操作了,实际环境不要这样进行~~停止服务;删除mysql的数据目录
[root@node1 ~]# innobackupex --apply-log /backup/2015-11-08_18-17-46/[root@node1 ~]# innobackupex --copy-back /backup/2015-11-08_18-17-46/[root@node1 ~]# chown -R mysql.mysql /var/lib/mysql/*//出现问题,mariadb服务启动不了,查看mariadb日志,显示事务日志的大小为48M;[root@node1 ~]# systemctl start mariadbJob for mariadb.service failed. See 'systemctl status mariadb.service' and 'journalctl -xn' for details.[root@node1 ~]# tail /var/log/mariadb/mariadb.log In case (b) you need to set innodb_log_file_size = 48M151108 18:31:25 [ERROR] Plugin 'InnoDB' init function returned error.151108 18:31:25 [ERROR] Plugin 'InnoDB' registration as a STORAGE ENGINE failed.151108 18:31:25 [Note] Plugin 'FEEDBACK' is disabled.151108 18:31:25 [ERROR] Unknown/unsupported storage engine: InnoDB151108 18:31:25 [ERROR] Aborting151108 18:31:25 [Note] /usr/libexec/mysqld: Shutdown complete151108 18:31:25 mysqld_safe mysqld from pid file /var/run/mariadb/mariadb.pid ended[root@node1 ~]# ll /var/lib/mysql/total 116772-rw-rw---- 1 mysql mysql 16384 Nov 8 18:31 aria_log.00000001-rw-rw---- 1 mysql mysql 52 Nov 8 18:31 aria_log_control-rw-r----- 1 mysql mysql 18874368 Nov 8 18:28 ibdata1-rw-r----- 1 mysql mysql 50331648 Nov 8 18:28 ib_logfile0 //这里-rw-r----- 1 mysql mysql 50331648 Nov 8 18:28 ib_logfile1 //这里 drwx------ 2 mysql mysql 4096 Nov 8 18:28 mysql-rw-rw---- 1 mysql mysql 0 Nov 8 18:28 mysql-bin.indexdrwx------ 2 mysql mysql 4096 Nov 8 18:28 performance_schemadrwx------ 2 mysql mysql 4096 Nov 8 18:28 test-rw-r----- 1 mysql mysql 445 Nov 8 18:28 xtrabackup_info# 临时解决方法,删除事务日志ib_logfile0 和ib_logfile1[root@node1 ~]# rm -rf /var/lib/mysql/ib_logfile*[root@node1 ~]# systemctl start mariadb[root@node1 ~]# ss -tanlState Recv-Q Send-Q Local Address:Port Peer Address:Port LISTEN 0 50 *:3306 *:*
2、示例 === 2次增量备份+二进制日志事件复制(时间点)及恢复过程
#完全备份
[root@node1 ~]# mkdir /backup/full[root@node1 ~]# innobackupex /backup/full/ [root@node1 ~]# ll /backup/full/2015-11-08_19-49-42/total 18464-rw-r----- 1 root root 385 Nov 8 19:49 backup-my.cnf-rw-r----- 1 root root 18874368 Nov 8 19:49 ibdata1drwx------ 2 root root 4096 Nov 8 19:49 mysqldrwx------ 2 root root 4096 Nov 8 19:49 performance_schemadrwx------ 2 root root 4096 Nov 8 19:49 test-rw-r----- 1 root root 21 Nov 8 19:49 xtrabackup_binlog_info-rw-r----- 1 root root 113 Nov 8 19:49 xtrabackup_checkpoints-rw-r----- 1 root root 450 Nov 8 19:49 xtrabackup_info-rw-r----- 1 root root 2560 Nov 8 19:49 xtrabackup_logfile[root@node1 ~]# cat /backup/full/2015-11-08_18-52-33/xtrabackup_checkpoints backup_type = full-backupedfrom_lsn = 0to_lsn = 1598988last_lsn = 1598988compact = 0recover_binlog_info = 0
#增量备份;要使用--incremental-basedir=完全备份目录,即基于上一次完全备份的增量备份
MariaDB [(none)]> create database test1;Query OK, 1 row affected (0.00 sec)MariaDB [(none)]> show master status;+------------------+----------+--------------+------------------+| File | Position | Binlog_Do_DB | Binlog_Ignore_DB |+------------------+----------+--------------+------------------+| mysql-bin.000003 | 330 | | |+------------------+----------+--------------+------------------+1 row in set (0.00 sec)[root@node1 ~]# innobackupex --incremental --incremental-basedir=/backup/full/2015-11-08_19-49-42/ /backup/incr/ //基于完全备份的增量备份[root@node1 ~]# cat /backup/incr/2015-11-08_19-52-19/xtrabackup_checkpoints backup_type = incremental //只新建了1个数据库好像看不出效果?O(∩_∩)Ofrom_lsn = 1597945to_lsn = 1597945last_lsn = 1597945compact = 0recover_binlog_info = 0[root@node1 2015-11-08_19-52-19]# cat xtrabackup_binlog_info //可以看出二进制日志的位置mysql-bin.000003330
#增量备份的增量备份
MariaDB [(none)]> create database test2; //新建数据库test2Query OK, 1 row affected (0.01 sec)MariaDB [(none)]> use test2;Database changedMariaDB [test2]> create table num(id int); //新建表numQuery OK, 0 rows affected (0.38 sec)MariaDB [test2]> insert into num value (1),(2),(3),(4),(5); //出入5条信息Query OK, 5 rows affected (0.02 sec)Records: 5 Duplicates: 0 Warnings: 0MariaDB [test2]> select * from num;+------+| id |+------+| 1 || 2 || 3 || 4 || 5 |+------+5 rows in set (0.00 sec)[root@node1 ~]# innobackupex --incremental --incremental-basedir=/backup/incr/2015-11-08_19-52-19/ /backup/incr/ //基于增量备份的增量备份[root@node1 ~]# cat /backup/incr/2015-11-08_20-00-57/xtrabackup_checkpoints backup_type = incrementalfrom_lsn = 1597945 //这次可以看出来效果了 !!to_lsn = 1602908last_lsn = 1602908compact = 0recover_binlog_info = 0
#使用mysqlbinlog工具导出二进制日志事件----数据库新做的修改
MariaDB [(none)]> create database test3; //新添加2个数据库test3,test4Query OK, 1 row affected (0.00 sec)MariaDB [(none)]> create database test4;Query OK, 1 row affected (0.00 sec)//查看上一次增量备份二进制日志事件位置[root@node1 2015-11-08_20-00-57]# cat xtrabackup_binlog_info mysql-bin.000003704[root@node1 ~]# mysqlbinlog --start-position=704 /var/lib/mysql/mysql-bin.000003 > /backup/increment.sql
#应用日志恢复;顺序:①先恢复完全备份-->②第一次增量备份-->③第二次增量备份;
[root@node1 ~]# innobackupex --apply-log --redo-only /backup/full/2015-11-08_19-49-42/[root@node1 ~]# innobackupex --apply-log --redo-only /backup/full/2015-11-08_19-49-42/ --incremental-dir=/backup/incr/2015-11-08_19-52-19/[root@node1 ~]# innobackupex --apply-log --redo-only /backup/full/2015-11-08_19-49-42/ --incremental-dir=/backup/incr/2015-11-08_20-00-57/
#MySQL数据库恢复过程;
①停止服务,删除数据目录---> ②先恢复准备好的完整备份 -->③恢复二进制日志事件
[root@node1 ~]# systemctl stop mariadb[root@node1 ~]# rm -rf /var/lib/mysql/*[root@node1 ~]# innobackupex --copy-back /backup/full/2015-11-08_19-49-42/[root@node1 ~]# rm -rf /var/lib/mysql/ib_logfile*[root@node1 ~]# chown -R mysql.mysql /var/lib/mysql/*[root@node1 ~]# systemctl start mariadb[root@node1 ~]# ss -tanlState Recv-Q Send-Q Local Address:Port Peer Address:Port LISTEN 0 50 *:3306 *:* //检查是否还原;发现没有test3和test4数据库;需要利用二进制日志做时间点还原才可以MariaDB [(none)]> show databases;+--------------------+| Database |+--------------------+| information_schema || mysql || performance_schema || test || test1 || test2 |+--------------------+6 rows in set (0.07 sec)MariaDB [(none)]> select * from test2.num;+------+| id |+------+| 1 || 2 || 3 || 4 || 5 |+------+5 rows in set (0.00 sec)[root@node1 ~]# mysql < /backup/increment.sql [root@node1 ~]# mysqlMariaDB [(none)]> show databases; //可以看到已经出现test3和test4数据库+--------------------+| Database |+--------------------+| information_schema || mysql || performance_schema || test || test1 || test2 || test3 || test4 |+--------------------+8 rows in set (0.01 sec)
至此~~MariaDB数据库的备份介绍完毕!O(∩_∩)O谢谢~~~
本文出自 “bengbengtu” 博客,请务必保留此出处http://bengbengtu.blog.51cto.com/9505633/1710660