思路:因为有的数据库比较大,整体压缩之后还是会有几个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