現場環境mysql賬戶登入錯誤,使用者名稱和密碼都確認過沒有問題的。報錯資訊如下:
error 1045 (28000): access denied for user 'test'@'localhost' (using password: yes)
檢視1045對應的錯誤資訊:
perror 1045:mysql error code 1045 (er_access_denied_error):access denied for user'%-.48s'@'%-.64s' (using password: %s), 顯然使用者名稱和密碼訪問被拒絕了,從原始碼跟蹤客戶端認證的流程。
sql_connection.cc:check_connection 客戶端認證的入口函式,主要工作:
ip_to_hostname函式:根據ip解析對應的host_name,在沒有配置skip_name_resolve的場景下工作
acl_check_host函式:匹配客戶端機器是否滿足mysql.user表中的host列,在程式啟動的時候會將mysql.user表中的host分為兩個hash結構儲存:acl_check_hosts和acl_wild_hosts,該函式檢查host或者ip是否在這兩個結構中包含
acl_authenticate:進行客戶端認證的主要函式
acl_authenticate 該函式主要功能如下圖,其中scrample是生成的一串隨機數值,用於認證使用;do_auth_once負責後續的認證工作
else
do_auth_once函式:
if (auth_plugin_name.str == native_password_plugin_name.str)authenticate_user函式,這是乙個函式指標,不同的plugin對應不同的處理函式,native_password_plugin外掛程式對應的處理函式為native_password_authenticate。plugin=native_password_plugin; 採用預設外掛程式
#ifndef embedded_library
else
#endif /* embedded_library */
mpvio->plugin= plugin;
old_status= mpvio->status;
if (plugin)
native_password_authenticate函式:
static int native_password_authenticate(mysql_plugin_vio *vio,server_mpvio_read_packet函式:mysql_server_auth_info *info)
......
}
read_packet:讀取返回報文到buffer中
parse_client_handshake_packet:解析客戶端的認證握手包
parse_client_handshake_packet函式,該函式根據不同的資料庫版本解析報文,獲取使用者名稱(連線時的輸入引數)和經過處理後的密碼
char *user= get_string(&end, &bytes_remaining_in_packet, &user_len); 獲取使用者名稱
passwd= get_length_encoded_string(&end, &bytes_remaining_in_packet,
&passwd_len);: 獲取經過處理後的密碼
find_mpvio_user(mpvio): 根據host和user匹配mysql.user中對應的一條記錄。匹配的順序是按照acl_users變數中的值
sql_auth_cache.cc: acl_load函式實現了載入mysql.user表的內容到acl_users中,其中對記錄進行了排序:
std::sort(acl_users->begin(), acl_users->end(), acl_compare()); 注意排序規則函式:根據成員的sort變數的降序排列
sort變數的賦值:sql_auth_cache.cc:get_sort函式,根據這條記錄的host和user計算,先按照host,host相同按照user配需,排序的規則:
1.沒有萬用字元 2.有部分萬用字元 ,如::1 3.%萬用字元 4. 空的 (匿名賬戶)
回到最初的問題;
登入命令: mysql -u test -p -h 127.0.0.1 配置檔案中沒有配置 skip_name_resolve
登入時對應客戶端的host 和 user 分別是localhost 和 test,
資料庫中載入的acl的users值為:
+-----------+-----------+因此賬戶匹配到localhost和空user,而不是匹配到% 和test,導致密碼出錯。| host | user |
+-----------+-----------+
| localhost | mysql.sys |
| localhost | |
| % | test |
+-----------+-----------+
如果配置了skip_name_resolve引數,不會進行ip_to_hostname的轉換,只會按照根據ip位址匹配,這是匹配到% test的賬戶,可以成功登入。
Mysql root 賬戶的登入問題
前些天登入乙個很久之前配置的資料庫,突然發現用 mysql uroot p x 登入不上去了。因為時間很長了,不記得是不是因為密碼錯了。於是就開始了漫長的試密碼。最後還是發現配置出現了問題,於是就搜尋了下解決辦法。最終找到了問題所在 似乎是因為我很久沒有更改密碼了,所以即使賬戶密碼正確也是登入不上去...
MySQL賬戶 密碼修改,跳過許可權強制登入
cmd視窗下登入mysql 登入 mysql u賬戶名 p 檢視mysql庫中現有的賬戶 select user from mysql.user 連線到mysql庫 use mysql mysql資料庫中有乙個user表,表中有使用者名稱user 許可權host 密碼authentication s...
SQL SERVER登入賬戶管理的T SQL 命令
一 sql server登入賬戶管理 1 create login 建立登入賬戶 create login 登入名 from windows with default database 資料庫名 登入名 網域名稱或計算機名 windows使用者賬號 該命令為建立windows類別的登入賬戶,如 cr...