python创建MySQL多实例-1

前言

  • 什么是多实例

多实例就是允许在同一台机器上创建另外一套不同配置文件的数据库,他们之间是相互独立的,主要有以下特点,

  • 1》 不能同时使用一个端口
  • 2》 不可以使用同一个socket文件
  • 3》 也不可以使用同样的pid
  • 4》 配置文件也必须是不一样的
  • 5》 存入数据的data目录也不能一样
  • 6》 日志文件位置也不可以一样

上面这些只是我个人的一些理解,具体的可能参考网上的一些文章

https://www.percona.com/blog/2014/08/26/mysqld_multi-how-to-run-multiple-instances-of-mysql/

https://freedo.ga/url?sa=t&rct=j&q=&esrc=s&source=web&cd=2&cad=rja&uact=8&ved=0ahUKEwjOr4-hj7LTAhXpiFQKHSKNDD4QFggrMAE&url=https%3A%2F%2Fdev.mysql.com%2Fdoc%2Fmysql%2Fen%2Fmultiple-servers.html&usg=AFQjCNGkZSDJbsHCVbm0n8cubpUha2SPsA

https://dev.mysql.com/doc/refman/en/multiple-windows-services.html

需求

通过python脚本来实现创建多个实例

使用方法

程序的目录结构如下

# tree mysql_tools/
mysql_tools/
├── library
│   ├── __init__.py
│   ├── __init__.pyc
│   ├── mysql.py
│   └── mysql.pyc
└── manager
├── __init__.py
└── myman.py 2 directories, 6 files
# python myman.py  -h
Usage: myman.py [options] Options:
-h, --help show this help message and exit
-n NAME, --name=NAME
-p PORT, --port=PORT
-c COMMAND, --command=COMMAND

如创建一个my02.cnf的配置文件,端口为3302

python myman.py -n my02 -p 3302 -c create

实例目录结构

# tree -L 3 /data/mysql/
/data/mysql/
├── conf
│   ├── my01.cnf
│   └── my02.cnf
└── data
├── my01
│   ├── ibdata1
│   ├── ib_logfile0
│   ├── ib_logfile1
│   ├── my01-err.log
│   ├── my01.pid
│   ├── my01.sock
│   ├── mysql
│   └── test
└── my02
├── ibdata1
├── ib_logfile0
├── ib_logfile1
├── my02-err.log
├── my02.pid
├── my02.sock
├── mysql
└── test 8 directories, 14 files

源码如下

  • ./library/mysql.py
#!/usr/bin/env python
#-*- coding:utf8 -*- from ConfigParser import ConfigParser
import os class MySQLDConfig(ConfigParser):
def __init__(self, cfg, **kwargs):
ConfigParser.__init__(self, allow_no_value=True)
# super(ConfigParser, self).__init__(allow_no_value=True) # ConfigParser的你类是以传统方式定义的,所以这里不可以用super来重写方法
self.cfg = cfg
self.mysqld_vars = {} if os.path.exists(self.cfg):
self.config = cfg
self.read(self.config)
self.get_mysqld_vars()
else:
self.get_default_mysqld_vars() self.set_mysqld_vars(kwargs) def set_mysqld_vars(self, kwargs):
for k,v in kwargs.items():
setattr(self, k, v)
' add every k-v pairs to dictonary. '
self.mysqld_vars[k] = v def get_mysqld_vars(self):
result = {}
'return a list'
options = self.options('mysqld')
for opt in options:
result[opt] = self.get('mysqld', opt)
self.set_mysqld_vars(result) def get_default_mysqld_vars(self):
defaults = {
'user': 'mysql',
'port': '3307',
'socket': ' /var/lib/mysql/mysql.sock',
# 'skip-locking': None,
'key_buffer_size': '256M',
'max_allowed_packet': '1M',
'table_open_cache': '256',
'sort_buffer_size': '1M',
'read_buffer_size': '1M',
'read_rnd_buffer_size': '4M',
'myisam_sort_buffer_size': '64M',
'thread_cache_size': '8',
'query_cache_size': ' 16M',
}
' set default dict k-v to instance property. '
self.set_mysqld_vars(defaults) def set_vars(self, k, v):
self.mysqld_vars[k] = v ' set propertyis for non-supported name, e.g. "skip-slave-start" '
def save_default_cfg(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.cfg, 'wb') as fd:
self.write(fd) if __name__ == '__main__':
cfg_file = '/tmp/my.cnf2'
mc = MySQLDConfig(cfg_file, max_connection=200, port=3307)
# mysqld_socket = mc.get('mysqld', 'socket')
# print mysqld_socket
mc.set_vars('skip-slave-start', None)
mc.save_default_cfg()
print mc.mysqld_vars['skip-slave-start']
print mc.max_connection
print mc.port
print mc.socket
  • ./library/mysql.py
#!/usr/bin/env python
#*-* coding: utf-8 -*- from optparse import OptionParser
import sys
import os
from subprocess import Popen,PIPE
import shlex
import time
import shutil current_dir = os.path.dirname(__file__)
parent_dir = os.path.join(current_dir, '../')
sys.path.append( os.path.abspath(parent_dir) ) from library.mysql import MySQLDConfig MYSQL_DATA_DIR = '/data/mysql/data'
MYSQL_CONF_DIR = '/data/mysql/conf' def opt():
parser = OptionParser()
parser.add_option('-n', '--name',
dest='name',
action='store',
default='myinstance'
)
parser.add_option('-p', '--port',
dest='port',
action='store',
default='3306'
)
parser.add_option('-c', '--command',
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.mkdir(MYSQL_DATA_DIR)
shutil.os.makedirs(MYSQL_DATA_DIR)
if not os.path.exists(MYSQL_CONF_DIR):
# os.mkdir(MYSQL_CONF_DIR)
shutil.os.makedirs(MYSQL_CONF_DIR) def readConfs():
from glob import glob
confs = glob(MYSQL_CONF_DIR + '/*.cnf')
return confs def checkPort(cfg_file, port):
mc = MySQLDConfig(cfg_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': os.path.join(MYSQL_DATA_DIR, name, '%s.sock' % name),
'port': port,
'datadir': os.path.join(MYSQL_DATA_DIR, name),
'log-error': os.path.join(MYSQL_DATA_DIR, name, '%s-err.log' % name)
} def getCnf(name):
return os.path.join(MYSQL_CONF_DIR, '%s.cnf' % name) def createInstance(name, port):
confs = readConfs() for conf in confs:
if conf.split('/')[-1].split('.')[0] == name:
print >> sys.stderr, 'Instance: %s is already exists' % name
sys.exit(-1)
if checkPort(conf, port):
print >> sys.stderr, 'Port: %s is already exists' % port
sys.exit(-1)
cnf = getCnf(name)
if not os.path.exists(cnf):
kwargs = _genDict(name, port)
mc = MySQLDConfig(cnf, **kwargs)
mc.save_default_cfg() datadir = os.path.join(MYSQL_DATA_DIR, name)
if not os.path.exists(datadir):
mysql_install(name)
setOwner(datadir)
mysqlRun(name) 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 def setOwner(datadir):
os.system('chown mysql:mysql %s' % datadir) def mysqlRun(name):
cnf = getCnf(name)
cmd = 'mysqld_safe --defaults-file=%s &' % cnf
# 此行不知为什么会有问题,猜想可能与后台进程符号'&'有关
# p = Popen(shlex.split(cmd), stdout=PIPE, stderr=PIPE)
p = Popen(cmd, stdout=PIPE, stderr=PIPE, shell=True)
# 如果是以后台进程启动的,那么就会hang住,因为后台进程并不会返回结果,所以p.communicate()就会一起处于等待状态
# p.communicate()
time.sleep(2)
p.returncode if __name__ == '__main__':
_init()
options, args = opt()
instance_name = options.name
instance_port = options.port
instance_cmd = options.command
createInstance(instance_name, instance_port)
# print options, args

python创建MySQL多实例-1的更多相关文章

  1. Python连接MySQL的实例代码

    Python连接MySQL的实例代码   MySQLdb下载地址:http://sourceforge.net/projects/mysql-python/ 下载解压缩后放到%Python_HOME% ...

  2. python3.4学习笔记(二十五) Python 调用mysql redis实例代码

    python3.4学习笔记(二十五) Python 调用mysql redis实例代码 #coding: utf-8 __author__ = 'zdz8207' #python2.7 import ...

  3. 一分钟在云端快速创建MySQL数据库实例

    本教程将帮助您了解如何使用Azure管理门户迅速创建,连接,配置MySQL 数据库 on Azure.完成本教程后,您将在Azure上拥有一个示例MySQL数据库服务器,并了解如何使用管理门户执行基本 ...

  4. python 创建mysql数据库

    昨天用shell脚本创建数据库,涉及java调用,比较折腾,改用python直接创建数据库,比较方便,好了,直接上代码,相关注释也添加了 # _*_encoding:UTF-8_*_import My ...

  5. 使用Python创建MySQL数据库实现字段动态添加以及动态的插入数据

    应用场景: 我们须要设计一个数据库来保存多个文档中每一个文档的keyword. 假如我们每一个文档字符都超过了1000,取当中出现频率最大的为我们的keyword. 如果每个文档的keyword都超过 ...

  6. python 创建类的实例对象

    # -*- coding: UTF-8 -*- class Employee: def __init__(self, name, salary): self.name = name self.sala ...

  7. python连接mysql数据库实例demo(银行管理系统数据库版)

    主函数: import adminView import os import pickle from bankFunction import BankFunction import time def ...

  8. Python操作MySQL数据库9个实用实例

    用python连接mysql的时候,需要用的安装版本,源码版本容易有错误提示.下边是打包了32与64版本. MySQL-python-1.2.3.win32-py2.7.exe MySQL-pytho ...

  9. Python 管理 MySQL

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

随机推荐

  1. centos 7 yum configuration; yum localinstall

    Linux下对于软件包的管理使用rpm管理方式.直接使用rpm包管理工具来进行rpm包的安装,升级,卸载时,对于最让人头疼的莫过与包之间的依赖关系.yum作为一个rpm包前端管理工具,可以自动处理依赖 ...

  2. django比较相等或者不相等的模板语法ifequal / ifnotequal

    转自:http://blog.csdn.net/goupper1991/article/details/50768346 ifequal / ifnotequal      在模板语言里比较两个值并且 ...

  3. 一个简单的servlet查询

    首先创建一个dynamic web project. 写一个test.jsp: 新建一个servlet: 新建一个student.jsp: 显示如图:

  4. maven项目创建

    一.搭建步骤 ♦首先创建一个Maven的Project,如下图: ♦点击Next,勾选 Create a simple project ♦点击Next,注意Packing要选择war,因为我们创建的是 ...

  5. 【Python】web.py-简单轻量级网页框架python

    简单轻量级网页框架python web.py的安装 python 3.x中安装web.py 最近决定从python2.7转移到3.x上工作. 使用数据库的时候,依然选用了之前比较感兴趣的web.py ...

  6. Linux 线程实现机制分析 Linux 线程模型的比较:LinuxThreads 和 NPTL

    Linux 线程实现机制分析 Linux 线程实现机制分析  Linux 线程模型的比较:LinuxThreads 和 NPTL http://www.ibm.com/developerworks/c ...

  7. 使用客户端等远程连接mysql数据库

    1:  远程数据库(D1)数据: 数据库用户:root,数据库密码:root,数据库ip 内网地址  192.168.100.91,数据库端口 3306 本地主机:ip  192.168.127.1 ...

  8. POJ3414—Pots(bfs加回溯)

    http://poj.org/problem?id=3414                                       Pots Time Limit: 1000MS   Memor ...

  9. 尝试.Net Core—使用.Net Core + Entity FrameWork Core构建WebAPI(一)

    想尝试.Net Core很久了,一直没有时间,今天回家,抛开一切,先搭建一个.Net Core的Demo出来玩玩. 废话少说,咱直奔主题: 一.开发环境 VS2015 Update3 Microsof ...

  10. [LeetCode] questions conclustion_BFS, DFS

    BFS, DFS 的题目总结. Directed graph: Directed Graph Loop detection and if not have, path to print all pat ...