Running multiple instances of MySQL on the same machine
There are various methods to run multiple instances of mysql (on different ports) on the same machine. We can either compile the mysql binary with different defaults and paths, use mysqld_multi or the MySQL Sandbox project. Still the simplest solution I’veĀ used in the past for such situations is to use the same binary and use a separate configuration file (with separate port, pid, socket and data directory). This post will explain this method.
1. Create separate data and log directories
We need to create new directories for our datadir and log folder (if used). Also we need to assign proper permissions on those folders:
mkdir /var/lib/mysql2
chown -R mysql.mysql /var/lib/mysql2/
mkdir /var/log/mysql2
chown -R mysql.mysql /var/log/mysql2
2. Create a new mysql configuration file
Next we need a separate configuration file. We can start by copying the existing one and changing the needed values. This example was taken on a debian machine that holds the mysql configurations under /etc/mysql/my.cnf. We just copy this folder and modify it from there:
cp -R /etc/mysql/ /etc/mysql2
if you use a redhat variant package then your configuration file is under /etc/my.cnf by default and you can just copy it directly:
cp /etc/my.cnf /etc/my2.cnf
(or change the path appropriately for your configuration file is in a different place).
Next, we need to edit our new configuration file and at least update the mysql port (default to 3306), the pid and socket to be different than the default ones, and also point the data and log folders to the ones created before. On my debian machine this can be done with something like this:
cd /etc/mysql2/
sed -i 's/3306/3307/g' my.cnf
sed -i 's/mysqld.sock/mysqld2.sock/g' my.cnf
sed -i 's/mysqld.pid/mysqld2.pid/g' my.cnf
sed -i 's/var\/lib\/mysql/var\/lib\/mysql2/g' my.cnf
sed -i 's/var\/log\/mysql/var\/log\/mysql2/g' my.cnf
3. Initializing and starting
Finally we need to initialize the default dbs:
mysql_install_db --user=mysql --datadir=/var/lib/mysql2/
Alternatively we can copy the existing /var/lib/mysql if this is needed (shut down mysql prior to do this).
Finally we can start our new mysql instance with:
mysqld_safe --defaults-file=/etc/mysql2/my.cnf &
We can connect to our new instance using:
mysql -S /var/run/mysqld/mysqld2.sockor
mysql -h 127.0.0.1 -P 3307
and if we no longer need it, stop it with:
mysqladmin -S /var/run/mysqld/mysqld2.sock shutdown
Here is a script we have used to create many instances that we needed for testing. Feel free to use or change it to suit your needs (it is for debian machines), and you run it with new_mysql_instance.sh <ID>
#!/bin/bash
i=$1
port=$[3306+$i]
mkdir /var/lib/mysql$i
chown -R mysql.mysql /var/lib/mysql$i/
mkdir /var/log/mysql$i
chown -R mysql.mysql /var/log/mysql$i
cp -R /etc/mysql/ /etc/mysql$i
cd /etc/mysql$i/
sed -i "s/3306/$port/g" my.cnf
sed -i "s/mysqld.sock/mysqld$i.sock/g" my.cnf
sed -i "s/mysqld.pid/mysqld$i.pid/g" my.cnf
sed -i "s/var\/lib\/mysql/var\/lib\/mysql$i/g" my.cnf
sed -i "s/var\/log\/mysql/var\/log\/mysql$i/g" my.cnf
mysql_install_db --user=mysql --datadir=/var/lib/mysql$i/
mysqld_safe --defaults-file=/etc/mysql$i/my.cnf &>
Tags: mysql, tips, Tips & Tricks

19th January 2009, 15:59
Why not use mysqlmanager?
19th January 2009, 16:21
@rusty_angel: I was not aware of this solution. Thank you for your addition.
19th January 2009, 16:26
I once spent two days writing my own scripts for that (with almost no knowlege of bash), before I found mysqlmanager
2nd February 2009, 19:42
Once you have multiple mysql instances running, how do you do a mysqldump on a particular instance?
Is it mysqldump -s=/var/mysql/mysql2.sock to dump from the 2nd instance and mysqldump -s=/var/mysql/mysql1.sock to dump from the 1st instance?
3rd February 2009, 15:07
@Jake: yes, if you run it locally you can use the
--socket=pathor-S pathparameter. While remotely just use the host/port where the respective server is listening.2nd April 2009, 18:54
mysqlmanager has been deprecated, so if you’d like to upgrade your mysql someday, you don’t want to use it.
26th October 2009, 18:29
If anyone is trying this and receive this result when installing the 2nd database:
ERROR: 1005 Can’t create table ‘db’ (errno: 13)
although all the permissions are correct … take a look into your /var/log/syslog … it is possible, that apparmor is installed and blocks any r/w access from mysqld outside its default directories …
You have to update the apparmor configuration /etc/apparmor.d/usr.sbin.mysqld – and restart apparmor!
regards
28th October 2009, 00:18
[...] Creating a 2nd MySQL Instance Very simple and straightforward. Follow these instructions on ducea.com. [...]
29th October 2009, 23:08
[...] Running multiple instances of MySQL on the same machine | MDLog:/sysadmin This entry was written by delicious and posted on October 29, 2009 at 3:08 pm and filed under links. Bookmark the permalink. Follow any comments here with the RSS feed for this post. Post a comment or leave a trackback: Trackback URL. [...]
11th December 2009, 23:30
I took this a little further by integrating it with the debian init.d script, which includes some maintenance tasks done under the mysql user debian-sys-maint. I basically pulled out the parts of the dpkg .postinst script that set this up. You can get the debian-sys-maint from /etc/mysql/debian.cnf. Here is a summary of what I did (I called my second instance mysql.replica instead of mysql2):
– sudo mkdir /var/lib/mysql.replica
sudo chown mysql.mysql /var/lib/mysql.replica
– cp -r /etc/mysql /etc/mysql.replica
edit paths, port (3307)
– cp /etc/init.d/mysql /etc/init.d/mysql.replica
edit paths
add –defaults-file=/etc/mysql.replica/my.cnf to mysqld_safe
add –defaults-file=/etc/mysql.replica/my.cnf to mysqld
– mysql_install_db –user=mysql –datadir=/var/lib/mysql.replica
– /etc/init.d/mysql.replica start
– mysql –defaults-file=/etc/mysql.replica/my.cnf -u root
ALTER TABLE user CHANGE password Password varchar(41) collate utf8_bin NOT NULL default ”;
UPDATE user SET password=PASSWORD(“”) WHERE user=’root’;
FLUSH PRIVILEGES;
REPLACE INTO user SET
host=’localhost’, user=’debian-sys-maint’, password=password(”),
Select_priv=’Y', Insert_priv=’Y', Update_priv=’Y', Delete_priv=’Y',
Create_priv=’Y', Drop_priv=’Y', Reload_priv=’Y', Shutdown_priv=’Y',
Process_priv=’Y', File_priv=’Y', Grant_priv=’Y', References_priv=’Y',
Index_priv=’Y', Alter_priv=’Y', Show_db_priv=’Y', Super_priv=’Y',
Create_tmp_table_priv=’Y', Lock_tables_priv=’Y', Execute_priv=’Y',
Repl_slave_priv=’Y', Repl_client_priv=’Y';
– update-rc.d mysql.replica defaults 19 21
The second instance can now be started and stopped (and will start automatically at boot) just like the primary instance.
16th December 2009, 00:02
@Andrew: thank you for your addition to the post.
21st February 2010, 12:26
How to setup a replication server on same hos running to instances of mysql?
any idea?
22nd February 2010, 16:28
@d.bilbao: it should work the same as on different machines. Just be sure to use the proper MASTER_PORT if needed.
30th March 2010, 15:54
[...] Running multiple instances of MySQL on the same machine | MDLog:/sysadmin As you phase MySQL out of your life, you may find that you want to centralize all your legacy MySQL db's (e.g. your 4.x MySQL db that you can't upgrade and your current 5.x that you don't want chewing up resources on your production machines and that 5.1.x that you had to install in order to make it clear to your superiors that MySQL was dead) on a single machine. This is a good guide to getting started on that. [...]
17th April 2010, 10:31
Thank you for this post. Iam going to setup replication mysql on same server. This post really help a lot!!
3rd June 2010, 20:09
In Ubuntu 10.04, paths allowed access by mysql is “secured” with apparmor. This has the effect of causing the mysql_install_db operation to fail. I’d detailed how to fix this quickly in this ubuntu forums post: http://ubuntuforums.org/showpost.php?p=9405790&postcount=6
29th October 2010, 09:49
[...] http://www.ducea.com/2009/01/19/running-multiple-instances-of-mysql-on-the-same-machine/ [...]
20th November 2010, 19:25
[...] quick google turns out this [...]
15th December 2010, 10:13
[...] Reference: ducea.com [...]
6th January 2011, 09:50
mysqld_safe A mysqld process already exists
20th January 2011, 04:28
This is really helped me a lot …
And it is very easy to understand and implement ..
23rd January 2011, 21:06
[...] This post was mentioned on Twitter by Tubagus Saepul Anwar, Rizqinofa. Rizqinofa said: Trik cara menjalankan beberapa instance Mysql dalam satu server http://bit.ly/hGTvJ2 [...]
3rd February 2011, 00:47
I don’t know if anyone’s mentioned it already, but you may also need to edit AppArmor’s settings. I had to tell AppArmor to allow MySQL to access the new folders and files.
25th March 2011, 18:44
Thanks for this, and to Andrew Pimlott for the Ubuntu stuff.
Here are some additional notes for more recent versions of Ubuntu, namely 10.04 in my case.
There is an additional line at the bottom of the mysql_xyz.cnf that needs to be updated (the include dir). This can be done automatically with the rest of the seds:
sed -i “s/\/etc\/mysql\//\/etc\/mysql$i\//g” my.cnf
Ubuntu now uses upstart to start mysql. So init.d stuff becomes irrelevant, I think. But you have to duplicate and edit the upstart script in /etc/init/mysql_xyz.conf
- change the HOME Env var as needed.
- find other references to the standard mysql install and change it to your special install. Line 24 has some gobbledigoop that I changed.
- change the exec on line 27:
exec /usr/sbin/mysqld –defaults-file=”${HOME}”/my.cnf
(note it doesn’t use mysqld_safe! Search Google for “Ubuntu mysql upstart nysqld_safe” to get few answers and many more questions. I didn’t change it.)
You’ll want to create a root password for your new mysql instance, and drop the anon accounts, etc.. Also, probably create a debian user as described above.
Then change debian.cnf so that it reflects the right sockets.
And of course do the apparmor thing, as mentioned seven times above.
With the above I can do “start mysql_xyz”, “stop mysql_xyz”, etc…
So far I haven’t had problems on my dev machine. But we’ll see what happens when I do an upgrade of Ubuntu… it should be lots of fun.
18th April 2011, 14:59
[...] http://www.ducea.com/2009/01/19/running-multiple-instances-of-mysql-on-the-same-machine/ Share this:Email This entry was posted in Personal and tagged lucid lynx, multiple instances, mysql, mysql sandbox, mysqld_multi, ubuntu. Bookmark the permalink. ← Synergy FTW [...]
20th April 2011, 07:13
This guide helped me a lot.
Thanks for the good work.
26th April 2011, 15:45
Important
MySQL Instance Manager is been deprecated in MySQL 5.1 and is removed in MySQL 5.5.
–from the mysqlmanager page.
26th April 2011, 17:20
If you get “mysqld_safe A mysqld process already exists’
It will be mostly because of the port conflict. Make sure the port number is replaced. I got this issue on CentOS because my cnf file didn’t have a port entry and hence sed couldnt replace the port=3306 value. So the new instance tried to use 3306 itself and failed.
31st May 2011, 08:43
I’ve followed your steps one by one. And finally when I got to the “moment of truth”, mysql2 started with mysqld_safe with defaults-file=/etc/mysql2/my.cnf
I even managed to connect to mysql using command line
mysql -u root -p -P 3307.
But once I execute command in mysql,
mysql> show databases;
I got all databases even from mysql that is running on port 3306.
Why is that ???
20th June 2011, 13:41
Alex, this is because mysql is stupid enough.
You need to specify -h 127.0.0.1 (-h localhost is not working !!!) to use with -P, or use -S / –socket .
20th June 2011, 13:52
I have made some improvements and Debian-adaptations to script.
Now it generates new configs in /etc/mysql$I, new init.d script /etc/init.d/mysql$I and setups new DB.
You can start DB by ‘/etc/init.d/mysqlN start’ and stop it by ‘/etc/init.d/mysqlN stop’. Also possible to do ‘killall mysqlN’
Please don`t forget to set root password as script not does this.
Work was done for Debian 6.0.1.
#!/bin/bash
i=$1
if test -z “$1″ # No command-line arg supplied?
then
echo “Usage: `basename $0` instanseNum”
exit
fi
if test -d “/etc/mysql$1″ #
then
echo “Error: Directory /etc/mysql$i already exists!”
exit
fi
port=$(($i+3306))
#make new init script
cp /etc/init.d/mysql /etc/init.d/mysql$i
#make symlink for binary ( to make ‘kill’ working )
ln -s /usr/sbin/mysqld /usr/sbin/mysqld$i
#Fix init script
sed -i “s/\/etc\/mysql/\/etc\/mysql$i/g” /etc/init.d/mysql$i
sed -i “s/\/etc\/init.d\/mysql/\/etc\/init.d\/mysql$i/g” /etc/init.d/mysql$i
sed -i “s/\/usr\/bin\/mysqld_safe\ >/\/usr\/bin\/mysqld_safe\ –defaults-file=\/etc\/mysql$i\/my.cnf\ –mysqld=mysqld$i\ >/g” /etc/init.d/mysql$i
sed -i “s/\/usr\/sbin\/mysqld\ –print-defaults/\/usr\/sbin\/mysqld$i\ –defaults-file=\/etc\/mysql$i\/my.cnf\ –print-defaults/g” /etc/init.d/mysql$i
sed -ri “s/\ mysqld$/\ mysqld$i/g” /etc/init.d/mysql$i
sed -ri “s/\ mysqld;/\ mysqld$i;/g” /etc/init.d/mysql$i
sed -ri “s/\”mysqld\”/\”mysqld$i\”/g” /etc/init.d/mysql$i
#make new config files from existing one
mkdir /etc/mysql$i/
#cp -rt /etc/mysql$i/ /etc/mysql/
cp -R /etc/mysql/* “/etc/mysql$i”
#Fix paths in script
sed -i “s/\/etc\/mysql/\/etc\/mysql$i/” /etc/mysql$i/debian-start
sed -i “s/\/etc\/init.d\/mysql/\/etc\/init.d\/mysql$i/” /etc/mysql$i/debian-start
#And make new config debian.cnf
dc=/etc/mysql$i/debian.cnf;
pass=`perl -e ‘print map{(“a”..”z”,”A”..”Z”,0..9)[int(rand(62))]}(1..16)’`;
cat /dev/null > $dc
echo “# Automatically generated for Debian scripts. DO NOT TOUCH!” >>$dc
echo “[client]” >>$dc
echo “host = localhost” >>$dc
echo “user = debian-sys-maint” >>$dc
echo “password = $pass” >>$dc
echo “socket = /var/run/mysqld/mysqld$i.sock” >>$dc
echo “[mysql_upgrade]” >>$dc
echo “host = localhost” >>$dc
echo “user = debian-sys-maint” >>$dc
echo “password = $pass” >>$dc
echo “socket = /var/run/mysqld/mysqld$i.sock” >>$dc
echo “basedir = /usr” >>$dc
# If this dir chmod go+w then the admin did it. But this file should not.
chown 0:0 $dc
chmod 0600 $dc
#Fix paths and so on in my.cnf
sed -i “s/3306/$port/g” /etc/mysql$i/my.cnf
sed -i “s/mysqld.sock/mysqld$i.sock/g” /etc/mysql$i/my.cnf
sed -i “s/mysqld.pid/mysqld$i.pid/g” /etc/mysql$i/my.cnf
sed -i “s/\/var\/lib\/mysql/\/var\/lib\/mysql$i/g” /etc/mysql$i/my.cnf
sed -i “s/\/var\/log\/mysql/\/var\/log\/mysql$i/g” /etc/mysql$i/my.cnf
sed -i “s/\/etc\/mysql/\/etc\/mysql$i/g” /etc/mysql$i/my.cnf
#Make some dirs for logs and data
mkdir /var/log/mysql$i
chown -R mysql:adm /var/log/mysql$i
chmod 2750 /var/log/mysql$i
mkdir /var/lib/mysql$i
chown -R mysql /var/lib/mysql$i
chmod 700 /var/lib/mysql$i
touch /var/lib/mysql$i/debian-5.1.flag
#Create new database
mysql_install_db –user=mysql –datadir=/var/lib/mysql$i/
#UPdate debian-sys-maint user in new database
MYSQL_BOOTSTRAP=”/usr/sbin/mysqld –bootstrap –user=mysql –skip-grant-tables –datadir=/var/lib/mysql$i”
replace_query=`echo -e \
“USE mysql\n” \
“REPLACE INTO user SET ” \
” host=’localhost’, user=’debian-sys-maint’, password=password(‘$pass’), ” \
” Select_priv=’Y', Insert_priv=’Y', Update_priv=’Y', Delete_priv=’Y', ” \
” Create_priv=’Y', Drop_priv=’Y', Reload_priv=’Y', Shutdown_priv=’Y', ” \
” Process_priv=’Y', File_priv=’Y', Grant_priv=’Y', References_priv=’Y', ” \
” Index_priv=’Y', Alter_priv=’Y', Super_priv=’Y', Show_db_priv=’Y', “\
” Create_tmp_table_priv=’Y', Lock_tables_priv=’Y', Execute_priv=’Y', “\
” Repl_slave_priv=’Y', Repl_client_priv=’Y', Create_view_priv=’Y', “\
” Show_view_priv=’Y', Create_routine_priv=’Y', Alter_routine_priv=’Y', “\
” Create_user_priv=’Y', Event_priv=’Y', Trigger_priv=’Y’ “`;
echo “$replace_query” | $MYSQL_BOOTSTRAP
#2>&1 | $ERR_LOGGER
#Now U can start new db instance by ‘using /etc/init.d/mysql$i start’ and stop it in the same way.
#
# I was lazy enough to generate and set root password to new db. Do it yourself.
# mysqladmin -h 127.0.0.1 -P 3308 -u root password ‘the2NewSuper5234Passweord’
# mysql -h 127.0.0.1 -P 3308 -u root -p
# mysql -S /var/run/mysqld/mysqld2.sock -u root -p
20th June 2011, 17:44
Alex,
You probably didn’t edit the data directory in the second my.cnf file.
26th July 2011, 09:55
[...] http://www.ducea.com/2009/01/19/running-multiple-instances-of-mysql-on-the-same-machine/ mysql ← ?????????? IP ?? ?????????? /* [...]
16th November 2011, 04:26
Great article, my only problem is once the machine has been rebooted the second MySQL instance doesn’t auto start!! How can this be achieved?
6th December 2011, 21:09
Add the second instance to /etc/rc.local
9th December 2011, 00:08
After done above steps to run second instance in my machine, i unable to connect my mysql….please help
testmachine:/var/lib/mysql2 # mysql -h 127.0.0.1 -P 3307 -uroot -pvembu
ERROR 2003 (HY000): Can’t connect to MySQL server on ’127.0.0.1′ (111)
9th December 2011, 06:44
@dinesh: check your mysql logs as it should say why it failed starting.
19th January 2012, 09:26
use these commands according your mysql instance
mysql -uroot -S /var/lib/mysql/mysql.sock -ppassword
mysql -uroot -S /var/lib/mysql2/mysql.sock -ppassword
or create script to easily connect with mysql cli
if your default mysql is inside “/usr/bin/” then create 2nd in the same directory as
touch /usr/bin/mysql2
chmod +x /usr/bin/mysql2
edit the file and paste given below lines and save it
vim /usr/bin/mysql2
#!/bin/bash
mysql –socket=/var/lib/mysql2/mysql.sock $1 $2 $3 $4 $5 $6 $7 $8
now on linux console simply type mysql2 and you will connect with your 2nd instance.
22nd January 2012, 22:39
mysql_install_db –user=mysql –datadir=/var/lib/mysql2/
I tried this solution but above command is giving error.
Any solution?