個人網(wǎng)站首頁怎么做合肥推廣外包公司
復(fù)制
改變主庫
確定期望的日志位置
如果有備庫和新主庫的位置不相同,則需要找到該備庫最后一條執(zhí)行的時間在新主庫的二進制日志中相應(yīng)的位置,然后再執(zhí)行CHANGE MASTER TO.可以通過mysqlbinlog工具來找到備庫執(zhí)行的最后一條查詢,然后在主庫上找到同樣的查詢,進行簡單的計算即可得到。
為了便于描述,假設(shè)每個日志時間有一個自增的數(shù)字ID,最新的備庫,也就是新主庫,在舊主庫崩潰時獲得了編號為100的事件,假設(shè)有另外兩臺備庫:replica2和replica3。replica2已經(jīng)獲取了99號事件,replica3獲取了98號事件。如果把兩臺備庫都指向新主庫的同一個二進制日志位置,它們將從101號事件開始復(fù)制,從而導(dǎo)致數(shù)據(jù)不同步。但只要新主庫的二進制日志已經(jīng)通過log_slave_updates打開,就可以在新主庫的二進制日志中找到99號和100號日志,從而將備庫恢復(fù)到一致的狀態(tài)。由于服務(wù)器重啟,不同的配置,日志輪轉(zhuǎn)或者FLUSH LOGS命令,同一個事件在不同的服務(wù)器上可能有不同的偏移量。找到這些事件可能會耗時很長并且枯燥,但是通常沒有難度。通過mysqlbinlog從二進制日志或中繼日志中解析出每臺備庫上執(zhí)行的最后一個事件,并同樣使用該命令解析新主庫上的二進制日志,找到相同的查詢,mysqlbinlog會打印出該事件的偏移量,在CHANGE MASTER TO命令中使用這個值。(pt-heartbeat的心跳記錄能夠很好地幫助你好到正在查找的事件的大約位置)
更快的方法是把新主庫和停止的備庫上的字節(jié)偏移量相減,它顯示了字節(jié)位置的差異。然后把這個值和新主庫當(dāng)前二進制日志的位置相減,就可以得到期望的查詢的位置。只需要驗證一下就可以據(jù)此啟動備庫。
假設(shè)server1是server2和server3的主庫,其中服務(wù)器server1已經(jīng)崩潰。根據(jù)SHOW SLAVE STATUS獲得Master_Log_File/Read_Master_Log_Pos的值,server2已經(jīng)執(zhí)行完了server1上所有的二進制日志,但server3還不是最新的數(shù)據(jù),如圖顯示了這個場景(日志事件和偏移量僅僅是為了舉例).正如圖所示。我們可以肯定server2已經(jīng)執(zhí)行完主庫上的所有二進制日志,因為Master_Log_File和Read_Master_Log_Pos值和server1上最后的日志位置是相吻合的,因此我們可以將server2提升為新主庫,并將server3設(shè)置為server2的備庫。應(yīng)該在server3上為需要執(zhí)行的CHANGE MASTER TO語句賦予什么樣樣的參數(shù)呢?這里需要做一點點計算和調(diào)整。server3在偏移量1493停止,比server2執(zhí)行的最后一條語句的偏移量1582小89字節(jié)。server2正在向偏移量為8167的二進制日志寫入,8167-89=8078,因此理論上我們應(yīng)該將server3指向server2的日志的偏移量為8078的位置。最好去確認下這個位置附近的日志事件,以確定在該位置上是否是正確的日志事件,因為可能有別的例外,例如有些更新可能只發(fā)生在server2上。假設(shè)我們光查到的事件是一樣的,下面這條命令會將server3切換為server2的備庫。
server2>CHANGE MASTER TO MASTER_HOST="server2",MASTER_LOG_FILE="mysql-bin.000009", MASTER_LOG_POS=8078;
如果服務(wù)器在它崩潰時已經(jīng)執(zhí)行完成并記錄了超過一個事件,會怎樣呢?因為server2僅僅讀取并執(zhí)行到了偏移量1582,你可能永遠地失去了一個事件。但是如果老主庫的磁盤沒有損壞,仍然可以通過mysqlbinlog或者從日志服務(wù)器的二進制日志中找到丟失的事件。
如果需要從老朱庫上恢復(fù)丟失的事件,建議在提升新主庫之后且在允許客戶端連接之前做這件事情,這樣就無須再每臺備庫上都執(zhí)行丟失的事件,只需要使用復(fù)制來完成。但如果崩潰的老主庫完全不可用,就不得不等待,稍后再做這項工作。
上述流程中一個可調(diào)整的地方是使用可靠的方式來存儲二進制日志,如SAN或分布式復(fù)制數(shù)據(jù)庫設(shè)備(DRBD).即使主庫完全失效,依然能夠獲得它的二進制日志。也可以設(shè)置一個日志服務(wù)器,把備庫指向它,然后讓所有備庫趕上主庫失效的點。這使得提升一個備庫為新的主庫沒那么中國要。本質(zhì)上這和計劃中的提升是相同的。(當(dāng)提升一臺備庫為主庫時,千萬不要將它鞥多服務(wù)器ID修改成源主庫的服務(wù)器ID,否則將不能使用日志服務(wù)器從一個舊主庫來重放日志事件。這也是確保服務(wù)器ID最好保持不變的原因之一)
在一個主-主配置中交換角色
主-主復(fù)制拓撲結(jié)構(gòu)的一個好處就是可以很容易地切換主動和被動的角色,因為其配置是對稱的。當(dāng)在主-主配置下切換角色時,必須確保任何時候只有一個服務(wù)器可以寫入。如果兩臺服務(wù)器交叉寫入,可能會導(dǎo)致寫入沖突。換句話說,在切換角色后,原被動服務(wù)器不應(yīng)該接收到主動服務(wù)器的任何二進制日志。可以通過確保原被動服務(wù)器的復(fù)制SQL線程在該服務(wù)器可寫之前已經(jīng)趕上主動服務(wù)器來避免。通過以下步驟切換服務(wù)器角色,可以避免更新沖突的危險:
- 1.停止主動服務(wù)器上的所有寫入
- 2.在主動服務(wù)器上執(zhí)行SET GLOBAL read_only=1,同時在配置文件里也設(shè)置以下read_only,防止重啟后失效。但記住這不會阻止擁有超級權(quán)限的用戶更改數(shù)據(jù)。如果想阻止所有人更改數(shù)據(jù),可以執(zhí)行FLUSH TABLES WITH READ LOCK。如果沒有這么做,你必須kill所有的客戶端連接以保證沒有長時間運行的語句或者未提交的事務(wù)
- 3.在主動服務(wù)器上執(zhí)行SHOW MASTER STATUS并記錄二進制日志坐標
- 4.使用主動服務(wù)器上的二進制日志坐標在被動服務(wù)器上執(zhí)行SELECT MASTER _POS_WAIT().該語句將阻塞住,直到復(fù)制跟上主動服務(wù)器
- 5.在被動服務(wù)器上執(zhí)行SET GLOBAL read_only=0,這樣就變換成主動服務(wù)器。
- 6.修改應(yīng)用的配置,使其寫入到新的主動服務(wù)器中
可能還需要做一些額外的工作,包括更改兩臺服務(wù)器的IP地址,這取決于應(yīng)用的配置
復(fù)制的問題和解決方案
中斷MySQL的復(fù)制并不是件難事,因為實現(xiàn)簡單,配置相當(dāng)容易,但也意味著有很多的方式導(dǎo)致復(fù)制停止,現(xiàn)如混亂并中斷。
數(shù)據(jù)損壞或丟失的錯誤
由于各種各樣的原因,MySQL的復(fù)制并不能很好地從服務(wù)器崩潰、掉電、磁盤損壞、內(nèi)存或網(wǎng)絡(luò)錯誤中恢復(fù)。遇到這些問題時幾乎可以肯定都需要從某個點開始重啟復(fù)制。大部分由于非正常關(guān)機后導(dǎo)致的復(fù)制問題都是由于沒有把數(shù)據(jù)及時地刷到磁盤。下面是意外關(guān)閉服務(wù)器時可能會碰到的情況.
- 1.主庫意外關(guān)閉
如果沒有設(shè)置主庫的sync_binlog選項,就可能在崩潰前沒有將最后的幾個二進制日志事件刷新到磁盤中。備庫IO線程因此也可能一直處于讀不到尚未寫入磁盤的事件的狀態(tài)中。當(dāng)主庫重新啟動時,備庫將重連到主庫并在此嘗試去讀該事件,但主庫會告訴備庫沒有這個二進制日志偏移量。二進制日志轉(zhuǎn)儲線程通常很快,因此這種情況步經(jīng)常發(fā)生。解決這個問題的方法是指定備庫從下一個二進制日志的開頭讀日志。但是一些日志事件將永久地丟失,建議使用Percona Toolkit中的pt-table-checksum工具來檢查主備一致性,以便于修復(fù)??梢酝ㄟ^在主庫開啟sync_binlog來避免事件丟失。即使開啟了sync_binlog.MyISAM表的數(shù)據(jù)仍然可能在崩潰的時候損壞,對于InnoDB事務(wù),如果innodb_flush_log_at_trx_commit沒有設(shè)為1,也可能丟失數(shù)據(jù)(但數(shù)據(jù)不會損壞) - 2.備庫意外關(guān)閉
當(dāng)備庫在一次非計劃中的關(guān)閉后重啟時,會去讀master.info文件以找到上次停止復(fù)制的位置。不幸的是,該文件并沒有同步寫到磁盤,文件中存儲的信息可能是錯誤的。備庫可能會嘗試重新執(zhí)行一些二進制日志事件,這可能會導(dǎo)致唯一索引錯誤。除非能確定備庫在哪里停止(通常不太可能),否則唯一的辦法就是忽略那些錯誤。Percona Toolkit中的pt-slave-restart工具可以幫助完成這一點。如果使用的都是InnoDB表,可以在重啟觀察MySQl錯誤日志。InnoDB在恢復(fù)過程中會打印出它的恢復(fù)點的二進制日志坐標??梢允褂眠@個只來決定備庫指向主庫的偏移量。Percona Server提供了一個新的特性,可以在恢復(fù)的過程中自動將這些信息提取出來,并更新master.info文件,從根本上使得復(fù)制能夠協(xié)調(diào)好備庫上的事務(wù)。MySQL5.5也提供了一些選項來控制i如何將master.info和其他文件刷新到磁盤,這有助于減少這些問題。
除了由于MySQL非正常關(guān)閉導(dǎo)致的數(shù)據(jù)丟失外,磁盤上的二進制日志或終極日志文件損壞并不罕見,下面是一些更普遍的場景:
- 1.主庫上的二進制日志損壞。
如果主庫上的二進制日志損壞,除了忽略損壞的位置外你別無選擇??梢栽谥鲙焐蠄?zhí)行FLUSH LOGS命令,這樣主庫會開始一個新的日志文件,然后將備庫指向該文件的開始位置。也可以試著去發(fā)現(xiàn)損壞區(qū)域的結(jié)束位置。某些情況下可以通過SET GLOBAL SQL_SLAVE_SKIP_COUNTER=1來忽略一個損壞的事件。如果有多個損壞的事件,就需要重復(fù)該步驟,直到跳過所有損壞的事件。但如果有太多的損壞事件,這么做可能就沒有意義了。損壞的事件會阻止服務(wù)器找到下一個事件。這種情況下,可能不得不手動地去找到下一個完好地事件。 - 2.備庫上的中繼日志損壞
如果主庫上的日志是完好的,就可以通過CHNAGE MASTER TO命令丟棄并重新獲取損壞的事件。只需要將備庫指向它當(dāng)前正在復(fù)制的位置(Relay_Master_Log_File/Exec_Master_Log_Pos)這會導(dǎo)致備庫丟棄所有在磁盤上的中繼日志。就這一點而言,MySQL5.5做了一些改進,它能夠在崩潰后自動重新獲取中繼日志。 - 3.二進制日志與InnoDB事務(wù)日志不同步
當(dāng)主庫崩潰時,InnoDB可能將一個事務(wù)標記為已提交,此時蓋世五可能還沒有記錄到二進制日志中,除非是某個備庫的中繼日志已經(jīng)保存,否則沒有任何辦法恢復(fù)丟棄的事務(wù)。在MySQL5.0版本可以設(shè)置sync_binlog選項來防止該問題,對于更早的MySQL4.1可以設(shè)置sync_binlog和safe_binlog選項