簡介:應用程序僅須要鏈接mycat,後端服務器的讀寫分離由mycat進行控制,後端服務器數據的同步由MySQL主從同步進行控制。java
本次實驗環境架構圖
node
服務器主機規劃mysql
主機名 | IP | 功能 | 備註 |
---|---|---|---|
linux-node1 | 192.168.56.11 | mycat | 須要安裝MySQL不用啓動 |
linux-node2 | 192.168.56.12 | mysql-master1,mysql-slave1 | slave1端口:3307 |
linux-node3 | 192.168.56.13 | mysql-master2,mysql-slave2 | slave2端口:3307 |
建立mysql用戶linux
groupadd mysql useradd -r -g mysql -s /bin/false mysql
安裝MySQLsql
yum install -y libaio cd /usr/local/src/ wget http://mirrors.sohu.com/mysql/MySQL-5.7/mysql-5.7.17-linux-glibc2.5-x86_64.tar.gz tar -zxf mysql-5.7.17-linux-glibc2.5-x86_64.tar.gz cp -rf mysql-5.7.17-linux-glibc2.5-x86_64 /data/app/mysql-3306 cp -rf mysql-5.7.17-linux-glibc2.5-x86_64 /data/app/mysql-3307 chown -R mysql:mysql /data/app/mysql-3306 chown -R mysql:mysql /data/app/mysql-3307 /data/app/mysql-3306/bin/mysqld --initialize-insecure --user=mysql --basedir=/data/app/mysql-3306 --datadir=/data/app/mysql-3306/data /data/app/mysql-3307/bin/mysqld --initialize-insecure --user=mysql --basedir=/data/app/mysql-3307 --datadir=/data/app/mysql-3307/data
須要修改的參數:shell
master端數據庫
cat > /data/app/mysql-3306/my.cnf<<EOF [client] port = 3306 socket = /data/app/mysql-3306/mysql.sock [mysqld] port = 3306 user = mysql server-id = 1 bind-address = 0.0.0.0 basedir = /data/app/mysql-3306 datadir = /data/app/mysql-3306/data socket = /data/app/mysql-3306/mysql.sock pid-file = /data/app/mysql-3306/mysql.pid log-error = /data/app/mysql-3306/mysqld.log skip-name-resolve log_bin = mysql-bin log-slave-updates auto-increment-increment = 2 auto-increment-offset = 1 sql_mode=NO_ENGINE_SUBSTITUTION,STRICT_TRANS_TABLES EOF chown mysql.mysql /data/app/mysql-3306/my.cnf
slave端後端
cat > /data/app/mysql-3307/my.cnf<<EOF [client] port = 3307 socket = /data/app/mysql-3307/mysql.sock [mysqld] port = 3307 user = mysql server-id = 11 bind-address = 0.0.0.0 basedir = /data/app/mysql-3307 datadir = /data/app/mysql-3307/data socket = /data/app/mysql-3307/mysql.sock pid-file = /data/app/mysql-3307/mysql.pid log-error = /data/app/mysql-3307/mysqld.log skip-name-resolve log_bin = mysql-bin sql_mode=NO_ENGINE_SUBSTITUTION,STRICT_TRANS_TABLES EOF chown mysql.mysql /data/app/mysql-3307/my.cnf
master端服務器
cat > /data/app/mysql-3306/my.cnf<<EOF [client] port = 3306 socket = /data/app/mysql-3306/mysql.sock [mysqld] port = 3306 user = mysql server-id = 2 bind-address = 0.0.0.0 basedir = /data/app/mysql-3306 datadir = /data/app/mysql-3306/data socket = /data/app/mysql-3306/mysql.sock pid-file = /data/app/mysql-3306/mysql.pid log-error = /data/app/mysql-3306/mysqld.log skip-name-resolve log_bin = mysql-bin log-slave-updates auto-increment-increment = 2 auto-increment-offset = 2 sql_mode=NO_ENGINE_SUBSTITUTION,STRICT_TRANS_TABLES EOF chown mysql.mysql /data/app/mysql-3306/my.cnf
slave 端架構
cat > /data/app/mysql-3307/my.cnf<<EOF [client] port = 3307 socket = /data/app/mysql-3307/mysql.sock [mysqld] port = 3307 user = mysql server-id = 22 bind-address = 0.0.0.0 basedir = /data/app/mysql-3307 datadir = /data/app/mysql-3307/data socket = /data/app/mysql-3307/mysql.sock pid-file = /data/app/mysql-3307/mysql.pid log-error = /data/app/mysql-3307/mysqld.log skip-name-resolve log_bin = mysql-bin sql_mode=NO_ENGINE_SUBSTITUTION,STRICT_TRANS_TABLES EOF chown mysql.mysql /data/app/mysql-3307/my.cnf
linux-node2和linux-node3都執行以下命令
touch /data/app/mysql-3306/mysqld.log && chown mysql.mysql /data/app/mysql-3306/mysqld.log sed -i 's#/usr/local/mysql#/data/app/mysql-3306#g' /data/app/mysql-3306/bin/mysqld_safe /data/app/mysql-3306/bin/mysqld_safe --defaults-file=/data/app/mysql-3306/my.cnf --basedir=/data/app/mysql-3306 --datadir=/data/app/mysql-3306/data --user=mysql & touch /data/app/mysql-3307/mysqld.log && chown mysql.mysql /data/app/mysql-3307/mysqld.log sed -i 's#/usr/local/mysql#/data/app/mysql-3307#g' /data/app/mysql-3307/bin/mysqld_safe /data/app/mysql-3307/bin/mysqld_safe --defaults-file=/data/app/mysql-3307/my.cnf --basedir=/data/app/mysql-3307 --datadir=/data/app/mysql-3307/data --user=mysql &
檢查端口是否正常
ss -lntup |egrep '3306|3307' tcp LISTEN 0 80 *:3306 *:* users:(("mysqld",19973,22)) tcp LISTEN 0 80 *:3307 *:* users:(("mysqld",20537,22))
第一步先配置主從模式
master端
cd /data/app/mysql-3306/ ./bin/mysql -uroot -p -S mysql.sock -P 3306 mysql> CREATE USER 'repl'@'192.%' IDENTIFIED BY 'mysql'; Query OK, 0 rows affected (0.05 sec) mysql> GRANT REPLICATION SLAVE ON *.* TO 'repl'@'192.%'; Query OK, 0 rows affected (0.00 sec) mysql> show master status; +------------------+----------+--------------+------------------+-------------------+ | File | Position | Binlog_Do_DB | Binlog_Ignore_DB | Executed_Gtid_Set | +------------------+----------+--------------+------------------+-------------------+ | mysql-bin.000001 | 613 | | | | +------------------+----------+--------------+------------------+-------------------+ 1 row in set (0.00 sec)
slave端
cd /data/app/mysql-3307/ ./bin/mysql -uroot -p -S mysql.sock -P 3307 mysql> CHANGE MASTER TO MASTER_HOST='192.168.56.12', -> MASTER_PORT=3306, -> MASTER_USER='repl', -> MASTER_PASSWORD='mysql', -> MASTER_LOG_FILE='mysql-bin.000001', -> MASTER_LOG_POS=613; Query OK, 0 rows affected, 2 warnings (0.04 sec) mysql> start slave; Query OK, 0 rows affected (0.02 sec) mysql> show slave status\G *************************** 1. row *************************** Slave_IO_State: Waiting for master to send event Master_Host: 192.168.56.12 Master_User: repl Master_Port: 3306 Connect_Retry: 60 Master_Log_File: mysql-bin.000001 Read_Master_Log_Pos: 613 Relay_Log_File: linux-node2-relay-bin.000002 Relay_Log_Pos: 320 Relay_Master_Log_File: mysql-bin.000001 Slave_IO_Running: Yes Slave_SQL_Running: Yes
master端
cd /data/app/mysql-3306/ ./bin/mysql -uroot -p -S mysql.sock -P 3306 mysql> CREATE USER 'repl'@'192.%' IDENTIFIED BY 'mysql'; Query OK, 0 rows affected (0.05 sec) mysql> GRANT REPLICATION SLAVE ON *.* TO 'repl'@'192.%'; Query OK, 0 rows affected (0.00 sec) mysql> show master status; +------------------+----------+--------------+------------------+-------------------+ | File | Position | Binlog_Do_DB | Binlog_Ignore_DB | Executed_Gtid_Set | +------------------+----------+--------------+------------------+-------------------+ | mysql-bin.000001 | 613 | | | | +------------------+----------+--------------+------------------+-------------------+ 1 row in set (0.00 sec)
slave端
cd /data/app/mysql-3307/ ./bin/mysql -uroot -p -S mysql.sock -P 3307 mysql> CHANGE MASTER TO MASTER_HOST='192.168.56.13', MASTER_PORT=3306, MASTER_USER='repl', MASTER_PASSWORD='mysql', MASTER_LOG_FILE='mysql-bin.000001', MASTER_LOG_POS=613; Query OK, 0 rows affected, 2 warnings (0.04 sec) mysql> start slave; Query OK, 0 rows affected (0.02 sec) mysql> show slave status\G *************************** 1. row *************************** Slave_IO_State: Waiting for master to send event Master_Host: 192.168.56.13 Master_User: repl Master_Port: 3306 Connect_Retry: 60 Master_Log_File: mysql-bin.000001 Read_Master_Log_Pos: 613 Relay_Log_File: linux-node2-relay-bin.000002 Relay_Log_Pos: 320 Relay_Master_Log_File: mysql-bin.000001 Slave_IO_Running: Yes Slave_SQL_Running: Yes
第二步配置雙主模式
檢查兩個master端的binlog位置
linux-node2 master端
cd /data/app/mysql-3306/ ./bin/mysql -uroot -p -S mysql.sock -P 3306 mysql> show master status; +------------------+----------+--------------+------------------+-------------------+ | File | Position | Binlog_Do_DB | Binlog_Ignore_DB | Executed_Gtid_Set | +------------------+----------+--------------+------------------+-------------------+ | mysql-bin.000001 | 613 | | | | +------------------+----------+--------------+------------------+-------------------+ 1 row in set (0.00 sec)
linux-node3 master端
cd /data/app/mysql-3306/ ./bin/mysql -uroot -p -S mysql.sock -P 3306 mysql> show master status; +------------------+----------+--------------+------------------+-------------------+ | File | Position | Binlog_Do_DB | Binlog_Ignore_DB | Executed_Gtid_Set | +------------------+----------+--------------+------------------+-------------------+ | mysql-bin.000001 | 613 | | | | +------------------+----------+--------------+------------------+-------------------+ 1 row in set (0.00 sec)
node2-master 上配置跟node3同步
CHANGE MASTER TO MASTER_HOST='192.168.56.13', MASTER_PORT=3306, MASTER_USER='repl', MASTER_PASSWORD='mysql', MASTER_LOG_FILE='mysql-bin.000001', MASTER_LOG_POS=613; mysql> start slave; Query OK, 0 rows affected (0.03 sec) mysql> show slave status\G *************************** 1. row *************************** Slave_IO_State: Waiting for master to send event Master_Host: 192.168.56.13 Master_User: repl Master_Port: 3306 Connect_Retry: 60 Master_Log_File: mysql-bin.000001 Read_Master_Log_Pos: 613 Relay_Log_File: linux-node2-relay-bin.000002 Relay_Log_Pos: 320 Relay_Master_Log_File: mysql-bin.000001 Slave_IO_Running: Yes Slave_SQL_Running: Yes
node3-master 上配置跟node2同步
CHANGE MASTER TO MASTER_HOST='192.168.56.12', MASTER_PORT=3306, MASTER_USER='repl', MASTER_PASSWORD='mysql', MASTER_LOG_FILE='mysql-bin.000001', MASTER_LOG_POS=613; mysql> start slave; Query OK, 0 rows affected (0.00 sec) mysql> mysql> show slave status\G *************************** 1. row *************************** Slave_IO_State: Waiting for master to send event Master_Host: 192.168.56.12 Master_User: repl Master_Port: 3306 Connect_Retry: 60 Master_Log_File: mysql-bin.000001 Read_Master_Log_Pos: 613 Relay_Log_File: linux-node3-relay-bin.000002 Relay_Log_Pos: 320 Relay_Master_Log_File: mysql-bin.000001 Slave_IO_Running: Yes Slave_SQL_Running: Yes
mysql> create database test; Query OK, 1 row affected (0.01 sec) mysql> use test; Database changed mysql> create table temp(id int,name varchar(64)); Query OK, 0 rows affected (0.11 sec) mysql> insert into temp values(1,'aaa'); Query OK, 1 row affected (0.28 sec) mysql> CREATE TABLE temp2(id INT PRIMARY KEY NOT NULL AUTO_INCREMENT ,nname VARCHAR(64)); Query OK, 0 rows affected (0.01 sec) mysql> insert into temp2(nname) values('bbb'); Query OK, 1 row affected (0.01 sec) mysql> select * from test.temp; +------+------+ | id | name | +------+------+ | 1 | aaa | +------+------+ 1 row in set (0.01 sec) mysql>
在node2-slave端查看數據是否存在
mysql> select * from test.temp; +------+------+ | id | name | +------+------+ | 1 | aaa | +------+------+ 1 row in set (0.00 sec) mysql>
在node3-master端查看數據是否存在
mysql> select * from test.temp; +------+------+ | id | name | +------+------+ | 1 | aaa | +------+------+ 1 row in set (0.00 sec) mysql>
在node3-slave端查看數據是否存在
mysql> select * from test.temp; +------+------+ | id | name | +------+------+ | 1 | aaa | +------+------+ 1 row in set (0.00 sec) mysql>
mysql> use test; mysql> insert into temp2(nname) values('ddd'); Query OK, 1 row affected (0.02 sec) mysql> insert into temp2(nname) values('fff'); Query OK, 1 row affected (0.00 sec) mysql> select * from test.temp2; +----+-------+ | id | nname | +----+-------+ | 1 | bbb | | 2 | ddd | | 4 | fff | +----+-------+ 3 rows in set (0.00 sec)
在node3-slave端查看數據是否存在
mysql> select * from test.temp2; +----+-------+ | id | nname | +----+-------+ | 1 | bbb | | 2 | ddd | | 4 | fff | +----+-------+ 3 rows in set (0.00 sec) mysql>
在node2-master端查看數據是否存在
mysql> select * from test.temp2; +----+-------+ | id | nname | +----+-------+ | 1 | bbb | | 2 | ddd | | 4 | fff | +----+-------+ 3 rows in set (0.00 sec) mysql>
在node2-slave端查看數據是否存在
mysql> select * from test.temp2; +----+-------+ | id | nname | +----+-------+ | 1 | bbb | | 2 | ddd | | 4 | fff | +----+-------+ 3 rows in set (0.00 sec) mysql>
cd /usr/local/src wget http://dl.mycat.io/1.6-RELEASE/Mycat-server-1.6-RELEASE-20161028204710-linux.tar.gz tar -zxf Mycat-server-1.6-RELEASE-20161028204710-linux.tar.gz mv mycat /data/app/mycat-1.6 ln -s /data/app/mycat-1.6 /data/app/mycat
修改schema.xml
的配置文件
balance="1"
: 所有的readHost與stand by writeHost參與select語句的負載均衡。writeType="0"
: 全部寫操做發送到配置的第一個writeHost,第一個掛了切到還生存的第二個 writeHost,從新啓動後以切換後的爲準,切換記錄在配置文件中:dnindex.properties 。switchType="1"
: 1 默認值,自動切換。cd /data/app/mycat cp conf/schema.xml conf/schema.xml.bak cat > conf/schema.xml <<EOF <?xml version="1.0"?> <!DOCTYPE mycat:schema SYSTEM "schema.dtd"> <mycat:schema xmlns:mycat="http://io.mycat/"> <schema name="TESTDB" checkSQLschema="true" sqlMaxLimit="100" dataNode="dn1"></schema> <dataNode name="dn1" dataHost="node1" database="test" /> <dataHost name="node1" maxCon="10" minCon="5" balance="1" writeType="0" dbType="mysql" dbDriver="native" switchType="1"> <heartbeat>select user()</heartbeat> <writeHost host="master1" url="192.168.56.12:3306" user="root" password="mysql"> <readHost host="slave2" url="192.168.56.13:3307" user="root" password="mysql" /> </writeHost> <writeHost host="master2" url="192.168.56.13:3306" user="root" password="mysql"> <readHost host="slave2" url="192.168.56.13:3307" user="root" password="mysql" /> </writeHost> </dataHost> </mycat:schema> EOF
啓動mycat服務
./bin/mycat start ss -lntup |egrep '(8066|9066)' tcp LISTEN 0 100 :::8066 :::* users:(("java",16546,79)) tcp LISTEN 0 100 :::9066 :::* users:(("java",16546,75))
第一步:在linux-node2-master端配置mycat鏈接帳號
mysql> GRANT ALL PRIVILEGES ON *.* TO root@'192.%' IDENTIFIED BY 'mysql'; Query OK, 0 rows affected, 1 warning (0.07 sec)
第二步:在mycat服務器上安裝mysql服務,可是不啓動。
具體步驟省略,詳細內容能夠參考上面的MySQL安裝。
第三步:使用mysql的客戶端鏈接mycat
cd /data/app/mysql/ ./bin/mysql -uroot -p -P 8066 -h 192.168.56.11 ##鏈接mycat,初始密碼123456 mysql> show databases; +----------+ | DATABASE | +----------+ | TESTDB | +----------+ 1 row in set (0.00 sec) mysql> use TESTDB; mysql> insert into temp2(nname) values('eee'); Query OK, 1 row affected (0.09 sec) mysql> insert into temp2(nname) values('ggg'); Query OK, 1 row affected (0.01 sec)
linux-node3-slave 端查看數據是否同步
mysql> select * from test.temp2; +----+-------+ | id | nname | +----+-------+ | 1 | bbb | | 2 | ddd | | 4 | fff | | 5 | eee | | 7 | ggg | +----+-------+ 5 rows in set (0.00 sec)
根據查詢結果發現數據寫入到了linux-node3-slave端。
關閉linux-node2-master的服務
mysql> shutdown; Query OK, 0 rows affected (0.01 sec) shell > ss -lntup |grep 3306 ## 確認端口已經關閉。
mycat端插入新的數據查看數據是否同步
mysql> insert into temp2(nname) values('mmmm'); Query OK, 1 row affected (0.07 sec) mysql> insert into temp2(nname) values('nnnn'); Query OK, 1 row affected (0.01 sec)
linux-node3-slave端查看數據是否同步
mysql> select * from test.temp2; +----+-------+ | id | nname | +----+-------+ | 1 | bbb | | 2 | ddd | | 4 | fff | | 5 | eee | | 7 | ggg | | 8 | mmmm | | 10 | nnnn | +----+-------+ 7 rows in set (0.00 sec) mysql>
linux-node2-slave端查看數據是否同步
mysql> select * from test.temp2; +----+-------+ | id | nname | +----+-------+ | 1 | bbb | | 2 | ddd | | 4 | fff | | 5 | eee | | 7 | ggg | +----+-------+ 5 rows in set (0.00 sec) mysql>
由於linux-node2的master端已經掛了,故數據不能同步。
登陸到mycat服務器上執行以下命令:
mysql> select * from temp2; +----+-------+ | id | nname | +----+-------+ | 1 | bbb | | 2 | ddd | | 4 | fff | | 5 | eee | | 7 | ggg | | 8 | mmmm | | 10 | nnnn | +----+-------+ 7 rows in set (0.00 sec) mysql> select * from temp2; +----+-------+ | id | nname | +----+-------+ | 1 | bbb | | 2 | ddd | | 4 | fff | | 5 | eee | | 7 | ggg | | 8 | mmmm | | 10 | nnnn | +----+-------+ 7 rows in set (0.00 sec)
執行屢次發現結果同樣,說明在一臺master端掛掉的狀況下,其鏈接的slave端也被剔除,所以數據完整性能夠保證。
第一次配置的時候maser端沒有配置log-slave-updates
致使,node3-slave上沒有node2-master端的數據。
解釋:
從庫開啓log-bin參數,若是直接往從庫寫數據,是能夠記錄log-bin日誌的,可是從庫經過I0線程讀取主庫二進制日誌文件,而後經過SQL線程寫入的數據,是不會記錄binlog日誌的。也就是說從庫從主庫上覆制的數據,是不寫入從庫的binlog日誌的。因此從庫作爲其餘從庫的主庫時須要在配置文件中添加log-slave-updates參數。
解決辦法:
[mysqld] log-slave-updates