日日操夜夜添-日日操影院-日日草夜夜操-日日干干-精品一区二区三区波多野结衣-精品一区二区三区高清免费不卡

公告:魔扣目錄網(wǎng)為廣大站長(zhǎng)提供免費(fèi)收錄網(wǎng)站服務(wù),提交前請(qǐng)做好本站友鏈:【 網(wǎng)站目錄:http://www.ylptlb.cn 】, 免友鏈快審服務(wù)(50元/站),

點(diǎn)擊這里在線咨詢客服
新站提交
  • 網(wǎng)站:51998
  • 待審:31
  • 小程序:12
  • 文章:1030137
  • 會(huì)員:747

1.1 鎖概述

鎖是計(jì)算機(jī)協(xié)調(diào)多個(gè)進(jìn)程或線程并發(fā)訪問(wèn)某一資源的機(jī)制(避免爭(zhēng)搶)。

在數(shù)據(jù)庫(kù)中,除傳統(tǒng)的計(jì)算資源(如 CPU、RAM、I/O 等)的爭(zhēng)用以外,數(shù)據(jù)也是一種供許多用戶共享的資源。如何保證數(shù)據(jù)并發(fā)訪問(wèn)的一致性、有效性是所有數(shù)據(jù)庫(kù)必須解決的一個(gè)問(wèn)題,鎖沖突也是影響數(shù)據(jù)庫(kù)并發(fā)訪問(wèn)性能的一個(gè)重要因素。從這個(gè)角度來(lái)說(shuō),鎖對(duì)數(shù)據(jù)庫(kù)而言顯得尤其重要,也更加復(fù)雜。

1.2 鎖分類

從對(duì)數(shù)據(jù)操作的粒度分 :

1) 表鎖:操作時(shí),會(huì)鎖定整個(gè)表。

2) 行鎖:操作時(shí),會(huì)鎖定當(dāng)前操作行。

從對(duì)數(shù)據(jù)操作的類型分:

1) 讀鎖(共享鎖):針對(duì)同一份數(shù)據(jù),多個(gè)讀操作可以同時(shí)進(jìn)行而不會(huì)互相影響。

2) 寫鎖(排它鎖):當(dāng)前操作沒(méi)有完成之前,它會(huì)阻斷其他寫鎖和讀鎖。

1.3 MySQL 鎖

相對(duì)其他數(shù)據(jù)庫(kù)而言,MySQL的鎖機(jī)制比較簡(jiǎn)單,其最顯著的特點(diǎn)是不同的存儲(chǔ)引擎支持不同的鎖機(jī)制。下表中羅列出了各存儲(chǔ)引擎對(duì)鎖的支持情況:

MySQL-鎖機(jī)制詳述

 

MySQL這3種鎖的特性可大致歸納如下 :

MySQL-鎖機(jī)制詳述

 

從上述特點(diǎn)可見(jiàn),很難籠統(tǒng)地說(shuō)哪種鎖更好,只能就具體應(yīng)用的特點(diǎn)來(lái)說(shuō)哪種鎖更合適!僅從鎖的角度來(lái)說(shuō):表級(jí)鎖更適合于以查詢?yōu)橹鳎挥猩倭堪此饕龡l件更新數(shù)據(jù)的應(yīng)用,如Web 應(yīng)用;而行級(jí)鎖則更適合于有大量按索引條件并發(fā)更新少量不同數(shù)據(jù),同時(shí)又有并查詢的應(yīng)用,如一些在線事務(wù)處理(OLTP)系統(tǒng)。

1.2 MyISAM 表鎖

MyISAM 存儲(chǔ)引擎只支持表鎖,這也是MySQL開始幾個(gè)版本中唯一支持的鎖類型。

1.2.1 如何加表鎖

MyISAM 在執(zhí)行查詢語(yǔ)句(SELECT)前,會(huì)自動(dòng)給涉及的所有表加讀鎖,在執(zhí)行更新操作(UPDATE、DELETE、INSERT 等)前,會(huì)自動(dòng)給涉及的表加寫鎖,這個(gè)過(guò)程并不需要用戶干預(yù),因此,用戶一般不需要直接用 LOCK TABLE 命令給 MyISAM 表顯式加鎖。

顯示加表鎖語(yǔ)法:

create database demo_03 default charset=utf8mb4;
?
use demo_03;
?
CREATE TABLE `tb_book` (
  `id` INT(11) auto_increment,
  `name` VARCHAR(50) DEFAULT NULL,
  `publish_time` DATE DEFAULT NULL,
  `status` CHAR(1) DEFAULT NULL,
  PRIMARY KEY (`id`)
) ENGINE=myisam DEFAULT CHARSET=utf8 ;
?
INSERT INTO tb_book (id, name, publish_time, status) VALUES(NULL,'JAVA編程思想','2088-08-01','1');
INSERT INTO tb_book (id, name, publish_time, status) VALUES(NULL,'solr編程思想','2088-08-08','0');
?
?
?
CREATE TABLE `tb_user` (
  `id` INT(11) auto_increment,
  `name` VARCHAR(50) DEFAULT NULL,
  PRIMARY KEY (`id`)
) ENGINE=myisam DEFAULT CHARSET=utf8 ;
?
INSERT INTO tb_user (id, name) VALUES(NULL,'令狐沖');
INSERT INTO tb_user (id, name) VALUES(NULL,'田伯光');
?
1.2.2 讀鎖案例

準(zhǔn)備環(huán)境

create database demo_03 default charset=utf8mb4;
?
use demo_03;
?
CREATE TABLE `tb_book` (
  `id` INT(11) auto_increment,
  `name` VARCHAR(50) DEFAULT NULL,
  `publish_time` DATE DEFAULT NULL,
  `status` CHAR(1) DEFAULT NULL,
  PRIMARY KEY (`id`)
) ENGINE=myisam DEFAULT CHARSET=utf8 ;
?
INSERT INTO tb_book (id, name, publish_time, status) VALUES(NULL,'java編程思想','2088-08-01','1');
INSERT INTO tb_book (id, name, publish_time, status) VALUES(NULL,'solr編程思想','2088-08-08','0');
?
CREATE TABLE `tb_user` (
  `id` INT(11) auto_increment,
  `name` VARCHAR(50) DEFAULT NULL,
  PRIMARY KEY (`id`)
) ENGINE=myisam DEFAULT CHARSET=utf8 ;
?
INSERT INTO tb_user (id, name) VALUES(NULL,'令狐沖');
INSERT INTO tb_user (id, name) VALUES(NULL,'田伯光');
?

客戶端 一 :

1)獲得tb_book 表的讀鎖

insert into tb_book values(null,'Mysql高級(jí)','2088-01-01','1');

2) 執(zhí)行查詢操作

insert into tb_book values(null,'Mysql高級(jí)','2088-01-01','1');
MySQL-鎖機(jī)制詳述

 

可以正常執(zhí)行 , 查詢出數(shù)據(jù)。

客戶端 二 :

3) 執(zhí)行查詢操作

insert into tb_book values(null,'Mysql高級(jí)','2088-01-01','1');
MySQL-鎖機(jī)制詳述

 

客戶端 一 :

4)查詢未鎖定的表

insert into tb_book values(null,'Mysql高級(jí)','2088-01-01','1');
MySQL-鎖機(jī)制詳述

 

客戶端 二 :

5)查詢未鎖定的表

insert into tb_book values(null,'Mysql高級(jí)','2088-01-01','1');
MySQL-鎖機(jī)制詳述

 

可以正常查詢出未鎖定的表;

客戶端 一 :

6) 執(zhí)行插入操作

insert into tb_book values(null,'Mysql高級(jí)','2088-01-01','1');
MySQL-鎖機(jī)制詳述

 

執(zhí)行插入, 直接報(bào)錯(cuò) , 由于當(dāng)前tb_book 獲得的是 讀鎖, 不能執(zhí)行更新操作。

客戶端 二 :

7) 執(zhí)行插入操作

insert into tb_book values(null,'Mysql高級(jí)','2088-01-01','1');
MySQL-鎖機(jī)制詳述

 

當(dāng)在客戶端一中釋放鎖指令 unlock tables 后 , 客戶端二中的 inesrt 語(yǔ)句 , 立即執(zhí)行 ;

1.2.3 寫鎖案例

客戶端 一 :

1)獲得tb_book 表的寫鎖

lock table tb_book write ;

2)執(zhí)行查詢操作

select * from tb_book ;
MySQL-鎖機(jī)制詳述

 

查詢操作執(zhí)行成功;

3)執(zhí)行更新操作

update tb_book set name = 'java編程思想(第二版)' where id = 1;
MySQL-鎖機(jī)制詳述

 

更新操作執(zhí)行成功 ;

客戶端 二 :

4)執(zhí)行查詢操作

select * from tb_book ;
MySQL-鎖機(jī)制詳述

 

當(dāng)在客戶端一中釋放鎖指令 unlock tables 后 , 客戶端二中的 select 語(yǔ)句 , 立即執(zhí)行 ;

MySQL-鎖機(jī)制詳述

 

1.2.4 結(jié)論

鎖模式的相互兼容性如表中所示:

MySQL-鎖機(jī)制詳述

 

由上表可見(jiàn):

1) 對(duì)MyISAM 表的讀操作,不會(huì)阻塞其他用戶對(duì)同一表的讀請(qǐng)求,但會(huì)阻塞對(duì)同一表的寫請(qǐng)求;

2) 對(duì)MyISAM 表的寫操作,則會(huì)阻塞其他用戶對(duì)同一表的讀和寫操作;

簡(jiǎn)而言之,就是讀鎖會(huì)阻塞寫,但是不會(huì)阻塞讀。而寫鎖,則既會(huì)阻塞讀,又會(huì)阻塞寫。

此外,MyISAM 的讀寫鎖調(diào)度是寫優(yōu)先,這也是MyISAM不適合做寫為主的表的存儲(chǔ)引擎的原因。因?yàn)閷戞i后,其他線程不能做任何操作,大量的更新會(huì)使查詢很難得到鎖,從而造成永遠(yuǎn)阻塞。

1.2.5 查看鎖的爭(zhēng)用情況
show open tables;
MySQL-鎖機(jī)制詳述

 

In_user : 表當(dāng)前被查詢使用的次數(shù)。如果該數(shù)為零,則表是打開的,但是當(dāng)前沒(méi)有被使用。

Name_locked:表名稱是否被鎖定。名稱鎖定用于取消表或?qū)Ρ磉M(jìn)行重命名等操作。

show status like 'Table_locks%';
MySQL-鎖機(jī)制詳述

 

Table_locks_immediate : 指的是能夠立即獲得表級(jí)鎖的次數(shù),每立即獲取鎖,值加1。

Table_locks_waited : 指的是不能立即獲取表級(jí)鎖而需要等待的次數(shù),每等待一次,該值加1,此值高說(shuō)明存在著較為嚴(yán)重的表級(jí)鎖爭(zhēng)用情況。

1.3 InnoDB 行鎖

1.3.1 行鎖介紹

行鎖特點(diǎn) :偏向InnoDB 存儲(chǔ)引擎,開銷大,加鎖慢;會(huì)出現(xiàn)死鎖;鎖定粒度最小,發(fā)生鎖沖突的概率最低,并發(fā)度也最高。

InnoDB 與 MyISAM 的最大不同有兩點(diǎn):一是支持事務(wù);二是 采用了行級(jí)鎖。

1.3.2 背景知識(shí)

事務(wù)、ACID屬性、事務(wù)隔離級(jí)別,詳情請(qǐng)看:事務(wù)特性及隔離級(jí)別詳述

1.3.3 InnoDB 的行鎖模式

InnoDB 實(shí)現(xiàn)了以下兩種類型的行鎖。

  • 共享鎖(S):又稱為讀鎖,簡(jiǎn)稱S鎖,共享鎖就是多個(gè)事務(wù)對(duì)于同一數(shù)據(jù)可以共享一把鎖,都能訪問(wèn)到數(shù)據(jù),但是只能讀不能修改。
  • 排他鎖(X):又稱為寫鎖,簡(jiǎn)稱X鎖,排他鎖就是不能與其他鎖并存,如一個(gè)事務(wù)獲取了一個(gè)數(shù)據(jù)行的排他鎖,其他事務(wù)就不能再獲取該行的其他鎖,包括共享鎖和排他鎖,但是獲取排他鎖的事務(wù)是可以對(duì)數(shù)據(jù)就行讀取和修改。

對(duì)于UPDATE、DELETE和INSERT語(yǔ)句,InnoDB會(huì)自動(dòng)給涉及數(shù)據(jù)集加排他鎖(X);

對(duì)于普通SELECT語(yǔ)句,InnoDB不會(huì)加任何鎖;

可以通過(guò)以下語(yǔ)句顯示給記錄集加共享鎖或排他鎖 。

共享鎖(S):SELECT * FROM table_name WHERE ... LOCK IN SHARE MODE
?
排他鎖(X) :SELECT * FROM table_name WHERE ... FOR UPDATE
1.3.4 案例準(zhǔn)備工作
create table test_innodb_lock(
    id int(11),
    name varchar(16),
    sex varchar(1)
)engine = innodb default charset=utf8;
?
insert into test_innodb_lock values(1,'100','1');
insert into test_innodb_lock values(3,'3','1');
insert into test_innodb_lock values(4,'400','0');
insert into test_innodb_lock values(5,'500','1');
insert into test_innodb_lock values(6,'600','0');
insert into test_innodb_lock values(7,'700','0');
insert into test_innodb_lock values(8,'800','1');
insert into test_innodb_lock values(9,'900','1');
insert into test_innodb_lock values(1,'200','0');
?
create index idx_test_innodb_lock_id on test_innodb_lock(id);
create index idx_test_innodb_lock_name on test_innodb_lock(name);
1.3.5 行鎖基本演示
MySQL-鎖機(jī)制詳述

 

1.3.6 無(wú)索引行鎖升級(jí)為表鎖

如果不通過(guò)索引條件檢索數(shù)據(jù),那么InnoDB將對(duì)表中的所有記錄加鎖,實(shí)際效果跟表鎖一樣。

查看當(dāng)前表的索引 : show index from test_innodb_lock ;

MySQL-鎖機(jī)制詳述

 


MySQL-鎖機(jī)制詳述

 

由于 執(zhí)行更新時(shí) , name字段本來(lái)為varchar類型, 我們是作為數(shù)組類型使用,存在類型轉(zhuǎn)換,索引失效,最終行鎖變?yōu)楸礞i ;

1.3.7 間隙鎖危害

當(dāng)我們用范圍條件,而不是使用相等條件檢索數(shù)據(jù),并請(qǐng)求共享或排他鎖時(shí),InnoDB會(huì)給符合條件的已有數(shù)據(jù)進(jìn)行加鎖; 對(duì)于鍵值在條件范圍內(nèi)但并不存在的記錄,叫做 "間隙(GAP)" , InnoDB也會(huì)對(duì)這個(gè) "間隙" 加鎖,這種鎖機(jī)制就是所謂的 間隙鎖(Next-Key鎖) 。

示例 :

MySQL-鎖機(jī)制詳述

 

1.3.8 InnoDB 行鎖爭(zhēng)用情況
show  status like 'innodb_row_lock%';
MySQL-鎖機(jī)制詳述

 

Innodb_row_lock_current_waits: 當(dāng)前正在等待鎖定的數(shù)量
?
Innodb_row_lock_time: 從系統(tǒng)啟動(dòng)到現(xiàn)在鎖定總時(shí)間長(zhǎng)度
?
Innodb_row_lock_time_avg:每次等待所花平均時(shí)長(zhǎng)
?
Innodb_row_lock_time_max:從系統(tǒng)啟動(dòng)到現(xiàn)在等待最長(zhǎng)的一次所花的時(shí)間
?
Innodb_row_lock_waits: 系統(tǒng)啟動(dòng)后到現(xiàn)在總共等待的次數(shù)
?
當(dāng)?shù)却拇螖?shù)很高,而且每次等待的時(shí)長(zhǎng)也不小的時(shí)候,我們就需要分析系統(tǒng)中為什么會(huì)有如此多的等待,然后根據(jù)分析結(jié)果著手制定優(yōu)化計(jì)劃。
1.3.9 總結(jié)

InnoDB存儲(chǔ)引擎由于實(shí)現(xiàn)了行級(jí)鎖定,雖然在鎖定機(jī)制的實(shí)現(xiàn)方面帶來(lái)了性能損耗可能比表鎖會(huì)更高一些,但是在整體并發(fā)處理能力方面要遠(yuǎn)遠(yuǎn)由于MyISAM的表鎖的。當(dāng)系統(tǒng)并發(fā)量較高的時(shí)候,InnoDB的整體性能和MyISAM相比就會(huì)有比較明顯的優(yōu)勢(shì)。

但是,InnoDB的行級(jí)鎖同樣也有其脆弱的一面,當(dāng)我們使用不當(dāng)?shù)臅r(shí)候,可能會(huì)讓InnoDB的整體性能表現(xiàn)不僅不能比MyISAM高,甚至可能會(huì)更差。

優(yōu)化建議:

  • 盡可能讓所有數(shù)據(jù)檢索都能通過(guò)索引來(lái)完成,避免無(wú)索引行鎖升級(jí)為表鎖。
  • 合理設(shè)計(jì)索引,盡量縮小鎖的范圍
  • 盡可能減少索引條件,及索引范圍,避免間隙鎖
  • 盡量控制事務(wù)大小,減少鎖定資源量和時(shí)間長(zhǎng)度
  • 盡可使用低級(jí)別事務(wù)隔離(但是需要業(yè)務(wù)層面滿足需求)

分享到:
標(biāo)簽:機(jī)制 MySQL
用戶無(wú)頭像

網(wǎng)友整理

注冊(cè)時(shí)間:

網(wǎng)站:5 個(gè)   小程序:0 個(gè)  文章:12 篇

  • 51998

    網(wǎng)站

  • 12

    小程序

  • 1030137

    文章

  • 747

    會(huì)員

趕快注冊(cè)賬號(hào),推廣您的網(wǎng)站吧!
最新入駐小程序

數(shù)獨(dú)大挑戰(zhàn)2018-06-03

數(shù)獨(dú)一種數(shù)學(xué)游戲,玩家需要根據(jù)9

答題星2018-06-03

您可以通過(guò)答題星輕松地創(chuàng)建試卷

全階人生考試2018-06-03

各種考試題,題庫(kù),初中,高中,大學(xué)四六

運(yùn)動(dòng)步數(shù)有氧達(dá)人2018-06-03

記錄運(yùn)動(dòng)步數(shù),積累氧氣值。還可偷

每日養(yǎng)生app2018-06-03

每日養(yǎng)生,天天健康

體育訓(xùn)練成績(jī)?cè)u(píng)定2018-06-03

通用課目體育訓(xùn)練成績(jī)?cè)u(píng)定