1つのホスト上に複数のMySQLを立ち上げる

カテゴリ: My Web Development / 公開日: 2012年11月04日(日曜)17:46 / 投稿者: Tom Goodsun

最近ではレプリケーションによってDBへの負荷を分散するといった仕組みが取られることがほとんどです。
レプリケーションとは、データを更新するマスターDBの複製(レプリカ)を別のMySQLサーバーに作る仕組みで、複製となるものをスレーブといいます。

通常考えると、この構成を作るには必要なスレーブ分だけホストサーバーが必要のように思われます。
しかし、本番用の構成ならまだしも、開発用ともなるとそれほどコストをかけられません。

mobageも本番構成で1つのホスト上に複数のMySQLを立ち上げる方法をとっているそうで、MySQLもそういった仕組みが予め用意されています。(この方法はmobageとは若干方法が異なります。)

重要なのは、ひとつのMySQLインスタンスに対して、IPアドレスとポート番号の一意の組合せを与えることです。
Linuxの場合、1つのNICに対して複数のIPアドレスを持たせることができますが、今回は1つのIPアドレスに対して複数のポート番号を指定することにします。

まずは、my.cnfをバックアップを取って、設定をしてみましょう。

# cp -upv /etc/m.cnf /etc/my.cnf.backup
# vi /etc/my.cnf

[mysqld_multi]
mysqld=/usr/bin/mysqld_safe
mysqladmin=/usr/bin/mysqladmin
user=root
password={your_password}

[mysqld]
user=mysql
symbolic-links=0
character-set-server=utf8
skip-character-set-client-handshake
bind-address=127.0.0.1
federated

[mysqld1]
server-id=1
sync_binlog=1
datadir=/var/lib/mysql/multi1
socket=/var/lib/mysql/multi1/mysql.sock
port=3306

[mysqld2]
server-id=2
sync_binlog=1
datadir=/var/lib/mysql/multi2
socket=/var/lib/mysql/multi2/mysql.sock
port=3307

[mysqld3]
server-id=3
sync_binlog=1
datadir=/var/lib/mysql/multi3
socket=/var/lib/mysql/multi3/mysql.sock
port=3308

[mysqld_safe]
log-error=/var/log/mysqld.log
pid-file=/var/run/mysqld/mysqld.pid

[client]
default-character-set=utf8
  • [mysqld_multi] mysqld_multiの設定を記述
  • [mysqld] 共通の設定をmysqldに記述
  • [mysqld1]インスタンス1の設定
  • [mysqld2]インスタンス2の設定
  • [mysqld3]インスタンス3の設定

各インスタンス用のデータディレクトリを用意して、MySQLの基本DBをインストールします。

# mkdir /var/lib/mysql/multi{1,2,3}
# chown mysql: /var/lib/mysql/multi*
# mysql_install_db --datadir=/var/lib/mysql/multi1/
# mysql_install_db --datadir=/var/lib/mysql/multi2/
# mysql_install_db --datadir=/var/lib/mysql/multi3/

これで、各インスタンスに対してDBをインストールすれば基本的な設定は終わりなのですが、システムとして運用するために予め自動起動設定を準備しておきます。
起動スクリプトはhttp://yaplog.jp/watarin/archive/53のものを拝借します。

# vi /etc/init.d/mysqld_multi


#!/bin/sh

# Mysql daemon start/stop script.
#

# Usually this is put in /etc/init.d (at least on machines SYSV R4
# based systems) and linked to /etc/rc3.d/S99mysql and /etc/rc0.d/S01mysql.
# When this is done the mysql server will be started when the machine is started
# and shut down when the systems goes down.

# Comments to support chkconfig on RedHat Linux
# chkconfig: 2345 90 90
# description: A very fast and reliable SQL database engine.

# The following variables are only set for letting mysql.server find things
# if you want to affect other MySQL variables, you should make your changes
# in the /etc/my.cnf or other configuration files

MYSQLDIR=/usr
PATH=/sbin:/usr/sbin:/bin:/usr/bin:/usr/local/bin:$MYSQLDIR/bin
export PATH

# See how we were called.
case "$1" in
start)
echo -n "Starting mysqld: "
$MYSQLDIR/bin/mysqld_multi start 1,2,3
echo
;;
stop)
echo -n "Shutting down mysqld: "
$MYSQLDIR/bin/mysqld_multi stop 1,2,3
echo
;;
status)
$MYSQLDIR/bin/mysqld_multi report 1,2,3
;;
restart)
$0 stop
$0 start
;;
*)
echo "Usage: $0 {start|stop|restart|status}"
exit 1
esac

exit 0


# chmod 755 /etc/init.d/mysqld_multi
# chkconfig --add /etc/init.d/mysqld_multi

ntsysvなどを使って、mysqldを自動起動設定から外し、mysqld_multiを追加します。
ここまで来たら、mysqld_multiを起動させましょう。

# /etc/init.d/mysqld_multi start

起動スクリプトのコマンドはstatusやstop、restartがあります。

ここからが一番注意が必要です。
まずはどれでもいいので、MySQLへ接続してみます。

# mysql -u root -p -h 127.0.0.1 -P 3306

パスワードはまだ設定していませんで、なしでOKです。
-hオプションで接続先のホストを指定するのですが、省略すると「localhost」が割り当てられるのですが、明示的にlocalhostを指定した場合でも「localhost」が指定されるとポートは3306が指定され、ソケットファイルも/var/lib/mysql以下にあるものが使用されてしまいます。
これは明示的にポートを指定しても上書きされてしまうとのことで、ホスト名はローカルループバックアドレスである「127.0.0.1」を指定します。

これはphpMyAdminやほかのクライアントを使う場合も同じですので、注意しましょう。