新聞中心
從我上大學(xué)時(shí),數(shù)據(jù)庫(kù)概論老師就告訴我,MySQL使用grant對(duì)用戶(hù)授權(quán)之后,一定記得要用flush privilege命令刷新緩存,這樣才能使賦權(quán)命令生效。畢業(yè)工作以后,在很多的技術(shù)文檔上,仍然可以看到這種解釋。

創(chuàng)新互聯(lián)專(zhuān)注于恩陽(yáng)網(wǎng)站建設(shè)服務(wù)及定制,我們擁有豐富的企業(yè)做網(wǎng)站經(jīng)驗(yàn)。 熱誠(chéng)為您提供恩陽(yáng)營(yíng)銷(xiāo)型網(wǎng)站建設(shè),恩陽(yáng)網(wǎng)站制作、恩陽(yáng)網(wǎng)頁(yè)設(shè)計(jì)、恩陽(yáng)網(wǎng)站官網(wǎng)定制、重慶小程序開(kāi)發(fā)公司服務(wù),打造恩陽(yáng)網(wǎng)絡(luò)公司原創(chuàng)品牌,更為您提供恩陽(yáng)網(wǎng)站排名全網(wǎng)營(yíng)銷(xiāo)落地服務(wù)。
但是,grant授權(quán)之后真的必須flush privilege嗎?如果不flush,授權(quán)真的就不生效嗎?
本篇文章也許會(huì)顛覆你的認(rèn)知。
grant語(yǔ)句都做了哪些事
grant語(yǔ)句一般和創(chuàng)建用戶(hù)配合使用,比如創(chuàng)建一個(gè)用戶(hù)之后,給這個(gè)用戶(hù)授予一定的權(quán)限,當(dāng)然,也可以對(duì)一個(gè)已存在的用戶(hù)授權(quán)。
我們以新建一個(gè)用戶(hù)testuser為例:
create user 'testuser'@'%' identified by 'pwd';
這條語(yǔ)句會(huì)往mysql.user表插入一行數(shù)據(jù),同時(shí)會(huì)往內(nèi)存中一個(gè)叫acl_users的數(shù)組中插入一個(gè)acl_user對(duì)象。
由于還沒(méi)有對(duì)這個(gè)用戶(hù)授權(quán),所以這個(gè)用戶(hù)在user表中權(quán)限字段都是N,在acl_users數(shù)組中的對(duì)象的access字段都是0,表示還沒(méi)有任何權(quán)限。
而對(duì)于一個(gè)用戶(hù)的權(quán)限來(lái)說(shuō),其范圍是不同的,分別為全局權(quán)限、DB權(quán)限、表權(quán)限、列權(quán)限。
全局權(quán)限
當(dāng)我們對(duì)一個(gè)用戶(hù)授予全局權(quán)限后,這個(gè)用戶(hù)就擁有了對(duì)整個(gè)數(shù)據(jù)庫(kù)實(shí)例的權(quán)限。
對(duì)testuser授予全局權(quán)限的寫(xiě)法:
grant all privileges on *.* to 'testuser'@'%' with grant option;
使用grant授權(quán)之后,mysql.user表中testuser這一行的權(quán)限字段的值就會(huì)全部變成Y,內(nèi)存中access的值也會(huì)變成1。
這時(shí),如果有新的數(shù)據(jù)庫(kù)鏈接接入,就可以從acl_users數(shù)組中查到這個(gè)用戶(hù)的權(quán)限,并且保存在當(dāng)前的線(xiàn)程對(duì)象。
總結(jié)一下就是,grant命令同時(shí)更新了磁盤(pán)和內(nèi)存的值,并且對(duì)于新鏈接會(huì)立刻生效,但是對(duì)于已經(jīng)存在的老的鏈接,則不會(huì)產(chǎn)生影響。
大家可以思考一下,為什么對(duì)于老的鏈接,grant命令不會(huì)立刻生效。
DB權(quán)限
DB權(quán)限就是給一個(gè)用戶(hù)單獨(dú)指定某個(gè)庫(kù)的所有權(quán)。
grant all privileges on db1.* to 'testuser'@'%' with grant option;
DB權(quán)限與全局權(quán)限的授權(quán)命令的區(qū)別在于指定了DB庫(kù):db1.*,而不是*.*。
執(zhí)行g(shù)rant命令之后,MySQL會(huì)往mysql.db表插入一條記錄,并且把權(quán)限字段的值置為Y,
另外增加一個(gè)對(duì)象到內(nèi)存中的acl_dbs中,access的值設(shè)置為1。
當(dāng)MySQL判斷一個(gè)用戶(hù)對(duì)某個(gè)數(shù)據(jù)庫(kù)的執(zhí)行權(quán)限時(shí),會(huì)遍歷這個(gè)acl_dbs數(shù)組,根據(jù)當(dāng)前的user、host地址、DB名匹配符合的記錄,并判斷其中的權(quán)限位。
DB權(quán)限和全局權(quán)限的不同點(diǎn)在于,全局權(quán)限查詢(xún)后會(huì)設(shè)置到當(dāng)前鏈接的線(xiàn)程對(duì)象中,每次判斷權(quán)限只需從線(xiàn)程對(duì)象中獲取判斷即可,而判斷DB權(quán)限需要每次遍歷acl_dbs數(shù)組。
由于每次判斷DB權(quán)限都需要去內(nèi)存中遍歷acl_dbs數(shù)組,而這個(gè)數(shù)組又是一個(gè)全局對(duì)象,所以使用grant操作DB權(quán)限后,會(huì)立刻對(duì)所有鏈接生效。
表權(quán)限和列權(quán)限
除了全局權(quán)限和DB權(quán)限,MySQL還支持我們定義粒度更細(xì)的表權(quán)限和列權(quán)限。
grant all privileges on db1.table1 to 'testuser'@'%' with grant option;
grant SELECT(id) ON db1.table1 TO 'testuser'@'%' with grant option;
grant表權(quán)限時(shí),MySQL會(huì)更新mysql.tables_priv表,
grant列權(quán)限時(shí),MySQL會(huì)更新mysql.columns_priv表,
同時(shí),這兩個(gè)操作都會(huì)觸發(fā)MySQL更新內(nèi)存中的hash表column_priv_hash。
?與DB權(quán)限一樣,對(duì)于表權(quán)限和列權(quán)限的修改,也會(huì)立刻影響到所有的鏈接。
那說(shuō)了這么多,看起來(lái)grant命令都是立刻生效了,好像也不需要執(zhí)行flush privileges了?
其實(shí)答案就是這樣的,grant命令授權(quán)后,并不需要再特意執(zhí)行flush privileges了。
flush privileges的使用場(chǎng)景
既然MySQL提供了flush privileges,說(shuō)明肯定有其適用的場(chǎng)景。
那么,flush privileges一般用在什么場(chǎng)景呢?
當(dāng)使用flush privileges時(shí),會(huì)清空內(nèi)存中的acl_users、acl_dbs等數(shù)組,然后從表mysql.users、mysql.db等表中重新加載數(shù)據(jù),
?換句話(huà)說(shuō),flush privileges主要用于使內(nèi)存中的權(quán)限和數(shù)據(jù)庫(kù)中保持一致。
一般來(lái)說(shuō),內(nèi)存中的數(shù)據(jù)和磁盤(pán)表中的數(shù)據(jù)都是一致的,但是當(dāng)我們直接使用DML語(yǔ)句修改權(quán)限表中的值時(shí),就會(huì)造成內(nèi)存和磁盤(pán)的數(shù)據(jù)不一致。
這時(shí),就需要使用flush privileges命令,刷新內(nèi)存,使內(nèi)存和磁盤(pán)的數(shù)據(jù)保持一致。
總結(jié)
使用grant命令之后,并不需要再隨手加上flush privileges,因?yàn)間rant 語(yǔ)句會(huì)同時(shí)修改數(shù)據(jù)表和內(nèi)存。
只有當(dāng)我們不規(guī)范的直接使用DML語(yǔ)句修改表中權(quán)限字段時(shí),才需要使用flush privileges刷新數(shù)據(jù)。
分享標(biāo)題:違背常識(shí),MySQL使用Grant授權(quán)后沒(méi)必要FlushPrivilege
標(biāo)題鏈接:http://www.fisionsoft.com.cn/article/djjeogj.html


咨詢(xún)
建站咨詢(xún)
