戰(zhàn)指南:從 root 認(rèn)證到遠(yuǎn)程訪問)
做運(yùn)維這幾年在能在 Ubuntu 22.04 上裝 MySQL 的機(jī)會(huì)沒有一百也有八十次了。我真正把這套流程吃透是在連續(xù)三次幫別人收拾裝完就跑不起來(lái)的服務(wù)器之后——那幾臺(tái)機(jī)器都是系統(tǒng)剛裝好MySQL 安裝過(guò)程毫無(wú)波瀾結(jié)果要么 root 密碼怎么試都進(jìn)不去要么遠(yuǎn)程連不上要么建好的表插進(jìn)去的中文全是問號(hào)。問題從來(lái)不在安裝命令本身而在安裝之后那一堆需要懂原理才能做對(duì)的配置。這篇就寫我在 ubuntu22.04 上安裝和配置 mysql 的完整記錄從 apt 安裝、root 認(rèn)證、字符集、時(shí)區(qū)、遠(yuǎn)程訪問到幾個(gè)我真實(shí)踩過(guò)的坑整理成一份可以直接照著做的實(shí)操教程。如果你手頭有一臺(tái)剛裝好的 Ubuntu 22.04 服務(wù)器或者想在本地虛擬機(jī)里搭一套 MySQL 環(huán)境做開發(fā)測(cè)試照著這篇文章走完基本不會(huì)出大問題。1. 動(dòng)手之前先摸清底細(xì)版本、路線和系統(tǒng)狀態(tài)1.1 Ubuntu 22.04 官源里的 MySQL 8.0 到底能不能用Ubuntu 22.04 的官方軟件源默認(rèn)提供 MySQL 8.0.x注意不是 5.7也不是 MariaDB。我見過(guò)不少人在這一步就猶豫覺得官方源版本不夠新非要去裝 8.2、8.3 之類的版本。我的建議是除非有明確需求否則直接用發(fā)行版?zhèn)}庫(kù)里的版本。原因是 Ubuntu 打包的 MySQL 會(huì)跟著系統(tǒng)一起做測(cè)試和 systemd 服務(wù)腳本、AppArmor 配置、日志輪轉(zhuǎn)策略都是配套好的。裝完以后服務(wù)怎么啟動(dòng)、日志寫到哪、權(quán)限策略長(zhǎng)什么樣全部是開箱即用的狀態(tài)。從官方 APT 倉(cāng)庫(kù)裝的版本可能確實(shí)更新但你需要自己維護(hù)源地址和 GPG 密鑰還要承受升級(jí)時(shí)配置差異帶來(lái)的風(fēng)險(xiǎn)。確認(rèn)版本信息很簡(jiǎn)單安裝之前先執(zhí)行sudo apt update apt-cache policy mysql-server裝完以后看實(shí)際版本mysql --version我手頭一臺(tái)服務(wù)器裝完以后輸出的是mysql Ver 8.0.35-0ubuntu0.22.04.1作為長(zhǎng)期運(yùn)行的數(shù)據(jù)庫(kù)服務(wù)器這個(gè)版本完全夠用。1.2 三種安裝方式怎么選apt、官方 APT 倉(cāng)庫(kù)、源碼編譯把三種方式擺在一起對(duì)比會(huì)更直觀安裝方式優(yōu)點(diǎn)缺點(diǎn)適合場(chǎng)景apt發(fā)行版源最省事與系統(tǒng)集成好升級(jí)隨系統(tǒng)大版本走小版本更新滯后絕大多數(shù)生產(chǎn)與開發(fā)環(huán)境官方 APT 倉(cāng)庫(kù)版本新補(bǔ)丁及時(shí)安全修復(fù)快需要自己配源、管密鑰升級(jí)時(shí)可能有配置差異對(duì)版本有強(qiáng)需求或合規(guī)要求高的環(huán)境源碼編譯定制化強(qiáng)可以自定義編譯參數(shù)編譯慢、依賴多、后期維護(hù)成本極高極少見通常是被迫選擇普通項(xiàng)目用第一種就夠了。即使你真的需要新版本我也建議走官方 APT 倉(cāng)庫(kù)而不是源碼編譯。源碼編譯 MySQL 的坑實(shí)在太多依賴庫(kù)版本沖突、Boost 版本要求、編譯參數(shù)錯(cuò)誤導(dǎo)致性能下降而且后續(xù)每次更新都要重新編譯一遍沒有任何運(yùn)維收益。1.3 準(zhǔn)備階段必做的三件小事安裝之前我習(xí)慣順手做三件事sudo apt update df -h sudo ss -tlnp | grep 3306第一件保證軟件源索引是新的避免 apt 拉到過(guò)時(shí)的元數(shù)據(jù)第二件確認(rèn)磁盤還有充足空間MySQL 8.0 安裝后數(shù)據(jù)目錄加上日志至少預(yù)留幾個(gè) GB磁盤寫滿會(huì)導(dǎo)致初始化失敗第三件確認(rèn) 3306 端口還沒被占用如果機(jī)器上已經(jīng)跑了別的服務(wù)占用這個(gè)端口后續(xù)啟動(dòng)會(huì)直接沖突。這些檢查聽起來(lái)很基礎(chǔ)但我每次裝都做節(jié)省了不少裝完莫名其妙起不來(lái)的排查時(shí)間。尤其是ss那條曾經(jīng)救過(guò)我一次——那臺(tái)機(jī)器上有個(gè)殘留的容器端口映射占著 3306安裝一切正常服務(wù)就是起不來(lái)提前確認(rèn)就能一眼定位。2. 從零到跑起來(lái)apt 裝完后要做的幾件事2.1 一條命令裝完但裝完要看的不只是安裝成功實(shí)際安裝只需要一條命令sudo apt install -y mysql-server執(zhí)行過(guò)程中 apt 會(huì)拉取 mysql-server、mysql-client 以及一系列運(yùn)行時(shí)依賴。如果系統(tǒng)里之前殘留過(guò)別的 MySQL 相關(guān)包apt 可能會(huì)提示你是否替換這時(shí)建議看清楚再回車不要一路 Y。裝完以后第一件事不是急著建庫(kù)而是看一眼服務(wù)狀態(tài)sudo systemctl status mysql正常狀態(tài)是active (running)。如果這里就報(bào)錯(cuò)直接跳到文末第 6 節(jié)看排查路線不要繼續(xù)往下走后面所有操作都依賴一個(gè)能正常啟動(dòng)的 MySQL 實(shí)例。2.2 讓 MySQL 開機(jī)自啟并確認(rèn) 3306Ubuntu 的 mysql-server 包在安裝時(shí)會(huì)自動(dòng)把 MySQL 注冊(cè)為 systemd 服務(wù)。這里建議主動(dòng)執(zhí)行一次sudo systemctl enable mysql sudo systemctl start mysql然后確認(rèn)監(jiān)聽端口和開機(jī)自啟狀態(tài)sudo ss -tlnp | grep 3306 sudo systemctl is-enabled mysql兩條輸出分別說(shuō)明 3306 端口正在被 mysqld 監(jiān)聽、MySQL 服務(wù)已加入開機(jī)自啟列表。這里有個(gè)重點(diǎn)默認(rèn)情況下 MySQL 只監(jiān)聽127.0.0.1即只允許本機(jī)連接。這個(gè)特性會(huì)在第 5 節(jié)詳細(xì)展開你現(xiàn)在只需要記住裝完默認(rèn)狀態(tài)是本機(jī)可用、外部不可達(dá)。2.3 初次進(jìn)入 MySQL 后建議做的事現(xiàn)在用無(wú)密碼方式登錄sudo mysql -u root看到mysql提示符就代表一切正常。建議此時(shí)至少執(zhí)行兩條命令SHOW DATABASES; SELECT user, host, plugin FROM mysql.user;第一條會(huì)列出默認(rèn)數(shù)據(jù)庫(kù)information_schema、mysql、performance_schema、sys。第二條用來(lái)查看用戶列表重點(diǎn)關(guān)注rootlocalhost那一行對(duì)應(yīng)的plugin值后面第 3 節(jié)會(huì)用到。這里順便多說(shuō)一句如果之后你用某個(gè)開發(fā)框架初始化數(shù)據(jù)庫(kù)時(shí)報(bào)錯(cuò)無(wú)法創(chuàng)建數(shù)據(jù)庫(kù)多半就是賬號(hào)權(quán)限不夠。你需要回到這里用 root 執(zhí)行GRANT給業(yè)務(wù)賬號(hào)授權(quán)而不是去修改 MySQL 的底層權(quán)限表——直接改 mysql.user 表是反模式很容易把系統(tǒng)搞壞。3. root 賬號(hào)的認(rèn)證機(jī)制為什么默認(rèn)只能用 sudo mysql 進(jìn)3.1 auth_socket 的工作方式和設(shè)計(jì)初衷如果你剛裝完就執(zhí)行mysql -u root -p會(huì)被告知密碼錯(cuò)誤。這不代表你漏設(shè)了密碼而是 rootlocalhost 用的認(rèn)證插件是auth_socket。auth_socket不校驗(yàn)密碼它只校驗(yàn)兩件事連接方式是不是本地 Unix socket以及發(fā)起連接的進(jìn)程是不是以系統(tǒng) root 身份運(yùn)行。換句話說(shuō)只要你能拿到系統(tǒng)的 root 權(quán)限在本地執(zhí)行sudo mysql就能直接進(jìn) MySQL root密碼形同虛設(shè)。這個(gè)設(shè)計(jì)有它的道理Ubuntu 的思路是MySQL 的 root 應(yīng)該由系統(tǒng)的 root 來(lái)管你要用 MySQL 做業(yè)務(wù)就去建自己的業(yè)務(wù)賬號(hào)。對(duì)不少開發(fā)者來(lái)說(shuō)這有點(diǎn)繞把 root 改成密碼登錄更順手所以接下來(lái)要做的就是改認(rèn)證方式。3.2 改成密碼登錄的正確姿勢(shì)用前面說(shuō)的sudo mysql -u root方式進(jìn)入后執(zhí)行ALTER USER rootlocalhost IDENTIFIED WITH caching_sha2_password BY 你的強(qiáng)密碼;或者更簡(jiǎn)潔一點(diǎn)ALTER USER rootlocalhost IDENTIFIED BY 你的強(qiáng)密碼;默認(rèn)認(rèn)證插件是caching_sha2_password這是 MySQL 8.0 的默認(rèn)項(xiàng)安全性比老式的mysql_native_password更高。不過(guò)要注意如果以后有一個(gè)非常老的客戶端連過(guò)來(lái)不認(rèn)這個(gè)插件可以暫時(shí)給對(duì)應(yīng)賬號(hào)指定mysql_native_password但這個(gè)插件在 8.0.34 開始已經(jīng)被標(biāo)記為廢棄只能作為過(guò)渡手段。改完之后有一件事必須記住以后 root 也需要密碼才能進(jìn)入包括本機(jī)sudo mysql也無(wú)法直接繞過(guò)。我見過(guò)好幾個(gè)同事改完密碼隨手一放過(guò)兩天忘了最后只能走skip-grant-tables的恢復(fù)流程非常折騰。所以改之前先確認(rèn)密碼已經(jīng)記在安全的地方。3.3 mysql_secure_installation 加固流程逐項(xiàng)說(shuō)明改完密碼后建議立刻跑一遍官方加固腳本sudo mysql_secure_installation腳本會(huì)依次詢問幾個(gè)問題我按推薦答案逐項(xiàng)說(shuō)是否配置密碼強(qiáng)度校驗(yàn)組件VALIDATE PASSWORD COMPONENT——開發(fā)環(huán)境可以選 N正式環(huán)境建議選 Y。選 Y 后還會(huì)讓你選強(qiáng)度等級(jí) 0/1/2一般選 1 級(jí)就夠。是否為 root 設(shè)置密碼——如果你在前面已經(jīng)改過(guò)這里會(huì)要求輸入當(dāng)前密碼。是否移除匿名用戶——選 Y。殘留的匿名賬號(hào)會(huì)帶來(lái)權(quán)限混亂具體見第 6 節(jié)。是否禁止 root 遠(yuǎn)程登錄——選 Y。遠(yuǎn)程連接要單獨(dú)建用戶不要開 root 遠(yuǎn)程。是否刪除 test 數(shù)據(jù)庫(kù)——選 Y。默認(rèn) test 庫(kù)沒有任何權(quán)限限制留著沒有好處。是否立即刷新權(quán)限表——選 Y。這一套流程跑完一個(gè)相對(duì)干凈的基礎(chǔ)環(huán)境就出來(lái)了。很多人裝完 MySQL 直接開始建庫(kù)跳過(guò)加固腳本后面遇到的很多詭異問題其實(shí)都能在這個(gè)腳本里避免。4. 字符集、排序規(guī)則和時(shí)區(qū)讓數(shù)據(jù)庫(kù)說(shuō)中文4.1 為什么是 utf8mb4 而不是 utf8MySQL 里的utf8其實(shí)不是大家理解的 UTF-8它最多只支持 3 字節(jié)字符官方文檔叫它utf8mb3。表情符號(hào)、部分生僻漢字、擴(kuò)展區(qū)字符都需要 4 字節(jié)編碼存進(jìn) utf8 字段要么報(bào)錯(cuò)要么變成問號(hào)。utf8mb4才是完整的 UTF-8 編碼。MySQL 8.0 默認(rèn)字符集已經(jīng)改成 utf8mb4但如果你是從舊版本遷移過(guò)來(lái)的環(huán)境服務(wù)器變量很可能還停留在舊值。裝完以后用這條 SQL 看一眼SHOW VARIABLES LIKE character_set_server;如果看到的不是 utf8mb4就要在配置層面統(tǒng)一改掉。排序規(guī)則方面8.0 默認(rèn)是utf8mb4_0900_ai_ci我自己的習(xí)慣是新環(huán)境直接用默認(rèn)值但如果你要從 5.7 遷移庫(kù)可以用utf8mb4_unicode_ci它在舊版本里就存在兼容性更好。4.2 修改配置文件讓全局默認(rèn)生效Ubuntu 上 MySQL 的主配置是/etc/mysql/my.cnf它通過(guò) include 加載/etc/mysql/conf.d/和/etc/mysql/mysql.conf.d/下的文件。服務(wù)端配置真正存放的位置是/etc/mysql/mysql.conf.d/mysqld.cnf。編輯這個(gè)文件在[mysqld]段下加入[mysqld] character-set-server utf8mb4 collation-server utf8mb4_unicode_ci然后重啟sudo systemctl restart mysql重啟后再次確認(rèn)SHOW VARIABLES LIKE character_set%; SHOW VARIABLES LIKE collation%;這里有個(gè)細(xì)節(jié)非常容易踩服務(wù)端字符集改了但客戶端連接時(shí)的character_set_client可能還是舊的。為了讓 mysql 命令行客戶端也統(tǒng)一可以新建一個(gè)/etc/mysql/conf.d/charset.cnf[client] default-character-set utf8mb4服務(wù)端、數(shù)據(jù)庫(kù)、客戶端三層字符集全部統(tǒng)一后中文亂碼問題基本就根治了。我之前幫人排查過(guò)一個(gè)亂碼問題服務(wù)端和庫(kù)都改成 utf8mb4 了亂碼依舊最后發(fā)現(xiàn)就是客戶端連接參數(shù)沒帶上字符集設(shè)置——服務(wù)端改得再對(duì)客戶端以 latin1 連進(jìn)來(lái)照樣是問號(hào)。4.3 已經(jīng)建好的老庫(kù)老表怎么補(bǔ)救如果你在改配置之前就已經(jīng)建庫(kù)建表光改全局配置不會(huì)影響已有對(duì)象庫(kù)和表要單獨(dú)改ALTER DATABASE 你的庫(kù)名 CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci; ALTER TABLE 你的表名 CONVERT TO CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;注意這里的區(qū)別CONVERT TO會(huì)重建表并轉(zhuǎn)換已有列的數(shù)據(jù)大表可能需要很長(zhǎng)時(shí)間還會(huì)產(chǎn)生鎖競(jìng)爭(zhēng)盡量放在維護(hù)窗口執(zhí)行。如果只想改表的默認(rèn)字符集、不動(dòng)已有列的數(shù)據(jù)用ALTER TABLE ... DEFAULT CHARACTER SET utf8mb4就行。{% hint styleinfo %} 判斷一個(gè)表當(dāng)前到底是什么字符集用SHOW CREATE TABLE 表名;輸出的DEFAULT CHARSET位置就是答案。 {% endhint %}4.4 時(shí)區(qū)設(shè)置比你想的更影響業(yè)務(wù)代碼默認(rèn)情況下 MySQL 8.0 的時(shí)區(qū)跟隨系統(tǒng)的時(shí)區(qū)設(shè)置。如果服務(wù)器是 UTC 時(shí)區(qū)業(yè)務(wù)在北京時(shí)間上午 9 點(diǎn)寫入數(shù)據(jù)SELECT NOW()出來(lái)的時(shí)間會(huì)比預(yù)期晚 8 小時(shí)這個(gè)坑非常隱蔽——應(yīng)用日志看起來(lái)時(shí)間正常數(shù)據(jù)庫(kù)里查出來(lái)卻對(duì)不上。處理辦法是在[mysqld]段加入default-time-zone 08:00重啟后用SELECT NOW();驗(yàn)證。如果想用帶名字的時(shí)區(qū)比如Asia/Shanghai需要先把系統(tǒng)時(shí)區(qū)表導(dǎo)入 MySQLmysql_tzinfo_to_sql /usr/share/zoneinfo | sudo mysql mysql這條命令在生產(chǎn)環(huán)境要謹(jǐn)慎執(zhí)行因?yàn)樗鼤?huì)把大量時(shí)區(qū)數(shù)據(jù)寫進(jìn) mysql 系統(tǒng)庫(kù)。多數(shù)場(chǎng)景下直接寫固定偏移量就足夠了簡(jiǎn)單直接還沒有額外開銷。5. 遠(yuǎn)程訪問的完整鏈路bind-address、防火墻和專用賬號(hào)5.1 默認(rèn)只聽 127.0.0.1到底為什么回到前面說(shuō)的默認(rèn)只監(jiān)聽本地。打開/etc/mysql/mysql.conf.d/mysqld.cnf能看到這一行bind-address 127.0.0.1bind-address決定 mysqld 監(jiān)聽哪個(gè)網(wǎng)絡(luò)接口。127.0.0.1表示只允許本機(jī)回環(huán)接口連接安全性最好但其他機(jī)器完全無(wú)法訪問。需要遠(yuǎn)程連接時(shí)有兩種改法改成0.0.0.0監(jiān)聽所有網(wǎng)卡或者改成內(nèi)網(wǎng) IP比如10.0.0.8只監(jiān)聽特定網(wǎng)卡。我自己的習(xí)慣是盡量用具體 IP避免把服務(wù)暴露到不必要的網(wǎng)段。改完同樣要重啟然后用ss驗(yàn)證sudo ss -tlnp | grep 33065.2 修改監(jiān)聽并放行防火墻監(jiān)聽地址改完后還要過(guò)防火墻這一關(guān)。Ubuntu 自帶 UFW執(zhí)行sudo ufw allow 3306/tcp sudo ufw status如果部署在云服務(wù)器上記得同時(shí)檢查安全組的入方向規(guī)則。我見過(guò)很多案例本地防火墻開了、云安全組沒放行導(dǎo)致從公網(wǎng)怎么都連不上。兩地都要檢查缺一個(gè)就通不了。5.3 創(chuàng)建業(yè)務(wù)專用賬號(hào)別把 root 暴露出去遠(yuǎn)程連接我強(qiáng)烈不建議直接用 root哪怕只在公司內(nèi)網(wǎng)使用。正確做法是建一個(gè)只擁有所需權(quán)限的業(yè)務(wù)賬號(hào)CREATE USER app_user192.168.1.% IDENTIFIED BY 另一個(gè)強(qiáng)密碼; GRANT SELECT, INSERT, UPDATE, DELETE ON 你的庫(kù).* TO app_user192.168.1.%; FLUSH PRIVILEGES;賬號(hào)名后面的主機(jī)部分是重點(diǎn)。192.168.1.%表示只允許這個(gè)網(wǎng)段連接10.0.0.5精確匹配單個(gè) IP%表示任意主機(jī)能用但也最危險(xiǎn)。其實(shí)在 MySQL 8.0 里CREATE USER和GRANT執(zhí)行后權(quán)限會(huì)自動(dòng)生效不需要FLUSH PRIVILEGES——這個(gè)命令只有在你直接修改了 mysql.user 表時(shí)才需要。寫了當(dāng)然無(wú)害但也別指望它能解決權(quán)限不生效的問題。還有一個(gè)隱藏坑如果開啟了skip_name_resolveMySQL 不會(huì)反查客戶端域名所有按主機(jī)名匹配的賬號(hào)都會(huì)失效。所以生產(chǎn)環(huán)境統(tǒng)一用 IP 段做主機(jī)匹配別寫域名。最后說(shuō)一個(gè)和 MySQL 8.0 有關(guān)的小細(xì)節(jié)默認(rèn)還開啟了 33060 端口供 MySQL Shell 的 X Protocol 使用。如果你用 MySQL Shell 遠(yuǎn)程管理要記得在防火墻放行這個(gè)端口否則會(huì)出現(xiàn)3306 能連但 Shell 連不上的詭異現(xiàn)象。6. 部署后踩過(guò)的坑四個(gè)高頻問題的排查實(shí)錄6.1 AppArmor 攔住了自定義數(shù)據(jù)目錄有人不想把數(shù)據(jù)放在/var/lib/mysql想挪到/data/mysql。改了datadir之后啟動(dòng)服務(wù)會(huì)直接失敗錯(cuò)誤日志里寫著權(quán)限不足。這不是文件權(quán)限問題而是 AppArmor 在攔截。Ubuntu 自帶一套針對(duì) mysqld 的 AppArmor 策略只允許 mysqld 訪問/var/lib/mysql等預(yù)設(shè)路徑自定義目錄不在白名單里。解決思路有兩條。第一條是修改 AppArmor 配置文件編輯/etc/apparmor.d/usr.sbin.mysqld加上一行alias /var/lib/mysql/ - /data/mysql/,保存后重載sudo apparmor_parser -r /etc/apparmor.d/usr.sbin.mysqld第二條是我現(xiàn)在更推薦的做法不改 datadir而是在/var/lib/mysql路徑上掛載一塊新磁盤或分區(qū)。這樣既不會(huì)觸發(fā) AppArmor也完全不需要改 MySQL 配置后續(xù)磁盤擴(kuò)容也更靈活。數(shù)據(jù)目錄遷移這件事能不碰配置就別碰配置。6.2 老業(yè)務(wù)連不上 8.0caching_sha2_password 兼容性處理MySQL 8.0 默認(rèn)認(rèn)證插件改成caching_sha2_password之后客戶端驅(qū)動(dòng)跟不上就會(huì)出現(xiàn)這類報(bào)錯(cuò)Authentication plugin caching_sha2_password cannot be loaded。常見于比較老的 PHP mysqlnd、舊版 JDBC 驅(qū)動(dòng)、某些低版本的 Go 驅(qū)動(dòng)。最推薦的解法是升級(jí)客戶端驅(qū)動(dòng)庫(kù)這比在數(shù)據(jù)庫(kù)層面做兼容要徹底得多。如果業(yè)務(wù)暫時(shí)不能動(dòng)可以給這個(gè)老客戶端單獨(dú)建一個(gè)兼容賬號(hào)過(guò)渡CREATE USER legacy_app% IDENTIFIED WITH mysql_native_password BY 密碼; GRANT 需要的權(quán)限 ON 你的庫(kù).* TO legacy_app%;注意mysql_native_password在 8.0.34 開始被標(biāo)記為廢棄只適合作為過(guò)渡方案別把它當(dāng)成長(zhǎng)期配置。如果你發(fā)現(xiàn)新裝的 MySQL 里caching_sha2_password連不上的問題反復(fù)出現(xiàn)優(yōu)先從客戶端版本入手而不是把服務(wù)端認(rèn)證方式降級(jí)。6.3 anonymous user 導(dǎo)致 root 密碼白設(shè)有個(gè)很隱蔽的問題root 密碼明明改對(duì)了從本機(jī)用密碼登錄仍然被拒絕。查了一圈發(fā)現(xiàn)問題出在殘留的匿名賬號(hào)上。MySQL 匹配用戶時(shí)有一套優(yōu)先級(jí)規(guī)則匿名用戶在某些連接場(chǎng)景下會(huì)先被匹配到連接就被導(dǎo)向了一個(gè)你不知道的賬號(hào)自然提示 access denied。檢查方法SELECT user, host, plugin FROM mysql.user;看到 user 為空字符串的行就是匿名用戶。直接刪掉DROP USER localhost;這也解釋了為什么mysql_secure_installation里那個(gè)是否移除匿名用戶的問題值得選 Y。跳過(guò)這一步的人早晚要在這上面吃一次虧而且排查成本遠(yuǎn)高于按一次 Y 的成本。6.4 服務(wù)起不來(lái)的通用排查路線最后列一個(gè)通用的排查流程。MySQL 服務(wù)起不來(lái)時(shí)第一步永遠(yuǎn)不是改配置而是看日志systemctl status mysql journalctl -u mysql --no-pager -n 50 tail -n 100 /var/log/mysql/error.logUbuntu 上 MySQL 的錯(cuò)誤日志默認(rèn)在/var/log/mysql/error.log但具體路徑要看log_error參數(shù)指向哪里。日志位置不對(duì)可以用SHOW VARIABLES LIKE log_error;確認(rèn)。常見原因和處理動(dòng)作見下表報(bào)錯(cuò)/現(xiàn)象最常見的原因優(yōu)先處理動(dòng)作Job for mysql.service failed配置語(yǔ)法錯(cuò)誤、datadir 權(quán)限不對(duì)看 error.log檢查/var/lib/mysql屬主是否為 mysql:mysqlCant connect to local MySQL server through socket服務(wù)沒啟動(dòng)或 socket 目錄不可寫重啟服務(wù)確認(rèn)/var/run/mysqld存在且屬主正確The table ... is full磁盤滿df -h查看清理或擴(kuò)容AppArmor ... denied自定義路徑未加入策略按 6.1 的方式處理error.log 里通常已經(jīng)把真正的原因?qū)懬宄撕芏鄷r(shí)候只是一條配置不對(duì)或者目錄權(quán)限問題。把日志完整看完再動(dòng)手比瞎試一通高效太多。說(shuō)一句題外話我現(xiàn)在每裝一臺(tái)新機(jī)器的 MySQL都會(huì)在改完配置后先把/etc/mysql下所有 .cnf 文件備份一份文件名帶上日期。這套動(dòng)作花不了半分鐘但后期排查配置漂移問題時(shí)能省掉不少冤枉時(shí)間。如果你也要在生產(chǎn)環(huán)境部署建議把這篇里涉及的關(guān)鍵 SQL 命令整理成一份初始化腳本裝完直接跑一遍比手工一條條敲可靠得多。