2012-05-30 14 views

回答

76

百分號意味着所有IP的本地主機這樣是多餘的......沒有必要與本地主機的第二個記錄的。

編輯

居然有,「localhost」的是在MySQL特殊,它指的是在Unix套接字(或命名管道上的窗戶,我相信),而不是一個TCP/IP套接字連接。使用%作爲主機不包括'本地主機'

+0

在什麼版本?在MySQL 5.5.35中,「%」也與localhost匹配。 – depquid

+0

「localhost」不僅通過本地套接字連接,127.0.0.1(不使用套接字)也不會與%相匹配,而是與本地主機相匹配。看到今天haproxy安裝。 – Phillipp

26

正如@nos在目前對這個問題所接受的答案的評論中指出的,接受的答案是不正確的。

是的,使用%localhost作爲用戶帳戶主機時,通過套接字連接而不是標準TCP/IP連接進行連接時存在差異。

對於套接字,主機值%不包括localhost,因此如果要使用該方法進行連接,則必須指定它。

4

要提供一個稍微不同的答案,目前提供的答案。

如果在用戶表''@'localhost'中有一行來自本地主機的匿名用戶,那麼這將被視爲比使用通配符主機'user'@'%'的用戶更具體。這就是爲什麼有必要也提供'user'@'localhost'

你可以在this page的底部看到更詳細的解釋。

3

百分號表示:任何主機,包括遠程和本地連接。

本地主機只允許本地連接。

(這麼開始了,如果你不需要你的數據庫的遠程連接,你可以擺脫APPUSER的@「%」用戶馬上)

所以,是的,他們是重疊的,但...

...有一個設置這兩種類型的帳戶的原因,這是在mysql文檔中解釋: http://dev.mysql.com/doc/refman/5.7/en/adding-users.html

如果你有一個有匿名用戶在你的本地主機,您可以與發現:

select Host from mysql.user where User='' and Host='localhost'; 

,如果你只需要創建一個用戶APPUSER @「%」(你不是APPUSER @'本地主機'),那麼當appuser mysql用戶 從本地主機連接時,使用匿名用戶帳戶(它優先於您的appuser @'%'用戶)。

而且這種情況的解決方法是(作爲一個可以猜)創建APPUSER @「localhost」的(這是更具體的本地主機的匿名用戶,如果你的APPUSER從本地主機連接將被使用)。

1

我們來測試吧。

連接作爲超級用戶,然後:

SHOW VARIABLES LIKE "%version%"; 
+-------------------------+------------------------------+ 
| Variable_name           | Value                        | 
+-------------------------+------------------------------+ 
| version                 | 10.0.23-MariaDB-0+deb8u1-log | 

然後

USE mysql; 

與密碼bar創建用於測試的用戶foo

CREATE USER [email protected]'%' IDENTIFIED BY 'bar'; FLUSH PRIVILEGES; 

要連接到Unix領域套接字(即由文件系統條目命名的I/O管道或一些這樣的),在命令行上運行此:

mysql -pbar -ufoo 

要連接到TCP/IP端點127.0.0.1:3306代替,在命令行上運行此:

mysql -pbar -ufoo -h127.0.0.1 

要檢查連接是否通過TCP/IP套接字或Unix域套接字,通過檢查ps faux的輸出來獲取mysql客戶端進程的PID,然後運行lsof -p$GOTPID。你會看到類似這樣的:

mysql [PID] quux 3u IPv4 [code] 0t0 TCP localhost:[port]->localhost:mysql (ESTABLISHED) 

mysql [PID] quux 3u unix [code] 0t0 [code] socket 

所以:

案例0:主機= '10 .10.10.10' (空試驗)

update user set host='10.10.10.10' where user='foo'; flush privileges; 
  • 連接到插座:FAILURE
  • 連接到127.0.0.1:未能

案例1:主機= '%'

update user set host='%' where user='foo'; flush privileges; 
  • 與插座:OK
  • 連接到127.0.0。1:OK

情況2:主機= 'localhost' 的

update user set host='localhost' where user='foo';flush privileges; 
  • 連接到插座:OK
  • 連接到127.0.0.1:OK

情況3:主機='127.0.0.1'

update user set host='127.0.0.1' where user='foo';flush privileges; 
  • 連接到插座:未能
  • 連接到127.0.0.1:OK

案例4:主機= ''

update user set host='' where user='foo';flush privileges; 
  • 與插座:OK
  • 連接至127.0.0.1:好吧

(根據MySQL 5.7: 6.2.4 Access Control, Stage 1: Connection Verification,空字符串''也意味着「任何主機」,但在'%'之後排序。

案例5:主機= '192.168.0.1'(額外的測試)

( '192.168.0.1' 是我的機器的IP地址之一,你的情況適當改變)

update user set host='192.168.0.1' where user='foo';flush privileges; 
  • 連接到插座:未能
  • 連接到127.0.0.1:未能

  • 連接到192.168.0.1使用mysql -pbar -ufoo -h192.168.0.1:OK

邊緣情況答:主機= '0.0.0.0'

update user set host='0.0.0.0' where user='foo';flush privileges; 
  • 與插座:未能
  • 連接到127.0.0.1:失敗

邊緣案例B:主機= '255.255.255.255'

update user set host='255.255.255.255' where user='foo';flush privileges; 
  • 與插座:未能
  • 連接到127.0.0。1:故障

清理

delete from user where user='foo';flush privileges; 

附錄

要了解什麼是真正的mysql.user表,這是允許的一個表,使用:

SELECT SUBSTR(password,1,6) as password, user, host, 
Super_priv AS su, 
Grant_priv as gr, 
CONCAT(Select_priv, Lock_tables_priv) AS selock, 
CONCAT(Insert_priv, Update_priv, Delete_priv, Create_priv, Drop_priv) AS modif, 
CONCAT(References_priv, Index_priv, Alter_priv) AS ria, 
CONCAT(Create_tmp_table_priv, Create_view_priv, Show_view_priv) AS views, 
CONCAT(Create_routine_priv, Alter_routine_priv, Execute_priv, Event_priv, Trigger_priv) AS funcs, 
CONCAT(Repl_slave_priv, Repl_client_priv) AS replic, 
CONCAT(Shutdown_priv, Process_priv, File_priv, Show_db_priv, Reload_priv, Create_user_priv) AS admin 
FROM user ORDER BY user, host; 

這給出:

+----------+----------+-----------+----+----+--------+-------+-----+-------+-------+--------+--------+ 
    | password | user  | host  | su | gr | selock | modif | ria | views | funcs | replic | admin | 
    +----------+----------+-----------+----+----+--------+-------+-----+-------+-------+--------+--------+ 
    | *E8D46 | foo  |   | N | N | NN  | NNNNN | NNN | NNN | NNNNN | NN  | NNNNNN | 

同樣,對於表mysql.db

SELECT host,db,user, 
     Grant_priv as gr, 
     CONCAT(Select_priv, Lock_tables_priv) AS selock, 
     CONCAT(Insert_priv, Update_priv, Delete_priv, Create_priv, Drop_priv) AS modif, 
     CONCAT(References_priv, Index_priv, Alter_priv) AS ria, 
     CONCAT(Create_tmp_table_priv, Create_view_priv, Show_view_priv) AS views, 
     CONCAT(Create_routine_priv, Alter_routine_priv, Execute_priv) AS funcs 
     FROM db ORDER BY user, db, host;