戰(zhàn):存量環(huán)境下的高效運(yùn)維工具集)
1. 為什么這個(gè)過氣工具集還在我的工作臺里前幾天幫一家公司排查主從復(fù)制延遲登上去發(fā)現(xiàn)兩個(gè)庫的表結(jié)構(gòu)因?yàn)殚_發(fā)手工執(zhí)行了N次漏腳本的發(fā)布已經(jīng)悄悄長出了100多處差異。我第一反應(yīng)不是打開某個(gè)運(yùn)維平臺而是打開終端敲了條命令mysqldiff --server1admin10.0.0.10:3306 --server2admin10.0.0.11:3306 \ --difftypesql --changes-file/tmp/schema_diff.sql不到半分鐘128處差異被清清楚楚列出來還生成了可以直接執(zhí)行的變更腳本。這套被我反復(fù)使用的工具就是很多人已經(jīng)不關(guān)注的官方工具集——MySQL Utilities。你可能覺得奇怪這玩意不是停止開發(fā)了網(wǎng)上對它的評價(jià)也兩極分化。但我要說的是對于運(yùn)維手里還捏著MySQL 5.7、甚至5.6存量環(huán)境的人來說它依然是效率極高的瑞士軍刀。今天這篇就是我的實(shí)戰(zhàn)手冊把從安裝、結(jié)構(gòu)比對、數(shù)據(jù)導(dǎo)出導(dǎo)入到復(fù)制、高可用切換、權(quán)限克隆的高頻用法過一次最后附上我這些年踩過的坑。1.1 手工運(yùn)維的重復(fù)勞動有多坑先說我為什么對這套工具執(zhí)念這么深。早些年我管理幾十套MySQL實(shí)例每天干的活無非就是哪兩個(gè)庫結(jié)構(gòu)不一樣肉眼打開兩個(gè)窗口比對字段新環(huán)境要搭從庫手寫CHANGE MASTER那一套要復(fù)制一個(gè)用戶權(quán)限一行行SHOW GRANTS再手工回放。聽起來都不難問題是量大以后全是重復(fù)勞動而且特別容易出錯(cuò)。比如結(jié)構(gòu)比對你肉眼比對字段順序、默認(rèn)值、字符集字符串長一點(diǎn)眼睛直接看花。有一次我把varchar(255)看成varchar(256)上線第一天數(shù)據(jù)就溢出了。數(shù)據(jù)導(dǎo)出如果用mysqldump在多表關(guān)聯(lián)、存儲過程、觸發(fā)器混合的場景下dump出來的文件要么順序不對要么被外鍵約束卡住。權(quán)限復(fù)制就更不用提了一個(gè)賬號十幾個(gè)庫的權(quán)限手抄加引號轉(zhuǎn)義錯(cuò)一個(gè)字符就授權(quán)失敗。MySQL Utilities的設(shè)計(jì)初衷就是把這些高頻操作變成一句命令。你不用再去記那一長串SQL拼接邏輯也不用擔(dān)心中間某一步漏了。雖然它現(xiàn)在的更新已經(jīng)停滯但核心功能在5.7乃至8.0的兼容模式下依然可以工作而且在很多企業(yè)內(nèi)部存量實(shí)例根本輪不到你用新工具那它就是你最順手的搬磚工具。1.2 工具箱全景你會用到的組件MySQL Utilities不是一個(gè)單一命令而是一套Python腳本集合入口是mysqluc。裝好以后你可以直接運(yùn)行mysqluc進(jìn)入它的命令行也可以像普通命令一樣直接調(diào)每個(gè)工具。我用得最多的幾個(gè)工具列個(gè)清單給你參考工具名作用我的使用頻率mysqldiff比對兩個(gè)數(shù)據(jù)庫/兩段SQL的對象差異生成變更腳本每周mysqldbexport導(dǎo)出庫/表數(shù)據(jù)支持SQL和CSV格式每周mysqldbimport導(dǎo)入數(shù)據(jù)能處理依賴順序每周mysqlserverclone從現(xiàn)有實(shí)例克隆出獨(dú)立新實(shí)例每月mysqlreplicate快速配置主從復(fù)制每月mysqlfailover主庫故障自動切換每季度演練mysqluserclone克隆MySQL用戶權(quán)限隨時(shí)mysqlindexcheck檢查表中索引的使用情況每季度mysqlauditgrep過濾解析審計(jì)日志偶爾這些工具的共同點(diǎn)是參數(shù)風(fēng)格統(tǒng)一、有--dry-run預(yù)覽模式、輸出結(jié)果可解析。你在mysqluc里輸入一個(gè)工具名再敲--help基本就能把每個(gè)參數(shù)看明白。別被它的英文文檔勸退實(shí)際用起來比文檔簡單得多。1.3 安裝與初始化從下載到mysqluc能用很多人卡在第一步就是因?yàn)檫@個(gè)工具是基于Python 2的。早先版本需要Python 2.6/2.7系統(tǒng)如果已經(jīng)用Python 3直接跑多半會報(bào)語法錯(cuò)誤。我目前的推薦方案是在專用管理機(jī)上用源碼包安裝不跟業(yè)務(wù)服務(wù)器摻和。以1.6.5版本為例安裝流程大概是這樣的# 下載并解壓源碼包 tar zxf mysql-utilities-1.6.5.tar.gz cd mysql-utilities-1.6.5 # 用python2執(zhí)行安裝管理機(jī)可以保留一個(gè)python2環(huán)境 python2 setup.py install如果你的系統(tǒng)把python指向了3那就要明確調(diào)用python2。裝完以后驗(yàn)證一下:mysqluc --version如果顯示mysqluc 1.6.5這樣的版本信息就說明裝好了。還有一個(gè)常見的坑它默認(rèn)依賴mysql-connector-python。很多人在安裝時(shí)沒有先裝這個(gè)庫導(dǎo)致運(yùn)行任何工具都報(bào)ImportError: No module named mysql.connector。解決辦法一樣用Python 2環(huán)境裝對應(yīng)版本的connector然后確認(rèn)在PYTHONPATH里能找到。另外有些朋友習(xí)慣配合圖形管理工具一起用比如下載安裝dbx數(shù)據(jù)庫管理工具來做連接配置和任務(wù)監(jiān)控。我的建議是dbx這類工具做可視化操作沒問題安裝包從官方渠道拉連接MySQL時(shí)指定--socket或者TCP端口就行。但命令行場景下MySQL Utilities的本事是dbx沒法替你完成的尤其是差異比對和復(fù)制配置。所以兩者目前在我這里是互補(bǔ)狀態(tài)不沖突。2. 結(jié)構(gòu)比對與數(shù)據(jù)導(dǎo)出導(dǎo)入最穩(wěn)的三件套工具裝好以后先掌握最常用的三件套。這三個(gè)工具能覆蓋日常變更上線前的大部分檢查工作。2.1 mysqldiff操作步驟與輸出解讀mysqldiff是我打開率最高的命令。它的核心功能是比較兩個(gè)連接上的對象定義差異包括表結(jié)構(gòu)、視圖、存儲過程、函數(shù)、觸發(fā)器等?;久铋L這樣mysqldiff --server1admin:pass10.0.0.10:3306/db1 \ --server2admin:pass10.0.0.11:3306/db2 \ --difftypesql --changes-file/tmp/db_diff.sql參數(shù)說明里面--server1和--server2除了寫庫名以外還支持db1.tab1這種形式用來比對單表。--difftype支持sql、unified、differ幾種格式。我強(qiáng)烈建議用sql因?yàn)樗敵龅牟盍靠梢灾苯臃诺缴a(chǎn)庫執(zhí)行。--changes-file會把差異SQL寫進(jìn)文件方便你在執(zhí)行前人工Review。這里我特別提醒一點(diǎn)默認(rèn)情況下它只比較對象定義不會比較索引的可見性、統(tǒng)計(jì)信息這些運(yùn)行時(shí)屬性。如果你要連索引一起比加一個(gè)--show-options參數(shù)??匆淮螌?shí)際輸出# Comparing db1 to db2 [PASS] # Definition: Table db1.orders Reversed遇到[FAIL]的文件后面會跟具體的差異片段。有一次它告訴我某個(gè)字段的AUTO_INCREMENT屬性不一致我順著它的輸出去查果然發(fā)現(xiàn)從庫的表是用我三個(gè)月前的老備份恢復(fù)的差了一個(gè)自增計(jì)數(shù)設(shè)置。這種細(xì)節(jié)靠肉眼幾乎查不出來。還有個(gè)小技巧--changes-file生成的是完整ALTER語句但它不會幫你處理依賴順序。所以拿到變更腳本后我習(xí)慣先用dry-run模式跑一遍確認(rèn)沒語法錯(cuò)誤再執(zhí)行mysqldiff --server1admin:pass10.0.0.10:3306/db1 \ --server2admin:pass10.0.0.11:3306/db2 \ --difftypesql --dry-run2.2 mysqldbexport導(dǎo)出的正確姿勢如果說mysqldump是重武器那mysqldbexport就更像給你精細(xì)控制的手術(shù)刀。它可以按庫、按表導(dǎo)出也可以只導(dǎo)出某些對象的數(shù)據(jù)而不導(dǎo)出表結(jié)構(gòu)。我一般這么用mysqldbexport --serveradmin:pass10.0.0.10:3306/db1 \ --formatsql --exportboth --skip-gtid --output-file/tmp/db1_export.sql--formatsql表示輸出SQL文件如果你想拿去做數(shù)據(jù)分析可以改成--formatcsv。--export有多個(gè)值both表示結(jié)構(gòu)加數(shù)據(jù)structure-only是只要結(jié)構(gòu)>mysqldbimport --serveradmin:pass10.0.0.12:3306 \ --formatsql --import-file/tmp/db1_export.sql--formatsql要和導(dǎo)出時(shí)一致。--import-file不指定的話它默認(rèn)讀stdin所以你可以用管道m(xù)ysqldbexport ... --output-file- | mysqldbimport ... --formatsql這里有個(gè)關(guān)鍵參數(shù)是--force默認(rèn)情況下如果目標(biāo)庫已有同名的表它不會覆蓋而是報(bào)錯(cuò)。想要覆蓋導(dǎo)入加--force。但--force使用時(shí)要萬分小心它會直接把目標(biāo)表DROP掉重建。我的習(xí)慣是先備份再導(dǎo)入到臨時(shí)庫驗(yàn)證一次最后才切正式庫。權(quán)限陷阱也是老生長談。目標(biāo)庫的賬號如果只有INSERT、SELECT權(quán)限導(dǎo)入時(shí)建表語句就會被拒絕。所以導(dǎo)入賬號最少需要CREATE、DROP、INSERT、ALTER權(quán)限。你要是用root導(dǎo)入問題不大但生產(chǎn)環(huán)境不建議直接暴露root串在命令行里。可以用--login-path來管理密碼或者設(shè)置好~/.mylogin.cnf這樣命令里不出現(xiàn)明文密碼日志里也不容易泄露。3. 復(fù)制與高可用mysqlreplicate 和 mysqlfailover 的實(shí)戰(zhàn)經(jīng)驗(yàn)搭建主從復(fù)制過去要手動處理七八個(gè)步驟創(chuàng)建復(fù)制賬號、拷貝數(shù)據(jù)、記錄binlog位置、配置server-id、啟動slave……一步錯(cuò)后面全亂。3.1 用 mysqlreplicate 搭建主從復(fù)制如果你已經(jīng)有了一份全新的從庫數(shù)據(jù)mysqlreplicate能做的就是把那些手工步驟都省了。命令大概是這樣的mysqlreplicate --masteradmin:pass10.0.0.10:3306 \ --slaveadmin:pass10.0.0.11:3306 \ --rpl-userrepl:secret --start-slave執(zhí)行過程中它會在主庫創(chuàng)建復(fù)制賬號在從庫設(shè)置CHANGE MASTER TO并自動記錄當(dāng)前的binlog坐標(biāo)。加--start-slave的話它會直接啟動復(fù)制線程。實(shí)測下來只要網(wǎng)絡(luò)連通、server-id不沖突基本一次成功。這里我要強(qiáng)調(diào)一個(gè)隱藏條件它假設(shè)從庫的數(shù)據(jù)已經(jīng)跟主庫一致。如果不一致復(fù)制會在執(zhí)行過程中報(bào)錯(cuò)。所以我的標(biāo)準(zhǔn)流程是三層檢查用mysqldbexport或者別的備份工具把主庫數(shù)據(jù)恢復(fù)到從庫。用mysqldiff核對關(guān)鍵表結(jié)構(gòu)。最后才跑mysqlreplicate。在執(zhí)行前建議先看一遍--dry-run的輸出它會列出將要執(zhí)行的SQL確認(rèn)沒有意外再正式執(zhí)行。如果你要快速搭建從庫還有一個(gè)小兄弟工具叫mysqlserverclone。它可以在一個(gè)MySQL實(shí)例上克隆出一個(gè)新的獨(dú)立實(shí)例端口、數(shù)據(jù)目錄、server-id都可以指定mysqlserverclone --serveradmin:pass10.0.0.10:3306 \ --new-data/data/mysql3307 --new-port3307 \ --new-id3307 --mysqld-options--gtid_modeON這在日常開測試環(huán)境時(shí)簡直是救命工具。以前我建一套隔離測試庫要先裝了MySQL再手動配my.cnf折騰半小時(shí)?,F(xiàn)在一條命令兩分鐘得到一個(gè)端口不同、server-id不同的獨(dú)立實(shí)例。3.2 mysqlfailover 的配置與切換演練再往上一個(gè)層次就是高可用切換。mysqlfailover可以在主庫故障時(shí)自動把某個(gè)從庫提升為新主庫。它支持基于GTID或者binlog位置的復(fù)制拓?fù)洹;九渲檬窍仍谥鲙靻右粋€(gè)持續(xù)監(jiān)控進(jìn)程mysqlfailover --masteradmin:pass10.0.0.10:3306 \ --discover-slaves-loginadmin:pass \ --failover-modeauto --log/var/log/mysqlfailover.log--discover-slaves-login告訴它自動發(fā)現(xiàn)從庫--failover-modeauto表示故障時(shí)自動切換。這個(gè)進(jìn)程要一直跑著所以最好用systemd或supervisor守護(hù)。切換策略一般用--candidateslave2來指定一個(gè)數(shù)據(jù)最新的候選從庫--ping-interval控制心跳頻率比如--ping-interval3就是每3秒探活一次。如果主庫5秒內(nèi)沒有響應(yīng)它就開始選舉。選舉標(biāo)準(zhǔn)不是隨機(jī)的它會比較從庫的日志位置優(yōu)先選最接近主庫的那個(gè)。如果配置了--candidate則優(yōu)先選候選沒有候選選日志最新的從庫。切換完成后它會自動把其他從庫重新指向新主庫。如果擔(dān)心自動切換有風(fēng)險(xiǎn)你可以先把--failover-mode改成manual。這樣它只負(fù)責(zé)監(jiān)控和告警需要你手工確認(rèn)后才切換。我第一次在生產(chǎn)環(huán)境用它的安全方式就是manual先觀察它產(chǎn)生告警是否準(zhǔn)確連續(xù)演練幾次后才敢開auto。3.3 高可用切換的邊界與我的避坑提醒我要潑一盆冷水mysqlfailover又不是萬能的。首先是腦裂問題。這個(gè)工具本身不做防腦裂處理。主庫網(wǎng)絡(luò)閃斷但它自身還活著新的主庫已經(jīng)被選舉出來。如果業(yè)務(wù)流量還往老主庫寫兩個(gè)庫都會寫入新數(shù)據(jù)后續(xù)數(shù)據(jù)合并就非常麻煩。我的規(guī)避手段是在網(wǎng)絡(luò)層面做隔離比如在發(fā)生切換時(shí)立刻用防火墻規(guī)則把老主庫的對外流量禁用或者一切用VIP漂移。VIP配合mysqlfailover切換時(shí)VIP指向新主庫才能相對可靠。其次是日志清理和binlog事件。如果從庫落后主庫太多日志已經(jīng)被purge那么這個(gè)從庫就沒有競選資格。所以高可用環(huán)境里binlog的expire_logs_days配置不能太短。我一般設(shè)置7天同時(shí)搭配定時(shí)全備。最后是應(yīng)用側(cè)連接池。就算MySQL層面切換成功應(yīng)用的長連接還捏著老主庫的IP。如果你不用VIP應(yīng)用側(cè)必須實(shí)現(xiàn)故障重連。這一點(diǎn)在演練前一定要和開發(fā)團(tuán)隊(duì)確認(rèn)清楚不要等到真故障了才想起來改連接串。4. 日常巡檢、壓測與權(quán)限治理不止 DBA 能用MySQL Utilities的價(jià)值不只在緊急排障日常巡檢和上線前評估同樣能幫你省下大把時(shí)間。4.1 mysqlcheck / mysqlindexcheck 的巡檢組合mysqlcheck是MySQL自帶的表維護(hù)工具可以和mysqlindexcheck搭配來做巡檢。但我要重點(diǎn)說mysqlindexcheck因?yàn)樗軝z查冗余索引和未使用索引這屬于很多DBA容易忽略的隱性浪費(fèi)。用法很簡單mysqlindexcheck --serveradmin:pass10.0.0.10:3306/db1 \ --show-indexes --show-drops它會列出每個(gè)表的索引詳情并給出建議刪除的重復(fù)索引。比如一個(gè)字段a上既有單列索引又有(a,b)復(fù)合索引它會把單列索引標(biāo)成冗余。刪掉冗余索引之后寫入性能能明顯提升。這個(gè)工具只分析索引定義不會真的去執(zhí)行DROP INDEX所以你可以放心跑。我一般每季度跑一次把輸出交給開發(fā)確認(rèn)后再決定要不要?jiǎng)h。實(shí)測在我們的訂單庫中一次巡檢發(fā)現(xiàn)三個(gè)冗余索引刪除后寫入響應(yīng)時(shí)間平均降了12%。不過這個(gè)數(shù)據(jù)因環(huán)境而異但方向是對的。4.2 壓測組合mysqlslap 與 mysqladmin 配合很多人不知道m(xù)ysqlslap就是MySQL自帶的一個(gè)壓力測試工具。它模擬客戶端負(fù)載幫你快速確認(rèn)一個(gè)庫能扛住多大的并發(fā)。最簡單的用法mysqlslap --concurrency50 --iterations3 \ --number-of-queries1000 --create-schematest \ --querySELECT * FROM orders WHERE user_id12345 \ --host10.0.0.10 --useradmin --password***它會自動造一個(gè)測試表壓測完后自動清理。壓測的時(shí)候我同時(shí)在另一個(gè)終端跑mysqladmin status和mysqladmin extended-status來觀測線程數(shù)、請求隊(duì)列長度。比如mysqladmin --host10.0.0.10 --useradmin -p status輸出里的Threads、Questions、Connections是重點(diǎn)指標(biāo)。如果線程數(shù)快速上漲但Questions漲不動說明有鎖等待。這時(shí)候配合SHOW ENGINE INNODB STATUS\G看鎖信息基本能定位到瓶頸。需要提醒的是mysqlslap的壓測結(jié)果只能做相對參考。它產(chǎn)生的負(fù)載和真實(shí)業(yè)務(wù)差得很遠(yuǎn)真實(shí)業(yè)務(wù)有讀寫混合、有隨機(jī)分布、有事務(wù)提交頻率所以要拿它來定容量上限是不嚴(yán)謹(jǐn)?shù)?。我更推薦用它來做上線前冒煙比如確認(rèn)新索引有沒有帶來明顯副作用或者新從庫能否扛住基礎(chǔ)流量。4.3 mysqluserclone權(quán)限克隆的正確用法最后這個(gè)工具我做強(qiáng)推mysqluserclone。它可以一鍵把一個(gè)用戶的所有權(quán)限克隆到另一個(gè)新用戶身上。比如要?jiǎng)?chuàng)建一個(gè)和app_rw權(quán)限完全一樣的賬號app_rw_backupmysqluserclone --serveradmin:pass10.0.0.10:3306 \ app_rw app_rw_backup它會把原用戶的全局權(quán)限、庫級權(quán)限、表級權(quán)限都復(fù)制過去。相比手工SHOW GRANTS再重放至少節(jié)省了90%的時(shí)間而且不容易漏掉授權(quán)范圍。要注意的一點(diǎn)這個(gè)工具復(fù)制不了密碼本身的功能。它能克隆權(quán)限結(jié)構(gòu)但不會把原用戶的密碼hash復(fù)制過去。你需要為新用戶單獨(dú)設(shè)置密碼ALTER USER app_rw_backup% IDENTIFIED BY 新密碼;這個(gè)特性反而讓我覺得安全因?yàn)樾沦~號密碼必然要經(jīng)過一個(gè)人工設(shè)置的過程不會出現(xiàn)兩個(gè)賬號用同一套密碼的隱患。還有一個(gè)小場景應(yīng)用從一臺庫遷到另一臺庫應(yīng)用賬號也要跟著遷。你可以先用mysqldbexport把整個(gè)權(quán)限相關(guān)的庫導(dǎo)出再在目標(biāo)端導(dǎo)入。但賬號密碼的密文在mysql.user表里導(dǎo)出時(shí)有時(shí)候會變動所以我更傾向于直接用mysqluserclone在主庫克隆再在目標(biāo)端創(chuàng)建相同的賬號。效率實(shí)測下來比導(dǎo)入導(dǎo)出干凈得多。5. 我踩過的坑和現(xiàn)在的工作流工具再好只講命令不講坑等于沒講。這部分我把個(gè)人踩坑經(jīng)歷整理出來希望能給你省下幾晚加班。5.1 常見報(bào)錯(cuò)對照表下面的表是按我實(shí)際的經(jīng)歷整理出來的附帶解決思路。報(bào)錯(cuò)/現(xiàn)象原因解決辦法ImportError: No module named mysql.connector缺少mysql-connector-python用Python2環(huán)境安裝connector確認(rèn)PYTHONPATHUnable to retrieve server information連接賬號權(quán)限不足給賬號加SELECT、RELOAD等權(quán)限或使用rootERROR 2013 (HY000): Lost connection連接超時(shí)或keepalive斷開執(zhí)行前加--connect-timeout120網(wǎng)絡(luò)不穩(wěn)時(shí)重試mysqldiff提示對象不存在server參數(shù)寫錯(cuò)庫名或者沒加--pattern檢查--server1db的庫名表級別比對要寫db.table導(dǎo)入時(shí)報(bào)外鍵約束錯(cuò)誤表導(dǎo)入順序不對導(dǎo)入前臨時(shí)SET FOREIGN_KEY_CHECKS0或者按依賴排序切換后應(yīng)用連不上應(yīng)用長連接沒有重連機(jī)制使用VIP或者在應(yīng)用側(cè)啟用連接探活復(fù)制的從庫掉線無法自動續(xù)傳網(wǎng)絡(luò)閃斷導(dǎo)致IO線程停止START SLAVE;查看Last_IO_Errno修復(fù)網(wǎng)絡(luò)后重新START5.2 我的生產(chǎn)工作流現(xiàn)在我的常規(guī)變更都是這樣走的第一步變更前做結(jié)構(gòu)比對。只要涉及表結(jié)構(gòu)變更先跑mysqldiff生成變更腳本作為評審依據(jù)。第二步變更后做數(shù)據(jù)校驗(yàn)。涉及數(shù)據(jù)遷移就用mysqldbexport mysqldbimport并在遷移前后分別做行數(shù)統(tǒng)計(jì)。行數(shù)統(tǒng)計(jì)我直接用SQL幾條簡單的SELECT COUNT(*)就夠了。第三步重要實(shí)例的復(fù)制變化用mysqlreplicate重新配置。配置后觀察SHOW SLAVE STATUS確認(rèn)沒有報(bào)錯(cuò)。第四步每季度固定做一次mysqlindexcheck巡檢和mysqlslap壓測。這兩個(gè)命令我會寫進(jìn)cronjob輸出保存到文件方便歷史對比。第五步高可用每周做一次切換演練。不是真的把主庫停機(jī)而是用--failover-modemanual觸發(fā)一次計(jì)劃內(nèi)切換觀察日志和VIP漂移情況。這比出問題后再臨時(shí)演練可靠得多。5.3 維護(hù)現(xiàn)狀與替代方案我不得不承認(rèn)MySQL Utilities的官方維護(hù)確實(shí)停止了最后的1.6.5版本也是多年前的產(chǎn)物。它和新版MySQL 8.0的部分特性存在兼容性風(fēng)險(xiǎn)尤其是GTID、權(quán)限模型、密碼插件等深度集成的地方。所以如果你管理的全是MySQL 8.0環(huán)境我會建議用Oracle官方推廣的MySQL Shell和它的AdminAPI來替代一部分功能特別是復(fù)制和高可用場景。但如果你和我一樣手頭還有相當(dāng)比例的5.7實(shí)例MySQL Utilities依然是成本最低、最省事的方案。它不需要額外裝agent不需要升級業(yè)務(wù)側(cè)代碼命令行一敲就能用。另外一個(gè)趨勢是使用MySQL Enterprise Monitor或開源的Prometheusmysqld_exporter做監(jiān)控告警工具集則逐漸退居二線變成變更輔助工具。這其實(shí)是個(gè)好分工監(jiān)控交給新體系變更操作繼續(xù)用這些老伙計(jì)。畢竟它們足夠小、足夠快沒有花里胡哨的依賴。說實(shí)話這么多年過去了MySQL Utilities已經(jīng)不是我每天必開的工具但每當(dāng)我需要快速做一個(gè)結(jié)構(gòu)比對或者臨時(shí)搭一個(gè)從庫測試環(huán)境第一個(gè)想到的還是它。這也解釋了為什么它還在我的工作臺里占著一席之地。工具的價(jià)值不在于新不新而在于能不能穩(wěn)定解決你手頭的問題。與其追逐每個(gè)新工具不如把手上的這組命令吃透在關(guān)鍵時(shí)刻能頂上去就夠了。