MySQL的主從複製是其自帶的功能,經過邏輯的binlog日誌複製到要同步的服務器本地,主服務器(Master),接收來自用戶的內容更新,而一個或多個其餘的服務器充當從服務器(Slave),接收來自主服務器binlog文件的日誌內容,解析出SQL,從新更新到從服務器,使得主從服務器數據達到一致。前端
MySQL主從複製都是異步的複製方式,既不是嚴格實時的數據同步,可是正常狀況下給用戶的體驗是真實的。mysql
1在slave服務器上執行start slave命令開始主從複製
2.此時slave服務器的io線程會請求連接主服務器,並從指定的binlog文件位置以後開始獲取日誌內容
3.master服務器接收到slave服務器io線程的請求後,負責複製的io線程會根據收到的信息讀取日誌文件指定位置以後的日誌內容,而後返回給slave端的io線程,
返回信息除了日誌內容外,還有新的binlog文件以及新的指定的位置
4.當slave服務器io線程收到master服務器上的日誌文件內容以及新的日誌文件名和新的位置後,會把日誌內容寫到slave服務器端自身的relay log(中繼日誌)的最末端,
並將新的日誌文件名和位置記錄到master-info文件中,以便下次讀取
5.slave服務器的sql線程會實時監測本地的relay log的內容,而後及時把relay log的內容解析成sql語句,按順序依次執行這些sql語句,
並在relay log info中記錄中繼日誌的文件名與位置sql
此處應用爲 一臺電腦 多實例mysql 主從複製 和單實例多服務器主從複製原理同樣數據庫
設置server-id值並開啓binlog功能參數vim
vim my.cnf #修改主庫的配置文件 [mysqld] #參數要放在my.cnf中的[mysqld]模塊下,不然會出錯。 server-id = 1 #用於同步的每臺機器或實例server-id都不能相同 log-bin = /data/3306/mysql-bin #binlog日誌的位置
檢查配置參數後的結果緩存
egrep "server-id|log-bin" /data/3306/my.cnf log-bin = /data/3306/mysql-bin server-id = 1
重啓主庫MySQL服務服務器
/data/3306/mysql restart
登錄數據庫,檢查參數的更改狀況網絡
mysql -uroot -p123456 -S /data/3306/mysql.sock show variables like 'server_id'; #查看MySQL的系統變量(like相似於grep過濾) +---------------+-------+ | Variable_name | Value | +---------------+-------+ | server_id | 1 | #配置的server_id爲1 +---------------+-------+ 1 row in set (0.00 sec) show variables like 'log_bin'; +---------------+-------+ | Variable_name | Value | +---------------+-------+ | log_bin | ON | #binlog功能已開啓 +---------------+-------+ 1 row in set (0.00 sec)
創建用於從庫複製的帳號多線程
grant replication slave on *.* to 'wk'@'192.168.50.%' identified by '123456';
#replication slave爲mysql同步的必須權限,此處不要受權all權限
flush privileges; #建立完帳號並受權後,須要刷新權限,使受權的權限生效
檢查主庫建立的wk複製帳號命令及結果以下:架構
select user,host from mysql.user; +------+--------------+ | user | host | +------+--------------+ | root | 127.0.0.1 | | wk | 192.168.50.% | | root | ::1 | | | localhost | | root | localhost | | root | www | +------+--------------+
show grants for wk@'192.168.50.%'; #查看受權情況 +--------------------------------------------------------------------------------------------------------------------------+ | Grants for wk@192.168.50.% | +--------------------------------------------------------------------------------------------------------------------------+ | GRANT REPLICATION SLAVE ON *.* TO 'wk'@'192.168.50.%' IDENTIFIED BY PASSWORD '*6BB4837EB74329105EE4568DDA7DC67ED2CA2AD9' | +--------------------------------------------------------------------------------------------------------------------------+
#結果顯示受權正確
鎖表徹底備份主庫 (對於快速配置主從複製 不須要鎖表)
對主數據庫鎖表只讀(當前窗口不要關掉)的命令以下:
flush table with read lock; Query OK, 0 rows affected (0.00 sec)
在引擎不一樣的狀況下,這個鎖表命令的時間會受下面參數的控制。鎖表時,若是超過設置時間不操做會自動解鎖。
默認狀況下自動解鎖的時長參數值以下:
show variables like '%timeout%'; +----------------------------+----------+ | Variable_name | Value | +----------------------------+----------+ | connect_timeout | 10 | | delayed_insert_timeout | 300 | | innodb_lock_wait_timeout | 120 | | innodb_rollback_on_timeout | OFF | | interactive_timeout | 28800 | #自動解鎖時間受本參數影響 | lock_wait_timeout | 31536000 | | net_read_timeout | 30 | | net_write_timeout | 60 | | slave_net_timeout | 3600 | | wait_timeout | 28800 | #自動解鎖時間受本參數影響 +----------------------------+----------+
鎖表後查看主庫狀態
show master status; #根據Position偏移量 肯定是否在鎖表後的主從複製時 內容有所變更 +------------------+----------+--------------+------------------+ | File | Position | Binlog_Do_DB | Binlog_Ignore_DB | +------------------+----------+--------------+------------------+ | mysql-bin.000001 | 1193 | | | +------------------+----------+--------------+------------------+
鎖表後,必定要單開一個新的SSH窗口,導出數據庫的全部數據,若是數據量很大(50GB以上),而且容許停機,能夠停庫直接打包數據文件進行遷移,那樣更快。
分之一 快速主從複製 不須要上述鎖表mysql -uroot -p123456 -S /data/3306/mysql.sock -e "show master status"
mysqldump -uroot -p123456 -S /data/3306/mysql.sock --events -x --master-data=1 -A -B | gzip >/server/backup/mysql_bak.$(date +%F).sql.gz #-A表示備份全部庫;-B表示增長use DB和 drop 等(導庫時會直接覆蓋原有的) --master-data=1 直接記錄日誌文件名和偏移量 不須要在change master
裏寫入日誌文件名和偏移量 -x 導出時鎖表
分支二
mysqldump -uroot -p123123 -S /data/3306/mysql.sock --events -A -B | gzip >/server/backup/mysql_bak.$(date +%F).sql.gz
#此種配置須要上述鎖表同時還須要在change master裏寫入日誌文件名和偏移量
#爲了確保導出數據期間,數據庫沒有數據插入,導庫完畢能夠再次檢查主庫狀態信息,結果以下:
設置server-id值並關閉binlog功能參數
vi my.cnf [mysqld] server-id = 2 #調整等號後的數值,和任何一個數據庫實例都不一樣 egrep "server-id|log-bin" /data/3307/my.cnf #檢查配置參數後的結果 server-id = 2
重啓從數據庫
/data/3307/mysql restart
cd /server/backup/ gzip -d mysql_bak.2018-08-06.sql.gz mysql -uroot -S /data/3307/mysql.sock <mysql_bak.2018-08-06.sql #這是把數據還原到3307實例的命令
MySQL從庫鏈接主庫的配置信息以下:
分之一 快速配置 CHANGE MASTER TO MASTER_HOST='192.168.50.149', #這裏是主庫的IP MASTER_PORT=3306, #這裏是主庫的端口,從庫端口能夠和主庫不一樣 MASTER_USER='wk', #這裏是主庫上創建的用於複製的用戶wk MASTER_PASSWORD='123456'; #這裏是wk用戶的密碼 #因爲--master-data=1記錄了日誌文件名和偏移量因此此處不設置MASTER_LOG_FILE和MASTER_LOG_POS 分之二 CHANGE MASTER TO MASTER_HOST='192.168.50.149', #這裏是主庫的IP MASTER_PORT=3306, #這裏是主庫的端口,從庫端口能夠和主庫不一樣 MASTER_USER='wk', #這裏是主庫上創建的用於複製的用戶wk MASTER_PASSWORD='123456', #這裏是wk用戶的密碼 MASTER_LOG_FILE='mysql-bin.000001', #這裏是show master status時查看到的二進制日誌文件名稱,注意不能多空格 MASTER_LOG_POS=533; #這裏是show master status時查看到的二進制日誌偏移量,注意不能多空格
上述操做的原理其實是把用戶密碼等信息寫入從庫新的master.info文件中cat /data/3307/data/master.info
分之一 cat /data/3307/data/master.info 18 4 192.168.50.149 wk 123456 3306 60 0 分之二 cat /data/3307/data/master.info 18 mysql-bin.000001 1193 192.168.50.149 wk 123456 3306 60 0
啓動從庫同步開關,測試主從複製配置狀況
mysql -uroot -S /data/3307/mysql.sock -e "start slave" mysql -uroot -S /data/3308/mysql.sock -e "show slave status\G"
主從同步是否成功,最關鍵的爲下面的3項狀態參數:
此時主從複製配置成功
分之一和分之二的區別在於導出主備文件
在企業中增長從庫 只須要深夜掛定時任務執行
mysqldump -uroot -p123456 -S /data/3306/mysql.sock --events -x --master-data=1 -A -B | gzip >/server/backup/mysql_bak.$(date +%F).sql.gz
次日把該文件移植到從庫 開啓主從複製功能便可
登錄主數據庫查看MySQL線程的同步狀態
show processlist\G
#紅色內容表示上述狀態的意思是線程已經從binlog日誌讀取全部更新,並已經發送到了從數據庫服務器。線程目前爲空閒狀態,等待由主服務器上二進制日誌中的新事件更新 *************************** 1. row *************************** #從庫1IO線程 Id: 5 User: wk Host: 192.168.50.149:51932 db: NULL Command: Binlog Dump Time: 4480 State: Master has sent all binlog to slave; waiting for binlog to be updated Info: NULL *************************** 2. row *************************** #從庫2IO線程 Id: 15 User: wk Host: 192.168.50.149:51933 db: NULL Command: Binlog Dump Time: 557 State: Master has sent all binlog to slave; waiting for binlog to be updated Info: NULL *************************** 3. row *************************** Id: 17 User: root Host: localhost db: NULL Command: Query Time: 0 State: NULL Info: show processlist 3 rows in set (0.00 sec)
下圖中列出了主服務器binlog Dump線程中State列的最多見狀態。若是你沒有在主服務器上看見任何binlog Dump線程,則說明覆制沒有運行,二進制binlog日誌由各類事件組成,事件一般會爲更新添加信息。
登錄從數據庫查看MySQL線程工做狀態
show processlist\G
紅1表示線程已鏈接到服務器,等待二進制日誌到達
紅2表示已處理完全部日誌等待新日誌到來 *************************** 1. row *************************** #IO線程 Id: 5 User: system user Host: db: NULL Command: Connect Time: 621 State: Waiting for master to send event Info: NULL *************************** 2. row *************************** #SQL線程 Id: 6 User: system user Host: db: NULL Command: Connect Time: 385 State: Slave has read all relay log; waiting for the slave I/O thread to update it Info: NULL *************************** 3. row *************************** Id: 9 User: root Host: localhost db: NULL Command: Query Time: 0 State: NULL Info: show processlist 3 rows in set (0.00 sec)
複製故障
Slave_IO_Running: Yes
Slave_SQL_Running: No 表示複製故障
Master_Server_Id: 1 主從同步狀態:關閉
stop slave; #關閉主從同步 Query OK, 0 rows affected, 1 warning (0.00 sec)
set global sql_slave_skip_counter=1; #將sql線程同步指針向下移動一個,若是屢次不一樣步,能夠重複操做 Query OK, 0 rows affected (0.00 sec)
start slave; #開啓主從同步 Query OK, 0 rows affected (0.00 sec)
解決方法2
根據能夠忽略的錯誤號事先在配置文件中配置,跳過指定的不影響業務數據的錯誤,例如:
vim my.cnf
[mysqld] slave-skip-errors = 1032,1062,1007
若是從庫下邊還有從庫須要開啓從庫1的binlog功能
[mysqld]
log-slave-updates #必需要有這個參數 log-bin = /data/3307/mysql-bin expire_logs_days = 7 #至關於find /data/3307/ -type f -name "mysql-bin.000*" -mtime +7 | xargs rm -f 刪除7天以上的日誌文件
問題一:主庫的從庫太多,致使複製延遲
從庫數量以3~5個爲宜,要複製的從節點數量過多,會致使複製延遲。
問題二:從庫硬件比主庫差,致使複製延遲。
查看Master和Slave的系統配置,可能會由於機器配置不當,包括磁盤I/O,CPU,內存等各方面因素形成複製的延遲。這通常發生在高併發大數據量寫入場景中。
問題三:慢SQL語句太多
假如一條SQL語句執行時間是20秒,那麼從執行完畢到從庫上能查到數據至少須要20秒,這樣就延遲20秒了。
通常要把SQL語句的優化做爲常規工做,不斷的進行監控和優化,若是單個SQL的寫入時間長,能夠修改後分屢次寫入。經過查看慢查詢日誌或show full processlist命令,找出執行時間長的查詢語句或大的事務。
問題四:主從複製的設計問題
例如,主從複製單線程,若是主庫寫併發太大,來不及傳送到從庫,就會致使延遲。
更高版本的MySQL能夠支持多線程複製,門戶網站則會本身開發多線程同步功能。
問題五:主從庫之間的網絡延遲
主從庫的網卡,網線,鏈接的交換機等網絡設備均可能成爲複製的瓶頸,致使複製延遲,另外,跨公網主從複製很容易致使主從複製延遲。
問題六:主庫讀寫壓力大,致使複製延遲。
主庫硬件要搞好一點,架構的前端要加buffer及緩存層。
read-only參數選項可讓從服務器只容許來自從服務器線程或具備SUPER權限的數據庫用戶進行更新,確保從服務器不接受來自用戶端的非法用戶更新。
read-only參數容許數據庫更新的條件爲:
在my.cnf裏[mysqld]模塊下加read-only參數重啓數據庫,配置以下:
[mysqld]
read-only
生產環境中通常會採起忽略受權表方式的同步, 而後對從服務器(slave)上的用戶僅受權select 讀權限。不一樣步mysql庫,這樣咱們就保證主庫和從庫相同的用戶能夠受權不一樣的權限。。
忽略mysql庫和information_ schema 庫的主從同步。
[mysqld]
replicate- ignore -db=mysql4 binlog-do-db = testdh. binlog- ignore-db = mysql↔ binlog-ignore-db = per formance_ schemar binlog-ignore-db = informat ion_ schemat 提示:忽略記錄binlog日誌的參數binlog-ignore-db通常用於系統的庫和表。。