mysql在线更改表可用工具 pt-online-schema-change 更改,或者用gh-ost更改。pt-online-schema-change 在原表创建索引,跟踪新插入的数据。gh-ost则根据日志应用到更改后的表。
下面把pt-online-schema-change封装为脚本化
#!/usr/bin/python #coding:utf8# 使用方法 例如 python mysql_osc.py -s 192.168.x.x -p 3306 -d test -t test -a 'add column `name16` varchar(200)' import sys import os import commands import argparse
##自定义mysql链接类 from mysqlmodel import mysqlconn general_user = cf.get('mysqlinfo','user') general_passwd = cf.get('mysqlinfo','passwd') def osc(server_ip,server_port,dbname,tabname,ddlstmt): try: conn=mysqlconn(server_ip,server_port) sql1="SELECT COUNT(1) as dbcount FROM information_schema.tables WHERE TABLE_SCHEMA not in ('mysql','performance_schema','information_schema','sys','test') and TABLE_SCHEMA='%s' and TABLE_NAME='%s';" % (dbname,tabname) sql2="select COUNT(1) as inxcount from information_schema.STATISTICS where TABLE_SCHEMA='%s' and TABLE_NAME='%s' AND NON_UNIQUE=0 ;" % (dbname,tabname) sql3="show slave status" check_table=conn.myquery(sql1) check_index=conn.myquery(sql2) check_slave=conn.myquery(sql3) if len(check_slave)!=0: print "%s:%s 不是主节点,更改失败" % (server_ip,server_port) sys.exit() if check_table[0]["dbcount"]!=1: print "表名 %s.%s 不存在" % (dbname,tabname) sys.exit() if check_index[0]["inxcount"]<1: print "表名 %s.%s 不存在唯一索引" % (dbname,tabname) sys.exit() except Exception as error: print "error: %s " % (error) print "mysql 链接错误" sys.exit() try: cmd = """/usr/local/toolkit/bin/pt-online-schema-change p='%s',u=%s,A=utf8mb4,h='%s',P=%s,D=%s,t=%s --alter='%s' --execute """ % (general_passwd,general_user,server_ip,server_port,dbname,tabname,ddlstmt) #print cmd status=commands.getstatusoutput(cmd) mystatus=status[1] if status[1].find("Successfully altered")>0 and status[0]==0: mystatus="Successfully altered" return mystatus except Exception as error: print "error: %s " % (error) return "执行失败" if __name__ == '__main__': #参数: parser = argparse.ArgumentParser(description='请输入 -s ip , -p 端口 ,-d 数据库名称,-t 表名, -a 更改语句') parser.add_argument('-s','--host', type=str,required=True,help="数据库地址") parser.add_argument('-p','--port', type=int,required=True,help="数据库端口") parser.add_argument('-d','--db', type=str,required=True,help="数据库名") parser.add_argument('-t','--table', type=str,required=True,help="表名") parser.add_argument('-a','--ddlstmt', type=str,required=True,help="更改语句") args = parser.parse_args() server_ip = args.host server_port = args.port dbname = args.db tabname = args.table ddlstmt = args.ddlstmt if server_ip=="" or server_port=="" or dbname=="" or tabname=="" or ddlstmt=="": print "输入完整信息" sys.exit() status=osc(server_ip,server_port,dbname,tabname,ddlstmt) print status