锁主要解决写-写问题,mvcc用来解决读-写问题
MyISAM不使用行级锁,主要使用表锁
MyISAM存储引擎主要使用表锁(table-level locking),并不支持行级锁(row-level locking)。当MyISAM存储引擎执行修改数据(如INSERT、UPDATE、DELETE)的操作时,会在相关的表上加锁,这阻止了其他用户对同一表的写操作,但仍然允许读操作。由于MyISAM锁的粒度较大(整个表),它可能会在高并发的应用中成为瓶颈。
innodb默认使用行级锁,还会使用表锁
InnoDB默认行为是在需要时自动使用行级锁
尽管如此,InnoDB也可以使用表锁,特别是在执行全表操作(如ALTER TABLE)时。
BDB还有页锁
innodb的锁的mode和type
mode:读锁,写锁,意向读锁,意向写锁,自增锁(自增锁,auto字段添加,插入时会阻塞,值加一,并且事务回滚也不会回滚,所以可能不连续)
type:表锁,行锁
行子类型:间隙锁,行锁,邻键锁(间隙锁+行锁)
间隙锁和邻键锁用于解决幻读问题
主要用于保证可重复读(REPEATABLE READ)隔离级别下的一致性,
两阶段锁定协议
InnoDB遵循两阶段锁定协议来管理事务中的锁。这意味着事务在其执行过程中先加锁,直到事务结束(提交或回滚)才释放所有锁。
innnodb的行锁上在聚簇索引或者二级索引,存储在锁管理器这个数据结构中
锁的设置过程
- 当一个事务试图访问数据库中的一行数据时,InnoDB会检查是否有适合该查询的索引。
- 如果有,InnoDB通过索引查找到具体的数据行。
- 根据操作的类型(读取或写入),InnoDB决定施加共享锁还是独占锁。
- 如果索引是二级索引,InnoDB可能首先在二级索引上设置锁,然后通过二级索引找到聚簇索引中的实际数据行,再在聚簇索引的数据行上设置必要的锁。
- 锁信息被记录在内存中的锁表中。每当其他事务试图访问相同的数据行时,都会首先检查这个锁表来决定是否可以立即访问该行,还是需要等待或是触发死锁解决机制。
锁的管理
锁的信息并不存储在物理的索引结构中,而是在内存中的一个特定的数据结构(通常是哈希表)中管理。
这种设计允许InnoDB快速处理锁的检查和冲突解决,减少对数据库性能的影响。
在InnoDB中,意向锁的设计主要是为了在表级别表明事务对行级锁的意图
意向锁的加锁流程:意向锁只加载表上
一个事务想加行级锁,需要先给表加意向锁。
意向表锁的冲突
表有独占锁,加任何意向锁。
表有共享锁,加意向独占锁。尽管两个事务可能操作不同的行,意向锁仍然必须管理和协调事务之间在表级别的访问,以保证整个表的数据完整性和事务的隔离需求。
mysql给操作加共享锁指令
select * where id<10 lock in share mode;//加共享锁
select * where id<10 for update;//加独占锁