萌萌妈妈 发表于 2015-1-14 20:24:57

带来一篇Python下主动化办理Mysql数据库

如果您觉得本篇CentOSLinux教程讲得好,请记得点击右边漂浮的分享程序,把好文章分享给你的好朋友们!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=v

defget_mysqld_vars(self):
猎取现有设置文件信息
options=self.options(mysqld)
rst={}
foroinoptions:
rst=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
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:%progarg1arg2")
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:
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)
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

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)
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!=v:
printk,v,vars

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,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,sqlfile)
f,p=getBinlogPOS(sqlfile)
runMySQLdump(cmd)
changeMaster(cur,
host=kw,
port=kw,
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
serverid=args
mysqld_options={server-id:serverid}
ifdbtype==master:
mysqld_options=mysql-bin
elifdbtype==slave:
master_host=args
master_port=args
mysqld_options=master_host
mysqld_options=master_port
mysqld_options=REPLICATION_USER
mysqld_options=REPLICATION_PASS
mysqld_options=None
mysqld_options=mysql
mysqld_options=None
createInstance(instance_name,instance_port,dbtype=dbtype,**mysqld_options)
elifcommand==check:
diffVariables(instance_name)
elifcommand==adjust:
variable=args
value=args
setVariable(instance_name,variable,value)
elifcommand==backup:
backupMySQL(instance_name)
elifcommand==restore:
serverid==args
mhost=args
mport=args
sqlfile=args
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教程讲得好,请记得点击右边漂浮的分享程序,把好文章分享给你的好朋友们!

小妖女 发表于 2015-1-16 17:45:33

带来一篇Python下主动化办理Mysql数据库

我想即使Linux高手也很难快速准确精练的回答你。

兰色精灵 发表于 2015-1-19 18:23:22

一些显而易见的小错误还是用vi改正比较方便。以后的大一点的程序就得在Linux下调试了,因为有的头文件在VC里面说找不到。?

萌萌妈妈 发表于 2015-1-28 09:30:13

就这样,我们一边上OS理论课,一边上这个实验,这样挺互补的,老师讲课,一步一步地布置任务

活着的死人 发表于 2015-2-5 21:05:15

最好先搜寻一下论坛是否有您需要的文章。这样可以获得事半功倍的效果。

精灵巫婆 发表于 2015-2-13 15:40:50

对我们学习操作系统有很大的帮助,加深我们对OS的理解。?

再见西城 发表于 2015-3-3 23:46:36

Linux的成功就在于用最少的资源最短的时间实现了所有功能,这也是符合人类进化的,相信以后节能问题会日益突出。

灵魂腐蚀 发表于 2015-3-11 14:56:57

对Linux命令熟悉后,你可以开始搭建一个小的Linux网络,这是最好的实践方法。Linux是网络的代名词,Linux网络服务功能非常强大,不论是邮件服务器、Web服务器、DNS服务器等都非常完善。

谁可相欹 发表于 2015-3-19 03:14:17

熟悉系统的基本操作,Linux的图形界面直观,操作简便,多加上机练习就可熟悉操作,在Linux下学习办公软件等常用软件。

再现理想 发表于 2015-3-27 06:33:43

老实说,第一个程序是在C中编译好的,调试好了才在Linux下运行,感觉用vi比较麻烦,因为有错了不能调试,只是提示错误。
页: [1]
查看完整版本: 带来一篇Python下主动化办理Mysql数据库