
開篇先說明MySQL下載安裝及配置這事說簡單真簡單說麻煩也真麻煩。我?guī)屯戮冗^好多次裝完MySQL起不來的問題也在生產(chǎn)環(huán)境里見過因為安裝時一個字符集沒選對導(dǎo)致后期做數(shù)據(jù)遷移差點要重導(dǎo)全量的案例。這篇就圍繞從下載到配置的完整流程把版本選擇、安裝包形態(tài)、初始化邏輯、核心配置項這些環(huán)節(jié)逐個講透盡量讓沒裝過的人一次成功也讓已經(jīng)裝上但心里沒底的人能把配置邏輯理清楚。不管你是剛接觸數(shù)據(jù)庫的初學(xué)者還是需要在自己機器上搭開發(fā)環(huán)境的程序員又或者是被分配了臨時搭建內(nèi)部系統(tǒng)任務(wù)的運維新人這篇文章都適合你。我會把Windows和Linux兩條路徑都講清楚配置部分直接給出可用的參數(shù)和數(shù)值依據(jù)看完就能照著操作。1. 下載前先想明白你需要的究竟是哪種MySQL1.1 版本號別選花眼認準(zhǔn)LTS長期支持版很多人打開MySQL下載頁面就懵了頁面上有MySQL Community Server、MySQL Cluster、MySQL Router一堆入口還有8.0、8.1、8.2、8.3這些版本號。先別急核心就一句話新項目選8.0系列不要碰創(chuàng)新版。MySQL從8.0之后把發(fā)布節(jié)奏改了像8.1、8.2這種小版本屬于Innovation Release也就是創(chuàng)新版本官方只做短期支持適合喜歡嘗鮮的技術(shù)愛好者不適合用在開發(fā)和生產(chǎn)環(huán)境。我們?nèi)粘S玫膽?yīng)該是8.0.x這種長期支持版本比如8.0.34、8.0.36這類。順便提一句5.7現(xiàn)在已經(jīng)進入生命周期末期雖然網(wǎng)上還有很多老教程用的是5.7但如果這是你新搭的環(huán)境沒必要再選5.7除非你要維護的舊系統(tǒng)明確要求必須用5.7。選擇8.0還有一個很實際的原因它的默認字符集就是utf8mb4默認排序規(guī)則也是針對現(xiàn)代應(yīng)用優(yōu)化的這對中文和emoji存儲都很友好。而5.7的默認字符集還是latin1裝完不手動改配置的話后面建表存中文就容易出現(xiàn)亂碼問題。既然下載安裝只有一次少給自己埋雷。1.2 安裝包形態(tài)MSI、ZIP、系統(tǒng)軟件倉庫怎么選確定版本之后第二個容易糾結(jié)的是安裝包形態(tài)。MySQL官方下載頁面一般提供兩種MSI Installer圖形化向?qū)О惭b適合Windows用戶有安裝、配置、啟動一站式流程相當(dāng)于傻瓜模式。ZIP Archive壓縮包解壓即用沒有安裝向?qū)信渲枚伎渴謩訉懪渲梦募m合希望完全掌控安裝路徑和配置細節(jié)的人。我的建議是如果只是在本機搭開發(fā)環(huán)境用MSI就行省心。如果你后面可能要部署到多臺機器或者希望把安裝目錄、數(shù)據(jù)目錄完全按自己的規(guī)劃來放ZIP更合適因為MSI會在系統(tǒng)里寫很多注冊表項和默認目錄換路徑遷移反而麻煩。Linux下不建議用源代碼編譯安裝除非你有定制編譯參數(shù)的需求否則又慢又容易踩依賴坑。Linux上最推薦的是用官方軟件倉庫安裝或者用系統(tǒng)自帶的軟件源安裝這兩種方式都能自動處理依賴。用系統(tǒng)自帶源的好處是快但版本可能偏舊用官方倉庫的好處是能拿到最新的長期支持版本而且升級路徑清晰。我一般傾向用官方倉庫后面會講具體操作。不管哪種方式下載前都要確認操作系統(tǒng)架構(gòu)Windows區(qū)分64位和32位Linux區(qū)分x86_64和aarch64?,F(xiàn)在絕大多數(shù)機器都是64位下載x86_64版本基本不會錯。不要從第三方下載站拿安裝包那些捆綁了廣告推廣的版本很坑只認官方渠道。2. Windows下把MySQL跑起來ZIP版完整實操Windows下用ZIP版雖然要多寫幾個步驟但每一步干什么都很明確不容易被安裝向?qū)У碾[藏設(shè)置坑到。我用8.0.36版本為例安裝目錄放在D盤的mysql目錄下。2.1 動手安裝前先寫好my.ini配置文件很多人解壓完就直接運行mysqld然后發(fā)現(xiàn)服務(wù)起不來或者起來了但數(shù)據(jù)目錄不知道在哪根源就是沒寫配置文件。MySQL在Windows下的默認配置文件讀取順序會包含安裝目錄下的my.ini所以我們把配置寫在D:\mysql\my.ini路徑就最省事。先在最前面處理basedir和datadir這兩個基礎(chǔ)路徑[mysqld] basedirD:/mysql datadirD:/mysql/data port3306 character-set-serverutf8mb4 collation-serverutf8mb4_0900_ai_ci這里要注意路徑分隔符可以用正斜杠也可以在ini文件里寫成雙反斜杠因為ini解析時單個反斜杠會被當(dāng)成轉(zhuǎn)義字符容易出問題。我第一次沒注意寫成了單反斜杠結(jié)果MySQL半天起不來報錯就是路徑不對。還一個容易踩的點my.ini文件保存格式必須是UTF-8無BOM如果帶BOMMySQL讀取時會把BOM字符解析進參數(shù)里導(dǎo)致一些莫名其妙的報錯。datadir建議獨立規(guī)劃不要隨手放在安裝目錄里。數(shù)據(jù)目錄會隨著業(yè)務(wù)膨脹變得很大如果安裝盤空間不夠后面再挪盤會很折騰。我的習(xí)慣是放在D:\mysql\data和安裝程序分開備份時也方便。2.2 初始化數(shù)據(jù)目錄和服務(wù)安裝配置文件寫完之后用管理員身份打開命令提示符進入D:\mysql\bin目錄執(zhí)行mysqld --initialize --console這一步會初始化系統(tǒng)表空間和數(shù)據(jù)字典并生成一個臨時的root密碼。注意--console參數(shù)會把初始化日志打到控制臺密碼就在日志里的最后一行類似這種格式[Note] A temporary password is generated for rootlocalhost: 一些字符和數(shù)字混合如果你不想用臨時密碼也可以用mysqld --initialize-insecure這種方法會生成一個root空密碼適合純粹的本地開發(fā)測試環(huán)境但如果機器有對公網(wǎng)暴露的風(fēng)險千萬別這么干。初始化完成之后注冊Windows服務(wù)mysqld --install MySQL --defaults-fileD:/mysql/my.ini這里MySQL是服務(wù)名可以自己起比如叫MySQL80。--defaults-file參數(shù)指定配置文件路徑如果不指定MySQL會按默認順序去找my.ini但Windows下這個查找順序經(jīng)常不符合預(yù)期所以每次操作都顯式指定最穩(wěn)妥。然后啟動服務(wù)net start MySQL啟動成功后用臨時密碼登錄mysql -u root -p登錄進去第一件事就是改root密碼因為臨時密碼只能用于首次登錄ALTER USER rootlocalhost IDENTIFIED BY 你的新密碼;這里的密碼最好一次到位設(shè)置成自己習(xí)慣的強度。MySQL 8.0默認安裝了validate_password組件如果密碼太簡單會直接被拒絕要求包含大小寫字母、數(shù)字和特殊字符的組合。2.3 下載安裝過程中最常見的失敗場景如果net start的時候提示服務(wù)沒有響應(yīng)控制功能或者直接啟動失敗不要慌先去數(shù)據(jù)目錄下找錯誤日志文件。ZIP版的錯誤日志默認在datadir目錄下文件名是主機名.err。打開看最后幾行一般就能定位到原因。我遇到過的高頻原因有這么幾個端口被占用。MySQL默認3306如果本機已經(jīng)有別的實例或者某個程序占了3306服務(wù)就起不來。用netstat -ano | findstr 3306看看占用的進程要么改配置里的port要么處理占用進程。配置文件的路徑寫錯。要么basedir寫錯了位置要么my.ini里的參數(shù)名拼錯。參數(shù)拼錯時MySQL可能不會直接報錯而是用默認值這時候排查起來就頭疼所以配置文件內(nèi)容盡量精簡先保證能啟動再說。datadir里有殘留數(shù)據(jù)。如果你之前初始化過一次失敗后想重來但data目錄里已經(jīng)有文件了再次--initialize就會報錯。解決方法是把data目錄清空再執(zhí)行初始化。3. Linux下安裝官方倉庫和系統(tǒng)源兩條路Linux環(huán)境是MySQL最常見的部署場景服務(wù)器的穩(wěn)定性、性能都和它強相關(guān)。我主要說一下RHEL/CentOS系的官方倉庫安裝方式Debian/Ubuntu系的思路類似。3.1 用官方倉庫安裝版本可控以CentOS/RHEL系為例先安裝官方倉庫的RPM包rpm -ivh https://dev.mysql.com/get/mysql80-community-release-el7-7.rpm注意版本號會更新以官網(wǎng)實際提供的為準(zhǔn)。安裝完倉庫之后執(zhí)行dnf install mysql-server如果系統(tǒng)是CentOS 7這種沒有dnf的用yum install mysql-server即可。安裝完成后mysql-server這個包里已經(jīng)包含了服務(wù)端、客戶端、初始化腳本等不用再單獨裝客戶端。啟動服務(wù)systemctl start mysqld systemctl enable mysqldRHEL系用rpm方式安裝的MySQL初始化和Windows不太一樣。它在首次啟動時會自動初始化數(shù)據(jù)目錄并生成一個臨時root密碼這個密碼寫在日志文件里grep temporary password /var/log/mysqld.log拿到臨時密碼后登錄同樣是先改密碼ALTER USER rootlocalhost IDENTIFIED BY 新密碼;3.2 配置文件的組織方式和權(quán)限坑Linux下MySQL的配置文件是/etc/my.cnf它實際是一個聚合配置里面會通過!includedir引用/etc/my.cnf.d目錄下的所有.cnf文件。因此我們既可以直接在/etc/my.cnf里加參數(shù)也可以在/etc/my.cnf.d/下新建一個自己的配置文件比如server.cnf。我個人喜歡新建獨立配置文件的方式這樣升級MySQL或者排查時能一眼看出哪些參數(shù)是我加的哪些是默認的。配置好之后驗證一下mysql -u root -p -e SHOW VARIABLES LIKE port;Linux下還有一個坑是SELinux。如果你的數(shù)據(jù)目錄改在了自定義路徑下比如/data/mysql而不是默認的/var/lib/mysql那MySQL啟動時可能被SELinux攔下來報錯信息還不明顯。這種情況下有兩個選擇要么把SELinux對MySQL的type標(biāo)簽加到新路徑上要么用chcon把目錄的安全上下文改成mysqld_db_t。很多教程不會提這個但生產(chǎn)環(huán)境上我實實在在遇到過部署新機器時寧可多花一分鐘確認也別等服務(wù)起不來再查。3.3 初始化后的安全加固步驟Linux下MySQL裝好后我建議順手過一遍mysql_secure_installation這個交互腳本。它會引導(dǎo)你配置密碼校驗策略、刪除匿名用戶、禁止root遠程登錄、刪除test測試庫。雖然每一步都可以手動執(zhí)行但腳本能提醒容易漏掉的項。這里特別提醒不要圖省事跳過刪除匿名用戶這一步。我之前在測試環(huán)境漏掉了結(jié)果某次測試時一個不帶用戶名的連接直接以匿名用戶身份登了進去雖然只是測試環(huán)境但排查時也浪費了不少時間。4. 核心配置項解析知道參數(shù)為什么這么寫配置MySQL不是為了把參數(shù)寫滿而是真正理解哪些參數(shù)影響性能、哪些影響穩(wěn)定性然后根據(jù)業(yè)務(wù)場景做取舍。下面幾個配置項是每個MySQL實例都需要重點關(guān)注的。4.1 字符集必須安裝時就鎖死字符集是MySQL配置里最事后難改的一項。如果建表時用的是utf8mb3也就是utf8后面想改成utf8mb4表結(jié)構(gòu)要重建、數(shù)據(jù)要轉(zhuǎn)換如果數(shù)據(jù)量大這是一個大工程。MySQL 8.0的默認字符集已經(jīng)是utf8mb4但對小白來說最大的坑在客戶端連接的字符集。如果你在my.ini或my.cnf里只設(shè)置了character-set-server客戶端登錄時如果沒指定也可能出現(xiàn)終端里看著正常、程序里卻亂碼的情況。我的做法是[mysqld] character-set-serverutf8mb4 collation-serverutf8mb4_0900_ai_ci [client] default-character-setutf8mb4linux下客戶端配置也放在[client]段落。這樣從服務(wù)端到客戶端鏈路都是utf8mb4上傳下載再到顯示全線一致。實際項目里我見過很多亂碼案例最終排查下來都是中間某一段字符集不一致而不是數(shù)據(jù)庫存錯了。4.2 連接數(shù)和緩沖池給數(shù)值一個理由連接數(shù)和緩沖池是調(diào)優(yōu)時的兩個常見參數(shù)。max_connections表示最大連接數(shù)。默認值151看起來不多但每個連接都會占用一定內(nèi)存連接數(shù)設(shè)太大反而可能把內(nèi)存吃光。經(jīng)驗做法是先估算業(yè)務(wù)正常并發(fā)量留出兩到三倍余量再綜合機器內(nèi)存決定。一個比較常見的起步配置是300到500。你要知道不是設(shè)得越高越好連接數(shù)上來之后數(shù)據(jù)庫需要維護的線程資源更多反而可能導(dǎo)致性能下降。innodb_buffer_pool_size是InnoDB最重要的內(nèi)存參數(shù)它決定了數(shù)據(jù)頁緩存的容量。一臺只跑MySQL的8GB內(nèi)存機器我可以把緩沖池設(shè)到4GB到5GB然后再給其他進程和系統(tǒng)緩存留余地。如果機器內(nèi)存32GB可以逐步增加到20GB左右。設(shè)置之后用下面這條命令確認生效SHOW VARIABLES LIKE innodb_buffer_pool_size;注意這個參數(shù)的單位是字節(jié)設(shè)置的時候要寫清楚。比如5GB應(yīng)該寫成5368709120或者用MySQL 8.0支持的單位寫法innodb_buffer_pool_size5G4.3 日志參數(shù)慢查詢?nèi)罩竞湾e誤日志日志是排查問題的鑰匙寧可開著也別全關(guān)。慢查詢?nèi)罩居绕渲匾?。開發(fā)環(huán)境可能感覺不出來但生產(chǎn)環(huán)境一旦有慢查詢沒有日志就只能瞎猜。我的基本配置如下slow_query_log1 slow_query_log_file/var/log/mysql/slow.log long_query_time2 log_error/var/log/mysql/error.loglong_query_time的單位是秒設(shè)成2表示執(zhí)行超過2秒的SQL會被記錄。0.幾秒的慢查詢要不要記要看你業(yè)務(wù)對延遲的敏感度先記著后期再決定要不要縮小閾值。另外建議開啟log_error_verbosity2能讓錯誤日志包含更多調(diào)試信息排查問題時很有用。4.4 遠程訪問與賬號權(quán)限MySQL默認只允許本機訪問這是好事。如果需要讓其他機器連接有兩種做法我強烈建議只選第二種直接改bind-address0.0.0.0意味著所有IP都能訪問這臺數(shù)據(jù)庫只要防火墻放行3306整個網(wǎng)段都能連。這個方案適合內(nèi)網(wǎng)測試環(huán)境生產(chǎn)環(huán)境不建議。創(chuàng)建專門的遠程登錄賬號限制來源IP。比如CREATE USER app192.168.1.% IDENTIFIED BY 密碼; GRANT SELECT, INSERT, UPDATE, DELETE ON mydb.* TO app192.168.1.%;這樣數(shù)據(jù)庫只對192.168.1這個網(wǎng)段開放而且app賬號只有業(yè)務(wù)需要的權(quán)限即使泄露影響也可控。不要用root賬號做遠程連接這是底線。如果改了bind-address并重啟服務(wù)后遠程仍然連不上記得檢查系統(tǒng)防火墻。很多Linux發(fā)行版默認開了firewalld需要放行3306端口firewall-cmd --permanent --add-port3306/tcp firewall-cmd --reload5. 常見問題與排查技巧實錄安裝配置過程中有一些錯誤幾乎每個人都會遇到。我整理了一份速查表以后再碰到可以直接對著排查。5.1 高頻錯誤速查表錯誤現(xiàn)象大概率原因處理方法ERROR 1045 Access denied for user rootlocalhost密碼錯誤或者賬號被身份驗證插件限制確認密碼考慮caching_sha2_password兼容性ERROR 2003 Cant connect to MySQL server端口不通、服務(wù)沒啟動、bind-address限制檢查連接地址、端口、防火墻ERROR 1130 Host ... is not allowed to connect當(dāng)前賬號未授權(quán)該來源IP訪問用本地root創(chuàng)建遠程賬號并授權(quán)Cant open the mysql.plugin table權(quán)限問題或數(shù)據(jù)目錄損壞修復(fù)目錄權(quán)限或重新初始化[ERROR] InnoDB: Unable to lock ./ibdata1有另一個mysqld實例在運行殺掉舊進程再啟動服務(wù)啟動后立刻退出錯誤日志無有效信息my.ini路徑或配置文件格式問題檢查配置文件編碼、路徑寫法有一條要單獨提醒MySQL 8.0默認身份驗證插件是caching_sha2_password如果你的客戶端是舊版可能連不上。這時候有兩種解法升級客戶端驅(qū)動或者把賬號改成mysql_native_password。不過能升級盡量升級新插件的安全性更高。5.2 排查流程標(biāo)準(zhǔn)化別東一榔頭西一棒子每次遇到連不上數(shù)據(jù)庫這類問題我建議按順序排查不要跳步確認服務(wù)進程是否活著Windows看服務(wù)狀態(tài)Linux用ps -ef | grep mysqld。確認端口監(jiān)聽Windows用netstat -ano | findstr 3306Linux用ss -lntp | grep 3306。在本機用localhost連接測試排除網(wǎng)絡(luò)問題。查看錯誤日志尾部日志里通常有直接原因。用SHOW VARIABLES確認配置參數(shù)是否真正生效。這套流程走下來90%的問題能定位。我曾經(jīng)在排查一個應(yīng)用連不上數(shù)據(jù)庫的問題時卡了很久才發(fā)現(xiàn)是路由器上做了端口映射導(dǎo)致應(yīng)用連接時經(jīng)過了不合適的路徑。所有這些問題如果一開始就從進程、端口、日志三個維度同時排查會快很多。5.3 忘記root密碼怎么重置忘記root密碼也是一個高頻場景。標(biāo)準(zhǔn)做法是跳過授權(quán)表啟動重置密碼然后恢復(fù)正常模式。第一步停止MySQL服務(wù)。第二步以跳過授權(quán)表的方式啟動mysqld --skip-grant-tables --skip-networking 加上--skip-networking是因為跳過了授權(quán)表的情況下再開網(wǎng)絡(luò)端口等于把數(shù)據(jù)庫裸奔給所有能連到的人堅決不能這樣做。然后登錄mysql -u root登錄后先讓授權(quán)表生效再改密碼FLUSH PRIVILEGES; ALTER USER rootlocalhost IDENTIFIED BY 新密碼;改完之后把mysqld進程停掉用正常方式重新啟動。把進程停掉這一步很重要有些人改完密碼直接啟動另一個服務(wù)結(jié)果兩個進程互相爭搶數(shù)據(jù)目錄會報InnoDB無法鎖定文件。6. 安裝配置階段的實用心得踩過幾次坑之后有幾點經(jīng)驗確實值得分享出來幫助你在最初階段少走彎路。第一裝MySQL之前先決定data目錄放哪。很多人裝的時候隨手放在默認路徑等用了幾個月發(fā)現(xiàn)磁盤滿了要遷數(shù)據(jù)這時候就要停機、拷貝、改配置、驗證權(quán)限一系列操作下來風(fēng)險遠高于裝之前花五分鐘規(guī)劃。第二字符集的事別等建庫之后再想。一個規(guī)范的建庫語句長這樣CREATE DATABASE myapp CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci;這樣建庫后庫內(nèi)所有表默認繼承這個字符集后續(xù)基本不需要再單獨設(shè)置。第三密碼策略可以調(diào)但別調(diào)到?jīng)]策略。MySQL 8.0默認的validate_password策略比較嚴(yán)格測試環(huán)境覺得很煩可以通過設(shè)置validate_password.policy為LOW來降低要求但生產(chǎn)環(huán)境務(wù)必保持強密碼和合適的策略別因為測試環(huán)境習(xí)慣了簡單密碼生產(chǎn)環(huán)境也跟著大意。第四建議把安裝配置過程中的所有自定義參數(shù)整理一份notes包括配置文件路徑、數(shù)據(jù)目錄、端口、字符集、備份策略貼在自己能隨時看到的地方。裝好一次不代表永遠不重裝遇到機器遷移、環(huán)境重建時這份記錄能幫你節(jié)省大量時間。MySQL下載安裝及配置這個流程只要你理解每一步在做什么而不是機械照抄命令基本就不會有太多意外。裝好并跑通之后可以順手建一個測試庫用SELECT VERSION();驗證一下版本再試著重啟一次服務(wù)確認配置沒依賴臨時狀態(tài)這樣一套基礎(chǔ)環(huán)境才算真正穩(wěn)了。