mysql基本常识

一、mysql逻辑结构

  

首层连接处理、授权认证和安全等。

第二层架构包含mysql核心服务。包括查询解析、分析、优化、缓存以及所有的内置函数(例如:日期、时间、数学和加密函数),所有的跨存储引擎的功能都在这一层完成,比如存储过程、触发器、视图等。

第三层包含了存储引擎。存储引擎负责mysql的存储与提取。服务器通过API与存储引擎通信。这些接口屏蔽了不同存储引擎的差异。

二、并发控制

解决并发,需要两个类型的锁系统:共享锁和排他锁,也叫:读锁和写锁。读锁是共享的,是互相不阻塞的。多个用户在同一时刻可以同时读取同一个资源,而互不干扰。写锁是排他的,一个写锁会阻塞其他的写锁和读锁。
锁策略是在锁的开销和数据的安全性之间寻求平衡。锁粒度包括表锁和行级锁。

三、事务

事务时一组原子性的SQL查询。ACID表示原子性(atomicity)、一致性(consistency)、隔离性(isolation)和持久性(durability)。

隔离级别

READ UNCOMMITTED(未提交读),在该级别,事务中的修改,即使没有提交,其他事务也都是可见的。事务可以读取未提交的数据,被称为脏读。实际应用中很少。
READ COMMITTED(提交读),大多数数据库系统的默认隔离级别是该级别,但mysql不是。一个事务从开始直到提交之前,所做的任何修改对其他事务时不可见的。这个级别也叫不可重复读。
REPEATABLE READ (可重复读),该级别保证了在同一事务中多次读取同样记录的结果是一致的,解决了脏读问题。幻读指当某个事务在读取某个范围的记录是,另外一个事务又在该范围插入新的记录,当之前的事务再次读取该范围记录时,会产生幻行。InnoDB和XtraDB存储引擎通过多版本并发控制(MVCC)解决幻读问题。可重复读是mysql的默认事务隔离级别。
SERIALIZABLE(可串行化),是最高的隔离级别。在读取的每一行数据上都加锁,可能导致大量的超时和锁征用问题。实际应用中很少用到这个隔离级别。

死锁

死锁是指两个或多个事务在同一资源上相互占用,并请求对方占用的资源,从而导致恶性循环的现象。
为了解决死锁,数据库系统的实现了各种死锁检测和死锁超时机制。innoDB存储引擎能够检测到死锁的循环依赖,并立即返回一个错误。这种方法很有效,否则会产生非常慢的查询。另一种解决方式,当锁的等待时间超过设定的超时时间后放弃锁请求,这种方式不太好。
innoDB存储引擎在检测到死锁之后,将持有最少行级排他锁的事务进行回滚。

事务日志

事务日志可以提高事务的效率。使用事务日志,存储引擎在修改表的数据时只需要修改其内存拷贝,再把该修改行为记录持久在硬盘的事务日志中,而不是每次都将修改的事务本身持久到磁盘。事务日志采用的是追加的方式,因此写日志的操作是磁盘上一小块区域的顺序I/O,而不像随机I/O需要在磁盘多个地方移动磁头,所以采用事务日志的方式相对来说要快的多。事务日志持久以后,内存中被修改的数据在后台中可以慢慢的刷回到磁盘。目前大多数存储引擎是这样实现的,通常称之为预写式日志(write-ahead longging),修改数据需要写两次磁盘。

四、多版本并发控制

mysql的大多数事务型存储引擎的实现都不是单纯的行级锁。基于提升并发性能的考虑,都实现了多版本并发控制(MVCC),可以认为MVCC是行级锁的一个变种,它多数情况下避免加锁操作,因此开销更低。
MVCC的实现,是通过保存数据在某个时间点的快照来实现的。也就是说,不管执行多长时间,每个事务看到的数据是一致的。根据事务开始的时间不同,每个事务对同一张表,同一时刻看到的数据可能是不一样的。
innoDB的MVCC是通过每行记录后面保存两个隐藏的列来实现的。这两个列一个保存了行的创建时间,一个保存了行的过期时间(或删除时间)。当然存储的不是实际的时间值,而是系统版本号。每开始一个新的事务,系统版本号都会自动递增。事务开始时的系统版本号将作为该线程的版本号。用来和查询到的每行记录的版本号进行比较。
在REPEATABLE READ隔离级别下,MVCC的具体操作:
SELECT:
innoDB会根据会根据以下两个条件检查每行记录:
1、innoDB只查找版本号早于当前事务版本的数据行(也就是,行的系统版本号小于或等于事务的系统版本号),这样可以确保事务的读取行,要么在事务开始前已经存在,要么是事务自身插入或修改过的。
2、行的删除版本要么未定义,要么大于当前事务版本号。这可以确保事务读取的行在事务开始之前未被删除。
只有符合这两个条件的记录,才可以被作为查询结果返回。
INSERT:
innoDB为新插入的每一行保存当前系统版本号作为行版本号。
DELETE:
innoDB为删除的每一行保存当前系统版本号作为行删除标识。
UPDATE:
inniDB为插入一行新纪录,保存当前系统版本号作为行版本号;同时保存当前系统版本号作为原来的行删除标识。
保存这两个额外系统版本号,可以使大多数操作都可以不用加锁。这样设计可以使数据操作很简单,性能很好,并且也能保证只会读取到符合标准的行。不足之处是每行记录都要额外的存储空间,需要更多的行检查操作,以及额外的维护工作。
MVCC只在REPEATABLE READ 和READ COMMITED两个隔离级别下工作。因为READ UNCOMMITED 只读取最新的数据行,而不是符合当前事务版本的数据行。SERIALIZABLE则会对所有读取的行都加锁。










猜你喜欢

转载自blog.csdn.net/missA_fei/article/details/52120399