前言:在日常服务器运维工作中,备份数据库是必不可少的,刚工作那会看到公司都是用shell脚本循环备份数据库,到现在自己学习python语言后,利用多进程多线程相关技术来实现并行备份数据库,充分利用服务器资源,提高备份速度。

一、为什么要用线程池

1.多线程比单线程运行要快很多,比如在我工作中,每台服务器至少8个库以上,用单线程备份太慢了。

2.不是越多线程就会越好,而是根据服务器的资源来合理定义worker线程,否则会造成服务器严重负载,影响到线上业务。

3.备份数据库都是消耗IO操作,用多线程比多进程稍微会更有优势。

从Python3.2开始,标准库为我们提供了 concurrent.futures 模块,它提供了 ThreadPoolExecutor (线程池)和ProcessPoolExecutor (进程池)两个类。
相比 threading 等模块,该模块通过 submit 返回的是一个 future 对象,它是一个未来可期的对象,通过它可以获悉线程的状态主线程(或进程)中可以获取某一个线程(进程)执行的状态或者某一个任务执行的状态及返回值:
主线程可以获取某一个线程(或者任务的)的状态,以及返回值。
当一个线程完成的时候,主线程能够立即知道。
让多线程和多进程的编码接口一致。
 
二、线程池练习
演示例子1:使用submit方法
from concurrent.futures import ThreadPoolExecutor
import time def test_thread(sec):
time.sleep(sec)
print(f"sleep {sec} done")
return sec with ThreadPoolExecutor(max_workers=4) as t: # 创建一个最大容纳数量为4的线程池
task1 = t.submit(test_thread, 1)
task2 = t.submit(test_thread, 2) # 通过submit提交执行的函数到线程池中
task3 = t.submit(test_thread, 3) print(f"task1: {task1.done()}") # 通过done来判断线程是否完成
print(f"task2: {task2.done()}")
print(f"task3: {task3.done()}") time.sleep(2.5)
print(f"task1: {task1.done()}")
print(f"task2: {task2.done()}")
print(f"task3: {task3.done()}")
print(task1.result()) # 通过result来获取返回值

结果输出:

task1: False
task2: False
task3: False
sleep 1 done
sleep 2 done
task1: True
task2: True
task3: False
1
sleep 3 done
使用 with 语句 ,通过 ThreadPoolExecutor 构造实例,同时传入 max_workers 参数来设置线程池中最多能同时运行的线程数目。
使用 submit 函数来提交线程需要执行的任务到线程池中,并返回该任务的句柄(类似于文件、画图),注意 submit() 不是阻塞的,而是立即返回。
通过使用 done() 方法判断该任务是否结束。上面的例子可以看出,提交任务后立即判断任务状态,显示3个任务都未完成。在延时2.5后,task1 和 task2 执行完毕,task3 仍在执行中。
 
演示例子2:使用map方法
import time
from concurrent.futures import ThreadPoolExecutor def spider(page):
time.sleep(page)
return page start = time.time()
executor = ThreadPoolExecutor(max_workers=4) i = 1
for result in executor.map(spider, [2, 3, 1, 4]):
print("task{}:{}".format(i, result))
i += 1

结果输出:

task1:2
task2:3
task3:1
task4:4
from concurrent.futures import ThreadPoolExecutor有两种方式,一种是submit()函数,另一种是map()函数,两者的主要区别在于:
1.map可以保证输出的顺序, submit输出的顺序是乱的
2.如果你要提交的任务的函数是一样的,就可以简化成map。但是假如提交的任务函数是不一样的,或者执行的过程之可能出现异常(使用map执行过程中发现问题会直接抛出错误)就要用到submit()
3.submit和map的参数是不同的,submit每次都需要提交一个目标函数和对应的参数,map只需要提交一次目标函数,目标函数的参数放在一个迭代器(列表,字典)里就可以。

三、线上数据库测试

环境:centos6,数据库版本5.7,数据备份2个1.7G、一个800M、一个200M

第一种:shell脚本for的方式备份4个数据库

#!/bin/bash
backup_path="/data/backup/"
myuser="root"
mypwd="123456"
db_name="test_1000"
current_time=$(date +%Y%m%d%H%M%S)
for i in $(seq 4);do
/usr/local/mysql/bin/mysqldump -u${myuser} -p${mypwd} --single-transaction --master-data=2 --set-gtid-purged=off "${db_name}${i}" | gzip > ${backup_path}/"${db_name}${i}"_${current_t
ime}.sql.gz
done

查看执行时间    

mysqldump: [Warning] Using a password on the command line interface can be insecure.
mysqldump: [Warning] Using a password on the command line interface can be insecure.
mysqldump: [Warning] Using a password on the command line interface can be insecure.
mysqldump: [Warning] Using a password on the command line interface can be insecure. real 4m28.421s
user 3m50.360s
sys 0m5.962s

第二种方式:多线程备份  

  

可以明显看到优势

总结:在服务器上有需要备份多个数据库时,使用python多线程的方式比传统的shell脚本循环备份会更有优势,可以充分利用服务器上的资源,有效提升效率。

  

详细参考:

  

  

  

 
 

python使用多线程备份数据库的更多相关文章

  1. Python 生产环境MySQL数据库增量备份脚本

    MySQL数据库常用的办法是通过MySQLdump导出sql进行备份,但是不适合数据量很大的数据库,速度,锁表是两个严重的问题.前面写了一遍文章介绍xtrabackup的热备工具,见 http://w ...

  2. MySQL数据库之多线程备份工具mydumper

    Mydumper介绍: 1)Mydumper是一个针对MySQL和Drizzle的高性能多线程备份和恢复工具 2)特性: 轻量级C语言编写 执行速度比mysqldump快10倍 快速的文件压缩 支持导 ...

  3. python 多线程操作数据库

    如果使用多线程操作数据库,容易引起多用户操作锁表 OperationalError: (2013, 'Lost connection to MySQL server during query') 使用 ...

  4. 实现定时备份mysql数据库并把备份数据库邮件发送

    一.先来看备份mysql数据库的命令 1 mysqldump -u root --password=root --database abcDataBase > c:/abc_backup.sql ...

  5. MySQL实验准备(二)--Python模拟数据(MySQL数据库)

    Python模拟数据(MySQL数据库) 数据模拟 目的:模拟多个表的插入和查询数据的模拟,再通过基准测试脚本测试服务器性能和收集数据,仿真模拟. 备注: 如果需要基础的python环境,可以查看&l ...

  6. MySQL多线程备份工具mydumper

    mydumper是一个针对MySQL和Drizzle的高性能多线程的备份和恢复工具.此工具的开发人员分别来自MySQL.Fackbook.SkySQL公司,目前已经有一些大型产品业务测试并使用了该工具 ...

  7. MySQL多线程备份工具:mydumper

    MySQL多线程备份工具:mydumper http://www.orczhou.com/index.php/2011/12/how-to-split-mysqldump-file/ Mydumper ...

  8. Linux(CentOS7)设置自动备份数据库到阿里云OSS

    环境:阿里云服务器CentOS7.4 + MySQL5.6 基本思路: 1.编写shell脚本,备份数据库到指定目录下 2.编写Python脚本,把文件上传到OSS 3.把shell脚本和Python ...

  9. mysql多线程备份与还原工具mydumper

    (一)mydumper介绍 之前我们已经学过如何使用mysqldump备份恢复数据库:<mysql逻辑备份与还原工具mysqldump>,就目前来说,mysqldump是使用最广泛的MyS ...

随机推荐

  1. pycharm pymysql连接mysql 报错 pymysql.err.InterfaceError: (0, '')

    pycharm  pymysql连接mysql  执行MySQL操作遇到以下报错信息: conn.query(q) File "C:\Software\Python37\lib\site-p ...

  2. 12.Quick QML-QML 布局(Row、Column、Grid、Flow和嵌套布局) 、Repeater对象

    1.Row布局 Row中的item可以不需要使用anchors布局,就能通过行的形式进行布局. 并且item可以使用Positioner附加属性来访问有关其在Row中的位置及其他信息. 示例如下所示, ...

  3. B - 抽屉 POJ - 2356 (容斥原理)

    The input contains N natural (i.e. positive integer) numbers ( N <= 10000 ). Each of that numbers ...

  4. 【golang】golang中结构体的初始化方法(new方法)

    准备工作: 定义结构体:Student import ( "fmt" "reflect") type Student struct { StudentId st ...

  5. 逆向工程第001篇:解锁FIFA07传奇模式

    FIFA07传奇难度的解锁,可以说是所有FIFA07玩家的终极目标.但是如果想以正常方式对其进行解锁,绝对是一件耗时耗力的工作.所以在这里我打算通过分析游戏存档文件的十六进制代码的方式,一步一步地找到 ...

  6. Linux中的防火墙(Netfilter、Iptables、Firewalld)

    目录 Netfilter Iptables iptables做本地端口转发 Firewalld Netfilter Netfilter是Linux 2.4内核引入的全新的包过滤引擎,位于Linux内核 ...

  7. 逆向 stdio.h 函数库 fseek 函数(调试版本)

    0x01 fseek 函数 函数原型:int fseek(FILE *stream, long int offset, int whence) 函数功能:设置流 stream 的文件位置为给定的偏移 ...

  8. PhpStorm 配置本地文件自动上传至服务器

    目的:本地文件夹下的文件实时同步至指定服务器的文件夹,减少代码移植的成本和风险 添加一个SFTP连接 Tools - Deployment - Browse Remote Host 配置连接参数 Co ...

  9. sql常识-RIGHT JOIN

    SQL RIGHT JOIN 关键字 RIGHT JOIN 关键字会右表 (table_name2) 那里返回所有的行,即使在左表 (table_name1) 中没有匹配的行. RIGHT JOIN ...

  10. 三、postman持久化及批量运行

    一.设置环境变量 环境变量的引用为{{变量名}},运行脚本之前切记要在右上角选择对应脚本设置的环境变量后点击保存 二.设置全局变量 三.脚本导入导出及分享 1.导入脚本 2.导出脚本 3.分享脚本 四 ...