This blog describes how to configure systemd for multiple instances of MySQL. With package installations of MySQL using YUM or APT, it’s easy to manage MySQL with systemctl, but how will you manage it when you install from the generic binaries?
Here, we will configure multiple MySQL instances from the generic binaries and manage them using systemd.
We will do that, but why would you need multiple instances on the same host in the first place? Why not just create another database on the same instance? In some cases, you will need multiple instances on the host.
The original motivation for FB was due to different hardware generations, especially between regions/data centers. For example, an older data center may have smaller/less powerful machines, so they run fewer mysqld per host there to compensate. There were other exceptions, too, like abnormally large special-case-shard needing dedicated machines.
That said, other performance motivations mentioned above did play into it, especially before the days of multi-threaded replication. And I agree that in the modern age of cloud and huge flash storage, the vast majority of companies will never need to consider doing this in prod, but there is always a chance of its need.
To install and use a MySQL binary distribution, the command sequence looks like this:
|
1 |
yum install libaio1 libaio-dev numactl<br>useradd -r -g mysql -s /bin/false mysql<br>groupadd mysql<br>cd /usr/local/<br>tar xvfz /root/Percona-Server-8.0.19-10-Linux.x86_64.ssl101.tar.gz<br>ln -s /usr/local/Percona-Server-8.0.19-10-Linux.x86_64.ssl101/ mysql<br>cd /data/<br>mkdir -p /data/mysql/{3306,3307}/data<br>chown -R mysql:mysql /data<br>chmod 750 -R /data/mysql/{3306,3307}/data |
Below is an example of the first instance I placed in /etc/prod3306.cnf. My naming convention is prod3306 and prod3307. I then place that naming convention in the configuration filename /etc/prod3306.cnf. I could have done my.cnf.instance or instance.my.cnf.
|
1 |
[root@ip-172-31-128-38 share]# cat /etc/prod3306.cnf<br><br>[mysqld@prod3306]<br>datadir=/data/mysql/3306<br>socket=/data/mysql/3306/prod3306.sock<br>mysqlx_socket=/data/mysql/3306/prod3306x.sock<br>log-error=/data/mysql/prod3306.err<br>port=3306<br>mysqlx_port=33060<br>server-id=1336<br>slow_query_log_file=/data/mysql/3306/slowqueries.log<br>innodb_buffer_pool_size = 50G<br>lower_case_table_names=0<br>tmpdir=/data/mysql/3306/tmp/<br>log_bin=/data/mysql/3306/prod3306-bin<br>relay_log=/data/mysql/3306/prod3306-relay-bin<br>lc_messages_dir=/usr/local/mysql/share<br><br><br>[mysqld@prod3307]<br>datadir=/data/mysql/3307<br>socket=/data/mysql/3307/prod3307.sock<br>mysqlx_socket=/data/mysql/3307/prod3307x.sock<br>log-error=/data/mysql/prod3307.err<br>port=3307<br>mysqlx_port=33070<br>server-id=2337<br>slow_query_log_file=/data/mysql/3307/slowqueries.log<br>innodb_buffer_pool_size = 50G<br>lower_case_table_names=0<br>lc_messages_dir=/usr/local/mysql/share<br>tmpdir=/data/mysql/3307/tmp/<br>log_bin=/data/mysql/3307/prod3307-bin<br>relay_log=/data/mysql/3307/prod3307-relay-bin |
The directory lc_messages_dir=/usr/local/mysql/share is required when your MySQL binaries base directory is not the default one, so I had to pass the path for it — otherwise, MySQL won’t start.
Initialize your database and get the temporary password for the database from the error log file so you can log in and update the passwords after the MySQL instances are started.
|
1 |
ln -s /usr/local/mysql/bin/mysqld /usr/bin<br>mysqld --no-defaults --initialize-insecure --user=mysql --datadir=/data/mysql/3307 --lower_case_table_names=0<br>mysqld --no-defaults --initialize-insecure --user=mysql --datadir=/data/mysql/3306 --lower_case_table_names=0 |
Create the SYSTEMD base configuration at /etc/systemd/system/[email protected] and place the following contents inside. This is where the naming convention of the MySQL instances comes into effect. In the SYSTEMD configuration file, %I will be replaced with the naming convention that you use.
|
1 |
[root@ip-172-31-128-38 share]# cat /usr/lib/systemd/system/[email protected]<br># Copyright (c) 2016, 2021, Oracle and/or its affiliates.<br>#<br># This program is free software; you can redistribute it and/or modify<br># it under the terms of the GNU General Public License, version 2.0,<br># as published by the Free Software Foundation.<br>#<br># This program is also distributed with certain software (including<br># but not limited to OpenSSL) that is licensed under separate terms,<br># as designated in a particular file or component or in included license<br># documentation. The authors of MySQL hereby grant you an additional<br># permission to link the program and your derivative works with the<br># separately licensed software that they have included with MySQL.<br>#<br># This program is distributed in the hope that it will be useful,<br># but WITHOUT ANY WARRANTY; without even the implied warranty of<br># MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the<br># GNU General Public License, version 2.0, for more details.<br>#<br># You should have received a copy of the GNU General Public License<br># along with this program; if not, write to the Free Software<br># Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA<br>#<br># systemd service file for MySQL forking server<br>#<br><br>[Unit]<br>Description=MySQL Server<br>Documentation=man:mysqld(8)<br>Documentation=http://dev.mysql.com/doc/refman/en/using-systemd.html<br>After=network.target<br>After=syslog.target<br><br>[Install]<br>WantedBy=multi-user.target<br>[Service]<br>User=mysql<br>Group=mysql<br>Type=forking<br>PIDFile=/data/mysql/mysqld-%i.pid<br># Disable service start and stop timeout logic of systemd for mysqld service.<br>TimeoutSec=0<br># Execute pre and post scripts as root<br>PermissionsStartOnly=true<br># Needed to create system tables<br>#ExecStartPre=/usr/bin/mysqld_pre_systemd %I<br># Start main service<br>ExecStart=/usr/bin/mysqld --defaults-file=/etc/prod3306.cnf --defaults-group-suffix=@%I --daemonize --pid-file=/data/mysql/mysqld-%i.pid $MYSQLD_OPTS<br><br># Use this to switch malloc implementation<br>EnvironmentFile=-/etc/sysconfig/mysql<br># Sets open_files_limit<br>LimitNOFILE = 65536<br>Restart=on-failure<br>RestartPreventExitStatus=1<br>Environment=MYSQLD_PARENT_PID=1<br>PrivateTmp=false<br>[root@ip-172-31-128-38 share]# |
Reload daemon
|
1 |
systemctl daemon-reload |
Start MySQL
|
1 |
systemctl start mysqld@prod3307<br><br>systemctl start mysqld@prod3306 |
Enable MySQL service
|
1 |
systemctl enable mysqld@prod3307<br><br>systemctl enable mysqld@prod3306 |
Error log for each instance
|
1 |
[root@ip-172-31-128-38 3307]# tail -5 /data/mysql/prod3306.er<br><br>tail: cannot open '/data/mysql/prod3306.er' for reading: No such file or directory<br><br>[root@ip-172-31-128-38 3307]# tail -5 /data/mysql/prod3306.err<br><br>2023-07-10T05:26:42.521994Z 0 [System] [MY-010910] [Server] /usr/bin/mysqld: Shutdown complete (mysqld 8.0.19-10) Percona Server (GPL), Release 10, Revision f446c04.<br><br>2023-07-10T05:26:48.210107Z 0 [System] [MY-010116] [Server] /usr/bin/mysqld (mysqld 8.0.19-10) starting as process 20477<br><br>2023-07-10T05:26:52.094196Z 0 [Warning] [MY-010068] [Server] CA certificate ca.pem is self signed.<br><br>2023-07-10T05:26:52.112887Z 0 [System] [MY-010931] [Server] /usr/bin/mysqld: ready for connections. Version: '8.0.19-10' socket: '/data/mysql/3306/prod3306.sock' port: 3306 Percona Server (GPL), Release 10, Revision f446c04.<br><br>2023-07-10T05:26:52.261062Z 0 [System] [MY-011323] [Server] X Plugin ready for connections. Socket: '/data/mysql/3306/prod3306x.sock' bind-address: '::' port: 33060 |
|
1 |
root@ip-172-31-128-38 3307]# tail -5 /data/mysql/prod3307.err<br><br>2023-07-10T05:26:36.032160Z 0 [System] [MY-010910] [Server] /usr/bin/mysqld: Shutdown complete (mysqld 8.0.19-10) Percona Server (GPL), Release 10, Revision f446c04.<br><br>2023-07-10T05:26:58.328962Z 0 [System] [MY-010116] [Server] /usr/bin/mysqld (mysqld 8.0.19-10) starting as process 20546<br><br>2023-07-10T05:27:02.179449Z 0 [Warning] [MY-010068] [Server] CA certificate ca.pem is self signed.<br><br>2023-07-10T05:27:02.198092Z 0 [System] [MY-010931] [Server] /usr/bin/mysqld: ready for connections. Version: '8.0.19-10' socket: '/data/mysql/3307/prod3307.sock' port: 3307 Percona Server (GPL), Release 10, Revision f446c04.<br><br>2023-07-10T05:27:02.346514Z 0 [System] [MY-011323] [Server] X Plugin ready for connections. Socket: '/data/mysql/3307/prod3307x.sock' bind-address: '::' port: 33070<br><br>[root@ip-172-31-128-38 3307]# |
Utilizing systemctl to control MySQL significantly simplifies the management of MySQL instances. This approach facilitates the easy configuration of multiple instances, extending beyond two, and streamlines the overall administration process. However, it is essential to be mindful of memory allocation when setting up multiple MySQL instances on a single server. Allocating memory appropriately for each MySQL instance ensures sufficient overhead and optimal performance.
Percona Monitoring and Management is a best-of-breed open source database monitoring solution. It helps you reduce complexity, optimize performance, and improve the security of your business-critical database environments, no matter where they are located or deployed.