redo log 是事务持久性的保证
undo log 是事务原子性的保证
锁机制 是事务隔离性的保证
MySQL的自动加锁依赖于数据库的事务机制。当事务对某个数据行进行更新操作时,MySQL就会自动给该行加上排他锁,防止其他事务同时对其进行修改。同时,MySQL也会对读操作进行共享锁的加锁机制,确保读取的数据不被其他事务修改
MySQL的加锁机制是自动的,但人为干预也有其必要性。通过使用不同的加锁方式,可以灵活地掌控事务的并发控制,从而提高数据库的性能和安全性。
begin;
select * from table_name for share nowait 、 select * from table_name for share skip locked
myisam 存储引擎 只支持表锁
innodb 存在引擎 支持 表锁、页锁、行锁
查看锁的情况
show open tables ; # show open tables where in_use>0; 查看有锁的记录
lock tables 表 read ## 共享锁
lock tables 表 write ## 排它锁
unlock tables ## 解锁
mysql 中 可以为某个列,加 Auto_increment 。
create table student(
stu_no int not null auto_increment,
stu_name varchar(20) not null
) engine = innodb default charset=utf8mb4 collate=utf8mb4_0900_ai_ci;
auto_increment 修饰的列,在添加数据的时候,可以省略或 null。
可以**预先确定要插入的行数(当语句被初始化处理时)**的语句。包括没有嵌套子查询的单行和多行
insert 。。。。 values() 和 replace 语句
例如
insert into student(stu_name) values(‘zen’),(‘zen-ares’);
**事先不知道要插入的行数(和所需要自动递增值的数量)**的语句。
insert 。。。。select ,replace。。。。select 和 load data 语句
innodb在处理一行,auto_increment 列分配一个新值
innodb_autoinc_lock_mode
0:传统
1:连续
2:交错
mdl锁,属于表锁范畴。MDL的作用是,保证读写的正确性。如果一个事务中一个查询正在遍历一个表的数据,而执行期间(事务没结束或终止)另一个线程(事务)对这个表结构做变更,增加一列,那么第一个事务的查询拿到的结构集跟表结构对不上,这个肯定是不行的。
对一个表做增删改查操作的时候,加 MDL读锁;当要对表做结构变更操作的时候,加MDL写锁
MDL读锁之间不互斥,因此可以多个线程(事务)同时对一个表增删改查。
MDL读写锁之间、mdl写锁之间是互斥的,用来保证变更表结构操作的安全性。
解决DML(如下)和DDL操作之间的一致性问题。不需要显示使用,跟意向锁一样,由引擎自动加解。
MDL在访问一个表的时候会被自动加上。
封锁记录中的间隔,防止间隔中被其他事务插入。
间隙锁主要出现在RR隔离级别,避免出现幻读。
行锁分三类
Record Lock,记录锁,也就是仅仅把一条记录锁上;
Gap Lock,间隙锁,锁定一个范围,但是不包含记录本身,只存在于可重复读隔离级别,目的是为了解决可重复读隔离级别下幻读的现象
Next-Key Lock:临键锁 Record Lock + Gap Lock 的组合,锁定一个范围,并且锁定记录本身。
当事务执行 commit 后,事务过程中生成的锁都会被释放。
Gap Lock 称为间隙锁,只存在于可重复读隔离级别,目的是为了解决可重复读隔离级别下幻读的现象。
next-key lock 即能保护该记录,又能阻止其他事务将新纪录插入到被保护记录前面的间隙中。 (a,b]
一个事务在插入一条记录的时候,需要判断插入位置是否已被其他事务加了间隙锁(next-key lock 也包含间隙锁)。
如果有的话,插入操作就会发生阻塞,直到拥有间隙锁的那个事务提交为止(释放间隙锁的时刻),在此期间会生成一个插入意向锁,表明有事务想在某个区间插入新记录,但是现在处于等待状态。