mysql主從複製與讀寫分離
主從複製原理:在主資料庫執行後,都會寫入本地的日誌系統A中。假設,實時的將變化了的日誌系統中的資料庫事件操作,在主資料庫的3306埠,通過網路發給從資料。從資料庫收到後,寫入本地日誌系統B,然後一條條的將資料庫事件在資料庫中完成。那麼,主資料庫的變化,從資料庫也會變化,這樣就是所謂的MYSQL的複製。
讀寫分離可以提高資料庫的讀寫效能。
實驗環境
iptables和selinux關閉
redhat6.5
主資料庫 server2 172.25.12.2
從資料庫 server3 172.25.12.3
實驗所需的的rpm包
mysql-community-client-5.7.17-1.el6.x86_64.rpm
mysql-community-common-5.7.17-1.el6.x86_64.rpm
mysql-community-libs-5.7.17-1.el6.x86_64.rpm
mysql-community-libs-compat-5.7.17-1.el6.x86_64.rpm
mysql-community-server-5.7.17-1.el6.x86_64.rpm
1.資料庫的配置
安裝資料庫
/etc/init.d/mysqld start
修改密碼:
grep password /var/log/mysqld.log
檢視那資料庫的臨時密碼
2017-08-03T07:20:46.472777Z 1 [Note] A temporary password is generated for root@localhost: bty;2uN;C1qF
mysql -p 登陸資料庫的修改密碼
Enter password:
mysql> show databases;
mysql> ALTER USER [email protected]
新增本地資料庫使用者
mysql> show databases;
mysql> select * from mysql.user\G;
檢查資料庫
[[email protected] ~]# mysql -p
mysql> show databases;
其他資料庫主機操作類似。
2.主從複製:
主資料庫
配置主資料檔案
[[email protected] ~]# vim /etc/my.cnf
server-id=1
log-bin=mysql-bin
binlog-do-db=test
binlog-ignore-db=mysql
配置從資料檔案
[
server-id=3
[[email protected] ~]# /etc/init.d/mysqld restart
[[email protected] ~]# /etc/init.d/mysqld restart
主資料庫:
[[email protected] ~]# /etc/init.d/mysqld restart
[[email protected] ~]# mysql -p
mysql> show databases;
mysql> grant replication slave on . to [email protected]’172.25.12.%’ identified by ‘Redhat+007’;
主服務上新增一個授權的賬戶,使得到時候從伺服器可以使用該賬號來完成資料的獲取.
可以在從資料庫端進行測試:
mysql -uwax -pRedhat+007 -h 172.25.12.11
mysql> show master status;
+------------------+----------+--------------+------------------+-------------------+
| File | Position | Binlog_Do_DB | Binlog_Ignore_DB | Executed_Gtid_Set |
+------------------+----------+--------------+------------------+-------------------+
| mysql-bin.000001 | 833 | test | mysql | |
+------------------+----------+--------------+------------------+-------------------+
mysql-bin.000001 是二進位制日誌檔案
833 是結束的位置
在從資料庫上
[[email protected] ~]# mysql -p
Enter password:
mysql> show slave status;
mysql> change master to master_host=’172.25.12.11’,master_user=’wax’, master_password=’Redhat+007’, master_log_file=’mysql-bin.000001’, master_log_pos=833;
mysql> start slave;
mysql> show slave status;
mysql> show slave status\G;
Relay_Log_Pos: 638
Relay_Master_Log_File: mysql-bin.000001
Slave_IO_Running: Yes
Slave_SQL_Running: Yes
測試:
在主資料庫上
mysql> create database test;
mysql> use test;
Database changed
mysql> create table usertb (
-> username varchar(15) not null ,
-> password varchar(25) not null );
mysql> insert into usertb values (“user1”,”123”);
mysql> insert into usertb values (“user2”,”123”);
mysql> select * from usertb ;
mysql> update usertb set password=’333’ where username=’user2’;
mysql> select * from usertb ;
從資料庫
[[email protected] ~]# mysql -p
mysql> show databases;
mysql> use test;
mysql> select * from usertb;
mysql> quit
- GTID
GTID是一個基於原始MySQL伺服器生成的一個已經被成功執行的全域性事務ID,它由伺服器ID以及事務ID組合而成。這個全域性事務ID不僅僅在原始伺服器器上唯一,在所有存在主從關係 的mysql伺服器上也是唯一的。正是因為這樣一個特性使得mysql的主從複製變得更加簡單,以及資料庫一致性更可靠。
主資料庫
[[email protected] mysql]# vim /etc/my.cnf
gtid_mode=ON
enforce-gtid-consistency=true
[[email protected] mysql]# /etc/init.d/mysqld restart
從伺服器
[[email protected] ~]# vim /etc/my.cnf
gtid_mode=ON
enforce-gtid-consistency=true
[[email protected] ~]# /etc/init.d/mysqld restart
[[email protected] ~]# mysql -pRedhat+007
mysql> stop slave;
mysql> change master to master_host=’172.25.12.2’,master_user=’wax’, master_password=’Redhat+007’,MASTER_AUTO_POSITION=1;
mysql> start slave;
mysql> show slave status\G;
mysql> set global read_only=on ;
mysql> use test;
mysql> show tables;
mysql> use mysql;
mysql> show tables;
mysql> select * from gtid_executed;
3.並行複製
MySQL 5.7並行複製的思想簡單易懂,一言以蔽之:一個組提交的事務都是可以並行
回放,因為這些事務都已進入到事務的prepare階段,則說明事務之間沒有任何衝突
(否則就不可能提交)。
在從伺服器
[[email protected] ~]# vim /etc/my.cnf
slave-parallel-type=LOGICAL_CLOCK
slave-parallel-workers=16
master_info_repository=TABLE
relay_log_info_repository=TABLE
relay_log_recovery=ON
[[email protected] ~]# /etc/init.d/mysqld restart
[[email protected] ~]# mysql -pRedhat+007
mysql> show processlist;
會出現16個預設的程序
[[email protected] ~]# mysql -pRedhat+007
mysql> show databases;
mysql> use mysql;
mysql> show tables;
+---------------------------+
| Tables_in_mysql |
+---------------------------+
| server_cost |
| servers |
| slave_master_info |
| slave_relay_log_info |
| slave_worker_info |
| slow_log |
| tables_priv |
資料的的一些資訊以表格的形式儲存,而不是以庫的形式儲存
4.半同步複製 指IO執行緒 為儘可能的資料一致性
[[email protected] mysql]# cd /usr/lib64/mysql/plugin/
[[email protected] plugin]# ls 檢視半同步模組
[[email protected] mysql]# mysql -pRedhat+007
mysql> INSTALL PLUGIN rpl_semi_sync_master SONAME ‘semisync_master.so’;
匯入半同步模組
mysql> show plugins;檢視模組
mysql> show variables like ‘%semi_sync%’;
| Variable_name | Value |
+-------------------------------------------+------------+
| rpl_semi_sync_master_enabled | OFF |
| rpl_semi_sync_master_timeout | 10000 |
會等待十妙。如果不能收到從伺服器的迴應,則轉化為非同步
| rpl_semi_sync_master_trace_level | 32 |
| rpl_semi_sync_master_wait_for_slave_count | 1 |
| rpl_semi_sync_master_wait_no_slave | ON |
| rpl_semi_sync_master_wait_point | AFTER_SYNC |
+-------------------------------------------+------------+
6 rows in set (0.00 sec)
mysql> set global rpl_semi_sync_master_enabled=1;
mysql> show variables like ‘%semi_sync%’;
mysql> show status like ‘%semi_sync%’;
從資料庫上:
mysql> INSTALL PLUGIN rpl_semi_sync_slave SONAME ‘semisync_slave.so’; 匯入模組
mysql> show plugins;
| validate_password | ACTIVE | VALIDATE PASSWORD | validate_password.so | GPL |
| rpl_semi_sync_slave | ACTIVE | REPLICATION | semisync_slave.so | GPL
mysql> show variables like ‘%semi_sync%’;
| rpl_semi_sync_slave_enabled | OFF |
| rpl_semi_sync_slave_trace_level | 32 |
mysql> set global rpl_semi_sync_slave_enabled=1;
mysql> show variables like ‘%semi_sync%’;
| rpl_semi_sync_slave_enabled | ON |
| rpl_semi_sync_slave_trace_level | 32 |
mysql> show status like ‘%semi_sync%’;
| Rpl_semi_sync_slave_status | OFF |
停掉開啟使其生效
mysql> stop slave io_thread;
mysql> start slave io_thread;
mysql> show status like ‘%semi_sync%’;
| Rpl_semi_sync_slave_status | ON |
測試:
在主資料庫上:
mysql> use test;
mysql> insert into usertb values (‘user3’,’1234’);
mysql> show status like ‘%semi_sync%’;
mysql> insert into usertb values (‘user4’,’5432’);
mysql> show status like ‘%semi_sync%’;
mysql> insert into usertb values (‘user5’,’545532’);
可以停掉從資料庫上的IO執行緒再測試
mysql> stop slave io_thread;
mysql> start slave io_thread;
5.讀寫分離
MySQL的主從複製和MySQL的讀寫分離兩者有著緊密聯絡,首先部署主從複製,只有主從複製完了,才能在此基礎上進行資料的讀寫分離。簡單來說,讀寫分離就是隻在主伺服器上寫,只在從伺服器上讀,基本的原理是讓主資料庫處理事務性查詢,而從資料庫處理select查詢,資料庫複製被用來把事務性查詢導致的改變更新同步到叢集中的從資料庫。
資料庫的讀寫分離:
新建一個虛擬機器作為排程器
mysql-proxy-0.8.5-linux-el6-x86-64bit.tar.gz
tar zxf mysql-proxy-0.8.5-linux-el6-x86-64bit.tar.gz -C /usr/local/
cd /usr/local/
ln -s mysql-proxy-0.8.5-linux-el6-x86-64bit/ mysql-proxy
cd mysql-proxy
mkdir etc 建立指令碼存放目錄
mkdir log 建立日誌目錄
修改讀寫分離配置檔案
vi /usr/local/mysql-proxy/lua/rw-splitting.lua
min_idle_connections = 1,#預設超過4個連線數時,才開始讀寫分離,改為1
max_idle_connections = 2, #預設8,改為2
vim mysql-proxy.conf
[mysql-proxy]
user=root 執行mysql-proxy使用者
daemon=true 以守護程序方式執行
keepalive=true 崩潰時,嘗試重啟
log-level=debug 定義log日誌級別,由高到低分別有(error|warning|info|message|debug)
log-file=/usr/local/mysql-proxy/log/mysql-proxy.log 日誌位置
admin-username=wax 主從mysql共有的使用者
admin-password=Redhat+007 使用者的密碼
admin-lua-script=/usr/local/mysql-proxy/lib/mysql-proxy/lua/admin.lua 管理指令碼
proxy-lua-script=/usr/local/mysql-proxy/share/doc/mysql-proxy/rw-splitting.lua 讀寫分離配置指令碼
proxy-read-only-backend-addresses=172.25.12.3:3306 指定後端從slave讀取資料
proxy-backend-addresses=172.25.12.2:3306 指定後端主master寫入資料
plugins=proxy,admin
~
chmod 660 /usr/local/mysql-proxy/etc/mysql-proxy.conf
bin/mysql-proxy –defaults-file=/usr/local/mysql-proxy/etc/mysql-proxy.conf
測試:
在排程資料庫上
[[email protected] mysql-proxy]# ps ax
1177 ? S 0:00 /usr/local/mysql-proxy/libexec/mysql-proxy --defaults-file=/usr/local/mysql-pro
1178 ? S 0:00 /usr/local/mysql-proxy/libexec/mysql-proxy --defaults-file=/usr/local/mysql-pro
1179 pts/0 R+ 0:00 ps ax
[[email protected] mysql-proxy]# netstat -antlpe
Active Internet connections (servers and established)
Proto Recv-Q Send-Q Local Address Foreign Address State User Inode PID/Program name
tcp 0 0 0.0.0.0:22 0.0.0.0:* LISTEN 0 8125 903/sshd
tcp 0 0 127.0.0.1:25 0.0.0.0:* LISTEN 0 8331 981/master
tcp 0 0 0.0.0.0:4040 0.0.0.0:* LISTEN 0 9734 1178/mysql-proxy
tcp 0 0 0.0.0.0:4041 0.0.0.0:* LISTEN 0 9737 1178/mysql-proxy
遠端登入資料庫看是否可以檢視
[[email protected] mysql-proxy]# yum install -y mysql
[[email protected] mysql-proxy]# mysql -h 172.25.12.4 -P 4041 -u admin -p
mysql-proxy啟動後會啟動兩個埠4040和4041,4040用於SQL轉發,4041用於管理mysql-proxy。如有多個mysql-slave可以依次在後面新增
mysql> show databases;
ERROR 1105 (07000): use 'SELECT * FROM help' to see the supported commands
mysql> SELECT * FROM help;
+------------------------+------------------------------------+
| command | description |
+------------------------+------------------------------------+
| SELECT * FROM help | shows this help |
| SELECT * FROM backends | lists the backends and their state |
+------------------------+------------------------------------+
2 rows in set (0.00 sec)
mysql> SELECT * FROM backends;
+-------------+------------------+---------+------+------+-------------------+
| backend_ndx | address | state | type | uuid | connected_clients |
+-------------+------------------+---------+------+------+-------------------+
| 1 | 172.25.12.4:3306 | unknown | rw | NULL | 0 |
| 2 | 172.25.12.2:3306 | unknown | ro | NULL |
在主資料庫中為使用者授權
mysql> select * from mysql.user\G;
mysql> grant insert,select,update on . to [email protected]’172.25.12.%’ identified by ‘Westos+007’;
mysql> quit
在從資料庫中為使用者授權
[[email protected] mysql]# mysql -pRedhat+007
mysql> grant select on . to [email protected]’172.25.12.%’ identified by ‘Westos+007’;
Query OK, 0 rows affected, 1 warning (0.00 sec)
mysql> quit
Bye
[[email protected] mysql-proxy]# yum install -y lsof
lsof(list open files)是一個列出當前系統開啟檔案的工具。在linux環境下,任何事物都以檔案的形式存在,通過檔案不僅僅可以訪問常規資料,還可以訪問網路連線和硬體。所以如傳輸控制協議 (TCP) 和使用者資料報協議 (UDP) 套接字等,系統在後臺都為該應用程式分配了一個檔案描述符,無論這個檔案的本質如何,該檔案描述符為應用程式與基礎作業系統之間的互動提供了通用介面。
在真機上進行多次連線連線後檢視排程器和後臺的來年接情況
yum install -y mysql
mysql -h 172.25.12.4 -P 4040 -u admin -pWestos+007
在排程器和資料庫伺服器檢視開啟的連線
[[email protected] mysql-proxy]# lsof -i :3306
COMMAND PID USER FD TYPE DEVICE SIZE/OFF NODE NAME
mysql-pro 1238 root 13u IPv4 10349 0t0 TCP server4:38410->server2:mysql (ESTABLISHED)
mysql-pro 1238 root 15u IPv4 10368 0t0 TCP server4:38411->server2:mysql (ESTABLISHED)
mysql-pro 1238 root 16u IPv4 10373 0t0 TCP server4:55728->server3:mysql (ESTABLISHED)
mysql-pro 1238 root 18u IPv4 10375 0t0 TCP server4:55729->server3:mysql (ESTABLISHED)
[[email protected] mysql]# yum install -y lsof
[[email protected] mysql]# lsof -i :3306
COMMAND PID USER FD TYPE DEVICE SIZE/OFF NODE NAME
mysqld 1208 mysql 34u IPv6 8528 0t0 TCP *:mysql (LISTEN)
mysqld 1208 mysql 52u IPv6 9402 0t0 TCP server2:mysql->server4:38393 (ESTABLISHED)
mysqld 1208 mysql 53u IPv6 9285 0t0 TCP server2:mysql->server3:40559 (ESTABLISHED)
mysqld 1208 mysql 55u IPv6 9404 0t0 TCP server2:mysql->server4:38395 (ESTABLISHED)
[[email protected] mysql]# yum install -y lsof
[[email protected] mysql]# lsof -i :3306
[[email protected] mysql]# lsof -i :3306
6.資料庫日誌的檢視
可在主資料庫上檢視日誌檔案
[[email protected] ~]# cd /var/lib/mysql
[[email protected] mysql]# mysqlbinlog mysql-bin.000001
檢視資料庫的二進位制檔案
檢視資料庫的一些引數
mysql> show variables like ‘%sync%’; 頻率
mysql> show variables like ‘%binlog%’; 日誌檔案
mysql> show variables like ‘%log%’;
資料庫的編碼查詢
mysqlbinlog binlog.000003
mysqlbinlog binlog.000003 –base64-output=DECODE-ROWS
mysqlbinlog binlog.000003 –base64-output=DECODE-ROWS -v
mysqlbinlog binlog.000003 –base64-output=DECODE-ROWS -vv
mysqlbinlog binlog.000003 –base64-output=DECODE-ROWS -vvv