LoginSignup
1
2

More than 5 years have passed since last update.

とりあえずお手軽にUbuntu一台でMariaDBのマスタースレーブ構築してみるよ

Last updated at Posted at 2018-01-16

はじめに

ローカルマシンでMaster-Slave構成のDBへのアクセステストを行うために、とりあえずで構築してみました。
MySQLは良く見かけるので、あえてMariaDBで。galera使って、MultiMaster構成も捨てがたかったけど、実案件でまだ使うことはなさそうなので、古き良きMaster-Slave構成を選択しました。
なお、同一サーバ上で複数のインスタンスを起動するために、mysqld_multiコマンドを使用しています。

使ったものは以下の通りです。

名前 バージョン
Ubuntu 16.04.2
MariaDB 10.2.12

手順

なお、以後、シェル中のsudoは省略しています。

まずはリポジトリ

MariaDB公式サイトに従い、リポジトリを追加します。

# apt-key adv --recv-keys --keyserver hkp://keyserver.ubuntu.com:80 0xF1656F24C74CD1D8
# vi /etc/apt/sources.list.d/mariadb.list (以下記述)
deb [arch=amd64,i386] http://ftp.yz.yamagata-u.ac.jp/pub/dbms/mariadb/repo/10.2/ubuntu xenial main
deb-src http://ftp.yz.yamagata-u.ac.jp/pub/dbms/mariadb/repo/10.2/ubuntu xenial main

# apt-get update

そして、インストール

リポジトリからmariadb-serverをインストールします。

# apt-get install mariadb-server

余分なユーザーやテーブルを削除した後、一旦、サーバを止めます。

# mysql_secure_installation
# service mysql stop

スレーブ用インスタンスの作成

スレーブ用のデータディレクトリを作成し、データの初期設定を行います。

# mkdir /var/lib/mysql-slave
# chown mysql:mysql /var/lib/mysql-slave
# mysql_install_db --datadir=/var/lib/mysql-slave

二つのインスタンスを立ち上げる

my.cnfを複数インスタンス用に変更します。

# cp /etc/mysql/my.cnf /etc/mysql/my.cnf.orig
# vi /etc/mysql/my.cnf  (下記の内容を追加)
my.cnf
(追加部分)
[mysqld_multi]
user        = root
password        = hogehoge
mysqld          = /usr/bin/mysqld_safe
mysqladmin      = /usr/bin/mysqladmin

[mysqld1]
pid-file    = /var/run/mysqld/mysqld.pid
socket      = /var/run/mysqld/mysqld.sock
port        = 3306
datadir     = /var/lib/mysql
general_log_file        = /var/log/mysql/mysql.log
general_log             = 1
server-id       = 1
report_host     = master1
log_bin         = /var/log/mysql/mariadb-bin
log_bin_index       = /var/log/mysql/mariadb-bin.index
expire_logs_days    = 3
max_binlog_size         = 100M

[mysqld2]
pid-file    = /var/run/mysqld/mysqld-slave.pid
socket      = /var/run/mysqld/mysqld-slave.sock
port        = 3307
datadir     = /var/lib/mysql-slave
general_log_file        = /var/log/mysql/mysql-slave.log
general_log             = 1
server-id       = 2
report_host     = slave1
# slaves
relay_log       = /var/log/mysql/relay-bin
relay_log_index = /var/log/mysql/relay-bin.index
relay_log_info_file = /var/log/mysql/relay-bin.info
read_only

mysqld1は、最初にインストールされたインスタンスでマスター部分になります。binary logを有効にし、server-idを指定しています。
mysqld2が、手動で追加したインスタンスでスレーブ部分になります。mysqld1の内容をコピーしてきて、PID、ソケット、データディレクトリなどをスレーブ用に変更しました。また、ポートを3307にしています。さらに、今回はrelay logを有効にし、read_onlyにしています。

では、mysqld_multiを使って、二つのインスタンスが立ち上がるか確認してみます(なお、この時点では二つのインスタンスはmaster-slaveの関係になっていません)。

# mysqld_multi start
# mysqld_multi report   (確認用)

Reporting MariaDB servers
MariaDB server from group: mysqld1 is running
MariaDB server from group: mysqld2 is running

マスターとスレーブ

それでは、マスターからスレーブにデータをコピーし、同期を行うことにします。

マスター側

まず、マスター側サーバで、レプリケーション用のユーザを作成し、また、binary logの状態を記録しておきます。

# mysql -u root -P 3306 -h 127.0.0.1
> grant replication slave on *.* to repl@127.0.0.1 identified by 'REPLのパスワード';
> flush tables with read lock;
> show master status;  (FileとPositionを記録しておく)
+--------------------+----------+--------------+------------------+
| File               | Position | Binlog_Do_DB | Binlog_Ignore_DB |
+--------------------+----------+--------------+------------------+
| mariadb-bin.000012 |      663 |              |                  |
+--------------------+----------+--------------+------------------+

つづいて、マスター側のデータをダンプします。

# mysqldump -u root -p --all-databases --lock-all-tables -P 3306 -h 127.0.0.1 > /tmp/dbdump.db

さきほどread lockをかけていたので、忘れずにlockを解除しておきます。

# mysql -u root -P 3306 -h 127.0.0.1
> unlock tables;

スレーブ側

続いて、スレーブ側にマスターの設定を行い、スレーブを開始します。
問題なければ、show slave statusでパラメータが表示されるはずです。

# mysql -u root -P 3307 -h 127.0.0.1 < /tmp/dbdump.db
> change master to master_host='127.0.0.1', master_port=3306, master_user='repl', master_password='REPLのパスワード', master_log_file='記録したbinary logのファイル名', master_log_pos=記録したbinary logのPosition;
> start slave
> show slave status\G (確認用)
*************************** 1. row ***************************
               Slave_IO_State: Waiting for master to send event
                  Master_Host: 127.0.0.1
                  Master_User: repl
                  Master_Port: 3306
                Connect_Retry: 60
              Master_Log_File: mariadb-bin.000012
          Read_Master_Log_Pos: 663
               Relay_Log_File: relay-bin.000018
                Relay_Log_Pos: 964
                            (略)

ユーザと作業用databaseの作成

スレーブ側インスタンスにはread_onlyを付けていますが、このままでは、最初に作られた万能ユーザしか居ませんので、書き込みし放題です。
作業用データベースと、作業用ユーザを作成します。
データベース名や、作業用ユーザのIDやパスワードは適宜書き換えてください。(まさかデータベース用アカウントにSCOTT/TIGERを使っている人はいませんよね・・・)。

# mysql -u root -P 3306 -h 127.0.0.1
> create database workdb;
> create user scott@'127.0.0.1' identified by 'tiger';
> grant all on workdb.* to scott@'127.0.0.1';

スタートアップ

さて、このままでは、init.dには従来のmysqlが登録されたままになっているため、サーバを再起動したときに、マスター側のインスタンスしか立ち上がらないということになります。
mysqld_multi用のスクリプトを作成し、それと置き換えることにします。

# update-rc.d mysql remove
# cp /etc/init.d/mysql /etc/init.d/mysql_multi
# vi /etc/init.d/mysql_multi (以下のスクリプトを作成)

mysqld_multiの内容 (ひどい手抜き)

#!/bin/bash
#
### BEGIN INIT INFO
# Required-Start:    $remote_fs $syslog
# Required-Stop:     $remote_fs $syslog
# Should-Start:      $network $named $time
# Should-Stop:       $network $named $time
# Default-Start:     2 3 4 5
# Default-Stop:      0 1 6
### END INIT INFO
#
set -e
set -u
${DEBIAN_SCRIPT_DEBUG:+ set -v -x}

test -x /usr/sbin/mysqld || exit 0

. /lib/lsb/init-functions

SELF=$(cd $(dirname $0); pwd -P)/$(basename $0)

if [ -f /etc/default/mysql ]; then
  . /etc/default/mysql
fi

# Safeguard (relative paths, core dumps..)
cd /
umask 077

case "${1:-''}" in
  'start')
  /usr/bin/mysqld_multi start
  ;;

  'stop')
  /usr/bin/mysqld_multi stop
  ;;

  'restart')
  $SELF stop
  $SELF start
  ;;

  *)
  echo "Usage: $SELF start|stop|restart"
  exit 1
  ;;
esac

スクリプトを登録します。

# update-rc.d mysql_multi defaults
# update-rc.d mysql_multi enable

これで、サーバの起動と終了がserviceコマンドで行えるようになるはず・・・

# service mysql_multi start
# mysqld_multi report
Reporting MariaDB servers
MariaDB server from group: mysqld1 is running
MariaDB server from group: mysqld2 is running

次に停止の確認。

# service mysql_multi stop
# mysqld_multi report
Wide character in print at /usr/bin/mysqld_multi line 599.
Reporting MariaDB servers
MariaDB server from group: mysqld1 is not running
MariaDB server from group: mysqld2 is running

あ、あれ・・・。
To-Do: 原因が分かったら記事を修正する。
(未完)

logrotate(追記)

このままでは、logrotateがマスター側のログのみを対象にしてしまうので、スレーブ側のログも対象にする。

# vi /etc/logrotate.d/mysql-server

下の行に、mysql-slave.logを追加します。
/var/log/mysql/mysql.log /var/log/mysql/mysql-slow.log /var/log/mysql/mariadb-slow.log /var/log/mysql/error.log
↓
/var/log/mysql/mysql.log /var/log/mysql/mysql-slow.log /var/log/mysql/mariadb-slow.log /var/log/mysql/error.log /var/log/mysql/mysql-slave.log

あと、ログがうまく書き込まれないケースがあるようなので、maskを640から660に変更しておきます。(調べてない)
create 640 mysql adm
↓
create 660 mysql adm

character-set(追記)

デフォルトだとcharacter-setがlatin1なので、utf8mb4に変更します。
my.cnfにcharacter-setを追記します。

my.cnf
(追加部分のみ)
[client]
default-character-set = utf8mb4

[mysql]
default-character-set = utf8mb4

[mysqld1]
character-set-server = utf8mb4

[mysqld2]
character-set-server = utf8mb4
1
2
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
1
2