随笔 - 279  文章 - 1 评论 - 10 阅读 - 94万
< 2025年3月 >
23 24 25 26 27 28 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 1 2 3 4 5

前言: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

 

posted on   浮沉一梦  阅读(544)  评论(0编辑  收藏  举报
编辑推荐:
· 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 重磅开源!
· 周边上新:园子的第一款马克杯温暖上架
点击右上角即可分享
微信分享提示