十年網(wǎng)站開發(fā)經(jīng)驗(yàn) + 多家企業(yè)客戶 + 靠譜的建站團(tuán)隊(duì)
量身定制 + 運(yùn)營(yíng)維護(hù)+專業(yè)推廣+無(wú)憂售后,網(wǎng)站問(wèn)題一站解決
服務(wù)器由兩種表的鎖定方法:

創(chuàng)新互聯(lián)公司于2013年開始,先為撫順縣等服務(wù)建站,撫順縣等地企業(yè),進(jìn)行企業(yè)商務(wù)咨詢服務(wù)。為撫順縣企業(yè)網(wǎng)站制作PC+手機(jī)+微官網(wǎng)三網(wǎng)同步一站式服務(wù)解決您的所有建站問(wèn)題。
1.內(nèi)部鎖定
內(nèi)部鎖定可以避免客戶機(jī)的請(qǐng)求相互干擾——例如,避免客戶機(jī)的SELECT查詢被另一個(gè)客戶機(jī)的UPDATE查詢所干擾。也可以利用內(nèi)部鎖定機(jī)制防止服務(wù)器在利用myisamchk或isamchk檢查或修復(fù)表時(shí)對(duì)表的訪問(wèn)。
語(yǔ)法:
鎖定表:LOCK TABLES tbl_name {READ | WRITE},[ tbl_name {READ | WRITE},…]
解鎖表:UNLOCK TABLES
LOCK TABLES為當(dāng)前線程鎖定表。UNLOCK TABLES釋放被當(dāng)前線程持有的任何鎖。當(dāng)線程發(fā)出另外一個(gè)LOCK TABLES時(shí),或當(dāng)服務(wù)器的連接被關(guān)閉時(shí),當(dāng)前線程鎖定的所有表自動(dòng)被解鎖。
如果一個(gè)線程獲得在一個(gè)表上的一個(gè)READ鎖,該線程(和所有其他線程)只能從表中讀。如果一個(gè)線程獲得一個(gè)表上的一個(gè)WRITE鎖,那么只有持鎖的線程READ或WRITE表,其他線程被阻止。
每個(gè)線程等待(沒(méi)有超時(shí))直到它獲得它請(qǐng)求的所有鎖。
WRITE鎖通常比READ鎖有更高的優(yōu)先級(jí),以確保更改盡快被處理。這意味著,如果一個(gè)線程獲得READ鎖,并且然后另外一個(gè)線程請(qǐng)求一個(gè)WRITE鎖, 隨后的READ鎖請(qǐng)求將等待直到WRITE線程得到了鎖并且釋放了它。
顯然對(duì)于檢查,你只需要獲得讀鎖。再者鐘情跨下,只能讀取表,但不能修改它,因此他也允許其它客戶機(jī)讀取表。對(duì)于修復(fù),你必須獲得些所以防止任何客戶機(jī)在你對(duì)表進(jìn)行操作時(shí)修改它。
2.外部鎖定
服務(wù)器還可以使用外部鎖定(文件級(jí)鎖)來(lái)防止其它程序在服務(wù)器使用表時(shí)修改文件。通常,在表的檢查操作中服務(wù)器將外部鎖定與myisamchk或isamchk作合使用。但是,外部鎖定在某些系統(tǒng)中是禁用的,因?yàn)樗荒芸煽康倪M(jìn)行工作。對(duì)運(yùn)行myisamchk或isamchk所選擇的過(guò)程取決于服務(wù)器是否能使用外部鎖定。如果不使用,則必修使用內(nèi)部鎖定協(xié)議。
如果服務(wù)器用--skip-locking選項(xiàng)運(yùn)行,則外部鎖定禁用。該選項(xiàng)在某些系統(tǒng)中是缺省的,如Linux??梢酝ㄟ^(guò)運(yùn)行mysqladmin variables命令確定服務(wù)器是否能夠使用外部鎖定。檢查skip_locking變量的值并按以下方法進(jìn)行:
◆
如果skip_locking為off,則外部鎖定有效您可以繼續(xù)并運(yùn)行人和一個(gè)實(shí)用程序來(lái)檢查表。服務(wù)器和實(shí)用程序?qū)⒑献鲗?duì)表進(jìn)行訪問(wèn)。但是,運(yùn)行任何一個(gè)實(shí)用程序之前,應(yīng)該使用mysqladmin
flush-tables。為了修復(fù)表,應(yīng)該使用表的修復(fù)鎖定協(xié)議。
◆
如果skip_locaking為on,則禁用外部鎖定,所以在myisamchk或isamchk檢查修復(fù)表示服務(wù)器并不知道,最好關(guān)閉服務(wù)器。如果堅(jiān)持是服務(wù)器保持開啟狀態(tài),月確保在您使用此表示沒(méi)有客戶機(jī)來(lái)訪問(wèn)它。必須使用卡黨的鎖定協(xié)議告訴服務(wù)器是該表不被其他客戶機(jī)訪問(wèn)。
檢查表的鎖定協(xié)議
本節(jié)只介紹如果使用表的內(nèi)部鎖定。對(duì)于檢查表的鎖定協(xié)議,此過(guò)程只針對(duì)表的檢查,不針對(duì)表的修復(fù)。
1.調(diào)用mysql發(fā)布下列語(yǔ)句:
$mysql –u root –p db_namemysqlLOCK TABLE tbl_name READ;mysqlFLUSH TABLES;
該鎖防止其它客戶機(jī)在檢查時(shí)寫入該表和修改該表。FLUSH語(yǔ)句導(dǎo)致服務(wù)器關(guān)閉表的文件,它將刷新仍在告訴緩存中的任何為寫入的改變。
2.執(zhí)行檢查過(guò)程
$myisamchk tbl_name$ isamchk tbl_name
3.釋放表鎖
mysqlUNLOCK TABLES;
如果myisamchk或isamchk指出發(fā)現(xiàn)該表的問(wèn)題,將需要執(zhí)行表的修復(fù)。
修復(fù)表的鎖定協(xié)議
這里只介紹如果使用表的內(nèi)部鎖定。修復(fù)表的鎖定過(guò)程類似于檢查表的鎖定過(guò)程,但有兩個(gè)區(qū)別。第一,你必須得到寫鎖而非讀鎖。由于你需要修改表,因此根本不允許客戶機(jī)對(duì)其進(jìn)行訪問(wèn)。第二,必須在執(zhí)行修復(fù)之后發(fā)布FLUSH
TABLE語(yǔ)句,因?yàn)閙yisamchk和isamchk建立的新的索引文件,除非再次刷新改表的高速緩存,否則服務(wù)器不會(huì)注意到這個(gè)改變。本例同樣適合優(yōu)化表的過(guò)程。
1.調(diào)用mysql發(fā)布下列語(yǔ)句:
$mysql –u root –p db_namemysqlLOCK TABLE tbl_name WRITE;mysqlFLUSH TABLES;
2.做數(shù)據(jù)表的拷貝,然后運(yùn)行myisamchk和isamchk:
$cp tbl_name.* /some/other/dir$myisamchk --recover tbl_name$ isamchk --recover tbl_name
--recover選項(xiàng)只是針對(duì)安裝而設(shè)置的。這些特殊選項(xiàng)的選擇將取決與你執(zhí)行修復(fù)的類型。
3.再次刷新高速緩存,并釋放表鎖:
mysqlFLUSH TABLES;mysqlUNLOCK TABLES;
1、在mysql數(shù)據(jù)庫(kù)中如何鎖定一行數(shù)據(jù),保證不被其他的操作影響。
2、從對(duì)數(shù)據(jù)的操作類型分為讀鎖和寫鎖。從對(duì)數(shù)據(jù)操作的粒度來(lái)分:表鎖和行鎖。
3、現(xiàn)在我們建立一個(gè)表來(lái)演示數(shù)據(jù)庫(kù)的行鎖講解。
4、行鎖基本演示如下圖所示。
5、如果兩個(gè)會(huì)話操作的是不同的行,就不會(huì)互相阻塞了。
白話解說(shuō)如下:
簡(jiǎn)單說(shuō),就是lock table,不讓別人動(dòng)
鎖分共享鎖和排它鎖。
共享鎖時(shí),別人能讀,不能改變量表數(shù)據(jù)
排它鎖時(shí),別人既不能讀,也不能改表數(shù)據(jù)
根據(jù)以上特點(diǎn),應(yīng)該就知道何時(shí)使用鎖了。不想讓別人變更數(shù)據(jù),對(duì)自己產(chǎn)生影響,就加鎖。一定要在不用之后,進(jìn)行鎖釋放,不然,應(yīng)用系統(tǒng)會(huì)一直因?yàn)樽x取數(shù)據(jù)而報(bào)錯(cuò)。
好處就是,保證數(shù)據(jù)的原子性,完整性,一致性。 只有加鎖者釋放了鎖,別人才能改變數(shù)據(jù)。
缺點(diǎn)就是,增加了系統(tǒng)開銷,有可能產(chǎn)生鎖等待,造成數(shù)據(jù)庫(kù)運(yùn)行異常。這都是不正常的使用鎖帶來(lái)的問(wèn)題。
mysql 為并發(fā)事務(wù)同時(shí)對(duì)一條記錄進(jìn)行讀寫時(shí),提出了兩種解決方案:
1)使用 mvcc 的方法,實(shí)現(xiàn)多事務(wù)的并發(fā)讀寫,但是這種讀只是“快照讀”,一般讀的是歷史版本數(shù)據(jù),還有一種是“當(dāng)前讀”,一般加鎖實(shí)現(xiàn)“當(dāng)前讀”,或者 insert、update、delete 也是當(dāng)前讀。
2)使用加鎖的方法,鎖分為共享鎖(讀鎖),排他鎖(寫鎖)
快照讀:就是select
當(dāng)前讀:特殊的讀操作,插入/更新/刪除操作,屬于當(dāng)前讀,處理的都是當(dāng)前的數(shù)據(jù),需要加鎖。
mysql 在 RR 級(jí)別怎么處理幻讀的呢?一般來(lái)說(shuō),RR 級(jí)別通過(guò) mvcc 機(jī)制,保證讀到低于后面事務(wù)的數(shù)據(jù)。但是 select for update 不會(huì)觸發(fā) mvcc,它是當(dāng)前讀。如果后面事務(wù)插入數(shù)據(jù)并提交,那么在 RR 級(jí)別就會(huì)讀到插入的數(shù)據(jù)。所以,mysql 使用 行鎖 + gap 鎖(簡(jiǎn)稱 next-key 鎖)來(lái)防止當(dāng)前讀的時(shí)候插入。
Gap Lock在InnoDB的唯一作用就是防止其他事務(wù)的插入操作,以此防止幻讀的發(fā)生。
Innodb自動(dòng)使用間隙鎖的條件:
InnoDB默認(rèn)是行級(jí)別的鎖,當(dāng)有明確指定的主鍵時(shí)候,是行級(jí)鎖。否則是表級(jí)別。
例子: 假設(shè)表foods ,存在有id跟name、status三個(gè)字段,id是主鍵,status有索引。
例1: (明確指定主鍵,并且有此記錄,行級(jí)鎖)
例2: (明確指定主鍵/索引,若查無(wú)此記錄,無(wú)鎖)
例3: (無(wú)主鍵/索引,表級(jí)鎖)
例4: (主鍵/索引不明確,表級(jí)鎖)
for update的注意點(diǎn)
for update的疑問(wèn)點(diǎn)
mysql鎖機(jī)制是在并發(fā)操作的時(shí)候,避免多人同時(shí)操作而發(fā)生錯(cuò)誤。
先說(shuō)一下表級(jí)鎖吧
表級(jí)鎖 一般引擎都支持,資源消耗小。申請(qǐng)鎖的時(shí)候 整表鎖定(分讀寫鎖),其它線程或操作不能進(jìn)行操作
行級(jí)鎖 INNODB引擎支持。資源消耗大 鎖定的時(shí)候 被鎖的行只能進(jìn)行一個(gè)操作 其它均不能操作些行。