準備
我是在CentOS
上使用docker
部署,因此需要提前準備與docker
相關的操作.
docker
配置
映射
一個主機對多個虛擬機,所以需要使用不同的具名配置文件夾,比如/etc/mysql/my.cnf.d/master01
來做不同mysql-docker
實例的啓動項的配置區分.除此之外還有數據文檔配置的區分:/var/lib/mysql/master01
mysql-docker
一般默認的數據及啓動項配置分別對應/var/lib/mysql
和/etc/my.cnf.d
,對應起來就是如下關係:
/etc/mysql/my.cnf.d/master01:/etc/my.cnf.d
/var/lib/mysql/master01:/var/lib/mysql
可能涉及創建文件夾
mkdir -p /etc/mysql/my.cnf.d/master01 /var/lib/mysql/master01
# 權限設置要嚴格,否則有些配置文件,比如my.cnf會失效
chmod 645 -R /etc/mysql/my.cnf.d/master01
chmod 777 -R /var/lib/mysql/master01
端口
默認是3306
,我映射爲6306
鏡像
理論上是選擇mysql
的鏡像,但本次是爲搭建PXC(Percona XtraDB Cluster)
集羣做準備的,那麼選擇percona:5.7.23
權限
這裏指的是root
用戶的初始密碼如何定義和設置的問題,可以有三種選擇,三選一:
-
無密碼:
MYSQL_ALLOW_EMPTY_PASSWORD=true
-
指定密碼:
MYSQL_ROOT_PASSWORD=XXX
, 推薦. -
隨機密碼:
MYSQL_RANDOM_ROOT_PASSWORD=true
.不推薦! 因爲這意味着需要自己重置密碼,並且需要預先在
my.cnf
的[mysqld]
下配置skip-grant-tables
,自己定義密碼後還需要重啓,比較麻煩.
啓動
主節點
創建容器
以上準備工作大致勾勒出了容器創建命令:
docker create --name percona-master01 -v /var/lib/mysql/master01:/var/lib/mysql -v /etc/mysql/my.cnf.d/master01:/etc/my.cnf.d -p 6306:3306 -e MYSQL_ROOT_PASSWORD=master01 percona:5.7.23
my.cnf
要做集羣,首先至少需要配置如下幾項:
- 開啓
log-bin
- 設置
server-id
所以在對應目錄/etc/mysql/my.cnf.d/master01
下創建my.cnf
並寫入:
[mysqld]
log-bin=mysql-bin
server-id=1
sql_mode=STRICT_TRANS_TABLES,ERROR_FOR_DIVISION_BY_ZERO,NO_AUTO_CREATE_USER,NO_ENGINE_SUBSTITUTION
這裏的sql_mode
是爲了解決可能出現的1055錯誤的,與是否配置集羣無關.
提供一下初始化的便捷腳本:
cat << EOF > /etc/mysql/my.cnf.d/master01/my.cnf
[mysqld]
log-bin=mysql-bin
server-id=1
sql_mode=STRICT_TRANS_TABLES,ERROR_FOR_DIVISION_BY_ZERO,NO_AUTO_CREATE_USER,NO_ENGINE_SUBSTITUTION
EOF
啓動鏡像
運行master01
並查看日誌:
docker start percona-master01 && docker logs -f percona-master01
驗證
等待啓動完成後,可以先在宿主機上查看相應的配置是否生效,比如log-bin
:
ll /var/lib/mysql/master01 | grep mysql-bin
或者直接登錄驗證,可以連接宿主機端口,也可以連接docker虛擬機,不過需要先查詢它的IP.
- 宿主機
# 不能省略-h127.0.0.1,否則會認爲是localhost而拒絕登錄
mysql -h127.0.0.1 -P6306 -uroot -pmaster01 -Dmysql
- 虛擬機
docker exec -it percona-master01 mysql -uroot -pmaster01 -Dmysql
授權
此時服務端就搭建好了,也連接上了,還需要做些初始化操作,比如創建用戶pxc
並賦予權限.
可以在服務端,也可以在客戶端連接並操作.無論是服務端還是客戶端,實際的sql
操作自然不變.
以創建集羣用戶,賦予權限和查看集羣狀態的核心sql
爲例:
use mysql;
create user 'pxc'@'%' identified by 'pxc';
grant replication slave on *.* to 'pxc'@'%';
flush privileges;
重啓後執行:
# 查看集羣狀態
show master status;
# 查看二進制日誌相關的配置項
show global variables like 'binlog%';
# 查看server相關的配置項
show global variables like 'server%';
小結
不論怎麼連,只要是命令就可以使用shell腳本一條一條實現比如創建用戶
# -D數據庫名 -e需要執行的SQL腳本
mysql -h127.0.0.1 -P6306 -uroot -pmaster01 -Dmysql -e"create user 'pxc'@'%' identified by 'pxc';"
從節點
與主節點的配置大致相同,這裏只列出關鍵配置的區別.
權限設置要嚴格,否則有些配置文件,比如my.cnf會失效
bash-4.2$ mysql -uroot -p
mysql: [Warning] World-writable config file '/etc/my.cnf.d/my.cnf' is ignored.
mysql: [Warning] World-writable config file '/etc/mysql/my.cnf' is ignored.
mkdir -p /etc/mysql/my.cnf.d/slave01 /var/lib/mysql/slave01
chmod 644 -R /etc/mysql/my.cnf.d
chmod g+w,o+w -R /var/lib/mysql
my.cnf
仍然採用相同的思路在/etc/mysql/my.cnf.d/slave01
下創建my.cnf
並寫入:
[mysqld]
# 服務ID,不與master重複即可
server-id=2
sql_mode=STRICT_TRANS_TABLES,ERROR_FOR_DIVISION_BY_ZERO,NO_AUTO_CREATE_USER,NO_ENGINE_SUBSTITUTION
docker create --privileged --name percona-slave01 -v /var/lib/mysql/slave01:/var/lib/mysql -v /etc/mysql/my.cnf.d/slave01:/etc/my.cnf.d -p 6307:3306 -e MYSQL_ROOT_PASSWORD=slave01 percona:5.7.23
docker start percona-slave01 && docker logs -f percona-slave01
mysql -h0.0.0.0 -P6307 -uroot -pslave01 -Dmysql
查看主節點(端口是6306
)的二進制日誌(bin-log
)信息:
mysql -h0.0.0.0 -P6306 -uroot -pmaster01 -Dmysql -e'show master status;'
輸出如下:
+------------------+----------+--------------+------------------+-------------------+
| File | Position | Binlog_Do_DB | Binlog_Ignore_DB | Executed_Gtid_Set |
+------------------+----------+--------------+------------------+-------------------+
| mysql-bin.000001 | 154 | | | |
+------------------+----------+--------------+------------------+-------------------+
關聯主節點
CHANGE MASTER TO
master_host='192.168.0.122',
master_user='pxc',
master_password='pxc',
master_port=6306,
master_log_file='mysql-bin.000001',
master_log_pos=154;
start slave;
show slave status;
啓動從節點並查看從節點狀態
start slave;
show slave status;
master02和slave02搭建的命令瀑布
這裏是記錄下自己完整的操作過程,不要直接執行.
#!/bin/bash
###### master02 ######
mkdir -p /etc/mysql/my.cnf.d/master02 /var/lib/mysql/master02
chmod 645 -R /etc/mysql/my.cnf.d/master02
chmod 777 -R /var/lib/mysql/master02
docker create --name percona-master02 -v /var/lib/mysql/master02:/var/lib/mysql -v /etc/mysql/my.cnf.d/master02:/etc/my.cnf.d -p 7306:3306 -e MYSQL_ROOT_PASSWORD=master02 percona:5.7.23
cat << EOF > /etc/mysql/my.cnf.d/master02/my.cnf
[mysqld]
log-bin=mysql-bin
server-id=10
sql_mode=STRICT_TRANS_TABLES,ERROR_FOR_DIVISION_BY_ZERO,NO_AUTO_CREATE_USER,NO_ENGINE_SUBSTITUTION
EOF
docker start percona-master02 && docker logs -f percona-master02
docker exec percona-master02 mysql -uroot -pmaster02 -e"show variables like 'log_bin'"
docker exec percona-master02 mysql -uroot -pmaster02 -e"show master status;"
docker exec percona-master02 mysql -uroot -pmaster02 -e"show global variables like 'server%';"
docker exec percona-master02 mysql -uroot -pmaster02 -Dmysql -e"create user 'pxc'@'%' identified by 'pxc';"
docker exec percona-master02 mysql -uroot -pmaster02 -Dmysql -e"grant replication slave on *.* to 'pxc'@'%';"
docker exec percona-master02 mysql -uroot -pmaster02 -Dmysql -e"flush privileges;"
###### slave02 ######
mkdir -p /etc/mysql/my.cnf.d/slave02 /var/lib/mysql/slave02
chmod 645 -R /etc/mysql/my.cnf.d/slave02
chmod 777 -R /var/lib/mysql/slave02
docker create --name percona-slave02 -v /var/lib/mysql/slave02:/var/lib/mysql -v /etc/mysql/my.cnf.d/slave02:/etc/my.cnf.d -p 7307:3306 -e MYSQL_ROOT_PASSWORD=slave02 percona:5.7.23
cat << EOF > /etc/mysql/my.cnf.d/slave02/my.cnf
[mysqld]
server-id=12
sql_mode=STRICT_TRANS_TABLES,ERROR_FOR_DIVISION_BY_ZERO,NO_AUTO_CREATE_USER,NO_ENGINE_SUBSTITUTION
EOF
docker start percona-slave02
docker exec percona-slave02 mysql -uroot -pslave02 -e"CHANGE MASTER TO master_host='192.168.0.122', master_user='pxc', master_password='pxc', master_port=7306, master_log_file='mysql-bin.000003', master_log_pos=154;start slave;"
docker exec percona-slave02 mysql -uroot -pslave02 -e"start slave;"
docker exec percona-slave02 mysql -uroot -pslave02 -e"show slave status;"
缺點
如果不小心在slave
節點上進行寫操作,就會出現同步失效問題,兩種解決方案:
- 手動同步主節點的
log_bin
此時執行show slave status;
會得到如下結果:Slave_SQL_Running:No
,解決辦法是手動同步,也就是根據master
當前的日誌位置,重新執行change master
操作. - 架構變更
- 使用Mycat實現讀寫分離
- 改爲HAProxy+Mycat+PXC方式,使得每個節點都可讀可寫.