数据库与网站全自动备份脚本_远程备份

远程备份 一般用于多个运行的网站自动备份到一台备份机
一般用crontab定时器运行
分为两部分
接收端(备份机) 接收上传 并处理
发送端(运行着的网站) 可以是多台 备份 压缩 上传

发送端代码

#!/bin/bash

#备份机接收上传的url 
uploadUrl="http://127.0.0.1/?key=abcdefg"

#备份所使用的目录 需提前创建
BCK_DIR="/www/mybak"

#备份数据库配置  这里最好用root 一次备份所有数据库
DB_USER="root"
DB_PASS="123456"
BIN_DIR="/www/server/mysql/bin"

#备份网站配置
#是否备份网站
IS_BAK_WEBSITE="1"
#需要备份的网站目录 
WEBSITE_DIR="/www/wwwroot"

#当前日期
dateDIR=`date +"%y-%m-%d"`

#创建一个data目录用于放备份的数据库
cd $BCK_DIR
mkdir -p data

for i in `$BIN_DIR/mysql -u$DB_USER -p$DB_PASS -e "show databases"  | grep -v "Database" | grep -v "information_schema" | grep -v "mysql" | grep -v "performance_schema" | grep -v "sys"`

do
  $BIN_DIR/mysqldump -u$DB_USER -p$DB_PASS $i > $BCK_DIR/data/${i}_${dateDIR}.sql
done

#备份网站
if [ "$IS_BAK_WEBSITE" = "1" ]; then
    cp -r $WEBSITE_DIR $BCK_DIR/website
fi

#压缩
cd $BCK_DIR; tar -czvf backup_${dateDIR}.tar.gz * --remove-files

#上传
cd $BCK_DIR; curl -F "file=@backup_${dateDIR}.tar.gz" -X POST "${uploadUrl}"

#删除文件
cd $BCK_DIR; rm -rf backup_${dateDIR}.tar.gz

接收端脚本 php的

<?php
//配置信息
//备份保存的目录 需提前创建
$backupDIr = "/www/wwwroot/bak";

//保存多少份备份 用于自动删除旧的备份
$backUpLimit = 2;

//连接key 只有key正确才能上传
$connectKey = 'abcdefg';

//设置本机最少保留多少磁盘空间 快满了就不保存了 单位是 G
$needRaminSpace = 5;

//判断磁盘空间
$freeSpaceG = floor(disk_free_space("/") / (1024 * 1024 * 1024));
if($freeSpaceG < $needRaminSpace){
    echo '磁盘空间不足,拒绝保存';die;
}

//获取对方IP  因为可能有多个站备份过来
//来获取对方IP 用于创建目录 或者 保存到对应目录 或者删除多余的文件
$remoteIp = $_SERVER['REMOTE_ADDR'];
//保存目录  加上IP
$backupDIr = $backupDIr . '/' . $remoteIp;

//判断key
if( !is_array($_GET) ||  count($_GET) == 0 || !isset($_GET["key"]) || $_GET["key"] != $connectKey){
    echo 'keyError';die;
} 

//来接收文件上传 这里仅允许 .gz后缀的文件 为了安全
if( (!isset($_FILES['file'])) || (substr($_FILES["file"]["name"], -3) != '.gz') || ($_FILES["file"]["error"] > 0) ){
    echo 'fileError';die;
}

//判断目录是否存在
if ( !is_dir($backupDIr) ) {
    mkdir($backupDIr);
}

//定义文件存放位置  加个时间戳吧 下面再删除文件时候  用这个时间戳判断新旧
$saveFileName = $backupDIr . '/' . $_FILES["file"]["name"]  . '_' . time();

//转存
move_uploaded_file($_FILES["file"]["tmp_name"], $saveFileName);

//最后再来根据文件的新旧 只保留指定的文件个数
//获取某目录下所有文件、目录名(不包括子目录下文件、目录名)  
$handler = opendir($backupDIr);  
while ( ( $filename = readdir($handler) ) !== false ) {
    // 务必使用!==,防止目录下出现类似文件名“0”等情况  
    if ($filename !== "." && $filename !== "..") 
    {       
            //把文件名里前面保存的时间戳做为key  后面10位
            $timeStamp = substr($filename, -10);
            $files[$timeStamp] = $filename;
     } 
}  
closedir($handler);  

//$files 里保存着所有文件名 key就是那个时间戳 value就是文件名
//如果大于指定的文件个数 才做操作
if ( count($files) > $backUpLimit) {
    //需要删除文件的个数
    $needDeleteCount = count($files) - $backUpLimit;

    //把时间戳单独拿出来弄个数组  方便筛选
    $timeStampArr = array_keys($files);

    for ($i=0; $i < $needDeleteCount; $i++) { 
        //找出最小的
        $minTimeStamp = min($timeStampArr);

        //删除文件  这个时间当key
        unlink($backupDIr . '/' . $files[$minTimeStamp]);

        //再把保存时间的数组里当前元素删掉 进行下次循环
        $deleteKey = array_search($minTimeStamp, $timeStampArr);
        unset($timeStampArr[$deleteKey]);
    }
}

echo '备份机返回_ok';