目錄:html
mysql主從同步定義mysql
主從同步機制linux
配置主從同步sql
配置主服務器shell
配置從服務器數據庫
使用主從同步來備份安全
使用mysqldump來備份服務器
備份原始文件網絡
主從同步的小技巧異步
排錯
Slave_IO_Running: NO
Slave_SQL_Running: No
mysql主從同步定義
主從同步使得數據能夠從一個數據庫服務器複製到其餘服務器上,在複製數據時,一個服務器充當主服務器(master),其他的服務器充當從服務器(slave)。由於複製是異步進行的,因此從服務器不須要一直鏈接着主服務器,從服務器甚至能夠經過撥號斷斷續續地鏈接主服務器。經過配置文件,能夠指定複製全部的數據庫,某個數據庫,甚至是某個數據庫上的某個表。
使用主從同步的好處:
- 經過增長從服務器來提升數據庫的性能,在主服務器上執行寫入和更新,在從服務器上向外提供讀功能,能夠動態地調整從服務器的數量,從而調整整個數據庫的性能。
- 提升數據安全-由於數據已複製到從服務器,從服務器能夠終止複製進程,因此,能夠在從服務器上備份而不破壞主服務器相應數據
- 在主服務器上生成實時數據,而在從服務器上分析這些數據,從而提升主服務器的性能
注意,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會有以下
長處:
- 日誌文件更小
- 記錄了全部的語句,能夠用來往後審計
弊端:
- 使用以下函數的語句不能被正確地複製: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();
- 在日誌中出現以下警告信息的不能正確地複製:[Warning] Statement is not safe to log in statement format.
- 或者在客戶端中出現show warnings
- Insert … select語句會執行大量的行級鎖表
- Update語句會執行大量的行級鎖表來掃描整個表
2.RBR:主服務器把表的行變化做爲事件寫入到二進制日誌中,主服務器把表明了行變化的事件複製到從服務中,使用RBR的
長處:
- 全部的數據變化都是被複制,這是最安全的複製方式
- 更少的行級鎖表
弊端:
- 日誌會很大
- 不能經過查看日誌來審計執行過的sql語句,不過能夠經過使用mysqlbinlog
- --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;
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',
如圖所示:
啓動主從同步進程
mysql > start slave;
檢查狀態
mysql > show slave status \G
上面的兩個進程都顯示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
這是一個很常見的錯誤(我也曾對這個錯誤咬牙切齒),總結起來就三個緣由:
- 主服務器的網絡不通,或者主服務器的防火牆拒絕了外部鏈接3306端口
- 在配置從服務器時,輸錯了ip地址和密碼,或者主服務器在建立用戶時寫錯了用戶名和密碼
- 在配置從服務器時,輸錯了主服務器的二進制日誌信息
排錯過程:(主服務器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;
上圖就是個人錯誤根源,能夠看到用戶名徹底寫錯了,先刪除錯誤的用戶:
mysql > drop user 「rep@192.168.1.%」@」%」;
再從新建立用戶:
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