MySQL設(shè)置數(shù)據(jù)庫(kù)為只讀
前言:
默認(rèn)情況下,我們的 MySQL 實(shí)例是可讀寫的。但有些情況下,我們可以將整個(gè)實(shí)例設(shè)置為只讀狀態(tài),比如做遷移維護(hù)的時(shí)候或者將從庫(kù)設(shè)為只讀。本篇文章我們來(lái)看下 MySQL 設(shè)置只讀相關(guān)知識(shí)。
? 1.關(guān)于 read_only 參數(shù)
MySQL系統(tǒng)中,提供有 read_only 和 super_read_only 兩個(gè)只讀參數(shù),參考官方文檔,這里介紹下這兩個(gè)參數(shù)的作用:
read_only 參數(shù)默認(rèn)不開(kāi)啟,開(kāi)啟后會(huì)阻止沒(méi)有 super 權(quán)限的用戶執(zhí)行數(shù)據(jù)庫(kù)變更操作。開(kāi)啟后,普通權(quán)限用戶執(zhí)行插入、更新、刪除等操作時(shí),會(huì)提示 --read-only 錯(cuò)誤。但具有 super 權(quán)限的用戶仍可執(zhí)行變更操作。
super_read_only 參數(shù)同樣默認(rèn)關(guān)閉,開(kāi)啟后不僅會(huì)阻止普通用戶,也會(huì)阻止具有 super 權(quán)限的用戶對(duì)數(shù)據(jù)庫(kù)進(jìn)行變更操作。
read_only 和 super_read_only 是有關(guān)聯(lián)的,二者之間的關(guān)系如下:
設(shè)置 super_read_only=on ,也就隱式地設(shè)置了 read_only=on。
設(shè)置 read_only=off ,也就隱式地設(shè)置了 super_read_only=off。
可以單獨(dú)開(kāi)啟 read_only 而不開(kāi)啟 super_read_only。
不過(guò),從庫(kù)開(kāi)啟 read_only 并不影響主從同步,即 salve 端仍然會(huì)讀取 master 上的日志,并且在 slave 實(shí)例中應(yīng)用日志,保證主從數(shù)據(jù)庫(kù)同步一致。(經(jīng)測(cè)試,從庫(kù)端開(kāi)啟 super_read_only 仍不影響主從同步。)
下面我們具體來(lái)操作下,看下 read_only 參數(shù)的用法:
#?查看?read_only?參數(shù)
mysql>?show?global?variables?like?'%read_only%';
+-----------------------+-------+
|?Variable_name?????????|?Value?|
+-----------------------+-------+
|?innodb_read_only??????|?OFF???|
|?read_only?????????????|?OFF???|
|?super_read_only???????|?OFF???|
|?transaction_read_only?|?OFF???|
|?tx_read_only??????????|?OFF???|
+-----------------------+-------+
#?動(dòng)態(tài)修改?read_only?參數(shù)?(若想重啟生效?則需將?read_only?=?1?加入配置文件中)
mysql>?set?global?read_only?=?1;
Query?OK,?0?rows?affected?(0.00?sec)
mysql>?show?global?variables?like?'read_only';
+---------------+-------+
|?Variable_name?|?Value?|
+---------------+-------+
|?read_only?????|?ON????|
+---------------+-------+
#?read_only?開(kāi)啟的情況下?操作數(shù)據(jù)
#?使用超級(jí)權(quán)限用戶
mysql>?create?table?tb_a?(a?int);
Query?OK,?0?rows?affected?(0.05?sec)
#?使用普通權(quán)限用戶
mysql>?create?table?tb_b?(b?int);?
ERROR?1290?(HY000):?The?MySQL?server?is?running?with?the?--read-only?option?so?it?cannot?execute?this?statement
#?開(kāi)啟?super_read_only,再次使用超級(jí)權(quán)限用戶來(lái)操作數(shù)據(jù)
mysql>?set?global?super_read_only?=?1;
Query?OK,?0?rows?affected?(0.00?sec)
mysql>?show?global?variables?like?'super_read_only';
+-----------------+-------+
|?Variable_name???|?Value?|
+-----------------+-------+
|?super_read_only?|?ON????|
+-----------------+-------+
mysql>?create?table?tb_c?(c?int);??
ERROR?1290?(HY000):?The?MySQL?server?is?running?with?the?--super-read-only?option?so?it?cannot?execute?this?statement
#?關(guān)閉?read_only?參數(shù)
mysql>?set?global?read_only?=?0;
Query?OK,?0?rows?affected?(0.00?sec)? 2.flush tables with read lock 設(shè)置
除了 read_only 參數(shù)外,執(zhí)行 flush tables with read lock 也可將數(shù)據(jù)庫(kù)設(shè)置為只讀狀態(tài),那么二者有什么區(qū)別呢?我們先來(lái)了解下 flush tables with read lock 的作用。
執(zhí)行此命令會(huì)給數(shù)據(jù)庫(kù)加全局讀鎖,使得數(shù)據(jù)庫(kù)處于只讀狀態(tài),以下語(yǔ)句會(huì)被阻塞:數(shù)據(jù)更新語(yǔ)句(增刪改)、數(shù)據(jù)定義語(yǔ)句(建表、修改表結(jié)構(gòu)等)和更新類事務(wù)的提交語(yǔ)句。下面我們來(lái)具體實(shí)驗(yàn)下:
#?執(zhí)行FTWRL
mysql>?flush?tables?with?read?lock;
Query?OK,?0?rows?affected?(0.02?sec)
#?進(jìn)行數(shù)據(jù)變更操作
mysql>?insert?into?tb_a?values?(1);
ERROR?1223?(HY000):?Can't?execute?the?query?because?you?have?a?conflicting?read?lock
#?解鎖
mysql>?unlock?tables;
Query?OK,?0?rows?affected?(0.00?sec)
mysql>?insert?into?tb_a?values?(1);
Query?OK,?1?row?affected?(0.01?sec)值得注意的是,從庫(kù)端執(zhí)行 flush tables with read lock 會(huì)導(dǎo)致 SQL 線程卡住,主備延遲。與開(kāi)啟 read_only 參數(shù)不同的是,執(zhí)行 flush tables with read lock 后,其余客戶端執(zhí)行數(shù)據(jù)變更操作會(huì)持續(xù)等待而不是立即報(bào)錯(cuò),極其容易引起數(shù)據(jù)庫(kù) hang 住,執(zhí)行這個(gè)命令還是要小心的。
以個(gè)人數(shù)據(jù)庫(kù)運(yùn)維經(jīng)驗(yàn)來(lái)講,一般只有從庫(kù)需要設(shè)置只讀狀態(tài),從庫(kù)端建議開(kāi)啟 read_only 或 super_read_only,避免人為寫入。flush tables with read lock 適用于進(jìn)行數(shù)據(jù)遷移時(shí),可以保證數(shù)據(jù)庫(kù)不發(fā)生數(shù)據(jù)改變,不過(guò)要注意及時(shí)解鎖。
總結(jié):
本篇文章主要介紹了 MySQL 只讀狀態(tài)相關(guān)知識(shí),其實(shí)除了從庫(kù)外,其余實(shí)例很少設(shè)置全局只讀,只是遇到某種需求的情況下需要將數(shù)據(jù)庫(kù)設(shè)為只讀狀態(tài),寫本篇文章的目的也是遇到此類需求時(shí),可以有個(gè)參考。
PS:
先給各位小伙伴說(shuō)聲抱歉,近期因工作等各種事情沒(méi)抽出時(shí)間寫文章,導(dǎo)致發(fā)文頻率有所降低。請(qǐng)各位放心,以后技術(shù)文章還會(huì)有,有想投稿的小伙伴也可以加我微信與我聯(lián)系哦。
推薦閱讀
(點(diǎn)擊標(biāo)題可跳轉(zhuǎn)閱讀)
