はじめに
こんにちは 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インストールディレクトリ | /usr/local/mysql |
MySQLコンフィグ | /etc/my.cnf |
MySQLログディレクトリ | /usr/local/mysql/var/log |
ささ、それでは手順に参りましょう
まずはMySQLをサーバに入れます
MySQLインストール
その前に
- インストール手順はtarボールの中にあるINSTALL-SOURCEに書いてあります
- cmakeのオプションは同じくtarボールの中にあるCMakeLists.txtを参考にお好きなものをどうぞ
開発ツールをインストール
[bash gutter="false"] shell> yum groupinstall "Development Tools" shell> yum install cmake [/bash]
ソース置き場に移動
[bash gutter="false"] shell> cd /usr/local/src/ [/bash]
ソースコードを取得
MySQLのサイトからダウンロードしてください
tarボールを解凍
[bash gutter="false"] shell> tar xzvf mysql-5.6.10.tar.gz [/bash]
グループとユーザを作成
[bash gutter="false"] shell> groupadd mysql shell> useradd -g mysql -d /usr/local/mysql mysql [/bash]
権限変更
[bash gutter="false"] shell> chown -R mysql. mysql-5.6.10 [/bash]
移動
[bash gutter="false"]shell> cd mysql-5.6.10[/bash]
ビルド
ビルドにはcmake2.6以上が必要です。
[bash gutter="false"]shell> cmake -V[/bash]
で確認
[shell gutter="false"] 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]
コンパイル
[bash gutter="false"]shell> make -j 3[/bash]
※使うコア数は環境に合わせましょう
インストール
[bash gutter="false"]shell> make -j 3 install[/bash]
パスを通す
やり方は自由で
私は/etc/profileにこんな感じで追記しました
[bash gutter="false"]
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 [/bash]
MySQLのインストールシェルを実行
[bash gutter="false"]shell> scripts/mysql_install_db --user=mysql[/bash]
起動スクリプトを設置
[bash gutter="false"]shell> cp support-files/mysql.server /etc/init.d/mysql[/bash]
MySQLベースディレクトリの権限を設定
[bash gutter="false"]shell> chown -R mysql. /usr/local/mysql[/bash]
/etc/my.cnf(もちろん参考で)
[bash] [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 [/bash]
パラメタ名 | 役割 |
---|---|
slave_parallel_workers | スレーブで起動するSQLスレッド数を指定 |
binlog-row-image=minimal | 変更された行イメージだけを保持 |
gtid-mode=on | GTIDモードを有効にする |
enforce-gtid-consistency=on | 非トランザクションテーブルを更新し、単一のステートメントを許可する(って書いてあった) |
下2つがGTID使う場合必須です
MySQL起動
[bash gutter="false"]shell> /etc/init.d/mysql start[/bash]
rootユーザのパスなどを設定するスクリプトを実行
[bash gutter="false"]shell> mysql_secure_installation[/bash]
[bash gutter="false"] 「ERROR 1372 (HY000) at line 1: Password hash should be a 41-digit hexadecimal number」 [/bash]
な人はmy.cnfにold_passwords=1が入っているかもしれないのでコメントアウトしてmysqlを再起動してください 旧バージョンからアップグレードの人はmysql_upgrade必要かも
自動起動の設定
[bash gutter="false"] shell> chkconfig --add mysql shell> chkconfig mysql on [/bash]
レプリケーション用のユーザを作成
面倒なので3つのサーバ間なら誰がどこからでもレプリケーションできるようにします
[bash gutter="false"] 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; [/bash]
レプリケーション環境の構築
ここまでやったらmaster01のスナップショットからmaster02とslave01を複製しました
コピーしたらこれはやっといてね
でないとサーバがユニークにならんのさ
さて、それではレプリケーションをはじめましょう
[bash gutter="false"] mysql> CHANGE MASTER TO MASTER_HOST = 'master01', MASTER_PORT = 3306, MASTER_USER = '<USER>', MASTER_PASSWORD ='<PASSWORD>', MASTER_AUTO_POSITION = 1; mysql> START SLAVE; [/bash]
状態を確認 うまくいったかなー
[bash gutter="false"] mysql> SHOW SLAVE STATUS\G
Slave_IO_Running: Yes Slave_SQL_Running: Yes [/bash]
うん、いい感じ
SHOW SLAVE STATUSのパラメタ的にはこのあたりが5.6から追加になっている部分ですね
[bash gutter="false"] 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 [/bash]
Oracle様の資料を読んでいない悪い子のためにGTID補足
[bash gutter="false"]e1eedd5d-9182-11e2-b260-36d7966a4f4e:1-313
「:」をデリミタにして e1eedd5d-9182-11e2-b260-36d7966a4f4e = master01のUUID 1-313 = 実行したトランザクションのID [/bash]
さて、ではmaster01でSQLを一発
[bash gutter="false"]mysql> CREATE DATABASE repl_test;[/bash]
GTIDはどうなったかな
[bash gutter="false"] mysql> SELECT @@global.gtid_executed; +--------------------------------------------+ | @@global.gtid_executed | +--------------------------------------------+ | e1eedd5d-9182-11e2-b260-36d7966a4f4e:1-314 | +--------------------------------------------+ [/bash]
インクリメントしてますね
そんじゃmaster02でも確認しましょう まずはGTIDから
[bash gutter="false"] mysql> SELECT @@global.gtid_executed; +--------------------------------------------------------------------------------------+ | @@global.gtid_executed | +--------------------------------------------------------------------------------------+ | 2c92dbad-920f-11e2-b5f4-32cc6aab1d8f:1-2, | | e1eedd5d-9182-11e2-b260-36d7966a4f4e:1-314 | +--------------------------------------------------------------------------------------+ [/bash]
うむうむ、master01のID314のトランザクションが流れてきてますね さて、DBはできてるかな
[bash gutter="false"] mysql> SHOW DATABASES; +--------------------+ | Database | +--------------------+ | information_schema | | mysql | | performance_schema | | repl_test | +--------------------+ [/bash]
苦しゅうない
ここまで確認できたらslave01もmaster01からレプリケーションするようにしてあげましょう
できたかな
ここまででこんな構成になってるはず
さぁ次はmaster01に障害があった体でslave01のマスターをmaster01からmaster02にスイッチします
シナリオはこんな感じ
- master01がダウン
- master02へ更新が向く
- masterを失ったslave01は更新データがもらえず途方にくれる
- そこに通りすがりのエンジニアが手動でCHANGE MASTERしてくれる
- slave01はmaster02から更新データを取得し最新に保たれる
ではやってみます
1.master01を停止する
IOスレッドが切れたことを確認
● master02
[bash gutter="false"] mysql> show slave status\G Slave_IO_State: Reconnecting after a failed master event read Slave_IO_Running: Connecting Slave_SQL_Running: Yes [/bash]
● slave01
[bash gutter="false"] mysql> show slave status\G Slave_IO_State: Reconnecting after a failed master event read Slave_IO_Running: Connecting Slave_SQL_Running: Yes [/bash]
マスターへ接続ができなくなったのでmaster02とslave01のスレッドを止めます
[bash gutter="false"]mysql> STOP SLAVE;[/bash]
2.master02のデータを更新します
テーブル作成
[bash gutter="false"]mysql> USE repl_test; mysql> CREATE TABLE switch ( -> id integer PRIMARY KEY AUTO_INCREMENT, -> value integer NOT NULL); [/bash]
DB削除
[bash gutter="false"]mysql> DROP DATABASE repl_test;[/bash]
別のDBとテーブルを作成
[bash gutter="false"]mysql> CREATE DATABASE repl_test2;[/bash] [bash gutter="false"]mysql> USE repl_test2;[/bash] [bash gutter="false"] mysql> CREATE TABLE switch2 ( -> id integer PRIMARY KEY AUTO_INCREMENT, -> value integer NOT NULL); [/bash]
レコード追加
[bash gutter="false"]mysql> INSERT INTO switch2(value) VALUES(777);[/bash] [bash gutter="false"] 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 [/bash]
3.slave01のマスターをmaster01からmaster02へスイッチ
[bash gutter="false"] mysql> CHANGE MASTER TO MASTER_HOST = 'master02', -> MASTER_PORT = 3306, -> MASTER_USER = '<USER>', -> MASTER_PASSWORD ='<PASSWORD>', -> MASTER_AUTO_POSITION = 1; mysql> START SLAVE; [/bash]
レプリケーションの状態を確認
[bash gutter="false"] 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 [/bash]
復習
[bash gutter="false"] 2c92dbad-920f-11e2-b5f4-32cc6aab1d8f:1-7
「:」をデリミタにして 2c92dbad-920f-11e2-b5f4-32cc6aab1d8f = master02のUUID 1-7 = さっき実行したトランザクション [/bash]
ちゃんとレプリケートされたようですね
ではデータも確認しましょう
[bash gutter="false"] mysql> SHOW DATABASES; +--------------------+ | Database | +--------------------+ | information_schema | | mysql | | performance_schema | | repl_test2 | +--------------------+ [/bash] [bash gutter="false"] mysql> USE repl_test2; mysql> SELECT * FROM switch2; +----+-------+ | id | value | +----+-------+ | 1 | 777 | +----+-------+ [/bash]
以上!
まとめ
● インストール
・基本的には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