一、项目概况
因XX项目未建设备份一体机,存在数据丢失风险,本方案采用NFS服务将数据库服务器上挂载网络存储直接备份到网络存储上,保障生产数据在异机有备份,降低数据丢失风险。
NFS通常指的是 "Network File System"(网络文件系统)。这是一个允许在网络上共享文件系统的协议,最初由Sun Microsystems开发。NFS使得不同计算机之间可以通过网络共享文件和资源,使文件在网络上的访问变得更加方便。
以下是 NFS 的一些基本特点和工作原理:
网络共享:NFS 允许在网络上的计算机之间共享文件和目录。这使得用户可以在不同计算机之间访问和共享文件,就像它们是本地文件一样。
客户端-服务器模型:NFS 采用客户端-服务器模型。文件服务器上的文件系统通过 NFS 协议对客户端系统可见,客户端通过 NFS 客户端软件连接到文件服务器,并像本地文件一样访问远程文件系统。
透明性: 对用户来说,使用 NFS 访问远程文件系统就像访问本地文件一样,这就是透明性的概念。用户不需要了解文件存储在哪里或如何通过网络传输。
挂载(Mounting): 在 NFS 中,客户端通过挂载(mount)文件系统来访问远程服务器上的文件。一旦挂载完成,远程文件系统就会在本地文件系统层次结构中可用。
安全性: 随着 NFS 的发展,安全性成为越来越重要的关注点。较新的版本(如NFSv4)包括更强大的安全性特性,如Kerberos认证和加密传输。
二、安装依赖环境
本方案只需要1台机器,作为备份服务器,是NFS的服务端。
1、在备份服务器安装NFS服务端
(1)安装服务端
yum -y install nfs-utils rpcbind
(2)exports配置
vim /etc/exports
# 允许将 /data/beifen文件系统以读写方式(rw)和同步模式(sync)挂载
/data/beifen *(rw,sync)
(3)启动服务
systemctl start rpcbind
systemctl start nfs
systemctl enable rpcbind
systemctl enable nfs
2、在生产数据库服务器上安装NFS客户端
(1)nfs客户端安装
yum -y install nfs-utils
(2)启动服务
systemctl start nfs
systemctl enable nfs
三、编写脚本
1、编写NFS挂载和卸载脚本
此方案仅涉及mysql和文件备份脚本,其他数据库的原理一样,只需要更换备份脚本即可。
(1)挂载(mount_backup.sh)
#!/bin/bash
mount -t nfs 192.168.59.171:/data/fuhui /backup
(2)卸载(umount_backup.sh)
#!/bin/bash
umount /backup/
两个脚本均放在/root/backup_scripts/目录下
2、备份脚本(全量+增量)
此脚本也放在/root/backup_scripts/目录下,数据量小于100G,建议使用逻辑备份,具体脚本在附件。
vi /home/mysql/scripts/backup.sh
#!/bin/bash
# 挂载存储
sh /root/backup_scripts/mount_backup.sh
echo ""
START_TIME=`date`
echo "############## backup start at $START_TIME ##############"
echo ""
###you need install xtrabackup!###
# Set env
source /home/mysql/.bash_profile
which xtrabackup
# Database Info
DB_USER="数据库账号"
DB_PASS="R00t@123"
#HOST="数据库密码"
#PORT="24801"
CONF="/data/mysqldb/conf/mysql.conf"
SOCKET="/data/mysqldb/socket/mysql.sock"
# Databases to backup
# DB_NAME=("db1" "db2" "db3")
# Others
BAK_BASE="/backup/mysql_bak/mysql"
DATE=`date +%F`
YESTERDAY=`date +%F -d "-1 days"`
WEEK_DAY=`date +%w`
BAK_DIR=$BAK_BASE/$DATE-$WEEK_DAY
# Create Directory and backup
if [ "$WEEK_DAY" == "6" ]; then
xtrabackup --defaults-file=$CONF --socket=$SOCKET --backup --user=$DB_USER --password=$DB_PASS --target-dir=$BAK_DIR --compress
elif [ "$WEEK_DAY" == "0" ]; then
INCRE_BASE=$BAK_BASE/$YESTERDAY-6
xtrabackup --defaults-file=$CONF --socket=$SOCKET --backup --user=$DB_USER --password=$DB_PASS --target-dir=$BAK_DIR --incremental-basedir=$INCRE_BASE --compress
else
INCRE_BASE=$BAK_BASE/$YESTERDAY-$[WEEK_DAY-1]
xtrabackup --defaults-file=$CONF --socket=$SOCKET --backup --user=$DB_USER --password=$DB_PASS --target-dir=$BAK_DIR --incremental-basedir=$INCRE_BASE --compress
fi
# TODO
#for var in ${DB_NAME[@]};
#do
# xtrabackup --defaults-file=$CONF --socket=$SOCKET --backup --databases $var --user=$DB_USER --password=$DB_PASS --target-dir=$BAK_DIR --compress
#done
echo ""
END_TIME=`date`
echo "############## backup end at $END_TIME ##############"
echo ""
# 卸载存储
sh /root/backup_scripts/umount_backup.sh
vim /home/mysql/scripts/cleanup.sh
#!/bin/bash
echo ""
START_TIME=`date`
echo "############## clean up start at $START_TIME ##############"
echo ""
find /backup/mysql_bak/mysql -maxdepth 1 -type d -mtime +30
find /backup/mysql_bak/mysql -maxdepth 1 -type d -mtime +30 -exec rm -rf {} \;
echo ""
END_TIME=`date`
echo "############## clean up end at $END_TIME ##############"
echo ""
3、设置定时任务运行脚本
每天凌晨 0:10 分清理 30 天之前的备份,每天 0:30 分使用 xtrabackup 进行备份,注意只有周六是全备,其他时间均是增备。
crontab -e
10 0 * * * /root/backup_scripts/cleanup.sh >> /root/backup_scripts/cleanup.log 2>&1
30 0 * * * /root/backup_scripts/backup.sh >> /root/backup_scripts/backup.log 2>&1
4、附件
mysql逻辑备份脚本,数据量小于100G,建议使用逻辑备份。
#!/bin/bash
# 挂载存储
sh /opt/mount_backup.sh
#mybackup.sh
#备份保留天数,建议保留三天
days=1
#备份时间
time=`date +%Y%m%d%H%M%S`
# 设定日志名称
mkdir -p /backup/logs/
mkdir -p /backup/full/
logname="/backup/logs/full_`date +%Y%m%d`.log"
#logname="/backup/logs/`date +%Y%m%d`.log"
#备份保存路径
backup_dir=/backup/full
#备份工具
tool=mysqldump
#用户名
username=root
#密码
password=123456
#端口
port="3306"
#是否采用--all-databases备份所有数据库,是填写Y,否填其他
bak_all=Y
#将要备份的数据库,填写将要备份的数据库名
database_arr=(sqlroad information_schema mysql performance_schema sys)
#备份命令可根据实际情况自行添加参数
#如果文件夹不存在则创建
if [ ! -d $backup_dir/mysqlbak_$time ];
then
mkdir -p $backup_dir/mysqlbak_$time;
fi
if [ $bak_all == "Y" ];
then
$tool -u$username -p$password -P$port --master-data --single-transaction --all-databases |gzip > $backup_dir/mysqlbak_$time/mysqlbak_all_$time.sql.gz
else
i=0
while [ $i -lt "${#database_arr[*]}" ]
do
database=${database_arr[$i]}
$tool -u$username -p$password -P$port --master-data --single-transaction $database |gzip > $backup_dir/mysqlbak_$time/mysqlbak_${database}_${time}.sql.gz
let i+=1
done
fi
if [ -f "$backup_dir/mysqlbak_$time/mysqlbak_all_$time.sql.gz" ]; then
echo "文件存在,执行成功"
else
echo "文件不存在"
fi
#删除三天前的备份
find $backup_dir -maxdepth 1 -type d -mtime +$days -name 'mysqlbak*' -exec rm -rf {} \;
# 卸载存储
sh /opt/umount_backup.sh
文件备份脚本
#!/bin/bash
#备份路径信息
File_HOME=需要备份的文件或目录路径(根据实际修改)
Back_HOME="/data/huifu/file_back"
#时间格式化
DATE="`date +%Y%m%d`"
#文件保留天数
DAY=7
#选择备份类型,文件(F)或目录(D)
types=F
test -d $Back_HOME/file || mkdir -p $Back_HOME/file
#判断目录或文件是否为空
num=$(ls $File_HOME|wc -l )
if [ $num == 0 ]
then echo “备份文件或目录为空,已退出”
exit
fi
#执行备份
if [ $types == F ]
then
cp $File_HOME $Back_HOME/file
cd $Back_HOME/file
tar -cf $Back_HOME/file-${DATE}.tar.gz * --remove-files
rm -rf $Back_HOME/file
elif [ $types == D ]
then
cp -r $File_HOME/* $Back_HOME/file
cd $Back_HOME
tar -cf file-${DATE}.tar.gz file --remove-files
else echo "未知备份类型,退出"
exit
fi
if [ $? == 0 ]
then
echo “备份成功”
else
echo “备份失败,请检查磁盘空间”
exit
fi
echo -e "已创建备份文件:\e[32m file-${DATE}.tar.gz\e[0m"
#查找 * 天前的文件
OLD_BACKUP="`find ${Back_HOME} -type f -mtime +${DAY} -iname file-${DATE}\*.gz`"
#遍历旧备份文件
for bak in "${OLD_BACKUP[@]}"; do
rm -f ${bak}
done