前言:DB2一个实例下,可以存在多个数据库,之前使用shell备份脚本,但是同一时刻只能备份一个数据库,对于几百G的备份文件,这个速度显然太慢,今天学习了Python多线程,刚好应用一下。
分析:1、Python多线程在某些场景上是鸡肋,但是这里使用多线程,目的是开启多个shell子进程。
2、磁盘I/O允许情况下,使用多个db2 backup进程。
3、thread模块有诸多问题,这里使用threading模块。
4、先前备份脚本修改端口来清理已连接应用,太过暴力,虽然都为冷备,但每次重启开销太大,这里使用db2 force application all。
5、如果第四步清理连接异常,那就无法进行备份,暂时未找到捕获异常的合适方式,待考虑,不过使用连续三次清理,不是特别情况,99.9%情况下是OK的。
6、可以不使用多线程,直接在使用subprocess开启多个子进程,这里是应用多线程,subprocess不在展示。
下面是具体代码:
MyThread.py
1 2 3 4 5 6 7 8 9 10 11 12 13 14 | #!/usr/bin/env python # encoding: utf-8 import threading class MyThread(threading.Thread): #Thread子类 def __init__( self ,func,args,name = ''): threading.Thread.__init__( self ) self .name = name self .func = func self .args = args def run( self ): self .func( * self .args) |
db2backup.py
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 | #!/usr/bin/env python # encoding: utf-8 import threading import logging import commands import sys import MyThread from time import ctime, sleep logging.basicConfig(level = logging.DEBUG, format = '%(asctime)s %(filename)s[line:%(lineno)-1d] %(levelname)s %(message)s' , datefmt = '%a, %d %b %Y %H:%M:%S' , filename = 'db2_backup.log' , filemode = 'a' ) # logging.debug('This is debug message') # logging.info('This is info message') # logging.warning('This is warning message') def db2_backup(inst_name, db_name, bak_dir): #实现db2 备份 #检查实例用户 whoami = commands.getstatusoutput( 'whoami' ) if whoami[ 1 ] ! = inst_name: #print '用户身份有误,当前实例 %s,配置文件实例 %s' %(whoami,inst_name) logging.error( '用户身份有误,当前实例 %s,配置文件实例 %s' % (whoami,inst_name)) sys.exit() #开始备份 cmd = 'db2 backup database %s to %s' % (db_name,bak_dir) exec_res = commands.getstatusoutput(cmd) if exec_res[ 0 ] = = 0 : #print "%s 备份成功." % db_name logging.info( '% %s 备份成功.' % (ctime(),db_name)) print exec_res[ 1 ] return exec_res def read_conf(file_path): #读取要备份的数据库配置 db_conf = [] with open (file_path, 'r' ) as f: for line in f: line_list = line.strip().split( ':' ) if len (line_list) ! = 3 : logging.warning( '%s 行配置不正确' % line.strip()) continue cur_line = (line_list[ 0 ],line_list[ 1 ],line_list[ 2 ]) db_conf.append(cur_line) return db_conf def main(): db_conf = read_conf( 'database.cfg' ) thread_num = len (db_conf) #实例化线程 threads = [] for line in db_conf: t = MyThread.MyThread(db2_backup,line,db2_backup.__name__) threads.append(t) #清除已建立连接 force_num = 3 while force_num: commands.getstatusoutput( 'db2 force application all' ) if force_num = = 3 : sleep( 1 ) force_num - = force_num #执行线程 for i in range (thread_num): threads[i].start() #等待线程同步,结束进程 for i in range (thread_num): threads[i].join() if __name__ = = '__main__' : main() |
要备份的数据库的配置信息:
database.cfg
实例名,数据库名,备份目录
1 2 | db2inst1:PTEST: / home / db2inst1 db2inst1:PTEST2: / home / db2inst1 |
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 10年+ .NET Coder 心语,封装的思维:从隐藏、稳定开始理解其本质意义
· .NET Core 中如何实现缓存的预热?
· 从 HTTP 原因短语缺失研究 HTTP/2 和 HTTP/3 的设计差异
· AI与.NET技术实操系列:向量存储与相似性搜索在 .NET 中的实现
· 基于Microsoft.Extensions.AI核心库实现RAG应用
· 10年+ .NET Coder 心语 ── 封装的思维:从隐藏、稳定开始理解其本质意义
· 地球OL攻略 —— 某应届生求职总结
· 提示词工程——AI应用必不可少的技术
· Open-Sora 2.0 重磅开源!
· 周边上新:园子的第一款马克杯温暖上架