Python2备份CentOS7的mysql数据库,并用ftp传输之备份

环境:
centos7最小化,python2.7.5。

功能实现:
第一,用Centos7自带python2.7.5备份mysql5.7
第二,实现备份失败进行自动发送邮件
第三,对打包后的tar.gz文件进行ftp传输至目的ftp服务器。
以下是我的Pycharm结构:
Python2备份CentOS7的mysql数据库,并用ftp传输之备份_第1张图片
main.py是主要实现功能就是备份数据库。
代码如下:

# -*- coding:UTF-8 -*-
import os
import time
import yaml
import sys
import subprocess
import myemail
import targz
import myFtp
reload(sys)
sys.setdefaultencoding('utf-8')


#   定义执行备份脚本,读取文件中的数据库名称,注意按行读写,不校验是否存在该库
def run_backup(user, dbname, todayDetail):
        dumpcmd = "mysqldump -u" + user + " --default-character-set=utf8 " + dbname + " > " + todayDetail + os.sep + dbname + ".sql"
        print '执行命令:' + dumpcmd
        # result = os.system(dumpcmd)
        result = subprocess.Popen(dumpcmd, shell=True, stdout=subprocess.PIPE, stderr=subprocess.PIPE)
        thisErrors = result.stderr.read()
        if thisErrors == '':
            print '备份成功:' + dbname
        else:
            print '失败:' + dbname
            print thisErrors
            # errors.append(dbname)
            errors = '数据库:' + dbname + '备份失败' + '\n' +'异常:' + thisErrors
            # 备份失败则直接发送邮件
            myemail.email(errors)


def mkdir(today, todayDetail, content, user, names, backpath):
    #   创建备份文件夹
    if not os.path.exists(todayDetail):
        os.makedirs(todayDetail)
        print "年月日文件夹:" + today
        print "具体时间文件夹:" + todayDetail
    #   备份数据库文件存在就执行备份和压缩,否则退出
    if content['db_name'] == None:
        print '无数据库!'
        pass
    else:
        if len(names) != 0:
            for name in names:
                dbname = name['name']
                print "开始备份数据库:" + (name['name'])
                run_backup(user, dbname, todayDetail)
        else:
            print "没有发现数据库..."
            pass
        # 进行清理文件夹
        filepath = targz.run_tar()
        # ftp 上传
        myFtp.upftp(filepath)


if __name__ == '__main__':
    #   配置文件是config.yaml 读取出来后得到的结果赋值给变量。
    filename = os.path.join(os.path.dirname(__file__), 'config.yaml').replace("\\", "/")
    f = open(filename)
    content = (yaml.load(f, Loader=yaml.FullLoader))['mysql']
    #   从yaml配置文件中提取:用户名、密码、数据库名称(多个库分行放置)和备份的路径
    host = content['db_host']
    user = content['db_user']
    password = content['db_password']
    names = content['db_name']
    backpath = content['db_backupPath']

    # 创建时间
    dateTime = time.strftime('%H-%M-%S')
    today = backpath + os.sep + time.strftime('%Y%m%d')
    todayDetail = today + os.sep + dateTime

    # 创建文件夹
    mkdir(today, todayDetail, content, user, names, backpath)

myemail.py模块:

# -*- coding:UTF-8 -*-
import sys
import os
import smtplib
from email.mime.text import MIMEText
import yaml
import time
import urllib2
import re
reload(sys)


def email(errors):
    # 邮件发送配置:
    filename = os.path.join(os.path.dirname(__file__), 'config.yaml').replace("\\", "/")
    f = open(filename)
    content = (yaml.load(f, Loader=yaml.FullLoader))['email']
    host = content['email_smtp']
    password = content['email_passwd']
    sender = content['email_sender']
    receivers = content['email_receivers']
    port = content['email_port']
    # 获取公网ip
    url = urllib2.urlopen("http://txt.go.sohu.com/ip/soip")
    text = url.read()
    ip = re.findall(r'\d+.\d+.\d+.\d+', text)[0]
    # print ip
    for receiver in receivers:
        receiver = receiver['name']
        subject = ip + '服务器--' + time.strftime('%Y%m%d-%H点%M分%S秒') + '数据库备份异常!'
        msg = MIMEText(errors)
        msg['Subject'] = subject
        msg['From'] = sender
        msg['To'] = receiver
        try:
            s = smtplib.SMTP(host, port)
            s.login(sender, password)
            s.sendmail(sender, receiver, msg.as_string())
            print '备份失败邮件已发送成功!'
        except smtplib.SMTPException as e:
            print errors + '发送失败' + format(e)

打包的targz.py

# -*- coding:UTF-8 -*-
import sys
import os
import time
import yaml
reload(sys)


#   执行压缩的函数
def run_tar():
    filename = os.path.join(os.path.dirname(__file__), 'config.yaml').replace("\\", "/")
    f = open(filename)
    content = (yaml.load(f, Loader=yaml.FullLoader))['mysql']
    # 备份路径
    backuppath = content['db_backupPath']
    compress_file = time.strftime('%Y%m%d') + ".tar.gz"
    compress_cmd = "tar -czvf " + compress_file + " " + time.strftime('%Y%m%d')
    # print compress_cmd
    # 切入需要打包的环境下然后进行打包
    os.chdir(backuppath)
    os.system(compress_cmd)
    print "打包%s完成!" % compress_file
    # print backuppath + compress_file
    #   删除备份文件夹
    # remove_cmd = "rm -rf " + backuppath + os.sep + time.strftime('%Y%m%d')
    # os.system(remove_cmd)
    # print "删除" + backuppath + os.sep + time.strftime('%Y%m%d') + "完成!"
    return str(backuppath + os.sep + compress_file)

ftp传输块:

# -*- coding:UTF-8 -*-
import sys
from ftplib import FTP
import time
import yaml
import os
reload(sys)


def upmakedir(ftp, path):
    count = 1
    try:
        res = ftp.mkd(path)
        print '建立的远程文件夹:' + res
        count += 1
    except Exception as e:
        print '报错:' + str(e)
        path = path + '-' + str(1)
        res = ftp.mkd(path)
        print '建立的远程文件夹:' + res
    return path


def upftp(localpath):
    filename = os.path.join(os.path.dirname(__file__), 'config.yaml').replace("\\", "/")
    f = open(filename)
    content = (yaml.load(f, Loader=yaml.FullLoader))['ftp']
    #   创建一个ftp的实例
    ftp = FTP(host=content['ftp_host'])
    #   打开调试级别2,显示详细信息
    ftp.set_debuglevel(2)
    #   连接ftp服务器,需要输入IP,端口,以及超时时间
    ftp.connect(host=content['ftp_host'], port=content['ftp_port'], timeout=600)
    #   连接的用户名、密码
    ftp.login(str(content['ftp_user']), str(content['ftp_password']))
    # 建立远程文件夹,以年月日命名, 如果已存在远程目录则将抛出异常并跳过继续上传。
    path = time.strftime('%Y%m%d')
    # 远程创建文件夹
    path = upmakedir(ftp, path)
    # 缓冲
    bufsize = 1024
    # ftp服务器上该文件的名字,并放在当天目录下
    remotepath = path + os.sep + localpath.split('/')[-1]
    # print remotepath
    with open(localpath, 'rb') as fp:
        # 将这个文件上传
        ftp.storbinary('STOR ' + remotepath, fp, bufsize)
        ftp.set_debuglevel(0)
        ftp.quit()

配置文件:config.yaml

# mysql数据库配置:
mysql :
  # 数据库ip
  db_host : localhost
  # 数据库账号
  db_user : root
  # 数据库密码
  db_password : 123456
  # mysqldump 备份数据目录
  db_backupPath : /backup/mysql
  # 需要备份的数据库
  db_name :
    - name : zuida
    - name : mysql
    - name : 51job

# 邮箱设置:
email :
    # 设置服务器
  email_smtp : smtp.163.com
    # 服务器端口
  email_port : 25
    # 口令
  email_passwd : 123456
    # 发送者
  email_sender : [email protected]
    # 接收者
  email_receivers :
    - name : [email protected]
  #  - name : [email protected]

# ftp配置项:
ftp :
  # 用户名
  ftp_user : admin
  # 密码
  ftp_password : 123456
  # ftp的ip
  ftp_host : 192.168.0.107
  # 端口
  ftp_port : 21

再讲讲我这中间遇到的问题吧:
第一就是这个mysql的全备:

mysqldump -uroot -p123456 --default-character-set=utf8 dbname > dbname.sql

1、由于有时候备份不知道为什么会备份失败,失败在于它不能完全备份,就是只有一条插入语句
2、由于有时候可能配置中把数据库名写错,会导致这个命令报错,所以经过大佬们的建议用的是subprocess库来实现。

errot = subprocess.Popen("python", stdin=subprocess.PIPE, stdout=subprocess.PIPE, stderr=subprocess.PIPE)
thisErrors = errot.stderr.read()

此处thisErrors返回就是报错,可以记录
第二个就是ftp备份,查阅了一些资料
你们可以参考这个:
https://www.cnblogs.com/gongxr/p/7529949.html

写的不是很详细,有些地方还是留了个坑,有什么疑问可以留言区讨论。

你可能感兴趣的:(shell)