中文字幕av专区_日韩电影在线播放_精品国产精品久久一区免费式_av在线免费观看网站

溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點擊 登錄注冊 即表示同意《億速云用戶服務條款》

更改用戶host留下的坑

發布時間:2020-03-04 15:45:32 來源:網絡 閱讀:167 作者:wangkunj 欄目:MySQL數據庫

前言:?

我們在創建數據庫用戶的時候都會指定host,即一個完整的用戶可描述為 'username'@'host' 。創建用戶時不顯式指定host則默認為%,%代表所有ip段都可以使用這個用戶,我們也可以指定host為某個ip或ip段,這樣會僅允許在指定的ip主機使用該數據庫用戶。不過你也應該明白 'username'@'%' 和 'username'@'192.168.6.%' 是兩個毫無關聯的用戶,這兩個用戶可以有不同的密碼和權限,這里不建議創建多個同名不同host的用戶,還有不要輕易更改用戶的host,筆者曾經遇到過因為更改用戶host引發的故障,下面將其分享出來,為你講述前因后果。

1.故障模擬

當時為了規范安全,將某個程序用戶的host由%改為了應用服務器ip段,過段時間業務反饋某些功能報錯,經排查發現是因為無法調用存儲過程(大家可以先思考下原因),下面模擬下故障操作。

# 原有用戶、表、存儲過程模擬創建
mysql> create user 'testuser'@'%' identified by '123456';
Query OK, 0 rows affected (0.04 sec)

mysql> grant select,insert,update,delete,execute on `testdb`.* to 'testuser'@'%';
Query OK, 0 rows affected (0.01 sec)

mysql> flush privileges;
Query OK, 0 rows affected (0.00 sec)

mysql> show grants for 'testuser'@'%';
+-------------------------------------------------------------------------------+
| Grants for testuser@%                                                         |
+-------------------------------------------------------------------------------+
| GRANT USAGE ON *.* TO 'testuser'@'%'                                          |
| GRANT SELECT, INSERT, UPDATE, DELETE, EXECUTE ON `testdb`.* TO 'testuser'@'%' |
+-------------------------------------------------------------------------------+

CREATE TABLE `students` (
 `id` int(11) NOT NULL ,
 `name` varchar(20),
 `age` int(11),
 PRIMARY KEY (`id`)
) ENGINE=InnoDB ;
INSERT INTO `students` VALUES ('1001', 'lodd', '23');
INSERT INTO `students` VALUES ('1002', 'sdfs', '21');
INSERT INTO `students` VALUES ('1003', 'sdfsa', '24');

DROP PROCEDURE IF EXISTS select_students_count;
DELIMITER $$
CREATE DEFINER=`testuser`@`%` PROCEDURE `select_students_count`()
BEGIN
   SELECT count(id) from students;
END
$$
DELIMITER ;

# 使用testuser用戶調用存儲過程 調用正常
mysql> call select_students_count();
+-----------+
| count(id) |
+-----------+
|         3 |
+-----------+

# 更改用戶host 重命名用戶
mysql> RENAME USER 'testuser'@'%' to 'testuser'@'192.168.6.%';
Query OK, 0 rows affected (0.00 sec)
mysql> flush privileges;
Query OK, 0 rows affected (0.01 sec)
mysql> show grants for  'testuser'@'192.168.6.%';
+---------------------------------------------------------------------------------------+
| Grants for testuser@localhost                                                         |
+---------------------------------------------------------------------------------------+
| GRANT USAGE ON *.* TO 'testuser'@'localhost'                                          |
| GRANT SELECT, INSERT, UPDATE, DELETE, EXECUTE ON `testdb`.* TO 'testuser'@'localhost' |
+---------------------------------------------------------------------------------------+

# 再次用testuser用戶調用存儲過程 無法調用 出現故障
mysql> call select_students_count();
ERROR 1449 (HY000): The user specified as a definer ('testuser'@'%') does not exist
2.故障排查與解決

其實我們手動調用下存儲過程后,從報錯內容明顯可以看出是因為'testuser@'%'用戶不存在的問題。因為該存儲過程的定義者是'testuser@'%',而我們將此用戶的host改成了192.168.6.%,那么當我們之后調用該存儲過程時,系統判別到此存儲過程的屬主用戶不存在,因此系統拒絕請求并拋出異常。

當知道上述原因后,解決方法就會明朗許多,我們只需要將該存儲過程的屬主改為新的用戶即可。其實更改過用戶后,該用戶下的視圖、存儲過程、函數、觸發器、事件都會受到影響,當我們定義視圖、存儲過程、函數時使用 DEFINER?屬性時,若調用這些對象,系統會首先判別此對象的屬主用戶是否存在,不存在會直接拋出錯誤。

此問題的解決方案有兩種,一是將此存儲過程的安全屬性由 DEFINER?改為 INVOKER?,個人不推薦這個方案,至于?DEFINER?和?INVOKER?的區別,下個章節會額外講解。二是更改此存儲過程的屬主,下面給出更改方法并加以驗證:

# 通過系統表更改存儲過程的屬主
mysql> update mysql.proc set definer='testuser@192.168.6.%' where db='testdb' and name='select_students_count' and type='PROCEDURE';           
Query OK, 1 row affected (0.01 sec)
Rows matched: 1  Changed: 1  Warnings: 0

# 使用testuser用戶調用驗證 調用成功
mysql> call select_students_count();
+-----------+
| count(id) |
+-----------+
|         3 |
+-----------+
1 row in set (0.00 sec)

?

3.DEFINER與INVOKER拓展知識

MySQL中,創建視圖(view)、函數(function)、存儲過程(procedure)、觸發器(trigger)、事件(event)時,可以指定安全驗證方式(也就是SQL SECURITY)屬性,其值可以為DEFINER或INVOKER,表示在執行過程中,使用誰的權限來執行。

  • DEFINER:由definer(定義者)指定的用戶的權限來執行
  • INVOKER:由調用這個視圖(存儲過程)的用戶的權限來執行

默認情況下,系統指定為DEFINER。當SQL SECURITY屬性為DEFINER時,數據庫中必須存在DEFINER指定的用戶,并且該用戶擁有對應的操作權限及引用的相關對象的權限,才能成功執行。與當前用戶是否有權限無關。當SQL SECURITY屬性為INVOKER時,只要執行者有執行權限并且有引用的相關對象的權限,就可以成功執行。

了解了上述知識后,可能你早已明白上述故障發生的前因后果。在日常生產中,不建議使用INVOKER屬性,因為將SQL SECURITY定義為INVOKER后,其他用戶想調用此對象時不僅需要有該對象的執行權限還要有其他引用到的相關對象的權限,極大的增加了運維復雜性。下面回顧整篇文章,整理出一下幾點個人建議,以供大家參考:

  1. 不創建多個同名不同host的用戶。
  2. 不要輕易更改用戶的host。
  3. 更改用戶host請用RENAME USER語句,直接更新mysql.user系統表中的host屬性會使權限丟失。
  4. 更改用戶host后,要注意此用戶下的各個對象的DEFINER屬性。
  5. 創建視圖、存儲過程等對象建議將SQL SECURITY定義為DEFINER。
  6. 數據庫遷移時,要注意新環境存在相關對象定義的DEFINER用戶。

總結:?

本文從一個故障出發,詳細記錄了故障發生的原因及背后涉及的知識,其實像DEFINER屬性這些細節類的東西很容易被忽視,只有遇到問題了我們才會去探究。希望本篇文章能讓你學到新東西,特別是上面總結的幾點建議都是筆者日常運維總結出的。原創不易,請大家多多支持!

向AI問一下細節

免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。

AI

纳雍县| 礼泉县| 肃宁县| 仁化县| 宁津县| 皮山县| 河曲县| 铁岭市| 佛山市| 龙山县| 福州市| 呈贡县| 安远县| 灌云县| 长阳| 浦东新区| 鸡东县| 广元市| 通江县| 吴堡县| 泸西县| 青铜峡市| 台东县| 武定县| 嵩明县| 民县| 屯留县| 宁安市| 彝良县| 洞头县| 沙田区| 永德县| 乐亭县| 灌云县| 屯昌县| 西平县| 新平| 靖江市| 阿坝| 将乐县| 仁布县|