Python脚本每日自动备份MySQL数据库,无需mysqldump

编写一个Python脚本,每天凌晨3点开始备份

脚本具有以下特点

  • 不需要安装mysql-client,并且Windows Linux都可以使用
  • 支持多个数据库连接的备份
  • 每个数据库支持多个表备份
  • 日志保存下来,方便第二天早上查看备份结果

首先安装需要的库

pip3 install pymysql loguru

支持多个数据库

在这里插入图片描述

可选开始备份时间

在这里插入图片描述

备份速率调整

在这里插入图片描述
备份有大量数据传输,虽然是在夜间,也要控制速率,防止对服务端压力过大,1000条为limit的查询,可以控制下行带宽在5Mbps以下,不过上百万条数据的表,可能要备份很久。可以凌晨1点就开始备份,或者把1000条延时从0.2调到0.1或更短,或者调整每次查询的limit到5000。

开始备份时的控制台截图:

在这里插入图片描述

完整代码(需填入自己的数据库地址、端口、密码)

# author @xuehu96 2024-9-22
import os
import time
from datetime import datetime

import pymysql
from loguru import logger

# author @xuehu96 2024-9-22
def backup_database(host, port, user, password, databases):
    logger.info(f"Linking {host} ...")
    for db_name in databases:
        try:
            # 连接到数据库
            conn = pymysql.connect(host=host, port=port, user=user, password=password, database=db_name,
                                   charset='utf8mb4')
            cursor = conn.cursor()
            logger.info(f"Backuping {db_name} ...")

            # 创建备份文件夹
            backup_folder = f"./backups/{db_name}"
            if not os.path.exists(backup_folder):
                os.makedirs(backup_folder)

            # 获取当前日期
            current_date = datetime.now().strftime("%Y-%m-%d")

            # 备份数据库
            backup_file = f"{backup_folder}/{current_date}.sql"
            with open(backup_file, "w", encoding='utf-8') as f:
                # 获取所有表名
                cursor.execute("SHOW TABLES")
                tables = cursor.fetchall()
                for table in tables:
                    table_name = table[0]
                    logger.info(f"Backing table {table_name} ...")
                    # 导出表结构
                    cursor.execute(f"SHOW CREATE TABLE {table_name}")
                    create_table_sql = cursor.fetchone()[1]
                    f.write(f"{create_table_sql};\n\n")

                    # 导出表数据
                    limit = 1000  # 每次查询1000条记录
                    offset = 0
                    while True:
                        cursor.execute(f"SELECT * FROM {table_name} LIMIT {offset}, {limit}")
                        rows = cursor.fetchall()
                        if not rows:
                            break  # 当没有更多数据时退出循环
                        for row in rows:
                            placeholders = []
                            for value in row:
                                if value is None:
                                    placeholders.append('NULL')
                                elif isinstance(value, (int, float)):
                                    placeholders.append(f"{value}")
                                else:
                                    placeholders.append(f"'{value}'")

                            placeholders = ', '.join(placeholders)
                            query = f"INSERT INTO {table_name} VALUES ({placeholders});"
                            f.write(f"{query}\n")
                        f.write("\n")
                        offset += limit
                        time.sleep(0.2)  # 每处理一批数据后暂停0.2秒

                        logger.info(f"Backup table {table_name} successfully, inserted {len(rows)} rows.")

            # 关闭连接
            cursor.close()
            conn.close()

            logger.info(f"Backup of {db_name} completed successfully.")
        except Exception as e:
            logger.error(f"Backup of {db_name} failed: {e}")
        finally:
            time.sleep(1)

# author @xuehu96 2024-9-22
def main():
    logger.add("backup.log")

    while True:
        now = datetime.now()
        if now.hour == 3 and now.minute == 0:
            logger.info("Starting backup process.")

            # 第一个数据库连接信息
            host1 = "192.168.127.12" # 填写数据库IP或域名
            port1 = 2049
            user1 = "root"
            password1 = "XXXXXXXXXXXXXX"
            databases1 = ['DB1', 'DB2', 'test', 'test2', 'V5', 'V6', 'V7'] # 备份的数据库列表

            # 备份第一个数据库连接
            backup_database(host1, port1, user1, password1, databases1)

            # 第二个数据库连接信息
            host2 = "sh-XXXX.com"
            port2 = 2599
            user2 = "root"
            password2 = "XXXXXXXXXXXXXX"
            databases2 = ['ERP', 'DEVICE', 'GATEWAY']

            # 备份第二个数据库连接
            backup_database(host2, port2, user2, password2, databases2)

            logger.info("Backup process completed.")
            break

        time.sleep(60)

if __name__ == "__main__":
    main()
    
# author @xuehu96 2024-9-22

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/881615.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

Mybatis Plus分页查询返回total为0问题

Mybatis Plus分页查询返回total为0问题 一日&#xff0c;乌云密布&#xff0c;本人看着mybatis plus的官方文档&#xff0c;随手写了个分页查询&#xff0c;如下 Page<Question> questionPage questionService.page(new Page<>(current, size),questionService.g…

[C语言]连子棋游戏

文章目录 一、前言二、游戏思路三、游戏方法1、初始化2、判断胜利3、交互4、电脑下棋 四、核心方法说明1、初始化游戏2、销毁棋盘3、显示游戏4、电脑下棋5、用户下棋6、判断游戏状态7、游戏交互 五、游戏效果展示与源码分享1、游戏效果2、源代码 一、前言 对于指针和数组理解尚…

DataGrip在Windows和MacOS平台上的快捷键

0. 背景信息 No.说明1测试DataGrip版本号 : 2024.2.2 1. Windows下快捷键 2. MacOS下快捷键

基于波特图的控制系统设计算法

波特图&#xff08;Bode Plot&#xff09;是一种用于描述线性控制系统频率响应的图形表示方法&#xff0c;通常用于分析和设计控制系统。它以控制系统的传递函数&#xff08;或频域传递函数&#xff09;为基础&#xff0c;将系统的幅频特性&#xff08;振幅-频率响应&#xff0…

PyCharm与Anaconda超详细安装配置教程

1、安装Anaconda&#xff08;过程&#xff09;-CSDN博客 2.创建虚拟环境conda create -n pytorch20 python3.9并输入conda activate pytorch20进入 3.更改镜像源conda/pip(只添加三个pip源和conda源即可) 4.安装PyTorch&#xff08;CPU版&#xff09; 5.安装Pycharm并破解&…

LED灯、蜂鸣器、继电器的控制

LED灯的控制 该专栏所有文章都默认使用STM32F103ZET6开发板 目录 LED灯的控制 一、简单的LED灯控制 1、初始化函数 led灯 2、应用函数 2、蜂鸣器 3、继电器 一、简单的LED灯控制 编程框架&#xff1a;初始化函数和应用函数 1、初始化函数 初始化函数一般包括&#xf…

SVTR文字识别

论文地址&#xff1a;https://arxiv.org/abs/2205.00159 notes&#xff1a; 论文2.5中说的N nodes&#xff0c;就是输出的类别数量&#xff0c;英文37&#xff0c;中文6625&#xff0c;英文37说的是最简单的英文文字识别任务&#xff0c;不区分大小写&#xff0c;就是26个字母…

软件测试 BUG 篇

目录 一、软件测试的生命周期 二、BUG 1. bug的概念 2. 描述bug的要素 3. bug的级别 4. bug的生命周期 5. 与开发产生争执怎么办&#xff1f;&#xff08;面试高频考题&#xff09; 5.1 先检查自身&#xff0c;是否bug描述不清楚 5.2 站在用户角度考虑并抛出问题 5.3 …

nginx架构篇(三)

文章目录 一、Nginx实现服务器端集群搭建1.1 Nginx与Tomcat部署1. 环境准备(Tomcat)2. 环境准备(Nginx) 1.2. Nginx实现动静分离1.2.1. 需求分析1.2.2. 动静实现步骤 1.3. Nginx实现Tomcat集群搭建1.4. Nginx高可用解决方案1.4.1. Keepalived1.4.2. VRRP介绍1.4.3. 环境搭建环境…

【已解决】SpringBoot3项目整合Druid依赖:Druid监控页面404报错

文章标题 问题描述原因分析解决方案参考资料 问题描述 最近&#xff0c;笔者在SpringBoot3项目中整合Druid连接池时&#xff0c;偶然翻到一条介绍Druid监控的短视频&#xff0c;兴致盎然之下尝试设置了一下Druid监控。 But&#xff0c;按照视频中提供的yml参数对照设置&#x…

【全网最全】2024华为杯数学建模C题高质量成品查看论文!【附带全套代码+数据】

题 目&#xff1a; ___基于数据驱动下磁性元件的磁芯损耗建模 完整版获取&#xff1a; 点击链接加入群聊【2024华为杯数学建模助攻资料】&#xff1a;http://qm.qq.com/cgi-bin/qm/qr?_wv1027&kxtS4vwn3gcv8oCYYyrqd0BvFc7tNfhV7&authKeyedQFZne%2BzvEfLEVg2v8FOm%…

山体滑坡检测系统源码分享

山体滑坡检测检测系统源码分享 [一条龙教学YOLOV8标注好的数据集一键训练_70全套改进创新点发刊_Web前端展示] 1.研究背景与意义 项目参考AAAI Association for the Advancement of Artificial Intelligence 项目来源AACV Association for the Advancement of Computer Vis…

使用vue创建项目

一、安装环境 二、创建vue框架&#xff08;创建文件夹&#xff0c;摁shift鼠标右键 打开&#xff09; 1、项目配置 2、新增目录 三、路径别名配置 输入/ ,VSCode会联想出src下的所有子目录和文件&#xff0c;统一文件路径访问时不容易出错 四、ElementPlus配置 1、组件分为…

华为全联接大会HC2024 观会感

9/19-21于上海&#xff0c;华为举办了他一年一届也是最重要的华为系展会-Huawei Connect 华为全联接大会&#xff0c;今天有幸赶在展会最后一天来参观一下 上午照常是keynote&#xff0c;由华为计算线总裁进行了今天的KN开场&#xff0c;介绍了华为在“算”方面的进展&#x…

web基础—dvwa靶场(九)Weak Session IDs

Weak Session IDs&#xff08;弱会话&#xff09; Weak Session IDs&#xff08;弱会话&#xff09;&#xff0c;用户访问服务器的时候&#xff0c;一般服务器都会分配一个身份证 session id 给用户&#xff0c;用于标识。用户拿到 session id 后就会保存到 cookies 上&#x…

某花顺爬虫逆向分析

目标网站&#xff1a; aHR0cHM6Ly9xLjEwanFrYS5jb20uY24v 一、抓包分析 携带了cookie&#xff0c;每次请求的cookie都不一样&#xff0c;且不携带cookie不能成功返回数据 hook Cookie代码 _cookie document.cookie Object.defineProperty(document, cookie, {get(){con…

camtasia2024绿色免费安装包win+mac下载含2024最新激活密钥

Hey, hey, hey&#xff01;亲爱的各位小伙伴&#xff0c;今天我要给大家带来的是Camtasia2024中文版本&#xff0c;这款软件简直是视频制作爱好者的福音啊&#xff01; camtasia2024绿色免费安装包winmac下载&#xff0c;点击链接即可保存。 先说说这个版本新加的功能吧&#…

[JavaEE] UDP协议

目录 再谈端口号 一、端口号的划分 二、UDP协议 三、UDP的特点 再谈端口号 一、端口号的划分 0-1023&#xff1a;知名端口号&#xff0c;端口号固定&#xff0c;其中包括HTTP&#xff0c;FTP&#xff0c;SSH等广为使用的应用层协议。 1024-65535&#xff1a;操作系统动态分…

微软AI核电计划

每周跟踪AI热点新闻动向和震撼发展 想要探索生成式人工智能的前沿进展吗&#xff1f;订阅我们的简报&#xff0c;深入解析最新的技术突破、实际应用案例和未来的趋势。与全球数同行一同&#xff0c;从行业内部的深度分析和实用指南中受益。不要错过这个机会&#xff0c;成为AI领…

AtCoder ABC370 A-D题解

比赛链接:ABC370 AT 上 400 分寄。 Problem A: Code #include <bits/stdc.h> using namespace std; int main(){int L,R;cin>>L>>R;if(LR)cout<<"Invalid"<<endl;else if(L1)cout<<"YES"<<endl;elsecout<…