
MysqL 是一个比较优秀的开源的数据库,很多公司都在使用。作为运维人员,经常做着一些重复性的工作,比如创建数据库实例,数据库备份等,完全都可以使用 python 编写一个工具来实现。
一、模块 ConfigParser 学习ConfigParser 模块可以解析类似 MysqL 配置文件 my.cnf 和 windows 下的 ini 配置文件。使用 ConfigParser 模块解析这类配置文件非常方便,而且可以增加、设置或删除配置文件的 section option 等,如果你使用 C 语言解析过配置文件,你就能明白 ConfigParser 模块的高效。
1. 使用前需要注意的ConfigParser 模块在 python 2.6 版本中不支持没有 value 的 option 解析,解决的方法有 2 种:
(a) 升级 python 2.6 到 python 2.7。
(b) 拷贝一个 python 2.7 标准库的 ConfigParser.py 文件到 2.6 的标准库覆盖原来的 ConfigParser.py 文件。
推荐使用第一种方式,直接,一劳永逸;不过第二种方式比较简单。我用的是 CentOS 6,默认 python2.6.6,我升级 python 版本为 2.7.10。
参考我的一篇博文:http://www.cnblogs.com/liwei0526vip/p/6219998.html
2. ConfigParser 基本使用导入模块并实例化
import ConfigParserconf = ConfigParser.ConfigParser(allow_no_value=True)读配置文件 read/readfp
In [3]: conf.read('/root/my.cnf')Out[3]: []# 返回配置文件列表,其实可以读取多个配置文件的列表,实际应用中没有意义,一般都只读取一个配置文件# readfp() 函数可以读取 open() 函数返回的文件句柄 fpsection 相关 *** 作
,MysqLdMysqLdumpMysqLmyisamchkMysqLhotcopy']判断是否有section [user]In [15]: conf.has_section()Out[15]: True
options 相关 *** 作
In [16]: conf.options(') 列出optionsIn [17]: conf.set(keyvalue') 添加options [key] 同样可以修改optionsIn [18]: conf.remove_option(') 删除optionsIn [23]: conf.has_option( 判断是否有[key]获取 get 值 value
In [24]: conf.get(port)Out[24]: 3306' 返回value字符串格式In [25]: conf.getint()Out[25]: 3306 返回value整数格式In [26]: conf.getfloat(xxxx') 返回value浮点数格式In [27]: conf.getboolean(') 返回value布尔型格式In [28]: conf.items()Out[28]: [(),(query_cache_size16Mserver-ID1')]写入配置文件
3. 高级功能项ConfigParser 模块中定义了3个类对配置文件进行 *** 作。分别是 RawConfigParser、ConfigParser、SafeConfigParser。RawCnfigParser 是最基础的INI文件读取类,ConfigParser、SafeConfigParser支持对%(value)s变量的解析
>>> 设定配置文件 test.conf
[test] url = http://%(host)s:%(port)s/Portal host = localhost port = 8080>>> 代码中使用ConfigParser解析:
>>> 终端输出内容:http://localhost:8080/Portallocalhost:8080SafeConfigParser 可以实现 ConfigParser 同样的功能。
二、生成 MysqL 配置文件模板
通过借助于 ConfigParser 模块,写了一个 MysqLDConfig 的工具类,使用这个类可以对 MysqL 配置文件进行一些列的 *** 作:生成模板、添加选项、修改选项等,非常方便,作为后续开发工具箱的一个重要工具库。代码 MysqL.py 如下:
:41 socket/var/lib/MysqL/MysqL.sock42 key_buffer_size256M43 max_allowed_packet1M44 table_open_cache25645 sort_buffer_size46 read_buffer_size47 read_rnd_buffer_size4M48 myisam_sort_buffer_size64M49 thread_cache_size850 51 thread_concurrency52 ': 53 }54 self.set_MysqLd_vars(defaults)55 56 特殊的接口 单独去设置/添加变量 比如skip-salve-start等不能通过变量传递的选项57 set_vars(self,v):58 self.MysqLd_vars[k] =59 60 将所有的选项保存到配置文件,包括:新添加和更新的61 save(self):62 if not self.has_section():63 self.add_section(64 self.MysqLd_vars.items():65 self.set(66 with open(self.config,1)">) as fd:67 self.write(fd)68 69 if __name__ == __main__70 mc = MysqLDConfig(/root/my1.cnf71 print mc.get('MysqLd','port')72 print mc.max_connections73 print mc.port74 print mc.socket75 76 mc.set_vars('skip-slave-start',None)77 mc.save()78 print mc.port三、创建 MysqL 实例
借助于上一章节编写的 MysqLDConfig 类,来创建 MysqL 实例,大概如下几个步骤:
生成配置文件安装初始化 MysqL 实例设置属主属组启动 MysqL 运行此时的代码结构:
├── library│ ├── __init__.py│ └── MysqL.py└── MysqLmanager └── myman.py2 directorIEs,3 files具体的主代码 myman.py 如下:
15 MysqL实例的配置文件目录 16 MysqL_CONF_DIR = /var/MysqLmanager/conf 17 18 设置选项参数 19 opt(): 20 parser = OptionParser() 21 parser.add_option( 22 -n--name 指定实例的name 23 dest = name 24 action = store 25 default = myinstance 26 ) 27 28 -p--port 指定端口 29 dest = 30 action = 31 default = 32 33 34 -c--command create check and so on... 35 dest = command 36 action = 37 default = check 38 39 options,args = parser.parse_args() 40 return options,args 41 42 初始化目录(如果不存在则创建) 43 _init(): 44 not os.path.exists(MysqL_data_dir): 45 os.makedirs(MysqL_data_dir) 46 os.path.exists(MysqL_CONF_DIR): 47 os.makedirs(MysqL_CONF_DIR) 48 49 使用glob模块读取配置文件,返回配置文件列表(绝对路径) 50 readConfs(): 51 glob 52 confs = glob.glob(MysqL_CONF_DIR + /*.cnf 53 confs 54 55 检查指定的配置文件中端口号是否与指定端口相同 56 checkPort(conf_file,port): 57 mc = MysqLDConfig(conf_file) 58 if mc.MysqLd_vars['] == port: 59 True 60 61 False 62 63 有些配置项的值由具体示例而定,将这些不定项设置为字典 64 _genDict(name,1)"> 65 66 pID-file': os.path.join(MysqL_data_dir,name,1)">%s.pID' % name),1)"> 67 /tmp/%s.sock name,1)"> 68 : port,1)"> 69 datadir: os.path.join(MysqL_data_dir,name),1)"> 70 log-error%s.log 71 } 72 73 通过配置文件名称->配置文件的绝对路径 74 getCNF(name): 75 cnf = os.path.join(MysqL_CONF_DIR,1)">%s.cnf name) 76 cnf 77 78 MysqL执行安装过程 79 MysqL_install(name): 80 cnf = getCNF(name) 81 cmd = MysqL_install_db --defaults-file=%s 82 p = Popen(shlex.split(cmd),stdout=PIPE,stderr=PIPE) 83 p.communicate() 84 p.returncode 85 86 为保险起见,设置MysqL实例数据目录的属主数组 87 setowner(datadir): 88 os.system(chown MysqL:MysqL %s -R datadir) 89 90 运行MysqL实例 91 MysqL_run(name): 92 cnf = 93 cmd = MysqLd_safe --defaults-file=%s & 94 p = Popen(cmd,stderr=PIPE,shell= 95 time.sleep(2) 96 97 98 创建MysqL实例主函数,由create子命令触发调用 99 createInstance(name,1)">100 exists_confs = readConfs()101 102 检查给定的端口号和名称是否已经使用103 for conf exists_confs:104 if conf.split(/')[-1][:-4] == name:105 print >> sys.stderr,1)">Instance: %s is exists name106 sys.exit(-1107 checkPort(conf,1)">108 Port: %s is exists port109 sys.exit(-1110 111 1. 生成配置文件112 cnf =113 os.path.exists(cnf):114 c =115 mc = MysqLDConfig(cnf,1)">c)116 mc.save()117 datadir = os.path.join(MysqL_data_dir,name)118 os.path.exists(datadir):119 2. 安装初始化MysqL实例120 MysqL_install(name)121 3. 设置属主属组122 setowner(datadir)123 4. 启动MysqL运行124 MysqL_run(name)125 126 127 128 _init()129 options,1)"> opt()130 instance_name = options.name131 instance_port = options.port132 instance_cmd = options.command133 if instance_cmd == create: 134 createInstance(instance_name,instance_port)>>>> 扩展:实现几个简单使用功能
启动 MysqL 实例关闭 MysqL 实例重启 MysqL 实例四、MysqLdb 模块的使用
1. 安装 MysqL-python
直接使用 yum 工具安装:
[root@MysqL ~]# yum install MysqL-python -y2. 设置库路径
使用 rpm -ql MysqL-python 命令可以查看到默认安装 MysqLdb 库路径是:/usr/lib64/python2.6/site-packages 。如果没有升级 python 版本,可以正常使用,直接 import 即可。但是我升级了 python 2.7.10 ,默认 python 2.7 不会去旧版本路径下找库的,因此无法使用。解决办法有几种:
设置环境变量 PYTHONPATH在 sys.path 追加路径拷贝 MysqLdb 库目录到 Python2.7 路径下添加 .pth 文件,添加路径我这里使用的方式是第 4 种:
[root@MysqL site-packages]# pwd/usr/local/python27/lib/python2.7/site-packages[root@MysqL site-packages]# cat python26sitepackages.pth # 添加 xxx.pth 文件,文件中设置第三方库路径/usr/lib64/python2.6/site-packages
# *.pth文件名称随意,文件后缀一定要是.pth3. 基本使用
) 获取游标句柄In [3]: cur = conn.cursor() 执行SQL语句In [4]: cur.execute(show databases;)Out[4]: 3L 获取sql执行结果In [5]: cur.fetchall()Out[5]: ((information_schema五、MysqL 配置文件检查(与内存)
MysqL 可以通过配置文件和数据库命令行方式去修改参数变量,经常会有这种情况,临时通过命令行手动修改了选项参数,比如最大连接数不够了,通过 set global max_connections=200 来临时设置了参数。但是下次重启 MysqL 又会从配置文件读取参数。现在可以通过开发的工具箱来读取配置文件和内存中的参数是否一致,如果不一致,考虑以内存中的值为准,写入配置文件。部分代码如下:
?????????????????????????????????22 diffMyVariables(name):23 cur = connMysqL(name)24 vars = getMyVariables(cur)25 cnf =26 mc =27 mc.MysqLd_vars.items():28 k = k.replace(-_29 if k in vars and v != vars[k]:30 print k,v,vars[k]31 32 33 34 options,1)">35 instance_name =36 instance_port =37 instance_cmd =39 createInstance(instance_name,instance_port)40 elif instance_cmd == 'check'41 diffMyVariables(instance_name)命令执行:python myman.py -n my01 -p 3306 -c check
六、MysqL 配置文件调整(同步)
通过 check 命令找到了配置文件和内存中参数的不同,然后就可以通过 adjust 命令来调整一下配置文件,保持配置文件和内存的同步。实现代码如下:
try20 k = args[0]21 except IndexError:22 print Usage: -c adjust max_connections 300. At least 1 arg.23 24 v = args[126 v = None27 setMyVariables(instance_name,v)七、数据库 MysqL 主从复制介绍
1. MysqL 主节点设置步骤
打开bin-log:log-bin = MysqL-bin设置server-ID:server-ID = 1创建主从账号:grant replication slave on *.* to 'slave'@'%' IDentifIEd by '123456';2. MysqL 从节点设置步骤
设置server-ID:server-ID = 2(写入配置文件)设置master-host:master-host = 192.168.0.8(写入配置文件)设置master-port:master-port = 3306(写入配置文件)设置master-user:master-user = slave(写入配置文件)设置master-password:master-pass = 123456(写入配置文件)注意:以上 master 开头的选项可以写入配置文件,但不建议写入配置文件,不安全。可以使用如下命令代替:
MysqL> change master to master_host = '192.168.0.8= 3306,master_user repl123456'3. 先后运行 Mster 和 Slave 实例
先运行 master,后运行 slave。在从节点上运行命令查看:show slave status\G;
4. 其它选项
skip-slave-start:从库节点 slave 运行时,不会直接启动 slave 的主从复制
replicate-ignore-db:忽略某个数据库的同步复制,比如 MysqL 库,忽略,常容易出错八、代码实现主库和从库创建
以下是继续使用 create 子命令来实现主从库的创建。
" % (REPliCATION_USER,REPliCATION_PASS) 7 cur = 9 10 代替配置文件,在slave上设置master相关信息11 changeMaster(name,host,port,user,password):12 sql = """change master to 13 master_host = '%s',1)">14 master_port = %s,1)">15 master_user = '%s',1)">16 master_password = '%s'17 """ % (host,password)18 19 cur =21 23 24 options,1)">25 instance_name =26 instance_port =27 instance_cmd =28 if instance_cmd == 'create' args:30 createInstance(instance_name,1)">31 32 dbtype =33 serverID = args[134 MysqL_options = {: serverID}35 if dbtype == 'master'36 MysqL_options[log-bin'] = MysqL-bin37 createInstance(instance_name,instance_port,1)">MysqL_options) 38 runsql(instance_name)39 elif dbtype == 'slave'40 5.5 版本以上不建议将master开头字段写入配置文件,其实低版本写入配置文件也是不妥当的41 MysqL_options['master-host'] = args[2]42 MysqL_options['master-port'] = args[3]43 MysqL_options['master-user'] = REPliCATION_USER44 MysqL_options['master-pass'] = REPliCATION_PASS45 MysqL_options[replicate-ignore-db' 设置忽略MysqL库46 MysqL_options[skip-slave-start'] = None 设置slave运行时不自动启动主从复制47 createInstance(instance_name,**MysqL_options) 按照从选项来创建实例48 host = args[2] 传入master的主机49 port = args[3] 传入master的端口50 user = REPliCATION_USER51 password = REPliCATION_PASS52 设置master信息 changeMaster(instance_name,password) 54 55 adjust57 58 k =59 60 61 62 v = args[163 64 v =65 setMyVariables(instance_name,courIEr'>创建主库:python myman.py -n master01 -p 3306 -c create master 1
创建从库:python myman.py -n slave01 -p 3307 -c create slave 2 192.168.0.8 3306九、备份 MysqL 数据库
数据库备份很重要,要制定好备份策略。部分代码如下:
执行命令:python myman.py -n master01 -c backup十、MysqL 备份的恢复还原
通过 backup 命令备份后得到 sql 文件,在另一个 MysqL 实例中可以直接导入备份文件。但是如果 master 节点又有数据写入,那么导入sql后的节点和原来节点的数据是不一致的,缺少了后续的写入数据。在 master 导出 sql 文件后,记录 bin-log 文件和 log 位置,那么在从节点导入 sql 文件后,再次根据 bin-log 和 pos 来和 master 进行再次同步,那么,master 和 slave 就保持数据的同步了。具体代码如下:
6 master_port = %s,1)"> 7 master_user = '%s',1)"> 8 master_password = '%s' 9 11 sql = 12 master_password = '%s',1)"> master_log_file = '%s',1)">17 master_log_pos = %s18 20 cur = 定义MysqL备份恢复主函数,参数需要指定备份的sql文件 24 def restoreMysqL(name,sqlfile,1)">25 创建从实例 传入选项参数26 createInstance(name,1)">kw)27 cnf =28 mc =29 port = mc.MysqLd_vars[ 执行导入sql的shell命令31 cmd = MysqL -h 127.0.0.1 -u root -P %s < %s32 p = Popen(cmd,1)">33 stdin,1)">34 35 定义内部正则过滤参数的功能函数,获取:master-log-file 和 master-log-pos37 findPos(s): re39 rlog = re.compile(rMASTER_LOG_file='(\S+)'40 rpos = re.compile(rMASTER_LOG_POS=(\d+)41 log = rlog.search(s)42 pos = rpos.search(s)43 if log and pos:44 return log.group(1),pos.group(145 46 (None,None)47 48 读sql文件,返回log、pos getPos(sqlfile):50 with open(sqlfile) as fd:51 for line fd:52 log,pos = findPos(line)53 54 log,pos56 :57 58 ... 省略了中间部分代码 ...59 ': MysqL备份命令60 backupMysqL(instance_name)restore': MysqL备份的恢复命令62 server_ID =63 master_host = args[164 master_port = args[265 sqlfile = args[366 MysqLd_options = {: server_ID}67 MysqLd_options['] =68 MysqLd_options[69 恢复固定sql内容(sql文件备份的内容)70 restoreMysqL(instance_name,1)">MysqLd_options)71 logfile,logpos = getPos(sqlfile)72 指定log和pos,来配置slave激活master的主从复制(实现增量备份的恢复)73 changeMaster(instance_name,master_host,master_port,REPliCATION_USER,REPliCATION_PASS,logpos)测试实验过程:
>>> python myman.py -n master01 -p 3306 -c create master 1
>>> create database db1; create database db2; create database db3;
>>> python myman.py -n master01 -p 3306 -c backup
>>> create database db4;
>>> python myman.py -n slave01 -p 3307 -c restore 2 192.168.0.8 3306 /var/MysqLmanager/back/master01/2017-01-01.03:08:36.sql测试结果:slave01 可以同步到 master01 两次的写入数据。
这篇篇幅太长了,另开一篇博文《使用 python 管理 mysql 开发工具箱 - 2》
---------- 本文结束 ----------
总结以上是内存溢出为你收集整理的使用 python 管理 mysql 开发工具箱 - 1全部内容,希望文章能够帮你解决使用 python 管理 mysql 开发工具箱 - 1所遇到的程序开发问题。
如果觉得内存溢出网站内容还不错,欢迎将内存溢出网站推荐给程序员好友。
欢迎分享,转载请注明来源:内存溢出
微信扫一扫
支付宝扫一扫
评论列表(0条)