返回顶部

mydumper备份代码

[复制链接]
骑单车的小女孩Lv.2 显示全部楼层 发表于 2016-12-30 00:32:13 |阅读模式 打印 上一主题 下一主题

马上注册,结交更多好友,享用更多功能,让你轻松玩转社区。

您需要 登录 才可以下载或查看,没有帐号?立即注册

x
来源:http://www.open-open.com/code/view/1443669081080
  1.    #!/usr/bin/phthon  
  2.       
  3.       
  4.     import os  
  5.     import time  
  6.     import commands  
  7.     import shutil  
  8.     import threading  
  9.     from os.path import join, getsize  
  10.     import MySQLdb as mydb  
  11.       
  12.       
  13.     # 备份目录  
  14.     baseDir = "/data2/backup/backup_data/"  
  15.       
  16.       
  17.     # ns 或 wx;  备份后是否要压缩(mydumper 自带压缩功能),要压缩 True,否则 False.  
  18.     idc = 'ns'; isZip = True  
  19.       
  20.       
  21.     # 备份失败是否重试 ,True 则重试,不重试 设 False, retry_sleep 多久后才开始重试(秒)  
  22.     is_errRetryBackup = True; retry_sleep = 300  
  23.       
  24.       
  25.     # 备份日期  
  26.     backup_date = time.strftime("%Y%m%d")  
  27.       
  28.       
  29.     # 备份命令  
  30.     cmd  = "/usr/local/bin/mydumper -h %s -u root -p password? -P %s %s -t 5 -o %s"  
  31.       
  32.       
  33.     '''''
  34.     功能描述:
  35.       1. mydumper 远程批量备份, 备份列表由配置文件提供
  36.       2. 可按要求对备份是否压缩(mydumper 自动压缩)
  37.       3. 备份失败允许再尝试备份一次
  38.       4. 备份信息写入数据库
  39.     '''  
  40.     def main():  
  41.         thread_pool = []  
  42.       
  43.       
  44.         # 是否启用压缩  
  45.         zip = '-c' if isZip == True else ''  
  46.       
  47.       
  48.         # 从配置文件读取 ip, 名称, 端口, 并拼凑备份语句  
  49.         #f = open('/data2/backup/cnf/other_list.cnf', 'r')  
  50.         f = open('/data/other_list.cnf', 'r')  
  51.         for lines in f.readlines():  
  52.             if (not lines.startswith('#') and len(lines.strip()) > 0):  
  53.                 str = lines.split()  
  54.                 host, businessName, port, isMaster = str[0], str[1], str[2], str[3]  
  55.                 # 业务文件夹不存在则创建  
  56.                 dir = baseDir + '/' + businessName;  
  57.                 if (not os.path.exists(dir)):  
  58.                      os.makedirs(dir)  
  59.       
  60.       
  61.                 dir += "/%s%s" % (businessName, backup_date)  
  62.                 # 业务目录: dir , 备份目录: dir/name+备份日期  
  63.                 strcmd  = cmd % (host, port, zip, dir)  
  64.       
  65.       
  66.                 th = threading.Thread(target = mydumper, args =(strcmd, dir, businessName, host, port, is_errRetryBackup, int(isMaster)))  
  67.                 thread_pool.append(th)  
  68.       
  69.       
  70.         if (thread_pool):  
  71.             for t in thread_pool:  
  72.                 t.daemon = True  
  73.                 t.start()  
  74.             for t in thread_pool:  
  75.                 t.join()  
  76.       
  77.       
  78.     def mydumper(sCmd, backupDir, businessName, host, port, is_Retry, isMaster):  
  79.         master_host = ""; backup_host = host; name = businessName; port = port; backup_type = 1; file = "";  
  80.         start_time = ""; stop_time = ""; returncode = 0; file_size = 0; slave_statement = ""; std_err = "";  
  81.       
  82.       
  83.         start_time = time.strftime("%Y%m%d%H%M%S")  
  84.       
  85.       
  86.         # 清除可能遗留的备份  
  87.         if (os.path.exists(backupDir)):  
  88.             shutil.rmtree(backupDir)  
  89.       
  90.       
  91.         # 执行备份  
  92.         returncode, std_err = execute(sCmd)  
  93.       
  94.       
  95.         stop_time = time.strftime("%Y%m%d%H%M%S")  
  96.       
  97.       
  98.         if (returncode == 0):  
  99.             # 备份 std_err 返回不为空也视为出错。  
  100.             if (std_err.strip() != ""):  
  101.                 returncode = 123456  
  102.             else:  
  103.                 # 获取 change master to 信息,再次校验备份是否有效  
  104.                 returncode, std_err, master_host, slave_statement = statement(backupDir, backup_host, isMaster)  
  105.       
  106.       
  107.                 if (returncode == 0):  
  108.                     file = backupDir  
  109.       
  110.       
  111.         if (returncode != 0):  
  112.             # 异常备份标记为: 日期 + _ERR  
  113.             errDir = backupDir + "_ERR"  
  114.             os.rename(backupDir, errDir)  
  115.             file = errDir  
  116.       
  117.       
  118.         # 获取备份大小  
  119.         file_size = getDirsize(file)  
  120.       
  121.       
  122.         if (len(std_err) > 255):  
  123.             std_err = std_err[:250] + "..."  
  124.       
  125.       
  126.         my_args  = [idc, master_host, backup_host, name, port, backup_type, file, start_time, stop_time, returncode, file_size, slave_statement, std_err]  
  127.       
  128.       
  129.         # 写入数据库  
  130.         call_proc(my_args)  
  131.       
  132.       
  133.         # 备份失败是否需要重备? 重备允许一次.  
  134.         if (is_Retry == True and returncode != 0):  
  135.             time.sleep(retry_sleep)  
  136.       
  137.       
  138.             oldfile = sCmd.split('-o')[1]  
  139.             pos = oldfile.rfind("/") + 1  
  140.       
  141.       
  142.             # 获取备份全路径, 备份文件标记为重备 字样  
  143.             retry_file = oldfile[:pos] + "ReBackup-" + oldfile[pos:]  
  144.       
  145.       
  146.             retryCmd = sCmd.replace(oldfile,  retry_file)  
  147.       
  148.       
  149.             # 重备开始  
  150.             mydumper(retryCmd, retry_file.strip(), name, host, port, False, isMaster)  
  151.       
  152.       
  153.     def getDirsize(path):  
  154.         # 获取备份文件夹大小  
  155.         size = 0L  
  156.         for root, dirs, files in os.walk(path):  
  157.             size += sum([getsize(join(root, name)) for name in files])  
  158.         return (size)  
  159.       
  160.       
  161.     def statement(path, backup_host, isMaster):  
  162.         '''''
  163.         功能: 从 metadata 读取change master to 信息
  164.         1. 备份过程: 会先生成: metadata.partial, 完成后metadata.partial会重名为: metadata 并写入备份完成时间
  165.         2. metadata 分3段:
  166.            (1) Started dump: 备份开始时间.
  167.            (2) master 的log-file 和 log-pos 信息 (必有); slave 的host、log-file 和 log-pos 信息 (备机是slave 才有)
  168.            (3) Finished dump: 备份结束时间
  169.         3. 返回错码, master_host 和 change master to 信息
  170.         '''  
  171.         path += "/metadata"; sMetadata = ""; master_host = ""; er_code = 654321; er_info = "%s not exists !!!" % (path)  
  172.       
  173.       
  174.         if (os.path.exists(path)):  
  175.             if (isMaster != 1):  
  176.                 # 备机是 slave  
  177.                 num = 3  
  178.                 sFinds = "SLAVE STATUS"  
  179.             else:  
  180.                 num = 2  
  181.                 sFinds = "MASTER STATUS"  
  182.       
  183.       
  184.             f = open(path, 'r')  
  185.             rows = f.readlines(); i = 100; lst =[]  
  186.             for s in rows:  
  187.                 if (s.find(sFinds) > 0):  
  188.                     i = 1; continue  
  189.       
  190.       
  191.                 if (i <= num):  
  192.                     lst.append(s.split(':')[1].strip())  
  193.                     i += 1  
  194.       
  195.       
  196.             if (isMaster == 1):  
  197.                 # 备机是 master  
  198.                 master_host = backup_host  
  199.                 log_file, log_pos = lst;  
  200.             else:  
  201.                 # 备机是 slave  
  202.                 master_host, log_file, log_pos = lst;  
  203.       
  204.       
  205.             er_code = 0  
  206.             er_info = ""  
  207.             sMetadata = "CHANGE MASTER TO MASTER_HOST='%s',MASTER_LOG_FILE='%s',MASTER_LOG_POS=%s,MASTER_USER='rep_user',MASTER_PASSWORD='meizu.com'" % (master_host, log_file, log_pos )  
  208.       
  209.       
  210.         return (er_code, er_info, master_host, sMetadata)  
  211.       
  212.       
  213.     def execute(cmd):  
  214.         '''''
  215.         1.执行 shell 命令
  216.         2.返回执行信息 (returncode = 0 则执行成功, std_err 为报错的错误信息)
  217.         '''  
  218.         try:  
  219.             returncode, std_err = commands.getstatusoutput(cmd)  
  220.             return (returncode, std_err)  
  221.         except os.error, e:  
  222.             # 异常返回 1001 错误  
  223.             return (1001, e)  
  224.       
  225.       
  226.     def call_proc(my_args):  
  227.         # 备份信息写入数据库  
  228.         try:  
  229.             conn = mydb.connect(host = '127.0.0.1', user = 'test', passwd = 'zxc/213?', db = 'meizu_item')  
  230.             cur  = conn.cursor()  
  231.       
  232.       
  233.             cur.callproc('sp_backup_i',[my_args[0], my_args[1], my_args[2], my_args[3], my_args[4], my_args[5], my_args[6], my_args[7], my_args[8], my_args[9], my_args[10], my_args[11], my_args[12]])  
  234.             conn.commit()  
  235.         except mydb.Error, e:  
  236.             pass  
  237.             # print "Mysql Error %d: %s" % (e.args[0], e.args[1])  
  238.         finally:  
  239.             cur.close(); conn.close()  
  240.       
  241.       
  242.     if __name__ == '__main__':  
  243.         main()  
复制代码

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

云萌主 云萌主-BIGSAAS旗下,由北京合智互联信息技术有限公司在2018年创立,为广大云应用技术爱好者的平台。在云萌主论坛可以查看云应用技术文章、云产品产品最新资讯、技术问答、技术视频。在畅游云上技术的同时,学到最新的云应用产品和技术。
  • 微信公众号

  • Powered by Discuz! X3.4 | Licensed | Copyright © 2001-2022, Aliyun Cloud. | 星点互联设计
  • 京ICP备18052714号 | 营业执照 | |合智互联| QQ