前幾天發現了一個有趣的事情,兩台類似的mysql數據庫,都有dong這個用戶。在本地連接時,一個連接正常,一個連接失敗。
兩台的mysql版本都是5.6 。下面是兩台mysql上的所有賬戶:
服務器1:
服務器2:
這兩台服務器上都有dong用戶,且都可以從任何地方登陸(host列的值是%)。但我在服務器2上卻登陸失敗了!
服務器1登陸成功
服務器2 登陸失敗
查閱官方文檔后,發現了一些信息。
有時候用戶的連接信息可能匹配到了user表的多行記錄。那到底用哪一行來認證呢?
mysql會把user表加載到內存,並對所有的行進行排序。當有用戶連接時,就從第一行開始匹配,並使用第一個匹配到的行來認證。排序是按照主機名的明確性來排序,誰更明確,誰就排在前面。主機名明確性相同就按照用戶名的明確性繼續排序。(localhost比%明確,%代表可以從任意地方登陸,localhost代表只能從本地登陸)
比如:服務器1 的user表排序后的順序可能是
root localhost
rep %
dong %
root %
服務器2 的user表排序后的順序可能是
root localhost
root localhost.localdomain
root 127.0.0.1
root ::1
localhost
localhost.localdomain
dong %
在服務器1上登陸時,匹配到了1行,也就是(dong %),登陸沒有問題。在服務器2上登陸時,匹配到了3行,也就是('' localhost),('' localhost.localdomain),(dong %) 。但是第一個匹配到的是('' localhost),所以會用這一行來認證。至於登陸失敗是因為('' localhost)這個用戶是沒有密碼的。如果使用 mysql -udong 就可以登陸了,並且會以''@localhost這個用戶來登陸。
查看一下登陸的用戶
???哪里來的dong@localhost 用戶?查看一下這個用戶的權限
驗證了我前面說的是用’’@localhost這個用戶登陸的。
一般的我們會刪掉服務器2上用戶名為空的用戶,這樣登陸就不會出現上面的問題。或者也可以再建一個同名的用戶,不過登陸的host是localhost 這樣在本地也可以登陸了。