Mysql DBA-安装

2025-05-27 15:09

MYSQL-DBA

MySQL简介

MySQL 相关产品介绍

  • Oracle MySQL Cloud Service (commercial)商业付费软件,基于 MySQL 企业版和 Oracle 云服务提供企业级的 MySQL 数据库服务

  • MySQL Enterprise Edition (commercial)商业付费软件,除了提供 MySQL 数据库服务之外,又包含了 connector (程序连接接口),partition (表分区),企业级的 monitor (监控),HA (高可用),backup (备份),Scalability (扩展) 等服务

  • MySQL Cluster CGE (commercial)商业付费软件,基于 MySQL Cluster 和企业版拥有的各项功能提供企业级的高并发、高吞吐的数据库服务

  • MySQL Community Edition免费社区软件,提供基础的数据库服务和其他衍生服务

MySQL 社区软件相关产品介绍

  • MySQL Community Server:MySQL社区服务器最流行的开源数据库管理软件

  • MySQL Cluster MySQL Cluster:基于 MySQL 数据库而实现的集群服务,自身能提供高并发高负载等特性

  • MySQL Fabric:MySQL Fabric MySQL 官方提供的关于 MySQL 数据库高可用和数据分片的解决方案

  • MySQL Connectors MySQL连接:为应用程序提供 JDBC/ODBC 等访问 MySQL 数据库的接口服务

mysql5.0之上各版本之间区别

MySQL 5.1(2008 年发布 )

  • 新增功能:增加了 Event scheduler(事件调度器,可定时执行任务 )、Partitioning(表分区功能,利于大数据量管理 )、Pluggable storage engine API(可插拔存储引擎 API,方便扩展存储引擎 ) 、Row - based replication(基于行的复制,改善复制性能 );支持 Global 级别动态修改 general query log 和 slow query log。

  • 存储引擎特性:类似增加崩溃恢复功能的 MyISAM,使用表级锁,能实现读写不冲突,即写操作时可读,但多个写操作不能并发 。

MySQL 5.5(2010 年 12 月发布 )

  • 存储引擎变更:默认存储引擎从 MyISAM 改为 InnoDB 。

  • 性能提升:提高默认线程并发数等参数控制 ;可处理高达 128K 的并发事务,改善事务处理中元数据锁定 ;增加删除缓冲和清除缓冲等 ;引入性能架构监控运行时性能。

  • 功能增强:支持半同步复制,提高数据复制安全性;增加与 InnoDB 压缩和事务处理锁定有关的 INFORMATION_SCHEMA 表 ;表和索引 RANG 和 LIST 分区范围扩展到非整数列和日期 ,且支持多列分区 。

MySQL 5.6(2013 年 2 月发布 )

  • InnoDB 改进:可限制大量表打开时内存占用过多问题 ;性能加强 ;死锁信息可记录到 error 日志 。

  • 复制功能优化:支持延时复制,便于特殊情况数据恢复 ;行级复制功能加强,降低资源开销 ;复制事件采用 crc32 校验,增强主从复制数据一致性 。

  • 其他增强:表分区功能进一步增强 ;新增 log_bin_basename ,方便监管 binlog 位置 。

MySQL 5.7(2015 年发布 )

  • 性能大幅提升:查询性能相比 5.6 提升约 1 倍 ,降低建立数据库连接时间 。

  • 安装程序改进:安装相关调整,如废弃 mysql_install_db ,使用 mysqld –initialize 替代 。

MySQL 8.0(后续版本 )

  • 性能提升:读写、I/O 密集型、高竞争等工作负载性能比 5.7 快 2 倍 。

  • 安全性增强:增加隐藏用户密码、强密码策略、加密密码传输、更好身份验证等功能 。

  • 数据类型扩充:添加更多数据类型,满足现代应用对非结构化数据存储和操作需求 。

  • 管理功能丰富:提供更好的管理监控、健康监测、性能优化、复制、备份恢复、分区等选项 。

  • 集成优化:具备更好的 MySQL Router 选项以及连接命令 。

MySQL 各版本的发布时间线

  • 1995 年:MySQL 1.0 发布(仅供内部使用 )。

  • 1996 年:MySQL 3.11.1 发布 ,直接跳过了 MySQL 2.x 版本 。

  • 1999 年:MySQL AB 公司成立 ;同年发布 MySQL 3.23,该版本集成了 Berkeley DB 存储引擎。

  • 2000 年:ISAM 升级为 MyISAM 存储引擎 ;同年,MySQL 基于 GPL 协议开放源码。

  • 2002 年:MySQL 4.0 发布,集成了 InnoDB 存储引擎。

  • 2005 年:MySQL 5.0 发布 ,开始支持游标、存储过程、触发器、视图、XA 事务等特性。

  • 2008 年:Sun 以 10 亿美金收购 MySQL AB ;同年,发布 MySQL 5.1 ,开始支持定时器(Event scheduler)、分区、基于行的复制等特性 。

  • 2010 年:MySQL 5.5 发布 ,InnoDB 成为默认的存储引擎 。

  • 2013 年:MySQL 5.6 发布 ,支持全局事务等 。

  • 2015 年:MySQL 5.7 发布 ,提升性能,支持 CTE(通用表表达式)、窗口函数、JSON 支持、Instant DDL(即时数据定义语言操作)等现代化功能 。

  • 2016 年:MySQL 8.0.0 版本发布 。

  • 2018 年:MySQL 8.0 正式发布,引入诸多新特性 。

  • 2020 年:MySQL HeatWave 推出 ,支持内存加速和机器学习功能 。

  • 2024 年:发布 MySQL 8.4 LTS(长期支持版)和 9.0 。

操作系统与 MySQL 版本适配度

操作系统

系统版本

MySQL 5.6

MySQL 5.7

MySQL 8.0

MySQL 9.0

Windows 窗户

Windows 7


Windows 8 及以上


Windows 10 及以上

Linux

Debian/Ubuntu 系列

✔(最高适配到 Ubuntu 17.04 )

✔(最高适配到 Ubuntu 18.04 )


RedHat/CentOS 系列

macOS 操作系统

-

MySQL文档

https://dev.mysql.com/doc/

image.png

MySQL安装

MySQL8+Linux为例

二进制安装(RPM、ZIP、Tar)

https://dev.mysql.com/downloads/repo/yum/

https://dev.mysql.com/doc/mysql-apt-repo-quick-guide/en/

请参考以上网站

源码安装

参考官网文档

二进制解压安装

下载

mysql-8.0.14-linux-glibc2.12-x86_64.tar.xz

image-20250526122909519

解压

mysql-8.0.14-linux-glibc2.12-x86_64.tar.xz

image.png

mysql8.0的目录结构

image.png

  • bin:存放 MySQL 的可执行文件,如mysqld(服务器守护进程 )、mysql(命令行客户端 )等,用于启动服务器、执行 SQL 语句等操作。

  • docs:存储 MySQL 相关的文档资料,如用户手册、技术参考等,方便用户查阅了解 MySQL 功能特性、使用方法和技术细节。

  • etc:一般放置 MySQL 的配置文件,如my.cnfmy.ini(Windows 系统 ),用于配置 MySQL 服务器的参数,像连接设置、缓存大小、字符集等,决定 MySQL 的运行方式和性能表现。

  • include:包含供开发人员使用的头文件,在进行 MySQL 相关的 C/C++ 等语言开发时,这些头文件用于声明函数、数据结构等,方便与 MySQL 进行交互开发 。

  • lib:存放 MySQL 的库文件,是 MySQL 运行过程中依赖的一些库,如存储引擎相关库等,为 MySQL 提供底层功能支持。

  • man:存储 MySQL 的手册页文件,在 Linux 系统下,通过man命令可以查看相关手册,获取 MySQL 命令和工具的使用说明。

  • share:包含一些共享资源文件,如错误消息文件、字符集文件等 ,用于在 MySQL 运行过程中提供错误提示、字符编码转换等功能。

  • support - files:提供一些辅助文件,如初始化脚本、配置文件模板等 ,可用于初始化数据库、设置配置文件等操作,帮助用户更方便地部署和管理 MySQL。

配置安装

1、创建mysql用户和组(以mysql用户启动)

groupadd mysql
useradd mysql -g mysql

2、创建data目录

mkdir /usr/local/mysql/data

3、修改解压包权限

 chown –R mysql mysql解压目录
 chgrp –R mysql mysql解压目录

4、安装mysql

bin/mysqld --initialize --user=mysql --datadir /usr/local/mysql/data ## 初始化数据目录
cp -f support-files/my-default.cnf/etc/my.cnf ## 将默认配置文件复制到指定目录
bin/mysqld_safe --datadir=/usr/local/mysql/data --user=mysql & ## 启动 MySQL 服务
cp support-files/mysql.server/etc/init.d/mysql.server ## 将 MySQL 加入到服务自启动
/etc/init.d/mysql.server start ##启动mysql服务

5、开启防火墙端口

firewall-cmd --permanent --add-port=3306/tcp
firewall-cmd --reload

6、设置环境变量

vi ~/.bash_profile
####
PATH=$PATH:$HOME/bin:/usr/local/mysql/bin
解析support-files里文件

image.png

  • magic:是一个用于文件类型识别的文件。它包含了一些规则和模式,file命令等工具可以借助它来判断文件的类型,比如判断某个文件是文本文件、二进制文件,还是与 MySQL 相关的特定格式文件等,在系统对文件进行分类和处理时起到辅助识别作用 。

  • mysql - log - rotate:是用于 MySQL 日志轮转的脚本。日志轮转是指定期将旧的日志文件进行归档(如重命名、压缩等 ),并创建新的日志文件继续记录日志。通过这个脚本,可以实现 MySQL 日志文件的自动管理,避免日志文件过大占用过多磁盘空间,同时方便对历史日志进行保存和后续分析 。

  • mysql.server :是 MySQL 服务的启动脚本。它可以用来启动、停止、重启 MySQL 服务。在系统启动时,若要让 MySQL 自动启动,通常会配置该脚本。它会检查 MySQL 相关的配置,初始化必要的环境,然后调用mysqld等程序来启动 MySQL 服务器 。

  • mysqld_multi.server :用于管理多个 MySQL 服务器实例的脚本。当系统中运行着多个不同配置、不同端口等的 MySQL 实例时,可通过这个脚本来统一管理它们的启动、停止、重启等操作,方便在多实例环境下对 MySQL 进行运维管理 。

magic
#
# Add the following to the end of your /etc/magic file to get the 'file'
# command to recognize some MySQL files.
#
0       beshort           0xfe01        MySQL table definition file
>2      byte            x               Version %d
0       belong&0xffffff00 0xfefe0300    MySQL MISAM index file
>3      byte            x               Version %d
0       belong&0xffffff00 0xfefe0700    MySQL MISAM compressed data file
>3      byte            x               Version %d
0       belong&0xffffff00 0xfefe0500    MySQL ISAM index file
>3      byte            x               Version %d
0       belong&0xffffff00 0xfefe0600    MySQL ISAM compressed data file
>3      byte            x               Version %d
0       string           \376bin        MySQL replication log

该文件是用于扩展系统中**/etc/magic文件的规则。/etc/magic**文件是用于文件类型识别的配置文件,file命令会依据其中定义的规则来判断文件类型。将这段内容添加到/etc/magic文件末尾后,file命令就能识别特定的 MySQL 相关文件类型。

具体规则解析

  1. MySQL 表定义文件识别

 0 beshort 0xfe01 MySQL table definition file

0:表示从文件起始位置开始检查。

**beshort:**这是一种数据匹配类型,用于匹配 2 字节的短整数(big - endian 格式,即大端序 )。

0xfe01:是期望匹配到的具体 2 字节数值。当文件起始位置的 2 字节内容为0xfe01时,file命令就会将该文件识别为MySQL table definition file(MySQL 表定义文件 )。

2. MySQL MISAM 索引文件识别

 0 belong&0xffffff00 0xfefe0300 MySQL MISAM index file

0:从文件起始位置开始。

**belong&0xffffff00:**belong用于匹配 4 字节整数,&0xffffff00表示对匹配到的 4 字节整数进行按位与操作,屏蔽掉后 8 位 。

0xfefe0300:是经过上述按位与操作后期望匹配到的数值。若匹配成功,文件会被识别为MySQL MISAM index file(MySQL MISAM 索引文件 )。

 >3 byte x Version %d

3:表示从文件第 4 个字节开始检查(偏移量为 3 )。

byte:匹配 1 字节数据。

x:表示匹配任意字节值。这里匹配到的字节值会用于后续格式化输出Version %d,用于显示文件版本信息。

3. MySQL MISAM 压缩数据文件识别

 0 belong&0xffffff00 0xfefe0700 MySQL MISAM compressed data file

原理同 MISAM 索引文件识别规则的起始部分。从文件起始位置开始,匹配经过按位与操作后值为0xfefe0700的 4 字节整数,匹配成功则识别为MySQL MISAM compressed data file`(MySQL MISAM 压缩数据文件 )。

3 byte x Version %d:同上述版本信息匹配规则,从第 4 个字节开始匹配任意 1 字节值用于显示版本。

4. MySQL ISAM 索引文件识别

0 belong&0xffffff00 0xfefe0500 MySQL ISAM index file

从文件起始位置开始,匹配经过按位与操作后值为0xfefe0500的 4 字节整数,匹配成功识别为MySQL ISAM index file(MySQL ISAM 索引文件 )。

3 byte x Version %d:同样是从第 4 个字节开始匹配版本信息相关字节。

5. MySQL ISAM 压缩数据文件识别

0 belong&0xffffff00 0xfefe0600 MySQL ISAM compressed data file

从文件起始位置开始,匹配经过按位与操作后值为0xfefe0600的 4 字节整数,匹配成功识别为MySQL ISAM compressed data file(MySQL ISAM 压缩数据文件 )。

3 byte x Version %d:从第 4 个字节开始匹配版本信息字节。

6. MySQL 复制日志文件识别

0 string \376bin MySQL replication log

0:从文件起始位置开始。

string:用于匹配字符串。\376bin:要匹配的具体字符串内容。当文件起始位置能匹配到\376bin这个字符串时,file命令会将该文件识别为MySQL replication log(MySQL 复制日志 )。

mysql-log-rotate
# Copyright (c) 2000, 2011, Oracle and/or its affiliates. All rights reserved.
# 
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License, version 2.0,
# as published by the Free Software Foundation.
#
# This program is also distributed with certain software (including
# but not limited to OpenSSL) that is licensed under separate terms,
# as designated in a particular file or component or in included license
# documentation.  The authors of MySQL hereby grant you an additional
# permission to link the program and your derivative works with the
# separately licensed software that they have included with MySQL.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
# GNU General Public License, version 2.0, for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program; if not, write to the Free Software
# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301  USA

# The log file name and location can be set in
# /etc/my.cnf by setting the "log-error" option
# in either [mysqld] or [mysqld_safe] section as
# follows:
#
# [mysqld]
# log-error=/usr/local/mysql/data/mysqld.log
#
# In case the root user has a password, then you
# have to create a /root/.my.cnf configuration file
# with the following content:
#
# [mysqladmin]
# password = <secret> 
# user= root
#
# where "<secret>" is the password. 
#
# ATTENTION: The /root/.my.cnf file should be readable
# _ONLY_ by root !

/usr/local/mysql/data/mysqld.log {
        # create 600 mysql mysql
        notifempty
        daily
        rotate 5
        missingok
        compress
    postrotate
	# just if mysqld is really running
	if test -x /usr/local/mysql/bin/mysqladmin && \
	   /usr/local/mysql/bin/mysqladmin ping &>/dev/null
	then
	   /usr/local/mysql/bin/mysqladmin flush-logs
	fi
    endscript
}

​ 这个脚本是一个 MySQL 日志轮转配置,用于管理 MySQL 错误日志文件。它通常被系统的日志轮转工具(如logrotate)使用,确保 MySQL 日志文件不会无限增长,同时保持服务的正常运行。

脚本结构与功能

脚本采用了logrotate配置文件的语法,主要包含以下部分:

  1. 文件路径

 /usr/local/mysql/data/mysqld.log {
     ...
 }

指定要轮转的日志文件路径。

2. 轮转策略配置

notifempty    # 当日志文件为空时不进行轮转
daily         # 每天进行一次日志轮转
rotate 5      # 保留最近5个日志文件,超出的会被删除
missingok     # 如果日志文件不存在,不报错继续执行
compress      # 轮转后的日志文件进行压缩
  1. 轮转后操作

 postrotate
     # 仅在MySQL服务器运行时执行
     if test -x /usr/local/mysql/bin/mysqladmin && \
        /usr/local/mysql/bin/mysqladmin ping &>/dev/null
     then
        /usr/local/mysql/bin/mysqladmin flush-logs
     fi
 endscript

这部分代码在日志轮转完成后执行,主要功能是:

​ 检查mysqladmin工具是否存在且可执行

​ 检查 MySQL 服务器是否正在运行(通过ping命令)

​ 如果 MySQL 服务器运行,则执行flush-logs命令,通知 MySQL 服务器开始写入新的日志文件

使用说明与注意事项

  1. 配置位置

    日志文件路径可在**/etc/my.cnf中通过log-error**选项设置

    示例配置:

   [mysqld]
   log-error=/usr/local/mysql/data/mysqld.log
  1. 认证设置

    如果 MySQL root 用户设置了密码,需要创建**/root/.my.cnf**文件

    该文件需包含:

   [mysqladmin]
   password = <secret>
   user = root

注意:此文件必须只能由 root 用户读取,否则 MySQL 会拒绝使用它

3. 安全提示

/root/.my.cnf文件权限应为600(只有所有者可读可写)

脚本默认配置每天轮转日志并保留 5 个历史文件,可根据实际需求调整

mysql.server
#!/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=<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 --datadir="$datadir" --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

mysql.server是 MySQL 的守护进程启动 / 停止脚本,通常放置在**/etc/init.d**目录,用于在系统启动和关闭时管理 MySQL 服务。以下是对该脚本的详细解析:


该脚本用于启动和停止 MySQL 守护进程,通常放置在**/etc/init.d**目录,并通过软链接到系统启动和关闭相关目录,实现开机自启和关机停止


支持chkconfig与LSB的注释

# 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

针对 RedHat Linux 的chkconfig注释,定义了服务在运行级别 2、3、4、5 启动,启动顺序为 64,停止顺序为 36 。


遵循 Linux Standard Base(LSB )初始化脚本规范的注释,声明了脚本提供的服务、启动依赖、停止依赖、默认启动和停止的运行级别等信息


配置文件与路径相关设置

# 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=<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=

说明如果 MySQL 安装在非/usr/local/mysql目录,需通过特定方式让脚本正常工作,如在安装目录运行脚本、在配置文件指定basedir路径等。


定义了basedir(MySQL 安装目录 )和datadir(MySQL 数据目录 )变量,初始为空。


服务启动超时设置

# 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

定义了服务启动等待超时时间为 900 秒,该值可被my.cnf中的设置覆盖

锁文件相关设置

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

定义了 RedHat 和 SuSE 系统下 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=

根据basedir是否设置,为bindir(可执行文件目录 )、datadirsbindir(系统二进制文件目录 )、libexecdir(可执行文件目录 )等变量设置默认值。

datadir_set用于标记datadir是否已设置。

引入LSB函数或自定义日志函数

#
# 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

尝试引入**/lib/lsb/init-functions**中的函数用于打印消息,如果文件不存在,则自定义成功和失败消息的打印函数。

环境变量设置

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

设置PATH环境变量,包含常用系统目录和 MySQL 可执行文件目录,方便脚本执行相关命令

命令行参数处理

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.

将第一个命令行参数赋值给mode,用于确定操作模式(启动、停止等 )。

处理其他命令行参数,在 RPM 升级操作时可能会用到,这里不做具体检查。

输出格式判断

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

判断系统中echo命令的输出格式,设置echo_necho_c变量,用于后续打印消息时控制格式。

解析服务器参数函数

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
}

定义parse_server_arguments函数,用于解析命令行中以**--basedir=--datadir=--pid-file=--service-startup-timeout=**开头的参数,并设置相应变量值。

等待 PID 文件状态函数

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
}

wait_for_pid函数用于等待 PID 文件达到指定状态(创建或删除 ),在等待过程中检查服务器进程状态,若超时则打印失败消息并返回相应状态码。

查找my_print_defaults工具

# 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

尝试查找my_print_defaults工具,优先在bindir目录下查找,若不存在则从**/etc/my.cnf配置文件中寻找basedir**,并在相应目录查找该工具,若仍未找到则尝试在PATH中查找。

读取额外配置文件参数

#
# 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`

尝试从basedir目录读取my.cnf配置文件,若存在则设置extra_args变量。然后调用parse_server_arguments函数解析从my_print_defaults工具获取的参数。

设置 PID 文件路径

#
# 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

如果未指定mysqld_pid_file_path,则根据datadir和主机名生成默认的 PID 文件路径;否则,若路径不是绝对路径,则将其转换为基于datadir的路径。

操作模式处理

启动模式(start)

'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 --datadir="$datadir" --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
    ;;

切换到basedir目录,打印启动消息。

检查mysqld_safe可执行文件是否存在,若存在则调用它启动 MySQL 服务器,并传递数据目录和 PID 文件路径等参数。

使用wait_for_pid函数等待 PID 文件创建,若成功则在锁文件目录创建锁文件,最后根据返回值退出脚本。

停止模式(stop)

'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
    ;;

检查 PID 文件是否存在,若存在则创建一个特殊文件告知mysqld_safe需要停止。

获取 PID 并尝试向进程发送信号,打印停止消息,使用wait_for_pid函数等待 PID 文件删除,若成功则删除锁文件,最后根据返回值退出脚本。

重启模式(restart)

'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
    ;;

先尝试停止 MySQL 服务,若成功则启动服务,否则打印失败消息并退出。

重载模式(reload和force-reload)

'reload'|'force-reload')
    if test -s "$mysqld_pid
mysqld_multi.server
#!/bin/sh
#
# A simple startup script for mysqld_multi by Tim Smith and Jani Tolonen.
# This script assumes that my.cnf file exists either in /etc/my.cnf or
# /root/.my.cnf and has groups [mysqld_multi] and [mysqldN]. See the
# mysqld_multi documentation for detailed instructions.
#
# This script can be used as /etc/init.d/mysql.server
#
# Comments to support chkconfig on RedHat Linux
# chkconfig: 2345 64 36
# description: A very fast and reliable SQL database engine.
#
# Version 1.0
#

basedir=/usr/local/mysql
bindir=/usr/local/mysql/bin

if test -x $bindir/mysqld_multi
then
  mysqld_multi="$bindir/mysqld_multi";
else
  echo "Can't execute $bindir/mysqld_multi from dir $basedir";
  exit;
fi

case "$1" in
    'start' )
        "$mysqld_multi" start $2
        ;;
    'stop' )
        "$mysqld_multi" stop $2
        ;;
    'report' )
        "$mysqld_multi" report $2
        ;;
    'restart' )
        "$mysqld_multi" stop $2
        "$mysqld_multi" start $2
        ;;
    *)
        echo "Usage: $0 {start|stop|report|restart}" >&2
        ;;
esac

​ 这是一个用于管理多实例 MySQL 服务的启动脚本,由 Tim Smith 和 Jani Tolonen 编写,主要通过mysqld_multi工具实现对多个 MySQL 实例的统一控制。脚本设计为可放置在/etc/init.d目录下作为系统服务使用,适用于需要运行多个 MySQL 实例的场景。

核心功能与结构

  1. 前提条件说明

    脚本依赖

 my.cnf

配置文件,且文件需包含以下配置段:

[mysqld_multi]:多实例管理全局配置

[mysqldN]:具体实例配置(N 为实例编号,如[mysqld1]

配置文件路径优先为/etc/my.cnf,其次为/root/.my.cnf。

2. 环境变量与路径设置

 basedir=/usr/local/mysql
 bindir=/usr/local/mysql/bin

basedir:MySQL 安装根目录(默认/usr/local/mysql)

bindir:可执行文件目录(默认指向安装目录下的bin)

3. 工具可用性检查

 if test -x $bindir/mysqld_multi
 then
   mysqld_multi="$bindir/mysqld_multi";
 else
   echo "Can't execute $bindir/mysqld_multi from dir $basedir";
   exit;
 fi

检查

 mysqld_multi

工具是否存在且可执行:

  • 若存在,将工具路径赋值给mysqld_multi变量

  • 若不存在,打印错误信息并退出脚本

  1. 命令行操作解析

 case "$1" in
     'start' )
         "$mysqld_multi" start $2
         ;;
     'stop' )
         "$mysqld_multi" stop $2
         ;;
     'report' )
         "$mysqld_multi" report $2
         ;;
     'restart' )
         "$mysqld_multi" stop $2
         "$mysqld_multi" start $2
         ;;
     *)
         echo "Usage: $0 {start|stop|report|restart}" >&2
         ;;
 esac

操作模式说明:

start [N]:启动编号为 N 的 MySQL 实例(如start 1启动[mysqld1])

stop [N]:停止编号为 N 的 MySQL 实例

report [N]:查看实例 N 的运行状态报告

restart [N]:先停止实例 N,再启动实例 N

参数传递:

$1为操作类型(如start)

$2为实例编号或参数(如1)

默认行为:若参数错误,输出使用帮助信息到标准错误流

配置文件示例

要使脚本正常工作,my.cnf需包含以下配置:

[mysqld_multi]
mysqld = /usr/local/mysql/bin/mysqld_safe
mysqladmin = /usr/local/mysql/bin/mysqladmin
user = root
password = <root密码>

[mysqld1]
port = 3306
socket = /tmp/mysql1.sock
datadir = /data/mysql1
pid-file = /data/mysql1/mysqld.pid

[mysqld2]
port = 3307
socket = /tmp/mysql2.sock
datadir = /data/mysql2
pid-file = /data/mysql2/mysqld.pid

多实例管理原理

mysqld_multi通过读取[mysqldN]配置段获取每个实例的端口、数据目录等参数

启动实例时,会调用mysqld_safe并传递对应配置

停止实例时,通过mysqladmin发送停止信号

状态报告通过检查进程和 PID 文件生成

使用场景与注意事项

  1. 适用场景

    需要在同一服务器运行多个 MySQL 实例(如不同业务隔离)

    测试环境需要模拟多节点部署

    开发环境需要同时运行不同版本的 MySQL

  2. 注意事项

    每个实例需配置独立的端口、Socket 和数据目录

    [mysqld_multi]段需配置有效的认证信息(userpassword

    建议为每个实例设置独立的系统用户,避免权限冲突

    生产环境中建议通过--user参数指定低权限用户运行实例

    与单实例脚本的区别

    单实例脚本(如mysql.server)直接操作单个mysqld进程

    多实例脚本通过mysqld_multi协调多个实例的生命周期

    配置文件需要为每个实例单独定义参数,而非全局配置

    通过该脚本,管理员可便捷地管理多个 MySQL 实例的启停和状态查询,无需为每个实例单独编写启动脚本,提高多实例环境的运维效率。

    备注:

    快捷链接

ln -s  /usr/local/mysql-8.0.14-linux-glibc2.12-x86_64/* /usr/local/mysql
#移除软链接 移除软链接时,直接使用链接名称,不要在末尾添加斜杠 rm -r /usr/local/mysql  删除源目录(谨慎操作!)
rm /usr/local/mysql

ln -s  /usr/local/mysql-8.0.14-linux-glibc2.12-x86_64/* /usr/local/mysql
ln -s  /usr/local/mysql-8.0.14-linux-glibc2.12-x86_64/etc/my.cnf /etc/my.cnf
相关新闻
热点
投票
查看结果
Tags

站点地图 在线访客: 今日访问量: 昨日访问量: 总访问量:

© 2025 个人网站 版权所有

备案号:苏ICP备2024108837号

苏公网安备32011302322151号