|
马上注册,结交更多好友,享用更多功能,让你轻松玩转社区。
您需要 登录 才可以下载或查看,没有帐号?立即注册
x
如果您觉得本篇CentOSLinux教程讲得好,请记得点击右边漂浮的分享程序,把好文章分享给你的好朋友们![/code]MySQL数据库一款十分优异的开源数据库,良多人都在利用。我也不破例,数据库实例创立、数据库形态检测、数据库备份等,每天做侧重复、单调的事情。为了加重事情量,利用Python写了一个主动办理Mysql数据库的工具。
Mysql办理工具的次要功效:
>数据库实例创立
>数据库备份
>数据库设置检测
>数据库主从同步
>设置文件从头载进
2.工具代码布局:
library:将共用的功效封装成一个库。
mysqlmanager:myman.py剧本完成基础办理Mysql的功效。
3.工具代码展现
library/mysql.py:
#!/usr/local/bin/python2.7
#-*-coding:utf-8-*-
fromConfigParserimportConfigParser
importos
importMySQLdb
defgetMyVariables(cur):
查询数据库设置信息
cur.execute(showglobalvariables;)
data=cur.fetchall()
returndict(data)
classMySQLDConfig(ConfigParser):
将一切公用的功效封装成一个class
def__init__(self,config,**kw):
Python版本必需2.7以上,2.6版本没有allow_no_value属性
ConfigParser.__init__(self,allow_no_value=True)
self.config=config
self.mysqld_vars={}
ifos.path.exists(self.config):
self.read(self.config)
self.get_mysqld_vars()
else:
self.set_mysqld_defaults_var()
self.set_mysqld_vars(kw)
defset_mysqld_vars(self,kw):
猎取设置文件信息,掩盖默许设置
fork,vinkw.items():
self.mysqld_vars[k]=v
defget_mysqld_vars(self):
猎取现有设置文件信息
options=self.options(mysqld)
rst={}
foroinoptions:
rst[o]=self.get(mysqld,o)
self.set_mysqld_vars(rst)
defset_mysqld_defaults_var(self):
假如设置文件不存在,设置默许设置
defaults={
"user":"mysql",
"pid-file":"/var/run/mysqld/mysqld.pid",
"socket":"/var/lib/mysql/mysql.sock",
"port":"3306",
"basedir":"/usr",
"datadir":"/tmp/mysql",
"tmpdir":"/tmp",
"skip-external-locking":None,
"bind-address":"127.0.0.1",
"key_buffer":"16M",
"max_allowed_packet":"16M",
"thread_stack":"192K",
"thread_cache_size":"8",
"myisam-recover":"BACKUP",
"query_cache_limit":"1M",
"query_cache_size":"16M",
"log_error":"/var/log/mysqld.log",
"expire_logs_days":"10",
"max_binlog_size":"100M"
}
self.set_mysqld_vars(defaults)
defsave(self):
将设置信息保留至设置文件
ifnotself.has_section(mysqld):
self.add_section(mysqld)
fork,vinself.mysqld_vars.items():
self.set(mysqld,k,v)
withopen(self.config,w)asfd:
self.write(fd)
if__name__=="__main__":
mc=MySQLDConfig(/root/david/mysqlmanager/cnfs/my.cnf,max_connection=200,user=mysql)
mc.set_var(skip-slave-start,None)
mc.save()
library/utils.py
#!/usr/local/bin/python2.7
#-*-coding:utf-8-*-
格局工夫的转换,数据库设置文件的单元(*.cnf)和数据库global(mysql>showglobalvariables;)设置的单元纷歧致,必要转换
unit={t:2**40,g:2**30,m:2**20,k:2**10,b:1}
defconvertUnit(s):
s=s.lower()
lastchar=s[-1]
num=int(s[:-1])
iflastcharinunit:
returnnum*unit[lastchar]
else:
returnint(s)
defscaleUnit(d):
fork,vinunit.items():
num=d/v
if(0<num<2**10):
returnnum,k
mysqlmanager/myman.py:
5
#!/usr/local/bin/python2.7
#-*-coding:utf-8-*-
fromosimportpath
fromoptparseimportOptionParser
fromsubprocessimportPIPE,Popen
importMySQLdb
importglob
importos
importsys
importtime
importdatetime
importre
DIRNAME=path.dirname(__file__)
OPSTOOLS_DIR=path.abspath(path.join(DIRNAME,..))
sys.path.append(OPSTOOLS_DIR)
fromlibrary.mysqlimportMySQLDConfig,getMyVariables
REPLICATION_USER=repl
REPLICATION_PASS=123qwe
MYSQL_DATA_DIR=/home/david/data
MYSQL_CONF_DIR=/home/david/cnfs
MYSQL_BACK_DIR=/home/david/backup
defopts():
parser=OptionParser(usage="usage:%prog[options]arg1arg2")
parser.add_option("-c","--cmd",
dest="cmd",
action="store",
default="check",
help="Checktheconfigurationfileanddatabaseconfigurationparametersaredifferent.[%options]"
)
parser.add_option("-n","--name",
dest="name",
action="store",
default="mysqlinstance",
help="CreateExamples."
)
parser.add_option("-p","--port",
dest="port",
action="store",
default="3306",
help="Examplesofport."
)
returnparser.parse_args()
defcheckPort(d,p):
实例端口检测
formind:
ifp==m.mysqld_vars[port]:
returnTrue
returnFalse
defsetReplMaster(cur):
设置slave数据库同步用户的受权
sql="GRANTREPLICATIONSLAVEON*.*TO%s@localhostIDENTIFIEDBY%s"%(REPLICATION_USER,REPLICATION_PASS)
cur.execute(sql)
defconnMySQLd(mc):
毗连数据库
host=127.0.0.1
user=root
port=int(mc.mysqld_vars[port])
conn=MySQLdb.connect(host,port=port,user=user)
cur=conn.cursor()
returncur
defrun_mysql(cnf):
运转数据库
cmd="mysqld_safe--defaults-file=%s&"%cnf
p=Popen(cmd,stdout=PIPE,shell=True)
time.sleep(5)
returnp.returncode
defsetOwner(p,user):
设置目次权限
os.system("chown-R%s:%s%s"%(user,user,p))
defmysql_install_db(cnf):
数据库初始化
p=Popen("mysql_install_db--defaults-file=%s"%cnf,stdout=PIPE,shell=True)
#p=Popen("mysql_install_db--user=mysql--datadir=%s"%MYSQL_DATA_DIR,stdout=PIPE,shell=True)
stdout,stderr=p.communicate()
returnp.returncode
def_genDict(name,port):
设置文件存储目次及监听端口
return{
pid-file:path.join(MYSQL_DATA_DIR,name,"%s.pid"%name),
socket:/tmp/%s.sock%name,
port:port,
datadir:path.join(MYSQL_DATA_DIR,name)+/,
log_error:path.join(MYSQL_DATA_DIR,name)
}
defreadConfs():
读取设置文件,假如设置文件不存在,利用默许设置天生设置文件
confs=glob.glob(path.join(MYSQL_CONF_DIR,*.cnf))
return[MySQLDConfig(c)forcinconfs]
defgetCNF(name):
猎取设置文件完全路径
returnpath.join(MYSQL_CONF_DIR,"%s.cnf"%name)
defrunMySQLdump(cmd):
启动Mysql下令
p=Popen(cmd,stdout=PIPE,shell=True)
stdout,stderr=p.communicate()
returnp.returncode
defgetBinlogPOS(f):
猎取binlog
withopen(f)asfd:
f,p=findLogPos(l)
iffandp:
returnf,p
deffindLogPos(s):
rlog=re.compile(r"MASTER_LOG_FILE=(S+),",re.IGNORECASE)
rpos=re.compile(r"MASTER_LOG_POS=(d+),?",re.IGNORECASE)
log=rlog.search(s)
pos=rpos.search(s)
iflogandpos:
returnlog.group(1),int(pos.group(1))
else:
return(None,None)
defchangeMaster(cur,host,port,user,mpass,mf,p):
sql=CHANGEMASTERTO
MASTER_HOST=%s,
MASTER_PORT=%s,
MASTER_USER=%s,
MASTER_PASSWORD=%s,
MASTER_LOG_FILE=%s,
MASTER_LOG_POS=%s;%(host,port,user,mpass,mf,p)
cur.execute(sql)
defcreateInstance(name,port,dbtype="master",**kw):
创立数据库实例
cnf=path.join(MYSQL_CONF_DIR,"%s.cnf"%name)
datadir=path.join(MYSQL_DATA_DIR,name)
exists_cnfs=readConfs()
ifcheckPort(exists_cnfs,port):
print>>sys.stderr,"portexist."
sys.exit(-1)
ifnotpath.exists(cnf):
c=_genDict(name,port)
c.update(kw)
mc=MySQLDConfig(cnf,**c)
mc.save()
else:
mc=MySQLDConfig(cnf,**kw)
ifnotpath.exists(datadir):
mysql_install_db(cnf)
setOwner(datadir,mc.mysqld_vars[user])
run_mysql(cnf)
time.sleep(3)
cur=connMySQLd(mc)
setReplMaster(cur)
defdiffVariables(instance_name):
查询数据库设置文件和数据库设置的差别
cnf=getCNF(instance_name)
ifpath.exists(cnf):
mc=MySQLDConfig(cnf)
printmc
cur=connMySQLd(mc)
vars=getMyVariables(cur)
fork,vinmc.mysqld_vars.items():
k=k.replace(-,_)
ifkinvarsandvars[k]!=v:
printk,v,vars[k]
defsetVariable(instance_name,variable,value):
从头加载设置
cnf=getCNF(instance_name)
ifpath.exists(cnf):
mc=MySQLDConfig(cnf)
cur=connMySQLd(mc)
cur.execute(setglobal%s=%s%(variable,value))
mc.set_var(variable,value)
mc.save()
defbackupMySQL(instance_name):
备份数据库
cnf=getCNF(instance_name)
ifpath.exists(cnf):
mc=MySQLDConfig(cnf)
now=datetime.datetime.now()
timestamp=now.strftime(%Y-%m-%d-%H%M%S)
backup_file=path.join(MYSQL_BACK_DIR,instance_name,timestamp+.sql)
_dir=path.dirname(backup_file)
ifnotpath.exists(_dir):
os.makedirs(_dir)
cmd=mysqldump-A-x-F--master-data=1--host=127.0.0.1--user=root--port=%s>%s%(mc.mysqld_vars[port],backup_file)
runMySQLdump(cmd)
defrestoreMySQL(instance_name,instance_port,sqlfile,**kw):
createInstance(instance_name,instance_port,**kw)
cnf=getCNF(instance_name)
ifpath.exists(cnf):
mc=MySQLDConfig(cnf)
cur=connMySQLd(mc)
cmd="mysql-h127.0.0.1-P%s-uroot<%s"%(mc.mysqld_vars[port],sqlfile)
f,p=getBinlogPOS(sqlfile)
runMySQLdump(cmd)
changeMaster(cur,
host=kw[master-host],
port=kw[master-port],
user=REPLICATION_USER,
mpass=REPLICATION_PASS,
mf=f,
p=p)
def_init():
查询mysql几个目次是不是存在,假如不存在,主动创立
ifnotpath.exists(MYSQL_DATA_DIR):
os.makedirs(MYSQL_DATA_DIR)
ifnotpath.exists(MYSQL_CONF_DIR):
os.makedirs(MYSQL_CONF_DIR)
ifnotpath.exists(MYSQL_BACK_DIR):
os.makedirs(MYSQL_BACK_DIR)
defmain():
opt,args=opts()
instance_name=opt.name
instance_port=opt.port
command=opt.cmd
ifcommand=="create":
ifnotargs:
createInstance(instance_name,instance_port)
else:
dbtype=args[0]
serverid=args[1]
mysqld_options={server-id:serverid}
ifdbtype==master:
mysqld_options[log-bin]=mysql-bin
elifdbtype==slave:
master_host=args[2]
master_port=args[3]
mysqld_options[master-host]=master_host
mysqld_options[master-port]=master_port
mysqld_options[master-user]=REPLICATION_USER
mysqld_options[master-password]=REPLICATION_PASS
mysqld_options[skip-slave-start]=None
mysqld_options[replicate-ignore-db]=mysql
mysqld_options[read-only]=None
createInstance(instance_name,instance_port,dbtype=dbtype,**mysqld_options)
elifcommand==check:
diffVariables(instance_name)
elifcommand==adjust:
variable=args[0]
value=args[1]
setVariable(instance_name,variable,value)
elifcommand==backup:
backupMySQL(instance_name)
elifcommand==restore:
serverid==args[0]
mhost=args[1]
mport=args[2]
sqlfile=args[3]
mysqld_options={
"master-host":mhost,
"master-port":mport,
"server-id":serverid,
"skip-slave-start":None,
}
restoreMySQL(instance_name,instance_port,sqlfile,**mysqld_options)
if__name__=="__main__":
printmain()
4.测试
匡助信息:
创立master实例:
创立slave实例:
检测设置文件和数据库加载设置差别:
因为单元格局分歧,以是呈现了差别,能够分离library/utils.py举行单元换算
数据库备份:
必要注重:
1.python版本必需2.7及2.7以上版本。
2.MYSQL_DATA_DIR目次不克不及放在/root目次下,假如放在root目次下,初始化数据库的时分会报错(权限成绩)。我在这犯不对.
如果您觉得本篇CentOSLinux教程讲得好,请记得点击右边漂浮的分享程序,把好文章分享给你的好朋友们! |
|