Python自动创建MySQL的从库脚本


本脚本主要用于创建mysql主从的从库,并且主库已经配置好相关的主从参数,主库上面有需要同步的数据库备份,在从库上执行此脚本,通过内网取得主库的配置文件、数据库备份、主库的权限库等用于从库的创建,自动获得需要同步主库的bin-log位置及pos点(本脚本的备份是晚上0点备份,此脚本已经在我公司多个游戏数据库上应用,还不错,大家可以看看!

  1. #!/usr/bin/env python  
  2. # -*- coding: utf-8 -*-  
  3. ##############################################################################  
  4. # @Author:       wangwei  
  5. # @E-mail:        wangwei03@gyyx.cn  
  6. # @Create Date:  2012-06-19  
  7. # @Version:      V1  
  8. #注意事项:1、主库已经按照要求修改配置文件打开了bin-log,设置了相关参数  
  9. #          2、从库已经安装和主库一样版本的mysql  
  10. #          3、运行之后删除/data1/目录下的压缩包  
  11. #          4、运行格式:python create_slave.py 根据提示输入主库的内网地址  
  12. #          5、在执行check_mysql时,会出现Broken pipe的错误,这个是由于python调用系统命令关闭和打开mysql时显示的信息没有正确的显示在终端造成的,没有影响,暂时没有找到不让显示此类信息的方法,亟待解决  
  13. ##############################################################################  
  14. import paramiko,os,sys,datetime,time,MySQLdb  
  15.  
  16. class Database:  
  17.  
  18.     def __init__(self,host):  
  19.         self.user='root' 
  20.         self.password='14314' 
  21.         self.port=10000 
  22.         self.today=datetime.date.today().strftime('%Y%m%d')  
  23.         self.bindir='/data1/mysql_log' 
  24.         self.host=host  
  25.         if not os.path.isdir(self.bindir):  
  26.             os.mkdir(self.bindir)  
  27.             os.popen("ln -s /data1/mysql_log /mysql_log")  
  28.         if not os.path.isdir('/data1/mysql_log/binlog'):   
  29.             os.mkdir('/data1/mysql_log/binlog')  
  30.         if not os.path.isdir('/data1/mysql_log/relaylog'):  
  31.             os.mkdir('/data1/mysql_log/relaylog')  
  32.         os.popen("chown -R mysql.mysql /data1/mysql_log/")  
  33.  
  34.     def check_mysql(self):#检查从库nysql数据库服务是否运行,如在运行则pkill掉,然后跳过权限表启动,为导入数据做准备  
  35.         print "\033[1;32;40m%s\033[0m" % "Check mysql now,Please wait...." 
  36.         if not os.path.isdir("/usr/local/mysql"):  
  37.             print "\033[1;31;40m%s\033[0m" % "    Mysql not install,Please install mysql !" 
  38.             sys.exit()  
  39.         if os.popen("netstat -ntlp|grep 3306|wc -l").read().strip() != '0':  
  40.             os.popen("pkill mysqld")  
  41.             time.sleep(5)  
  42.         conm = "/usr/local/mysql/bin/mysqld_safe --defaults-file=/usr/local/mysql/etc/innodb.cnf --datadir=/home/mysql/data --user=mysql --skip-grant-tables &" 
  43.         os.popen(conm)  
  44.         time.sleep(5)  
  45.         if os.popen("netstat -ntlp|grep 3306|wc -l").read().strip() == '0':  
  46.             print "\033[1;31;40m%s\033[0m" % "Mysql not Running,please start with '--skip-grant-tables' !" 
  47.             sys.exit()  
  48.  
  49.     def export_table(self):#导出当前主库的表结构和备份mysql权限库  
  50.         print "\033[1;32;40m%s\033[0m" % "Export master table and back mysql,Please wait ...." 
  51.         try:  
  52.             s=paramiko.SSHClient()  
  53.             s.set_missing_host_key_policy(paramiko.AutoAddPolicy())  
  54.             s.connect(self.host,self.port,self.user,self.password)  
  55.             conm = "/usr/local/mysql/bin/mysqldump --add-drop-table -udump -p1443214234 -d -B test adb ddb tdb|bzip2 -2 > /data/script/db_back/table_%s.bz2 && tar -zcvf /data/script/db_back/mysql.tgz /home/mysql/data/mysql && cp -f /usr/local/mysql/etc/innodb.cnf /data/script/db_back/ && echo $?" % self.today  
  56.             stdin,stdout,stderr=s.exec_command(conm)  
  57.             result = stdout.readlines()[-1].strip()  
  58.             s.close()  
  59.             if result == '0':  
  60.                 print "    Export_table success !" 
  61.             else:  
  62.                 print "\033[1;31;40m%s\033[0m" % "Export_table Error !" 
  63.                 sys.exit()  
  64.         except Exception,e:  
  65.             print "\033[1;31;40m%s\033[0m" % "SSH connect Error !" 
  66.             sys.exit()  
  67.  
  68.     def down_back(self):#拷贝主库当天的数据库备份和表结构  
  69.         local_dir='/data1/' 
  70.         remote_dir='/data/script/db_back/' 
  71.         try:  
  72.             t=paramiko.Transport((self.host,self.port))  
  73.             t.connect(username=self.user,password=self.password)  
  74.             sftp=paramiko.SFTPClient.from_transport(t)  
  75.             files=sftp.listdir(remote_dir)  
  76.             print "\033[1;32;40m%s\033[0m" % "Download back file,Please wait ...." 
  77.             print '    Beginning to download file  from %s  %s ' % (self.host,datetime.datetime.now())  
  78.             for f in files:  
  79.                 if f.find(self.today) != -1 or f == 'mysql.tgz' or f == 'innodb.cnf':  
  80.                     print '        Downloading file:',self.host + ':' + os.path.join(remote_dir,f)  
  81.                     sftp.get(os.path.join(remote_dir,f),os.path.join(local_dir,f))  
  82.                     #sftp.put(os.path.join(local_dir,f),os.path.join(remote_dir,f))  
  83.             t.close()  
  84.             print '    Download All back file success %s ' % datetime.datetime.now()  
  85.         except Exception,e:  
  86.             print "\033[1;31;40m%s\033[0m" % "SFTP connect Error !" 
  87.             sys.exit()  
  88.  
  89.     def unbz2(self):#解压拷贝的数据库备份和表结构bz2包  
  90.         print "\033[1;32;40m%s\033[0m" % "Decompression file,Please wait ...." 
  91.         print '    Beginning to Decompression file  from %s' % datetime.datetime.now()  
  92.         conm = 'bzip2 -dfk /data1/*%s*.bz2 && echo $?' % self.today  
  93.         bz = os.popen(conm).read().strip()  
  94.         if bz == '0':  
  95.             print '    Decompression file  success %s' % datetime.datetime.now()  
  96.         else:  
  97.             print "\033[1;31;40m%s\033[0m" % "Decompression Error !" 
  98.             sys.exit()  
  99.  
  100.     def restart_mysql(self):  
  101.         print "\033[1;32;40m%s\033[0m" % "Restart mysql Now,Please wait ...." 
  102.         os.popen("rm -rf /usr/local/mysql/etc/innodb.cnf && cp -f /data1/innodb.cnf /usr/local/mysql/etc/innodb.cnf")  
  103.         os.popen("sed -i 's/server-id       = 1/server-id       = 2/' /usr/local/mysql/etc/innodb.cnf")  
  104.         os.popen("/usr/local/mysql/bin/mysqladmin shutdown")  
  105.         os.popen("tar -zxvf /data1/mysql.tgz -C /")  
  106.         os.popen("rm -rf /home/mysql/data/*.info && rm -rf /home/mysql/data/ib_logfile*")  
  107.         os.popen("/usr/local/mysql/bin/mysqld_safe --defaults-file=/usr/local/mysql/etc/innodb.cnf --datadir=/home/mysql/data --user=mysql &")  
  108.         time.sleep(5)  
  109.         if os.popen("netstat -ntlp|grep 3306|wc -l").read().strip() == '0':  
  110.             print "\033[1;31;40m%s\033[0m" % "Mysql not Running,please start with '--skip-grant-tables' !" 
  111.             sys.exit()  
  112.  
  113.     def import_date(self):#导入表结构和备份数据库  
  114.         print "\033[1;32;40m%s\033[0m" % "Slave import master date,Please wait ...." 
  115.         #导入表结构  
  116.         dir = '/data1/' 
  117.         table = 'table_%s' % self.today  
  118.         conm = "/usr/local/mysql/bin/mysql  < %s%s && echo $?" % (dir,table)  
  119.         result = os.popen(conm).read().strip()  
  120.         if result == '0':  
  121.             print "    Import %s success !" % table  
  122.         else:  
  123.             print "\033[1;31;40m%s\033[0m" % "Import Table structure Error !" 
  124.             sys.exit()  
  125.  
  126.         for f in os.listdir(dir):#导入数据库  
  127.             if os.path.isfile(os.path.join(dir,f)) and (f.find('bz2') == -1and (f.find('table') == -1):  
  128.                 if f.find('adb') != -1:  
  129.                     conm = "/usr/local/mysql/bin/mysql adb < %s && echo $?" % os.path.join(dir,f)  
  130.                     result = os.popen(conm).read().strip()  
  131.                     if result == '0':  
  132.                         print "    Import %s success !" % f  
  133.                     else:  
  134.                         print "\033[1;31;40m%s\033[0m" % "Import Database adb Error !" 
  135.                         sys.exit()  
  136.                 elif f.find('tdb') != -1:  
  137.                     conm = "/usr/local/mysql/bin/mysql tdb < %s && echo $?" % os.path.join(dir,f)  
  138.                     result = os.popen(conm).read().strip()  
  139.                     if result == '0':  
  140.                         print "    Import %s success !" % f  
  141.                     else:  
  142.                         print "\033[1;31;40m%s\033[0m" % "Import Database tdb Error !" 
  143.                         sys.exit()  
  144.                 elif f.find('ddb') != -1:  
  145.                     conm = "/usr/local/mysql/bin/mysql ddb < %s && echo $?" % os.path.join(dir,f)  
  146.                     result = os.popen(conm).read().strip()  
  147.                     if result == '0':  
  148.                         print "    Import %s success !" % f  
  149.                     else:  
  150.                         print "\033[1;31;40m%s\033[0m" % "Import Database ddb Error !" 
  151.                         sys.exit()  
  152.  
  153.     def slave_start(self):#启动salve  
  154.         print "\033[1;32;40m%s\033[0m" % "Settings Slave,Please wait ...." 
  155.         binlog,log_pos=self.bin_pos()  
  156.         sql = "change master to master_host='%s',master_user='repl',master_password='12341324',master_port=3306,master_log_file='%s',master_log_pos=%s;" % (self.host,binlog,log_pos)  
  157.         try:  
  158.             conn = MySQLdb.connect(host = '127.0.0.1',user = 'repl_monitor',passwd = 'sdfsdgfg',connect_timeout=5)  
  159.             cursor = conn.cursor(cursorclass = MySQLdb.cursors.DictCursor)  
  160.             #cursor.execute("slave stop;")  
  161.             cursor.execute(sql)  
  162.             cursor.execute("slave start;")  
  163.             cursor.execute("show slave status;")  
  164.             alldata = cursor.fetchall()[0]  
  165.             for key in alldata:  
  166.                 print "%21s :" % key + '\t' + alldata[key]  
  167.             time.sleep(2)  
  168.             print 
  169.             print "******************************************" 
  170.             print 
  171.             cursor.execute("show slave status;")  
  172.             alldata = cursor.fetchall()[0]  
  173.             for key in alldata:  
  174.                 print "%21s :" % key + '\t' + alldata[key]  
  175.             cursor.close()  
  176.             conn.close()  
  177.         except MySQLdb.Error,e:  
  178.             print e  
  179.  
  180.     def bin_pos(self):#获取主库备份前的一个bin-log文件以及它的第一个pos位置  
  181.         today=datetime.date.today()  
  182.         yesterday = (today - datetime.timedelta(days=1)).strftime('%b %d')  
  183.         try:  
  184.             s=paramiko.SSHClient()  
  185.             s.set_missing_host_key_policy(paramiko.AutoAddPolicy())  
  186.             s.connect(self.host,self.port,self.user,self.password)  
  187.             conm = "ls -al /mysql_log/binlog|grep '%s'|tail -1|awk '{print $9}'" % yesterday  
  188.             stdin,stdout,stderr=s.exec_command(conm)  
  189.             binlog = stdout.read().strip()  
  190.             conm = "/usr/local/mysql/bin/mysqlbinlog /mysql_log/binlog/%s|grep log_pos|head -1|awk '{print $7}'" % binlog  
  191.             stdin,stdout,stderr=s.exec_command(conm)  
  192.             log_pos = stdout.read().strip()  
  193.             s.close()  
  194.             return binlog,log_pos  
  195.         except Exception,e:  
  196.             print "\033[1;31;40m%s\033[0m" % "SSH connect Error !" 
  197.             sys.exit()  
  198.  
  199. if __name__=="__main__":  
  200.     master_ip = raw_input('Enter :Mater_eth1_ip :')  
  201.     boss = Database(master_ip)  
  202.     boss.check_mysql()  
  203.     boss.export_table()  
  204.     boss.down_back()  
  205.     boss.unbz2()  
  206.     boss.import_date()  
  207.     boss.restart_mysql()  
  208.     boss.slave_start() 

相关内容