Description:
On many modern linux systems the socket and pid-file will be created in a /var/run/mysql folder. This folder is often located on a tmpfs so the directory needs to be recreated after a reboot. The init script does this but the mysqld_multi script doesn't.
How to repeat:
Consider following config:
[root@localhost ~]# cat /etc/my.cnf
[mysqld_multi]
user = root
mysqladmin = /usr/bin/mysqladmin
mysqld = /usr/bin/mysqld
log = /var/log/mysql/mysqld_multi.log
[mysqld1]
socket = /var/run/mysql/mysql1.sock
port = 3306
pid-file = /var/run/mysql/mysql1.pid
datadir = /data/mysql1
user = mysql
log-error = /var/log/mysql/mysql1.log
[mysqld2]
socket = /var/run/mysql/mysql2.sock
port = 3307
pid-file = /var/run/mysql/mysql2.pid
datadir = /data/mysql2
user = mysql
log-error = /var/log/mysql/mysql2.log
and this configuration (default Centos 7)
[root@localhost ~]# df -hT /var/run
Filesystem Type Size Used Avail Use% Mounted on
tmpfs tmpfs 245M 4.5M 240M 2% /run
[root@localhost ~]#
after reboot the /var/run/mysql does not exist an starting any of the instances will fail because it can not create the socket and/or pid-file
Suggested fix:
[root@localhost ~]# cat mysqld_multi.patch
--- /usr/bin/mysqld_multi.orig 2018-03-09 18:37:19.025626239 +0000
+++ /usr/bin/mysqld_multi 2018-03-09 17:55:40.000000000 +0000
@@ -20,9 +20,10 @@
use Getopt::Long;
use POSIX qw(strftime getcwd);
use File::Path qw(mkpath);
+use File::Basename;
$|=1;
-$VER="2.16";
+$VER="2.16-dev";
my @defaults_options; # Leading --no-defaults, --defaults-file, etc.
@@ -323,12 +324,39 @@
{
@options = defaults_for_group($groups[$i]);
+ $system_user = 'mysql'; # set default system user to 'mysql'
+ for ($j = 0, $tmp= ""; defined($options[$j]); $j++)
+ {
+ if ("--user=" eq substr($options[$j], 0, 7)) {
+ $system_user = $options[$j];
+ $system_user =~ s/\-\-user\=//;
+ }
+ }
+
$basedir_found= 0; # The default
$mysqld_found= 1; # The default
$mysqld_found= 0 if (!length($mysqld));
$com= "$mysqld";
for ($j = 0, $tmp= ""; defined($options[$j]); $j++)
{
+ if ("--socket=" eq substr($options[$j], 0, 9)) {
+ $socket = $options[$j];
+ $socket =~ s/\-\-socket\=//;
+ $socket_dir = dirname($socket);
+ if (! -d $socket_dir) {
+ eval { mkpath($socket_dir, { user => $system_user }) };
+ }
+ }
+ if ("--pid-file=" eq substr($options[$j], 0, 11)) {
+ $pidfile = $options[$j];
+ $pidfile =~ s/\-\-pid-file\=//;
+ $pidfile_dir = dirname($pidfile);
+ if (! -d $pidfile_dir) {
+ eval { mkpath($pidfile_dir, { user => $system_user }) };
+ }
+ }
+
+
if ("--datadir=" eq substr($options[$j], 0, 10)) {
$datadir = $options[$j];
$datadir =~ s/\-\-datadir\=//;
@@ -341,7 +369,7 @@
if (-w $datadir) {
print "\n\nInstalling new database in $datadir\n\n";
$install_cmd="/usr/local/Percona-Server-5.7.19-17-Linux.x86_64.ssl101/bin/mysql_install_db ";
- $install_cmd.="--user=mysql ";
+ $install_cmd.="--user=$system_user ";
$install_cmd.="--datadir=$datadir";
system($install_cmd);
} else {
Description: On many modern linux systems the socket and pid-file will be created in a /var/run/mysql folder. This folder is often located on a tmpfs so the directory needs to be recreated after a reboot. The init script does this but the mysqld_multi script doesn't. How to repeat: Consider following config: [root@localhost ~]# cat /etc/my.cnf [mysqld_multi] user = root mysqladmin = /usr/bin/mysqladmin mysqld = /usr/bin/mysqld log = /var/log/mysql/mysqld_multi.log [mysqld1] socket = /var/run/mysql/mysql1.sock port = 3306 pid-file = /var/run/mysql/mysql1.pid datadir = /data/mysql1 user = mysql log-error = /var/log/mysql/mysql1.log [mysqld2] socket = /var/run/mysql/mysql2.sock port = 3307 pid-file = /var/run/mysql/mysql2.pid datadir = /data/mysql2 user = mysql log-error = /var/log/mysql/mysql2.log and this configuration (default Centos 7) [root@localhost ~]# df -hT /var/run Filesystem Type Size Used Avail Use% Mounted on tmpfs tmpfs 245M 4.5M 240M 2% /run [root@localhost ~]# after reboot the /var/run/mysql does not exist an starting any of the instances will fail because it can not create the socket and/or pid-file Suggested fix: [root@localhost ~]# cat mysqld_multi.patch --- /usr/bin/mysqld_multi.orig 2018-03-09 18:37:19.025626239 +0000 +++ /usr/bin/mysqld_multi 2018-03-09 17:55:40.000000000 +0000 @@ -20,9 +20,10 @@ use Getopt::Long; use POSIX qw(strftime getcwd); use File::Path qw(mkpath); +use File::Basename; $|=1; -$VER="2.16"; +$VER="2.16-dev"; my @defaults_options; # Leading --no-defaults, --defaults-file, etc. @@ -323,12 +324,39 @@ { @options = defaults_for_group($groups[$i]); + $system_user = 'mysql'; # set default system user to 'mysql' + for ($j = 0, $tmp= ""; defined($options[$j]); $j++) + { + if ("--user=" eq substr($options[$j], 0, 7)) { + $system_user = $options[$j]; + $system_user =~ s/\-\-user\=//; + } + } + $basedir_found= 0; # The default $mysqld_found= 1; # The default $mysqld_found= 0 if (!length($mysqld)); $com= "$mysqld"; for ($j = 0, $tmp= ""; defined($options[$j]); $j++) { + if ("--socket=" eq substr($options[$j], 0, 9)) { + $socket = $options[$j]; + $socket =~ s/\-\-socket\=//; + $socket_dir = dirname($socket); + if (! -d $socket_dir) { + eval { mkpath($socket_dir, { user => $system_user }) }; + } + } + if ("--pid-file=" eq substr($options[$j], 0, 11)) { + $pidfile = $options[$j]; + $pidfile =~ s/\-\-pid-file\=//; + $pidfile_dir = dirname($pidfile); + if (! -d $pidfile_dir) { + eval { mkpath($pidfile_dir, { user => $system_user }) }; + } + } + + if ("--datadir=" eq substr($options[$j], 0, 10)) { $datadir = $options[$j]; $datadir =~ s/\-\-datadir\=//; @@ -341,7 +369,7 @@ if (-w $datadir) { print "\n\nInstalling new database in $datadir\n\n"; $install_cmd="/usr/local/Percona-Server-5.7.19-17-Linux.x86_64.ssl101/bin/mysql_install_db "; - $install_cmd.="--user=mysql "; + $install_cmd.="--user=$system_user "; $install_cmd.="--datadir=$datadir"; system($install_cmd); } else {