mysql 主从 编码_Mysql 主从复制
MySQL Replication
主從復制(也稱 AB 復制)允許將來自一個MySQL數據庫服務器(主服務器)的數據復制到一個或多個MySQL數據庫服務器(從服務器)。
復制是異步的 從站不需要永久連接以接收來自主站的更新。
根據配置,您可以復制數據庫中的所有數據庫,所選數據庫甚至選定的表。
MySQL中復制的優點包括:
橫向擴展解決方案 - 在多個從站之間分配負載以提高性能。在此環境中,所有寫入和更新都必須在主服務器上進行。但是,讀取可以在一個或多個從設備上進行。該模型可以提高寫入性能(因為主設備專用于更新),同時顯著提高了越來越多的從設備的讀取速度。
數據安全性 - 因為數據被復制到從站,并且從站可以暫停復制過程,所以可以在從站上運行備份服務而不會破壞相應的主數據。
分析 - 可以在主服務器上創建實時數據,而信息分析可以在從服務器上進行,而不會影響主服務器的性能。
遠程數據分發 - 您可以使用復制為遠程站點創建數據的本地副本,而無需永久訪問主服務器。
Replication 的原理
少一張圖
前提是作為主服務器角色的數據庫服務器必須開啟二進制日志
主服務器上面的任何修改都會通過自己的 I/O tread(I/O 線程)保存在二進制日志 Binary log 里面。
從服務器上面也啟動一個 I/O thread,通過配置好的用戶名和密碼, 連接到主服務器上面請求讀取二進制日志,然后把讀取到的二進制日志寫到本地的一個Realy log(中繼日志)里面。
從服務器上面同時開啟一個 SQL thread 定時檢查 Realy log(這個文件也是二進制的),如果發現有更新立即把更新的內容在本機的數據庫上面執行一遍。
每個從服務器都會收到主服務器二進制日志的全部內容的副本。
從服務器設備負責決定應該執行二進制日志中的哪些語句。
除非另行指定,否則主從二進制日志中的所有事件都在從站上執行。
如果需要,您可以將從服務器配置為僅處理一些特定數據庫或表的事件。
重要: 您無法將主服務器配置為僅記錄特定事件。
每個從站(從服務器)都會記錄二進制日志坐標:
文件名
文件中它已經從主站讀取和處理的位置。
由于每個從服務器都分別記錄了自己當前處理二進制日志中的位置,因此可以斷開從服務器的連接,重新連接然后恢復繼續處理。
一主多從
如果一主多從的話,這時主庫既要負責寫又要負責為幾個從庫提供二進制日志。此時可以稍做調整,將二進制日志只給某一從,這一從再開啟二進制日志并將自己的二進制日志再發給其它從。或者是干脆這個從不記錄只負責將二進制日志轉發給其它從,這樣架構起來性能可能要好得多,而且數據之間的延時應該也稍微要好一些。工作原理圖如下:
少一張圖
關于二進制日志
mysqld將數字擴展名附加到二進制日志基本名稱以生成二進制日志文件名。每次服務器創建新日志文件時,該數字都會增加,從而創建一系列有序的文件。每次啟動或刷新日志時,服務器都會在系列中創建一個新文件。服務器還會在當前日志大小達到max_binlog_size參數設置的大小后自動創建新的二進制日志文件 。二進制日志文件可能會比max_binlog_size使用大型事務時更大, 因為事務是以一個部分寫入文件,而不是在文件之間分割。
為了跟蹤已使用的二進制日志文件, mysqld還創建了一個二進制日志索引文件,其中包含所有使用的二進制日志文件的名稱。默認情況下,它具有與二進制日志文件相同的基本名稱,并帶有擴展名'.index'。在mysqld運行時,您不應手動編輯此文件。
術語二進制日志文件通常表示包含數據庫事件的單個編號文件。
術語 二進制日志 表示含編號的二進制日志文件集加上索引文件。
SUPER 權限的用戶可以使用SET sql_log_bin=0語句禁用其當前環境下自己的語句的二進制日志記錄
配置 Replication
配置步驟:
1. 在主服務器上,您必須啟用二進制日志記錄并配置唯一的服務器ID。需要重啟服務器。
編輯主服務器的配置文件 my.cnf,添加如下內容
[mysqld]
log-bin=/var/log/mysql/mysql-bin
server-id=1
創建日志目錄并賦予權限
shell> mkdir /var/log/mysql
shell> chown mysql.mysql /var/log/mysql
重啟服務
shell> systemctl restart mysqld
注意:
如果省略server-id(或將其顯式設置為默認值0),則主服務器拒絕來自從服務器的任何連接。
為了在使用帶事務的InnoDB進行復制設置時盡可能提高持久性和一致性,
您應該在master my.cnf文件中使用以下配置項:
innodb_flush_log_at_trx_commit = 1
sync_binlog = 1
確保在主服務器上 skip_networking 選項處于 OFF 關閉狀態, 這是默認值。
如果是啟用的,則從站無法與主站通信,并且復制失敗。
mysql> show variables like '%skip_networking%';
+-----------------+-------+
| Variable_name | Value |
+-----------------+-------+
| skip_networking | OFF |
+-----------------+-------+
1 row in set (0.00 sec)
2. 應該創建一個專門用于復制數據的用戶
每個從服務器需要使用MySQL 主服務器上的用戶名和密碼連接到主站。
例如,計劃使用用戶 repl 可以從任何主機上連接到 master 上進行復制操作, 并且用戶 repl 僅可以使用復制的權限。
在 主服務器 上執行如下操作
mysql> CREATE USER 'repl'@'%'
mysql> GRANT REPLICATION SLAVE ON *.* TO 'repl'@'%' identified by
'QFedu123!';
mysql>
3. 在從服務器上使用剛才的用戶進行測試連接
shell> mysql -urepl -p'QFedu123!' -hmysql-master1
下面的操作根據如下情況繼續
主服務器中有數據
如果在啟動復制之前有現有數據需要與從屬設備同步,請保持客戶端正常運行,以便鎖定保持不變。這可以防止進行任何進一步的更改,以便復制到從站的數據與主站同步。
在主服務器中導出現有的數據
如果主數據庫包含現有數據,則必須將此數據復制到每個從站。有多種方法可以實現:
使用mysqldump工具創建要復制的所有數據庫的轉儲。這是推薦的方法,尤其是在使用時 InnoDB。
shell> mysqldump -u用戶名 -p密碼 --all-databases --master-data=1 > dbdump.db
這里的用戶是主服務器的用戶
如果不使用 --master-data 參數,則需要手動鎖定單獨會話中的所有表。
從主服務器中使用 scp 或 rsync 等工具,把備份出來的數據傳輸到從服務器中。
在主服務中執行如下命令
scp dbdump.db root@mysql-slave1:/root/
這里的 mysql-slave1 需要能被主服務器解析出 IP 地址,或者說可以在主服務器中 ping 通。
配置從服務器,并重啟
在從服務器 上編輯其配置文件 my.cnf 并添加如下內容:
// my.cnf 文件
[mysqld]
server-id=2
導入數據到從服務器,并配置連接到主服務器的相關信息
登錄到從服務器上,執行如下操作
/*導入數據*/
mysql> source /root/fulldb.dump
#在從服務器配置連接到主服務器的相關信息
mysql> CHANGE MASTER TO
MASTER_HOST='mysql-master1', -- 主服務器的主機名(也可以是 IP)
MASTER_USER='repl', -- 連接到主服務器的用戶
MASTER_PASSWORD='123'; == 到主服務器的密碼
啟動從服務器的復制線程mysql> start slave;
Query OK, 0 rows affected (0.09 sec)
檢查是否成功
在從服務上執行如下操作,加長從服務器端 IO線程和 SQL 線程是否是 OK
mysql> show slave status\G
輸出結果中應該看到 I/O 線程和 SQL 線程都是 YES, 就表示成功。
執行此過程后,在主服務上操作的修改數據的操作都會在從服務器中執行一遍,這樣就保證了數據的一致性。
將新的服務器加入,變為從服務器
和上面的步驟一樣,但是新加入的服務器的server-id 的值不能和現有都服務器 server-id 的值一樣。
假如在新加入從服務器之前,主服務器執行了刪除庫的操作。
并且,刪除的庫剛好是在第一次 mysqldump 備份時的數據中。
就會出現問題,在從服務器上提示報錯沒有這個數據庫;
主服務器中無數據
主服務器中設置
my.cnf配置文件
[mysqld]
log-bin=/var/log/mysql/mysql-bin
server-id=1
設置 log-bin 時必須同時設置 server-id
創建日志目錄并賦予權限
shell> mkdir /var/log/mysql
shell> chown mysql.mysql /var/log/mysql
重啟服務
從服務器設置
my.cnf配置文件
[mysqld]
server-id=3
重啟服務
查看主服務器的二進制日志的名稱
通過使用命令行客戶端連接到主服務器來啟動主服務器上的會話,并通過執行以下FLUSH TABLES WITH READ LOCK語句來刷新所有表和阻止寫語句:
mysql> FLUSH TABLES WITH READ LOCK;
mysql> show master status \G
****************** 1. row ****************
File: mysql-bin.000001
Position: 0
Binlog_Do_DB:
Binlog_Ignore_DB:
Executed_Gtid_Set:
1 row in set (0.00 sec)
在從服務器的 mysql 中執行如下語句mysql> CHANGE MASTER TO
MASTER_HOST='mysql-master1',
MASTER_USER='repl',
MASTER_PASSWORD='123',
MASTER_LOG_FILE='mysql-bin.000001',
MASTER_LOG_POS=0;
mysql> start slave;
查看
在master上執行show binlog events命令,可以看到第一個binlog文件的內容。
mysql> show binlog events\G
*************************** 1. row ***************************
Log_name: mysql-bin.000001
Pos: 4
Event_type: Format_desc
Server_id: 1
End_log_pos: 107
Info: Server ver: 5.5.28-0ubuntu0.12.10.2-log, Binlog ver: 4
*************************** 2. row ***************************
Log_name: mysql-bin.000001
Pos: 107
Event_type: Query
Server_id: 1
End_log_pos: 181
Info: create user rep
*************************** 3. row ***************************
Log_name: mysql-bin.000001
Pos: 181
Event_type: Query
Server_id: 1
End_log_pos: 316
Info: grant replication slave on *.* to rep identified by '123456'
3 rows in set (0.00 sec)
Log_name 是二進制日志文件的名稱,一個事件不能橫跨兩個文件
Pos 這是該事件在文件中的開始位置
Event_type 事件的類型,事件類型是給slave傳遞信息的基本方法,每個新的binlog都以Format_desc類型開始,以Rotate類型結束
Server_id 創建該事件的服務器id
End_log_pos 該事件的結束位置,也是下一個事件的開始位置,因此事件范圍為Pos~End_log_pos - 1
Info 事件信息的可讀文本,不同的事件有不同的信息
在從站上暫停復制
您可以使用STOP SLAVE和 START SLAVE語句停止并啟動從站上的復制 。
要停止從主服務器處理二進制日志,請使用 STOP SLAVE:
mysql> STOP SLAVE;
當復制停止時,從I / O線程停止從主二進制日志讀取事件并將它們寫入中繼日志,并且SQL線程停止從中繼日志讀取事件并執行它們。您可以通過指定線程類型單獨暫停I / O或SQL線程:
mysql> STOP SLAVE IO_THREAD;
mysql> STOP SLAVE SQL_THREAD;
要再次開始執行,請使用以下START SLAVE語句:
mysql> START SLAVE;
要啟動特定線程,請指定線程類型:
mysql> START SLAVE IO_THREAD;
mysql> START SLAVE SQL_THREAD;
復制原理實現細節
MySQL復制功能使用三個線程實現,一個在主服務器上,兩個在從服務器上:
Binlog轉儲線程 主設備創建一個線程,以便在從設備連接時將二進制日志內容發送到從設備。可以SHOW PROCESSLIST在主服務器的輸出中將此線程標識為Binlog Dump線程。
二進制日志轉儲線程獲取主機二進制日志上的鎖,用于讀取要發送到從機的每個事件。一旦讀取了事件,即使在事件發送到從站之前,鎖也會被釋放。
從屬 I/O線程 在從屬服務器上發出 START SLAVE 語句時,從屬服務器會創建一個 I/O 線程,該線程連接到主服務器并要求主服務器發送其在二進制日志中的更新記錄。
從屬 I/O線程讀取主Binlog Dump線程發送的更新 (請參閱上一項)并將它們復制到包含從屬中繼日志的本地文件。
此線程的狀態顯示為 Slave_IO_running輸出 SHOW SLAVE STATUS或 Slave_running輸出中的狀態SHOW STATUS。
從屬SQL線程 從屬設備創建一個SQL線程來讀取由從屬 I/O 線程寫入的中繼日志,并執行其中包含的事件。
當從屬服務器從放的事件,追干上主服務器的事件后,從屬服務器的 I/O 線程將會處于休眠狀態,直到主服務器的事件有更新時,被主服務器發送的信號喚醒。
在前面的描述中,每個主/從連接有三個線程。具有多個從站的主站為每個當前連接的從站創建一個二進制日志轉儲線程,每個從站都有自己的I / O和SQL線程。
從站使用兩個線程將讀取更新與主站分開并將它們執行到獨立任務中。因此,如果語句執行緩慢,則不會減慢讀取語句的任務。例如,如果從服務器尚未運行一段時間,則當從服務器啟動時,其I / O線程可以快速從主服務器獲取所有二進制日志內容,即使SQL線程遠遠落后。如果從服務器在SQL線程執行了所有獲取的語句之前停止,則I / O線程至少已獲取所有內容,以便語句的安全副本本地存儲在從屬的中繼日志中,準備在下次執行時執行奴隸開始。
該SHOW PROCESSLIST語句提供的信息可以告訴您主服務器和從服務器上有關復制的信息。有關主狀態的信息,請參見第8.14.4節“復制主線程狀態”。有關從站狀態,請參見第8.14.5節“復制從站I / O線程狀態”和 第8.14.6節“復制從站SQL線程狀態”。
以下示例說明了三個線程如何顯示在輸出中SHOW PROCESSLIST。
在主服務器上,輸出SHOW PROCESSLIST如下所示:
mysql> SHOW PROCESSLIST\G
*************************** 1\. row ***************************
Id: 2
User: root
Host: localhost:32931
db: NULL
Command: Binlog Dump
Time: 94
State: Has sent all binlog to slave; waiting for binlog to
be updated
Info: NULL
這里,線程2是Binlog Dump為連接的從屬服務的復制線程。該 State信息表明所有未完成的更新已發送到從站,并且主站正在等待更多更新發生。如果Binlog Dump在主服務器上看不到任何 線程,則表示復制未運行; 也就是說,目前沒有連接任何從站。
在從屬服務器上,輸出SHOW PROCESSLIST如下所示:
mysql> SHOW PROCESSLIST\G
*************************** 1\. row ***************************
Id: 10
User: system user
Host:
db: NULL
Command: Connect
Time: 11
State: Waiting for master to send event
Info: NULL
*************************** 2\. row ***************************
Id: 11
User: system user
Host:
db: NULL
Command: Connect
Time: 11
State: Has read all relay log; waiting for the slave I/O
thread to update it
Info: NULL
該State信息指示線程10是與主服務器通信的I / O線程,并且線程11是處理存儲在中繼日志中的更新的SQL線程。在 SHOW PROCESSLIST運行時,兩個線程都處于空閑狀態,等待進一步更新。
Time列中 的值可以顯示從站與主站進行比較的時間。請參見 第A.13節“MySQL 5.7 FAQ:復制”。如果主站側有足夠的時間在Binlog Dump線程上沒有活動,則主站確定從站不再連接。對于任何其他客戶端連接,這樣做的超時取決于的值 net_write_timeout和 net_retry_count; 有關這些的更多信息,請參見第5.1.7節“服務器系統變量”。
該SHOW SLAVE STATUS 語句提供有關從屬服務器上的復制處理的其他信息。請參見 第16.1.7.1節“檢查復制狀態”。
...省略 更多在原文查看
總結
以上是生活随笔為你收集整理的mysql 主从 编码_Mysql 主从复制的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 我想办理透支卡怎么办
- 下一篇: mysql+不锁表添加字段_MySQL5