MySQL5.6.10をソースからインストールしてGTIDによるマスター切り替えを試す



はじめに

こんにちは
nendのインフラ担当してますto_maruyamaです

最近JFLの藤枝MYFCに注目してます
齊藤、市川、村瀬、ケルロン(敬称略)が見たい
嗚呼、試合見に行きたい

そんなわけで今回はMYFCならぬMySQL5.6.10 GAのインルトールを行います

ついでにGTIDを使ったマスター切り替えを試してみます

GTID使うとレプリケーションするのにMaster Position見なくていいそうですね
ほんとなんだろうなー?

概要

今回やるのはインストールと下図のマスター切り替えです

概要

Oracle社が開催した「MySQL Tech Tour – Japan」の資料のまんまにやろうとしています

資料はここにあるのでご一読を!たとえこの記事をこれ以上読む気がなくてもご一読を!

環境はこんな感じです

【サーバ構成】
サーバ名 役割
master01 MySQLマスター
master02 MySQLサブマスター
slave01 MySQLスレーブ
【サーバ仕様】
項目 内容
OS CentOS release 6.4 (mini丸)
CPU Intel(R) Xeon(R) CPU E5640 @ 2.67GHz(仮想3コア)
メモリ 2GB
ディスク 1TB
【MySQL関連】
項目 内容
MySQLインストールディレクトリ /usr/local/mysql
MySQLコンフィグ /etc/my.cnf
MySQLログディレクトリ /usr/local/mysql/var/log

ささ、それでは手順に参りましょう

まずはMySQLをサーバに入れます

MySQLインストール

その前に

  • インストール手順はtarボールの中にあるINSTALL-SOURCEに書いてあります
  • cmakeのオプションは同じくtarボールの中にあるCMakeLists.txtを参考にお好きなものをどうぞ

開発ツールをインストール

shell> yum groupinstall "Development Tools"
shell> yum install cmake

ソース置き場に移動

shell> cd /usr/local/src/

ソースコードを取得

MySQLのサイトからダウンロードしてください

tarボールを解凍

shell> tar xzvf mysql-5.6.10.tar.gz

グループとユーザを作成

shell> groupadd mysql
shell> useradd -g mysql -d /usr/local/mysql mysql

権限変更

shell> chown -R mysql. mysql-5.6.10

移動

shell> cd mysql-5.6.10

ビルド

ビルドにはcmake2.6以上が必要です。

shell> cmake -V

で確認

shell> cmake . \
-DCMAKE_INSTALL_PREFIX=/usr/local/mysql \
-DDEFAULT_SYSCONFDIR=/etc \
-DDEFAULT_CHARSET=utf8 \
-DDEFAULT_COLLATION=utf8_general_ci \
-DWITH_EXTRA_CHARSETS=all \
-DWITH_INNODB_MEMCACHED=ON \
-DWITH_LIBWRAP=ON \
-DWITH_READLINE=ON \
-DWITH_INNOBASE_STORAGE_ENGINE=1 \
-DWITH_ARCHIVE_STORAGE_ENGINE=1 \
-DWITH_BLACKHOLE_STORAGE_ENGINE=1 \
-DWITH_PERFSCHEMA_STORAGE_ENGINE=1 \
-DWITH_PARTITION_STORAGE_ENGINE=1

コンパイル

shell> make -j 3

※使うコア数は環境に合わせましょう

インストール

shell> make -j 3 install

パスを通す

やり方は自由で

私は/etc/profileにこんな感じで追記しました

# Path manipulation
if [ "$EUID" = "0" ]; then
    pathmunge /sbin
    pathmunge /usr/sbin
    pathmunge /usr/local/sbin
    pathmunge /usr/local/mysql/bin
else
    pathmunge /usr/local/sbin after
    pathmunge /usr/sbin after
    pathmunge /sbin after
    pathmunge /usr/local/mysql/bin after
fi

MySQLのインストールシェルを実行

shell> scripts/mysql_install_db --user=mysql

起動スクリプトを設置

shell> cp support-files/mysql.server /etc/init.d/mysql

MySQLベースディレクトリの権限を設定

shell> chown -R mysql. /usr/local/mysql

/etc/my.cnf(もちろん参考で)

[client]
port            = 3306
socket=/var/lib/mysql/mysql.sock
default-character-set=utf8

[mysqld]
slave_parallel_workers = 3
port            = 3306
socket=/var/lib/mysql/mysql.sock
skip-external-locking
key_buffer = 32M
max_allowed_packet = 16M
sort_buffer_size = 4M
read_buffer_size = 4M
read_rnd_buffer_size = 4M
join_buffer_size = 8M
myisam_sort_buffer_size = 1M
max_connections = 200
thread_cache_size = 200
table_open_cache = 1024
table_definition_cache=600
query_cache_type = 1
query_cache_size = 128M
query_cache_limit = 4M
tmp_table_size = 32M
max_heap_table_size = 32M

sync_binlog=1
relay-log=relay-bin
relay-log-index=relay-bin
binlog-row-image=minimal

server-id       = 1

skip_slave_start=1
expire_logs_days=2

gtid-mode=on
enforce-gtid-consistency=on
log-bin
log-bin-index=mysql-bin-index
log-slave-updates

innodb_thread_concurrency = 0
innodb_data_home_dir = /usr/local/mysql/data/
innodb_data_file_path = ibdata1:2G
innodb_file_per_table
innodb_autoextend_increment=100
innodb_log_group_home_dir = /usr/local/mysql/data/
innodb_buffer_pool_size = 1000M
innodb_additional_mem_pool_size = 20M
innodb_log_file_size = 1G
innodb_log_files_in_group=2
innodb_log_buffer_size = 8M
innodb_flush_log_at_trx_commit = 2
innodb_support_xa=1
innodb_lock_wait_timeout = 50
innodb_flush_method=O_DIRECT
innodb_io_capacity=40000
innodb_read_io_threads=8
innodb_write_io_threads=16
innodb_adaptive_flushing=1

datadir=/usr/local/mysql/data
user=mysql
skip-character-set-client-handshake
character-set-server=utf8
default-storage-engine=InnoDB
collation-server = utf8_bin
init-connect = SET NAMES utf8

long_query_time=5
log-slow-admin-statements

slow_query_log=ON
slow_query_log_file=/usr/local/mysql/var/log/mysql-slow.log

skip-name-resolve

[mysqldump]
quick
max_allowed_packet = 16M
default-character-set=utf8

[mysql]
no-auto-rehash
default-character-set=utf8

[isamchk]
key_buffer = 256M
sort_buffer_size = 256M
read_buffer = 2M
write_buffer = 2M

[myisamchk]
key_buffer = 256M
sort_buffer_size = 256M
read_buffer = 2M
write_buffer = 2M

[mysqlhotcopy]
interactive-timeout

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

[mysql.server]
basedir=/usr/local/mysql

【5.6で追加されたパラメタ】
パラメタ名 役割
slave_parallel_workers スレーブで起動するSQLスレッド数を指定
binlog-row-image=minimal 変更された行イメージだけを保持
gtid-mode=on GTIDモードを有効にする
enforce-gtid-consistency=on 非トランザクションテーブルを更新し、単一のステートメントを許可する(って書いてあった

下2つがGTID使う場合必須です

MySQL起動

shell> /etc/init.d/mysql start

rootユーザのパスなどを設定するスクリプトを実行

shell> mysql_secure_installation
「ERROR 1372 (HY000) at line 1: Password hash should be a 41-digit hexadecimal number」

な人はmy.cnfにold_passwords=1が入っているかもしれないのでコメントアウトしてmysqlを再起動してください
旧バージョンからアップグレードの人はmysql_upgrade必要かも

自動起動の設定

shell> chkconfig --add mysql
shell> chkconfig mysql on

レプリケーション用のユーザを作成

面倒なので3つのサーバ間なら誰がどこからでもレプリケーションできるようにします

mysql> GRANT REPLICATION SLAVE, REPLICATION CLIENT ON *.* TO <USER>@'master01' IDENTIFIED BY '<PASSWORD>';
mysql> GRANT REPLICATION SLAVE, REPLICATION CLIENT ON *.* TO <USER>@'master02' IDENTIFIED BY '<PASSWORD>';
mysql> GRANT REPLICATION SLAVE, REPLICATION CLIENT ON *.* TO <USER>@'slave01' IDENTIFIED BY '<PASSWORD>';
mysql> FLUSH PRIVILEGES;

レプリケーション環境の構築

ここまでやったらmaster01のスナップショットからmaster02とslave01を複製しました

コピーしたらこれはやっといてね

  • /etc/my.cnfのserver-idを変更
  • /usr/local/mysql/data/auto.cnfのserver-uuid行を削除
  • mysql再起動

でないとサーバがユニークにならんのさ

さて、それではレプリケーションをはじめましょう

mysql> CHANGE MASTER TO MASTER_HOST = 'master01',
       MASTER_PORT = 3306,
       MASTER_USER = '<USER>',
       MASTER_PASSWORD ='<PASSWORD>',
       MASTER_AUTO_POSITION = 1;
mysql> START SLAVE;

状態を確認
うまくいったかなー

mysql> SHOW SLAVE STATUS\G

Slave_IO_Running: Yes
Slave_SQL_Running: Yes

うん、いい感じ

SHOW SLAVE STATUSのパラメタ的にはこのあたりが5.6から追加になっている部分ですね

Master_UUID: e1eedd5d-9182-11e2-b260-36d7966a4f4e
Retrieved_Gtid_Set: e1eedd5d-9182-11e2-b260-36d7966a4f4e:299-313
Executed_Gtid_Set: 2c92dbad-920f-11e2-b5f4-32cc6aab1d8f:1-2,
                   e1eedd5d-9182-11e2-b260-36d7966a4f4e:1-313

Oracle様の資料を読んでいない悪い子のためにGTID補足

e1eedd5d-9182-11e2-b260-36d7966a4f4e:1-313

「:」をデリミタにして
e1eedd5d-9182-11e2-b260-36d7966a4f4e = master01のUUID
1-313 = 実行したトランザクションのID

さて、ではmaster01でSQLを一発

mysql> CREATE DATABASE repl_test;

GTIDはどうなったかな

mysql> SELECT @@global.gtid_executed;
+--------------------------------------------+
| @@global.gtid_executed                     |
+--------------------------------------------+
| e1eedd5d-9182-11e2-b260-36d7966a4f4e:1-314 |
+--------------------------------------------+

インクリメントしてますね

そんじゃmaster02でも確認しましょう
まずはGTIDから

mysql> SELECT @@global.gtid_executed;
+--------------------------------------------------------------------------------------+
| @@global.gtid_executed                                                               |
+--------------------------------------------------------------------------------------+
| 2c92dbad-920f-11e2-b5f4-32cc6aab1d8f:1-2,                                            |
| e1eedd5d-9182-11e2-b260-36d7966a4f4e:1-314                                           |
+--------------------------------------------------------------------------------------+

うむうむ、master01のID314のトランザクションが流れてきてますね
さて、DBはできてるかな

mysql> SHOW DATABASES;
+--------------------+
| Database           |
+--------------------+
| information_schema |
| mysql              |
| performance_schema |
| repl_test          |
+--------------------+

苦しゅうない

ここまで確認できたらslave01もmaster01からレプリケーションするようにしてあげましょう

できたかな

ここまででこんな構成になってるはず

現在の構成

さぁ次はmaster01に障害があった体でslave01のマスターをmaster01からmaster02にスイッチします

シナリオはこんな感じ

  1. master01がダウン
  2. master02へ更新が向く
  3. masterを失ったslave01は更新データがもらえず途方にくれる
  4. そこに通りすがりのエンジニアが手動でCHANGE MASTERしてくれる
  5. slave01はmaster02から更新データを取得し最新に保たれる

ではやってみます

1.master01を停止する

IOスレッドが切れたことを確認

● master02

mysql> show slave status\G
Slave_IO_State: Reconnecting after a failed master event read
Slave_IO_Running: Connecting
Slave_SQL_Running: Yes

● slave01

mysql> show slave status\G
Slave_IO_State: Reconnecting after a failed master event read
Slave_IO_Running: Connecting
Slave_SQL_Running: Yes

マスターへ接続ができなくなったのでmaster02とslave01のスレッドを止めます

mysql> STOP SLAVE;

2.master02のデータを更新します

テーブル作成

mysql> USE repl_test;
mysql> CREATE TABLE switch (
    -> id integer PRIMARY KEY AUTO_INCREMENT,
    -> value integer NOT NULL);

DB削除

mysql> DROP DATABASE repl_test;

別のDBとテーブルを作成

mysql> CREATE DATABASE repl_test2;
mysql> USE repl_test2;
mysql> CREATE TABLE switch2 (
    -> id integer PRIMARY KEY AUTO_INCREMENT,
    -> value integer NOT NULL);

レコード追加

mysql> INSERT INTO switch2(value) VALUES(777);
mysql> SHOW MASTER STATUS\G
File: master02-bin.000008
Position: 1466
Binlog_Do_DB:
Binlog_Ignore_DB:
Executed_Gtid_Set: 2c92dbad-920f-11e2-b5f4-32cc6aab1d8f:1-7,
                   e1eedd5d-9182-11e2-b260-36d7966a4f4e:1-314

3.slave01のマスターをmaster01からmaster02へスイッチ

mysql> CHANGE MASTER TO MASTER_HOST = 'master02',
    -> MASTER_PORT = 3306,
    -> MASTER_USER = '<USER>',
    -> MASTER_PASSWORD ='<PASSWORD>',
    -> MASTER_AUTO_POSITION = 1;
mysql> START SLAVE;

レプリケーションの状態を確認

mysql> SHOW SLAVE STATUS\G
Slave_IO_Running: Yes
Slave_SQL_Running: Yes
Master_UUID: 2c92dbad-920f-11e2-b5f4-32cc6aab1d8f
Retrieved_Gtid_Set: 2c92dbad-920f-11e2-b5f4-32cc6aab1d8f:3-7
Executed_Gtid_Set: 2c92dbad-920f-11e2-b5f4-32cc6aab1d8f:1-7,
                   e1eedd5d-9182-11e2-b260-36d7966a4f4e:1-314

復習

2c92dbad-920f-11e2-b5f4-32cc6aab1d8f:1-7

「:」をデリミタにして
2c92dbad-920f-11e2-b5f4-32cc6aab1d8f = master02のUUID
1-7 = さっき実行したトランザクション

ちゃんとレプリケートされたようですね

ではデータも確認しましょう

mysql> SHOW DATABASES;
+--------------------+
| Database           |
+--------------------+
| information_schema |
| mysql              |
| performance_schema |
| repl_test2         |
+--------------------+
mysql> USE repl_test2;
mysql> SELECT * FROM switch2;
+----+-------+
| id | value |
+----+-------+
|  1 |   777 |
+----+-------+

以上!

まとめ

● インストール

・基本的には5.5と変わらず
my.cnfの新しいパラメタ

● GTIDによるマスター切り替え

slave01のマスターをmaster01からmaster02にスイッチする場合
従来のPositionを利用したレプリケーションだと
slave01がmaster01のどのPositionまでトランザクションを実行していて
そのPositionがmaster02のどのPositionにあたるのかを調べたうえで
Positionを指定してCHANGE MASTERをする必要がありました(ああ、ややこしい)

GTIDの場合、「MASTER_AUTO_POSITION = 1」を設定するだけで
簡単にマスターのスイッチができるんですね

これはスレーブがmaster:rangeを表すIDを持っている
つまり、どのマスターのどのトランザクションまで実行したかを知っているから
のようですが、詳細は次回以降で調査していこうと思います

次回

次回はGTIDの突っ込んだ話と、MySQL WorkbenchのMySQL Utilitiesを使って遊んでみます

今回はあえてMySQL Workbenchが間に合わなくて手動で行った作業がたくさんあります
MySQL Workbenchには自動化ツールがごっさ入っているので
次回以降はそれを使って処理を華麗に自動化していきます

それではまた次回!

編集後記

5.6のパスワード桁数制限にハマってぐぐってたら下の記事を読むことになった

http://dev.mysql.com/doc/refman/5.1/ja/password-hashing.html

MySQL 4.1 (4.1.1 を含む 4.1 シリーズ) から MySQL 5.1 へのアップグレードでは、パスワード ハッシュ メカニズムが同一であるため、このアップグレードでは、ここに挙げるパスワード ハッシュに関する問題は発生しません。これ以外のアップグレード、たとえば、MySQL 4.1 よりも古いバージョンから 5.1 にする場合は、まず、MySQL 4.1 へアップグレードしてから、 5.1 へのアップグレード (インルトール) を行ないます。

インルトール≒インストールw

Add a Comment

メールアドレスが公開されることはありません。 * が付いている欄は必須項目です


*