51工具盒子

依楼听风雨
笑看云卷云舒,淡观潮起潮落

数据库备份脚本

之前有朋友问有没有备份脚本,给分享一个,我就很是好奇,实在不会自己写,网上一搜一大堆的东西麽,拿过来改吧改吧就可以用了呀,实在没有啥可写的,但有人要求了,这里就水一篇吧。

备份脚本六个注意点

在写脚本前我这里按照个人习惯大概总结了以下六点,感兴趣的可以继续看看,不感兴趣的直接跳过就好。

1、首先要注意的一点就是 shell 环境是 bash 还是 sh ,需要在你的脚本开头中注明。

#!/bin/bash

2、其次就是数据库环境变量需要申明,例如直接加载 .bash_profile 或者单独申明 ORACLE_HOME、ORACLE_BASE 等。

source /home/oracle/.bash_profile
`或者
ORACLE_BASE=/u01/app/oracle
ORACLE_HOME=/u01/app/product/11.2.0/dbhome_1
ORACLE_SID=JiekeXu1
ORACLE_USER=oracle
ORACLE_GROUP=oinstall`

3、接下来就是定义相关备份目录、日志目录等全局通用目录。

DICPATH=/db_backup/oracle/rman
`LOGPATH=$DICPATH/log
DATPATH=$DICPATH/data`

4、到这里呢才算开始正式的备份任务,使用数据库备份工具编写备份脚本。

rman target / 
`mysqldump ......`

5、备份完成需要考虑存放日期,存放一周,两周,或者 scp、ftp 等传到远程异地,然后考虑清理本地的磁盘空间。

--清理备份产生的日志
find ${DIR}/log -name ${NAME}\* -mtime +90 | xargs rm -f
--清理备份集
--使用操作系统命令直接删除备份集
find ${DIR}/data -name ${NAME}\* -mtime +30 | xargs rm -f
  1. 这一步就是部署备份了,一般借助操作系统的 crontab 定时任务来搞定。

crontab 命令的语法

crontab [-u username] [-l|-e|-r]
选项与参数:
-u :只有 root 才能进行这个任务,亦即帮其他使用者创建/移除 crontab 工作排程;
-e :编辑 crontab 的工作内容
-l :查阅 crontab 的工作内容
-r :移除所有的 crontab 的工作内容,若仅要移除一项,请用 -e 去编辑

*    *    *    *    *
-    -    -    -    -
|    |    |    |    |
|    |    |    |    +----- 星期中的星期几 (0 - 6) (星期天为 0)
|    |    |    +---------- 月份 (1 - 12) 
|    |    +--------------- 一个月中的第几天 (1 - 31)
|    +-------------------- 小时 (0 - 23)
+------------------------- 分钟 (0 - 59)

另外关于 crontab 还有几点要注意的:

  • 定时任务添加注释

  • >/dev/null 2>&1 ==> &>/dev/null,别随意打印日志文件

  • 定时任务里面的程序脚本尽量用全路径

  • 避免不必要的程序以及命令输出

  • 定时任务之前添加注释

    下面看几个 crontab 的例子。

    0 */2 * * * /sbin/service httpd restart 意思是每两个小时重启一次apache

    50 7 * * * /sbin/service sshd start 意思是每天7:50开启ssh服务

    50 22 * * * /sbin/service sshd stop 意思是每天22:50关闭ssh服务

    0 0 1,15 * * fsck /home 每月1号和15号检查/home 磁盘

    1 * * * * /home/jieke/backup 每小时的第一分执行 /home/jieke/backup这个文件

    00 03 * * 1-5 find /home/oracle ".xxx" -mtime +4 -exec rm {} ; 每周一至周五3点钟,在目录 /home/oracle 中,查找文件名为.xxx的文件,并删除4天前的文件。

    30 6 */10 * * ls 意思是每月的1、11、21、31日是的6:30执行一次ls命令


下面正式分享几个脚本。

Oracle rman 增备脚本

vim  /home/oracle/scripts/oracle_rman.sh

#!/bin/bash
source /home/oracle/.bash_profile


DICPATH=/db_backup/oracle/rman


LOGPATH=$DICPATH/log
DATPATH=$DICPATH/data


if \[ ! -d $LOGPATH \]; then
mkdir -p $LOGPATH
fi


if \[ ! -d $DATPATH \]; then
mkdir -p $DATPATH
fi


if \[ "$1" = "full" \]; then
echo 'jxrt'
rman target /  nocatalog msglog=$LOGPATH/rman_db_`date '+%Y%m%d%H%M%S'`.log \<\<EOF
run{
REPORT OBSOLETE;
#crosscheck archivelog all;
allocate channel c1 type disk;
allocate channel c2 type disk;
allocate channel c3 type disk;
allocate channel c4 type disk;
allocate channel c5 type disk;
allocate channel c6 type disk;
allocate channel c7 type disk;
allocate channel c8 type disk;
sql 'alter system archive log current';
backup as compressed  backupset incremental level 0 cumulative database FILESPERSET 8 tag 'dbfull' format '$DATPATH/full_%d_%T_%s_%U.bak' ;
sql 'alter system archive log current';
backup as compressed backupset archivelog all tag 'arch' format '$DATPATH/arch_%d_%T_%s_%U.arc';
DELETE force NOPROMPT OBSOLETE  recovery window of 8 days device type disk;
delete noprompt expired backup;
delete noprompt expired archivelog all;
backup current controlfile format '$DATPATH/ctl_%d_%T_%s_%U.bak';
release channel c1;
release channel c2;
release channel c3;
release channel c4;
release channel c5;
release channel c6;
release channel c7;
release channel c8;
}
exit;
EOF


elif \[ "$1" = "diff" \]; then
rman target /  nocatalog msglog=$LOGPATH/rman_db_`date '+%Y%m%d%H%M%S'`.log \<\<EOF
run{
REPORT OBSOLETE;
#crosscheck archivelog all;
allocate channel c1 type disk;
allocate channel c2 type disk;
allocate channel c3 type disk;
allocate channel c4 type disk;
allocate channel c5 type disk;
allocate channel c6 type disk;
allocate channel c7 type disk;
allocate channel c8 type disk;
sql 'alter system archive log current';
backup as compressed  backupset incremental level 1 cumulative database FILESPERSET 8 tag 'dbincrL1' format '$DATPATH/incr_L1_%d_%T_%s_%U.bak' ;
sql 'alter system archive log current';
backup as compressed backupset archivelog all tag 'arch' format '$DATPATH/arch_%d_%T_%s_%U.arc';
DELETE force NOPROMPT OBSOLETE  recovery window of 8 days device type disk;
delete noprompt expired backup;
delete noprompt expired archivelog all;
backup current controlfile format '$DATPATH/ctl_%d_%T_%s_%U.bak';
release channel c1;
release channel c2;
release channel c3;
release channel c4;
release channel c5;
release channel c6;
release channel c7;
release channel c8;
}
exit;
EOF
fi

`#oracle 用户下的定时备份任务,可加参数 full 或者 diff
#30 0 * * * sh /home/oracle/db/scripts/oracle_rman.sh full`

运行脚本
每周五凌晨 2:10 分运行 rman 脚本进行数据库全备,注意后面加参数 full;
其他时间每天 2:22 分运行 rman 脚本进行数据库增量备份,注意后面加参数 diff。

10 2 * * 5 /bin/bash /home/oracle/scripts/oracle_rman.sh full
22 2 * * 6,0,1,2,3,4 /bin/bash /home/oracle/scripts/oracle_rman.sh diff
Oracle rman 全备脚本

下面的脚本是对数据库进行全备或者归档日志备份的,注意如果使用到了 catlog 的话,也可以使用我注释掉的 rman target catlog 连接串。

vim rman_nfs_bak.sh

#!/bin/bash


---------------------------------------------------------------------
=====================================================================



hot_database_backup_proxy.sh
============================



---------------------------------------------------------------------
=====================================================================



This script uses Recovery Manager to take a hot (inconsistent) database
=======================================================================



backup. A hot backup is inconsistent because portions of the database are
=========================================================================



being modified and written to the disk while the backup is progressing.
=======================================================================



You must run your database in ARCHIVELOG mode to make hot backups. It is
========================================================================



assumed that this script will be executed by user root. In order for RMAN
=========================================================================



to work properly we switch user (su -) to the oracle dba account before
=======================================================================



execution. If this script runs under a user account that has Oracle dba
=======================================================================



privilege, it will be executed using this user's account.
=========================================================



---------------------------------------------------------------------
=====================================================================



ORACLE_USER=oracle
ORACLE_GROUP=oinstall
TARGET_CONNECT_STR=/
ORACLE_SID=JIEKEDB2
BAK_DIR=/backup/DB_Bak


source /home/${ORACLE_USER}/.bash_profile


---------------------------------------------------------------------
=====================================================================



Get the directory where the script locates and create log directory.
====================================================================



---------------------------------------------------------------------
=====================================================================



DIR=$(cd `dirname ${0}`; pwd)
if \[ ! -d ${DIR}/logs \]
then
mkdir -p ${DIR}/logs
chown -R ${ORACLE_USER}:${ORACLE_GROUP} ${DIR}/logs
fi


---------------------------------------------------------------------
=====================================================================



Get the variables we need from the local instance.
==================================================



---------------------------------------------------------------------
=====================================================================



SID=`ps -ef|grep pmon|grep ora_|awk -F'_' '{print $NF}'`
case "$SID" in
"$ORACLE_SID")   RCVCAT_CONNECT_STR=jieke/jieke0jiekeR#@catalog
;;
\*) echo "Cannot get SID,database is not running" \>\> ${DIR}/logs/`basename ${0}`_error.out
exit 1
;;
esac


---------------------------------------------------------------------
=====================================================================



Determine the user which is executing this script.
==================================================



---------------------------------------------------------------------
=====================================================================



CUSER=`whoami`
if \[ ${CUSER} != ${ORACLE_USER} \]
then
echo "Please user oracle_user to run the script!" \>\> ${DIR}/logs/`basename ${0}`_error.out
exit 1
fi


---------------------------------------------------------------------
=====================================================================



Put output in \<this file name\>.out. Change as desired.
========================================================



Note: output directory requires write permission.
=================================================



---------------------------------------------------------------------
=====================================================================



case "$1" in
"arch") RMAN_LOG_FILE=${ORACLE_SID}arch`date +%Y%m%d-%H%M%S`.out
;;
"full") RMAN_LOG_FILE=${ORACLE_SID}full`date +%Y%m%d-%H%M%S`.out
;;
\*) echo " The following word is needed as a script parameter: arch or full! "\>\> ${DIR}/logs/`basename ${0}`_error.out
exit 1
;;
esac


NAME=`basename ${0}`
RMAN_LOG_FILE=${DIR}/logs/`basename $RMAN_LOG_FILE`
find ${DIR}/logs -name ${NAME}\* -mtime +30 \| xargs rm -f
if \[ -h ${DIR}/logs/last \]
then
rm ${DIR}/logs/last
fi
ln -s $RMAN_LOG_FILE ${DIR}/logs/last


---------------------------------------------------------------------
=====================================================================



You may want to delete the output file so that backup information does
======================================================================



not accumulate. If not, delete the following lines.
===================================================



---------------------------------------------------------------------
=====================================================================



if \[ -f "$RMAN_LOG_FILE" \]
============================



then
====



rm -f "$RMAN_LOG_FILE"
======================



fi
===



-----------------------------------------------------------------
=================================================================



Initialize the log file.
========================



-----------------------------------------------------------------
=================================================================



echo\>\> $RMAN_LOG_FILE
chmod 666 $RMAN_LOG_FILE


---------------------------------------------------------------------
=====================================================================



Log the start of this script.
=============================



---------------------------------------------------------------------
=====================================================================



echo Script $0 \>\> $RMAN_LOG_FILE
echo ==== started on `date '+%a,%Y%m%d-%H:%M:%S'` ==== \>\> $RMAN_LOG_FILE
echo\>\> $RMAN_LOG_FILE


---------------------------------------------------------------------
=====================================================================



Print out the value of the variables set by this script.
========================================================



---------------------------------------------------------------------
=====================================================================



echo\>\> $RMAN_LOG_FILE
echo   "RMAN: $RMAN" \>\> $RMAN_LOG_FILE
echo   "ORACLE_SID: $ORACLE_SID" \>\> $RMAN_LOG_FILE
echo   "ORACLE_USER: $ORACLE_USER" \>\> $RMAN_LOG_FILE
echo   "ORACLE_HOME: $ORACLE_HOME" \>\> $RMAN_LOG_FILE


Convert requests for incremental into archive log only backups
==============================================================



if \[ "$1" = "arch" \]; then
echo "Archive log only backup requested" \>\> $RMAN_LOG_FILE
CMD_STR="
#rman target $TARGET_CONNECT_STR catalog $RCVCAT_CONNECT_STR log $RMAN_LOG_FILE append \<\< EOF
rman target / log $RMAN_LOG_FILE append \<\< EOF
RUN {
sql 'alter system archive log current';
ALLOCATE CHANNEL ch00 device type DISK;
BACKUP
FILESPERSET 5
FORMAT '${BAK_DIR}/arch_%d_%s_%p_%t'
ARCHIVELOG ALL;
RELEASE CHANNEL ch00;
}
EOF
"
elif \[ "$1" = "full" \]; then
echo "Full database backup requested" \>\> $RMAN_LOG_FILE
CMD_STR="
rman target $TARGET_CONNECT_STR catalog $RCVCAT_CONNECT_STR log $RMAN_LOG_FILE append \<\< EOF
RUN {
ALLOCATE CHANNEL ch00 device type DISK;
ALLOCATE CHANNEL ch01 device type DISK;
BACKUP
TAG ${ORACLE_SID}hot_backup
FILESPERSET 5
FORMAT '${BAK_DIR}/database%d_%s_%p_%t'
DATABASE;
sql 'alter system archive log current';
RELEASE CHANNEL ch00;
RELEASE CHANNEL ch01;
}
EOF
"
fi


Initiate the command string
===========================



sh -c "$CMD_STR"
#sh -c "$CMD_STR" \>\> $RMAN_LOG_FILE
RSTAT=$?


---------------------------------------------------------------------
=====================================================================



Log the completion of this script.
==================================



---------------------------------------------------------------------
=====================================================================



if \[ "$RSTAT" = "0" \]
then
LOGMSG="ended successfully"
else
LOGMSG="ended in error"
fi


echo\>\> $RMAN_LOG_FILE
echo Script $0 \>\> $RMAN_LOG_FILE
echo ==== $LOGMSG on `date '+%a,%Y%m%d-%H:%M:%S'` ==== \>\> $RMAN_LOG_FILE
echo\>\> $RMAN_LOG_FILE

`exit $RSTAT`

运行脚本

每周一凌晨 1:10 分运行 rman 脚本进行数据库全备,注意后面加参数 full;
其他时间每天 0:10 分运行 rman 脚本进行数据库归档日志备份,注意后面加参数 arch。

10 1 * * 1 /home/oracle/db/scripts/rman_nfs_bak.sh full
10 0 * * * /home/oracle/db/scripts/rman_nfs_bak.sh arch

Oracle 归档删除脚本

vi /home/oracle/clear_arch.sh

#!/bin/bash
ORACLE_BASE=/u01/app/oracle
ORACLE_HOME=/u01/app/product/19.0.0/dbhome_1
ORACLE_SID=jiekexu


PATH=$PATH:$ORACLE_HOME/bin/
source /home/oracle/.bash_profile

`rman target / log=/home/oracle/clear_arch.log<<EOF
delete force noprompt archivelog all completed before 'sysdate-5';
exit
EOF`

运行脚本
chmod +x /home/oracle/clear_arch.sh
每隔六个小时运行一次,清理五天之前的归档日志。注意有备库或者 ogg 的需要格外注意,避免被过早的删除。

crontab -e
0 0,6,12,18 * * * /home/oracle/clear_arch.sh

MySQL xtrabackup 全备/增备脚本

more /home/mysql/scripts/backup.sh

#!/bin/bash


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="root"
DB_PASS="R00t@123"
#HOST="127.0.0.1"
#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="/db_bak/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 ""


vim  /home/mysql/scripts/cleanup.sh


#!/bin/bash


echo ""
START_TIME=`date`
echo "############## clean up start at $START_TIME ##############"
echo ""


find /db_bak/mysql_bak/mysql -maxdepth 1 -type d -mtime +30
find /db_bak/mysql_bak/mysql -maxdepth 1 -type d -mtime +30 -exec rm -rf {} ;

`echo ""
END_TIME=``date``
echo "############## clean up end at $END_TIME ##############"
echo ""`

运行脚本

每天凌晨 0:10 分清理 30 天之前的备份,每天 0:30 分使用 xtrabackup 进行备份,注意只有周六是全备,其他时间均是增备。

10 0 * * * /home/mysql/scripts/cleanup.sh >> /home/mysql/scripts/cleanup.log 2>&1
30 0 * * * /home/mysql/scripts/backup.sh >> /home/mysql/scripts/backup.log 2>&1

MySQL mysqldump 备份脚本 1

#!/bin/bash

定义变量
====



DB_USER="root"
DB_PASS="password"
DB_NAME="database_name"
BACKUP_DIR="/db_backup/mysql"
REMOTE_SERVER="remote_server_address"
REMOTE_DIR="/db_backup/mysql"


创建备份目录
======



if \[ ! -d $BACKUP_DIR \]; then
mkdir -p $BACKUP_DIR
fi


备份数据库
=====



mysqldump -u$DB_USER -p$DB_PASS $DB_NAME \> $BACKUP_DIR/$DB_NAME-$(date +%Y%m%d).sql


压缩备份文件
======



tar -czvf $BACKUP_DIR/$DB_NAME-$(date +%Y%m%d).tar.gz $BACKUP_DIR/$DB_NAME-$(date +%Y%m%d).sql


上传备份文件到远程服务器
============



scp $BACKUP_DIR/$DB_NAME-$(date +%Y%m%d).tar.gz $REMOTE_SERVER:$REMOTE_DIR


删除过期备份文件
========


`find $BACKUP_DIR -type f -name "*.tar.gz" -mtime +15 -delete`

MySQL mysqldump 备份脚本 2
vim mysql_backup.sh

#!/bin/bash
#完成数据库的定时备份
#备份的路径
BACKUP=/db_backup/backup/db
#当前的时间作为文件名
DATETIME=$(date +%Y_%m_%d_%H%M%S)
#可以输出变量调试
#echo ${DATETIME}
echo "==========开始备份==========="
echo "备份的路径是 $BACKUP/$DATETIME.tar.gz"

#主机
HOST=localhost
#用户名
DB_USER=root
#密码
DB_PWD=root
#备份数据库名
DATABASE=mysql
#创建备份的路径
#如果备份的路径文件夹存在就使用,否则创建
[ ! -d "$BACKUP/$DATETIME"  ]  && mkdir -p "$BACKUP/$DATETIME" 
#执行mysql的备份数据库的指令
mysqldump -u${DB_USER} -p${DB_PWD} --host=$HOST  $DATABASE | gzip  > $BACKUP/$DATETIME/$DATETIME.sql.gz
#打包备份文件
cd $BACKUP
tar -zcvf  $DATETIME.tar.gz  $DATETIME
#删除临时目录
rm -rf  $BACKUP/$DATETIME

#删除15天前的备份文件(-exec rm -rf {} \是固定写法,删除查询出来的数据)
find $BACKUP -mtime +15 -name  "*.tar.gz" -exec rm -rf {} \;
echo "==========备份完成==========="

MySQL mysqldump 备份脚本 3

vim mysql_backup.sh

#!/bin/bash
#全备方式,一般在从机上执行,适用于小中型mysql数据库
#删除15天以前备份


source /etc/profile        #加载系统环境变量
source \~/.bash_profile    #加载用户环境变量
set -o nounset             #引用未初始化变量时退出
#set -o errexit            #执行shell命令遇到错误时退出


user="root"
password="root"
host="localhost"
port="13306"
#需备份的数据库,数组
db=("test")
#备份时加锁方式,
#MyISAM为锁表--lock-all-tables,
#InnoDB为锁行--single-transaction
lock="--single-transaction"
mysql_path="/usr/local/mysql"
backup_path="${mysql_path}/backup"
date=$(date +%Y-%m-%d_%H-%M-%S)
day=15
backup_log="${mysql_path}/backup.log"


#建立备份目录
if \[ ! -e $backup_path \];then
mkdir -p $backup_path
fi


#删除以前备份
find $backup_path -type f -mtime +$day -exec rm -rf {} ; \> /dev/null 2\>\&1


echo "开始备份数据库:${db\[\*\]}"


#备份并压缩
backup_sql(){
dbname=$1
backup_name="${dbname}_${date}.sql"
#-R备份存储过程,函数,触发器
mysqldump -h $host -P $port -u $user -p$password $lock --default-character-set=utf8 --flush-logs -R $dbname \> $backup_path/$backup_name

if \[\[ $? == 0 \]\];then
cd $backup_path
tar zcpvf $backup_name.tar.gz $backup_name
size=$(du $backup_name.tar.gz -sh \| awk '{print $1}')
rm -rf $backup_name
echo "$date 备份 $dbname($size) 成功 "
else
cd $backup_path
rm -rf $backup_name
echo "$date 备份 $dbname 失败 "
fi
}


#循环备份
length=${#db\[@\]}
for (( i = 0; i \< $length; i++ )); do
backup_sql ${db\[$i\]} \>\> $backup_log 2\>\&1
done

`echo "备份结束,结果查看 $backup_log"
du $backup_path/`$date` -sh | awk '{print "文件:" $2 ",大小:" $1}'`

赞(0)
未经允许不得转载:工具盒子 » 数据库备份脚本