從小公司,一路跌跌撞撞到騰訊,論高級DBA的自我修養(yǎng)!
專職做 DBA 已經(jīng) 6 年多的時間了,一路走來,感觸非常深??赐小⑼路噶颂嗟腻e誤,同樣我自己也犯了非常多的錯誤,然而絕大多數(shù)的錯誤其實都是很低級的錯誤。
有的是因為不了解某個引擎的特性導(dǎo)致、有的是因為對線上環(huán)境不了解導(dǎo)致、有的是因為經(jīng)驗不足導(dǎo)致。一路上,跌跌撞撞,從小公司 DBA,到騰訊高級 DBA,再到現(xiàn)在的金融數(shù)據(jù)庫 DBA。
不由得想起 5 年前的我,剛進入 DBA 行業(yè),缺乏經(jīng)驗,經(jīng)常犯錯誤,不是我不夠努力,更多的是初來乍到的我根本不知道應(yīng)該在哪方面下功夫。
本文就是基于這方面的考慮,根據(jù)自己在 DBA 這個職業(yè)上走過的彎路,總結(jié)一些方法給 DBA 的同行。希望本文能給同行 DBA 或者運維的朋友們帶來一些改變,讓大家知道作為一個 DBA 需要在哪些方面下功夫。
下面主要從環(huán)境、數(shù)據(jù)安全、常規(guī)操作、預(yù)案、架構(gòu)、心態(tài)等層面進行分享,同時也會介紹一些實用的經(jīng)驗。
環(huán)境篇
毫無疑問,DBA 是需要綜合技能最多的一個職業(yè),需要你有網(wǎng)絡(luò)、操作系統(tǒng)、文件系統(tǒng)、數(shù)據(jù)庫、安全、編程等知識。
作為 DBA,為了少犯錯誤,你首先得非常熟悉你負責(zé)的數(shù)據(jù)庫環(huán)境,大到網(wǎng)絡(luò)環(huán)境、系統(tǒng)環(huán)境、數(shù)據(jù)庫環(huán)境(這里主要以MySQL為例)。如果不熟悉環(huán)境,很容易因為自身操作考慮不周而導(dǎo)致線上的故障。
想想就知道,有多少 DBA 因為 alter 操作導(dǎo)致的線上故障?有多少 DBA 忽略了字符集的問題導(dǎo)致了線上的亂碼?又有多少 DBA 由于遷移的時候沒有備份觸發(fā)器或者 event 導(dǎo)致的故障?太多的教訓(xùn)足以讓我們所有的 DBA 認識到熟悉環(huán)境的重要性。
另外 DBA 對線上環(huán)境如果足夠了解,在處理故障、討論處理方案等,都能極大地增強我們的自信,更好地提升自己的影響力。
我們可以說不熟悉環(huán)境的 DBA 不是好 DBA。下面來介紹環(huán)境部分 DBA 應(yīng)該注意的問題:
軟件環(huán)境
操作系統(tǒng)環(huán)境
針對操作系統(tǒng)部分,你可能需要了解的是使用的操作系統(tǒng)類型,Linux or Windows,該系統(tǒng)做了哪些內(nèi)核的優(yōu)化,尤其是針對數(shù)據(jù)庫。
比如文件描述符、配置 ntp、raid 的寫 cache 模式等,另外你還要對系統(tǒng)的運行狀態(tài)有大致的了解,CPU 使用、內(nèi)存使用、IO 使用以及網(wǎng)絡(luò)帶寬和包量的情況。
數(shù)據(jù)庫環(huán)境
數(shù)據(jù)庫環(huán)境包含的內(nèi)容就非常多了,這里只介紹如果不了解比較容易造成誤操作的部分:
部署方式
對于數(shù)據(jù)庫的部署,我們需要了解數(shù)據(jù)庫是如何部署的,部署在了什么目錄,可執(zhí)行文件、數(shù)據(jù)文件、log 文件、配置文件等的存放路徑,數(shù)據(jù)庫如何啟動和停止等。
使用引擎
了解目前數(shù)據(jù)庫默認使用的引擎,以及現(xiàn)有的表使用的引擎,提前清楚地了解各個引擎的特點和使用,避免在出現(xiàn)數(shù)據(jù)遷移、表損壞以及啟動問題手忙腳亂導(dǎo)致誤操作。
我們的技術(shù)就像武器庫,都是靠平時閑淡中的積累和打造,在出問題的時候直接從武器庫拿來使用,因此要經(jīng)常豐富我們的“武器庫”。
備注:雖然現(xiàn)在基本使用的都是 innodb 引擎,但是,你也同樣可以發(fā)現(xiàn)有的還用了 Myisam,甚至還有的用到了 memory、merge、spider、tokuDB 等。
同步方式
目前 MySQL 基本都會配置同步(如果沒有一定要加上,除非是數(shù)據(jù)丟了或者長時間故障也沒關(guān)系的庫),既然涉及到同步就會有多種不同的方式。
比如常見的分類:
- 基于 binlog 和 pos 的同步。
- 基于 GTID 的同步。
- 異步。
- 半同步。
- 單線程同步。
- 多線程同步。
針對這些同步,都有一些不同的特點,比如出現(xiàn)問題了,需要跳過某個位置,gtid 的同步和基于 pos 的同步操作就不一樣,同步方式也是你必須掌握的技巧。
版本
在維護數(shù)據(jù)庫的時候,還需要了解當(dāng)前數(shù)據(jù)庫使用的大版本。因為數(shù)據(jù)庫的大版本的功能會有很大的差異,有很多特性是只存在某個大版本的。
因此了解使用的版本能讓你大致知道當(dāng)前數(shù)據(jù)庫支持哪些特性。在涉及到遷移、同步、數(shù)據(jù)庫升級等操作的時候,能從容應(yīng)對。
存儲過程(procedure)、事件(event)
了解當(dāng)前數(shù)據(jù)庫是否存在存儲過程和事件,在數(shù)據(jù)備份、數(shù)據(jù)遷移的時候,需要將對應(yīng)的存儲過程和事件的參數(shù)添加進去。
另外如果存在事件,在遷移的時候會有特殊的操作,在遷移的目標(biāo)機器要先將事件關(guān)閉,切換后再打開。防止事件導(dǎo)致數(shù)據(jù)不一致。
關(guān)鍵配置
MySQL 有幾項非常關(guān)鍵的配置,需要了解清楚,避免由于配置沒搞清楚導(dǎo)致誤操作,總結(jié)關(guān)鍵配置如下:
- innodb_buffer_pool_size
- #對innodb生效,對性能影響非常大,一般可以設(shè)置內(nèi)存的50~80%
- key_buffer_size
- #對Myisam生效,建議修改成innodb
- innodb_flush_log_at_trx_commit
- #innodb的redo日志刷新方式,對innodb的影響會很大,一般設(shè)置為2log
- -bin
- #是否開始binlog,如果沒有開啟,一定要開啟
- sync_binlog
- #刷binlog的方式,一般設(shè)置為0,如果對數(shù)據(jù)需要強一致的,可以將sync_binlog設(shè)置為大于1的數(shù),兼顧安全和性能
- innodb_file_per_table
- #采用獨立表空間,建議都設(shè)置成獨立表空間,不然后面磁盤空間滿了,刪除表空間也無法釋放,必須做數(shù)據(jù)遷移
- lower_case_table_names
- #表明區(qū)分大小寫
- character_set_server
- #字符集在遷移、數(shù)據(jù)庫變更、數(shù)據(jù)導(dǎo)入等都是必須要注意的,不然數(shù)據(jù)亂碼了就會很麻煩
- max_connections
- #***連接數(shù)不能設(shè)置太大,要計算一下session內(nèi)存*max_connections + 固定內(nèi)存 < 總內(nèi)存-2G(這2G用來做系統(tǒng)內(nèi)存,留給系統(tǒng)的內(nèi)存可以再設(shè)大一點)
- transaction_isolation
- #設(shè)置隔離級別,默認是Repeatable Read,如果是binlog是row模式,也經(jīng)常設(shè)置為Read Committed級別
所有上面說的參數(shù),都需要深入了解和熟悉,當(dāng)我們在做數(shù)據(jù)遷移的時候或者搭建MySQL 的時候,一定要比對一下源實例的配置(比對工具可以參考 pt-config-diff 工具),以免遷移完成后由于參數(shù)不一致,中途要重啟實例的情況。
在這個問題上,我見過太多的教訓(xùn),希望大家能吸取教訓(xùn),減少故障和問題的發(fā)生。
數(shù)據(jù)庫環(huán)境收集工具介紹
前面我們介紹了數(shù)據(jù)庫相關(guān)的環(huán)境,對于那么多的環(huán)境變量,我們?nèi)绾胃玫娜ナ占@里給大家介紹一個工具。
pt-mysql-summary
這個工具的具體用法可以 Google 了解,也可以訪問如下鏈接了解,不在本文的論述范圍:https://www.percona.com/doc/percona-toolkit/2.1/pt-mysql-summary.html
硬件
硬件相關(guān)的信息也是我們需要關(guān)注的,針對每種硬件我們都會有大致的 QPS、TPS 等指標(biāo),這個對于新上業(yè)務(wù)的評估以及評估現(xiàn)在數(shù)據(jù)庫的瓶頸很有幫助。
對于硬件你需要了結(jié) CPU 核數(shù)、內(nèi)存的大小、硬盤的介質(zhì)(SAS? PCIE SSD ?NVME SSD?),***對線上的常見機型都有詳細的壓測數(shù)據(jù)。
了解每一種機型在 MySQL 中的表現(xiàn),也是體現(xiàn) DBA 專業(yè)度的一個指標(biāo)。
經(jīng)常有 DBA 由于不了解各個機型大致能支撐的性能 ,在方案選型和設(shè)備選型討論中,無法肯定地確認具體需要什么設(shè)備,當(dāng)前的設(shè)備配置是否能抗住對應(yīng)的訪問量,導(dǎo)致領(lǐng)導(dǎo)和開發(fā)對該 DBA 的專業(yè)度大打折扣。
如果大家在日常工作中有空閑的機器,不妨使用 sysbench、mysqlslap、fio 等工具搗鼓一下。
運行狀態(tài)
作為 DBA,我們還需要了解現(xiàn)在的實例的運行狀態(tài),如下幾個指標(biāo)都是我們需要了解的。
數(shù)據(jù)庫數(shù)據(jù)量和表的數(shù)據(jù)量,數(shù)據(jù)量到多少 G,尤其是單表的數(shù)據(jù)量:
- 實例負載情況(CPU負載、IO負載、系統(tǒng)負載)
- 慢查詢情況
- SQL延遲情況
- 鎖情況
- 臟頁情況
- 訪問模型
訪問模型就是這數(shù)據(jù)庫承擔(dān)的是讀多寫少還是讀少寫多,以及是否是高并發(fā)等等。
針對上述問題,可以采用 pt-mysql-summary 工具獲取,再加以分析,也可以通過如下兩個工具來實時查看:
- innotop
- orzdba
數(shù)據(jù)安全篇
針對數(shù)據(jù)安全,主要包含如下幾個部分:
權(quán)限安全
在權(quán)限方面,我們經(jīng)常會看到有很多的數(shù)據(jù)庫根本就沒有密碼,或者給業(yè)務(wù)的用戶使用完全的權(quán)限(all privileges),或者是給某個帳號可以從任何地方登錄的權(quán)限,這些都是非常致命的。
建議在授予權(quán)限的時候注意如下幾點:
- 數(shù)據(jù)庫一定設(shè)置符合密碼復(fù)雜度的用戶密碼。
- 禁止給用戶設(shè)置 % 的登錄機器。
- 只給業(yè)務(wù)最小權(quán)限的帳號,并限制登錄的機器。
數(shù)據(jù)一致性
目前一般都是主從架構(gòu),主從的數(shù)據(jù)是否一致?90% 以上的主從架構(gòu)都缺乏數(shù)據(jù)一致性校驗,之前遇到主從切換后數(shù)據(jù)不一致的情況,導(dǎo)致線上故障。
為了保證數(shù)據(jù)的一致性,記得周期性地使用 pt-table-checksum 來檢查主從數(shù)據(jù)是否一致,如果不一致,可以使用 pt-table-sync 進行修復(fù)。
數(shù)據(jù)安全
做為 DBA,經(jīng)常要思考,如果數(shù)據(jù)被誤刪,在現(xiàn)有的環(huán)境下是否會導(dǎo)致數(shù)據(jù)丟失。如果會,那就是你 DBA 工作沒有做到位。
主要考慮的指標(biāo)為:
- 備份策略(數(shù)據(jù)庫備份、binlog 備份)。
這里主要考慮三件事情:
- 數(shù)據(jù)備份策略是否合理。備份策略至少包含全量備份和 binlog 增量備份,由于有從機,基本 binlog 都會比較安全。
- 備份數(shù)據(jù)是否安全。備份數(shù)據(jù)是否安全,比如備份機器掛掉,是否所有的備份數(shù)據(jù)都會丟失,可以采用分布式文件系統(tǒng)或者在服務(wù)器中交錯存放來規(guī)避。
- 備份數(shù)據(jù)是否可用。常常問自己,我們的備份數(shù)據(jù)都是有效的嗎?周期性做備份數(shù)據(jù)還原的演練是必要的,確保備份數(shù)據(jù)的有效性。
常規(guī)操作篇
在操作數(shù)據(jù)庫的時候,首先我們需要熟練常規(guī)的操作。
常規(guī)的操作又分為兩部分:
- 線上數(shù)據(jù)庫的常規(guī)操作。
- 針對常見故障的預(yù)案的常規(guī)操作。
熟練了操作和預(yù)案,才能在線上出問題的時候不至于手忙腳亂。
常規(guī)操作
常規(guī)的操作一般包含如下幾項:
- 啟動停止。
- 數(shù)據(jù)庫常規(guī)變更。
- 索引優(yōu)化。
- 配置修改。
- 數(shù)據(jù)庫的備份。
- 數(shù)據(jù)的遷移。
- 切換。
以上這些操作,包含的內(nèi)容太多,DBA 們可以自行 Google,總之要達到非常熟練的地步。
如果命令記不住,建議將常規(guī)的操作通過關(guān)鍵字標(biāo)記,并記錄到類似印象筆記的文檔中,要急用的時候可以快速搜索到。也可以寫成工具腳本,隨時調(diào)用。
常見故障的預(yù)案
作為 DBA,經(jīng)常要面對各種突發(fā)的故障。大家要先搞清楚,不是遇到了故障我們才去找解決辦法,而是在沒有遇到故障之前就應(yīng)該想到某一部分可能會出現(xiàn)問題,如果出現(xiàn)問題,我們該當(dāng)如何來應(yīng)對。
比如 master 出現(xiàn)故障,我們?nèi)绾翁幚?當(dāng)你想到某個地方可能出現(xiàn)問題,那么就先將解決方案寫出來,然后再找環(huán)境測試解決方案的可行性。
驗證了方案可行性之后,***在線上安排對應(yīng)的案例演習(xí),確保解決方案是可靠的。最終達到的效果是任何團隊的任何一個成員對照文檔都能處理類似的故障。
極端情況下的預(yù)案
除了常見故障的預(yù)案,我們還應(yīng)當(dāng)思考極端情況下可能出現(xiàn)的故障(雖然可能永遠都用不上),比如數(shù)據(jù)庫主從都掛掉的情況。
***能拉上業(yè)務(wù)和開發(fā)的同學(xué)一起討論,得出可行性的解決辦法,然后找環(huán)境驗證。當(dāng)問題真的出現(xiàn)后,你會比沒有預(yù)案的時候鎮(zhèn)定很多,不至于一臉懵 B。
定期演習(xí)
預(yù)案做好以后***能定期安排演習(xí),開始搞互聯(lián)網(wǎng)金融后有更深的體會,這邊基本每個月都會有常規(guī)的演習(xí)。
定期演習(xí)非常必要,通過演習(xí),將演習(xí)過程中發(fā)現(xiàn)的問題都梳理出來,進行各個擊破,確保各個預(yù)案都能正常工作。
架構(gòu)篇
你是一個合格 DBA 嗎
作為運維 DBA,肯定會接觸到數(shù)據(jù)庫的架構(gòu)和業(yè)務(wù)架構(gòu),之前我們總監(jiān)要求新入職的員工必須對你所要負責(zé)的數(shù)據(jù)庫架構(gòu)進行串講,將不清楚的,不能直接上崗做線上操作。
這個無疑是非常正確的,尤其是在騰訊這種公司,很多后端的邏輯都通過 OSS 進行封裝,導(dǎo)致你能看到的只是 Web 頁面上的各個功能簡單的按鈕。只要輕輕一點,就能將很復(fù)雜的功能完成,這個對于后端邏輯沒有好奇心的人是非常致命的。
出了問題就找開發(fā),導(dǎo)致自己的能力沒有任何的提升,甚至還會在這種點鼠標(biāo)的工作中日益退化。因此在架構(gòu)篇部分其實想和大家聊的是在我們點鼠標(biāo)的同時,還是要深入地去了解點鼠標(biāo)背后發(fā)生的事情,知道異常如何分析和排查。
甚至要再大膽一點,你也可以嘗試著通過 Python 或者 Go 等語言去實現(xiàn)那些背后的邏輯,不要把自己局限在只是一個 OP。
因此我們在做運維的時候,不妨好好的問自己幾個問題:
- 我點了鼠標(biāo)之后,后端都干了什么事情? 需要和哪些服務(wù)交互?
- 如果點完鼠標(biāo)以后,報錯了,需要如何進行排查?需要到哪里看日志?需要如何處理?
問完這兩個問題,更次一點的是找研發(fā)詳細了解里面的運行邏輯,以及部署詳情,日志存放,出現(xiàn)問題如何排查等。更好的辦法,是找研發(fā)要代碼,然后自己去看對應(yīng)按鈕后面代碼的邏輯。
有的同學(xué)會說,我編碼能力差,看不懂。這個不用擔(dān)心,相信我,要基本看懂研發(fā)寫的代碼并沒有那么難,踐行一下你就會知道。等你看完研發(fā)的代碼,估計很快就可以自己寫一個類似的功能出來。
你真的了解線上的架構(gòu)嗎
現(xiàn)在數(shù)據(jù)庫高可用架構(gòu)比較多,不管是單純地使用主從架構(gòu)、MHA、MMM、ndbcluster 或是集成了 LVS、keepalived 等組件,我們都不應(yīng)該僅僅停留在正常情況下會搭建、操作和使用對應(yīng)的架構(gòu)。
更多的是,我們需要更深入的去了解里面運作的機理。就以 MHA 為例,它是如何檢測某一個實例異常的?各個組件之間如何配合?
當(dāng)做切換的時候,MHA 是如何保證數(shù)據(jù)的一致性?如果后端有多臺 slave,它是如何選擇哪一臺從機做切換,并且,其他從機如何處理?
只有深入了解了邏輯之后,再遇到故障和問題,你就能更快速的進行定位,減少對業(yè)務(wù)的影響。此外你還能有針對性的做自動化,讓自己工作更輕松。這么好的事情,為什么不踐行一下?
了解業(yè)務(wù)
還有一個問題,就是作為 DBA 要盡可能的去了解業(yè)務(wù),了解業(yè)務(wù)的讀寫模型,了解業(yè)務(wù)相關(guān)架構(gòu),了解業(yè)務(wù)如何使用數(shù)據(jù)庫。
這樣做的好處是你能針對業(yè)務(wù)的場景給出更好的優(yōu)化建議,出了問題也能快速判斷對業(yè)務(wù)的影響情況。
線上操作篇
DBA 面對線上復(fù)雜的環(huán)境,尤其是面對高并發(fā)的環(huán)境,很容易導(dǎo)致線上故障,下面是整理的十二個容易導(dǎo)致線上故障的操作以及規(guī)避誤操作的技巧,希望能對各位 DBA 有所幫助:
- 修改或刪除數(shù)據(jù)前先備份,先備份,先備份(重要事情說三遍)。
- 線上變更一定要有回退方案。
- 批量操作中間添加 sleep。
- DDL 操作要謹(jǐn)慎,對于大表的 alter 操作***使用 pt-online-schema-change。
- 變更操作先在測試環(huán)境測試。
- 重啟數(shù)據(jù)庫前先刷臟頁。
- 禁止批量刪除大量的 binlog。
- 對于變更操作一定要寫詳細的操作步驟,并 review。
- 按 enter 之前再進行一次環(huán)境確認。
- 如果你的操作可能會使?fàn)顩r變得更糟,請停止操作。
- 快速處理磁盤滿,使用 tune2fs 釋放文件系統(tǒng)保留塊。
- 連接數(shù)滿先修改內(nèi)存變量,而不是重啟,修改方式如下:
- gdb -p pid -ex "set max_connections=1000" -batch#pid是mysqld的對應(yīng)的pid
心態(tài)篇
心細膽大
從某種意義上講,DBA 是一個高危的行業(yè),不是開玩笑,看看下面的截圖就知道:
風(fēng)險本身是個偽***,對于某些人來說是風(fēng)險,但是對于某些人來說其實沒有風(fēng)險。就像醫(yī)生做手術(shù)一樣,我們常人看來就是個非常危險的事情,但是對于醫(yī)生來講,其實并沒有什么風(fēng)險(大部分的手術(shù))。
因此風(fēng)險在于你是否已經(jīng)了解深入,并且做足了功課。這就要求我們在做線上操作之前要心細,有詳細的操作步驟,有詳盡的回滾方案,做完備的測試。
這些做完了以后,你的膽子才能“大”起來,膽大是因為你心中有底,心中有自信。這些自信都是前面你做功課帶給你的。
勇于擔(dān)當(dāng)
出現(xiàn)問題本身并不可怕,可怕的是選擇逃避。我們要做的就是正視問題,吸取教訓(xùn),勇于擔(dān)當(dāng),做好 case study,防止團隊在同一個地方跌倒兩次。
工匠精神
今天看到同事發(fā)的一個朋友圈很有感觸,在沒有人注意的地方也不懈怠、不偷懶的精神,才是真正的工匠精神。
做為 DBA 也同樣非常需要這種精神,對于遺留問題的跟進不能偷懶、對于備份異常的巡檢不能偷懶、對于技術(shù)的積累不能偷懶,工匠精神是我們 DBA 在做日常管理工作不可缺少的精神。
有句話說的是:“我們之所以經(jīng)常犯錯,就是因為我們做的功課不夠”。
如果你有很多功課拉下了,請安排時間逐步補上,要堅信一切都是閑淡中求來,熱鬧中使用。有的事情知道了本身并沒有什么了不起,了不起的是那些堅持踐行的人。踐行起來,你會發(fā)現(xiàn)你的人生從此不同。
張秀云,網(wǎng)名飛鴻無痕,現(xiàn)任職于騰訊,負責(zé)騰訊金融數(shù)據(jù)庫的運維和優(yōu)化工作。2007年開始從事運維方面的工作,經(jīng)歷過網(wǎng)絡(luò)管理員、Linux運維工程師、DBA、分布式存儲運維等多個IT職位。對Linux運維、MySQL數(shù)據(jù)庫、分布式存儲有豐富的經(jīng)驗。