天天看點

不同場景下MySQL的遷移方案

一 為什麼要遷移

MySQL 遷移是 DBA 日常維護中的一個工作。遷移,究其本義,無非是把實際存在的物體挪走,保證該物體的完整性以及延續性。就像柔軟的沙灘上,兩個天真無邪的小孩,把一堆沙子挪向其他地方,鑄就内心神往的城堡。

生産環境中,有以下情況需要做遷移工作,如下:

1.磁盤空間不夠。比如一些老項目,選用的機型并不一定适用于資料庫。随着時間的推移,硬碟很有可能出現短缺;

2.業務出現瓶頸。比如項目中采用單機承擔所有的讀寫業務,業務壓力增大,不堪重負。如果 IO 壓力在可接受的範圍,會采用讀寫分離方案;

3.機器出現瓶頸。機器出現瓶頸主要在磁盤 IO 能力、記憶體、CPU,此時除了針對瓶頸做一些優化以外,選擇遷移是不錯的方案;

4.項目改造。某些項目的資料庫存在跨機房的情況,可能會在不同機房中增加節點,或者把機器從一個機房遷移到另一個機房。再比如,不同業務共用同一台伺服器,為了緩解伺服器壓力以及友善維護,也會做遷移。

一句話,遷移工作是不得已而為之。實施遷移工作,目的是讓業務平穩持續地運作。

二 MySQL 遷移方案概覽

MySQL 遷移無非是圍繞着資料做工作,再繼續延伸,無非就是在保證業務平穩持續地運作的前提下做備份恢複。那問題就在怎麼快速安全地進行備份恢複。

一方面,備份。針對每個主節點的從節點或者備節點,都有備份。這個備份可能是全備,可能是增量備份。線上備份的方法,可能是使用 mysqldump,可能是 xtrabackup,還可能是 mydumper。針對小容量(10GB 以下)資料庫的備份,我們可以使用 mysqldump。但針對大容量資料庫(數百GB 或者 TB 級别),我們不能使用 mysqldump 備份,一方面,會産生鎖;另一方面,耗時太長。這種情況,可以選擇 xtrabackup 或者直接拷貝資料目錄。直接拷貝資料目錄方法,不同機器傳輸可以使用 rsync,耗時跟網絡相關。使用

xtrabackup,耗時主要在備份和網絡傳輸。如果有全備或者指定庫的備份檔案,這是擷取備份的最好方法。如果備庫可以容許停止服務,直接拷貝資料目錄是最快的方法。如果備庫不允許停止服務,我們可以使用 xtrabackup(不會鎖定 InnoDB 表),這是完成備份的最佳折中辦法。

另一方面,恢複。針對小容量(10GB 以下)資料庫的備份檔案,我們可以直接導入。針對大容量資料庫(數百GB 或者 TB 級别)的恢複,拿到備份檔案到本機以後,恢複不算困難。具體的恢複方法可以參考第三節。

三 MySQL 遷移實戰

我們搞明白為什麼要做遷移,以及遷移怎麼做以後,接下來看看生産環境是怎樣操作的。不同的應用場景,有不同的解決方案。

閱讀具體的實戰之前,假設和讀者有如下約定:

1.為了保護隐私,本文中的伺服器 IP 等資訊經過處理;

2.如果伺服器在同一機房,用伺服器 IP 的 D 段代替伺服器,具體的 IP 請參考架構圖;

3.如果伺服器在不同機房,用伺服器 IP 的 C 段 和 D 段代替伺服器,具體的 IP 請參考架構圖;

4.每個場景給出方法,但不會詳細地給出每一步執行什麼指令,因為一方面,這會導緻文章過長;另一方面,我認為隻要知道方法,具體的做法就會迎面撲來的,隻取決于掌握知識的程度和擷取資訊的能力;

5.實戰過程中的注意事項請參考第四節。

3.1 場景一 一主一從結構遷移從庫

遵循從易到難的思路,我們從簡單的結構入手。A 項目,原本是一主一從結構。101 是主節點,102 是從節點。因業務需要,把 102 從節點遷移至 103,架構圖如圖一。102 從節點的資料容量過大,不能使用 mysqldump 的形式備份。和研發溝通後,形成一緻的方案。

不同場景下MySQL的遷移方案

圖一 一主一從結構遷移從庫架構圖

具體做法是這樣:

1.研發将 102 的讀業務切到主庫;

2.确認 102 MySQL 狀态(主要看 PROCESS LIST),觀察機器流量,确認無誤後,停止 102 從節點的服務;

3.103 建立 MySQL 執行個體,建成以後,停止 MySQL 服務,并且将整個資料目錄 mv 到其他地方做備份;

4.将 102 的整個 mysql 資料目錄使用 rsync 拷貝到 103;

5.拷貝的同時,在 101 授權,使 103 有拉取  binlog 的權限(REPLICATION SLAVE, REPLICATION CLIENT);

6.待拷貝完成,修改 103 配置檔案中的 server_id,注意不要和 102 上的一緻;

7.在 103 啟動 MySQL 執行個體,注意配置檔案中的資料檔案路徑以及資料目錄的權限;

8.進入 103 MySQL 執行個體,使用 SHOW SLAVE STATUS 檢查從庫狀态,可以看到 Seconds_Behind_Master 在遞減;

9.Seconds_Behind_Master 變為 0 後,表示同步完成,此時可以用 pt-table-checksum 檢查 101 和 103 的資料一緻,但比較耗時,而且對主節點有影響,可以和開發一起進行資料一緻性的驗證;

10.和研發溝通,除了做資料一緻性驗證外,還需要驗證賬号權限,以防業務遷回後通路出錯;

11.做完上述步驟,可以和研發協調,把 101 的部分讀業務切到 103,觀察業務狀态;

12.如果業務沒有問題,證明遷移成功。

3.2 場景二 一主一從結構遷移指定庫

我們知道一主一從隻遷移從庫怎麼做之後,接下來看看怎樣同時遷移主從節點。因不同業務同時通路同一伺服器,導緻單個庫壓力過大,還不便管理。于是,打算将主節點 101 和從節點 102 同時遷移至新的機器 103 和 104,103 充當主節點,104 充當從節點,架構圖如圖二。此次遷移隻需要遷移指定庫,這些庫容量不是太大,并且可以保證資料不是實時的。

不同場景下MySQL的遷移方案

圖二 一主一從結構遷移指定庫架構圖

具體的做法如下:

1、103 和 104 建立執行個體,搭建主從關系,此時的主節點和從節點處于空載;

2、102 導出資料,正确的做法是配置定時任務,在業務低峰做導出操作,此處選擇的是 mysqldump;

3、102 收集指定庫需要的賬号以及權限;

4、102 導出資料完畢,使用 rsync 傳輸到 103,必要時做壓縮操作;

5、103 導入資料,此時資料會自動同步到 104,監控伺服器狀态以及 MySQL 狀态;

6、103 導入完成,104 同步完成,103 根據 102 收集的賬号授權,完成後,通知研發檢查資料以及賬戶權限;

7、上述完成後,可研發協作,将 101 和 102 的業務遷移到 103 和 104,觀察業務狀态;

8、如果業務沒有問題,證明遷移成功。

3.3 場景三 一主一從結構雙邊遷移指定庫

接下來看看一主一從結構雙邊遷移指定庫怎麼做。同樣是因為業務共用,導緻伺服器壓力大,管理混亂。于是,打算将主節點 101 和從節點 102 同時遷移至新的機器 103、104、105、106,103 充當 104 的主節點,104 充當 103 的從節點,105 充當 106 的主節點,106 充當 105 的從節點,架構圖如圖三。此次遷移隻需要遷移指定庫,這些庫容量不是太大,并且可以保證資料不是實時的。我們可以看到,此次遷移和場景二很類似,無非做了兩次遷移。

不同場景下MySQL的遷移方案

圖三 一主一從結構雙邊遷移指定庫架構圖

2、102 導出 103 需要的指定庫資料,正确的做法是配置定時任務,在業務低峰做導出操作,此處選擇的是 mysqldump;

3、102 收集 103 需要的指定庫需要的賬号以及權限;

4、102 導出103 需要的指定庫資料完畢,使用 rsync 傳輸到 103,必要時做壓縮操作;

7、上述完成後,和研發協作,将 101 和 102 的業務遷移到 103 和 104,觀察業務狀态;

8、105 和 106 建立執行個體,搭建主從關系,此時的主節點和從節點處于空載;

9、102 導出 105 需要的指定庫資料,正确的做法是配置定時任務,在業務低峰做導出操作,此處選擇的是 mysqldump;

10、102 收集 105 需要的指定庫需要的賬号以及權限;

11、102 導出 105 需要的指定庫資料完畢,使用 rsync 傳輸到 105,必要時做壓縮操作;

12、105 導入資料,此時資料會自動同步到 106,監控伺服器狀态以及 MySQL 狀态;

13、105 導入完成,106 同步完成,105 根據 102 收集的賬号授權,完成後,通知研發檢查資料以及賬戶權限;

14、上述完成後,和研發協作,将 101 和 102 的業務遷移到 105 和 106,觀察業務狀态;

15、如果所有業務沒有問題,證明遷移成功。

3.4 場景四 一主一從結構完整遷移主從

接下來看看一主一從結構完整遷移主從怎麼做。和場景二類似,不過此處是遷移所有庫。因 101 主節點 IO 出現瓶頸,打算将主節點 101 和從節點 102 同時遷移至新的機器 103 和 104,103 充當主節點,104 充當從節點。遷移完成後,以前的主節點和從節點廢棄,架構圖如圖四。此次遷移是全庫遷移,容量大,并且需要保證明時。這次的遷移比較特殊,因為采取的政策是先替換新的從庫,再替換新的主庫。是以做法稍微複雜些。

不同場景下MySQL的遷移方案

圖四 一主一從結構完整遷移主從架構圖

具體的做法是這樣:

1、研發将 102 的讀業務切到主庫;

2、确認 102 MySQL 狀态(主要看 PROCESS LIST,MASTER STATUS),觀察機器流量,确認無誤後,停止 102 從節點的服務;

3、104 建立 MySQL 執行個體,建成以後,停止 MySQL 服務,并且将整個資料目錄 mv 到其他地方做備份,注意,此處操作的是 104,也就是未來的從庫;

4、将 102 的整個 mysql 資料目錄使用 rsync 拷貝到 104;

5、拷貝的同時,在 101 授權,使 104 有拉取  binlog 的權限(REPLICATION SLAVE, REPLICATION CLIENT);

6、待拷貝完成,修改 104 配置檔案中的 server_id,注意不要和 102 上的一緻;

7、在 104 啟動 MySQL 執行個體,注意配置檔案中的資料檔案路徑以及資料目錄的權限;

8、進入 104 MySQL 執行個體,使用 SHOW SLAVE STATUS 檢查從庫狀态,可以看到 Seconds_Behind_Master 在遞減;

9、Seconds_Behind_Master 變為 0 後,表示同步完成,此時可以用 pt-table-checksum 檢查 101 和 104 的資料一緻,但比較耗時,而且對主節點有影響,可以和開發一起進行資料一緻性的驗證;

10、除了做資料一緻性驗證外,還需要驗證賬号權限,以防業務遷走後通路出錯;

11、和研發協作,将之前 102 從節點的讀業務切到 104;

12、利用 102 的資料,将 103 變為 101 的從節點,方法同上;

13、接下來到了關鍵的地方了,我們需要把 104 變成 103 的從庫;

- 104 STOP SLAVE;

- 103 STOP SLAVE IO_THREAD;

- 103 STOP SLAVE SQL_THREAD,記住 MASTER_LOG_FILE 和 MASTER_LOG_POS;

- 104 START SLAVE UNTIL到上述 MASTER_LOG_FILE 和 MASTER_LOG_POS;

- 104 再次 STOP SLAVE;

- 104 RESET SLAVE ALL 清除從庫配置資訊;

- 103 SHOW MASTER STATUS,記住 MASTER_LOG_FILE 和 MASTER_LOG_POS;

- 103 授權給 104 通路 binlog 的權限;

- 104 CHANGE MASTER TO 103;

- 104 重新開機 MySQL,因為 RESET SLAVE ALL 後,檢視 SLAVE STATUS,Master_Server_Id 仍然為 101,而不是 103;

- 104 MySQL 重新開機後,SLAVE 回自動重新開機,此時檢視 IO_THREAD 和 SQL_THREAD 是否為 YES;

- 103 START SLAVE;

- 此時檢視 103 和 104 的狀态,可以發現,以前 104 是 101 的從節點,如今變成 103 的從節點了。

14、業務遷移之前,斷掉 103 和 101 的同步關系;

15、做完上述步驟,可以和研發協調,把 101 的讀寫業務切回 102,讀業務切到 104。需要注意的是,此時 101 和 103 均可以寫,需要保證 101 在沒有寫入的情況下切到 103,可以使用 FLUSH TABLES WITH READ LOCK 鎖住 101,然後業務切到 103。注意,一定要業務低峰執行,切記;

16、切換完成後,觀察業務狀态;

17、如果業務沒有問題,證明遷移成功。

3.5 場景五 雙主結構跨機房遷移

接下來看看雙主結構跨機房遷移怎麼做。某項目出于容災考慮,使用了跨機房,采用了雙主結構,雙邊均可以寫。因為磁盤空間問題,需要對 A 地的機器進行替換。打算将主節點 1.101 和從節點 1.102 同時遷移至新的機器 1.103 和 1.104,1.103 充當主節點,1.104 充當從節點。B 地的 2.101 和 2.102 保持不變,但遷移完成後,1.103 和 2.101 互為雙主。架構圖如圖五。因為是雙主結構,兩邊同時寫,如果要替換主節點,單方必須有節點停止服務。

不同場景下MySQL的遷移方案

圖五  雙主結構跨機房遷移架構圖

1、1.103 和 1.104 建立執行個體,搭建主從關系,此時的主節點和從節點處于空載;

2、确認 1.102 MySQL 狀态(主要看 PROCESS LIST),注意觀察 MASTER STATUS 不再變化。觀察機器流量,确認無誤後,停止 1.102 從節點的服務;

3、1.103 建立 MySQL 執行個體,建成以後,停止 MySQL 服務,并且将整個資料目錄 mv 到其他地方做備份;

4、将 1.102 的整個 mysql 資料目錄使用 rsync 拷貝到 1.103;

5、拷貝的同時,在 1.101 授權,使 1.103 有拉取  binlog 的權限(REPLICATION SLAVE, REPLICATION CLIENT);

6、待拷貝完成,修改 1.103 配置檔案中的 server_id,注意不要和 1.102 上的一緻;

7、在 1.103 啟動 MySQL 執行個體,注意配置檔案中的資料檔案路徑以及資料目錄的權限;

8、進入 1.103 MySQL 執行個體,使用 SHOW SLAVE STATUS 檢查從庫狀态,可以看到 Seconds_Behind_Master 在遞減;

9、Seconds_Behind_Master 變為 0 後,表示同步完成,此時可以用 pt-table-checksum 檢查 1.101 和 1.103 的資料一緻,但比較耗時,而且對主節點有影響,可以和開發一起進行資料一緻性的驗證;

10、我們使用相同的辦法,使 1.104 變成 1.103 的從庫;

11、和研發溝通,除了做資料一緻性驗證外,還需要驗證賬号權限,以防業務遷走後通路出錯;

12、此時,我們要做的就是将 1.103 變成 2.101 的從庫,具體的做法可以參考場景四;

13、需要注意的是,1.103 的單雙号配置需要和 1.101 一緻;

14、做完上述步驟,可以和研發協調,把 1.101 的讀寫業務切到 1.103,把 1.102 的讀業務切到 1.104。觀察業務狀态;

15、如果業務沒有問題,證明遷移成功。

3.6 場景六 多執行個體跨機房遷移

接下來我們看看多執行個體跨機房遷移證明做。每台機器的執行個體關系,我們可以參考圖六。此次遷移的目的是為了做資料修複。在 2.117 上建立 7938 和 7939 執行個體,替換之前資料異常的執行個體。因為業務的原因,某些庫隻在 A 地寫,某些庫隻在 B 地寫,是以存在同步過濾的情況。

不同場景下MySQL的遷移方案

圖六 多執行個體跨機房遷移架構圖

1、1.113 針對 7936 執行個體使用 innobackupex 做資料備份,注意需要指定資料庫,并且加上 slave-info 參數;

2、備份完成後,将壓縮檔案拷貝到 2.117;

3、2.117 建立資料目錄以及配置檔案涉及的相關目錄;

4、2.117 使用 innobackupex 恢複日志;

5、2.117 使用 innobackupex 拷貝資料;

6、2.117 修改配置檔案,注意如下參數:replicate-ignore-db、innodb_file_per_table = 1、read_only = 1、 server_id;

7、2.117 更改資料目錄權限;

8、1.112 授權,使 2.117 有拉取  binlog 的權限(REPLICATION SLAVE, REPLICATION CLIENT);

9、2.117 CHANGE MASTE TO 1.112,LOG FILE 和 LOG POS 參考 xtrabackup_slave_info;

10、2.117 START SLAVE,檢視從庫狀态;

11、2.117 上建立 7939 的方法類似,不過配置檔案需要指定 replicate-wild-do-table;

12、和開發一起進行資料一緻性的驗證和驗證賬号權限,以防業務遷走後通路出錯;

13、做完上述步驟,可以和研發協調,把相應業務遷移到 2.117 的 7938 執行個體和 7939 執行個體。觀察業務狀态;

14、如果業務沒有問題,證明遷移成功。

四、 注意事項

介紹完不同場景的遷移方案,需要注意如下幾點:

1、資料庫遷移,如果涉及事件,記住主節點打開 event_scheduler 參數;

2、不管什麼場景下的遷移,都要随時關注伺服器狀态,比如磁盤空間,網絡抖動;另外,對業務的持續監控也是必不可少的;

3、CHANGE MASTER TO 的 LOG FILE 和 LOG POS 切記不要找錯,如果指定錯了,帶來的後果就是資料不一緻;

4、執行腳本不要在 $HOME 目錄,記住在資料目錄;

5、遷移工作可以使用腳本做到自動化,但不要弄巧成拙,任何腳本都要經過測試;

6、每執行一條指令都要三思和後行,每個指令的參數含義都要搞明白;

7、多執行個體環境下,關閉 MySQL 采用 mysqladmin 的形式,不要把正在使用的執行個體關閉了;

8、從庫記得把 read_only = 1 加上,這會避免很多問題;

9、每台機器的 server_id 必須保證不一緻,否則會出現同步異常的情況;

10、正确配置 replicate-ignore-db 和 replicate-wild-do-table;

11、建立的執行個體記得把 innodb_file_per_table 設定為 1,上述中的部分場景,因為之前的執行個體此參數為 0,導緻 ibdata1 過大,備份和傳輸都消耗了很多時間;

12、使用 gzip 壓縮資料時,注意壓縮完成後,gzip 會把源檔案删除。

13、所有的操作務必在從節點或者備節點操作,如果在主節點操作,主節點很可能會當機;

14、xtrabackup 備份不會鎖定 InnoDB 表,但會鎖定 MyISAM 表。是以,操作之前記得檢查下目前資料庫的表是否有使用 MyISAM 存儲引擎的,如果有,要麼單獨處理,要麼更改表的 Engine;

五、技巧

在 MySQL 遷移實戰中,有如下技巧可以使用:

1、任何遷移 LOG FILE 以 relay_master_log_file(正在同步 master 上的 binlog 日志名)為準,LOG POS 以 exec_master_log_pos(正在同步目前 binlog 日志的 POS 點)為準;

2、使用 rsync 拷貝資料,可以結合 expect、nohup 使用,絕對是絕妙組合;

3、在使用 innobackupex 備份資料的同時可以使用 gzip 進行壓縮;

4、在使用 innobackupex 備份資料,可以加上 --slave-info 參數,友善做從庫;

5、在使用 innobackupex 備份資料,可以加上 --throttle 參數,限制 IO,減少對業務的影響。還可以加上 --parallel=n 參數,加快備份,但需要注意的是,使用 tar 流壓縮,--parallel 參數無效。

6、做資料的備份與恢複,可以把待辦事項列個清單,畫個流程,然後把需要執行的指令提前準備好;

7、本地快速拷貝檔案夾,有個不錯的方法,使用 rsync,加上如下參數:-avhW --no-compress --progress;

8、 不同分區之間快速拷貝資料,可以使用 dd。或者用一個更靠譜的方法,備份到硬碟,然後放到伺服器上。異地還有更絕的,直接快遞硬碟。

六、總結

本文從為什麼要遷移講起,接下來講了遷移方案,然後講解了不同場景下的遷移實戰,最後給出了注意事項以及實戰技巧。歸納起來,也就以下幾點:

第一,遷移的目的是讓業務平穩持續地運作;

第二,遷移的核心是怎麼延續主從同步,我們需要在不同伺服器和不同業務之間找到方案;

第三,業務切換需要考慮不同 MySQL 伺服器之間的權限問題;需要考慮不同機器讀寫分離的順序以及主從關系;需要考慮跨機房調用對業務的影響。

讀者在實施遷移的過程中,可以參考此文提供的思路。但怎樣保證每個操作正确無誤地運作,還需要三思而後行。

說句題外話,「證明自己有能力最重要的一點就是讓一切都在自己的掌控之中。」 

摘自《CSDN大資料》