mvcc原理
行级锁:操作对象是数据库表中的一行。是mvcc技术用的比较多的,行级锁对系统开销较大,但处理高并发较好。
mvcc使得大部分支持行锁的事务引擎,不再单纯的使用行锁来进行数据库的并发控制,取而代之的是把数据库的行锁与行的多个版本结合起来,只需要很小的开销,就可以实现非锁定读,从而大大提高数据库系统的并发性能。
mvcc工作过程
InnoDB的mvcc,是通过在每行记录后面保存两个隐藏的列来实现的。这两个列,一个保存了行的创建版本号,一个保存了行的删除版本号。每开始一个新的事务,系统版本号都会自动递增。事务开始时刻的系统版本号会作为事务的版本号,用来和查询到的每行记录的版本号进行比较。在repeatable read隔离级别下,mvcc具体的操作如下:
undo log工作简化流程为:开启事务,记录数据行数据快照到undo logo,更新数据,将undo log写到磁盘,将数据写到磁盘,提交事务。
1)为了保证数据的持久化数据要在事务提交之前持久化
2)undo log的持久化必须在数据持久化之前,这样才能保证系统崩溃时,可以用undo log来回滚事务
Innodb中的隐藏列
Inoodb通过undo log保存了已更改行的旧版本的信息的快照
Innodb的内部实现中为每一行数据增加了三个隐藏列用于实现mvcc
select
InnoDB会根据以下两个条件检查每行记录:
1、InnoDB只查找版本早于当前事务版本的数据行。这样可以确保事务读取的行,要么是在事务开始前已经存在,要么是事务自身插入或者修改过的。
2、行的删除版本,要么未定义,要么大于当前事务版本号。这样可以确保事务读取到的行,在事务开始之前未被删除。
只有符合上述两个条件的记录,才能作为查询结果返回。
insert
InnoDB为插入的每一行保存当前系统版本号作为行版本号。
delete
InnoDB为删除的每一行保存当前系统版本号作为行删除标识。
update
InnoDB为插入一行新纪录,保存当前系统版本号作为行版本号,同时,作为原来的行作为行删除标识。
mvcc优缺点
大多数情况下代替了行锁,实现了对读的非阻塞,读不加锁,读写不冲突。缺点是每行记录都需要额外的存储空间,需要做更多的行维护和检查工作。
1.mvcc只适用于mysql隔离级别中的读已提交和可重复读。
2.读为提交由于存在脏读,即能读到未提交事务的数据行,所以不适用mvcc
原因是mvcc的创建版本号和删除版本只在事务提交后才会产生。
3、串行化由于是会对所涉及到的表加锁,并非行锁,自然不存在行的版本控制问题。
4、mvcc主要作用于事务性的,有行锁控制的数据库模型。
mysql主从原理
读写分离:主服务器处理写操作以及实时性要求比较高的读操作,从而服务器处理读操作。
读写分离能提高性能的原因在于:
- 主从服务器负责各自的读和写,极大程度缓解了锁的争用。
- 从服务器可以使用MyISAM,提升查询性能以及节约系统开销
- 增加冗余,提高可用性
读写分离常用代理方式来实现,代理服务器接受应用层传来的读写请求,然后决定转发到哪个服务器
分库分表
- 水平切分:一个表中的数据不断增多时,把这些记录拆分结构不变的表,达到分布式的目的。水平拆分可以支撑非常大的数据量。
- 分表为了提升mysql并发能力,水平拆分最好分库。
- 垂直切分:是指表列的拆分,把一张列比较多的表拆分为多张表。
存储引擎
InnoDB是MySQL默认的事务型存储引擎,只有在需要它不支持特性时,才考虑使用其他存储引擎。
- 实现了四个标准的隔离级别,默认级别是可重复读。
- 主索引是聚簇索引,在索引中保存了数据,从而避免了直接读磁盘,
- 内存做了很多优化,
MyISAM设计简单,数据以紧密格式存储。不支持事务。
索引的底层结构
索引是B+树索引,在B+Tree中,一个节点中的key从左到右非递减排序。
操作
进行查找操作,首先在根节点进行二分查找,找到一个key所在的指针,然后递归地在指针所指向的节点进行查找。直到查找到叶子节点,然后在叶子节点进行二分查找,找出key多对应的data。
MySQL索引可以指定多个列作为索引列,多个索引列共同组城键。
适合于全键值,键值范围和键前缀查找。
- InnoDB的B+Tree索引分为主索引和辅助索引。
- 聚簇索引:主索引的叶子节点data域记录着完整单位数据记录。
- 辅助索引:的叶子节点data域记录着主键的值,因此在和使用辅助索引进行查找时,需要先查到主键值,然后再到主索引中进行查找。