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