最近服務器遷移,同時關閉了mysql數據庫遠程訪問,就是root只能本地訪問,但是同事在訪問一個視圖的時候一直報錯
The user specified as a definer('root'@'%') does not exist
原本只想打開訪問權限,後面是想辦法把%改爲localhost,一種方法是直右鍵視圖名,點擊設計選擇高級把%改爲localhost就可以
或者是直接用SQL語句修改:
ALTER ALGORITHM=UNDEFINED DEFINER=`root`@`localhost` SQL SECURITY DEFINER VIEW `view_all_aa` AS ………………………………………………………………;
參考文檔:http://pdf.us/2018/02/24/679.html
坑
昨天在做MySQL數據庫用戶權限規範的時候,將原來業務帳號'user'@'%'修改爲'user'@'192.168.1.%'時,忽然發現業務系統部分業務報404錯誤,後面找到程序員排查原因,發現是因爲報錯的業務在調用數據庫時,使用了視圖,而視圖的定義者是原來的'user'@'%',並且安全性設置的是definer,現在這個用戶不存在了,雖然新用戶'user'@'192.168.1.%’擁有和原來相同的數據庫權限,但是依然不能使用這些視圖。
找到了原因,那麼解決辦法也就出來了:一是將所有視圖的定義者修改爲'user'@'192.168.1.%';二是將安全性定義由definer設置爲invoker。因爲是生產環境,不能隨便搞,所以採用的是第一種方法,第二種方法沒有再試。
原理
definer和invoker的區別
在創建視圖或者是存儲過程的時候,是需要定義安全驗證方式的(也就是安全性SQL SECURITY),其值可以爲definer或invoker,表示在執行過程中,使用誰的權限來執行。
definer:由definer(定義者)指定的用戶的權限來執行
invoker:由調用這個視圖(存儲過程)的用戶的權限來執行
definer
當定義爲DEFINER時,必須數據庫中存在DEFINER指定的用戶,並且該用戶擁有對應的操作權限,才能成功執行。與當前用戶是否有權限無關。
示例:
CREATE DEFINER=dev
@%
PROCEDURE p_user_login
(IN u_name VARCHAR(25), IN u_password VARCHAR(100))
BEGIN
SELECT u.id, u.name, u.tid, u.status, u.is_report FROM v_user u WHERE u.name=u_name AND u.password=u_password AND u.status=1;
END;
invoker
當定義爲INVOKER時,只要執行者有執行權限,就可以成功執行。
示例:
CREATE DEFINER=dev
@%
PROCEDURE p_user_login
(IN u_name VARCHAR(25), IN u_password VARCHAR(100))
SQL SECURITY INVOKER
BEGIN
SELECT u.id, u.name, u.tid, u.status, u.is_report FROM v_user u WHERE u.name=u_name AND u.password=u_password AND u.status=1;
END;