原子性 (Atomicity)当前事务的操作要么同时成功,要么同时失败。原子性由undo log日志来实现。
一致性 (Consistency) : 使用事务的最终目的,由其它3个特性以及业务代码正确逻辑来实现。
隔离性 (lsolation) : 在事务并发执行时,他们内部的操作不能互相干扰,隔离性由MySQL的各种锁以及MVCC机制来实现。
持久性 (Durability) : 一旦提交了事务,它对数据库的改变就应该是永久性的。持久性由redo log日志来实现。
MVCC(Multi-Version Concurrency Control)多版本并发控制就可以做到读写不阻塞且避免了类似脏读这样的问题,主要通过undo日志链来实现。(undo 日志版本链在不同事务隔离级别基于可见性算法实现)。
select操作是快照读 (历史版本)
insert、update和delete是当前读 (当前版本)
read commit (读已提交),语句级快照
repeatable read (可重复读),事务级快照
序列化:本质是通过在select语句后面加了共享锁:lock in share mode;
大事务的影响
并发情况下,数据库连接池容易被撑爆;
锁定太多的数据,造成大量的阻塞和锁超时执行时间长,容易造成主从延迟;
回滚所需要的时间比较长;
undo log膨胀;
容易导致死锁;
事务优化实践原则
将查询等数据准备操作放到事务外
事务中避免远程调用,远程调用要设置超时,防止事务等待时间太久事务中避免一次性处理太多数据,可以拆分成多个事务分次处理
更新等涉及加锁的操作尽可能放在事务靠后的位置
能异步处理的尽量异步处理
应用侧(业务代码)保证数据一致性,非事务执行
事务问题定位
#查询执行时间超过1秒的事务,详细的定位问题方法后面讲完锁课程后会一起讲解
SELECT *
FROM
information_schema.innodb_trx
WHERE
TIME_TO_SEC( timediff( now( ),trx_started ) ) > 1;
#强制结束事务
kill 事务对应的线程id(就是上面语句查出结果里的trx_mysql_thread_id字段的值)
锁分类
乐观锁适合读操作更多的场景,悲观锁适合写操作较多的场景。
锁等待分析
通过检查InnoDB row lock状态变量来分析系统上的行锁的争夺情况。
show status like 'innodb_row_lock%';
对各个状态量的说明如下:
Innodb_row_lock_current_waits: 当前正在等待锁定的数量
Innodb_row_lock_time: 从系统启动到现在锁定总时间长度
Innodb_row_lock_time_avg: 每次等待所花平均时间
Innodb_row_lock_time_max: 从系统启动到现在等待最长的一次所花时间
Innodb_row_lock_waits: 系统启动后到现在总共等待的次数
对于这5个状态变量,比较重要的主要是:
Innodb_row_lock_time _avg (等待平均时长)
Innodb_row_lock_waits (等待总次数)
Innodb_row_lock_time (等待总时长)
间隙锁是在可重复读级别下才会生效
-- 查看事务
select * from INFORMATION SCHEMA.INNODB TRX;
-- 查看锁,8.0之后需要换成这张表data_locks
select * from INFORMATION SCHEMA.INNODB_LOCKS;
-- 查看锁等待8.0之后需要换成data_lock_waits
select * from INFORMATION SCHEMA.INNODB_LOCK_WAITS;
-- 查看锁等待详细信息
show engine innodb status;
锁优化实践
尽可能让所有数据检索都通过索引来完成,避免无索引行锁升级为表锁
合理设计索引,尽量缩小锁的范围
尽可能减少检索条件范围,避免间隙锁
尽量控制事务大小,减少锁定资源量和时间长度,涉及事务加锁的sql尽量放在事务最后执行
尽可能用低的事务隔离级别
sql执行流程:
WAL:Write-Ahead Logging 磁盘文件预写机制。
标签:事务,隔离,lock,Innodb,Mysql,机制,日志,row From: https://www.cnblogs.com/zhf123/p/17273979.html