innobackupex 备份脚本及恢复过程

写了一个全库备份+基于全备的增备脚本(不基于增备做增备)。

#!/bin/bash
#use crond, run at 00:00:00 (full) , per {x} min (increment)

user=root
password=root
savepath=/mnt/db_backup/$(date +%Y_%m_%d)
full_dirname=full
increment_dirname=increment_$(date +%Y_%m_%d_%H_%M_%S)
method=$1

if [ "$method" == "full" ]; then

 innobackupex --host=127.0.0.1 --user=$user --password=$password --no-lock --no-timestamp $savepath/$full_dirname

else

 if [ -d $savepath/$full_dirname ]; then

 innobackupex --host=127.0.0.1 --user=$user --password=$password --no-lock --no-timestamp --incremental-basedir=$savepath/$full_dirname --incremental $savepath/$increment_dirname
 fi

fi

exit

使用方法:
添加linux任务计划:
00 00 * * * sh /root/backup_script/backup.sh full
*/10 * * * sh /root/backup_script/backup.sh increment
保存,重启任务计划服务。

下面为恢复主机全部数据库过程:
PS:
主机用innobackupex备份全部数据库,每天一个全备+每隔x分钟基于全备做增备(不基于增备做增备)。

也可以将备份恢复到备份机器上,但强烈建议主备数据库版本一致

下面是在备用服务器上恢复(如果还在本机恢复,略过安装步骤):

安装mysql,这里直接采用编译好的二进制版本(主DB也是这样装的):

[root@m2 ~]# tar zxvf mysql-5.7.17-linux-glibc2.5-x86_64.tar.gz
[root@m2 ~]# mv mysql-5.7.17-linux-glibc2.5-x86_64 /usr/local/mysql/
[root@m2 ~]# useradd -s /sbin/nologin mysql
[root@m2 ~]# cd /usr/local/mysql/bin/
[root@m2 bin]# ./mysqld --user=mysql --basedir=/usr/local/mysql --datadir=/usr/local/mysql/data/ --initialize
[root@m2 bin]# cd ..
[root@m2 mysql]# cp support-files/mysql.server /etc/init.d/mysqld
[root@m2 mysql]# cp support-files/my-default.cnf /etc/my.cnf
[root@m2 mysql]# chmod 755 /etc/init.d/mysqld
剩下的安装步骤不需要。

删除原有mysql所有数据,下一步从备份数据中全部恢复到从DB
[root@m2 mysql]# rm -rf /usr/local/mysql/data/*

处理备份的数据:
把之前 innobackupex 备份的数据复制到从机(全量+最后一个增量)
[root@m2 ~]# innobackupex --apply-log --redo-only /root/2017_02_21/full/
[root@m2 ~]# innobackupex --apply-log /root/2017_02_21/full/ --incremental-dir=/root/2017_02_21/increment_2017_02_21_20_24_58/
[root@m2 ~]# innobackupex --apply-log /root/2017_02_21/full/

还原:
[root@m2 ~]# innobackupex --datadir=/usr/local/mysql/data/ --copy-back /root/2017_02_21/full/

恢复权限:
[root@m2 ~]# chown -R mysql:mysql /usr/local/mysql/data/
[root@m2 ~]# service mysqld start

从备份数据中恢复到从DB以后,数据库信息完全跟主DB的数据库信息一致。包括密码等。

xtrabackup 2.4.5 文档

mysql锁分为 读锁(读写都不行) 写锁(只读,不允许写入)
[root@localhost ~]# yum install cmake gcc gcc-c++ libaio libaio-devel automake autoconf bzr bison libtool ncurses5-devel perl perl-devel perl-Digest-MD5 perl-Time-HiRes perl-DBD-MySQL libev libev-devel libgcrypt libgcrypt-devel curl curl-devel python-setuptools libarchive-devel

直接rpm -ivh 安装官网下载的rpm包,根据提示缺什么装什么,直至完成。

以下内容仅为本机备份,本机恢复,如果复制到别的机器,单独恢复一个库会有问题。推荐使用备份所有库,即不加–databases=参数。

全量备份:
1、执行备份

[root@localhost ~]# innobackupex --user=root --password=root --databases=simon --no-lock --no-timestamp /mnt/backup/simon/full_$(date +%Y_%m_%d_%H_%M_%S)

2、删除simon库,测试

[root@localhost ~]# rm -rf /var/lib/mysql/simon/

恢复数据:
1、先关闭mysql服务
2、再处理备份数据

[root@localhost ~]# innobackupex --apply-log /mnt/backup/simon/full_2017_02_19_21_29_42/
--apply-log处理全备中的事物,未提交的回滚,已提交的写入文件

3、恢复

[root@localhost ~]# cp -R /mnt/backup/simon/full_2017_02_19_21_29_42/simon/ /var/lib/mysql/
[root@localhost ~]# chown -R mysql:mysql /var/lib/mysql/simon/

直接复制备份的simon库的文件夹到mysql数据目录,并修改权限,启动mysql。

数据恢复完成。

增量备份(只支持innodb):
1、增量备份基于全备

[root@localhost ~]# innobackupex --user=root --password=root --databases=simon --no-lock --no-timestamp /mnt/backup/simon/full_$(date +%Y_%m_%d_%H_%M_%S)

2、增量备份,目录要与全备目录路径一样,否则无法执行

[root@localhost ~]# innobackupex --user=root --password=root --databases=simon --no-lock --no-timestamp --incremental-basedir=/mnt/backup/simon/full_2017_02_19_21_29_42/ --incremental /mnt/backup/simon/increment_$(date +%Y_%m_%d_%H_%M_%S)

增量恢复:
删除simon库,模拟丢失

[root@localhost ~]# rm -rf /var/lib/mysql/simon/

关闭mysql服务

将增量备份数据合并到全备中 必须用全路径,否则整合全备+增备会失败,导致数据不全,或提示错误。

[root@localhost simon]# pwd
/mnt/backup/simon
[root@localhost simon]# innobackupex --apply-log --redo-only /mnt/backup/simon/full_2017_02_19_21_29_42/
[root@localhost simon]# innobackupex --apply-log /mnt/backup/simon/full_2017_02_19_21_29_42/ --incremental-dir=/mnt/backup/simon/increment_2017_02_19_22_16_10/
[root@localhost simon]# innobackupex --apply-log /mnt/backup/simon/full_2017_02_19_21_29_42/

[root@localhost ~]# cp -R /mnt/backup/simon/full_2017_02_19_21_29_42/simon/ /var/lib/mysql/
[root@localhost ~]# chown -R mysql:mysql /var/lib/mysql/simon/

启动mysql,数据恢复完成。

–apply-log –redo-only 作用,来自网络
redo-only 只对增量备份有作用,
对于全备份和增量备份(出最后一个增备外) 都需要加 redo-only ;
这个选项是 让xtrabackup跳过 rollback 阶段,只进行redo 阶段(中间的增备如果 rollback ,那增备之间可能无法衔接起来)

PS:
增量备份可以基于一个增量,再做增量,不过恢复起来比较繁琐。这里没有采用。

可看下下面资料:基于增量的增量备份及恢复
http://www.toxingwang.com/database/mysql/1539.html
http://blog.csdn.net/dbanote/article/details/13295727

centos6.5下drbd-8.4.1的编译安装与配置

Distributed Replicated Block Device(DRBD)是一种基于软件的,无共享,复制的存储解决方案,在服务器之间的对块设备(硬盘,分区,逻辑卷等)进行镜像。DRBD工作在内核当中的,类似于一种驱动模块。

DRBD工作的位置在文件系统的buffer cache和磁盘调度器之间,通过tcp/ip发给另外一台主机到对方的tcp/ip最终发送给对方的drbd,再由对方的drbd存储在本地对应磁盘 上,类似于一个网络RAID-1功能。

在高可用(HA)中使用DRBD功能,可以代替使用一个共享盘阵。本地(主节点)与远程主机(备节点)的数据可以保证实时同步。当本地系统出现故障时,远程主机上还会保留有一份相同的数据,可以继续使用。

系统版本:CentOS6.5_x64
内核版本:2.6.32-431.el6.x86_64

IP规划:
主节点 node1 192.168.0.175
备节点 node2 192.168.0.176

修改主机名:
主节点
[root@node1 ~]# cat /etc/sysconfig/network
NETWORKING=yes
HOSTNAME=node1
[root@node1 ~]# hostname node1
备节点
[root@node2 ~]# cat /etc/sysconfig/network
NETWORKING=yes
HOSTNAME=node2
[root@node2 ~]# hostname node2

修改两台机器的host:
node1添加
192.168.0.175 node1
192.168.0.176 node2

node2添加
192.168.0.175 node1
192.168.0.176 node2

selinux关闭、iptables关闭

drbd官方网站:http://oss.linbit.com/drbd/

安装编译环境:
[root@node1 ~]# yum install -y gcc gcc-c++ kernel-headers flex
其中还需要一个包,就是内核源码包kernel-devel,这里不通过yum安装,因为yum list出来的版本为2.6.32-504.8.1.el6。
而我系统内核版本为2.6.32-431.el6.x86_64,如果安装了最新的kernel-devel,在执行make KDIR=的时候会报错。
所以选择通过iso镜像中的rpm包安装。提取kernel-devel-2.6.32-431.el6.x86_64.rpm传到服务器中,直接rpm -ivh安装。

下载drbd源码包:
[root@node1 ~]# wget -c http://oss.linbit.com/drbd/8.4/drbd-8.4.1.tar.gz

解压编译:

[root@node1 drbd-8.4.1]# ./configure --prefix=/usr/local/drbd --with-km
[root@node1 drbd-8.4.1]# make KDIR=/usr/src/kernels/2.6.32-431.el6.x86_64/
[root@node1 drbd-8.4.1]# make install
[root@node1 drbd-8.4.1]# mkdir -p /usr/local/drbd/var/run/drbd
[root@node1 drbd-8.4.1]# cp /usr/local/drbd/etc/rc.d/init.d/drbd /etc/rc.d/init.d/
[root@node1 drbd-8.4.1]# chkconfig --add drbd
[root@node1 drbd-8.4.1]# chkconfig drbd on

安装内核模块:

[root@node1 drbd-8.4.1]# cd drbd
[root@node1 drbd]# make clean
[root@node1 drbd]# make KDIR=/usr/src/kernels/2.6.32-431.el6.x86_64/
[root@node1 drbd]# cp drbd.ko /lib/modules/2.6.32-431.el6.x86_64/kernel/lib/
[root@node1 drbd]# depmod

drbd配置:
对两台机器添加新硬盘,这里为/dev/sdb,分区,fdisk /dev/sdb 根据提示操作创建新分区(/dev/sdb1)。

创建挂载点: mkdir /db

配置主配置文件drbd.conf:
[root@node1 ~]# vi /usr/local/drbd/etc/drbd.conf 确认为以下两行

include "drbd.d/global_common.conf";
include "drbd.d/*.res";

配置global_common.conf:
[root@node1 ~]# vi /usr/local/drbd/etc/drbd.d/global_common.conf

common {
	net {

        protocol C;
		}
	}

主要在net段中添加同步协议 protocol C;

配置资源文件:
[root@node1 ~]# vi /usr/local/drbd/etc/drbd.d/r0.res

resource r0 {
  on node1 {
    device    /dev/drbd1;
    disk      /dev/sdb1;
    address   192.168.0.175:7789;
    meta-disk internal;
  }
  on node2 {
    device    /dev/drbd1;
    disk      /dev/sdb1;
    address   192.168.0.176:7789;
    meta-disk internal;
  }
}

创建资源r0:

node1和node2均执行
[root@node1 ~]# modprobe drbd    #载入模块
[root@node1 ~]# lsmod|grep drbd #确认载入
drbd 303444 3
libcrc32c 1246 1 drbd
[root@node1 ~]# dd if=/dev/zero of=/dev/sdb1 bs=1M count=100 #复制些数据,防止create-md时出错
[root@node1 ~]# drbdadm create-md r0 #创建drbd resource
[root@node1 ~]# drbdadm up r0               #启动创建的资源r0

以上编译安装配置操作过程均在node2中同样执行

配置完成后,查看主备资源状态:
主节点

[root@node1 ~]# cat /proc/drbd
version: 8.4.1 (api:1/proto:86-100)
GIT-hash: 91b4c048c1a0e06777b5f65d312b38d47abaea80 build by root@primary, 2015-03-10 13:38:08

 1: cs:Connected ro:Secondary/Secondary ds:Inconsistent/Inconsistent C r-----
    ns:0 nr:0 dw:0 dr:0 al:0 bm:0 lo:0 pe:0 ua:0 ap:0 ep:1 wo:b oos:52427148

备节点

[root@node2 ~]# cat /proc/drbd
version: 8.4.1 (api:1/proto:86-100)
GIT-hash: 91b4c048c1a0e06777b5f65d312b38d47abaea80 build by root@backup, 2015-03-10 13:38:22

 1: cs:Connected ro:Secondary/Secondary ds:Inconsistent/Inconsistent C r-----
    ns:0 nr:0 dw:0 dr:0 al:0 bm:0 lo:0 pe:0 ua:0 ap:0 ep:1 wo:b oos:52427148

node1和node2状态都是Secondary,现在需要设置一个Primary做为主节点。

把node1做为主节点,在node1上执行:
[root@node1 ~]# drbdadm primary  r0
再看下状态

[root@node1 ~]# cat /proc/drbd
version: 8.4.1 (api:1/proto:86-100)
GIT-hash: 91b4c048c1a0e06777b5f65d312b38d47abaea80 build by root@primary, 2015-03-10 13:38:08

 1: cs:SyncSource ro:Primary/Secondary ds:UpToDate/Inconsistent C r-----
    ns:484352 nr:0 dw:0 dr:485016 al:0 bm:28 lo:2 pe:9 ua:0 ap:0 ep:1 wo:b oos:51952012
	[>....................] sync'ed:  1.0% (50732/51196)M
	finish: 0:16:23 speed: 52,792 (52,792) K/sec

node2状态

[root@node2 ~]# cat /proc/drbd
version: 8.4.1 (api:1/proto:86-100)
GIT-hash: 91b4c048c1a0e06777b5f65d312b38d47abaea80 build by root@backup, 2015-03-10 13:38:22

 1: cs:SyncTarget ro:Secondary/Primary ds:Inconsistent/UpToDate C r-----
    ns:0 nr:1522688 dw:1520640 dr:0 al:0 bm:92 lo:3 pe:2 ua:2 ap:0 ep:1 wo:b oos:50906508
	[>....................] sync'ed:  3.0% (49712/51196)M
	finish: 0:11:06 speed: 76,312 (69,120) want: 100,160 K/sec

同步配置完成。

格式化挂载/dev/drbd1(只能在node1上执行):
[root@node1 ~]# mkfs.ext3 /dev/drbd1
[root@node1 ~]# mount /dev/drbd1 /db/
[root@node1 ~]# df -h
Filesystem Size Used Avail Use% Mounted on
/dev/mapper/VolGroup-lv_root 14G 1.3G 12G 10% /
tmpfs 489M 0 489M 0% /dev/shm
/dev/sda1 485M 33M 427M 8% /boot
/dev/drbd1 50G 180M 47G 1% /db

现在在node1的/db下创建文件等操作都会同步到node2的/dev/sdb1中
在/db下创建个测试文件
[root@node1 db]# touch TestWriteFromPrimary

停掉node2的drbd看是否同步过去。因为在drbd启动的时候,备机是无法挂载的。会提示个unknown filesystem type ‘drbd’

[root@node2 ~]# drbdadm down r0
[root@node2 ~]# mount /dev/sdb1 /db
[root@node2 ~]# ll /db/
total 16
drwx——. 2 root root 16384 Mar 11 10:47 lost+found
-rw-r–r–. 1 root root 0 Mar 11 10:48 TestWriteFromPrimary
看到TestWriteFromPrimary已经同步。

测试手动切换主备:
比如把node1改为Secondary,node2改为Primary,首先停掉挂载。

[root@node1 ~]# umount /dev/drbd1      #卸载
[root@node1 ~]# drbdadm secondary r0 #更改角色

[root@node1 ~]# cat /proc/drbd
version: 8.4.1 (api:1/proto:86-100)
GIT-hash: 91b4c048c1a0e06777b5f65d312b38d47abaea80 build by root@primary, 2015-03-10 13:38:08

 1: cs:Connected ro:Secondary/Secondary ds:UpToDate/UpToDate C r-----
    ns:52829360 nr:0 dw:958132 dr:51872669 al:446 bm:3202 lo:0 pe:0 ua:0 ap:0 ep:1 wo:b oos:0

[root@node2 ~]# drbdadm primary r0

[root@node2 ~]# cat /proc/drbd
version: 8.4.1 (api:1/proto:86-100)
GIT-hash: 91b4c048c1a0e06777b5f65d312b38d47abaea80 build by root@backup, 2015-03-10 13:38:22

 1: cs:Connected ro:Primary/Secondary ds:UpToDate/UpToDate C r-----
    ns:0 nr:829720 dw:829720 dr:664 al:0 bm:54 lo:0 pe:0 ua:0 ap:0 ep:1 wo:b oos:0

node2挂载/dev/drbd1
[root@node2 ~]# mount /dev/drbd1 /db/
[root@node2 ~]# df -h
Filesystem Size Used Avail Use% Mounted on
/dev/mapper/VolGroup-lv_root 14G 1.2G 12G 10% /
tmpfs 489M 0 489M 0% /dev/shm
/dev/sda1 485M 33M 427M 8% /boot
/dev/drbd1 50G 180M 47G 1% /db
[root@node2 ~]# cd /db
[root@node2 db]# touch TestWriteFromNode2

去node1停掉drbd,挂载sdb1看是否同步过去。
[root@node1 ~]# drbdadm down r0
[root@node1 ~]# mount /dev/sdb1 /db
[root@node1 ~]# ll /db
total 16
drwx——. 2 root root 16384 Mar 11 10:47 lost+found
-rw-r–r–. 1 root root 0 Mar 11 10:59 TestWriteFromNode2
-rw-r–r–. 1 root root 0 Mar 11 10:48 TestWriteFromPrimary
文件已同步。

关于drbdadm更多的参数可在命令行下直接执行 drbdadm 即可看到。

关于drbd的数据同步协议
drbd有三种数据同步模式:同步,异步,半同步
异步 :指的是当数据写到磁盘上,并且复制的数据已经被放到我们的tcp缓冲区并等待发送以后,就认为写入完成
半同步:指的是数据已经写到磁盘上,并且这些数据已经发送到对方内存缓冲区,对方的tcp已经收到数据,并宣布写入
同步 :指的是主节点已写入,从节点磁盘也写入
drbd的复制模型是靠protocol关键字来定义的:protocol A表示异步;protocol B表示半同步;protocol C表示同步,默认为protocol C。
在同步模式下只有主、从节点上两块磁盘同时损害才会导致数据丢失。在半同步模式下只有主节点宕机,同时从节点异常停电才会导致数据丢失。
注意:drbd的主不会监控从的状态所以有可能会造成数据重传

 

Linux下搭建iSCSI服务器

这里用esxi虚拟化中的虚拟机测试,添加一块200G的硬盘。
selinux、iptables 关闭

[root@localhost ~]# fdisk -l  #对新硬盘创建分区,不用挂载。

Disk /dev/sdb: 214.7 GB, 214748364800 bytes
255 heads, 63 sectors/track, 26108 cylinders
Units = cylinders of 16065 * 512 = 8225280 bytes
Sector size (logical/physical): 512 bytes / 512 bytes
I/O size (minimum/optimal): 512 bytes / 512 bytes
Disk identifier: 0x8d42c5ad

Device Boot Start End Blocks Id System
/dev/sdb1 1 26108 209712478+ 83 Linux

安装scsi target:
[root@localhost ~]# yum install -y scsi-target-utils

配置文件及命令:
/etc/tgt/targets.conf       主配置文档,设置要分享的磁盘
/usr/sbin/tgt-admin       线上查询、删除target 等功能的管理工具
/usr/sbin/tgt-setup-lun 建立target 以及设置分享的磁盘与可使用的用户端等工具软体
/usr/sbin/tgtadm            手动直接管理的管理员工具(可使用配置文档取代)
/usr/sbin/tgtd                 主要提供iSCSI target 服务的主程式
/usr/sbin/tgtimg             建置预计分享的映像档装置的工具(以映像档模拟磁盘)

编辑配置文件:
[root@localhost ~]# vi /etc/tgt/targets.conf

default-driver iscsi
<target iqn.2015-01.org.rootop:scsi1>
backing-store /dev/sdb1
initiator-address 192.168.0.16
incominguser admin admin123456789
</target>

target                      #目标名称
backing-store       #存储设备
initiator-address #限制来源IP
incominguser       #身份认证

重启tgtd服务:
[root@localhost ~]# service tgtd restart
[root@localhost ~]# chkconfig tgtd on

查看iscsi信息:

客户端挂载:

在WindowsServer2008R2中做iSCSI存储服务器

Windows Storage Server 2008是Windows Server 2008系列中的存储服务器版本,
是企业级的文件服务器平台,支持多Administrator文件存储相关的优化特性、副本管理,以及iSCSI功能。
简单来说,就是可以在普通的服务器上,安装上WSS2008,可以作为iSCSI存储服务器来说。而在以前,存储服务器的硬件、软件成本都比较昂贵,有了WSS2008,构建低成本、易于管理的存储服务器成为可能。

首先下载:Windows_Storage_Server_2008_R2.iso
在微软官网没找到下载地址,从百度网盘找到个资源,不确定安全性是否可靠。
可以直接在百度搜索 Windows_Storage_Server_2008_R2.iso 找到下载地址。

下载:iscsiTarget
版本: 3.3.16567 #目前微软官方最新
下载地址:http://download.microsoft.com/download/2/F/1/2F110B9C-6CB0-45F1-971B-4BA37395D820/iscsiTargetqfe6.exe

这个Windows_Storage_Server_2008_R2 看资料说是在server 2008 R2上打的补丁,然后系统版本就变为storage server 2008 R2 。
我这里系统为Server 2008 R2 enterprise ,在此基于安装storage server。
挂载下载的镜像或直接解压,打开文件夹下的Windows Storage Server 2008 R2目录,直接双击Windows6.1-KB982050-x64-EnterpriseBranding.MSU安装。
然后查看系统版本就变为storage server。下载iscsiTarget,解压,到x64目录下安装iscsitarget_public.msi即可。
安装过程为英文,完成后,从 管理工具 中找到 Microsoft iSCSI Software Target 运行后就是中文了。
安装过程中提示下载补丁,补丁已经包含在iso镜像中。直接点击确定即可。

从 管理工具 中找到 Microsoft iSCSI Software Target 开始配置iscsi存储服务器:

在iSCSI目标上“右键”,选择“创建iscsi目标”

点击“下一步”

iSCSI目标名称及描述可以自定义为自己的。

设置发起程序标示符,这里我是提供给内网的客户端使用,所以用客户端的ip来设定标识。也可以用发起端的名称。

创建虚拟磁盘

下一步

指定虚拟磁盘文件路径,这里我是测试用,只有一个分区,所以放到了c盘,实际环境中放到单独的一个分区中,而且服务器最好是做raid保护。

设定大小,这里给了10G。

描述可自行修改,继续下一步,完成。

回到windows客户端,我这里全部为win7系统,从 管理工具 找到 iSCSI 发起程序,在“目标”选项卡中,目标,写入服务器ip地址,点击快速连接。

点击“完成”即可。到磁盘管理中可以看到。

提示需要初始化磁盘,然后格式化即可。

扩展虚拟磁盘:

如果说客户端磁盘不够用的,可以在Microsoft iSCSI Software Target中扩大虚拟磁盘容量。

选择“设备”找到客户端所使用的虚拟磁盘,右键,扩展虚拟磁盘,根据提示,设置扩大多少容量。比如我这里再给10G。根据提示,完成。

磁盘管理-右键-刷新,可以看到新添加的10G磁盘。

可以通过“扩展卷”,将新分配的10G磁盘扩展到已有的分区中。根据提示操作即可。这样虚拟磁盘扩容完成。

快照功能:

在“设备”-虚拟磁盘-右键-创建快照。

在“快照”-活动快照,中可以看到创建的快照。

现在在iscsi目标中的iscsi-01中删除虚拟磁盘1。右键,选择“从iscsi目标删除虚拟磁盘”。

从活动快照,虚拟磁盘1,右键,回滚到快照。

然后从iscsi目标中,选择“向iscsi目标添加现有虚拟磁盘”。即可。

这里我在快照之前在磁盘中创建了一个文件夹test,一个文本文档test.txt,快照之后创建了一个test2.txt,回滚快照,发现test2没有了,说明快照生效。