MySQL 事务与锁机制原理

1、事务

一组操作要么全部成功,要么全部失败,目的是为了保证数据最终的一致性

2、事务特性

(1)原子性 atomicity

当前事务的操作要么同时成功,要么同时失败。原子性由 undo log 日志来保证

(2)一致性 consistency

使用事务的最终目的,由业务代码正确逻辑保证

(3)隔离性 lsolation

在事务并发执行时,他们内部的操作不能互相干扰

(同一份数据被多个事务或多个线程操作,可能有并发安全问题。隔离性的意思是通过设置一些级别,让他们多个线程操作同一个数据时尽可能不相互干扰)

(3)持久性 durability

一旦提交了事务,它对数据库的改变就应该是永久性的,持久性由 redo log 日志来保证

(redo 利用磁盘顺序写,提高磁盘写数据的性能)

3、隔离级别

InnoDB 引擎中,定义了四种隔离级别,级别越高事务隔离性越好,但性能就越低,而隔离性是由 MySQL 的各种锁以及 MVCC 机制来实现的。

(1)read uncommit 读未提交

脏读:读取了别的事务的操作却未提交的数据

(2)read commit 读已提交

不可重复读:每次读的数据都不一样

(3)repeatable read 可重复读

不管别的线程如何修改数据,每次读到数据都是第一次查找时间点当时的结果

脏写:用不正确的数据更新在数据库内,覆盖了原有正确的数据

(4)serializable 串行

当一个事务没有提交,另一个事务无法读取数据,直到事务提交后,阻塞消失,另一个事务读取更新后的数据

总之,写的时候不能读,读的时候不能写

但是效率低

串行化就是在后台针对 select 语句后加上了读锁 lock in share mode;

4、锁

(1)读锁(共享锁、S )锁:select ... lock in share mode;

读锁是共享的,多个事务可以同时读取同一个资源,但不允许其他事务修改

(2)写锁(排他锁、X锁):select ... for update;

写锁是排他的,会阻塞其他的写锁和读锁,update、delect、insert 都会加写锁

读锁和写锁是互斥的,会相互等待的

5、MVCC (multi-version concurrency control)机制

多版本并发控制,可以做到读写不阻塞,且避免了类似脏读这样的问题,主要通过 undo 日志链来实现

read commit 读已提交,语句级快照

repeatable read 可重复读,事务级快照

account 表后台有两个隐藏字段:trx_id:记录事务版本 id,roll_pointer:指向 insert undo log 的指针

cow(copy on write)机制:写的时候复制一份数据。若要更新数据时,先将数据复制一份出来,再在副本上修改数据,对应的事务 trx_id 也需要修改 ,roll_pointer 指向原本数据,原本数据成为了副本的 undo log 数据,再提交。

可重复读,写的时候修改副本,读的时候取第一次查询时间下的数据

读已提交,读的时候查询最新已提交数据

6、大事务的影响

(1)并发情况下,数据库连接池容易被撑爆

(2)锁定太多数据,造成大量的阻塞和锁超时

(3)执行时间长,容易造成主从延迟

(4)回滚所需要的时间比较长

(5)undo log 膨胀

(6)容易导致死锁

7、长事务的优化

(1)将查询等数据准备操作放到事务外

(2)事务中避免远程调用,远程调用要设置超时,防止事务等待时间太久

(3)事务中避免一次性处理太多数据,可以拆分成多个事务分次处理

(4)更新等设计加锁的操作尽可能放在事务靠后的位置

(5)能异步处理的尽量异步处理

(6)应用侧(业务代码)保证数据一致性,非事务执行

8、索引

帮助 MySQL 高效获取数据的排好序数据结构

(排好序:叶子节点按从左往右依次递增的方式排列,为了更好支持范围查找,区间访问的性能)

索引数据结构:

1、二叉树

2、红黑树(二叉平衡树)

3、Hash 表

4、B树

MySQL 中索引数据结构为 B+树

9、B 树

1、叶节点具有相同的深度,叶节点的指针为空

2、所有索引元素不重复

3、节点中的数据索引从左到右递增排列

10、B+ 树

1、非叶子节点不存储 data,只存储索引(冗余),可以放更多的索引

2、叶子节点包含所有索引字段

3、叶子节点用指针连接,提高区间访问(范围查找)的性能

(data 指索引所在行的磁盘地址;索引都是从左往右递增存放)

当树高度为3时,叶子节点可存储的索引数量为:1170*1170*16。MySQL启动时会把非叶子节点的索引下载到内存,当查找一个索引时只会和磁盘做一次 IO 交互,其它都在内存中直接查找,这个速度非常快。

(叶子节点存放在硬盘上,使用的时候才加载到内存)

11、存储索引

MyISAM 索引文件和数据文件是分离的(非聚集索引)

索引文件在 MYI 文件,数据文件在 MYD 文件

InnoDB 索引实现(聚集索引)

表数据文件本身就是按 B+ 树组织的一个索引结构文件

聚集索引:叶节点包含了完整的数据记录,这种索引查找速度更快一些

InnoDB 表必须建主键,推荐使用整型的自增主键

(建了主键就会用主键索引维护整个 B+ 树;如果不用主键,会找到一个有不重复值的列来维护整个 B+ 树)

(从根节点开始查找数据过程中会进行大量的比大小操作,使用整型比大小比使用UUID字符串比大小的效率高,并且整型占用的存储空间要更小。自增的主键能够提升写数据插入数据的效率)

非主键索引结构叶子节点存储的是主键值(一致性和节省存储空间)

(非主键索引存储的是索引所在行的主键。当用非主键索引查找 InnoDB 表,首先定位到主键,再到主键索引中去查找索引所在行记录的数据,相当于一个非聚集索引)

12、联合索引的底层存储结构

先按第一个字段排序,若有重复再以第二字段排序,以此类推

上面是非主键索引,下面是主键索引

学习视频来源:【重点】阿里巴巴内部Mysql性能优化最佳实践_哔哩哔哩_bilibili

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值