一、mysql体系和存储引擎
1、数据库和数据库实例的区别
数据库:存储数据的文件
数据库实例:可以操作数据的程序
2、mysql体系
a、连接池
b、管理服务和工具组件,backup、security等
c、sql接口,dml、ddl等
d、查询分析器
e、优化器
f、缓存
g、插件式存储引擎
h、数据文件
二、innoDB存储引擎
1、概述
事物安全的存储引擎,是OLTP(在线事物处理器)应用核心表中的首选存储引擎,是第一个完整支持acid事物的mysql存储引擎,其特点是支持行锁设计、支持MVCC(多版本并发控制)、支持外键、提供一致性锁定读,同事被设计来最有效的使用内存和cpu
2、innoDB体系架构
后台线程:负责刷新内存池中的数据,保证缓冲池的内存缓存的数据都是最近的数据,此外将已经修改的数据文件刷新到磁盘文件,同时保障在数据库发生异常的时候能恢复到正常运行的状态
masterThread:核心后台线程,主要负责将缓冲池的数据异步刷新到磁盘,保证数据的一致性,包括脏页的刷新,合并插入缓冲,undo页回收等。
IO thead:innodo中大量使用了AIO来处理io请求,这样极大提高数据库的性能,主要工作是处理IO的回调处理,包括read、write、insert buffer、log
purge Thread:事物被提交后,其所使用的undolog不再使用,因此需要purge thread来回收已经使用并分配的undo 页
page clear thread :1.2.x版本后才引入的,作用是将之前版本中的脏页的刷新操作放在单独的线程中来完成
内存:
缓冲池:innoDB存储引擎是基于磁盘存储的,并将其中的记录按照页的方式进行管理,基于磁盘的数据库通常使用缓冲池技术来提高数据库性能,缓冲池也是一个内存区域
读取页:首先先从磁盘读取到缓冲池中(将页FIX到缓冲池),下一次读取相同页,若在缓冲池中,直接读取,否则,从磁盘读取
修改页:首先修改缓冲池中的页,再以一定的频率刷新到磁盘上,但是不是每一次页的修改都会触发刷新,通过checkpoint机制刷回
3、checkpoint技术
a、从缓冲池当中刷新数据到磁盘时,如果发生宕机,数据会丢失,所以采用write ahead log策略,即当事物提交时,先写重做日志,再修改页。
b、checkpoint目的是解决以下问题
缩短数据库的恢复时间
缓冲池不够用时,将脏页刷新会磁盘
重做日志不可用时,刷新脏页
4、innoDB的关键特性
插入缓冲:和数据页一样,也是物理页的一部分,满足:索引是辅助索引,索引不是唯一索引
两次写:带来数据页的可靠性,double write分为2部分,第一部分是内存中的double buffer,大小为2M,另一部分是物理磁盘上的共享表空间中连续的128页,即2个区,也是2M。在对缓冲区刷新磁盘时,并不直接写磁盘,而是会通过memcpy函数先将脏页复制到内存中的 doublewrite buffer中,之后分两次,每次1M顺序写入共享表空间的磁盘上,然后马上通过调用fsync函数同步磁盘,避免缓冲写带来的问题。
自适应哈希索引:innoDB会自动根据访问的频率和模式来自动的给某些热点页创建哈希索引
异步IO:
刷新邻接页:
三、表
1、索引组织表
innoDB存储引擎中,表都是根据主键顺序组织存放的
2、innoDB逻辑存储结构
表空间(tablespace):innoDB存储引擎逻辑结构的最高层,所有数据都放在表空间中
段(segment):数据段、索引段、回滚段等。数据段为B+数的叶子节点,索引段为B+数的非叶子节点
区(extend):区是连续页组成的空间,任何情况下,区的大小为1M。
页(page):页是innoDB磁盘管理的最小单位,默认每页16Kb
行(row):innoDb存储引擎数据是按行进行存放的,每个页最多存放16K/2 -200 = 7992行记录
3、约束
约束和索引的区别:
约束:代表一种逻辑概念,保证数据的完整性
索引:索引是一种数据结构,既有逻辑上的概念,也代表着物理存储的方式
4、分区表
概念:
5.1版本之后增加的分区的支持,分区的过程是将一个表或者索引分解为多个、更小的,更可管理的部分。
目前只支持水平拆分,且为局部分区索引,一个分区中既存放了数据又存放了索引
分区和性能:
对于OLAP(在线分析处理)的应用,分区可以很好的提高查询的性能
对于OLTP的应用,分区应非常小心,这种应用,通常不会获取太多数据,大部分是根据索引返回几条记录,根据B+数的原理,对于一张大表,一般的B+数需要2·3次磁盘IO,因此不需要分区的帮助,并且设计不好的分区会带来严重的性能问题
四、索引与算法
1、innoDB支持三种索引:
B+树索引:B+数不能直接找到数据所在行,而是找到数据行所在的页,然后数据库将页读入内存,在内存中查找获取记录行
全文索引:
hash自适应索引:innoDB自动为某些热点数据创建hash索引
2、数据结构与算法
二分查找法:折半查找法,在一组有序数据中找到指定值
二叉查找树与平衡二叉树:
3、B+树
精简介绍:B+树是为磁盘和其他存取辅助设备设计的一种平衡查找树
4、B+树索引
聚集索引:按照每张表的主键构建一个B+树,同时叶子节点存放的是整张表的行记录数据,也将聚集索引的叶子节点称为数据页,每张表只能拥有一个聚集索引
辅助索引:叶子节点不包含行记录的全部数据,叶子节点除了包含键值外,还包含了一个书签(bookmark),用来告诉innoDB哪里可以找到对应的行数据。
5、cardinality值
表示高选择性,表示索引中不重复记录数的预估值, cardinality/n_rows_in_table应尽可能接近于1 ,如果值很小,则考虑是否有必要创建这个索引。
6、B+树索引的使用
1)不同应用(OLTP、OLAP)中B+树索引的应用
OLTP:B+树索引创建后,对该索引的使用应该只是通过该索引获取表中少部分的数据,这时B+索引才有意义,否则优化器可能不会使用索引。
OLAP:因为OLAP应用只需要访问大量的数据,通常对时间字段添加索引
2)联合索引:
3)覆盖索引:从辅助索引中就可以得到数据记录,不用去聚集索引中获取。使用辅助索引的一个好处就是,辅助索引不包含完整数据记录,其大小要远小于聚集索引,因此可以减少大量的IO操作。
4)优化器选择不使用索引的情况:这种情况大多发生于范围查找、join连接操作等
a、对于不能进行索引覆盖的情况,优化器选择辅助索引的情况是,通过辅助索引查找的数据是少量的
5)索引提示:用户可以指定某个索引进行查询,最可靠的是使用FORCE INDEX,而不是用USE INDEX
6)multi-range-read(MRR)优化
目的:减少磁盘的随机访问,并且将随机访问转化为顺序访问,适用于range、ref,eq_ref类型的查询
此外,MRR还可以将某些范围查询,拆分为键值对,一次来进行批量的数据查询,这样做的好处是在拆分的过程中,过滤掉一些不符合查询条件的数据。
7)index-condition-pushdown(ICP)优化
在存储引擎层,在查找索引的同时,进行条件的过滤,支持innoDB,MYISAM存储引擎
7、哈希算法
哈希索引,只适用于搜索等值的查询
8、全文检索
从innoDB1.2.x开始,支持全文检索,其支持MyISAM存储引擎的全部功能。
1)倒排索引:全文检索通常使用倒排索引实现,同B+索引一样,也是一种索引结构
2)innoDB全文检索:innoDB1.2.x开始,支持全文检索,采用full inverted index的方式
五、锁
1、innoDB存储引擎中的锁
innoDB存储引擎提供一致性非锁定读,行级锁支持,行级锁没有额外的开销,并可以同时得到并发性和一致性
1)、锁的类型
共享锁(S lock):允许事物读一行数据
排它锁(X lock):允许事物更新或者删除一行数据
X锁和其他锁均不兼容,S和X都是行锁,兼容是指对同一记录(row)锁的兼容性
为了在不同粒度上加锁,innoDB支持一种额外的加锁方式,意向锁,意向锁是将锁定的对象分为不同的层次,意向锁意味着事物希望在更细粒度上加锁
可以通过INNODB_TRX、INNODB_LOCKS、INNODB_LOCK_WAITS三张表获取表中事物锁的等待情况
2)、一致性非锁定读
定义:指innoDB引擎通过多版本控制的方式来读取当前执行时间数据库中行的数据,如果读取的行正在执行update、delete操作,当前事物不会去等待行上锁的释放,相反的会去读取行上的快照数据
在事物隔离级别为READ COMMITED 和 REPEATLE READ下,innoDB存储引擎使用一致性非锁定读,然而对于快照数据的定义不同,在READ COMMITED下,对于快照数据,读取的是锁定行上最新一份快照数据,在REPEATED READ 下,读取的是锁定行在事物开始时的快照数据。
3)、一致性锁定读
有些情况下,用户需要显示的对数据的读取操作加锁以保证数据的一致性,这就要求数据库支持加锁语句
innoDB存储引擎支持两种一致性的锁定读:
select ....for update:对读取的行记录添加X锁,其他事物不能对已锁定的行加任何锁
select lock in share mode:对读取的行记录添加S锁,其他事物可以对已锁定的行加S锁,如果添加X锁,则会被阻塞
4)、自增长与锁
从mysql5.1.22开始,innoDB提供了一种轻量级互斥量的自增长机制,大大提高了自增长插入的性能,并且提供了innodb_autoinc_lock_mode来控制自增长的模式
5)、外键和锁
对于外键的插入和更新,首先需要查询父表中的数据,但是对于父表的select操作,不是使用一致性非锁定读,这种方式会发生数据不一致的问题,因此此时使用的是select。。。。lock in share mode,主动对父表加一个S锁,如果此时父表上已经加了X锁,则子表上的操作会阻塞。
2、锁的算法
1)行锁的三种算法
Record Lock:单个行记录上的锁
Gap Lock:间隙锁,锁定一个范围,但不包含记录本身
Next-Key Lock:Gap Lock + Record Lock,锁定一个范围,并且包含记录本身
注意:对于唯一键值的锁定, Next-Key Lock降级为 Record Lock仅存在于查询所有的唯一索引列
2)解决Phanttom Problem(幻读)
Phanttom Problem是指在同一事物下,连续执行两次相同的sql,可能导致不同的结果,第二次sql语句可能返回之前不存在的行。
在默认的事物隔离级别下,即Repeatable read 下,innoDb存储引擎采用Next-Key Lock机制来避免Phanttom Problem问题
3、锁问题
1)脏读
脏数据(注意和脏页的区分):事物对缓冲池中的行记录的修改,还未被提交
脏读:一个事物读取到另一个事物未提交的数据,违反了事物的隔离性,脏读现象在生产环境汇总不常发生,脏读的发生需要的条件是隔离级别为READ UNCOMMITED,而目前绝大多数数据库都至少设置了READ COMMITED。
2)不可重复读
·在一个事物中两次读取相同的数据集合,获取的结果不一致
和脏读的区别:脏读获取的是其他事物未提交的数据,不可重复度读的是已经提交了的数据
innoDB存储引擎默认的事物隔离级别为READ REPEATABLE,采用Next-Key Lock算法,避免了不可重复读的现象,在Next-Key Lock算法下,对于索引的扫描,不仅锁住扫描到的索引,而且还锁住了这些索引覆盖的范围
3)丢失更新
一个事物的更新操作会被另一个事物的更新操作所覆盖,从而导致数据的不一致。
4、阻塞
因为不同锁之间的兼容性关系,在有些时候一个事物中的锁需要等待另一个事物中的锁释放它所占用的资源,这就是阻塞
需要牢记的是,在默认情况下innoDB引擎中不会回滚超时引发的错误异常。
5、死锁
死锁是指两个或者两个以上的事物在执行过程中,因争夺锁资源而相互等待的一种现象
解决死锁最简单的一种方法就是超时,innodb_lock_wait_timeout,超时回滚,但是这种方案在超时事物权重较大时,性能差
当前数据库普遍采用wait-for graph(等待图)来进行死锁检测,innodb存储引擎也采用这种方式,wait-for graph要求数据库保存以下两种信息:锁的信息链表、事物等待链表,通过上述链表可以构造一张图,这个图中,若存在回路,就代表存在死锁
六、事务
数据库系统引入事务的目的:事务会把数据库从一种一致状态转换为另一种一致装填,在数据库提交工作时,可以确保要么所有修改都保存,要么都不保存。
innoDB的事务符合ACID特性
1、认识事物
1)、概述
事务可由一条简单的sql组成,也可以由一组sql语句组成。事务是访问并更新数据库数据项的一个程序执行单元,在事物操作中,要么都执行,要么都不执行
事物必须满足ACID特性:
A(Atomicity):原子性,要么都执行,要么都不执行
C(Consistency):一致性,一致性指事务将数据库从一种一致状态转换为另一种一致的状态,在事物开始之前和事物结束之后,数据库的完整性没有被破坏
I(isolution):隔离性,事务的隔离性要求每个读写事务的对象对其他事物的操作对象能相互分离,即事务在提交前对其他事务不可见,通常使用锁来实现
D(Durability):持久性:事务一旦提交,起结果是永久性的,即使宕机等故障,数据库也能恢复数据
2)分类
扁平事物:事务类型中最简单的一种,在生产环境中使用最频繁的类型,在扁平事物中,所有操作都在同一层次,其间的操作是原子的,是应用程序称为原子操作的基本组成模块。
扁平事物不能提交或者回滚事物的一部分,在某些场景下有所限制
带保存点的扁平事物:除了支持扁平事务外,允许事物在执行过程中回滚到同一事物中较早的状态。保存点(Savepoint)用来通知系统应该记住事务当前的状态,以便之后发生错误回滚到保存点当时的状态。
链事物:保存点模式的一种变种,带有保存点的事务,在发生系统崩溃时,保存点会消失。链事物的思想是:在提交一个事务时,释放不需要的数据对象,将必要的处理上下文隐式传递给下一个要开始事物,提交事务操作和开始下一个事务合并为一个原子操作,意味着下一个事务会看到上一个事务的结果。链事务的回滚只能回滚到最近的一个保存点。
嵌套事物:是一个层次结构框架,由一个顶层事务控制着各个层次的事务。可实现事务间的并行性。innoDB存储引擎原生不支持。
分布式事物:一个分布式环境中的扁平事务
2、事务的实现
1)redo
重做日志用来实现事务的持久性,由两部分组成,一部分是:重做日志缓冲,二是:重做日志文件
innoDB存储引擎通过force log at commit机制来实现,在事务提交时,必须先将事务的所有日志写入重做日志文件中进行持久性。
redolog:实在存储引擎层产生的,是物理日志,记录的是对于每个页的修改。其记录的是物理操作日志,每个事务对应多条日志记录,并且重做日志是并发写入的,并非在事务提交时写入,所以在文件中的记录顺序并非是事务开始时的顺序。
binlog:是二进制日志,在数据库上次产生的,是一种逻辑日志,其记录的是对应的sql语句。二进制日志只是在事务提交时写入,并且对于一个事务,仅包含对应事务的一个日志。
2)undo
undo log帮助实现回滚和MVCC功能。
undo存放在数据库一个特殊段中,undo segment,位于共享表空间中。
undo是逻辑日志,只是将数据库逻辑的回复到以前的样子。
undolog会产生redolog,因为undolog也需要持久性的保护。
3)purge
delete和update操作可能并不会在事务提交时,直接删除原有的数据,purge操作完成最终的delete和update操作,这样设计师因为innoDB支持MVCC,所以记录不能事务提交时立即处理。
4)group commit
若事务是非只读事务,则每次事务提交时都会进行一次fsync操作,保证重做日志能够写入磁盘,为了提高磁盘的fsync效率,提供了group commit功能,即一次fsync可以刷新确保多个事务日志被写入文件
BLGC(Binary log group commit)
3、事务控制语句
START TRANSACTION | BEGIN :显示开启一个事务
COMMIT
ROLLBACK
SAVEPOINT identifier:创建一个保存点
RELEASE SAVEPINTidentifier:删除一个事物的保存点
SET TRANSACTION :设置事物的隔离级别
4、隐式提交的sql语句
某些sql语句执行完成后,会有一个隐式的commit操作
DDL:alter database...等
用来隐式的修改mysql架构的操作:create user ....等
管理语句:analyze table...等
5、对于事物操作的统计
如果用户都是显示的提交事务,可以通过com_commit、com_rollback进行统计
6、事务的隔离级别
innoDB存储引擎默认的隔离级别为:REPEATABLE READ,在这种隔离级别下,使用NEXT-KEY lock算法,可以避免幻读的产生,已经完全保证事务的隔离性要求,可以达到sql标准的SERIALIZABLE隔离级别。
7、分布式事物
1)、mysql数据库分布式事物
innoDB存储引擎提供了XA事务的支持,并通过XA事务来支持分布式事物的实现。分布式事物是指允许多个独立的事物资源参与到一个全局的事务当中。
注意,在使用分布式事物时,innoDB存储引擎的事务隔离级别要设置为SERIALIZABLE。
XA事务允许不同的数据库之间的分布式事物,只要数据库支持XA事物。
XA事务由多个资源管理器(SM),一个事务管理器(TM),一个应用程序(AP)构成
SM:提供访问事务资源的方法,通常一个数据库就是一个资源管理器
TM:协调参与全局事务中的各个事务,需要和参与全局事务的所有资源管理器通信
AP:定义事务的边界,指定全局事务中的操作
分布式事物使用两阶段提交(two-phase commit)的方式,在第一阶段,所有参与全局事务的节点都开始准备提交(prepare),告诉事务管理器他们准备好提交了; 在第二阶段,事务管理器告诉资源管理器执行commit或者rollback。如果任何一个节点显示不能提交,则所有节点都被告知需要回滚
2)、内部XA事物
在MySQL数据库中还存在一种分布式事务,其在存储引擎和插件之间,或者存在于存储引擎和存储引擎之间,称为内部XA事务。
最为常见的内部XA事务,存在于binlog和innoDB存储引擎之间。