MySQL锁及MVCC的原理分析

本文探讨了MySQL中InnoDB和MyISAM两种常用存储引擎的差异,重点在于锁的原理和事务处理。InnoDB支持行级锁和事务处理,适合高并发和对事务安全性要求高的场景;而MyISAM采用表级锁,适合读取频繁且更新操作较少的情况。了解锁机制有助于优化数据库性能和避免并发问题。
摘要由CSDN通过智能技术生成

MySQL中的数据用不同的技术存储在文件或内存中。每种技术都使用不同的存储机制、索引技巧、锁定水平并且最终提供广泛的不同的功能和能力。这些不同的技术称之为存储引擎。通过选择不同的存储引擎,你能够获得额外的速度或者功能,从而改善你的应用的整体功能。

引擎有InnoDB,MyIsam,Memory,Mrg_Myisam,Blackhole....(SHOW ENGINES-查看改数据库支持的搜索引擎),下文中只对两种常用的存储引擎InnoDB,MyIsam作比较。

# 查询该数据库的所有搜索引擎
SHOW ENGINES

开始测试插入

# myisam引擎建立表
create table testMyIsam(  
id int unsigned primary key auto_increment,  
name varchar(20) not null  
)engine=myisam; 

# innodb引擎建立表
create table testInnoDB( 
id int unsigned primary key auto_increment, 
name varchar(20) not null 
)engine=innodb;  


# 我们使用存储过程来插入更新删除记录,以此来比较插入效率,更新效率,删除效率,查询效率
# 创建存储过程
delimiter $$
create procedure ptestmyisam()
begin
declare pid int ;
set pid = 30000;
while pid>0 
do
insert into testMyIsam(name) values(concat("fuzhu", pid));
set pid = pid-1;
end while;
end $$

# 删除存储过程
drop procedure if exists ptestmyisam;

#使用存储过程:
call ptestmyisam();

# 在插入3W条记录时myisam速度是innodb三倍左右 

通过测试,MyIsam的增删改查速度比InnoDB非常快,这是因为MyIsam不支持事务而InnoDB支持事务。但是普通的增删改是必须要考虑事务安全的,所以我们还是选择速度比较慢的InnoDB。

使用 InnoDB:

1.可靠性高或者要求事务处理,则使用InnoDB。这个是必须的。

2.表更新和查询都相当的频繁,并且表锁定的机会比较大的情况指定InnoDB数据引擎的创建。

使用 MyISAM:

1.做很多count的计算的。如一些日志,调查的业务表。

2.插入修改不频繁,查询非常频繁的。

引擎原理

https://blog.csdn.net/qq_21993785/article/details/80582373

锁原理

是否开启事务,何时加锁(增删改查),加什么锁(行锁表锁共享锁排它锁....) 数据库会自动决定的,所以我们不懂锁机制也可以开开心心写代码

# 在执行下面查询前,存储引擎会自动加一个共享锁(读锁)。
select * from tablea;

# 在执行下面查询前,存储引擎会自动加一个排它锁(写锁)。
update * from tablea;
update table set column1='hello' where id=1
INSERT INTO `user` (`id`, `name`) VALUES ('1', 'a');

事务

# 查看当前所选库的提交模式
show variables like 'autocommit';
# 关闭当前库自动提交(仅仅临时有效,切换库后会自动恢复至默认开启状态)
set autocommit = 'OFF';
# 更新操作
update testInnoDB set name = 'www' where id = 1
# 回退
rollback
# 手动提交
COMMIT;

#-----------------------------------------------------------------------------

# 不用关心当前提交模式,sql直接开启事务
start transaction
# 更新操作
update testInnoDB set name = 'www' where id = 1
# 回退
rollback
# 手动提交
COMMIT;

# 当然啦,存储引擎InnoDB是支持事务的,所以上面测试有效,而存储引擎MyIsam不支持事务,所以无论开启事务与否,都无效的

MyISAM存储引擎支持的是表级锁,不支持行锁。默认是表锁

InnoDB存储引擎既支持表级锁,又支持行级锁,默认是行锁。(行锁通过给索引上的索引项加锁来实现行锁)

更新(update)或删除(delete)SQL语句是会加锁的,查询(select)或插入(insert)SQL语句不会加锁,如果更新或删除的时候使用到了索引那么这个锁就是行锁,反之就是表锁。查询或插入的时候无论是否使用了索引都不会加锁。

手动加锁的SQL是 ........FOR UPDATE。因为更新和删除是默认加锁的,我们手动加不加锁没有意义也无法对比,所以我们可以对查询和插入进行手动加锁,这样可以对比。select * from testtable where id = 1 for Update;(这个语句使用到了索引,我们对这个语句加锁,所以这个锁为行锁)

注意:select * from testtable where id = 1 for Updateupdate  testtable set name = 'wenjian' where id = 5 当我们执行这个SQL的时候,引擎在瞬间完成(加锁,更新,解锁)三个步骤,我们根本来不及进行测试,这时候我们可以开启下事务(这样我们就有足够时间去测试啦)

注意:因为行锁这个特性,所以数据库支持高并发,但是如果InnoDB更新数据的时候不是行锁而是表锁的话,那么其并发性会大打折扣,而且也可能导致你的程序出错。

注意:判断sql是行锁还是表锁是依靠sql是否使用了索引来判断的,我们可以借助explain sql语句,当type=index或range 时候,可以判断这sql使用了索引,进而来确定他使用的是行级锁

注意:行级锁分为两种S(共享锁)和X(排它锁),表级锁也分为两种S(共享锁)和X(排它锁)

表级锁:开销小,加锁快;不会出现死锁;锁定粒度大,发生锁冲突的概率最高,并发度最低。 
行级锁:开销大,加锁慢;会出现死锁;锁定粒度最小,发生锁冲突的概率最低,并发度也最高。 
页面锁:开销和加锁时间界于表锁和行锁之间;会出现死锁;锁定粒度界于表锁和行锁之间,并发度一般

 

# 产看数据库版本
select version();

# varchar(20) char(20) 
mysql5.0 版本前 代表20个字节(假设编码utf8,可以存储20个字母或6个汉字,一个汉字三个字节)
mysql5.0 版本后 代表20个字符 如果存字母就是20个字节,如果是汉字 就是60个字节

# 查看该字段的字节
select *, length(char4) from user;

# 查看mysql中支持的字符集,Maxlen 是该字符集中一个字符所占的最大字节数
SHOW CHARSET

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值