一、問題展示

大概就是這么一個報錯,這里出現(xiàn)了 ERROR 1045(28000)但是錯誤描述卻是Unknown error。
二、關于錯誤號和錯誤描述
實際上這里的ERROR 1045是一個標號對應
- ER_ACCESS_DENIED_ERROR 28000
實際上這就是密碼錯誤的報錯,而冒號以后的是錯誤的描述,在我們的安裝目錄下有一個share目錄,里面包含了各種語言關于錯誤描述的文件。那么我們這里應該可以定位是錯誤描述的文件沒有讀取到,遇到了問題。
三、代碼報錯部分

nr為我們的錯誤標號,如果通過錯誤標號沒有找到對應的錯誤描述那么就會報出Unkown error并且最后帶上錯誤標號,也就是我們看到最后的1045。
而對于查找的錯誤描述來自于初始化的時候讀取的文件:

這里可以大概看出來是通過語言進行匹配,然后找到lc_messages_dir所在的目錄下尋找。我們注意到如果讀取文件失敗那么將會有報錯信息。翻看問題數據庫的日志確實存在一行這樣的報錯:

其實如果讀取這個文件失效那么大部分錯誤都會報unknown error,比如:

官方文檔的描述:

四、為什么會這樣
找到出問題的原因是沒有讀取到錯誤描述文件,那么為什么讀取不到呢?測試發(fā)現(xiàn)默認的情況下lc_messages_dir會設置為my.cnf目錄basedir/share(我們通常也不會設置這個目錄),我們這里的問題實際上由于my.cnf中basedir目錄設置錯誤。但是為什么basedir目錄設置錯誤,又能夠啟動數據庫呢?這是因為通過mysqld_safe去拉取mysqld的時候會通過mysqld_safe的目錄反向推測mysqld所在的目錄,并不完全依賴basedir,但是lc_messages_dir卻是basedir/share 所以雖然數據能夠啟動但是錯誤描述文件卻找不到。
下面模擬一下:
-
我們在my.cnf中加入一個錯誤目錄
image.png - 使用mysqld_safe拉取mysqld
/bin/sh /opt/mysql/mysql3306/install/bin/mysqld_safe --datadir=/opt/mysql/mysql3306/data/ --pid-file=/opt/mysql/mysql3306/data/mgr2.pid -
查看lc_message_dir目錄
image.png -
驗證錯誤
image.png
錯誤得以重現(xiàn),當然如果用mysql.server去拉取因為mysql.server會解析basedir獲取mysqld_safe所在的目錄顯然是不行的報錯如下:



