mysql主從及mysql-proxy和mycat部署
一、mysql主從復制
1、mysql主從出現的原因
MYSQL主從復制集群在中小企業、大型企業中被廣泛使用,MYSQL主從復制的目的是實現數據庫冗余備份,將Master數據庫數據定時同步至Slave庫中,一旦Master數據庫宕機,可以將WEB應用數據庫配置快速切換至Slave數據庫,確保WEB應用較高的可用率。
2、mysql主從的原理
Mysql主從復制集群至少需要2台數據庫服務器,其中一台為Master庫,另外一台為Slave庫,MYSQL主從數據同步是一個異步復制的過程,要實現復制首先需要在master上開啟bin-log日志功能,bin-log日志用於記錄在Master庫中執行的增、刪、修改、更新操作的sql語句,整個過程需要開啟3個線程,分別是Master開啟IO線程,Slave開啟IO線程和SQL線程,具體主從同步原理詳解如下:
Slave上執行slave start,Slave IO線程會通過在Master創建的授權用戶連接上至Master,並請求master從指定的bin-log文件和position位置之后發送bin-log日志內容;
Master接收到來自slave IO線程的請求后,master IO線程根據slave發送的指定bin-log日志position點之后的內容,然后返回給slave的IO線程。
返回的信息中除了bin-log日志內容外,還有master最新的binlog文件名以及在binlog中的下一個指定更新position點;
Slave IO線程接收到信息后,將接收到的日志內容依次添加到Slave端的relay-log文件的最末端,並將讀取到的Master端的 bin-log的文件名和position點記錄到master.info文件中,以便在下一次讀取的時候能告知master從響應的bin-log文件名及最后一個position點開始發起請求;
Slave Sql線程檢測到relay-log中內容有更新,會立刻解析relay-log的內容成在Master真實執行時候的那些可執行的SQL語句,將解析的SQL語句並在Slave里執行,執行成功后,Master庫與Slave庫保持數據一致。
3、mysql主從復制部署
3.1實驗環境
mysql master服務器:10.0.0.5
mysql slave 服務器:10.0.0.6
mysql使用mariadb
3.2mysql主從部署步驟
①在master和slave服務器上安裝mariadb數據庫
yum install -y mariadb mariadb-server mariadb-devel
[root@web04 ~]# rpm -qa mariadb mariadb-server mariadb-devel
mariadb-server-5.5.64-1.el7.x86_64
mariadb-5.5.64-1.el7.x86_64
mariadb-devel-5.5.64-1.el7.x86_64
[root@web04 ~]#
②啟動mariadb數據庫
[root@web03 ~]# systemctl restart mariadb
[root@web03 ~]# ps -ef |grep mysql
mysql 20439 1 0 08:43 ? 00:00:00 /bin/sh /usr/bin/mysqld_safe --basedir=/usr
mysql 20601 20439 7 08:43 ? 00:00:00 /usr/libexec/mysqld --basedir=/usr --datadir=/var/lib/mysql --plugin-dir=/usr/lib64mysql/plugin --log-error=/var/log/mariadb/mariadb.log --pid-file=/var/run/mariadb/mariadb.pid --socket=/var/lib/mysql/mysql.sock
root 20652 18956 0 08:43 pts/1 00:00:00 grep --color=auto mysql
③在master和slave上開啟bin-log日志並配置server-id
[mysqld]
#server-id master和slave要不一樣
server-id 5
#binlog日志的名稱和位子可以直接定義
log-bin=/var/lib/mysql-bin
#binlog日志的格式
binlog_format = row
master
[mysqld]
datadir=/var/lib/mysql
socket=/var/lib/mysql/mysql.sock
log-bin=/var/lib/mysql/mysql_master-bin
binlog_format = row
server-id=5
# Disabling symbolic-links is recommended to prevent assorted security risks
symbolic-links=0
# Settings user and group are ignored when systemd is used.
# If you need to run mysqld under a different user or group,
# customize your systemd unit file for mariadb according to the
# instructions in http://fedoraproject.org/wiki/Systemd
[mysqld_safe]
log-error=/var/log/mariadb/mariadb.log
pid-file=/var/run/mariadb/mariadb.pid
#
# include all files from the config directory
#
!includedir /etc/my.cnf.d
slave
[mysqld] server-id=6 log-bin=/var/lib/mysql/mysql_slave-bin binlog_format = row datadir=/var/lib/mysql socket=/var/lib/mysql/mysql.sock # Disabling symbolic-links is recommended to prevent assorted security risks symbolic-links=0 # Settings user and group are ignored when systemd is used. # If you need to run mysqld under a different user or group, # customize your systemd unit file for mariadb according to the # instructions in http://fedoraproject.org/wiki/Systemd [mysqld_safe] log-error=/var/log/mariadb/mariadb.log pid-file=/var/run/mariadb/mariadb.pid # # include all files from the config directory # !includedir /etc/my.cnf.d
④重啟mariadb服務,查看二進制日志是否開啟
systemctl restart mariadb
MariaDB [(none)]> show variables like "%log_bin"; +---------------+-------+ | Variable_name | Value | +---------------+-------+ | log_bin | ON | | sql_log_bin | ON | +---------------+-------+ 2 rows in set (0.00 sec)
⑤授權從庫登陸
在master上授權,該步驟是在10.0.0.5上操作
MariaDB [(none)]> grant replication slave on *.* to tongbu@"10.0.0.%" identified by "123456"; Query OK, 0 rows affected (0.00 sec)
⑥查看master的log-file文件和Position節點信息
在master上查看,該步驟是在10.0.0.5上操作
MariaDB [(none)]> show master status; +-------------------------+----------+--------------+------------------+ | File | Position | Binlog_Do_DB | Binlog_Ignore_DB | +-------------------------+----------+--------------+------------------+ | mysql_master-bin.000001 | 394 | | | +-------------------------+----------+--------------+------------------+ 1 row in set (0.00 sec)
⑦配置slave服務器,該步驟在10.0.0.6上操作
MariaDB [(none)]> change master to master_host="10.0.0.5", #master的ip master_user="tongbu", #master上授權同步的用戶名 master_password="123456",##master上授權同步的密碼 master_log_file=" mysql_master-bin.000001", #master的log-file文件 master_log_pos=394;# Position節點位子 #可以在slave上使用help change master來查看內容
MariaDB [(none)]> change master to -> master_host='10.0.0.5', -> master_user='tongbu', -> master_password='123456', -> master_log_file='mysql_master-bin.000001', -> master_log_pos=544; Query OK, 0 rows affected (0.11 sec)
⑧在slave端開啟slave進程
mysql5.5:slave start mysql 5.7:start slave
MariaDB [(none)]> slave start; Query OK, 0 rows affected (0.00 sec)
⑨測試主從
檢查slave端是否有兩個yes
show slave status\G;
MariaDB [(none)]> show slave status\G; *************************** 1. row *************************** Slave_IO_State: Waiting for master to send event Master_Host: 10.0.0.5 Master_User: tongbu Master_Port: 3306 Connect_Retry: 60 Master_Log_File: mysql_master-bin.000001 Read_Master_Log_Pos: 544 Relay_Log_File: mariadb-relay-bin.000002 Relay_Log_Pos: 536 Relay_Master_Log_File: mysql_master-bin.000001 Slave_IO_Running: Yes Slave_SQL_Running: Yes Replicate_Do_DB: Replicate_Ignore_DB: Replicate_Do_Table: Replicate_Ignore_Table: Replicate_Wild_Do_Table: Replicate_Wild_Ignore_Table: Last_Errno: 0 Last_Error: Skip_Counter: 0 Exec_Master_Log_Pos: 544 Relay_Log_Space: 832 Until_Condition: None Until_Log_File: Until_Log_Pos: 0 Master_SSL_Allowed: No Master_SSL_CA_File: Master_SSL_CA_Path: Master_SSL_Cert: Master_SSL_Cipher: Master_SSL_Key: Seconds_Behind_Master: 0 Master_SSL_Verify_Server_Cert: No Last_IO_Errno: 0 Last_IO_Error: Last_SQL_Errno: 0 Last_SQL_Error: Replicate_Ignore_Server_Ids: Master_Server_Id: 5 1 row in set (0.00 sec) ERROR: No query specified
看到下面的兩個yes,說明主從配置完成並且正常 Slave_IO_Running: Yes Slave_SQL_Running: Yes
Show slave status\G,常見參數含義解析:
Slave_IO_State I/O線程連接Master狀態; Master_User 用於連接Master的用戶; Master_Port Master端監聽端口; Connect_Retry 主從連接失敗,重試時間間隔; Master_Log_File I/O線程讀取的Master二進制日志文件的名稱。 Read_Master_Log_Pos I/O線程已讀取的Master二進制日志文件的位置; Relay_Log_File SQL線程讀取和執行的中繼日志文件的名稱。 Relay_Log_Pos SQL線程已讀取和執行的中繼日志文件的位置; Relay_Master_Log_File SQL線程執行的Master二進制日志文件的名稱; Slave_IO_Running I/O線程是否被啟動並成功地連接到主服務器上; Slave_SQL_Running SQL線程是否被啟動; Replicate_Do_DB 指定的同步的數據庫列表; Skip_Counter SQL_SLAVE_SKIP_COUNTER設置的值; Seconds_Behind_Master Slave端SQL線程和I/O線程之間的時間差距,單位為秒,常被用於主從延遲檢查方法之一。
⑩測試
先查看slave的數據庫信息
MariaDB [(none)]> show databases; +--------------------+ | Database | +--------------------+ | information_schema | | mysql | | performance_schema | | test | +--------------------+ 4 rows in set (0.00 sec) MariaDB [(none)]>
在master上創建一個新的數據庫
MariaDB [(none)]> create database if not exists ywx default character set utf8; Query OK, 1 row affected (0.00 sec) MariaDB [(none)]> show databases; +--------------------+ | Database | +--------------------+ | information_schema | | mysql | | performance_schema | | test | | ywx | +--------------------+ 5 rows in set (0.00 sec)
在slave上查看master上新創建的庫
MariaDB [(none)]> show databases; +--------------------+ | Database | +--------------------+ | information_schema | | mysql | | performance_schema | | test | | ywx | +--------------------+ 5 rows in set (0.00 sec)
數據庫已經同步過來了
4、主從復制常見的故障
Slave_IO_Running: Connecting # 第一種:主庫宕機 # 第二種:從庫指定的用戶名與密碼錯誤(與主庫授權的用戶名和密碼不一致) # 第三種:關閉防火牆 Slave_IO_Running: No # 從庫指定的二進制文件有誤 Slave_SQL_Running: No # pos點問題
二、mysql讀寫分離
1、什么是mysql的讀寫分離
MYSQL讀寫分離的原理其實就是讓Master數據庫處理事務性增、刪除、修改、更新操作(CREATE、 INSERT、UPDATE、DELETE),而讓Slave數據庫處理SELECT操作,MYSQL讀寫分離前提是基於 MYSQL主從復制,這樣可以保證在Master上修改數據,Slave同步之后,WEB應用可以讀取到Slave端 的數據。
2、怎樣實現讀寫分離
實現MYSQL讀寫分離可以基於第三方插件,也可以通過開發修改代碼實現,具體實現的讀寫分離的常見 方式有如下四種: Amoeba讀寫分離; MySQL-Proxy讀寫分離; Mycat讀寫分離; 基於程序讀寫分離(效率很高,實施難度大,開發改代碼); Amoeba是阿里08年開源的以MySQL為底層數據存儲,並對WEB、APP應用提供MySQL協議接口的 proxy。它集中地響應WEB應用的請求,依據用戶事先設置的規則,將SQL請求發送到特定的數據庫上 執行,基於此可以實現負載均衡、讀寫分離、高可用性等需求。 Mysql-Proxy是MySQL官方提供的mysql中間件服務,支持無數客戶端連接,同時后端可連接若干台 Mysql-Server服務器,MYSQL-Proxy自身基於MySQL協議,連接MYSQL-Proxy的客戶端無需修改任何 設置, 跟正常連接MYSQL Server沒有區別,無需修改程序代碼。現在由mysql-route替代。 Mycat是基於阿里12年開源的cobar開發的一個數據庫中間件,在架構體系中是位於數據庫和應用層之 間的一個組件,並且對於應用層是透明的,它可實現讀寫分離,分庫分表。
3、實驗部署環境
mysql-proxy(mycat):10.0.0.240 mysql-master:10.0.0.6 mysql-slave:10.0.0.5
4、mysql-proxy讀寫分離部署
4.1、部署主從復制
部署master和slave的主從輔助(省略)
詳見mysql主從復制
4.2、部署mysql-proxy
①下載解壓並移動mysql-proxy包
mkdir -p /server/tools cd /server/tools # 下載mysql-proxy: wget -c http://mirrors.163.com/mysql/Downloads/MySQL-Proxy/mysql-proxy-0.8.4-linux-el6-x86-64bit.tar.gz # 解壓: tar -xf mysql-proxy-0.8.4-linux-el6-x86-64bit.tar.gz mv mysql-proxy-0.8.4-linux-el6-x86-64bit /usr/local/mysql-proxy # 配置環境變量: echo "export PATH=/usr/local/mysql-proxy/bin:$PATH" > /etc/profile.d/mysql-proxy.sh source /etc/profile.d/mysql-proxy.sh
②啟動MYSQL-Proxy中間件
#創建mysql-proxy用戶 useradd -r mysql-proxy #啟動mysql-proxy mysql-proxy --daemon --log-level=debug --user=mysql-proxy --keepalive --log-file=/var/log/mysql-proxy.log --plugins="proxy" --proxy-backend-addresses="10.0.0.5:3306" --proxy-read-only-backend-addresses="10.0.0.6:3306" --proxy-lua-script="/usr/local/mysql-proxy/share/doc/mysql-proxy/rw-splitting.lua" --plugins=admin --admin-username="admin" --admin-password="admin" --admin-lua-script="/usr/local/mysql-proxy/lib/mysql-proxy/lua/admin.lua"
[root@yum tools]# netstat -anlp|grep 40 tcp 0 0 0.0.0.0:4040 0.0.0.0:* LISTEN 82264/mysql-proxy tcp 0 0 0.0.0.0:4041 0.0.0.0:* LISTEN 82264/mysql-proxy #4040為數據傳輸接口,4041為管理接口
# Mysql-Proxy的相關參數詳解如下: --help-all :獲取全部幫助信息; --proxy-address=host:port :代理服務監聽的地址和端口,默認為4040; --admin-address=host:port :管理模塊監聽的地址和端口,默認為4041; --proxy-backend-addresses=host:port :后端mysql服務器的地址和端口; --proxy-read-only-backend-addresses=host:port :后端只讀mysql服務器的地址和端口; --proxy-lua-script=file_name :完成mysql代理功能的Lua腳本; --daemon :以守護進程模式啟動mysql-proxy; --keepalive :在mysql-proxy崩潰時嘗試重啟之; --log-file=/path/to/log_file_name :日志文件名稱; --log-level=level :日志級別; --log-use-syslog :基於syslog記錄日志; --plugins=plugin :在mysql-proxy啟動時加載的插件; --user=user_name :運行mysql-proxy進程的用戶; --defaults-file=/path/to/conf_file_name :默認使用的配置文件路徑,其配置段使用[mysqlproxy]標識; --proxy-skip-profiling :禁用profile; --pid-file=/path/to/pid_file_name :進程文件名;
③在master和slave上授權proxy
因為master和proxy為主從配置,只需要在master上授權proxy即可,slave會自動的同步master上的授權操作
在master上操作
grant all on *.* to mysql-proxy@"10.0.0.%" identified by '123456';
在master查看proxy授權信息
MariaDB [(none)]> select user,host from mysql.user; +-------------+-----------+ | user | host | +-------------+-----------+ | mysql-proxy | 10.0.0.% | | tongbu | 10.0.0.% | | root | 127.0.0.1 | | root | ::1 | | | localhost | | root | localhost | | | web03 | | root | web03 | +-------------+-----------+ 8 rows in set (0.01 sec)
在slave端查看proxy授權信息
MariaDB [(none)]> select user,host from mysql.user; +-------------+-----------+ | user | host | +-------------+-----------+ | mysql-proxy | 10.0.0.% | | root | 127.0.0.1 | | root | ::1 | | | localhost | | root | localhost | | | web04 | | root | web04 | +-------------+-----------+ 7 rows in set (0.00 sec)
④登陸mysql-proxy4041管理接口,查看讀寫分離的狀態
在mysql-proxy上操作
登陸mysql-proxy的管理地址
[root@yum yum.repos.d]# mysql -h10.0.0.240 -uadmin -padmin -P4041 Welcome to the MariaDB monitor. Commands end with ; or \g. Your MySQL connection id is 1 Server version: 5.0.99-agent-admin Copyright (c) 2000, 2018, Oracle, MariaDB Corporation Ab and others. Type 'help;' or '\h' for help. Type '\c' to clear the current input statement. MySQL [(none)]>
查看后端master和slave數據庫的狀態信息
[root@yum ~]# mysql -h10.0.0.240 -uadmin -padmin -P4041 Welcome to the MariaDB monitor. Commands end with ; or \g. Your MySQL connection id is 1 Server version: 5.0.99-agent-admin Copyright (c) 2000, 2018, Oracle, MariaDB Corporation Ab and others. Type 'help;' or '\h' for help. Type '\c' to clear the current input statement. MySQL [(none)]> select * from backends; +-------------+---------------+---------+------+------+-------------------+ | backend_ndx | address | state | type | uuid | connected_clients | +-------------+---------------+---------+------+------+-------------------+ | 1 | 10.0.0.5:3306 | unknown | rw | NULL | 0 | | 2 | 10.0.0.6:3306 | unknown | ro | NULL | 0 | +-------------+---------------+---------+------+------+-------------------+ 2 rows in set (0.00 sec)
因為還沒有讀寫過數據庫,所有state為unknow。
⑤通過mysql-proxy創建數據
通過4040代理端口插入數據,該sql語句會走master,於是可以激活master狀態:
mysql -h 10.0.0.240 -umysql-proxy -p123456 -P4040;
[root@yum ~]# mysql -h10.0.0.240 -umysql-proxy -p123456 -P4040 Welcome to the MariaDB monitor. Commands end with ; or \g. Your MariaDB connection id is 7 Server version: 5.5.64-MariaDB MariaDB Server Copyright (c) 2000, 2018, Oracle, MariaDB Corporation Ab and others. Type 'help;' or '\h' for help. Type '\c' to clear the current input statement. MariaDB [(none)]> create database king default character set utf8; Query OK, 1 row affected (0.00 sec)
通過4041代理端口查看后端master庫的狀態為up
mysql -h 10.0.0.240 -uadmin -padmin -P4041;
MySQL [(none)]> select * from backends; +-------------+---------------+---------+------+------+-------------------+ | backend_ndx | address | state | type | uuid | connected_clients | +-------------+---------------+---------+------+------+-------------------+ | 1 | 10.0.0.5:3306 | up | rw | NULL | 0 | | 2 | 10.0.0.6:3306 | unknown | ro | NULL | 0 | +-------------+---------------+---------+------+------+-------------------+ 2 rows in set (0.00 sec)
⑥通過mysql-proxy查詢數據
通過4040代理端口查詢數據,該sql語句會走slave,於是可以激活slave狀態:
mysql -h 10.0.0.240 -umysql-proxy -p123456 -P4040;
先創建ywx庫的t1表
create database ywx; use ywx; create table t1(id int ,name varchar(20));
多查詢幾次
通過4041代理端口查看后端master庫的狀態為up
MariaDB [ywx]> select * from t1; Empty set (0.00 sec)
MySQL [(none)]> select * from backends; +-------------+---------------+-------+------+------+-------------------+ | backend_ndx | address | state | type | uuid | connected_clients | +-------------+---------------+-------+------+------+-------------------+ | 1 | 10.0.0.5:3306 | up | rw | NULL | 0 | | 2 | 10.0.0.6:3306 | up | ro | NULL | 0 | +-------------+---------------+-------+------+------+-------------------+ 2 rows in set (0.00 sec)
⑦測試寫是走master,讀是slave
查看master和slave的數據信息
master端
MariaDB [(none)]> use ywx; MariaDB [ywx]> show tables; +---------------+ | Tables_in_ywx | +---------------+ | t1 | +---------------+ 1 row in set (0.00 sec)
slave
MariaDB [(none)]> use ywx; MariaDB [ywx]> show tables; +---------------+ | Tables_in_ywx | +---------------+ | t1 | +---------------+ 1 row in set (0.00 sec)
master和slave是一樣,為了方便我們區分master和slave,我們在slave端的t1表中插入數據,master端沒有數據
mster
MariaDB [ywx]> select * from t1; Empty set (0.00 sec)
slave插入數據
MariaDB [ywx]> insert into t1(id) values(1),(2); Query OK, 2 rows affected (0.00 sec) Records: 2 Duplicates: 0 Warnings: 0 MariaDB [ywx]> select * from t1; +------+------+ | id | name | +------+------+ | 1 | NULL | | 2 | NULL | +------+------+ 2 rows in set (0.00 sec)
下面的所有操作都是在mysql-proxy端操作
使用4040端口登陸mysql-proxy
mysql-proxy -h 10.0.0.240 -umysql-proxy -p123456 -P4040
查詢t1表,有數據,可以確定查詢是走了slave庫
MariaDB [(none)]> use ywx; Reading table information for completion of table and column names You can turn off this feature to get a quicker startup with -A Database changed MariaDB [ywx]> select * from t1; +------+------+ | id | name | +------+------+ | 1 | NULL | | 2 | NULL | +------+------+ 2 rows in set (0.00 sec)
我們向t1表中寫入一些數據
MariaDB [ywx]> insert into t1(id) values(3),(4),(5); Query OK, 3 rows affected (0.01 sec) Records: 3 Duplicates: 0 Warnings: 0 MariaDB [ywx]> select * from t1; +------+------+ | id | name | +------+------+ | 1 | NULL | | 2 | NULL | | 3 | NULL | | 4 | NULL | | 5 | NULL | +------+------+ 5 rows in set (0.00 sec)
分表查看master庫和slave庫中ywx.t1表中的數據
master
MariaDB [ywx]> select * from t1; +------+------+ | id | name | +------+------+ | 3 | NULL | | 4 | NULL | | 5 | NULL | +------+------+ 3 rows in set (0.00 sec)
slave
MariaDB [ywx]> select * from t1; +------+------+ | id | name | +------+------+ | 1 | NULL | | 2 | NULL | | 3 | NULL | | 4 | NULL | | 5 | NULL | +------+------+ 5 rows in set (0.00 sec)
可以看到master和slave都有3、4、5的數據信息。
可以確定mysql-proxy插入數據是走的master的庫,查詢數據是走的slave庫。
4.3、mysql主從的故障對mysql-proxy的影響
①mysql slave端出現故障,mysql-porxy會將查詢的服務器從slave端轉移到master端
主從正常,mysql-proxy查詢是訪問slave端
MariaDB [ywx]> select * from t1; +------+------+ | id | name | +------+------+ | 1 | NULL | | 2 | NULL | | 3 | NULL | | 4 | NULL | | 5 | NULL | +------+------+ 5 rows in set (0.00 sec)
slave故障,mysql-proxy查詢有訪問slave端轉移到master端
MariaDB [ywx]> select * from t1; +------+------+ | id | name | +------+------+ | 3 | NULL | | 4 | NULL | | 5 | NULL | +------+------+ 3 rows in set (0.00 sec)
在mysql-proxy管理用戶查看讀寫信息,可以發現mysql-proxy的讀服務器(slave 10.0.0.6)的state會變為down,
所有業務全部轉移到master(10.0.0.5)上。
也就是說slave端出現故障了,對整個業務沒有影響。
[root@yum ~]# mysql -h10.0.0.240 -uadmin -padmin -P4041 Welcome to the MariaDB monitor. Commands end with ; or \g. Your MySQL connection id is 1 Server version: 5.0.99-agent-admin Copyright (c) 2000, 2018, Oracle, MariaDB Corporation Ab and others. Type 'help;' or '\h' for help. Type '\c' to clear the current input statement. MySQL [(none)]> select * from backends; +-------------+---------------+-------+------+------+-------------------+ | backend_ndx | address | state | type | uuid | connected_clients | +-------------+---------------+-------+------+------+-------------------+ | 1 | 10.0.0.5:3306 | up | rw | NULL | 0 | | 2 | 10.0.0.6:3306 | down | ro | NULL | 0 | +-------------+---------------+-------+------+------+-------------------+
恢復mysql主從。
②mysql master段出現故障,mysql-proxy只能查詢不能寫入
master故障宕機后
MySQL [(none)]> select * from backends; +-------------+---------------+-------+------+------+-------------------+ | backend_ndx | address | state | type | uuid | connected_clients | +-------------+---------------+-------+------+------+-------------------+ | 1 | 10.0.0.5:3306 | down | rw | NULL | 0 | | 2 | 10.0.0.6:3306 | up | ro | NULL | 0 | +-------------+---------------+-------+------+------+-------------------+ 2 rows in set (0.00 sec)
mysql-proxy可以通過slave段正常訪問
MariaDB [ywx]> select * from ywx.t1; +------+------+ | id | name | +------+------+ | 1 | NULL | | 2 | NULL | | 3 | NULL | | 4 | NULL | | 5 | NULL | | 10 | NULL | +------+------+ 6 rows in set (0.00 sec)
但是無法寫入數據
MariaDB [ywx]> insert into t1(id) values(11),(12); ERROR 2013 (HY000): Lost connection to MySQL server during query MariaDB [ywx]>
5、mycat的讀寫部署
5.1、mycat的介紹
Mycat基於阿里開源的Cobar產品而研發 , 一個徹底開源的,面向企業應用開發的大數據庫集群 , 一個可 以視為MySQL集群的企業級數據庫,用來替代昂貴的Oracle集群 ,MYCAT並不依托於任何一個商業公 司, 永不收費,永不閉源 !
mycat的原理圖
5.2、mycat的部署
5.2.1實驗環境:
mycat 10.0.0.240 master 10.0.0.5 slave 10.0.0.6 使用在MySQL中創建king數據庫,在king數據庫的t1表來做測試
在master和slave數據庫中數據信息(要先創建好)
MariaDB [king]> select * from king.t1; +------+----------+ | id | name | +------+----------+ | 1 | xiaowang | | 2 | xiaogong | +------+----------+ 2 rows in set (0.00 sec)
5.2.2在master和slave部署mysql主從
#1、主從復制部署省略
5.2.3配置mycat
在mycat上配置
#2、下載安裝mycat mkdir -p /server/tools cd /server/tools wget -chttp://dl.mycat.io/1.6.7.1/Mycat-server-1.6.7.1-release-20190627191042-linux.tar.gz #3、解壓並移動到/usr/local下 tar -xf Mycat-server-1.6.7.1-release-20190627191042-linux.tar.gz mv mycat /usr/local/ #4、安裝java-jdk: yum install java-1.8.0-openjdk -y #5、# 配置mycat環境變量: echo "export PATH=/usr/local/mycat/bin:$PATH" > /etc/profile.d/mycat.sh source /etc/profile.d/mycat.sh
在master上配置
#6、在master和slave端對mycat授權,因為master和slave為主從,只需要再master上授權即可 MariaDB [(none)]> grant all on *.* to 'mycat-proxy'@'10.0.0.%' identified by '123456'; Query OK, 0 rows affected (0.00 sec) MariaDB [(none)]> select user,host from mysql.user; +-------------+-----------+ | user | host | +-------------+-----------+ | mycat-proxy | 10.0.0.% | | mysql-proxy | 10.0.0.% | | tongbu | 10.0.0.% | | root | 127.0.0.1 | | root | ::1 | | | localhost | | root | localhost | | | web03 | | root | web03 | +-------------+-----------+ 9 rows in set (0.00 sec) slave上自動同步 MariaDB [ywx]> select user,host from mysql.user; +-------------+-----------+ | user | host | +-------------+-----------+ | mycat-proxy | 10.0.0.% | | mysql-proxy | 10.0.0.% | | root | 127.0.0.1 | | root | ::1 | | | localhost | | root | localhost | | | web04 | | root | web04 | +-------------+-----------+ 8 rows in set (0.00 sec)
在mycat上配置
配置mycat的配置文件server.xml和schema.xml
配置server.xml,只需要配置以下的內容,其它的不用配置
#配置管理用戶,可讀可寫 # <user name="mycat" defaultAccount="true">定義管理員用戶 # <property name="password">123456</property> 定義管理員用戶密碼 # <property name="schemas">kaka</property>定義一個邏輯庫與schemas配置文件對應 <user name="mycat" defaultAccount="true"> <property name="password">123456</property> <property name="schemas">kaka</property> </user> #配置只讀用戶和與管理員對應的邏輯庫名 #<property name="schemas">kaka</property>定義與上面一直的邏輯庫名 <user name="user"> <property name="password">user</property> <property name="schemas">kaka</property> <property name="readOnly">true</property> </user>
配置schema.xml,只需要配置以下的內容,其它的不用配置
#設置邏輯庫及數據庫節點 #<schema name="kaka",schema name與server.xml一致 <schema name="kaka" checkSQLschema="false" sqlMaxLimit="100" dataNode="dn1"> </schema> # 配置數據庫節點對應的后端真實的數據庫,database真實的數據庫必須存在master和slave上 <!-- <dataNode name="dn1$0-743" dataHost="localhost1" database="db$0-743" /> --> <dataNode name="dn1" dataHost="localhost1" database="king" /> <!--<dataNode name="dn4" dataHost="sequoiadb1" database="SAMPLE" /> <dataNode name="jdbc_dn1" dataHost="jdbchost" database="db1" /> <dataNode name="jdbc_dn2" dataHost="jdbchost" database="db2" /> <dataNode name="jdbc_dn3" dataHost="jdbchost" database="db3" /> --> # 配置讀寫庫以及均衡 <dataHost name="localhost1" maxCon="1000" minCon="10" balance="1" writeType="0" dbType="mysql" dbDriver="native" switchType="1" slaveThreshold="100"> <heartbeat>select user()</heartbeat> <!-- can have multi write hosts --> #配置寫庫(master) <writeHost host="hostM1" url="10.0.0.5:3306" user="mycat-proxy" password="123456"> <!-- can have multi read hosts --> #配置讀庫(slave) <readHost host="hostS1" url="10.0.0.6:3306" user="mycat-proxy" password="123456" /> #配置寫庫,master庫宕機了,數據寫入將由配置的hostM1服務器轉移到下面的hostM2的服務器來寫入 </writeHost> <writeHost host="hostM2" url="10.0.0.6:3306" user="mycat-proxy" password="123456" />
啟動mycat
[root@yum conf]# mycat start Starting Mycat-server...
[root@yum conf]# netstat -anlp|grep 066 tcp6 0 0 :::8066 :::* LISTEN 84580/java tcp6 0 0 :::9066 :::* LISTEN 84580/java #8066為mycat的數據端口 #9066為mycat的管理端口
5.2.4連接測試:
先把mycat的日志模式改為debug模式
vim /usr/local/mycat/conf/log4j2.xml
把level="info"改為level="debug",后重啟mycat (mycat restart)
<asyncRoot level="debug" includeLocation="true"> <!--<AppenderRef ref="Console" />--> <AppenderRef ref="RollingFile"/>
連接數據庫:
mysql -umycat -p123456 -P8066 -h10.0.0.240
Welcome to the MariaDB monitor. Commands end with ; or \g. Your MySQL connection id is 1 Server version: 5.6.29-mycat-1.6.7.1-release-20190627191042 MyCat Server (OpenCloudDB) Copyright (c) 2000, 2018, Oracle, MariaDB Corporation Ab and others. Type 'help;' or '\h' for help. Type '\c' to clear the current input statement. MySQL [(none)]>
在mycat下查看數據庫信息
MySQL [(none)]> show databases; +----------+ | DATABASE | +----------+ | kaka | +----------+ 1 row in set (0.00 sec) MySQL [(none)]> use kaka; Reading table information for completion of table and column names You can turn off this feature to get a quicker startup with -A Database changed MySQL [kaka]> show tables; +----------------+ | Tables_in_king | +----------------+ | t1 | +----------------+ 1 row in set (0.01 sec) MySQL [kaka]> desc t1; +-------+-------------+------+-----+---------+-------+ | Field | Type | Null | Key | Default | Extra | +-------+-------------+------+-----+---------+-------+ | id | int(11) | YES | | NULL | | | name | varchar(20) | YES | | NULL | | +-------+-------------+------+-----+---------+-------+ 2 rows in set (0.01 sec) MySQL [kaka]> select * from t1; +------+----------+ | id | name | +------+----------+ | 1 | xiaowang | | 2 | xiaogong | +------+----------+ 2 rows in set (0.01 sec)
可以看出在mycat中kaka庫(在server.xml中創建的邏輯庫)對應的后端mysql中的king庫(mysql中真實存在的庫),其數據信息時完全一致的。
在mycat上開啟mycat日志信息
[root@yum ~]# echo > /usr/local/mycat/logs/mycat.log [root@yum ~]# tailf /usr/local/mycat/logs/mycat.log
先在mycat上查詢數據信息
MySQL [kaka]> select * from t1; +------+----------+ | id | name | +------+----------+ | 1 | xiaowang | | 2 | xiaogong | +------+----------+ 2 rows in set (0.00 sec)
在mycat日志上可以看到一條如下的信息,通過該日志信息可以看出mycat的查詢是在slave數據據(10.0.0.6)上查詢的
[node=dn1{select * from t1}, packetId=6], host=10.0.0.6, port=3306, statusSync=null, writeQueue=0, modifiedSQLExecuted=false]
在mycat上給t1表創建一條數據信息
MySQL [kaka]> insert into t1 values(3,"xiaoxiao"),(4,"popo"); Query OK, 2 rows affected (0.00 sec) Records: 2 Duplicates: 0 Warnings: 0 MySQL [kaka]> select * from t1; +------+----------+ | id | name | +------+----------+ | 1 | xiaowang | | 2 | xiaogong | | 3 | xiaoxiao | | 4 | popo | +------+----------+ 6 rows in set (0.00 sec)
在mycat日志上可以看到一條如下的信息,通過該日志信息可以看出mycat更改數據庫信息是在master數據據(10.0.0.5)上執行相應的sql語句
[node=dn1{insert into t1 values(3,"xiaoxiao"),(4,"popo")}, packetId=0], host=10.0.0.5, port=3306, statusSync=null, writeQueue=0, modifiedSQLExecuted=true]
5.3、mysql主從數據故障了對mycat的影響
mysql主從數據庫其中一台宕機了對mycat沒有任何影響。 slave宕機了,mycat自動把數據的讀取轉移到master上; master宕機了,mycat自動把數據的讀取轉移到slave上。
模擬master宕機:
在master上關閉數據庫
[root@web03 ~]# systemctl stop mariadb
在mycat上寫入數據信息
MySQL [kaka]> insert into t1 values(5,"aaa"); Query OK, 1 row affected (0.01 sec)
可以看到數據信息是通過slave(10.0.0.6)寫入數據庫的
[node=dn1{insert into t1 values(5,"aaa")}, packetId=1], host=10.0.0.6, port=3306, statusSync=null, writeQueue=0, modifiedSQLExecuted=true]
5.4mycat一般錯誤解決
MySQL [lutixiadb]> show tables; ERROR 1184 (HY000): Invalid DataSource:0 可能是后端節點出現了問題,也有可能是代理端無法連上后端節點導致: 可以先在代理端直接用授權用戶名和密碼登錄后端數據庫測試連接問題: [root@node3 conf]# mysql -umycat-proxy -h192.168.75.134 -p123456 ERROR 1129 (HY000): Host 'node3' is blocked because of many connection errors; unblock with 'mysqladmin flush-hosts' # 可以看到因為多次錯誤,代理端服務器被鎖定了,所以也會出現上面的報錯: 在后端主庫執行如下命令: mysqladmin flush-hosts 再次測試,一般問題就能解決。