1. 程式人生 > >CentOS6.5搭建MySQL主從複製,讀寫分離(冷月宮主親自整理,最簡單明瞭)

CentOS6.5搭建MySQL主從複製,讀寫分離(冷月宮主親自整理,最簡單明瞭)

CentOS6.5搭建MySQL主從複製,讀寫分離


MySQL主從複製的優點:
1、 如果主伺服器出現問題, 可以快速切換到從伺服器提供的服務,保證高可用性
2、 可以在從伺服器上執行查詢操作, 降低主伺服器的訪問壓力
3、 可以在從伺服器上執行備份, 以避免備份期間影響主伺服器的服務


注意事項:
1、server-id必須唯一,一般使用ip的後三位
2、從庫Slave_IO_Running:NO 可能原因:帳號無許可權操作
3、Can't execute the query because you have a conflicting read lock,解鎖下即可 unlock tables;
4、一般只有更新不頻繁的資料或者對實時性要求不高的資料可以通過從伺服器查詢, 實時性要求高的資料仍然需要從主資料庫獲得
5、修改完主從伺服器的配置需要重啟mysql:service mysqld restart


MySQL_Proxy:192.168.10.211 4040
MySQL_Master: 192.168.10.212 3306
MySQL_Slave01: 192.168.10.213 3306
MySQL_Slave02: 192.168.10.214 3306


請先分別安裝mysql,版本需一致,裝了即可跳過


一、安裝mysql(master和slave)


yum -y install mysql mysql-server #輸入y即可自動安裝,直到安裝完成


設定防火牆開放3306埠。
vim /etc/sysconfig/iptables
service iptables restart


service mysqld start
mysqladmin -u root password '
[email protected]
'
mysql -u root -p


set password for [email protected]=password('[email protected]');
create user 'MySQL'@'%' identified by '[email protected]'; 
grant all privileges on *.* to 'MySQL'@'localhost' identified by '[email protected]';
grant all privileges on *.* to 'MySQL'@'%' identified by '
[email protected]
';
GRANT ALL PRIVILEGES ON *.* TO 'MySQL'@'%' IDENTIFIED BY '[email protected]' WITH GRANT OPTION MAX_QUERIES_PER_HOUR 0 MAX_CONNECTIONS_PER_HOUR 0 MAX_UPDATES_PER_HOUR 0 MAX_USER_CONNECTIONS 0;
flush privileges;




1、先登入主機 A,在主伺服器上,設定一個從資料庫的賬戶,使用REPLICATION SLAVE(從複製)賦予許可權,如:
mysql>create user 'slave01'@'192.168.10.213' identified by '
[email protected]
'; 
mysql>GRANT REPLICATION SLAVE ON *.* TO 'slave01'@'192.168.10.213' IDENTIFIED BY '[email protected]';


mysql>create user 'slave02'@'192.168.10.214' identified by '[email protected]'; 
mysql>GRANT REPLICATION SLAVE ON *.* TO 'slave02'@'192.168.10.214' IDENTIFIED BY '[email protected]';


賦予從機許可權,有多臺從機,就執行多次。
mysql>flush privileges;
mysql>exit;
2、 開啟主機A的my.cnf,輸入如下:(修改主資料庫的配置檔案my.cnf,開啟BINLOG,並設定server-id的值,修改之後必須重啟mysql服務)
cp /etc/my.cnf /etc/my.cnf.bak
vim /etc/my.cnf 
server-id=1    #主機標示,整數
log_bin=mysql-bin #確保此檔案可寫,開啟bin-log
read-only=0  #主機,讀寫都可以
binlog-do-db=test   #需要備份資料,多個寫多行
binlog-ignore-db=mysql #不需要備份的資料庫,多個寫多行


重啟mysql服務:
service mysqld restart
mysql -u root -p


可以通過mysql>show variables like 'log_%'; 驗證二進位制日誌是否已經啟動。
3、現在可以停止主資料的的更新操作,並生成主資料庫的備份,我們可以通過mysqldump到處資料到從資料庫,當然了,你也可以直接用cp命令將資料檔案複製到從資料庫去,注意在匯出資料之前先對主資料庫進行READ LOCK,以保證資料的一致性
mysql> flush tables with read lock;
Query OK, 0 rows affected (0.19 sec)


然後mysqldump匯出資料:
mysqldump -h127.0.0.1 -p3306 -uroot -p test > /opt/test.sql


4、得到主伺服器當前二進位制日誌名和偏移量,這個操作的目的是為了在從資料庫啟動後,從這個點開始進行資料的恢復。
mysql> show master status;
+------------------+----------+--------------+------------------+
| File             | Position | Binlog_Do_DB | Binlog_Ignore_DB |
+------------------+----------+--------------+------------------+
| mysql-bin.000007 |      517 | test         | mysql            |
+------------------+----------+--------------+------------------+
1 row in set (0.00 sec)




最好在主資料庫備份完畢,恢復寫操作。
mysql> unlock tables;
Query OK, 0 rows affected (0.28 sec)


5、將剛才主資料備份的test.sql複製到從資料庫(navicat、phpmyadmin、命令列都可以),進行匯入。
scp -r -P 22 /opt/test.sql [email protected]:/opt/
scp -r -P 22 /opt/test.sql [email protected]:/opt/


mysql -u root -p test < /opt/test.sql
6、修改從資料庫的my.cnf,增加server-id引數,指定複製使用的使用者,主資料庫伺服器的ip,埠以及開始執行復制日誌的檔案和位置。開啟從機B的my.cnf,輸入(修改之後必須重啟mysql服務)
cp /etc/my.cnf /etc/my.cnf.bak
vim /etc/my.cnf 


server-id=2
log_bin=mysql-bin
master-host=192.168.10.212
master-user=slave01
[email protected]
master-port=3306
master-connect-retry=60 #如果從伺服器發現主伺服器斷掉,重新連線的時間差(秒)
replicate-do-db=test #只複製某個庫
replicate-ignore-db=mysql #不復制某個庫
slave-skip-errors


7、在從伺服器上,啟動slave程序
mysql -u root -p
mysql> start slave;


8、在從伺服器進行show salve status驗證


mysql> SHOW SLAVE STATUS\G
*************************** 1. row ***************************
               Slave_IO_State: Waiting for master to send event
                  Master_Host: 192.168.10.212
                  Master_User: slave01
                  Master_Port: 3306
                Connect_Retry: 60
              Master_Log_File: mysql-bin.000004
          Read_Master_Log_Pos: 106
               Relay_Log_File: mysqld-relay-bin.000006
                Relay_Log_Pos: 251
        Relay_Master_Log_File: mysql-bin.000004
             Slave_IO_Running: Yes
            Slave_SQL_Running: Yes
              Replicate_Do_DB: test
          Replicate_Ignore_DB: mysql
           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: 106
              Relay_Log_Space: 552
              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: 
1 row in set (0.00 sec)


提示
Slave_IO_Running: Yes
Slave_SQL_Running: Yes
說明配置成功了




如果有NO,則做如下操作:
在Master機操作:
service mysqld restart
show master status;


mysql> show master status;
+------------------+----------+--------------+------------------+
| File             | Position | Binlog_Do_DB | Binlog_Ignore_DB |
+------------------+----------+--------------+------------------+
| mysql-bin.000003 |      954 | test         | mysql            |
+------------------+----------+--------------+------------------+
1 row in set (0.00 sec)


mysql> 


在Slave機操作:
SLAVE STOP; 
CHANGE MASTER TO MASTER_LOG_FILE='mysql-bin.000003', MASTER_LOG_POS=954; 
SLAVE START; 
show slave status\G


如果還是有NO就要注意一下在Master機上的授權語句,需要對slave授REPLICATION SLAVE許可權。


9、測試主從伺服器是否能同步 
插入 修改 刪除 增加欄位 修改欄位 增加表自己測試都可以


[[email protected] ~]$mysql -uroot [email protected]
mysql> create database test;  或   use test;
mysql> create table user(id int);
mysql> insert into user values(1),(2),(3),(4),(5),(6);
Query OK, 2 rows affected (0.00 sec)
Records: 2  Duplicates: 0  Warnings: 0


mysql> select * from user;
+----+
| id |
+----+
|  1 |
|  2 |
+----+
2rows in set (0.00 sec)




mysql> select * from user;
+----+
| id |
+----+
|  1 |
|  2 |
|  3 |
|  4 |
|  5 |
|  6 |
+----+
6 rows in set (0.00 sec)




mysql> update user set id=11 where id=1;
Query OK, 1 row affected (0.00 sec)
Rows matched: 1  Changed: 1  Warnings: 0




mysql> select * from user;
+----+
| id |
+----+
| 11 |
|  2 |
|  3 |
|  4 |
|  5 |
|  6 |
+----+
6 rows in set (0.00 sec)




mysql> delete from user where id=2;
Query OK, 1 row affected (0.00 sec)




mysql> select * from user;
+----+
| id |
+----+
| 11 |
|  3 |
|  4 |
|  5 |
|  6 |
+----+
5 rows in set (0.00 sec)




mysql> alter table user add name varchar(50);
Query OK, 5 rows affected (0.01 sec)
Records: 5  Duplicates: 0  Warnings: 0




mysql> select * from user;
+----+------+
| id | name |
+----+------+
| 11 | NULL |
|  3 | NULL |
|  4 | NULL |
|  5 | NULL |
|  6 | NULL |
+----+------+
5 rows in set (0.00 sec)
mysql> ALTER TABLE user  MODIFY COLUMN name VARCHAR(200);
Query OK, 5 rows affected (0.01 sec)
Records: 5  Duplicates: 0  Warnings: 0




mysql> desc user;
+-------+--------------+------+-----+---------+-------+
| Field | Type         | Null | Key | Default | Extra |
+-------+--------------+------+-----+---------+-------+
| id    | int(11)      | NO   |     | NULL    |       |
| name  | varchar(200) | YES  |     | NULL    |       |
+-------+--------------+------+-----+---------+-------+
2 rows in set (0.00 sec)


mysql> create table user2(id int);
Query OK, 0 rows affected (0.01 sec)


mysql> show tables;
+----------------+
| Tables_in_test |
+----------------+
| test           |
| user           |
| user2          |
+----------------+
3 rows in set (0.00 sec)
mysql>






在從伺服器檢視是否同步過來 如果一致說明成功


mysql> use test;
Database changed
mysql> select * from user;
+----+
| id |
+----+
|  1 |
|  2 |
|  3 |
|  4 |
|  5 |
|  6 |
+----+
2 rows in set (0.00 sec)


mysql> select * from user;
+----+
| id |
+----+
|  1 |
|  2 |
|  3 |
|  4 |
|  5 |
|  6 |
+----+
6 rows in set (0.00 sec)


mysql> select * from user;
+----+
| id |
+----+
| 11 |
|  2 |
|  3 |
|  4 |
|  5 |
|  6 |
+----+
6 rows in set (0.00 sec)


mysql> select * from user;
+----+
| id |
+----+
| 11 |
|  3 |
|  4 |
|  5 |
|  6 |
+----+
5 rows in set (0.00 sec)


mysql> select * from user;
+----+------+
| id | name |
+----+------+
| 11 | NULL |
|  3 | NULL |
|  4 | NULL |
|  5 | NULL |
|  6 | NULL |
+----+------+
5 rows in set (0.00 sec)
mysql> desc user;
+-------+--------------+------+-----+---------+-------+
| Field | Type         | Null | Key | Default | Extra |
+-------+--------------+------+-----+---------+-------+
| id    | int(11)      | NO   |     | NULL    |       |
| name  | varchar(200) | YES  |     | NULL    |       |
+-------+--------------+------+-----+---------+-------+
2 rows in set (0.00 sec)


mysql> show tables;
+----------------+
| Tables_in_test |
+----------------+
| test           |
| user           |
| user2          |
+----------------+
3 rows in set (0.00 sec)


mysql>


mysql binlog日誌檢視: 


show binlog events\G;


*************************** 12. row ***************************
   Log_name: mysql-bin.000007
        Pos: 985
 Event_type: Query
  Server_id: 1
End_log_pos: 1075
       Info: use `test`; delete from user where id=2
*************************** 13. row ***************************
   Log_name: mysql-bin.000007
        Pos: 1075
 Event_type: Query
  Server_id: 1
End_log_pos: 1175
       Info: use `test`; alter table user add name varchar(50)
*************************** 14. row ***************************
   Log_name: mysql-bin.000007
        Pos: 1175
 Event_type: Query
  Server_id: 1
End_log_pos: 1287
       Info: use `test`; ALTER TABLE user  MODIFY COLUMN name VARCHAR(200)
*************************** 15. row ***************************
   Log_name: mysql-bin.000007
        Pos: 1287
 Event_type: Query
  Server_id: 1
End_log_pos: 1376
       Info: use `test`; create table user2(id int)
15 rows in set (0.00 sec)


本文永久更新連結地址:http://www.linuxidc.com/Linux/2016-09/135121.htm




二.安裝mysql-proxy
實現讀寫分離是由lua指令碼實現的,現在mysql-proxy裡面已經整合,無需再安裝
cd /u01/
wget http://downloads.mysql.com/archives/get/file/mysql-proxy-0.8.5-linux-glibc2.3-x86-64bit.tar.gz
tar -zxvf mysql-proxy-0.8.5-linux-glibc2.3-x86-64bit.tar.gz
mv mysql-proxy-0.8.5-linux-glibc2.3-x86-64bit mysql-proxy
3.配置mysql-proxy
cd mysql-proxy
mkdir lua #建立指令碼存放目錄
mkdir logs #建立日誌目錄
mkdir conf #放置配置檔案
cp share/doc/mysql-proxy/rw-splitting.lua ./lua #複製讀寫分離配置檔案
cp share/doc/mysql-proxy/admin-sql.lua ./lua #複製管理指令碼


vim conf/mysql-proxy.cnf      (選項值後不能有任何空格,keepalive也是)
[mysql-proxy]
daemon=true
#以守護程序方式執行
user=root
#執行mysql-proxy使用者
pid-file=/u01/mysql-proxy/logs/mysql-proxy.pid
#程序pid檔案
keepalive=true
#mysql-proxy崩潰時,嘗試重啟
event-threads=4
#event-handing執行緒數,預設值是1
max-open-files=2048
#最大檔案控制代碼數


log-level=info
#日誌級別:error|warning|info|message|debug
#log-use-syslog=true  
#日誌使用syslog,和log-file只能開啟一個
log-file=/u01/mysql-proxy/logs/mysql-proxy.log
#日誌檔案


admin-username=MySQL
#主從mysql共有的使用者
[email protected]
#使用者的密碼
admin-address=192.168.10.211:4040
#mysql-proxy執行ip和埠,不加埠,預設4040
admin-lua-script=/u01/mysql-proxy/lua/admin-sql.lua
#指定管理指令碼


proxy-skip-profiling=true
#是否禁用查詢效能剖析
proxy-backend-addresses=192.168.10.212:3306
#後端主mysql的ip和port
proxy-read-only-backend-addresses=192.168.10.213:3306,192.168.10.214:3306
#指定後端從slave讀取資料,多個以逗號分隔,超過2條換行寫
proxy-lua-script=/u01/mysql-proxy/lua/rw-splitting.lua
#指定讀寫分離配置檔案位置




由於安全要求,必須將配置檔案許可權設為660(建立人可讀寫,同組人可讀),否則不允許啟動。
chmod 660 conf/mysql-proxy.cnf
4.修改讀寫分離指令碼
if not proxy.global.config.rwsplit then
        proxy.global.config.rwsplit = {
                min_idle_connections = 1, --預設超過4個連線數時,才開始讀寫分離,改為1
                max_idle_connections = 1, --預設8,改為1


                is_debug = false
        }
end
5.啟動mysql-proxy
./bin/mysql-proxy --defaults-file=conf/mysql-proxy.cnf


使用多個客戶端查詢,新增資料測試。