Mysql主從同步(複製)

原文鏈接:https://www.cnblogs.com/kylinlin/p/5258719.html

目錄:

mysql主從同步定義

     主從同步機制

配置主從同步

     配置主服務器

     配置從服務器

使用主從同步來備份

     使用mysqldump來備份

     備份原始文件

主從同步的小技巧

排錯

     Slave_IO_Running: NO

     Slave_SQL_Running: No

 

mysql主從同步定義

主從同步使得數據可以從一個數據庫服務器複製到其他服務器上,在複製數據時,一個服務器充當主服務器(master),其餘的服務器充當從服務器(slave)。因爲複製是異步進行的,所以從服務器不需要一直連接着主服務器,從服務器甚至可以通過撥號斷斷續續地連接主服務器。通過配置文件,可以指定複製所有的數據庫,某個數據庫,甚至是某個數據庫上的某個表。

使用主從同步的好處:

  1. 通過增加從服務器來提高數據庫的性能,在主服務器上執行寫入和更新,在從服務器上向外提供讀功能,可以動態地調整從服務器的數量,從而調整整個數據庫的性能。
  2. 提高數據安全-因爲數據已複製到從服務器,從服務器可以終止複製進程,所以,可以在從服務器上備份而不破壞主服務器相應數據
  3. 在主服務器上生成實時數據,而在從服務器上分析這些數據,從而提高主服務器的性能

注意,mysql是異步複製的,而MySQL Cluster是同步複製的。有很多種主從同步的方法,但核心的方法有兩種,Statement Based Replication(SBR)基於SQL語句的複製,另一種是Row Based Replication(RBR)基於行的複製,也可以使用Mixed Based Replication(MBR)。在mysql5.6中,默認使用的是SBR。而mysql 5.6.5和往後的版本是基於global transaction identifiers(GTIDs)來進行事務複製。當使用GTIDs時可以大大簡化複製過程,因爲GTIDs完全基於事務,只要在主服務器上提交了事務,那麼從服務器就一定會執行該事務。

通過設置服務器的系統變量binlog_format來指定要使用的格式:

1.SBR:當使用二進制日誌時,主服務器會把SQL語句寫入到日誌中,然後從服務器會執行該日誌,這就是SBR,在mysql5.1.4之前的版本都只能使用這種格式。使用SBR會有如下

長處:

  1. 日誌文件更小
  2. 記錄了所有的語句,可以用來日後審計

弊端:

  1. 使用如下函數的語句不能被正確地複製:load_file(); uuid(), uuid_short(); user(); found_rows(); sysdate(); get_lock(); is_free_lock(); is_used_lock(); master_pos_wait(); rand(); release_lock(); sleep(); version();
  2. 在日誌中出現如下警告信息的不能正確地複製:[Warning] Statement is not safe to log in statement format.
  3. 或者在客戶端中出現show warnings
  4. Insert … select語句會執行大量的行級鎖表
  5. Update語句會執行大量的行級鎖表來掃描整個表

2.RBR:主服務器把表的行變化作爲事件寫入到二進制日誌中,主服務器把代表了行變化的事件複製到從服務中,使用RBR的

長處:

  1. 所有的數據變化都是被複制,這是最安全的複製方式
  2. 更少的行級鎖表

弊端:

  1. 日誌會很大
  2. 不能通過查看日誌來審計執行過的sql語句,不過可以通過使用mysqlbinlog  
  3. --base64-output=decode-rows --verbose來查看數據的 變動

3.MBR:既使用SBR也使用RBR,默認使用SBR

 

主從同步機制

Mysql服務器之間的主從同步是基於二進制日誌機制,主服務器使用二進制日誌來記錄數據庫的變動情況,從服務器通過讀取和執行該日誌文件來保持和主服務器的數據一致。

在使用二進制日誌時,主服務器的所有操作都會被記錄下來,然後從服務器會接收到該日誌的一個副本。從服務器可以指定執行該日誌中的哪一類事件(譬如只插入數據或者只更新數據),默認會執行日誌中的所有語句。

每一個從服務器會記錄關於二進制日誌的信息:文件名和已經處理過的語句,這樣意味着不同的從服務器可以分別執行同一個二進制日誌的不同部分,並且從服務器可以隨時連接或者中斷和服務器的連接。

主服務器和每一個從服務器都必須配置一個唯一的ID號(在my.cnf文件的[mysqld]模塊下有一個server-id配置項),另外,每一個從服務器還需要通過CHANGE MASTER TO語句來配置它要連接的主服務器的ip地址,日誌文件名稱和該日誌裏面的位置(這些信息存儲在主服務器的數據庫裏)

 

配置主從同步

有很多種配置主從同步的方法,可以總結爲如下的步驟:

1.在主服務器上,必須開啓二進制日誌機制和配置一個獨立的ID

2.在每一個從服務器上,配置一個唯一的ID,創建一個用來專門複製主服務器數據的賬號

3.在開始複製進程前,在主服務器上記錄二進制文件的位置信息

4.如果在開始複製之前,數據庫中已經有數據,就必須先創建一個數據快照(可以使用mysqldump導出數據庫,或者直接複製數據文件)

5.配置從服務器要連接的主服務器的IP地址和登陸授權,二進制日誌文件名和位置

配置主服務器

1.更改配置文件,首先檢查你的主服務器上的my.cnf文件中是否已經在[mysqld]模塊下配置了log-bin和server-id

[mysqld]

log-bin=mysql-bin

server-id=1

注意上面的log-bin和server-id的值都是可以改爲其他值的,如果沒有上面的配置,首先關閉mysql服務器,然後添加上去,接着重啓服務器

2.創建用戶,每一個從服務器都需要用到一個賬戶名和密碼來連接主服務器,可以爲每一個從服務器都創建一個賬戶,也可以讓全部服務器使用同一個賬戶。下面就爲同一個ip網段的所有從服務器創建一個只能進行主從同步的賬戶。

首先登陸mysql,然後創建一個用戶名爲rep,密碼爲123456的賬戶,該賬戶可以被192.168.253網段下的所有ip地址使用,且該賬戶只能進行主從同步

mysql > grant replication slave on *.* to ‘rep’@‘192.168.253.%’ identified by ‘123456’;

3.獲取二進制日誌的信息並導出數據庫,步驟:

首先登陸數據庫,然後刷新所有的表,同時給數據庫加上一把鎖,阻止對數據庫進行任何的寫操作

mysql > flush tables with read lock;

然後執行下面的語句獲取二進制日誌的信息

mysql > show master status;

圖片1

File的值是當前使用的二進制日誌的文件名,Position是該日誌裏面的位置信息(不需要糾結這個究竟代表什麼),記住這兩個值,會在下面配置從服務器時用到。

注意:如果之前的服務器並沒有配置使用二進制日誌,那麼使用上面的sql語句會顯示空,在鎖表之後,再導出數據庫裏的數據(如果數據庫裏沒有數據,可以忽略這一步)

[root@localhost backup]# mysqldump -uroot -p'123456' -S /data/3306/data/mysql.sock --all-databases > /server/backup/mysql_bak.$(date +%F).sql

如果數據量很大,可以在導出時就壓縮爲原來的大概三分之一

[root@localhost backup]# mysqldump -uroot -p'123456' -S /data/3306/data/mysql.sock --all-databases | gzip > /server/backup/mysql_bak.$(date +%F).sql.gz

這時可以對數據庫解鎖,恢復對主數據庫的操作

mysql > unlock tables;

 

配置從服務器

首先檢查從服務器上的my.cnf文件中是否已經在[mysqld]模塊下配置leserver-id

[mysqld]

server-id=2

注意上面的server-id的值都是可以改爲其他值的(建議更改爲ip地址的最後一個字段),如果沒有上面的配置,首先關閉mysql服務器,然後添加上去,接着重啓服務器

如果有多個從服務器上,那麼每個服務器上配置的server-id都必須不一致。從服務器上沒必要配置log-bin,當然也可以配置log-bin選項,因爲可以在從服務器上進行數據備份和災難恢復,或者某一天讓這個從服務器變成一個主服務器

如果主服務器導出了數據,下面就導入該文件,如果主服務器沒有數據,就忽略這一步

[root@localhost ~]# mysql -uroot -p'123456' -S /data/3306/data/mysql.sock < /server/backup/mysql_bak.2015-07-01.sql

如果從主服務器上拿過來的是壓縮文件,就先解壓再導入

配置同步參數,登陸mysql,輸入如下信息:

複製代碼

mysql> CHANGE MASTER TO

-> MASTER_HOST='master_host_name',

-> MASTER_USER='replication_user_name',

-> MASTER_PASSWORD='replication_password',

-> MASTER_LOG_FILE='recorded_log_file_name',

複製代碼

如圖所示:

圖片2

 

啓動主從同步進程

mysql > start slave;

檢查狀態

mysql > show slave status \G

圖片3

上面的兩個進程都顯示YES則表示配置成功

 

使用主從同步來備份

把主服務器的數據複製到從服務器上,然後備份從服務器的數據,在數據量不是很大的時候使用mysqldump命令,對於很大的數據庫,就直接備份數據文件。

使用mysqldump來備份

步驟:(以下的所有操作都在從服務器上進行)

1.首先暫停從服務器的複製進程

shell > mysqladmin stop-slave

或者只是暫停SQL進程(從服務器仍然能接收二進制日誌的事件,但不會執行這些事件,這樣能在重啓SQL進程時加快複製進度)

shell > mysql -e ‘stop slave sql_thread;’

2.使用mysqldump導出全部或部分的數據庫

shell > mysqldump --all-databases > fulldb.dump

3.在導出數據庫後,重啓複製進程

shell > mysqladmin start-slave

 

備份原始文件

爲了保證數據文件的完整性,在備份之前首先關閉從服務器,步驟:

1.關閉從服務器:

shell > mysqladmin shutdown

2.複製數據文件,可以使用壓縮命令,假如當前目錄就是數據庫的數據目錄(在my.cnf文件中的配置項datadir的值就是該目錄的位置)

shell > tar cf /tmp/dbbackup.tar ./data

3.然後再啓動mysql服務器

 

主從同步的小技巧

主服務器第一次導入數據,如果你從其他地方拿來了要導入到主服務器中的數據,此時只要在主服務器中導入一次即可,因爲這些數據會自動發送到從服務器中,在主服務器上使用命令

shell > mysql -h master < other_data.sql

增加從服務器,本來已經至少有一個從服務器時(暫時命名爲slave1),決定再添加其餘的從服務器(slave2),此時就不需要像上面那樣去操作主服務器,只要複製一個已經存在的從服務器就可以了

 

排錯

Slave_IO_Running: NO

這是一個很常見的錯誤(我也曾對這個錯誤咬牙切齒),總結起來就三個原因:

  1. 主服務器的網絡不通,或者主服務器的防火牆拒絕了外部連接3306端口
  2. 在配置從服務器時,輸錯了ip地址和密碼,或者主服務器在創建用戶時寫錯了用戶名和密碼
  3. 在配置從服務器時,輸錯了主服務器的二進制日誌信息

排錯過程:(主服務器ip:192.168.1.139,從服務器ip:192.168.1.204)

第0步就是檢查錯誤日誌,如果不能快速排錯,可以按我的步驟試試:

1.首先在從服務器上執行ping程序,確定能ping通主服務器

在從服務器上執行mysq的遠程連接

[root@slave204 log]# mysql -urep -p -h 192.168.1.139 -P3306

如果顯示ERROR 1045 (28000): Access denied for user 'test'@'192.168.1.204' (using password: YES)則跳轉到第3

2.登陸主服務器的mysql,查看所有的用戶

mysql > select user,host from mysql.user;

圖片4

上圖就是我的錯誤根源,可以看到用戶名完全寫錯了,先刪除錯誤的用戶:

mysql > drop user “[email protected].%”@”%”;

再重新創建用戶:

mysql > grant replication slave on *.* to ‘rep’@‘192.168.1.%’ identified by ‘123456’;

mysql > flush privileges;

3.假如用戶名沒有錯,那麼如何排除是否是輸入的密碼錯誤呢?

額,我也想知道方法。最好就是多輸入幾遍,或者重新創建用戶名和密碼來測試。問題還沒有解決,轉到4

4.在你的防火牆中添加3306端口

[root@localhost mysql]# firewall-cmd --zone=public --add-port=3306/tcp --permanent

[root@localhost mysql]# firewall-cmd --reload

再關閉selinux

[root@slave204 log]# vi /etc/sysconfig/selinux

把SELINUX=enforcing改爲SELINUX=disabled

[root@slave204 log]# source /etc/sysconfig/selinux

登錄主服務器,查看服務器狀態

mysql > show master status \G

然後重新配置一次從服務器,在配置之前首先關閉主從同步進程

mysql > stop slave;

之外的方法,我也沒試過

 

Slave_SQL_Running: No

把上面的Slave_IO_Running調試成YES後,就輪到這個小樣了。我根據這個博客的內容來解決的:http://kerry.blog.51cto.com/172631/277414

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