python自动安装mysql5.7

python版本:python2.6

centos版本:centos6.9

mysql版本:mysql5.7.19

安装目录路径和数据目录路径都是固定,当然也可以自己修改

这个脚本的原理是,通过createmycnf.sh的shell脚本生成my.cnf,buffer pool大小等在shell脚本里已经计算好,然后installmysql.py修改生成好的my.cnf里的端口等变量

并根据my.cnf来初始化mysql,初始化完毕之后启动mysql服务,并设置mysql的root用户密码,整个执行过程的日志会保存在当前目录下的installmysql.log

注意:目前不支持多实例安装,只支持单实例安装

执行脚本前要先安装MySQL-python

installmysql.py

installmysql.py脚本参数

-P:mysql端口号
-f:mysql二进制安装包位置
-b:createmycnf.sh文件的位置
-p:mysql的root用户密码

#!/usr/bin/env python
-*- coding:utf-8 -*-
@Author : huazai
@Time : 2017/5/4 22:04
@File : installmysql.py
@Description : mysql数据目录路径:/data/mysql/  ,mysql安装目录路径:/usr/local/mysql

import os
import sys
from optparse import OptionParser
from subprocess import Popen, PIPE
import shlex
import time
import MySQLdb
import re
import shutil
import tarfile
import stat
import logging
import  pwd

logger = None
MYSQL_DATA_DIR = '/data/mysql/'
MYSQL_INSTALL_DIR = '/usr/local/mysql/'
MYSQL_CONF_DIR = '/etc/'
MYSQL_BACK_DIR = '/data/backup/mysql/'
MYSQL_STARTUP_SCRIPT = '/etc/init.d/mysql'

def init_log():
    global logger
    fmt_date = '%Y-%m-%d %H:%M:%S.%s'
    fmt_file = '%(lineno)s %(asctime)s  [%(process)d]: %(levelname)s  %(filename)s  %(message)s'

    log_file = 'installmysql.log'
    logger = logging.getLogger('mysqlinstallloging')
    logger.setLevel(logging.INFO)
    file_handler = logging.FileHandler(log_file, mode='a')
    file_handler.setFormatter(logging.Formatter(fmt_file, fmt_date))
    logger.addHandler(file_handler)

def opt():
    parser = OptionParser("Usage: %prog -P -f -b -p")
    parser.add_option("-P", "--port",
                      dest="port",
                      action="store",
                      default="3306",
                      help='port 3306')
    parser.add_option("-f", "--tarfile",
                      dest="tarfile",
                      action="store",
                      default="/tmp/mysql-5.6.28-linux-glibc2.5-x86_64.tar.gz",
                      help='file  /tmp/mysql-5.6.28-linux-glibc2.5-x86_64.tar.gz')
    parser.add_option("-b", "--bashfile",
                      dest="myfile",
                      action="store",
                      default="/tmp/createmycnf.sh",
                      help='file  /tmp/createmycnf.sh')
    parser.add_option("-p", "--mysqlpwd",
                      dest="mysqlpwd",
                      action="store",
                      default="123456",
                      help='password 123456')
    options, args = parser.parse_args()
    return options, args

设置安装目录和数据目录的权限
def setOwner(mysqlport):
    list=[]
    with open('/etc/passwd', 'r') as fd:
        for line in fd:
            matchmysql = re.search(r'mysql', line, re.I)

    if matchmysql:
        os.system('chown -R mysql:mysql %s' % MYSQL_DATA_DIR)
        os.system('chown -R mysql:mysql %s' % MYSQL_INSTALL_DIR)
    else:
        os.system('useradd  -M  -s /sbin/nologin  mysql')
        os.system('chown -R mysql:mysql %s' % MYSQL_DATA_DIR)
        os.system('chown -R mysql:mysql %s' % MYSQL_INSTALL_DIR)
    #检查安装目录和数据目录权限
    for i in  pwd.getpwnam('mysql'):
        list.append(i)
    mysqluid = list[2]
    mysqlgid = list[3]
    stdatadirmode = os.stat(MYSQL_DATA_DIR).st_mode
    stinstalldirmode = os.stat(MYSQL_INSTALL_DIR).st_mode
    if not (os.stat(MYSQL_DATA_DIR).st_uid == mysqluid and os.stat(MYSQL_DATA_DIR).st_gid == mysqlgid):
        logger.error('chown mysql datadir or installdir not ok ')
        sys.exit(1)
    if not (os.stat(MYSQL_DATA_DIR+'mysql%s/data' %(mysqlport)).st_uid == mysqluid and os.stat(MYSQL_DATA_DIR+'mysql%s/data' %(mysqlport)).st_gid == mysqlgid):
        logger.error('chown mysql datadir or installdir not ok ')
        sys.exit(1)
    if not (os.stat(MYSQL_DATA_DIR+'mysql%s/logs' %(mysqlport)).st_uid == mysqluid and os.stat(MYSQL_DATA_DIR+'mysql%s/data' %(mysqlport)).st_gid == mysqlgid):
        logger.error('chown mysql datadir or installdir not ok ')
        sys.exit(1)
    if not (os.stat(MYSQL_DATA_DIR + 'mysql%s/tmp' % (mysqlport)).st_uid == mysqluid and os.stat(MYSQL_DATA_DIR + 'mysql%s/tmp' % (mysqlport)).st_gid == mysqlgid):
        logger.error('chown mysql datadir or installdir not ok ')
        sys.exit(1)

创建必要的目录
def makeDIR(port):
    if os.path.exists('/data/mysql/mysql%s/data' % port):
        logger.error('mysql %s already install' % port)
        sys.exit(1)

    try:
        # os.makedirs('/usr/local/mysql')
        os.makedirs('/data/mysql/mysql%s/data' % port)
        os.makedirs('/data/mysql/mysql%s/tmp' % port)
        os.makedirs('/data/mysql/mysql%s/logs' % port)
    except Exception, e:
        logger.error(e)

解压二进制安装包
def extract(mysqlfile):
    if not os.path.exists(mysqlfile):
        logger.error('%s is not exists' % mysqlfile)
        sys.exit(1)
    os.chdir(os.path.dirname(mysqlfile))
    t = tarfile.open(mysqlfile, 'r:gz')
    t.extractall()  # 解压到当前目录
    t.close()

拷贝安装包文件到程序目录
def copyFile(mysqlfile):
    shutil.copytree(mysqlfile.split('.tar.gz')[0], MYSQL_INSTALL_DIR)
    shutil.copy2(MYSQL_INSTALL_DIR + 'support-files/mysql.server', MYSQL_STARTUP_SCRIPT)
    shutil.rmtree(mysqlfile.split('.tar.gz')[0])

设置环境变量
def setEnv():
    with open('/etc/profile', 'a') as fd:
        fd.write('export PATH=$PATH:/usr/local/mysql/bin' + '\n')
    os.system('source /etc/profile')

初始化mysql
def mysqlInstall():
    cnf = '/etc/my.cnf'
    if os.path.exists(cnf):
        cmd = MYSQL_INSTALL_DIR + "bin/mysqld --defaults-file=%s  --initialize-insecure" % cnf
        p = Popen(shlex.split(cmd), stdout=PIPE, stderr=PIPE)
        stdout, stderr = p.communicate()
        if stdout:
            logger.info('install output: %s' % (stdout))
        if stderr:
            logger.error('install error output: %s' % (stderr))

        if p.returncode == 0:
            logger.info('initialize completed')
            logger.info('install returncode: %s' % (p.returncode))
        else:
            logger.info('initialize failed , please check the mysql errror log')
            logger.info('install returncode: %s' % (p.returncode))
            sys.exit(1)
    else:
        logger.error(cnf + ' do not esixts')
        sys.exit(1)

设置my.cnf
def mycnfCreate(mybashfile, mysqlport):
    cnf = '/etc/my.cnf'
    cmd = "/bin/bash  %s" % mybashfile
    p = Popen(shlex.split(cmd), stdout=PIPE, stderr=PIPE)
    p.communicate()
    p.returncode
    f1 = open(cnf, "r", )
    f2 = open("%s.bak" % cnf, "w", )
    for line in f1:
        f2.write(re.sub(r'3306', mysqlport, line, count=1))
    f1.close()
    f2.close()
    os.remove(cnf)
    os.rename("%s.bak" % cnf, cnf)

设置启动脚本
def modifyStartupscript(port):
    isdatadirfind = 0
    isbasedirfind = 0
    f1 = open(MYSQL_STARTUP_SCRIPT, "r", )
    f2 = open("%s.bak" % MYSQL_STARTUP_SCRIPT, "w", )
    for line in f1:
        if line.startswith('datadir=') and not isdatadirfind:
            f2.write(line.replace('datadir=', 'datadir=/data/mysql/mysql%s/data' % port, 1))
            isdatadirfind = 1
        elif line.startswith('basedir=') and not isbasedirfind:
            f2.write(line.replace('basedir=', 'basedir=/usr/local/mysql', 1))
            isbasedirfind = 1
        else:
            f2.write(line)
    f1.close()
    f2.close()
    os.remove(MYSQL_STARTUP_SCRIPT)
    os.rename("%s.bak" % MYSQL_STARTUP_SCRIPT, MYSQL_STARTUP_SCRIPT)
    # 设置启动脚本执行权限
    stmode = os.stat(MYSQL_STARTUP_SCRIPT).st_mode
    os.chmod(MYSQL_STARTUP_SCRIPT, stmode | stat.S_IXOTH | stat.S_IXGRP | stat.S_IXUSR)

检查安装
def checkInstall(port):
    if not os.path.exists('/data/mysql/mysql%s/data/ibdata1' % port):
        logger.error('mysql not install ')
        sys.exit(1)
    with open('/data/mysql/mysql%s/logs/error.log' % port, 'r') as fd:
        fdlist = [i for i in fd if i]
        fdstr = ''.join(fdlist)
        re_error = re.compile(r'\s\[error\]\s', re.I | re.M)  # 匹配errorlog日志格式
        errorlist = re_error.findall(fdstr)

    if errorlist:
        logger.error('error.log error count:' + str(len(errorlist)))
        logger.error('mysql not install ')
        sys.exit(1)
    else:
        logger.info('install mysql  ok')

def mysqlserviceStart():
    cnf = '/etc/my.cnf'
    cmd = MYSQL_INSTALL_DIR+"bin/mysqld --defaults-file=%s &" %(cnf)
    p = Popen(cmd, stdout=PIPE, stderr=PIPE, shell=True)
    stdout, stderr = p.communicate()
    if stdout:
        logger.info('mysql startup output: %s' % (stdout))
    if stderr:
        logger.error('mysql startup error output: %s' % (stderr))

    if p.returncode == 0:
        logger.info('mysql startup completed')
        logger.info('mysql startup returncode: %s' % (p.returncode))
    else:
        logger.info('mysql startup failed , please check the mysql errror log')
        logger.info('mysql startup returncode: %s' % (p.returncode))
        sys.exit(1)
    time.sleep(4) # 休眠4秒 让mysql完全启动完毕

#连接mysql
def connMysql(mysqlport):
    cnf = '/etc/my.cnf'
    if os.path.exists(cnf):
        host = 'localhost'
        user = 'root'
        dbname = 'mysql'
        usocket = MYSQL_DATA_DIR+'mysql%s/tmp/mysql.sock' % (mysqlport)
        try:
            conn = MySQLdb.connect(host=host, user=user, db=dbname, unix_socket=usocket)
        except Exception, e:
            logger.error(e)
            sys.exit(1)
        cur = conn.cursor()
        return cur

#设置mysql的root的密码
def runSQL(mysqlport, mysqlpwd):
    sql = "alter user root@localhost identified  by '%s' " % (mysqlpwd)
    cur = connMysql(mysqlport)
    cur.execute(sql)

if __name__ == '__main__':
    init_log()

    options, args = opt()
    try:
        cmd = args[0]
    except IndexError:
        print "%s follow a command" % __file__
        print "%s -h" % __file__
        sys.exit(1)

    if (options.port and str.isdigit(options.port)) and (options.tarfile and os.path.isfile(options.tarfile)) and (
                options.myfile and os.path.isfile(options.myfile)) and (
            options.mysqlpwd):
        mysqlport = options.port
        mysqlfile = options.tarfile
        mybashfile = options.myfile
        mysqlpwd = options.mysqlpwd

    else:
        print "%s -h" % __file__
        sys.exit(1)

    if cmd == 'create':
        mycnfCreate(mybashfile, mysqlport)
        logger.info('step1:mycnfCreate completed')

        makeDIR(mysqlport)
        logger.info('step2:makeDIR completed')

        extract(mysqlfile)
        logger.info('step3:extract completed')

        copyFile(mysqlfile)
        logger.info('step4:copyFile completed')

        setOwner(mysqlport)
        logger.info('step5:setOwner completed')

        mysqlInstall()
        logger.info('step6:mysql_install completed')

        setEnv()
        logger.info('step7:setEnv completed')

        modifyStartupscript(mysqlport)
        logger.info('step8:modify_startupscript completed')

        checkInstall(mysqlport)
        logger.info('step9:checkInstall completed')

        mysqlserviceStart()
        logger.info('step10:mysqlserviceStart completed')

        runSQL(mysqlport, mysqlpwd)
        logger.info('step11:runSQL completed')

        print  'mysql install finish'

        # 调用示例
        # python /tmp/installmysql.py  -f /data/download/mysql-5.7.19-linux-glibc2.12-x86_64.tar.gz -P3306 -p123456 -b /tmp/createmycnf.sh  create

createmycnf.sh

如有不对的地方,欢迎大家拍砖o(∩_∩)o

本文版权归作者所有,未经作者同意不得转载。

Original: https://www.cnblogs.com/lyhabc/p/7859427.html
Author: 桦仔
Title: python自动安装mysql5.7

原创文章受到原创版权保护。转载请注明出处:https://www.johngo689.com/590821/

转载文章受原作者版权保护。转载请注明原作者出处!

(0)

大家都在看

  • 利用VBS循环弹窗

    VBScript是Visual Basic Script的简称,即 Visual Basic 脚本语言,有时也被缩写为VBS。 将以下代码复制到文本文档中,保存后修改文件后缀名称为…

    数据库 2023年6月11日
    0137
  • MySQL实战45讲 20

    20 | 幻读是什么,幻读有什么问题? 建表和初始化语句如下 CREATE TABLE t ( id int(11) NOT NULL, c int(11) DEFAULT NUL…

    数据库 2023年6月14日
    069
  • 什么是字节

    字节(byte):是计算机中数据处理的基本单位,用大写的B表示 Original: https://www.cnblogs.com/Icy01/p/16311502.htmlAut…

    数据库 2023年6月11日
    0124
  • 不扒瞎,这个程序让我从300s优化到了10s

    /*** RedisTemplate配置* @param lettuceConnectionFactory* @return*/ @Be…

    数据库 2023年6月9日
    065
  • 高可用 | Xenon 实现 MySQL 高可用架构 常用操作篇

    原创:知数堂 上一篇文章,我们详细介绍了 Xenon 实现 MySQL 高可用架构的部署过程。接下来本篇将介绍 Xenon 的常用操作,帮助大家在完成环境搭建之后,能把 Xenon…

    数据库 2023年5月24日
    0100
  • Python第二十一天 fileinput模块

    Python第二十一天 fileinput模块 fileinput模块 fileinput.input([files[, inplace[, backup[, bufsize[, …

    数据库 2023年6月9日
    087
  • JavaWeb核心篇(4)——Cookie和Session

    Java核心篇(4)——Cookie和Session 本篇文章将会简单介绍Cookie和Session的概念和用法 会话跟踪技术 首先我们需要搞清楚会话和会话跟踪的概念: 会话:用…

    数据库 2023年6月14日
    0125
  • MySQL——基础查询与条件查询

    基础查询 /* 语法: select 查询列表 from 表名; 类似于:System.out.println(打印东西); 1、查询列表可以是:表中的字段、常量值、表达式、函数 …

    数据库 2023年5月24日
    0113
  • mysql常用语句 4 + mysql的约束(非空,唯一,主键,外键)

    1.更新语句update dept1 set loc = ‘wz’,dname = ‘xueshenghui’ where dept…

    数据库 2023年5月24日
    085
  • MySQL慢查询优化问题-解决办法

    根据发现的问题,找出原因,然后对症下药。 [En] According to the problems found, find the cause, and then prescr…

    数据库 2023年5月24日
    097
  • 2022蓝帽杯初赛wp(取证)

    战果 取证全解 misc出了1个 解其他题就像在坐牢 有那么一点思路,但不是完全有 手机取证_1 解压并打开阅读器,搜索627604C2-C586-48C1-AA16-FF33C3…

    数据库 2023年6月11日
    0102
  • 使用clipboard.js复制文字+图片到微信后图片不显示问题处理

    使用clipboard.js复制文字 +图片,粘贴到微信不显示图片,而QQ可以。 解决方案: 图片链接使用http,不要使用https。 使用clipboard.js实现复制功能 …

    数据库 2023年6月14日
    0112
  • 9.回文数

    给你一个整数 x ,如果 x 是一个回文整数,返回 true ;否则,返回 false 。 回文数是指正序(从左向右)和倒序(从右向左)读都是一样的整数。 例如,121 是回文,而…

    数据库 2023年6月16日
    069
  • 力扣leetcode刷题记录1—-

    【以下题目来源均来自力扣leetcode】 World 表: 【描述】name 是这张表的主键。这张表的每一行提供:国家名称、所属大陆、面积、人口和 GDP 值。 【问题】如果一个…

    数据库 2023年6月16日
    089
  • Markdown语法浅学

    typora语法使用 1.字体 *斜体*,_斜体_ **粗体** ***加粗斜体*** ~~删除线~~ 下划线 ***分割线 , — 2.标题 一级标题 ## 二级标题 ###…

    数据库 2023年6月11日
    096
  • 有趣的BUG之Stack Overflow

    今天遇到一个很有意思的bug,当程序开发完成后打包到服务器运行,总是会出现栈溢出异常,经过排查发现,问题出现在一个接口上,但这个接口逻辑并不复杂,除了几局逻辑代码外和打印语句之外也…

    数据库 2023年6月6日
    090
亲爱的 Coder【最近整理,可免费获取】👉 最新必读书单  | 👏 面试题下载  | 🌎 免费的AI知识星球