VPS自动备份Shell脚本

2012年11月10日 | 分类: 搭建博客 | 标签: , , ,

VPS自动备份Shell脚本

VPS自动备份Shell脚本,用于Linux系统上一键备份和管理MySQL数据库以及Web数据,并自动上传至远程备份服务器。

一、特点与功能

1、纯shell脚本,使用简单,技术门槛低,容易修改,删除即可卸载。

2、可指定数据备份频率及保存的备份数量,能自动删除不必要的旧备份。

3、可指定多个需要备份的Mysql数据库,甚至排除某个数据库不备份。

4、可指定多个需要备份的数据目录,甚至支持二级目录打包备份。

5、支持本地和多重备份(ftp,scp,amazon s3),异地备份可选完全和增量备份。

二、下载与使用

2.1、下载脚本

https://gist.github.com/1505857

1
2
3
wget http://wangyan.org/download/shell/vps_auto_backup.sh
chmod 100 vps_auto_backup.sh
mkdir /var/shell && mv vps_auto_backup.sh /var/shell

2.2、设置cron守护进程

自动执行频率可随意设置,一般一小时一次就足够了。

1
2
crontab -e
0 * * * * /bin/bash  /var/shell/vps_auto_backup.sh

2.3、安装附加软件

如果你需要进行远程FTP、SCP备份,则需安装lftp、expect。

1
2
yum -y install lftp expect #centos
apt-get -y install lftp expect #ubuntu

三、配置选项

# 备份数据存放目录

1
BACKUP_DIR="/root/vps-bak"

MySQL备份选项

# 是否启用Mysql备份,0是关闭,1是启用。

1
ENABLE_MYSQL_BACKUP="1"

# 数据库备份时间间隔,1小时=3600秒。

1
MYSQL_BACKUP_CYCLE="43200"

# 数据库备份保存数量,默认保存最近4次备份。
# 例如:一天备份二次,需要保存最近二天备份,则此处填”4″

1
MYSQL_BACKUP_NUM="4"

# 数据库主机、用户名、密码。

1
2
3
MYSQL_HOST="localhost"
MYSQL_USER="root"
MYSQL_PWD="123456"

# 需要备份的数据库名,多个数据库要用空格分开,all表示所有数据库。

1
MYSQL_DB_NAMES="all"

# 需要排除备份的数据库名,多个数据库要用”|”分开。

1
MYSQL_EXCLUDE_DB="phpmyadmin|information_schema|performance_schema"

web备份选项

# 是否启用Web数据本地备份,0是关闭,1是启用。

1
ENABLE_LOCAL_BACKUP="1"

# 数据备份时间间隔,1小时=3600秒。

1
WWW_BACKUP_CYCLE="86400"

# 数据备份保存数量,默认保存最近2次备份。
# 例如:一天备份一次,需要保存最近二天备份,则此处填”2″

1
WWW_BACKUP_NUM="2"

# 需要备份的数据源目录,多个目录要用空格分开。

1
WWW_BACKUP_DIRS="/home /var/www"

# 需要备份的数据源目录深度,文件夹=0,文件夹+子文件夹=1

1
WWW_BACKUP_DEPTH="1"

FTP备份选项

# 是否启用远程FTP备份,0是关闭,1是启用。

1
ENABLE_FTP_BACKUP="0"

# FTP备份间隔,0表示禁用,1小时=3600秒

1
FTP_BACKUP_CYCLE="0"

# FTP备份模式,完全备份=0,增量备份=1

1
FTP_BACKUP_MODE="0"

# 远程FTP存储备份文件夹,如果不存在,则脚本会自动创建。

1
FTP_REMOTE_DIR="vps-bak"

# 远程FTP主机、用户名、密码。

1
2
3
FTP_HOSTNAME="192.168.8.128"
FTP_USERNAME="test"
FTP_PASSWORD="test"

SCP备份选项

# 是否启用远程scp备份,0是关闭,1是启用。
# 注意:为支持免证书登陆,需安装“expect”(yum -y install expect)

1
ENABLE_SCP_BACKUP="0"

# SCP备份间隔,0表示禁用,1小时=3600秒

1
SCP_BACKUP_CYCLE="0"

# 远程主机、用户名、密码。

1
2
3
SCP_HOST="192.168.8.128"
SCP_USER="root"
SCP_PASSWD="123456"

# 远程主机存储备份文件夹。

1
SCP_REMOTE_PATH="/root/vps-bak"

Amazon S3备份选项

# 是否启用Amazon s3备份,0是关闭,1是启用。

1
ENABLE_S3_BACKUP="0"

# Amazon s3 备份间隔,0表示禁用,1小时=3600秒

1
S3_BACKUP_CYCLE="0"

# Amazon s3备份模式,完全备份=0,增量备份=1

1
S3_BACKUP_MODE="0"

# Amazon s3 BUCKET名称,如果不存在,则脚本会自动创建。

1
S3_BUCKET="vps-bak"

# Amazon access key

1
ACCESS_KEY_ID="123456"

# Amazon secret access key

1
SECRET_ACCESS_KEY="123456"

四、建议反馈

如果您发现脚本存在错误或有更好的建议,可直接留言或发邮件至:

myidwy(at)gmail.com

五、更新历史

2011.12.23: 更新至0.2版,支持自定义远程备份频率、优化代码减少冗余。
2012.01.26: 更新至0.3版,修复在特定条件下,备份时间间隔值设置无效。

原文 : http://wangyan.org/blog/vps-backup-shell-script.html

==========

VPS自动监控Shell脚本

该脚本用于监控VPS服务器负载,Web程序内存及CPU使用。当服务器系统负载或内存使用达到预设值,则重启该程序,或者某个php-cgi进程占用CPU过大,则直接kill掉该进程。目的在于缓解服务器资源耗尽导致意外宕机等情况。

嗯,没错。该脚本是此前 v1 的更新版本,考虑今后可能还会更新,故移到 github gist 进行简单的版本控制。

一、使用方法:

1
2
3
4
git clone git://gist.github.com/1216837.git gist-1216837
vim gist-1216837/sys-mon.sh //修改内存、CPU等预设阀值
mkdir /var/script
mv gist-1216837/sys-mon.sh /var/script

设置每分钟执行一次

1
2
crontab -e
* * * * * /bin/bash  /var/shell/sys-mon.sh

二、Shell脚本内容

建议打开下面网址查看最新版本。

https://gist.github.com/1216837

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
#! /bin/bash
#====================================================================
# sys-mon.sh
#
# Copyright (c) 2011, WangYan <webmaster@wangyan.org>
# All rights reserved.
# Distributed under the GNU General Public License, version 3.0.
#
# Monitor system mem and load, if too high, restart some service.
#
# See: http://wangyan.org/blog/sys-mon-shell-script.html
#
# V 0.5, Date: 2011-12-08
#====================================================================

# Need to monitor the service name
# Must be in /etc/init.d folder exists
NAME_LIST="httpd nginx mysql"

# Single process to allow the maximum CPU (%)
PID_CPU_MAX="25"

# The maximum allowed memory (%)
PID_MEM_SUM_MAX="95"

# The maximum allowed system load
SYS_LOAD_MAX="6"

# Log path settings
LOG_PATH="/var/log/sys-mon.log"

# Date time format setting
DATA_TIME=$(date +"%y-%m-%d %H:%M:%S")

# Your email address
EMAIL="webmaster@example.com"

# Your website url
MY_URL="http://106.187.38.210/p.php"

#====================================================================

for NAME in $NAME_LIST
do
    PID_CPU_SUM="0";PID_MEM_SUM="0"
    PID_LIST=`ps aux | grep $NAME | grep -v root`

    IFS_TMP="$IFS";IFS=$'\n'
    for PID in $PID_LIST
    do
        PID_NUM=`echo $PID | awk '{print $2}'`
        PID_CPU=`echo $PID | awk '{print $3}'`
        PID_MEM=`echo $PID | awk '{print $4}'`
#       echo "$NAME: PID_NUM($PID_NUM) PID_CPU($PID_CPU) PID_MEM($PID_MEM)"

        PID_CPU_SUM=`echo "$PID_CPU_SUM + $PID_CPU" | bc`
        PID_MEM_SUM=`echo "$PID_MEM_SUM + $PID_MEM" | bc`

        if [ `echo "$PID_CPU >= $PID_CPU_MAX" | bc` -eq 1 ];then
            if [[ "$NAME" = "php-fpm" || "$NAME" = "httpd" ]];then
                sleep 5
                if [ `echo "$PID_CPU >= $PID_CPU_MAX" | bc` -eq 1 ];then
                    echo "${DATA_TIME}: kill ${NAME}($PID_NUM) successful (CPU:$PID_CPU)" | tee -a $LOG_PATH
                    kill $PID_NUM
                fi
            else
                echo "${DATA_TIME}: [WARNING!] ${NAME}($PID_NUM) cpu usage is too high! (CPU:$PID_CPU)" | tee -a $LOG_PATH
            fi
        fi
    done
    IFS="$IFS_TMP"

    SYS_LOAD=`uptime | awk '{print $(NF-2)}' | sed 's/,//'`
    SYS_MON="CPU:$PID_CPU_SUM MEM:$PID_MEM_SUM LOAD:$SYS_LOAD"
#   echo -e "$NAME: $SYS_MON\n"

    SYS_LOAD_TOO_HIGH=`awk 'BEGIN{print('$SYS_LOAD'>'$SYS_LOAD_MAX')}'`
    PID_MEM_SUM_TOO_HIGH=`awk 'BEGIN{print('$PID_MEM_SUM'>'$PID_MEM_SUM_MAX')}'`

    if [[ "$SYS_LOAD_TOO_HIGH" = "1" || "$PID_MEM_SUM_TOO_HIGH" = "1" ]];then
        /etc/init.d/$NAME stop
        sleep 5
        for ((i=1;i<4;i++))
        do
            if [ `pgrep $NAME | wc -l` = "0" ];then
                echo "$DATA_TIME: Stop $NAME successful! ($SYS_MON)" | tee -a $LOG_PATH
                break
            else
                echo "${DATA_TIME}: [WARNING!] Stop $NAME failed[$i]! ($SYS_MON)" | tee -a $LOG_PATH
                pkill $NAME && killall $NAME
            fi
        done
        /etc/init.d/$NAME start
        sleep 5
        for ((ii=1;ii<4;ii++))
        do
            if [ `pgrep $NAME | wc -l` != "0" ];then
                echo "$DATA_TIME: Start $NAME successful!" | tee -a $LOG_PATH
                break
            else
                echo "${DATA_TIME}: [WARNING!] Start $NAME failed[$ii]! ($SYS_MON)" | tee -a $LOG_PATH
                /etc/init.d/$NAME start
                sleep 5
            fi
        done
        if [ `pgrep $NAME | wc -l` != "0" ];then
            echo "${DATA_TIME}: [ERROR!] Start $NAME failed! ($SYS_MON)" | mail -s "Start $NAME failed" $EMAIL
        fi
    fi
done

STATUS_CODE=`curl -o /dev/null -s -w %{http_code} $MY_URL`
#echo -e "STATUS CODE: $STATUS_CODE\n"

if [ "$STATUS_CODE" != "200" ];then
    sleep 3
    STATUS_CODE=`curl -o /dev/null -s -w %{http_code} $MY_URL`
    if [ "$STATUS_CODE" != "200" ];then
        echo "${DATA_TIME}: [WARNING!] Website Downtime! ($SYS_MON)" | tee -a $LOG_PATH
        echo "${DATA_TIME}: [WARNING!] Website Downtime! ($SYS_MON)" | mail -s "Start $NAME failed" $EMAIL
    fi
fi

脚本内容不难理解,原理解释可参考《Linux 进程自动监控shell脚本》

三、注意事项

1、NAME_LIST 指定的监控程序必须在/etc/init.d 文件夹中存在,并且支持stop和start操作
2、PID_CPU_MAX 指的是单个进程的CPU占用,只针对php-fpm或httpd。
3、PID_MEM_SUM_MAX 指的是该程序所有进程实际内存占用,而并非系统总内存。
4、EMAIL 只有在程序启动失败后,你才能收到邮件提醒。

四、更新历史:

2011.11.28: 去掉nginx502状态监控,完善进程cpu监控,修正数据不准确等问题。
2011.12.07: 继续修正cpu监控不正确问题,增加宕机后邮件通知功能。

原文 : http://wangyan.org/blog/sys-mon-shell-script.html

===========

Linux 进程自动监控shell脚本

主要用于监控 linux 服务器负载及内存占用,当负载或内存占用达到设置值后,便自动重启该进程以避免宕机。

一、使用方法

下载、解压、运行

1
2
3
wget http://wangyan.org/download/script/pid_auto_reboot.tar.gz
tar -zxf pid_auto_reboot.tar.gz
./pid_auto_reboot.sh

设置每分钟执行一次

1
2
crontab -e
* * * * * /bin/bash  /var/shell/pid_auto_reboot.sh

二、原理解释

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
# 设置最大内存占用百分比
PID_MEM_MAX="85"

# 设置最大系统负载
SYS_LOAD_MAX="3"

# 设置需要监控的服务名称
NAME_LIST="php-fpm mysql"

for NAME in $NAME_LIST
do
    # 初始化内存统计
    PID_MEM_SUM=0

    # 获取该程序总进程数
    PID_NUM_SUM=`ps aux | grep $NAME | wc -l`

    # 列出每个进程内存占用百分比
    PID_MEM_LIST=`ps aux | grep $NAME | awk '{print $4}'`

    # 计算所有进程总内存占用
    for PID_MEM in $PID_MEM_LIST
    do
        PID_MEM_SUM=`echo $PID_MEM_SUM + $PID_MEM | bc`
    done

    # 获取最近一分钟系统负载
    SYS_LOAD=`uptime | awk '{print $(NF-2)}' | sed 's/,//'`

    # 比较内存占用和系统负载是否超过阀值
    MEM_VULE=`awk 'BEGIN{print('"$PID_MEM_SUM"'>='"$PID_MEM_MAX"'?"1":"0")}'`
    LOAD_VULE=`awk 'BEGIN{print('"$SYS_LOAD"'>='"$SYS_LOAD_MAX"'?"1":"0")}'`

    # 如果系统内存占用和系统负载超过阀值,则进行下面操作。
    if [ $MEM_VULE = 1 ] || [ $LOAD_VULE = 1 ] ;then
        #  写入日志
        echo $(date +"%y-%m-%d %H:%M:%S") "killall $NAME" "(MEM:$PID_MEM_SUM,LOAD:$SYS_LOAD)">> /var/log/autoreboot.log
        # 正常停止服务
        /etc/init.d/$NAME stop
        sleep 3
        # 强制关闭
        pkill $NAME

       #  重启
        /etc/init.d/$NAME start
       #写入日志
        echo $(date +"%y-%m-%d %H:%M:%S") "start $NAME" "(MEM:$PID_MEM_SUM,LOAD:$SYS_LOAD)" >> /var/log/autoreboot.log
    else
        echo "$NAME very health!(MEM:$PID_MEM_SUM,LOAD:$SYS_LOAD)" > /dev/null
    fi
done

更新(11.19.15):该脚本已更新至V2版本

http://wangyan.org/blog/sys-mon-shell-script.html

补充:

即便在[[]]结构中,同样不能直接比较浮点数大小,例如:

1
2
3
if [[ "2.0" >  "10" ]];then #结果输出yes显然错了。
echo "yes"
fi

参考资料:

1. http://www.hostloc.com/thread-38721-1-1.html

原文 : http://wangyan.org/blog/pid-auto-reboot-shell-html.html

===========

Ubuntu制作Debian软件包

在上一篇文章中我讲了,怎样在Ubuntu中编译MPlayer中文版。虽然也不算很麻烦,但总不至于每次重装系统后,都要编译一次吧?众所周知,Ubuntu是一个基于Debian包管理的系统,因此我们使用dpkg命令就可以轻松制作一个DEB包了。

下面将以Mplayer 为例子,讲一下Ubuntu制作Debian软件包具体过程。
注:这种方法说白了有点像RAR做的自解压文件,一般用于简单的打包。

一、制作前准备:

1
2
3
4
5
6
7
8
9
10
mkdir ~/mplayer  //建立工作目录
cd mplayer  //切换到工作目录
mkdir ~/mplayer/DEBIAN  //建立control文件存放目录
mkdir -p ~/mplayer/usr/local/mplayer //创建mplayer程序目录
(注意:"-p"绝对不能漏掉,因为,DEB包安装的时候默认是将文件释放到根目录)
mkdir ~/mplayer/usr/lib/  //创建用于存放解码包的目录
mkdir ~/mplayer/usr/bin/  //创建用于存放可执行文件的目录
mkdir ~/mplayer/usr/share/ 
mkdir ~/mplayer/usr/share/applications/  
mkdir ~/mplayer/usr/share/pixmaps/

二、复制安装文件:

1
cp -br /usr/local/mplayer/* ~/mplayer/usr/local/mplayer

特别注意:CP命令中的”-b”这个参数绝对不能少,为此我走了很多弯路。因为mplayer中的有很多“软链接”,具体内容以后再说。

三、复制解码包

1
2
cp -br /usr/lib/codecs  ~/mplayer/usr/lib/
cp -br /usr/lib/win32  ~/mplayer/usr/lib/

四、创建符号链接

1
2
3
4
5
6
cd ~/mplayer/usr
ln -s ../local/mplayer/bin/gmplayer ./bin/
ln -s ../local/mplayer/bin/mencoder ./bin/
ln -s ../local/mplayer/bin/mplayer ./bin/
ln -s ../../local/mplayer/share/applications/mplayer.desktop ./share/applications/
ln -s ../../local/mplayer/share/pixmaps/mplayer.xpm ./share/pixmaps/

五、创建一个control文件

1
gedit ~/mplayer/DEBIAN/control
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
Package: mplayer
Version: 1.0rc2
Section: utils
Priority: optional
Architecture: i386
Essential: no
Depends:
Recommends:
Suggests:
Installed-Size: 22528
Maintainer: WangYan <WebMaster@WangYan.Name>
Conflicts: 
Replaces:
Bugs: mailto:WebMaster@WangYan.Me
Description: The Ultimate Movie Player For Linux.
 It plays most mpeg, avi and asf files, supported by many native and win32
 DLL codecs. You can watch VCD, DVD and even DivX movies too. The other
 big feature of mplayer is the wide range of supported output drivers. It
 works with X11, Xv, DGA, OpenGL, SVGAlib, fbdev, but you can use SDL (and
 this way all drivers of SDL) and some lowlevel card-specific drivers (for
 Matrox/3dfx/SiS) too! Most of them supports software or hardware scaling,
 so you can enjoy movies in fullscreen.
 .
 This version includes the Gtk GUI.

control里面的东西都是什么意思,慢慢去看吧。如果我在”Conflicts:”后面填了”w32codecs”,意思是说如果安 装”w32codecs”,那么你将无法安装这个mplayer了,因为会产生冲突。另外,从”Description:”下面一行起要空一格。

六、最后用 dpkg-deb -b 命令打包。

1
2
cd ~/mplayer/
dpkg -b . ~/mplayer_1.0rc2-1_i386.deb

方法二:用checkinstall打包

1
2
安装“checkinstall”
sudo apt-get install checkinstall

将上文的编译安装命令”sudo make install”改为”sudo checkinstall -D make install”

其中的checkinstall所在行的命令就是打包命令,执行后会进入checkinstall的设置。

照着提示走,很快,一个DEB包就奇迹般出现了……

备注:这是一篇旧文章归档,实际发布日期为:2009-08-15

原文 : http://wangyan.org/blog/ubuntu-dpkg-debian.html

  1. windarrow_
    2012年11月19日13:01

    博主,我租的一个windows 2003 vps是59人民币每月的,请问有更便宜的2003vps推荐吗?

    • iGFW
      2012年11月19日13:12

      没有关注过windows vps

  2. fish
    2012年11月10日13:25

    hi.
    博主的openvpn还能正常连接吗?我连接不了,显示“TLS Error: TLS key negotiation failed to occur within 60 seconds (check your network connectivity) ”,搜了一下,看到此文:http://openvpn.net/index.php/open-source/faq/79-client/253-tls-error-tls-key-negotiation-failed-to-occur-within-60-seconds-check-your-network-connectivity.html,难道是gfw干扰的原因?有什么解决办法?

    • iGFW
      2012年11月10日15:21

      是的,GFW干扰了OpenVPN基本上所有的UDP端口和部分tcp端口,你可以尝试tcp方式连接,如果不支持tcp就没法了

      • fish
        2012年11月10日19:20

        hi.
        不是所有的 openvpn都支持tcp连接的吗?我试了改为tcp协议,还是连不上。

        • iGFW
          2012年11月10日19:37

          不是的,
          至于是否支持tcp连接及支持的tcp端口请咨询你所使用的openvpn的客服

          • fish
            2012年11月10日20:20

            hi.
            我的vps上的openvpn支持tcp(估计自建的openvpn都支持tcp连接),我把openvpn.conf中的proto后的udp改为了tcp,port的值改为了1196,然后重启openvpn;客户端的配置文件中的proto的值和端口也做了相应的修改,这样即可连接上了,可惜只能在pc上连接成功,在安卓手机上还是不行

          • iGFW
            2012年11月10日20:36

            做相应修改理论上因该没问题啊