使用 systemd 管理多个 MySQL 服务器实例
文章目录
- 使用 systemd 管理多个 MySQL 服务器实例
- 先决条件
- 支持 systemd 的操作系统
- 每个实例配置独立的目录和参数
- 部署多实例环境
- 1. 配置选项文件
- 使用 systemd 管理 MySQL 多实例
- 总结
本文仅讲述使用 RPM 包安装的多个 MySQL 实例如何使用 systemd 进行管理,MySQL 通用二进制包需要自行创建目录和systemd 管理的 mysqld.service 服务文件。
先决条件
支持 systemd 的操作系统
- RPM 包平台:
- Enterprise Linux variants version 7 及更高版本
- SUSE Linux Enterprise Server 12 及更高版本
- Fedora 29 及更高版本
- Debian 家族平台 :
- Debian 平台
- Ubuntu 平台
每个实例配置独立的目录和参数
- 最重要的是 DATADIR 。建议为每个实例配置配置独立的数据目录,在选项文件中配置
datadir=数据目录路径
。 port=port_num
控制 TCP/IP 连接的端口号。如果主机有多个网络地址,可以设置bind_address
以监听多个地址。socket={file_name|pipe_name}
控制 Unix 套接字文件路径或 Windows 命名管道的名称。在 Windows 上,必须仅为配置为允许命名管道连接的服务器指定不同的管道名称。log-error[=file_name]
选项指定默认的错误日志位置。如果不设置默认为 console ,即 stderr ;如果不指定值,则默认在数据目录下创建 hostname.err 文件;如果指定值而不指定后缀,则在指定 file_name 后加 .err 后缀;如果指定值包含后缀,则使用指定值。shared-memory-base-name=name
选项 仅在 Windows 上使用 。它指定 Windows 服务器使用的共享内存名称,以允许客户端使用共享内存进行连接。必须仅为配置为允许共享内存连接的服务器指定不同的共享内存名称。- (可选)
pid-file=file_name
选项表示服务器写入其进程 ID 的文件的路径名。systemd 管理的 MySQL 实例并不需要创建 pid 文件来记录进程 ID ,使用 tar 包等安装的 MySQL 用 mysqld_safe 或 mysqld_multi 需要它管理进程。 - 如果你显式指定了如下参数,则也应为每台服务器指定独立的参数设置:
general_log_file=file_name
log-bin[=file_name]
slow_query_log_file=file_name
- (推荐)
tmpdir=dir_name
。为每个实例指定不同的临时目录可以更好的分辨不同实例产生的临时文件,并且,如果使用多个物理磁盘,还可以扩展负载。
注意
如果要使用自定义 tmpdir ,请使用 DATADIR 以外的目录,且必须提前创建并且设置属主为mysql:mysql
,否则会报如下错误:mysqld[18655]: mysqld: Can't get stat of '/var/lib/mysql/tmp/replica04' (OS errno 2 - No such file or directory
可以直接执行如下命令解决:
[root@ic-source mysql]$ sudo -u mysql mkdir tmp/replica04
创建好
tmpdir
后,再次启动 MySQL 实例即可正常启动。
部署多实例环境
1. 配置选项文件
要使用多实例功能,请修改my.cnf
选项文件,以包含每个实例的关键选项配置。以下是典型的文件位置:
- /etc/my.cnf 或 /etc/mysql/my.cnf (RPM 平台)
- /etc/mysql/mysql.conf.d/mysqld.cnf (Debian 平台)
推荐的配置是使用简单的实例名,MySQL 官方在线文档中说 “@” 是 systemd 支持的唯一分隔符,是不对的,我参考 systemd 说明实测 systemd 的服务和单元名称支持 下划线(_)、英文句号(.)和@符号。但 MySQL 的 mysqld_pre_systemd 和 mysqld 对 systemd 支持似乎仅对 @ 作分隔符的多实例名称有很好的支持,其他命名方式可能产生非预期的结果甚至报错。
默认的数据目录是创建在/var/lib/mysql-实例名
,实例名是指选项文件中的选项组后缀,是 @ 后面的内容。
极简配置仅需配置Socke、端口号、数据目录,log-error
如果未指定会默认生成/var/log/mysql-实例名.log
日志文件。
MySQL 官网在线文档举例,使用如下配置文件创建名为 replica01 和 replica02 的两个实例。
- RPM 平台
[mysqld@replica01]
datadir=/var/lib/mysql-replica01
socket=/var/lib/mysql-replica01/mysql.sock
port=3307
log-error=/var/log/mysqld-replica01.log
[mysqld@replica02]
datadir=/var/lib/mysql-replica02
socket=/var/lib/mysql-replica02/mysql.sock
port=3308
log-error=/var/log/mysqld-replica02.log
- Debian 平台
[mysqld@replica01]
datadir=/var/lib/mysql-replica01
socket=/var/lib/mysql-replica01/mysql.sock
port=3307
log-error=/var/log/mysql/replica01.log
[mysqld@replica02]
datadir=/var/lib/mysql-replica02
socket=/var/lib/mysql-replica02/mysql.sock
port=3308
log-error=/var/log/mysql/replica02.log
你会发现,两个平台仅在log-error
的默认名称上有所不同。
下面我给出我的/etc/my.cnf
供您参考:
log_timestamps=SYSTEM
#lower_case_table_names=1
[mysqld-8.0]
#GR
disabled_storage_engines="MyISAM,BLACKHOLE,FEDERATED,ARCHIVE,MEMORY"
[mysqld@ics_pc_pri]
port=3306
datadir='/var/lib/mysql/data/ics_pc_pri'
tmpdir='/var/lib/mysql/tmp/ics_pc_pri'
socket='/var/lib/mysql/data/ics_pc_pri/mysql.sock'
log-error='/var/log/mysql-ics_pc_pri.log'
slow_query_log_file='/var/log/slow_query-ics_pc_pri.log'
log-bin='ics_pc_pri-bin'
innodb_buffer_pool_size=2048M
innodb_redo_log_capacity=1G
innodb_flush_method=O_DIRECT_NO_FSYNC
[mysqld@ics_rc01_pri]
port=3307
datadir='/var/lib/mysql/data/ics_rc01_pri'
tmpdir='/var/lib/mysql/tmp/ics_rc01_pri'
socket='/var/lib/mysql/data/ics_rc01_pri/mysql.sock'
log-error='/var/log/mysql-ics_rc01_pri.log'
slow_query_log_file='/var/log/slow_query-ics_rc01_pri.log'
log-bin='ics_rc01_pri-bin'
innodb_buffer_pool_size=1024M
innodb_redo_log_capacity=100M
innodb_flush_method=O_DIRECT_NO_FSYNC
[mysql]
port=3306
socket='/var/lib/mysql/data/ics_pc_pri/mysql.sock'
使用 systemd 管理 MySQL 多实例
systemd 的基础命令格式如下:
$ systemctl {start|stop|restart|status} mysqld
或者,使用与 System V 系统兼容的 service 命令(参数颠倒):
$ service mysqld {start|stop|restart|status}
而在使用 MySQL 多实例时使用的是mysqld@.service
模板服务。
在同一台服务器上管理多个 MySQL 服务器实例,systemd 自动使用不同的单元文件:
- mysqld@.service 而不是 mysqld.service (RPM 平台)
- mysql@.service 而不是 mysql.service (Debian 平台)
在单元文件中,%I和%I引用@标记后传入的参数,并用于管理特定实例。
systemd 使用如下命令启动 MySQL 服务器:
$ mysqld --defaults-group-suffix=@%I $MYSQLD_OPTS
比如,启动上面的 replica01 和 replica02 两个实例。
$ systemctl start mysqld@replica01
$ systemctl start mysqld@replica02
设置它们为开机自启动:
$ systemctl enable mysqld@replica01
$ systemctl enable mysqld@replica02
这里说明一下,/usr/bin/mysqld_pre_systemd
是一个 shell 脚本,(/usr/lib/systemd/system/mysqld@.service
是一个可编辑的明文普通文件。/usr/bin/mysqld_pre_systemd
脚本仍有些缺陷,比如在不显示指定log-error
选项时它会为其设置默认值/var/log/mysql-实例名.log
,并创建一个以这个默认值为名的空日志文件,而在初始化数据库时却没有使用这个日志文件,导致日志输出在了 stderr 上,随机生成的密码不可见了。同样,如果你不指定datadir
选项,/usr/bin/mysqld_pre_systemd
脚本默认也会创建一个,却没有在 mysqld 启动时应用。针对此 Bug ,笔者已修改脚本和单元文件解决,稍后将整理提交到 MySQL Forums 。
使用如下命令查看以mysqld@.service
为单元模板的的多实例的状态:
$ systemctl status mysqld@*
总结
使用 systemd 管理 MySQL 多实例的重点在于选项文件的配置,重要选项为datadir
,port
,socket
,log-error
。如需为每个实例指定独立的tmpdir
,需要提前创建。虽然某些选项不指定,/usr/bin/mysqld_pre_systemd
脚本会赋予默认值,但却存在缺陷,导致启动时报错,所以不建议使用。
此外,/etc/systemd/system/mysqld.service.d/override.conf
这个文件也会影响 systemd 管理 MySQL,但笔者发现其内容默认都是注释掉的,故没有影响。还有一个文件/etc/sysconfig/mysql
默认没有创建,也同样会产生影响。
更多详细内容,参见【《MySQL 8.0 参考手册》中文翻译】 专栏 2.5.9 节 使用 systemd 管理 MySQL 服务器实例 。