この記事は「MySQL Casual Advent Calendar 2018」20日目の記事です。
#はじめに
huatoです。
最近サーバ構築業務から遠ざかってます。
前回検証対応したときに放置していた問題点について再検証してみました。
検証目的での環境構築作業を簡略するために作成したansible playbookについても紹介しています。
前回検証時に放置してた問題点とは
https://qiita.com/huato/items/e090c56393b54e6451af
loose-group_replication_group_seedsのportは当初5.7の頃と同じ6606を設定していたが GRが正常動作しないため、エラーログを元に33061に変更
ずっと腹落ちしなかったので再検証しました。
#結果だけ先に書くと
https://dev.mysql.com/doc/refman/8.0/en/group-replication-configuring-instances.html
このページには記載が見受けられないが必須パラメータが増えていたので追加設定するか
native_passwordでgroup replicationが使用するユーザを作成しても暫定対応可能
group_replication_recovery_public_key_path
group_replication_recovery_get_public_key
#環境
CentOS Linux release 7.6.1810 (Core)
CPU:4core
RAM:4GB
Disk:40GB
MySQL 5.7.24
8.0.13
server1: 192.168.102.43 Primary
server2: 192.168.102.44 Secondary
server3: 192.168.102.45 Secondary
#OS周りの設定
検証目的なのでfirewalldを停止します。
systemctl stop firewalld
systemctl disable firewalld
selinuxも止めます。
setenforce 0
sed -i 's/SELINUX=permissive/SELINUX=disabled/g' /etc/selinux/config
reboot
今回の検証とは直接関係がありませんが
swappinessの設定はtunedが動いてるとsysctlの値が上書きされるので設定しなおします。
mkdir /etc/tuned/virtual-guest
cp /usr/lib/tuned/virtual-guest/tuned.conf /etc/tuned/virtual-guest/
vi /etc/tuned/virtual-guest/tuned.conf
vm.swappiness = 30
=>
vm.swappiness = 10
systemctl restart tuned
OS側の準備ができたので次はAnsibleで検証環境を整備します。
#Ansibleによる環境構築
ansibleはepelではなくCentOS標準リポジトリを使いました。
yum install ansible
インストールされたバージョン
ansible-2.4.2.0-2.el7.noarch
早速MySQLのインストールとGroup Replicationの設定をAnsibleで実施します。
本番環境ではパスワードべた書きせず変数にするなどして
エラー判定処理も追加して使いましょう。
template化したmy.cnfの一部
transaction_write_set_extraction=XXHASH64
loose-group_replication_group_name="{{ my_uuid }}"
loose-group_replication_start_on_boot=off
loose-group_replication_auto_increment_increment=1
loose-group_replication_local_address="{{ ansible_host }}:6606"
loose-group_replication_ip_whitelist="
{%- for host in groups[target_group] -%}
{{ hostvars[host].ansible_eth0.ipv4.address }}
{%- if not loop.last %},{% endif -%}
{%- endfor -%}"
loose-group_replication_group_seeds="
{%- for host in groups[target_group] -%}
{{ hostvars[host].ansible_eth0.ipv4.address }}:6606
{%- if not loop.last %},{% endif -%}
{%- endfor -%}"
loose-group_replication_bootstrap_group=off
ansibleのhosts指定箇所
[test2]
server1 ansible_host=192.168.102.43 set_hostname=db-master my_serverid=1
server2 ansible_host=192.168.102.44 set_hostname=db-slave my_serverid=2
server3 ansible_host=192.168.102.45 set_hostname=db-slave my_serverid=3
Group Replicationを組む箇所
---
- name: yum MySQL-python.x86_64 install
yum:
name: MySQL-python.x86_64
state: latest
disablerepo: mysql80-community
enablerepo: mysql57-community
- name: copy .my.cnf
copy:
src: roles/mysql_install/files/.my.cnf
dest: /root
group: root
mode: 600
#rpl_user
- name: create admin user
mysql_user:
state: present
host: "{{ hostvars[item].ansible_host }}"
name: rpl_user
password: dummy2
priv: '*.*:REPLICATION SLAVE'
with_items: "{{ groups[target_group] }}"
- name: install group replication 1
shell: /usr/bin/mysql -uroot -e "reset master;"
- name: install group replication 2
shell: /usr/bin/mysql -uroot -e "CHANGE MASTER TO MASTER_USER='rpl_user', MASTER_PASSWORD='dummy2' FOR CHANNEL 'group_replication_recovery';"
- name: install group replication 3
shell: /usr/bin/mysql -uroot -e "INSTALL PLUGIN group_replication SONAME 'group_replication.so';"
- name: start group replication 1
shell: /usr/bin/mysql -uroot -e "SET GLOBAL group_replication_bootstrap_group=ON;"
when: set_hostname == "db-master"
- name: install group replication 2
shell: /usr/bin/mysql -uroot -e "START GROUP_REPLICATION;"
when: set_hostname == "db-master"
- name: install group replication 3
shell: /usr/bin/mysql -uroot -e "SET GLOBAL group_replication_bootstrap_group=OFF;"
when: set_hostname == "db-master"
- name: start group replication slave
shell: /usr/bin/mysql -uroot -e "START GROUP_REPLICATION;"
when: set_hostname != "db-master"
- name: delete my.cnf
file:
path: /root/.my.cnf
state: absent
インストールするMySQLバージョン指定箇所
- name: install mysql-community-server
yum:
name: mysql-server
disable_gpg_check: yes
disablerepo: mysql80-community
enablerepo: mysql57-community
state: present
実行するplaybook
mysqlインストール処理
ansible-playbook -i hosts --extra-vars "hosts=test2 target_group=test2" setup_mysql.yml -k -u huato --ask-su-pass -vvv
group replicationを組む処理
ansible-playbook -i hosts --extra-vars "hosts=test2 target_group=test2" setup_gr.yml -k -u huato --ask-su-pass -vvv
mysqlのインストールや設定作業は手打ちでもそこまで手間ではないのですが
Group Replicationはmy.cnfに記載が必要な設定パラメータやコマンド実行の順番が煩雑なので
自動化またはmysql shll経由で作業するとオペレーションミスを防げると思います。
#構築した環境(MySQL 5.7.24)
status:
Server version: 5.7.24-log MySQL Community Server (GPL)
mysql> select * from performance_schema.replication_group_members
-> ;
+---------------------------+--------------------------------------+-------------+-------------+--------------+
| CHANNEL_NAME | MEMBER_ID | MEMBER_HOST | MEMBER_PORT | MEMBER_STATE |
+---------------------------+--------------------------------------+-------------+-------------+--------------+
| group_replication_applier | efc3fe17-0218-11e9-adb8-00505689ec08 | server3 | 3306 | ONLINE |
| group_replication_applier | f176a12b-0218-11e9-b945-005056893bba | server1 | 3306 | ONLINE |
| group_replication_applier | f19fcf16-0218-11e9-ae0b-005056894ac8 | server2 | 3306 | ONLINE |
+---------------------------+--------------------------------------+-------------+-------------+--------------+
3 rows in set (0.01 sec)
状態確認します
select member_host from performance_schema.global_status inner join performance_schema.replication_group_members where variable_name='group_replication_primary_member' AND member_id=variable_value;
+-------------+
| member_host |
+-------------+
| server1 |
+-------------+
1 row in set (0.00 sec)
問題が発生せず、Group Replicationが組み上がりました。
次はMySQL5.7をremoveしてMySQL8.0をインストールするために
データや設定ファイルを破棄します。
systemctl stop mysqld.service
yum -y remove mysql-* ; rm -rf /data /root/.my,cnf /root/.mysql_secret /etc/my.cnf*
mysql80-communityに向けて先ほどのyml書き換えてplaybook再実行します
disablerepo: mysql57-community
enablerepo: mysql80-community
一部手打ちした箇所
cd /data/
mysqld --initialize-insecure --user=mysql
mysql -uroot --connect-expired-password -e "ALTER USER 'root'@'localhost' IDENTIFIED BY 'escVieLL?';"
mysql_userモジュール箇所で止まりました。
https://github.com/ansible/ansible/issues/41116
issuesに従って設定を修正します。
mysql -uroot --connect-expired-password -e "ALTER USER 'root'@'localhost' IDENTIFIED WITH mysql_native_password BY 'escVieLL?';"
再現できました。RECOVERINGから先に進みません。
#構築した環境(MySQL 8.0.13)
Server version: 8.0.13 MySQL Community Server - GPL
mysql> select * from performance_schema.replication_group_members;
+---------------------------+--------------------------------------+-------------+-------------+--------------+-------------+----------------+
| CHANNEL_NAME | MEMBER_ID | MEMBER_HOST | MEMBER_PORT | MEMBER_STATE | MEMBER_ROLE | MEMBER_VERSION |
+---------------------------+--------------------------------------+-------------+-------------+--------------+-------------+----------------+
| group_replication_applier | bbe2ae8e-0221-11e9-943b-005056893bba | server1 | 3306 | ONLINE | PRIMARY | 8.0.13 |
| group_replication_applier | c8f4823f-0221-11e9-8b74-005056894ac8 | server2 | 3306 | RECOVERING | SECONDARY | 8.0.13 |
| group_replication_applier | cbce0973-0221-11e9-b151-00505689ec08 | server3 | 3306 | RECOVERING | SECONDARY | 8.0.13 |
+---------------------------+--------------------------------------+-------------+-------------+--------------+-------------+----------------+
3 rows in set (0.00 sec)
早速エラーログを確認します、特に気になるメッセージは見当たりません。
もう一度マニュアルを読み直します
https://dev.mysql.com/doc/refman/8.0/en/group-replication-configuring-instances.html
The recommended port for group_replication_local_address is 33061
推奨値らしいのでport 33061に内部通信のポート設定を変更しGroup Replicationを組み直しましたが
状態に変化はありませんでした。
mysql> select * from performance_schema.replication_group_members;
+---------------------------+--------------------------------------+-------------+-------------+--------------+-------------+----------------+
| CHANNEL_NAME | MEMBER_ID | MEMBER_HOST | MEMBER_PORT | MEMBER_STATE | MEMBER_ROLE | MEMBER_VERSION |
+---------------------------+--------------------------------------+-------------+-------------+--------------+-------------+----------------+
| group_replication_applier | d6d63760-0229-11e9-9ad7-005056893bba | server1 | 3306 | ONLINE | PRIMARY | 8.0.13 |
| group_replication_applier | d9451d13-0229-11e9-8c73-005056894ac8 | server2 | 3306 | RECOVERING | SECONDARY | 8.0.13 |
| group_replication_applier | da365faf-0229-11e9-9f43-00505689ec08 | server3 | 3306 | RECOVERING | SECONDARY | 8.0.13 |
+---------------------------+--------------------------------------+-------------+-------------+--------------+-------------+----------------+
3 rows in set (0.00 sec)
MySQL5.7と8.0の差分でコネクション周りで関係ありそうなところ、だとcaching_sha2_password?
ということで
試しにrpl_userの認証プラグインをnative_passwordに変更します
use mysql
set sql_log_bin=0;
ALTER USER 'rpl_user'@'192.168.102.43' IDENTIFIED WITH mysql_native_password BY 'dummy2';
ALTER USER 'rpl_user'@'192.168.102.44' IDENTIFIED WITH mysql_native_password BY 'dummy2';
ALTER USER 'rpl_user'@'192.168.102.45' IDENTIFIED WITH mysql_native_password BY 'dummy2';
set sql_log_bin=1;
動きました!
mysql> select * from performance_schema.replication_group_members;
+---------------------------+--------------------------------------+-------------+-------------+--------------+-------------+----------------+
| CHANNEL_NAME | MEMBER_ID | MEMBER_HOST | MEMBER_PORT | MEMBER_STATE | MEMBER_ROLE | MEMBER_VERSION |
+---------------------------+--------------------------------------+-------------+-------------+--------------+-------------+----------------+
| group_replication_applier | d6d63760-0229-11e9-9ad7-005056893bba | server1 | 3306 | ONLINE | PRIMARY | 8.0.13 |
| group_replication_applier | d9451d13-0229-11e9-8c73-005056894ac8 | server2 | 3306 | ONLINE | SECONDARY | 8.0.13 |
| group_replication_applier | da365faf-0229-11e9-9f43-00505689ec08 | server3 | 3306 | ONLINE | SECONDARY | 8.0.13 |
+---------------------------+--------------------------------------+-------------+-------------+--------------+-------------+----------------+
3 rows in set (0.00 sec)
マニュアルをよく読むと注意の記載がありました
https://dev.mysql.com/doc/refman/8.0/en/caching-sha2-pluggable-authentication.html
group_replication_recovery_public_key_path and
group_replication_recovery_get_public_key system variables serve the same purpose.
#まとめ
MySQL5.7と8.0でGroup Replicationの設定に細かい違いがありました。
この記事が同じ問題で困っている人の助けになれば幸いです。