螞蟻搬家式遷移mysql數據庫


伺機房搬遷的機會,打算作一次業務整合。現有的架構是在2010年規劃並運營起來的,隨着時間的推移,項目也愈來愈多。打開nginx配置文件,有四十多行include包含存在,每個包含就是一個項目(有些是web,有些是app)。一整個機櫃,老舊的設備,負載均衡高可用架構。爲保證業務一致性和下降成本,業務數據(開發的應用程序及用戶上傳數據)共享一套NFS;各業務共享同一套物理數據庫(一臺物理服務器mysql建立多個庫)。隨着業務和訪問量的增加,這種隱患愈來愈使人擔心,主要表如今如下幾個方面:mysql

安全問題linux

數十個站點共享目錄,以nfs方式共享給各物理服務器,這幾十個項目,只要任何一個有安全漏洞存在,有心人都能進來隨心所欲,讓站點所有淪陷。時不時的,被人注入惡意代碼,針對性的進行清除,但沒多久又被注入篡改。你們內心都有數,存在漏洞的地方,不必定是被篡改的那個。但站點太多,又沒有隔離,根本沒法用安全工具掃描(一個站點進行掃描,平均花費一天)。android

[root@web57 ~]# more   /usr/local/nginx/conf/nginx.confnginx

user  www   www;程序員

worker_processes    6;web

 

worker_rlimit_nofile 51200;ajax

 

events {sql

 use epoll;數據庫

 #use   kqueue;   #FreeBSD systemapi

 worker_connections 51200;

}

 

http {

 include         mime.types;

 default_type    application/octet-stream;

 #charset    gb2312;

 server_names_hash_bucket_size 256;

 client_header_buffer_size 256k;

 large_client_header_buffers 4 256k;

 client_max_body_size 500m;

…………………………………………省略若干…………………………………

include vhosts/faxian.quanzhen.com.conf;

include vhosts/www.quanzhen.com.conf;

include vhosts/news.quanzhen.com.conf;

include vhosts/s.quanzhen.com.conf;

include vhosts/down.quanzhen.com.conf;

include vhosts/static.quanzhen.com.conf;

include vhosts/image.quanzhen.com.conf;

include vhosts/3g.quanzhen.com.conf;

include vhosts/mini.quanzhen.com.conf;

include vhosts/xml.quanzhen.com.conf;

include vhosts/mayiapi.quanzhen.com.conf;

include vhosts/www.android77.com.conf;

include vhosts/fahongbao.android77.com.conf;

include vhosts/update.android77.com.conf;

include vhosts/dev.quanzhen.com.conf;

include vhosts/qr.110.cc.conf;

include vhosts/110.cc.conf;

include vhosts/eggserver.quanzhen.com.conf;

include vhosts/apkegg.quanzhen.com.conf;

include vhosts/eggserver.yidong7.cn.conf;

include vhosts/www.yidong7.cn.conf;

include vhosts/down.yidong7.cn.conf;

include vhosts/wan.quanzhen.com.conf;

include vhosts/open.quanzhen.com.conf;

include vhosts/bakdown.yidong7.cn.conf ;

include vhosts/hanhua.quanzhen.com.conf;

include vhosts/mpk.quanzhen.com.conf;

include vhosts/android.quanzhen.com.conf;

include vhosts/pay.quanzhen.com.conf;

include vhosts/cmstop.quanzhen.cn.conf;

include vhosts/news.quanzhen.cn.conf;

include vhosts/pingce.quanzhen.cn.conf;

include vhosts/gonglue.quanzhen.cn.conf;

include vhosts/hao.quanzhen.cn.conf;

include vhosts/all.quanzhen.cn.conf;

include vhosts/s.quanzhen.cn.conf;

include vhosts/apkz.quanzhen.com.conf;

include vhosts/ajax.quanzhen.com.conf;

include vhosts/union.quanzhen.com.conf;

include vhosts/mai.quanzhen.com.conf;

include vhosts/blog.quanzhen.com.conf;

include vhosts/guazi.quanzhen.com.conf;

include vhosts/lockscreen.yidong7.cn.conf;

include vhosts/dsp.pujia8.com.conf;

include vhosts/3svx4haii9.quanzhen.com.conf;

include vhosts/u.quanzhen.com.conf;

include vhosts/bianji.quanzhen.com.conf;

include vhosts/default.conf;

}

 

性能問題

主要集中在數據庫上邊,只要有一個庫出現問題,引發鎖表或者其它競爭,所有相關業務都會掛起,煩不勝煩啊。想進行拆分,決策人認爲,原本就滿機櫃了,若是再新家機器,得另租機櫃,考慮到成本等其它問題,只求不出事便可。

 

整合的計劃是,遷移部分業務到公有云上,騰出服務器後,對現有的設備進行擴充配置(拼內存、硬盤等,古舊的機器直接下架)。留下配置高的,進行虛擬化,既能減小設備數量(託管費下降),又有利於平常維護。

 

前邊說了這麼多,彷佛與技術關係不大,但對於一些有遺留問題的項目,仍是具備參考意義。接下來,咱們就進入正題,看看咱們要遷移的項目情況。要往雲上遷移的數據包括網站數據及數據庫數據,網站數據比較好辦,rsync同步到對應的目錄,而數據庫相對而言,要麻煩很多。兩個數據庫,一個容量38G,另外一個29G,不算太大,但公用的ibdata1文件卻有123G,最初是嘗試把這兩個庫,直接導入到阿里雲的RDS,在進行數次操做失敗後,諮詢客服獲得的答覆是RDS暫時不支持分表的數據庫。爲節省成本,購買一個配置高一點的雲主機(cpu 8core,內存32G,1T高效雲盤),部署上mysql5.6,供兩個數據庫使用。

 

第一次嘗試

預估了一下,200G的數據,貪心一把,看一次性能不能遷移完。提早幾天,把雲上的環境所有準備穩當(能出來測試頁),運營部門把通知發下去,而後某天夜裏0:30分,一些人在辦公室,一些人在家裏,眯着眼,莊重地在鍵盤敲入「screen」這幾個字符。在qq羣裏獲得一致許可,能夠進行數據庫導出操做之後,小弟當心翼翼地發來一條指令:

[root@db-209   ~]# innobackupex    --user=root  --passwor='i%=KGb76'   \

--defaults-file=/etc/my.cnf  \

--databases=「quanzhen_mobile7lockscreen   quanzhen_equipment」 /data/bakmysql/

InnoDB Backup Utility v1.5.1-xtrabackup; Copyright   2003, 2009 Innobase Oy

and Percona Ireland Ltd 2009-2012.  All Rights Reserved.

 

This software is published under

the GNU GENERAL PUBLIC LICENSE Version 2, June   1991.

 

180618 00:30:31    innobackupex: Starting mysql with options:  --defaults-file='/etc/my.cnf'   --password=xxxxxxxx --user='root' --unbuffered --

180618 00:30:31    innobackupex: Connected to database with mysql child process   (pid=20090)

180618 00:30:37    innobackupex: Connection to database server closed

IMPORTANT: Please check that the backup run   completes successfully.

             At the end of a successful backup run innobackupex

             prints "completed OK!".

 

innobackupex: Using mysql  Ver 14.12 Distrib 5.0.95, for   redhat-linux-gnu (x86_64) using readline 5.1

innobackupex: Using mysql server version Copyright   (c) 2000, 2011, Oracle and/or its affiliates. All rights reserved.

 

innobackupex: Created backup directory   /data/bakmysql/2018-06-18_00-30-37

180618 00:30:37    innobackupex: Starting mysql with options:  --defaults-file='/etc/my.cnf'   --password=xxxxxxxx --user='root' --unbuffered --

180618 00:30:37    innobackupex: Connected to database with mysql child process   (pid=20123)

180618 00:30:39    innobackupex: Connection to database server closed

 

180618 00:30:39    innobackupex: Starting ibbackup with command: xtrabackup_55  --defaults-file="/etc/my.cnf"  --defaults-group="mysqld"   --backup --suspend-at-end --target-dir=/data/bakmysql/2018-06-18_00-30-37   --tmpdir=/tmp

innobackupex: Waiting for ibbackup (pid=20132) to   suspend

innobackupex: Suspend file   '/data/bakmysql/2018-06-18_00-30-37/xtrabackup_suspended'

 

xtrabackup_55 version 2.0.7 for Percona Server   5.5.16 Linux (x86_64) (revision id: 552)

xtrabackup: uses posix_fadvise().

xtrabackup: cd to /data/mysql_db

xtrabackup: Target instance is assumed as   followings.

xtrabackup:     innodb_data_home_dir = ./

xtrabackup:     innodb_data_file_path = ibdata1:10M:autoextend

xtrabackup:     innodb_log_group_home_dir = ./

xtrabackup:     innodb_log_files_in_group = 2

xtrabackup:     innodb_log_file_size = 5242880

>> log scanned up to (601191481892)

[01] Copying ./ibdata1 to /data/bakmysql/2018-06-18_00-30-37/ibdata1

>> log scanned up to (601191481892)

>> log scanned up to (601191481892)

>> log scanned up to (601191481892)

>> log scanned up to (601191481892)

>> log scanned up to (601191481892)

>> log scanned up to (601191481892)

>> log scanned up to (601191481892)

…………………………………省略……………………………………………

樂觀估計,上午7點前,能完成整個遷移,幾我的商量輪流監看進展程度,等進行完一步後叫醒休息的人,以便進行下一步。結果,到凌晨六點多,才執行完這個innobackupex,還差好幾步呢,每一步都一樣耗時,只能宣告遷移暫時失敗,選個黃道吉日,分兩次進行遷移。

 

第二次分拆遷移

萬年曆排除近期諸事不宜的日子,再搖卦選利用用神的地支,選定日誌,約上相關人等,繼續進行遷移。有了上一次的教訓,在遷移前又對要遷移的庫作了清理,刪掉了一些無用的數據,省出來好幾個G的空間。在源數據庫,執行指令:

[root@db-209 ~]#innobackupex  --user=root    --passwor='i%=KGb76'  \

--defaults-file=/etc/my.cnf --databases=「quanzhen_equipment」   /data/bakmysql/

我交到好之後,就躺下睡覺,到凌晨三點電話響了,告知第一步完成。

[root@db-209 ~]#innobackupex  --apply-log /data/bakmysql/2018-06-18_00-30-37

日誌應用卻是執行的很快,回車即完。而後進行tar 打包和複製文件到目標服務器,因爲租賃的出口帶寬過小(總帶寬30M,如今讀者知道爲何要夜間訪問低谷進行遷移了吧?),複製文件到目標服務花了一些時間。

 

目標服務器,僅僅須要安裝好mysql軟件,建立好目錄/data/mysql_db,不須要執行數據庫初始化操做,由於innobackupex導入時,要求數據目錄必須爲空。阿里雲的配置,遠比源服務器配置高,解壓文件很快就完成。

 

檢查一下mysql選項文件/etc/my.cnf,注意是選項文件。設定「—datadir=/data/mysql_db」,就可執行導入操做,指令以下:

[root@msyql mysql_db]# innobackupex    --defaults-file=/etc/my.cnf  \

--copy-back /data/db_bk/2018-06-18_00-30-37

源數據導出時,沒有把庫mysql一併導出,這倒不是什麼要緊的事情,反正只有一個帳戶須要建立。接下來,初始化數據庫並建立應用賬號,具體操作以下:

[root@msyql mysql_db]#cd /usr/local/mysql/

[root@msyql ~]#scripts/mysql_install_db  --user=mysql --datadir=/data/mysql_db

[root@msyql ~]#mysql

mysql>grant all on quanzhen_equipment.*   to ……

還要記得給mysql空密碼消除掉。

 

源庫與目標庫,比對一下表的數量,以及隨機抽取一些大表,對記錄數進行比較。確認數據完整之後,一幫去調試應用,後續工做不表,沒我什麼事。

 

第三次分拆遷移

有了上一次的成功經驗,此次信心滿滿了,不過擔憂仍是有的,就是那個目標庫導入時,要求數據目錄爲空。小弟在未開始時,就來徵求個人意見,我擔憂可能會有障礙,就對他說,你只要把源站數據導出準備好,放到目標數據庫,餘下的我親自搞定。

 

本身的選擇有兩個,一個是使用選項「--force-non-empty-directories」,若是不行,就再弄一個mysql實例,啓用3307端口,雙實例運行。先嚐試第一個選項,看能不能進行下去,具體指令爲:

[root@msyql db_bk]# pwd

/data/db_bk

[root@msyql db_bk]#innobackupex  --defaults-file=/etc/my.cnf --copy-back \

--force-non-empty-directories 2018-06-22_00-24-52

180623 23:31:57 innobackupex: Starting the copy-back   operation

 

IMPORTANT: Please check that the copy-back run   completes successfully.

             At the end of a successful copy-back run innobackupex

             prints "completed OK!".

 

innobackupex version 2.4.11 based on MySQL server   5.7.19 Linux (x86_64) (revision id: b4e0db5)

innobackupex:   Can't create/write to file '/data/mysql_db/ib_logfile0' (Errcode: 17 - File   exists)

[01] error: cannot open the destination stream for   ib_logfile0

[01] Error: copy_file() failed.

悲催了,有同名文件存在,不行!直接終止運行。好吧,我把文件「ib_logfile0、ib_logfile1」挪走,再執行,仍是不行,提示文件「ibdata1」存在,這但是個你們夥。雖然擔憂新導入的ibdata1可能不包含現有數據庫相關信息,但忍不住想試一把。可能有讀者會問,這樣搞可能把數據庫原有的數據破壞掉了,其實我想到這一層來,老早我就把整個庫作了備份,買了保險的。

 

正全神貫注盯着屏幕查看輸出,但願進展順利,忽然,qq羣有消息傳來,問進展如何,啥時能完成。一看時間,六點了,北方大地已經一片光明。時間來不及了,停掉進程,試試直接複製文件,不使用innobuckupex。心中沒底,就去仔細比較了數據庫目錄與導出數據目錄中的三個文件「ibdata一、ib_logfile0、ib_logfile1」,發現其大小徹底相同。無論了,把現有數據庫裏的這幾個文件搬走,從導出目錄cp來着三個文件。複製完,執行mysqld_safe啓動服務,失敗,提示ib_logfile0無寫入權限;這好辦,一條chown指令而已。再執行啓動mysql服務,正常。

 

那麼數據對不對呢?我不能肯定,萬一不對,就再配一個mysql,導入數據,以雙實例啓動,後邊再想法整合;阿里雲購買的服務器,相互通訊是內網,不會在傳輸上浪費太多時間。

 

既然服務正常,就對一下數據吧,萬一運氣爆棚(前幾天夜裏夢到本身能飛,抓住一隻巨型天鵝,我美美地摟着天鵝的脖子…),數據完整可用呢!我本身悄悄對比了一陣,沒差別呢,又到qq羣呼叫其它人,說導入有障礙,數次不成功,後邊採起了一些不肯定的手段,mysql服務是起來了,請你們覈實一下數據,看是否完整可用。幾個程序員一陣忙碌,獲得答覆,數據是完整可用的。到此,個人工做完成了。

 

有人可能要鄙視我一番,爲何不先測試?不制定完善的流程?這個問題問得好!我數次建議決策人,準備點資源,說白了就是準備1臺空閒服務器,再內網演練,就算白天也能能進行(複製數據走內網,不在用戶訪問的帶寬),可是,沒有資源給我啊,但事情又不得不作。雖然累點,折騰一番,翻過來想,咱玩懸的也得到經驗,否則也沒有這個文章問世,大家以爲覺呢?


道長有話說
最近受邀在51CTO博客專欄出版《負載均衡高手煉成記》,依託本身十餘年的IT運維經驗,以實際工做經驗爲基礎,介紹不一樣場景下,負載均衡的實現方式,以及負載均衡的平常維護。
本專欄適合於一直徘徊在運維初級未找到入佳境之門的運維工程師,也適合對負載均衡有興趣瞭解和學習的技術愛好者。跟着田道長學完這個系列課程,不只學知識,更是漲薪、升職、進心儀公司的一大捷徑!
負載均衡高手煉成記

940cc356717369e1341b22ad114f793e.jpg

相關文章
相關標籤/搜索