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 ConfigParser
conf = ConfigParser.ConfigParser(allow_no_value=True)

读配置文件 read/readfp

In [3]: conf.read('/root/my.cnf')
Out[3]: ['/root/my.cnf']
# 返回配置文件列表,其实可以读取多个配置文件的列表,实际应用中没有意义,一般都只读取一个配置文件
# readfp() 函数可以读取 open() 函数返回的文件句柄 fp

section 相关操作

# 配置文件中有哪些 section
In [4]: conf.sections()
Out[4]: ['client', 'mysqld', 'mysqldump', 'mysql', 'myisamchk', 'mysqlhotcopy']
# 添加 section [user]
In [5]: conf.add_section('user')
In [6]: conf.sections()
Out[6]: ['client', 'mysqld', 'mysqldump', 'mysql', 'myisamchk', 'mysqlhotcopy', 'user']
# 删除 section [client] 注意:会把该section下的option全部删除
In [10]: conf.remove_section('client')
Out[10]: True
# 判断是否有section [user]
In [15]: conf.has_section('user')
Out[15]: True

options 相关操作

In [16]: conf.options('mysqld')             # 列出options
In [17]: conf.set('mysqld','key','value') # 添加options [key] 同样可以修改options
In [18]: conf.remove_option('mysqld','key') # 删除options
In [23]: conf.has_option('mysqld', 'key') # 判断是否有[key]

获取 get 值 value

In [24]: conf.get('mysqld', 'port')
Out[24]: '' # 返回value字符串格式
In [25]: conf.getint('mysqld', 'port')
Out[25]: 3306 # 返回value整数格式
In [26]: conf.getfloat('mysqld', 'xxxx') # 返回value浮点数格式
In [27]: conf.getboolean('mysqld', 'xxxx') # 返回value布尔型格式
In [28]: conf.items('mysqld')
Out[28]:
[('port', ''),
('query_cache_size', '16M'),
... ... ... ...
('server-id', '')]

写入配置文件

# 上述的设置是对内存中数据进行操作,并非实际写入配置文件,通过write写入配置文件
In [29]: fp = open('/tmp/my.cnf', 'w')
In [30]: conf.write(fp)
In [31]: fp.close()

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解析:

import ConfigParser
conf = ConfigParser.ConfigParser()
conf.read("test.conf")
print conf.get("test", "url")
conf.set("test", "url2", "%(host)s:%(port)s")
print conf.get("test", "url2")

>>> 终端输出内容:

http://localhost:8080/Portal
localhost:8080

SafeConfigParser 可以实现 ConfigParser 同样的功能。

二、生成 MySQL 配置文件模板

通过借助于 ConfigParser 模块,写了一个 MySQLDConfig 的工具类,使用这个类可以对 MySQL 配置文件进行一些列的操作:生成模板、添加选项、修改选项等,非常方便,作为后续开发工具箱的一个重要工具库。代码 mysql.py 如下:

 #!/usr/bin/python
#encoding: utf-8 from ConfigParser import ConfigParser
import sys,os # 定义MySQLConfig类 继承ConfigParser类
class MySQLDConfig(ConfigParser):
def __init__(self, config, **kw):
ConfigParser.__init__(self, allow_no_value=True)
# must support new style: object++ modify source code
#super(ConfigParser, self).__init__(allow_no_value=True)
# 所有选项都会汇聚到该字典中,统一写入配置文件
self.mysqld_vars = {}
self.config = config
if os.path.exists(self.config):
self.read(self.config)
self.get_mysqld_vars()
else:
self.get_defaults_mysqld_vars()
self.set_mysqld_vars(kw) # 统一的接口:将指定的kw写入setattr和全局字典
def set_mysqld_vars(self, kw):
for k,v in kw.items():
setattr(self, k, v)
self.mysqld_vars[k] = v # 读取配置文件[mysqld]段的所有选项并set
def get_mysqld_vars(self):
rst = {}
options = self.options('mysqld')
for o in options:
rst[o] = self.get('mysqld', o)
self.set_mysqld_vars(rst) # 设置默认的mysql选项, 如果没有配置文件,则使用默认配置项
def get_defaults_mysqld_vars(self):
defaults = {
'port':'',
'socket':'/var/lib/mysql/mysql.sock',
'key_buffer_size':'256M',
'max_allowed_packet':'1M',
'table_open_cache':'',
'sort_buffer_size':'1M',
'read_buffer_size':'1M',
'read_rnd_buffer_size':'4M',
'myisam_sort_buffer_size':'64M',
'thread_cache_size':'',
'query_cache_size':'16M',
'thread_concurrency':'',
'user': 'mysql',
}
self.set_mysqld_vars(defaults) # 特殊的接口 单独去设置/添加变量 比如skip-salve-start等不能通过变量传递的选项
def set_vars(self, k, v):
self.mysqld_vars[k] = v # 将所有的选项保存到配置文件,包括:新添加和更新的
def save(self):
if not self.has_section('mysqld'):
self.add_section('mysqld')
for k, v in self.mysqld_vars.items():
self.set('mysqld', k, v)
with open(self.config, 'w') as fd:
self.write(fd) if __name__ == '__main__':
mc = MySQLDConfig('/root/my1.cnf', max_connections=200, port=3307)
#print mc.get('mysqld','port')
#print mc.max_connections
#print mc.port
#print mc.socket #mc.set_vars('skip-slave-start', None)
mc.save()
print mc.port

三、创建 MySQL 实例

借助于上一章节编写的 MySQLDConfig 类,来创建 MySQL 实例,大概如下几个步骤:

  1. 生成配置文件
  2. 安装初始化 MySQL 实例
  3. 设置属主属组
  4. 启动 MySQL 运行

此时的代码结构:

├── library
│   ├── __init__.py
│   └── mysql.py
└── mysqlmanager
└── myman.py
2 directories, 3 files

具体的主代码 myman.py 如下:

 #!/usr/bin/env python
#encoding: utf-8 import os, sys, time
from subprocess import Popen, PIPE
import shlex
from optparse import OptionParser
DIRNAME = os.path.dirname(__file__)
OPSTOOLS = os.path.abspath(os.path.join(DIRNAME, '..'))
sys.path.append(OPSTOOLS)
from library.mysql import MySQLDConfig # MySQL实例的数据目录(会以name为子目录)
MYSQL_DATA_DIR = '/var/mysqlmanager/data'
# MySQL实例的配置文件目录
MYSQL_CONF_DIR = '/var/mysqlmanager/conf' # 设置选项参数
def opt():
parser = OptionParser()
parser.add_option(
'-n', '--name', # 指定实例的name
dest = 'name',
action = 'store',
default = 'myinstance'
)
parser.add_option(
'-p', '--port', # 指定端口
dest = 'port',
action = 'store',
default = ''
)
parser.add_option(
'-c', '--command', # create check and so on...
dest = 'command',
action = 'store',
default = 'check'
)
options, args = parser.parse_args()
return options, args # 初始化目录(如果不存在则创建)
def _init():
if not os.path.exists(MYSQL_DATA_DIR):
os.makedirs(MYSQL_DATA_DIR)
if not os.path.exists(MYSQL_CONF_DIR):
os.makedirs(MYSQL_CONF_DIR) # 使用glob模块读取配置文件,返回配置文件列表(绝对路径)
def readConfs():
import glob
confs = glob.glob(MYSQL_CONF_DIR + '/*.cnf')
return confs # 检查指定的配置文件中端口号是否与指定端口相同
def checkPort(conf_file, port):
mc = MySQLDConfig(conf_file)
if mc.mysqld_vars['port'] == port:
return True
else:
return False # 有些配置项的值由具体示例而定,将这些不定项设置为字典
def _genDict(name, port):
return {
'pid-file': os.path.join(MYSQL_DATA_DIR, name,'%s.pid' % name),
'socket': '/tmp/%s.sock' % name,
'port': port,
'datadir': os.path.join(MYSQL_DATA_DIR, name),
'log-error': os.path.join(MYSQL_DATA_DIR, name, '%s.log' % name),
} # 通过配置文件名称->配置文件的绝对路径
def getCNF(name):
cnf = os.path.join(MYSQL_CONF_DIR, '%s.cnf' % name)
return cnf # MySQL执行安装过程
def mysql_install(name):
cnf = getCNF(name)
cmd = 'mysql_install_db --defaults-file=%s' % cnf
p = Popen(shlex.split(cmd), stdout=PIPE, stderr=PIPE)
p.communicate()
p.returncode # 为保险起见,设置MySQL实例数据目录的属主数组
def setOwner(datadir):
os.system('chown mysql:mysql %s -R' % datadir) # 运行MySQL实例
def mysql_run(name):
cnf = getCNF(name)
cmd = 'mysqld_safe --defaults-file=%s &' % cnf
p = Popen(cmd, stdout=PIPE, stderr=PIPE, shell=True)
#time.sleep(2)
p.returncode # 创建MySQL实例主函数, 由create子命令触发调用
def createInstance(name, port):
exists_confs = readConfs() # 检查给定的端口号和名称是否已经使用
for conf in exists_confs:
if conf.split('/')[-1][:-4] == name:
print >> sys.stderr, 'Instance: %s is exists' % name
sys.exit(-1)
if checkPort(conf, port):
print >> sys.stderr, 'Port: %s is exists' % port
sys.exit(-1) # 1. 生成配置文件
cnf = getCNF(name)
if not os.path.exists(cnf):
c = _genDict(name, port)
mc = MySQLDConfig(cnf, **c)
mc.save()
datadir = os.path.join(MYSQL_DATA_DIR, name)
if not os.path.exists(datadir):
# 2. 安装初始化MySQL实例
mysql_install(name)
# 3. 设置属主属组
setOwner(datadir)
# 4. 启动MySQL运行
mysql_run(name) if __name__ == '__main__':
_init()
options, args = opt()
instance_name = options.name
instance_port = options.port
instance_cmd = options.command
if instance_cmd == 'create':
createInstance(instance_name, instance_port)

>>>> 扩展:实现几个简单使用功能

  1. 启动 MySQL 实例
  2. 关闭 MySQL 实例
  3. 重启 MySQL 实例

四、MySQLdb 模块的使用

1. 安装 MySQL-python

直接使用 yum 工具安装:

[root@mysql ~]# yum install MySQL-python -y

2. 设置库路径

使用 rpm -ql MySQL-python 命令可以查看到默认安装 MySQLdb 库路径是:/usr/lib64/python2.6/site-packages 。如果没有升级 python 版本,可以正常使用,直接 import 即可。但是我升级了 python 2.7.10 ,默认 python 2.7 不会去旧版本路径下找库的,因此无法使用。解决办法有几种:

  1. 设置环境变量 PYTHONPATH
  2. 在 sys.path 追加路径
  3. 拷贝 MySQLdb 库目录到 Python2.7 路径下
  4. 添加 .pth 文件,添加路径

我这里使用的方式是第 4 种:

[root@mysql site-packages]# pwd
/usr/local/python27/lib/python2./site-packages
[root@mysql site-packages]# cat python26sitepackages.pth # 添加 xxx.pth 文件,文件中设置第三方库路径
/usr/lib64/python2./site-packages
# *.pth文件名称随意,文件后缀一定要是.pth

3. 基本使用

# 导入MySQLdb模块
In [1]: import MySQLdb # 连接数据库
In [2]: conn = MySQLdb.Connect(host='127.0.0.1', port=3306, user='root', passwd='') # 获取游标句柄
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',), ('test',))

五、MySQL 配置文件检查(与内存)

MySQL 可以通过配置文件和数据库命令行方式去修改参数变量,经常会有这种情况,临时通过命令行手动修改了选项参数,比如最大连接数不够了,通过 set global max_connections=200 来临时设置了参数。但是下次重启 MySQL 又会从配置文件读取参数。现在可以通过开发的工具箱来读取配置文件和内存中的参数是否一致,如果不一致,考虑以内存中的值为准,写入配置文件。部分代码如下:

 # 根据配置文件信息连接MySQL数据库
def connMysql(name):
cnf = getCNF(name)
if os.path.exists(cnf):
mc = MySQLDConfig(cnf)
port = int(mc.mysqld_vars['port'])
host = '127.0.0.1'
user = 'root'
conn = MySQLdb.connect(host=host , port=port, user=user,)
cur = conn.cursor()
return cur # 获取内存中全局变量, 输出是一个字典.
def getMyVariables(cur):
sql = 'show global variables'
cur.execute(sql)
data = cur.fetchall()
return dict(data) # 对比配置文件和内存中变量, 找出不一致相
# 遗留问题: 单位不一致和目录最后'/'符号问题 ?????????????????????????????????
def diffMyVariables(name):
cur = connMysql(name)
vars = getMyVariables(cur)
cnf = getCNF(name)
mc = MySQLDConfig(cnf)
for k, v in mc.mysqld_vars.items():
k = k.replace('-', '_')
if k in vars and v != vars[k]:
print k, v, vars[k] if __name__ == '__main__':
_init()
options, args = opt()
instance_name = options.name
instance_port = options.port
instance_cmd = options.command
if instance_cmd == 'create':
createInstance(instance_name, instance_port)
elif instance_cmd == 'check':
diffMyVariables(instance_name)

命令执行:python myman.py -n my01 -p 3306 -c check

六、MySQL 配置文件调整(同步)

通过 check 命令找到了配置文件和内存中参数的不同,然后就可以通过 adjust 命令来调整一下配置文件,保持配置文件和内存的同步。实现代码如下:

 # 根据命令行参数调整配置文件
def setMyVariables(name, k, v):
cnf = getCNF(name)
mc = MySQLDConfig(cnf)
mc.set_vars(k, v)
mc.save() if __name__ == '__main__':
_init()
options, args = opt()
instance_name = options.name
instance_port = options.port
instance_cmd = options.command
if instance_cmd == 'create':
createInstance(instance_name, instance_port)
elif instance_cmd == 'check':
diffMyVariables(instance_name)
elif instance_cmd == 'adjust':
try:
k = args[0]
except IndexError:
print 'Usage: -c adjust max_connections 300. At least 1 arg.'
try:
v = args[1]
except IndexError:
v = None
setMyVariables(instance_name, k, v)

命令执行:python myman.py -n my01 -p 3306 -c adjust max_connections 200

七、数据库 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', master_port = 3306, master_user = 'repl', master_password = ''

3. 先后运行 Mster 和 Slave 实例

先运行 master,后运行 slave。在从节点上运行命令查看:show slave status\G;

4. 其它选项

skip-slave-start:从库节点 slave 运行时,不会直接启动 slave 的主从复制
replicate-ignore-db:忽略某个数据库的同步复制,比如 mysql 库,忽略,常容易出错

八、代码实现主库和从库创建

以下是继续使用 create 子命令来实现主从库的创建。

 REPLICATION_USER = 'repl'
REPLICATION_PASS = '' # 设置主从用户时执行创建用户的SQL语句
def runSQL(name):
sql = "grant replication slave on *.* to %s@'%%' identified by '%s'" % (REPLICATION_USER, REPLICATION_PASS)
cur = connMysql(name)
cur.execute(sql) # 代替配置文件,在slave上设置master相关信息
def changeMaster(name, host, port, user, password):
sql = """change master to
master_host = '%s',
master_port = %s,
master_user = '%s',
master_password = '%s'
""" % (host, port, user, password) cur = connMysql(name)
cur.execute(sql) if __name__ == '__main__':
_init()
options, args = opt()
instance_name = options.name
instance_port = options.port
instance_cmd = options.command
if instance_cmd == 'create':
if not args:
createInstance(instance_name, instance_port)
else:
dbtype = args[0]
serverid = args[1]
mysql_options = {'server-id': serverid}
if dbtype == 'master':
mysql_options['log-bin'] = 'mysql-bin'
createInstance(instance_name, instance_port, **mysql_options)
runSQL(instance_name)
elif dbtype == 'slave':
# 5.5 版本以上不建议将master开头字段写入配置文件,其实低版本写入配置文件也是不妥当的
#mysql_options['master-host'] = args[2]
#mysql_options['master-port'] = args[3]
#mysql_options['master-user'] = REPLICATION_USER
#mysql_options['master-pass'] = REPLICATION_PASS
mysql_options['replicate-ignore-db'] = 'mysql' # 设置忽略mysql库
mysql_options['skip-slave-start'] = None # 设置slave运行时不自动启动主从复制
createInstance(instance_name, instance_port, **mysql_options) # 按照从选项来创建实例
host = args[2] # 传入master的主机
port = args[3] # 传入master的端口
user = REPLICATION_USER
password = REPLICATION_PASS
# 设置master信息
changeMaster(instance_name, host, port, user, password)
elif instance_cmd == 'check':
diffMyVariables(instance_name)
elif instance_cmd == 'adjust':
try:
k = args[0]
except IndexError:
print 'Usage: -c adjust max_connections 300. At least 1 arg.'
try:
v = args[1]
except IndexError:
v = None
setMyVariables(instance_name, k, v)

创建主库: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 数据库

数据库备份很重要,要制定好备份策略。部分代码如下:

 # MySQL实例的数据目录(会以name为子目录)
MYSQL_DATA_DIR = '/var/mysqlmanager/data'
# MySQL实例的配置文件目录
MYSQL_CONF_DIR = '/var/mysqlmanager/conf'
# MySQL实例的备份文件目录
MYSQL_BACK_DIR = '/var/mysqlmanager/back' # MySQL备份,有待完善,调整下灵活性
def backupMysql(name):
import datetime
now = datetime.datetime.now()
ts = now.strftime('%Y-%m-%d.%H:%M:%S')
sqlfile = os.path.join(MYSQL_BACK_DIR, name, '%s.sql' % ts)
_dir = os.path.dirname(sqlfile) # 如果目录不存在,则创建
if not os.path.exists(_dir):
os.makedirs(_dir)
cnf = getCNF(name)
mc = MySQLDConfig(cnf)
port = mc.mysqld_vars['port']
# -A:所有数据库 -x:dump时锁表,只读 -F:dump前刷log
cmd = "mysqldump -A -x -F --master-data=1 --host=127.0.0.1 --port=%s --user=root > %s 2>/dev/null" % (port, sqlfile)
p = Popen(cmd, stdout=PIPE, shell=True)
stdin, stdout = p.communicate()
p.returncode if __name__ == '__main__':
_init()
options, args = opt()
instance_name = options.name
instance_port = options.port
instance_cmd = options.command
if instance_cmd == 'create':
if not args:
createInstance(instance_name, instance_port)
# ...... 省略其它部分
elif instance_cmd == 'check':
diffMyVariables(instance_name)
elif instance_cmd == 'adjust':
try:
k = args[0]
except IndexError:
print 'Usage: -c adjust max_connections 300. At least 1 arg.'
try:
v = args[1]
except IndexError:
v = None
setMyVariables(instance_name, k, v)
elif instance_cmd == 'backup':
backupMysql(instance_name)

执行命令: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 就保持数据的同步了。具体代码如下:

 # 代替配置文件,在slave上设置master相关信息, 注意最后2个缺省参数(是为restore命令而加)
def changeMaster(name, host, port, user, password, logfile=None, logpos=None):
if logfile is None:
sql = """change master to
master_host = '%s',
master_port = %s,
master_user = '%s',
master_password = '%s'
""" % (host, port, user, password)
else:
sql = """change master to
master_host = '%s',
master_port = %s,
master_user = '%s',
master_password = '%s',
master_log_file = '%s',
master_log_pos = %s
""" % (host, port, user, password, logfile, logpos) cur = connMysql(name)
cur.execute(sql) # 定义MySQL备份恢复主函数,参数需要指定备份的sql文件
def restoreMysql(name, port, sqlfile, **kw):
# 创建从实例 传入选项参数
createInstance(name, port, **kw)
cnf = getCNF(name)
mc = MySQLDConfig(cnf)
port = mc.mysqld_vars['port']
# 执行导入sql的shell命令
cmd = "mysql -h 127.0.0.1 -u root -P %s < %s" % (port, sqlfile)
p = Popen(cmd, stdout=PIPE, shell=True)
stdin, stdout = p.communicate()
p.returncode # 定义内部正则过滤参数的功能函数, 获取:master-log-file 和 master-log-pos
def findPos(s):
import re
rlog = re.compile(r"MASTER_LOG_FILE='(\S+)'")
rpos = re.compile(r"MASTER_LOG_POS=(\d+)")
log = rlog.search(s)
pos = rpos.search(s)
if log and pos:
return log.group(1), pos.group(1)
else:
return (None, None) # 读SQL文件,返回log、pos
def getPos(sqlfile):
with open(sqlfile) as fd:
for line in fd:
log, pos = findPos(line)
if log and pos:
return log, pos if __name__ == '__main__':
_init()
# ... 省略了中间部分代码 ...
elif instance_cmd == 'backup': # MySQL备份命令
backupMysql(instance_name)
elif instance_cmd == 'restore': # MySQL备份的恢复命令
server_id = args[0]
master_host = args[1]
master_port = args[2]
sqlfile = args[3]
mysqld_options = {'server-id': server_id}
mysqld_options['skip-slave-start'] = None
mysqld_options['replicate-ignore-db'] = 'mysql'
# 恢复固定SQL内容(SQL文件备份的内容)
restoreMysql(instance_name, instance_port, sqlfile, **mysqld_options)
logfile, logpos = getPos(sqlfile)
# 指定log和pos,来配置slave激活master的主从复制(实现增量备份的恢复)
changeMaster(instance_name, master_host, master_port, REPLICATION_USER, REPLICATION_PASS, logfile, 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的更多相关文章

  1. 使用 python 管理 mysql 开发工具箱 - 2

    这篇博文接着上篇文章<使用 python 管理 mysql 开发工具箱 - 1>,继续写下自己学习 python 管理 MySQL 中的知识记录. 一.MySQL 的读写分离 学习完 My ...

  2. Python 管理 MySQL

    Python MySQLdb 模块 Python pymysql 模块 Python SQLAlchemy 模块 Python ConfigParser 模块 Python 创建 MySQL 配置文件 ...

  3. 练习:python 操作Mysql 实现登录验证 用户权限管理

    python 操作Mysql 实现登录验证 用户权限管理

  4. python操作三大主流数据库(6)python操作mysql⑥新闻管理后台功能的完善(增、ajax异步删除新闻、改、查)

    python操作mysql⑥新闻管理后台功能的完善(增.删.改.查)安装表单验证D:\python\python_mysql_redis_mongodb\version02>pip instal ...

  5. Python 42 mysql用户管理 、pymysql模块

    一:mysql用户管理 什么是mysql用户管理 mysql是一个tcp服务器,应用于操作服务器上的文件数据,接收用户端发送的指令,接收指令时需要考虑到安全问题, ATM购物车中的用户认证和mysql ...

  6. 多版本Python管理及Python连接MySQL

    Python有个非常别扭的地方,就是两个不兼容的版本,很尴尬,有的包只能在低版本的2.7上才能运行,比如即将用到的MySQLdb. 所以首先必须在系统上安装两个版本的Python(貌似在pycharm ...

  7. Python自动化 【第十二篇】:Python进阶-MySQL和ORM

    本节内容 数据库介绍 mysql 数据库安装使用 mysql管理 mysql 数据类型 常用mysql命令 创建数据库 外键 增删改查表 权限 事务 索引 python 操作mysql ORM sql ...

  8. python数据库(mysql)操作

    一.软件环境 python环境默认安装了sqlite3,如果需要使用sqlite3我们直接可以在python代码模块的顶部使用import sqlite3来导入该模块.本篇文章我是记录了python操 ...

  9. python 操作mysql

    安装模块: #pip install .... MySQLdb(2.x) pymysql(3.x) import MySQLdb as sql con = sql.connect( host = &q ...

随机推荐

  1. scope.$apply是干嘛的

    开始用angular做项目的时候,一定碰到过$scope.$apply()方法,表面上看,这像是一个帮助你进行数据更新的方法,那么,它为何存在,我们又该如何使用它呢. JavaScript执行顺序 J ...

  2. <a> href属性--记录八

    1.去掉<a>标签的下划线 <ul style=" list-style-type:none; margin:0;color:Gray; font-size:11px;ma ...

  3. 创建 Monitor 并测试 - 每天5分钟玩转 OpenStack(124)

    前面我们创建了 Pool,VIP 并添加了 Member.今天将创建 Monitor,然后测试 LBaaS 是否能够正常工作. 创建 Monitor LBaaS 可以创建 monitor,用于监控 P ...

  4. C# Word中设置/更改文本方向

    C# Word中设置/更改文本方向 一般情况下在Word中输入的文字都是横向的,今天给大家分享两种方法来设置/更改一个section内的所有文本的方向及部分文本的方向,有兴趣的朋友可以试下. 首先,从 ...

  5. Oracle简单常用的数据泵导出导入(expdp/impdp)命令举例(上)

    <Oracle简单常用的数据泵导出导入(expdp/impdp)命令举例(上)> <Oracle简单常用的数据泵导出导入(expdp/impdp)命令举例(下)> 目的:指导项 ...

  6. 读书笔记--SQL必知必会15--插入数据

    15.1 数据插入 使用INSERT语句将行插入(或添加)到数据库表.可能需要特定的安全权限. 插入完整的行 插入行的一部分 插入某些查询的结果 15.1.1 插入完整的行 要求指定表名和插入到新行中 ...

  7. Windows环境下vscode-go安装笔记

    一.介绍 对于Visual Studio Code开发工具,有一款优秀的GoLang插件,它的主页为:https://github.com/microsoft/vscode-go 这款插件的特性包括: ...

  8. 微服务和SOA服务

    微服务和SOA都被认为是基于服务的架构,这意味着这两种架构模式都非常强调将“服务”作为其架构中的首要组件,用于实现各种功能(包括业务层面和非业务层面).微服务和SOA是两种差异很大的架构模式,但是他们 ...

  9. PyQt4入门学习笔记(二)

    之前第一篇介绍了pyqt4的大小,移动位置,消息提示.这次我们介绍菜单和工具栏 QtGui.QmainWindow这个类可以给我们提供一个创建带有状态栏.工具栏和菜单栏的标准的应用. 状态栏 状态栏是 ...

  10. WPF入门:XAML

    XAML是WPF技术中专门用于设计UI的语言 XAML优点最大的优点是将UI与逻辑代码剥离 创建第一个WPF应用程序 VS默认生成的WPF项目解决方案 Properties:里面主要包含了程序用到的一 ...