一 并发控制
1.1读写锁
读锁
读锁是共享的,或者说是互不阻塞的,多个客户端可以在同一时刻读取同一资源,互不干扰。
写锁
写锁是排他的,一个写锁会阻塞其他的写锁和读锁。
在实际开发过程中mysql每时每刻都发生锁定,当用户修改一部分数据是,mysql会进行锁定,防止其他用户读取同一数据。
1.2 锁粒度
锁的各种操作 包括 获得锁 检查锁是否已经解除,释放等,都会增加开销,所谓的锁就是在开销和数据安全之间进行一个平衡。
表锁(table lock)
表锁是mysql中最基本的锁策略,并且是开销最小的锁。当一个用户进行插入 删除 更新等 就会获得写锁 会阻塞其他用户的读写操作。
服务器会对alter table 的语句进行表锁,忽略存储引擎的锁机制。
行级锁(row lock)
行级锁最大程度的支持并发处理,同时也带来了最大的系统开销。InnoDB是支持行级锁的。
1.3事务
事务就是一个工作单元,有一系列的sql语句,如果其中一个不执行,那个这些语句就都不会执行。
事务的特性
1.原子性:
一个事务是最小单元,所有操作要么成功,要么全部回滚。
2.一致性:
数据库总会从一个一致性状态到另一个一致性状态。
3.隔离性:
在一个事务的最终提交前,对其他事务通常是不可见的。
4.持久性:
一旦事务提交,所做的修改就会永久的保存在数据库中。S
4种隔离级别
1.READ UNCOMMITTED(未提交读):
在这个级别中,数据的修改即使没提交,对于其他事务也是可见的,这个级别会导致很多问题,一般很少用。
2.READ COMMITTEND(提交读):
这个级别的操作,在提交之前,不会被别的事务看见的。
3.REPEATABLE READ(可重复读):
在同一次事务中,多次读取同样的记录,结果是一样的。这是mysql的默认级别。
4.SERIALIZABLE(可串行化):
强行串行事务,可能会超时,导致锁的竞争,一般很少用。
1.4死锁
死锁是指两个或者多个事务在同一个资源上相互占用,并且请求对方占用的资源,导致恶性循环。
innodb采用了死锁检测机制,能检测到所得循环依赖,innodb会将持有最少排他锁的事务进行回滚。
1.5mysql中的事务
1.自动提交
mysql默认采用自动提交(autocommit),就是如果不是显示的开启一个事务,每个查询都会被当做一次事务提交。
innodb支持显示行级锁:
select ... lock in share mode;
select ... for update;
1.6 MVCC
innodb的MVCC通过在每行数据后面加两个隐藏列来实现的。这两列,一个保存了创建时间,一个保存了过期时间(或者是删除时间)。当然存储的不是真正的时间值 而是系统的版本号。没开启一个新的事物,系统的版本号会自动递增。事务开始时的系统版本号会作为事务的版本号,用来和查询的每行数据进行比较。
select
a.innodb 只会查找早于当前事务版本的数据行(行的系统版本号,小于或者等于事务的版本号)。
b.innodb 行的删除版本号要么未定义,要么大于当前事务的版本号,保证数据在事务开始之前没有被删除。
insert
innodb为insert的数据保存当前系统的版本号作为行的版本号。
delete
innodb为删除的每一行数据保存当前的系统版本号作为行的删除标识
update
innodb 插入一条新的记录,保存当前的版本号为行的版本号,同时保存当前系统版本号到原来行作为删除标识
这种机制可以保证大部分读操作可以不用加锁。
1.7innodb概述
innodb的数据保存在表空间中tablespace,表空间是innodb管理的一个黑盒子。数据和索引单独存放。
innodb的主键是聚簇索引,二级索引必须包含主键。
innodb支持数据的热备份。
1.8myisam
myisam支持压缩,全文索引等。不支持事务和行级锁。对于只读的数据或者表比较小应该采用myisam数据库。
数据文件存在 .myd 索引文件存在 .myi
mysql数据以紧密型存储。