导航

mysql自动化安装脚本(二进制安装)

Posted on 2018-07-19 16:48  张鑫的园子  阅读(1591)  评论(0编辑  收藏  举报

为了日后安装数据库方便,遂写了一个自动安装MySQL的脚本:

测试可以安装mariadb和MySQL-5.7.X

安装前配置好对应的my.cnf文件放在/tmp路径下

将启动脚本mysql3306放在/usr/local/下

将安装包放在/usr/local路径下

安装方式为:./install_mysql.sh mysql-5.7.20 3306  # 第一个参数为数据库版本(格式统一),第二个参数为端口号,两个参数都可以根据自己情况修改

数据库启动/关闭为:service mysql3306 start/stop/restart/status

下面分别为安装脚本install_mysql.sh、启动脚本mysql3306、配置文件my.cnf

 

#!/bin/bash
############ Install MySQL############

export LANG=C
export LC_ALL=C                  #Set the LANG and all environment variable beginning with LC_ to C
typeset -r version=$1
typeset -r port=$2

# DEFINED VAR START
typeset -r softwaredir="/usr/local"
typeset -r basedir="/usr/local/mysql" #input version of server
typeset -r databasedir="/data/${port}"
typeset -r datadir="${databasedir}/data"
typeset -r logdir="${databasedir}/log"
typeset -r mysqluser="mysql"
typeset -r defaults_file="${databasedir}/my.cnf"
typeset -r mysqldautostartfile="/etc/rc.d/init.d/mysql${port}"
typeset -r pidfile="${databasedir}/mysql.pid"
typeset -r socketlink="${databasedir}/mysql.sock"
typeset timestamp=''
typeset sInsDir_G=''
typeset sLogDir_G=''
typeset sLog_G=''

#DEFINED ENV START
export PATH=/sbin:/usr/sbin:/usr/local/sbin:/usr/local/bin:/usr/bin:/bin:$PATH
#DEFINED ENV END

## -------------------- init global vars -------------------
sInsDir_G=$( echo $(basename $0) | awk -F. '{print $1}' )
if [ -z "${sLog_G}" ]; then
  sLog_G="/backup/SysMgtScripts/Log/${sInsDir_G}/$( hostname ).log"
fi
if [ -z "${sLogDir_G}" ]; then
  sLogDir_G=${sLog_G%/*}
fi
if [ ! -d ${sLogDir_G} ]; then
  mkdir -p ${sLogDir_G}
fi
## ---------------------------------------------------------

export sLog_G
export sLogDir_G

## ensure the directory structure exists
BASEDIR="/backup/SysMgtScripts/"
if [ ! -d $BASEDIR ]; then
  mkdir -p ${BASEDIR}/Log
fi


## -------------------- colourful print --------------------
rMsg ()   { echo -e "\033[031;1m$@\033[0m"; }
gMsg ()   { echo -e "\033[032;1m$@\033[0m"; }
yMsg ()   { echo -e "\033[033;1m$@\033[0m"; }

## normal message print and log
LogMsg()
{
    local timestamp=$( date '+%F %T' )
    gMsg "[${timestamp}]: $*"
    printf "[%s]:%s\n" "${timestamp}" "$*" >> "${sLog_G}"
}

# warning
Warn()
{
    local timestamp=$( date '+%F %T' )
    yMsg "[${timestamp}]: $*"
    printf "[%s]:%s\n" "${timestamp}" "$*" >> "${sLog_G}"
}

# error 
Error()
{
    local retval=$?
    local timestamp=$( date '+%F %T' )
    rMsg "[${timestamp}]: $*"
    printf "[%s]:%s\n" "${timestamp}" "$*" >> "${sLog_G}"
    exit $?
}

#Check mysql user exit or not.
CheckUser(){
  cat /etc/passwd |grep mysql &>/dev/null
  if [ $? -ne 0 ];then
    Warn "user ${mysqluser} not exist"
    useradd ${mysqluser} || Error "Create MySQL user Failed"
  else 
    LogMsg "user ${mysqluser} exist"
  fi
}

#Create dir for database
InitDirs(){
  list="${databasedir} ${datadir} ${logdir}"
  for i in $list;
  do
    if  [ ! -d $i ];then
      Warn "Missing directory $i "
      mkdir -p $i || Error "Fail to create directory $i"
      LogMsg "$i create successfully"
    fi

    Test_Owner_T=`ls -l -d $i |awk '{print $3}'`
    if [[ "${Test_Owner_T}" != "${mysqluser}" ]];then
      chown -R ${mysqluser}:${mysqluser} $i || Error "Fail to change the directory owner"
    fi
  done
}

InitEnv(){
  bashrc="/etc/profile"
  Test_Env_T=`cat ${bashrc} |grep "${basedir}"`
  if [[ "${Test_Env_T}" != "" ]];then
    LogMsg "${basedir} is already exists in ${bashrc}"
  else
    MYSQL_HOME=${basedir}
    echo "MYSQL_HOME=${basedir}" >> ${bashrc} || Error "Fail to init environment"
    echo "export PATH=\$PATH:${MYSQL_HOME}/bin" >> ${bashrc}
    LogMsg "Add MYSQL_HOME to /etc/profile"
  fi
  source /etc/profile
}

SetMycnf(){
  cp /tmp/my.cnf ${defaults_file} || Error "Fail to create my.cnf"

  if [[ ! -f "/etc/my.cnf" ]];then
    LogMsg "The Parameter File is OK"
  else
    mv /etc/my.cnf /etc/my.cnf.bak
    LogMsg "removed /etc/my.cnf to /etc/my.cnf.bak"
  fi
}


UnzipPackages() {
  Mysql_Package=`find ${softwaredir} -name ${version}*.tar.gz`
  if [[ ! -f ${Mysql_Package} ]];then
    Error "MySQL Install Package is not found"
  else
    Mysql_File=`find ${softwaredir} -name ${version}*.tar.gz -exec basename {} .tar.gz \;`
    if [[ ! -d "/usr/local/${Mysql_File}" ]];then
      LogMsg "unzip MySQL Install Package"
      tar xf ${Mysql_Package} -C ${softwaredir} || Error "Fail to unzip the Package"
    else
      LogMsg "No need to unzip"
    fi
  fi
}
  
InstallMysql(){
  reallinkname=${basedir}
  Mysql_File=`find ${softwaredir} -name ${version}*.tar.gz -exec basename {} .tar.gz \;`
  if [[ ! -d ${Mysql_File} ]];then
    LogMsg "It is unziping mysql install Package ..."
    UnzipPackages
    LogMsg "unzip successful"
  fi
  cd ${softwaredir}
  if [[ ! -d ${basedir} ]];then
    ln -s ${Mysql_File} ${reallinkname}
    chown -R ${mysqluser}:${mysqluser} ${reallinkname}
  fi
  cd ${reallinkname}
  result=$(echo ${version}|grep mariadb)
  if [[ "$result" != "" ]];then
    LogMsg "Install $version..."
    ./scripts/mysql_install_db --defaults-file=${defaults_file} >>/dev/null || Error "Fail to init MySQL"
  else
    LogMsg "Install $version..."
    bin/mysqld --defaults-file=${defaults_file} --user=mysql --initialize-insecure --datadir=${datadir} --basedir=${basedir} >>/dev/null || Error "Fail to init MySQL"
    bin/mysql_ssl_rsa_setup --datadir=${datadir}>>/dev/null
    sleep 2
  fi
}

MakeScript(){
  if [[ ! -f /usr/local/mysql3306 ]];then
    Error "start script file mysql3306 not found"
  else
    chmod u+x /usr/local/mysql3306
    cp ${softwaredir}/mysql3306  ${mysqldautostartfile}
    sed -i "0,/^basedir=/s@basedir=@basedir=${basedir}@" ${mysqldautostartfile}
    sed -i "0,/^datadir=/s@datadir=@datadir=${databasedir}@" ${mysqldautostartfile}
  fi
}

#start script
StartMySQL(){
  service mysql${port} start || Error "MySQL start Failed"
}

# change mysql password
ChangePassword(){
  mysql -S /data/${port}/mysql.sock -e "set password for root@localhost = password('123456');" || Error "Change root password Failed"
  mysql -S /data/${port}/mysql.sock -uroot -p123456 -e "grant all privileges on *.* to root@'%' identified by '123456' with grant option;"
}


TaskMain(){
  LogMsg "It is checking whether the mysqluser ready or not ..."
  CheckUser
  LogMsg "The mysqluser is ready"

  LogMsg "It is initiazating directories ..."
  InitDirs
  LogMsg "The directories initiazating successful"

  LogMsg "It is initiazating environment variables ..."
  InitEnv
  LogMsg "The environment variables initiazating successful"

  LogMsg "It is setting default files ..."
  SetMycnf
  LogMsg "The default files set successful"

  LogMsg "It is installing mysql database ..."
  InstallMysql
  LogMsg "the mysql database install successful"
  
  LogMsg "It is making mysql start script ..."
  MakeScript
  LogMsg "make script successful"
  
  LogMsg "It is starting mysql ..."
  StartMySQL
  LogMsg "successful"
  
  LogMsg "It is changing mysql password ..."
  ChangePassword
  LogMsg "change successful"

  LogMsg "The mysql service set successful"
}

# The execution body of the script
LogMsg "============Start Install MySQL============"
TaskMain $@;rc=$?
if [ ${rc} -ne 0 ] ;then
  Error '[ERROR] Failed to install mysql.'
else
  LogMsg '[INFO] Completed install mysql.'
fi
LogMsg "The script execution ends."
exit ${rc}

 

启动脚本:

#!/bin/sh
# Copyright Abandoned 1996 TCX DataKonsult AB & Monty Program KB & Detron HB
# This file is public domain and comes with NO WARRANTY of any kind

# MySQL daemon start/stop script.

# Usually this is put in /etc/init.d (at least on machines SYSV R4 based
# systems) and linked to /etc/rc3.d/S99mysql and /etc/rc0.d/K01mysql.
# When this is done the mysql server will be started when the machine is
# started and shut down when the systems goes down.

# Comments to support chkconfig on RedHat Linux
# chkconfig: 2345 64 36
# description: A very fast and reliable SQL database engine.

# Comments to support LSB init script conventions
### BEGIN INIT INFO
# Provides: mysql
# Required-Start: $local_fs $network $remote_fs
# Should-Start: ypbind nscd ldap ntpd xntpd
# Required-Stop: $local_fs $network $remote_fs
# Default-Start:  2 3 4 5
# Default-Stop: 0 1 6
# Short-Description: start and stop MySQL
# Description: MySQL is a very fast and reliable SQL database engine.
### END INIT INFO
 
# If you install MySQL on some other places than /usr/local/mysql, then you
# have to do one of the following things for this script to work:
#
# - Run this script from within the MySQL installation directory
# - Create a /etc/my.cnf file with the following information:
#   [mysqld]
#   basedir=/usr/local/mysql<path-to-mysql-installation-directory>
# - Add the above to any other configuration file (for example ~/.my.ini)
#   and copy my_print_defaults to /usr/bin
# - Add the path to the mysql-installation-directory to the basedir variable
#   below.
#
# If you want to affect other MySQL variables, you should make your changes
# in the /etc/my.cnf, ~/.my.cnf or other MySQL configuration files.

# If you change base dir, you must also change datadir. These may get
# overwritten by settings in the MySQL configuration files.

basedir=
datadir=

# Default value, in seconds, afterwhich the script should timeout waiting
# for server start. 
# Value here is overriden by value in my.cnf. 
# 0 means don't wait at all
# Negative numbers mean to wait indefinitely
service_startup_timeout=900

# Lock directory for RedHat / SuSE.
lockdir='/var/lock/subsys'
lock_file_path="$lockdir/mysql"

# The following variables are only set for letting mysql.server find things.

# Set some defaults
mysqld_pid_file_path=
if test -z "$basedir"
then
  basedir=/usr/local/mysql
  bindir=/usr/local/mysql/bin
  if test -z "$datadir"
  then
    datadir=/usr/local/mysql/data
  fi
  sbindir=/usr/local/mysql/bin
  libexecdir=/usr/local/mysql/bin
else
  bindir="$basedir/bin"
  if test -z "$datadir"
  then
    datadir="$basedir/data"
  fi
  sbindir="$basedir/sbin"
  libexecdir="$basedir/libexec"
fi

# datadir_set is used to determine if datadir was set (and so should be
# *not* set inside of the --basedir= handler.)
datadir_set=

#
# Use LSB init script functions for printing messages, if possible
#
lsb_functions="/lib/lsb/init-functions"
if test -f $lsb_functions ; then
  . $lsb_functions
else
  log_success_msg()
  {
    echo " SUCCESS! $@"
  }
  log_failure_msg()
  {
    echo " ERROR! $@"
  }
fi

PATH="/sbin:/usr/sbin:/bin:/usr/bin:$basedir/bin"
export PATH

mode=$1    # start or stop

[ $# -ge 1 ] && shift


other_args="$*"   # uncommon, but needed when called from an RPM upgrade action
           # Expected: "--skip-networking --skip-grant-tables"
           # They are not checked here, intentionally, as it is the resposibility
           # of the "spec" file author to give correct arguments only.

case `echo "testing\c"`,`echo -n testing` in
    *c*,-n*) echo_n=   echo_c=     ;;
    *c*,*)   echo_n=-n echo_c=     ;;
    *)       echo_n=   echo_c='\c' ;;
esac

parse_server_arguments() {
  for arg do
    case "$arg" in
      --basedir=*)  basedir=`echo "$arg" | sed -e 's/^[^=]*=//'`
                    bindir="$basedir/bin"
                    if test -z "$datadir_set"; then
                      datadir="$basedir/data"
                    fi
                    sbindir="$basedir/sbin"
                    libexecdir="$basedir/libexec"
        ;;
      --datadir=*)  datadir=`echo "$arg" | sed -e 's/^[^=]*=//'`
                    datadir_set=1
        ;;
      --pid-file=*) mysqld_pid_file_path=`echo "$arg" | sed -e 's/^[^=]*=//'` ;;
      --service-startup-timeout=*) service_startup_timeout=`echo "$arg" | sed -e 's/^[^=]*=//'` ;;
    esac
  done
}

wait_for_pid () {
  verb="$1"           # created | removed
  pid="$2"            # process ID of the program operating on the pid-file
  pid_file_path="$3" # path to the PID file.

  i=0
  avoid_race_condition="by checking again"

  while test $i -ne $service_startup_timeout ; do

    case "$verb" in
      'created')
        # wait for a PID-file to pop into existence.
        test -s "$pid_file_path" && i='' && break
        ;;
      'removed')
        # wait for this PID-file to disappear
        test ! -s "$pid_file_path" && i='' && break
        ;;
      *)
        echo "wait_for_pid () usage: wait_for_pid created|removed pid pid_file_path"
        exit 1
        ;;
    esac

    # if server isn't running, then pid-file will never be updated
    if test -n "$pid"; then
      if kill -0 "$pid" 2>/dev/null; then
        :  # the server still runs
      else
        # The server may have exited between the last pid-file check and now.  
        if test -n "$avoid_race_condition"; then
          avoid_race_condition=""
          continue  # Check again.
        fi

        # there's nothing that will affect the file.
        log_failure_msg "The server quit without updating PID file ($pid_file_path)."
        return 1  # not waiting any more.
      fi
    fi

    echo $echo_n ".$echo_c"
    i=`expr $i + 1`
    sleep 1

  done

  if test -z "$i" ; then
    log_success_msg
    return 0
  else
    log_failure_msg
    return 1
  fi
}

# Get arguments from the my.cnf file,
# the only group, which is read from now on is [mysqld]
if test -x "$bindir/my_print_defaults";  then
  print_defaults="$bindir/my_print_defaults"
else
  # Try to find basedir in /etc/my.cnf
  conf=/etc/my.cnf
  print_defaults=
  if test -r $conf
  then
    subpat='^[^=]*basedir[^=]*=\(.*\)$'
    dirs=`sed -e "/$subpat/!d" -e 's//\1/' $conf`
    for d in $dirs
    do
      d=`echo $d | sed -e 's/[  ]//g'`
      if test -x "$d/bin/my_print_defaults"
      then
        print_defaults="$d/bin/my_print_defaults"
        break
      fi
    done
  fi

  # Hope it's in the PATH ... but I doubt it
  test -z "$print_defaults" && print_defaults="my_print_defaults"
fi

#
# Read defaults file from 'basedir'.   If there is no defaults file there
# check if it's in the old (depricated) place (datadir) and read it from there
#

extra_args=""
if test -r "$basedir/my.cnf"
then
  extra_args="-e $basedir/my.cnf"
fi

parse_server_arguments `$print_defaults $extra_args mysqld server mysql_server mysql.server`

#
# Set pid file if not given
#
if test -z "$mysqld_pid_file_path"
then
  mysqld_pid_file_path=$datadir/`hostname`.pid
else
  case "$mysqld_pid_file_path" in
    /* ) ;;
    * )  mysqld_pid_file_path="$datadir/$mysqld_pid_file_path" ;;
  esac
fi

case "$mode" in
  'start')
    # Start daemon

    # Safeguard (relative paths, core dumps..)
    cd $basedir

    echo $echo_n "Starting MySQL"
    if test -x $bindir/mysqld_safe
    then
      # Give extra arguments to mysqld with the my.cnf file. This script
      # may be overwritten at next upgrade.
      $bindir/mysqld_safe --defaults-file="$datadir/my.cnf" --pid-file="$mysqld_pid_file_path" $other_args >/dev/null &
      wait_for_pid created "$!" "$mysqld_pid_file_path"; return_value=$?

      # Make lock for RedHat / SuSE
      if test -w "$lockdir"
      then
        touch "$lock_file_path"
      fi

      exit $return_value
    else
      log_failure_msg "Couldn't find MySQL server ($bindir/mysqld_safe)"
    fi
    ;;

  'stop')
    # Stop daemon. We use a signal here to avoid having to know the
    # root password.

    if test -s "$mysqld_pid_file_path"
    then
      # signal mysqld_safe that it needs to stop
      touch "$mysqld_pid_file_path.shutdown"

      mysqld_pid=`cat "$mysqld_pid_file_path"`

      if (kill -0 $mysqld_pid 2>/dev/null)
      then
        echo $echo_n "Shutting down MySQL"
        kill $mysqld_pid
        # mysqld should remove the pid file when it exits, so wait for it.
        wait_for_pid removed "$mysqld_pid" "$mysqld_pid_file_path"; return_value=$?
      else
        log_failure_msg "MySQL server process #$mysqld_pid is not running!"
        rm "$mysqld_pid_file_path"
      fi

      # Delete lock for RedHat / SuSE
      if test -f "$lock_file_path"
      then
        rm -f "$lock_file_path"
      fi
      exit $return_value
    else
      log_failure_msg "MySQL server PID file could not be found!"
    fi
    ;;

  'restart')
    # Stop the service and regardless of whether it was
    # running or not, start it again.
    if $0 stop  $other_args; then
      $0 start $other_args
    else
      log_failure_msg "Failed to stop running server, so refusing to try to start."
      exit 1
    fi
    ;;

  'reload'|'force-reload')
    if test -s "$mysqld_pid_file_path" ; then
      read mysqld_pid <  "$mysqld_pid_file_path"
      kill -HUP $mysqld_pid && log_success_msg "Reloading service MySQL"
      touch "$mysqld_pid_file_path"
    else
      log_failure_msg "MySQL PID file could not be found!"
      exit 1
    fi
    ;;
  'status')
    # First, check to see if pid file exists
    if test -s "$mysqld_pid_file_path" ; then 
      read mysqld_pid < "$mysqld_pid_file_path"
      if kill -0 $mysqld_pid 2>/dev/null ; then 
        log_success_msg "MySQL running ($mysqld_pid)"
        exit 0
      else
        log_failure_msg "MySQL is not running, but PID file exists"
        exit 1
      fi
    else
      # Try to find appropriate mysqld process
      mysqld_pid=`pidof $libexecdir/mysqld`

      # test if multiple pids exist
      pid_count=`echo $mysqld_pid | wc -w`
      if test $pid_count -gt 1 ; then
        log_failure_msg "Multiple MySQL running but PID file could not be found ($mysqld_pid)"
        exit 5
      elif test -z $mysqld_pid ; then 
        if test -f "$lock_file_path" ; then 
          log_failure_msg "MySQL is not running, but lock file ($lock_file_path) exists"
          exit 2
        fi 
        log_failure_msg "MySQL is not running"
        exit 3
      else
        log_failure_msg "MySQL is running but PID file could not be found"
        exit 4
      fi
    fi
    ;;
    *)
      # usage
      basename=`basename "$0"`
      echo "Usage: $basename  {start|stop|restart|reload|force-reload|status}  [ MySQL server options ]"
      exit 1
    ;;
esac

exit 0

配置文件:

[client]
port = 3306
socket = /data/3306/mysql.sock

[mysqld]
port = 3306
socket = /data/3306/mysql.sock
user = mysql
server_id = 5
character-set-server = utf8
default-storage-engine = innodb
pid-file = /data/3306/mysql.pid
datadir = /data/3306/data
basedir = /usr/local/mysql
lower_case_table_names = 1
interactive_timeout = 7200
local_infile = 1
max-connections = 1500
back_log = 500
max_connect_errors = 2000
open_files_limit = 20000
table_definition_cache = 20000
innodb_buffer_pool_size = 1G
log_bin = /data/3306/data/mysql-bin
slow_query_log_file = /data/3306/log/slowlog.log
log_error = /data/3306/log/mysql-error.log
relay_log = /data/3306/log/mysql-relay
innodb_autoextend_increment = 128
innodb_file_per_table = 1
innodb_open_files = 20000
innodb-log-files-in-group = 4
innodb_log_file_size = 200M
innodb_rollback_on_timeout = 1
innodb_lock_wait_timeout = 30
innodb_sort_buffer_size = 4M
innodb_log_buffer_size = 32M
innodb_read_io_threads = 16
innodb_write_io_threads = 16
join_buffer_size = 262144
tmp_table_size = 64M
max_heap_table_size = 64M
read_buffer_size = 131072
read_rnd_buffer_size = 262144
binlog_format = row
binlog_cache_size = 1048576
long_query_time = 6
slow_query_log = 1
master_verify_checksum = 1
slave_sql_verify_checksum = 1
relay_log_recovery = 1
relay_log_purge = 1
sync_binlog = 1
expire_logs_days = 7