MySQL启动方式及多实例

MySQL启动方式

mysqld

启动方式:

本文假设已添加MySQL安装目录/usr/local/mysql/bin至系统环境变量PATH
所以在执行MySQL相关命令时,不再切换到MySQL安装目录,或者使用完整路径。

1
2
3
4
shell > mysqld --user=mysql &

[1] 23046
2016-06-24 22:57:33 0 [Note] mysqld (mysqld 5.6.29-log) starting as process 23046 ...
  1. mysqld,即MySQL服务器。MySQL安装过程中,很多工作是由mysqld来完成的。
  2. 使用mysqld启动MySQL服务器之后,系统仅有一个mysqld进程。如下:
    1
    2
    3
    shell> ps aux | grep mysqld

    mysql 23046 0.2 9.6 780496 48480 pts/0 Sl 22:57 0:00 mysqld --user=mysql

mysqld_safe

启动方式:

1
2
3
4
5
shell> mysqld_safe --user=mysql &

[1] 23159
160624 23:11:43 mysqld_safe Logging to '/data/mysql/mysql3376/data/error.log'.
160624 23:11:43 mysqld_safe Starting mysqld daemon with databases from /data/mysql/mysql3376/data

  1. mysqld_safe启动时会调用mysqld来启动MySQL服务器
  2. mysqld_safemysqld的守护进程,添加了一些安全特性,当MySQL服务器出现错误时会重启mysqld
  3. 使用mysqld_safe启动MySQL服务器之后,系统有两个进程:mysqldmysqld_safe。如下:
    1
    2
    3
    4
    shell> ps aux | grep mysqld

    root 2892 0.1 0.2 106232 1400 pts/0 S 11:43 0:00 /bin/sh /usr/local/mysql/bin/mysqld_safe --user=mysql
    mysql 3934 0.1 9.6 780496 48472 pts/0 Sl 11:43 0:00 /usr/local/mysql/bin/mysqld --basedir=/usr/local/mysql --datadir=/data/mysql/mysql3376/data --plugin-dir=/usr/local/mysql/lib/plugin --user=mysql --log-error=/data/mysql/mysql3376/data/error.log --pid-file=/data/mysql/mysql3376/data/node601.pid --socket=/tmp/mysql3376.sock --port=3376

mysql.server

启动方式:

1
2
3
4
5
# 启动MySQL
shell> mysql.server start

# 关闭MySQL
shell> mysql.server stop

  1. mysql.server是一个SHELL脚本,通过调用mysqld_safe来启动MySQL;
  2. 使用RPM或其他的Linux系统的包管理器安装MySQL时,mysql.server通常会被安装在/etc/init.d路径下,文件名为mysqlmysqld
  3. 使用二进制包或源码安装时,mysql.server在MySQL安装目录的support-files下,可以手动将其复制到/etc/init.d路径下;

    1
    2
    shell> cp mysql.server /etc/init.d/mysql
    shell> chmod +x /etc/init.d/mysql

    此时也可以使用以下命令来启动和关闭MySQL

    1
    2
    3
    4
    5
    6
    7
    8
    9
    # 启动
    shell> service mysql start
    # shell> /etc/init.d/mysql start
    # 关闭
    shell> service mysql stop
    # shell> /etc/init.d/mysql stop
    # 重启
    shell> service mysql restart
    # shell> /etc/init.d/mysql restart
  4. 使用mysql.server启动MySQL服务器之后,系统有两个进程:mysqldmysqld_safe。如下:

    1
    2
    3
    4
    shell> ps aux | grep mysqld

    root 4453 0.2 0.2 11472 1388 pts/0 S 12:41 0:00 /bin/sh /usr/local/mysql/bin/mysqld_safe --datadir=/data/mysql/mysql3376/data --pid-file=/data/mysql/mysql3376/data/node601.pid
    mysql 5508 0.3 9.6 780496 48480 pts/0 Sl 12:41 0:00 /usr/local/mysql/bin/mysqld --basedir=/usr/local/mysql --datadir=/data/mysql/mysql3376/data --plugin-dir=/usr/local/mysql/lib/plugin --user=mysql --log-error=/data/mysql/mysql3376/data/error.log --pid-file=/data/mysql/mysql3376/data/node601.pid --socket=/tmp/mysql3376.sock --port=3376

以上为使用mysqldmysqld_safemysql.server进行MySQL单个实例的启动,使用[mysqld_multi]进行MySQL多实例的启动,将会在本文后面进行介绍。

MySQL配置文件

在介绍MySQL多实例之前,先介绍下MySQL配置文件。

  1. 在启动MySQL时,若没有在命令行显式指定配置文件的路径,默认情况下,MySQL会从以下位置依次读取配置文件。并且,后读取的配置文件中的参数会优先于其前面的配置文件的参数生效。

    1
    2
    3
    4
    /etc/my.cnf
    /etc/mysql/my.cnf
    /usr/local/mysql/etc/my.cnf
    ~/.my.cnf

    可以通过以下命令查看MySQL默认读取的配置文件:

    1
    2
    3
    4
    5
    6
    shell> mysqld --verbose --help | grep -A 5 'Default options'

    2016-06-25 12:50:43 0 [Note] mysqld (mysqld 5.6.29-log) starting as process 5602 ...
    2016-06-25 12:50:43 5602 [Note] Plugin 'FEDERATED' is disabled.
    Default options are read from the following files in the given order:
    /etc/my.cnf /etc/mysql/my.cnf /usr/local/mysql/etc/my.cnf ~/.my.cnf
  2. MySQL配置文件由一个或多个group组成,每个group的名称为要设置参数的MySQL程序的名称或者组名。

    • 常见的group有:[mysqld][mysql][client]等。
  3. 以MySQL程序命名的group包含的参数,对该程序生效。比如:
    • [mysqld][mysql]下的参数分别对mysqld服务器程序和mysql客户端程序生效;
    • [mysqldump]下的参数对mysqldump程序生效;
    • 等等…
  4. [client]分组下的参数,对所有的MySQL客户端程序生效。
    • 如果某个参数不能被所有的MySQL客户端程序识别,不要把该参数放在[client]分组下。否则,会引起不能识别该参数的程序报错并退出。
  5. MySQL常用程序读取的配置文件中group名称:
    1. mysql:[mysql][client]
    2. mysqld:[mysqld][server]
    3. mysqld_safe:[mysqld][server][mysqld_safe];为了向后兼容,也读取[safe_mysqld]分组下的参数;
    4. mysql.server:[mysql.server][mysqld];为了向后兼容,也读取[mysql_server]下的参数;

MySQL多实例

应用场景

  1. 在同一台服务器上,不同的业务使用不同的实例,互不影响;
  2. MySQL服务器随着连接数的上升,性能会下降,可以将连接数比较多的单个实例拆分成多个实例;
  3. 多实例在互联网公司比较常用;

多实例参数

MySQL多个实例的以下参数应保持不同:

  1. 数据目录:datadir=dir_name
  2. 端口:port=port_num
  3. socket文件名称:socket=file_name
  4. pid文件名称:pid-file=file_name
  5. 一些日志的名称和路径
    1. 通用查询日志:general_log_file=file_name
    2. 二进制日志:log-bin=file_name
    3. 慢查询日志:slow_query_log_file=file_name
    4. 错误日志:log-error=file_name

默认情况下,pid文件、以及以上各种日志文件,在各实例的数据目录下面,若已设置datadir为不同的目录,可不再显式设置这些选项。

设置tmpdir为不同的目录,可以方便的识别临时文件是由哪些MySQL实例产生的。当然,这并不是必须要设置的。

安装多实例

参照《MySQL安装和初始化》一文的介绍,现有系统已安装一个端口为3376的实例,在此基础上新增加一个端口为3377的实例。

  1. 关键参数对比

    1. 端口为3376的实例的参数:

      1
      2
      3
      4
      5
      6
      [mysqld]
      port = 3376
      socket = /tmp/mysql3376.sock
      datadir = /data/mysql/mysql3376/data
      tmpdir = /data/mysql/mysql3376/tmp
      log-bin = /data/mysql/mysql3376/logs/mysql-bin
    2. 端口为3377的实例的参数:

      1
      2
      3
      4
      5
      6
      [mysqld]
      port = 3377
      socket = /tmp/mysql3377.sock
      datadir = /data/mysql/mysql3377/data
      tmpdir = /data/mysql/mysql3377/tmp
      log-bin = /data/mysql/mysql3377/logs/mysql-bin
  2. 新建目录

    1
    shell> mkdir -pv /data/mysql/mysql3377/{data,logs,tmp}
  3. 修改配置文件

    • 将3376实例的配置文件复制到3377的目录下,并批量修改配置文件中的33763377
      由于以上各参数值都是由实例相应的端口组成,所以这里只需要替换配置文件中的端口号,即可达到不同实例不同的参数。

      1
      2
      3
      shell> cp /etc/my.cnf /data/mysql/mysql3377/my3377.cnf
      shell> cd /data/mysql/mysql3377
      shell> sed -i 's/3376/3377/g' my3377.cnf
    • 替换之后配置文件的参数如下:

      1
      2
      3
      4
      5
      6
      7
      8
      9
      10
      11
      12
      13
      14
      shell> grep 3377 my3377.cnf

      # client
      port = 3377
      socket = /tmp/mysql3377.sock
      # mysqld
      port = 3377
      datadir = /data/mysql/mysql3377/data
      tmpdir = /data/mysql/mysql3377/tmp
      socket = /tmp/mysql3377.sock
      log-bin = /data/mysql/mysql3377/logs/mysql-bin
      server-id =1613377
      innodb_data_home_dir = /data/mysql/mysql3377/data
      innodb_log_group_home_dir = /data/mysql/mysql3377/logs
  4. 修改目录权限

    1
    2
    3
    4
    5
    6
    7
    8
    shell> chown -R mysql:mysql /data/mysql/mysql3377
    shell> ll /data/mysql/mysql3377

    total 4
    drwxr-xr-x 2 mysql mysql 6 Jun 25 16:56 data
    drwxr-xr-x 2 mysql mysql 6 Jun 25 16:56 logs
    -rwxr-xr-x 1 mysql mysql 3020 Jun 25 17:06 my3377.cnf
    drwxr-xr-x 2 mysql mysql 6 Jun 25 16:56 tmp
  5. 初始化MySQL 3377实例

    1
    2
    shell> cd /usr/local/mysql/
    shell> ./scripts/mysql_install_db --defaults-file=/data/mysql/mysql3377/my3377.cnf --user=mysql
  6. 启动3377实例

    1
    2
    3
    4
    shell> mysqld --defaults-file=/data/mysql/mysql3377/my3377.cnf --user=mysql &

    [2] 6961
    2016-06-25 17:40:20 0 [Note] mysqld (mysqld 5.6.29-log) starting as process 6961 ...

    查看后台进程,已启动两个MySQL实例:33763377

    1
    2
    3
    4
    5
    shell> netstat -nalp | grep mysqld
    tcp 0 0 :::3376 :::* LISTEN 6857/mysqld
    tcp 0 0 :::3377 :::* LISTEN 6961/mysqld
    unix 2 [ ACC ] STREAM LISTENING 23304 6857/mysqld /tmp/mysql3376.sock
    unix 2 [ ACC ] STREAM LISTENING 23462 6961/mysqld /tmp/mysql3377.sock
  7. 关闭3377实例

    1
    2
    3
    4
    shell> mysqladmin -S /tmp/mysql3377.sock -vvv shutdown

    Shutdown signal sent to server; Waiting for pid file to disappear
    [2]+ Done mysqld --defaults-file=/data/mysql/mysql3377/my3377.cnf --user=mysql

mysqld_multi

从以上配置3377实例的过程可以看出,可以为每个实例指定单独的配置文件。在启动时,指定对应的配置文件(--defaults-file);在关闭时,指定实例对应的socket(或者ip和端口),即可分别管理每一个实例。

而多个实例的管理,也可以采用另一种方法:各个实例的参数都在同一个配置文件里配置,使用mysqld_multi管理这些实例。

这里的“配置文件”可以是默认的/etc/my.cnf,也可以是由--defaults-file指定的。

mysqld_multi相关配置文件

关于mysqld_multi的配置例子,可以使用命令mysqld_multi --example查看,如下为其中的一部分:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
shell > mysqld_multi --example

[mysqld_multi]
mysqld = /usr/local/mysql/bin/mysqld_safe
mysqladmin = /usr/local/mysql/bin/mysqladmin
user = multi_admin
password = my_password

[mysqld2]
socket = /tmp/mysql.sock2
port = 3307
pid-file = /usr/local/mysql/data2/hostname.pid2
datadir = /usr/local/mysql/data2
language = /usr/local/mysql/share/mysql/english
user = unix_user1

[mysqld3]
mysqld = /path/to/mysqld_safe
ledir = /path/to/mysqld-binary/
mysqladmin = /path/to/mysqladmin
socket = /tmp/mysql.sock3
port = 3308
pid-file = /usr/local/mysql/data3/hostname.pid3
datadir = /usr/local/mysql/data3
language = /usr/local/mysql/share/mysql/swedish
user = unix_user2

[mysqld_multi]分组下的参数,对mysqld_multi程序自身生效;[mysqldN]分组下的参数,对特定的实例生效(N为正整数)。

  1. [mysqld_multi]分组相关的参数选项如下:

    1. mysqld=prog_name
      • 用于启动MySQL的程序,可以是mysqld,也可以是mysqld_safe
      • 当mysqld指定为mysqld或者mysqld_safe时,启动实例时,会分别读取这两个程序相应的group的配置文件;
    2. mysqladmin=prog_name
      • 用于关闭MySQL服务的mysqladmin程序路径
    3. user=user_name

      • 调用mysqladmin时使用的MySQL用户名
      • 每一个被管理的实例中都需要有此用户名,且密码相同(如果密码不同,无法同时关闭多个实例),且具有SHUTDOWN权限
      • 可以使用以下命令在每一个实例中新建该用户
        1
        2
        mysql> CREATE USER 'multi_admin'@'localhost' IDENTIFIED BY 'multipass';
        mysql> GRANT SHUTDOWN ON *.* TO 'multi_admin'@'localhost';
    4. password=password

      • 调用mysqladmin时,所使用的user的密码
    5. log=file_name
      • 用来记录mysqld_muti的启动日志
  2. [mysqldN]
    • 该分组的参数,对特定的MySQL实例生效
    • [mysqld]分组下可用的参数,都可以针对各个实例在[mysqldN]分组下再特别指定
    • N为正整数,建议N为端口号,便于区分实例的配置文件
  3. [mysqld]、[mysqld_safe]
    • 通用设置,对所有的实例都生效

配置本文的3376、3377实例

/etc/my.cnf文件添加[mysqld_multi][mysqld3376][mysqld3377]分组的参数选项,如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
[mysqld_multi]
mysqld = /usr/local/mysql/bin/mysqld
mysqladmin = /usr/local/mysql/bin/mysqladmin
user = multi_admin
password = multipass
log = /data/mysql/multi.log

[mysqld3376]
port = 3376
socket = /tmp/mysql3376.sock
datadir = /data/mysql/mysql3376/data
tmpdir = /data/mysql/mysql3376/tmp
log-bin = /data/mysql/mysql3376/logs/mysql-bin
server-id = 1613376
innodb_data_home_dir = /data/mysql/mysql3376/data
innodb_log_group_home_dir = /data/mysql/mysql3376/logs
# 必须在此指定user=mysql(mysql为Linux系统用户)
# 或者,在[mysqld]分组下指定全局user=mysql,否则无法启动MySQL
user = mysql

[mysqld3377]
port = 3377
socket = /tmp/mysql3377.sock
datadir = /data/mysql/mysql3377/data
tmpdir = /data/mysql/mysql3377/tmp
log-bin = /data/mysql/mysql3377/logs/mysql-bin
server-id = 1613377
innodb_data_home_dir = /data/mysql/mysql3377/data
innodb_log_group_home_dir = /data/mysql/mysql3377/logs
user = mysql

mysqld_multi启动/关闭MySQL实例的方式

可以用来启动/关闭一个、多个或某个范围的实例
前提:已在配置文件中定义该实例对应分组的参数[mysqldN]

  1. 单个实例:Ni

    1
    2
    shell> mysqld_multi start Ni
    shell> mysqld_multi stop Ni
  2. 多个实例:Ni,Nj,...,Nk

    1
    2
    shell> mysqld_multi start Ni,Nj,Nk
    shell> mysqld_multi stop Ni,Nj,Nk
  3. 某个范围的多个实例:Ni-Nj

    1
    2
    shell> mysqld_multi start Ni-Nj
    shell> mysqld_multi stop Ni-Nj
  4. 多个分开的实例和某个范围的多个实例:Ni,...,Nj-Nk

    逗号,,破折号-前后不可以有空格,否则空格后面的字符将会被忽略

    1
    2
    shell> mysqld_multi start Ni,Nj-Nk
    shell> mysqld_multi stop Ni,Nj-Nk

启动/关闭本文的3376、3377实例

  1. 启动3376实例

    1
    mysqld_multi start 3376

    查看3376实例的mysqld进程是否已启动:

    1
    2
    3
    shell> ps aux | grep mysqld

    mysql 9686 0.2 9.6 780496 48484 pts/3 Sl 01:42 0:00 /usr/local/mysql/bin/mysqld --port=3376 --socket=/tmp/mysql3376.sock --datadir=/data/mysql/mysql3376/data --tmpdir=/data/mysql/mysql3376/tmp --log-bin=/data/mysql/mysql3376/logs/mysql-bin --server-id=1613376 --innodb_data_home_dir=/data/mysql/mysql3376/data --innodb_log_group_home_dir=/data/mysql/mysql3376/logs
  2. 关闭3376实例

    • 实际测试时,即使已经在配置文件的[mysqld_multi]分组下指定了password参数的值,关闭MySQL实例时,仍然会报密码错误。需要在命令行显式指定password的值,才能关闭实例。(原因未知)
    • [mysqld_multi]的log中报错信息如下:

      1
      2
      3
      4
      Stopping MySQL servers
      Warning: Using a password on the command line interface can be insecure.
      ^G/usr/local/mysql/bin/mysqladmin: connect to server at 'localhost' failed
      error: 'Access denied for user 'multi_admin'@'localhost' (using password: YES)'
    • 使用以下命令关闭实例:

      1
      mysqld_multi stop 3376 --password=multipass
  3. 同时启动3376、3377实例

    1
    2
    3
    4
    5
    shell> mysqld_multi start 3376,3377
    shell> ps aux | grep mysqld

    mysql 9845 1.0 9.6 780496 48468 pts/3 Sl 01:53 0:00 /usr/local/mysql/bin/mysqld --port=3376 --socket=/tmp/mysql3376.sock --datadir=/data/mysql/mysql3376/data --tmpdir=/data/mysql/mysql3376/tmp --log-bin=/data/mysql/mysql3376/logs/mysql-bin --server-id=1613376 --innodb_data_home_dir=/data/mysql/mysql3376/data --innodb_log_group_home_dir=/data/mysql/mysql3376/logs
    mysql 9848 1.0 9.6 780496 48456 pts/3 Sl 01:53 0:00 /usr/local/mysql/bin/mysqld --port=3377 --socket=/tmp/mysql3377.sock --datadir=/data/mysql/mysql3377/data --tmpdir=/data/mysql/mysql3377/tmp --log-bin=/data/mysql/mysql3377/logs/mysql-bin --server-id=1613377 --innodb_data_home_dir=/data/mysql/mysql3377/data --innodb_log_group_home_dir=/data/mysql/mysql3377/logs

    3376、3377这两个实例的进程已同时启动

  4. 同时关闭3376、3377实例

    1
    2
    3
    4
    shell> mysqld_multi stop 3376,3377 --password=multipass
    shell> ps aux | grep mysqld

    root 9958 0.0 0.1 103308 852 pts/3 S+ 01:55 0:00 grep mysql

    两实例的进程已同时被关闭。

多实例安装——使用现有实例安装

第3节中介绍的3377实例是全新安装的一个实例,安装完成后还需要进行初始化等操作。

新的实例的安装也可以在原有实例的数据的基础上进行安装。下面介绍在3377实例的基础上,来安装一个新的3378实例。

  1. 新建3378实例的目录

    1
    shell> mkdir -pv  /data/mysql/mysql3378
  2. 停止3377实例

    1
    2
    3
    4
    shell> mysqladmin -vvv --socket=/tmp/mysql3377.sock shutdown

    Shutdown signal sent to server; Waiting for pid file to disappear
    [2]+ Done mysqld --defaults-file=/data/mysql/mysql3377/my3377.cnf
  3. 将3377实例的数据等目录复制到3378目录

    1
    2
    3
    4
    5
    6
    7
    8
    9
    shell> cp -ar /data/mysql/mysql3377/* /data/mysql/mysql3378/
    shell> cd /data/mysql/mysql3378
    shell> ll

    total 8
    drwxr-xr-x 4 mysql mysql 121 Jun 26 15:46 data
    drwxr-xr-x 2 mysql mysql 4096 Jun 26 15:45 logs
    -rwxr-xr-x 1 mysql mysql 3019 Jun 26 15:38 my3377.cnf
    drwxr-xr-x 2 mysql mysql 6 Jun 26 15:45 tmp
  4. 修改3378实例的配置文件:datadirsocketport

    1
    2
    3
    shell> cd /data/mysql/mysql3378
    shell> mv my3377.cnf my3378.cnf
    shell> sed -i 's/3377/3378/g' my3378.cnf

    修改后的配置信息如下:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    shell> grep 3378  my3378.cnf

    port = 3378
    socket = /tmp/mysql3378.sock
    port = 3378
    datadir = /data/mysql/mysql3378/data
    tmpdir = /data/mysql/mysql3378/tmp
    socket = /tmp/mysql3378.sock
    log-bin = /data/mysql/mysql3378/logs/mysql-bin
    server-id =1613378
    innodb_data_home_dir = /data/mysql/mysql3378/data
    innodb_log_group_home_dir = /data/mysql/mysql3378/logs
  5. 删除3378数据目录的auto.cnf文件

    此文件为MySQL自动生成的server-uuid信息,需保证每个实例的该信息不同。
    删除此文件后,mysqld启动时会自动重新生成此文件。

    auto.cnf:

    1
    2
    [auto]
    server-uuid=fccde147-3b71-11e6-967d-0800272bc1fa
    1
    2
    shell> cd /data/mysql/mysql3378/data/
    shell> rm -f auto.cnf
  6. 启动3378实例

    1
    2
    3
    4
    shell> mysqld --defaults-file=/data/mysql/mysql3378/my3378.cnf --user=mysql &

    [1] 3191
    2016-06-26 16:18:26 0 [Note] mysqld (mysqld 5.6.29-log) starting as process 3191 ...

    确认实例是否启动成功:

    1
    2
    3
    shell> ps aux | grep mysqld

    mysql 3191 1.0 9.6 780496 48464 pts/2 Sl 16:18 0:00 mysqld --defaults-file=/data/mysql/mysql3378/my3378.cnf --user=mysql

附件

  1. 3377实例单独的配置文件:my3377.cnf
    链接:http://pan.baidu.com/s/1nvlKAet 密码:wv0o
  2. 使用mysqld_multi管理多实例时的配置文件:/etc/my.cnf
    链接:http://pan.baidu.com/s/1kUBWQTh 密码:vv99

声明

本文部分内容来自知数堂远程培训:https://zhishuedu.taobao.com/