Mysql數據庫的主從同步,實現讀寫分離 詳細配置說明 以及錯誤解決辦法

利用主從數據庫來實現讀寫分離,從而分擔主數據庫的壓力。在多個服務器上部署mysql,將其中一臺認爲主數據庫,而其他爲從數據庫,實現主從同步。其中主數據庫負責主動寫的操作,而從數據庫則只負責主動讀的操作(slave從數據庫仍然會被動的進行寫操作,爲了保持數據一致性),這樣就可以很大程度上的避免數據丟失的問題,同時也可減少數據庫的連接,減輕主數據庫的負載。
在這裏插入圖片描述

在上面的模型中,Mysql-A就是主服務器,即master,Mysql-B就是從服務器,即slave。

在Mysql-A的數據庫事件(例如修改數據庫的sql操作語句),都會存儲到日誌系統A中,在相應的端口(默認3306)通過網絡發送給Mysql-B。Mysql-B收到後,寫入本地日誌系統B,然後一條條的將數據庫事件在數據庫Mysql-B中完成。

日誌系統A,是MYSQL的日誌類型中的二進制日誌,也就是專門用來保存修改數據庫表的所有動作,即bin log,注意MYSQL會在執行語句之後,釋放鎖之前,寫入二進制日誌,確保事務安全。

日誌系統B,不是二進制日誌,由於它是從MYSQL-A的二進制日誌複製過來的,並不是自己的數據庫變化產生的,有點接力的感覺,稱爲中繼日誌,即relay log。

通過上面的機制,可以保證Mysql-A和Mysql-B的數據庫數據一致,但是時間上肯定有延遲,即Mysql-B的數據是滯後的。因此,會出現這樣的問題,Mysql-A的數據庫操作是可以併發的執行的,但是Mysql-B只能從relay log中一條一條的讀取執行。若Mysql-A的寫操作很頻繁,Mysql-B很可能就跟不上了。

主從同步複製有以下幾種方式:

(1)同步複製,master的變化,必須等待slave-1,slave-2,…,slave-n完成後才能返回。
(2)異步複製,master只需要完成自己的數據庫操作即可,至於slaves是否收到二進制日誌,是否完成操作,不用關心。MYSQL的默認設置。
(3)半同步複製,master只保證slaves中的一個操作成功,就返回,其他slave不管。這個功能,是由google爲MYSQL引入的。

實現的mysql5.7數據庫的主從同步配置,從而實現讀寫分離操作

master主服務器的配置

  1. 配置文件my.cnf的修改(系統不一致 文件可能名字位置不同)
[root@localhost mysql]# vim /etc/my.cnf
# 不同的系統名字位置不同 /etc/mysql/mysql.conf.d/mysqld.cnf 
#在[mysqld]中添加:
server-id=1
log_bin=master-bin
log_bin_index=master-bin.index
binlog_do_db=test
#備註:
#server-id 服務器唯一標識。
#log_bin 啓動MySQL二進制日誌,即數據同步語句,從數據庫會一條一條的執行這些語句。
#binlog_do_db 指定記錄二進制日誌的數據庫,即需要複製的數據庫名,如果複製多個數據庫,重複設置這個選項即可。
#binlog_ignore_db 指定不記錄二進制日誌的數據庫,即不需要複製的數據庫名,如果有多個數據庫,重複設置這個選項即可。
#其中需要注意的是,binlog_do_db和binlog_ignore_db爲互斥選項,一般只需要一個即可。
  1. 創建從服務器的用戶和權限
#進入mysql數據庫
[root@localhost mysql]# mysql -uroot -p
Enter password:
#創建來訪者用戶及host
mysql> create user 'masterbackup'@'192.168.139.%' identified by '123456';
#創建從數據庫的masterbackup用戶和權限
mysql> grant replication slave on *.* to masterbackup@'192.168.17.%' identified by '123456';
#備註
#192.168.17.%通配符,表示0-255的IP都可訪問主服務器,正式環境請配置指定從服務器IP
#若將 192.168.17.% 改爲 %,則任何ip均可作爲其從數據庫來訪問主服務器
 
#退出mysql
mysql> exit;
  1. 重啓mysql服務
[root@localhost mysql]# service mysql restart
Shutting down MySQL.... SUCCESS! 
Starting MySQL. SUCCESS!
  1. 查看主服務器狀態

#進入mysql數據庫
[root@localhost mysql]# mysql -uroot -p
Enter password:
 
#查看主服務器狀態
mysql> show master status;
+-------------------+----------+--------------+------------------+-------------------+
| File              | Position | Binlog_Do_DB | Binlog_Ignore_DB | Executed_Gtid_Set |
+-------------------+----------+--------------+------------------+-------------------+
| master-bin.000001 |      154 | test         |                  |                   |
+-------------------+----------+--------------+------------------+-------------------+
1 row in set (0.00 sec)

這些數據需要保存在從服務器上配置

slave從服務器的配置

  1. 配置文件my.cnf的修改
[root@localhost mysql]# vim /etc/my.cnf

#在[mysqld]中添加:
server-id=2
relay-log=slave-relay-bin
relay-log-index=slave-relay-bin.index
#replicate-do-db=test
#備註:
#server-id 服務器唯一標識,如果有多個從服務器,每個服務器的server-id不能重複,跟IP一樣是唯一標識,如果你沒設置server-id或者設置爲0,則從服務器不會連接到主服務器。
#relay-log 啓動MySQL二進制日誌,可以用來做數據備份和崩潰恢復,或主服務器掛掉了,將此從服務器作爲其他從服務器的主服務器。
#replicate-do-db 指定同步的數據庫,如果複製多個數據庫,重複設置這個選項即可。若在master端不指定binlog-do-db,則在slave端可用replication-do-db來過濾。
#replicate-ignore-db 不需要同步的數據庫,如果有多個數據庫,重複設置這個選項即可。
#其中需要注意的是,replicate-do-db和replicate-ignore-db爲互斥選項,一般只需要一個即可。

MySQL relay log 詳細參數解釋

https://blog.51cto.com/douya/1788753

2.重啓mysql服務

[root@localhost mysql]# service mysql restart
Shutting down MySQL.... SUCCESS! 
Starting MySQL. SUCCESS!
  1. 連接master主服務器

#進入mysql數據庫
[root@localhost mysql]# mysql -uroot -p
Enter password:
 
#連接master主服務器
mysql> change master to master_host='192.168.17.130',master_port=3306,master_user='masterbackup',master_password='123456',master_log_file='master-bin.000001',master_log_pos=154;
#備註:
#master_host對應主服務器的IP地址。
#master_port對應主服務器的端口。
#master_log_file對應show master status顯示的File列:master-bin.000001。
#master_log_pos對應show master status顯示的Position列:154。
  1. 啓動slave數據同步
#啓動slave數據同步
mysql> start slave;

#停止slave數據同步(若有需要)
mysql> stop slave;
  1. 查看slave信息
mysql> show slave status\G;

在這裏插入圖片描述
Slave_IO_Running和Slave_SQL_Running都爲yes,則表示同步成功。

主從服務器不同步解決方法

這裏有主從同步出現各種錯誤的詳細解決辦法和模擬實例說明

https://blog.51cto.com/13407306/2067333

以下介紹最簡單的兩種

  1. 在從數據庫中,使用SET全局sql_slave_skip_counter來跳過事件,跳過這一個錯誤,然後執行從下一個事件組開始。
#在從數據庫上操作
mysql > stop slave;
mysql > set global sql_slave_skip_counter=1;
mysql > start slave;
  1. 重新做主從,完全同步
1--master主庫上操作
mysql> flush tables with read lock;  //進行鎖表,防止數據寫入。注意該處是鎖定爲只讀狀態,語句不區分大小寫
#mysqldump --lock-all-tables --all-databases --flush-logs --master-data=2 > /root/allsql.sql   //主庫完全備份(如果是指定庫同步,就備份指定庫),注意數據庫備份一定要定期進行,確保數據萬無一失
mysql> show master status;      //查看master狀態,注意log file和pos節點,slave同步會用到
# scp mysql.bak.sql [email protected]:/tmp/   //把備份文件傳到slave從庫機器,進行數據恢復
#備註
#master_log_file和master_log_pos可能會不同,需要在主數據庫中show master status來查看

2--slave從庫操作
mysql> stop slave;
mysql> source /tmp/mysql.bak.sql
mysql> change master to master_host = '192.168.1.101', master_user = 'slave', master_port=3306.......;#配置和之前從庫配置一樣
mysql> start slave;
mysql> show slave status\G 
#結果yes成功
.......
Slave_IO_Running: Yes
Slave_SQL_Running: Yes
#解決完了把主庫解鎖
mysql> UNLOCK TABLES

總結

至此,mysql數據庫的主從同步就完成了,至於讀寫分離,我們可以通過程序來實現,這裏簡單講解一下實現思想。

我們可以在主服務器創建一個數據庫用戶(出於安全,根據需求給予相應的權限)主要用於寫操作,在程序中通過這一用戶連接主數據庫的只用於寫操作而不用讀操作。

在從服務器上創建一個數據庫用戶(出於安全,只給予讀select的權限)主要用於讀操作,在程序中通過這一用戶連接從數據庫即可。

當然,也可以找一個組件來完成MYSQL的代理,實現SQL語句的路由,這樣就不需要我們在程序上關注哪個數據庫是寫,哪個數據庫是讀的了。

轉載於: https://blog.csdn.net/qq_15092079/article/details/81672920

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章