Python 大数据库备份阿里云RDS数据库分表导出压缩

版权声明:本文为博主原创文章,未经博主允许不得转载 https://blog.csdn.net/qq_24909089/article/details/83073077

思路:因为有的数据库比较大,整体压缩之后还是会有几个G内容,既不方便下载也不方便恢复,然后就想到了对独立的表分开进行备份。

1.连接阿里云rds

2.创建文件夹,层级关系(服务器绝对路径->数据库名->日期->表名压缩包)

3.循环需要备份的数据库

4.从相应的数据库查找全部的表名,循环全部的表备份并忽略没有价值的表,直接压缩成.sql.gz文件

5.删除备份时间比较早的文件已节省服务器空间

6.挂载自动命令在每天的业务量最低的时候执行最佳 (凌晨2-4点间)

无法使用pymysql模块时需要安装pymysql 方法: https://blog.csdn.net/qq_24909089/article/details/83069085

代码示例如下:

#!/usr/bin/env python3
# -*- coding: utf-8 -*-
# @Author:
# @Date  : 2018/10/16
# !/usr/bin env python3

# 你需要导入这个模块
import os
import time
import datetime
import pymysql
import shutil

"""
配置信息
"""
# 需要备份的数据库集合
db_name = ['admin', 'admin2']

# 忽略文件(苹果笔记本易产生)
ignore = ['.DS_Store']

# 忽略部分表(类似一些价值不大的日志)
ignore_tables = ['user_log', 'sms_log']

# 数据库链接配置
db_config = {
    'host': "127.0.0.1",
    'user': "root",
    'pwd': "123456",
}

# 脚本绝对路径存放地址
absolute_path = '/Users/xubin/Python'

# 保留天数
save_day = 5

# 当前日期
date_time = time.strftime('%Y-%m-%d', time.localtime(time.time()))

"""
方法体
"""


def create_file(path):
    """
    创建文件夹函数
    :param path:创建文件路径
    :return:
    """
    # 去除首位空格
    path = path.strip()
    # 去除尾部 \ 符号
    path = path.rstrip("\\")

    # 判断路径是否存在
    if not os.path.exists(path):
        # 如果不存在则创建目录
        os.makedirs(path)
        return True
    else:
        # 如果目录存在则不创建
        return False


def export_backup(db_name, db_table_name, address):
    """
    导出数据库备份函数
    :param db_name: 数据库名称
    :param db_table_name: 表名称
    :param address: 导出数据库路径
    :return:
    """
    # ()中的参数 "调用mysqldump -h地址 -u用户名 -p密码 需要备份的数据库名 表名 >  生成的sql压缩文件名"
    os.system("mysqldump -h%s -u%s -p%s %s %s |gzip > %s" % (
        db_config['host'], db_config['user'], db_config['pwd'], db_name, db_table_name, address))


def access_table(db_name):
    """
    查询数据库全部的表信息
    :param db_name: 数据库名称
    :return:
    """
    db = pymysql.connect(db_config['host'], db_config['user'], db_config['pwd'], db_name)
    cursor = db.cursor()
    cursor.execute("show tables")
    table_list = [tuple[0] for tuple in cursor.fetchall()]
    db.close()
    return table_list


def delete_zip(day, folder):
    """
    删除文件函数
    :param day: 保留天数(多少天以内)
    :param folder: 指定需要检索删除的文件夹
    :return:
    """
    # 列出文件夹下所有的目录与文件
    list = os.listdir(folder)

    for i in range(0, len(list)):
        path = os.path.join(folder, list[i])
        files = os.path.basename(path)

        if files not in ignore:

            # 多少天之前时间
            now = datetime.datetime.now()
            delta = datetime.timedelta(days=day)
            n_days = now - delta
            before_time = n_days.strftime('%Y-%m-%d')

            # 比较大小
            time1 = datetime.datetime.strptime(files, "%Y-%m-%d")
            time2 = datetime.datetime.strptime(before_time, "%Y-%m-%d")

            if time1 < time2:
                shutil.rmtree(path)
                print('删除%s天之前的备份%s' % (day, path))


"""
调用
"""

# 导出数据库备份
for i in range(len(db_name)):

    # 文件夹地址
    mkpath = "%s/%s/%s\\" % (absolute_path, db_name[i], date_time)

    # 要删除的文件夹地址
    delete_url = "%s/%s" % (absolute_path, db_name[i])

    # 创建文件夹
    create_file(mkpath)
    print("创建文件夹:%s" % mkpath)

    # 获取全部表名
    all_table = access_table(db_name[i])

    print("--备份开始:%s--" % db_name[i])

    # 循环备份数据库表信息
    for z in range(len(all_table)):

        # 过滤忽略的表
        if all_table[z] not in ignore_tables:
            # 备份文件地址
            address = "%s/%s/%s/%s.sql.gz" % (absolute_path, db_name[i], date_time, all_table[z])

            # 备份数据库
            export_backup(db_name[i], all_table[z], address)
            print("[%s]" % all_table[z])

    else:
        print("--备份已完成:%s--" % mkpath)

    # 删除保留天数之外的文档
    delete_zip(save_day, delete_url)
    print("删除保留天数之外文件已完成:%s" % db_name[i])

else:
    print("已完成%s" % date_time)

压缩效果:

挂载自动命令:

# crontab -l

#测试定时py脚本
0 2 * * * python /Users/xubin/Python/dbsql_ce.py >> /Users/xubin/Python/1234.txt

常见问题:

手动执行没问题,挂载crontab自动脚本报错 (sh: mysqldump: command not found)

解决问题:

mysqldump实际的位置在/alidata/server/mysql/bin,而crontab只会去/usr/bin寻找。

方法一: 建立软连接:ln -fs /alidata/server/mysql/bin/mysqldump /usr/bin

方法二:使用mysqldump时,使用完整路径:os.system("/alidata/server/mysql/bin/mysqldump -h127.0.0.1 -uroot -ppasswd testdata > testdata.sql")

感谢: https://www.cnblogs.com/shizouwei/p/7600067.html

猜你喜欢

转载自blog.csdn.net/qq_24909089/article/details/83073077