MySQL常用基础概念(二)
大家好,我是梦辛工作室的灵,最近我在阅读一本高性能MySQL的书,对我有很大的启发,后面会不断的对有用的内容做一个摘要,当然也是为了巩固自己的学习内容,有兴趣的同学可以去京东购买该书,对MySQL理解可以让我们更深的理解并操作它(高性能MySQL第三版)
1.3.3 事务日志 事务日志可以帮助提高事务的效率。使用事务日志,存储引擎在修改表的数据时只需要修改其内存拷贝,再把该修改行为记录到持久在硬盘的事务日志中,而不用每次都将修改的数据本身持久化到磁盘
1.3.4 MySQL中的事务 MySQL提供了两种事务型的存储引擎: InnoDB 和 NDB Cluster。
自动提交(AUTOCOMMIT) MySQL默认采用自动提交(AUTOCOMMIT)模式。也就是说如果不是显示的开始一个事务,则每个查询都被当做一个事务执行提交操作,在当前连接中,可以通过AUTOCOMMIT变量来启用或禁用自动提交模式;
也可查看当前提交模式 SHOW VARIABLES LIKE ‘AUTOCOMMIT’;
1或者ON标识启用, 0 或者OFF标识禁用。 当AUTOCOMMIT=0时,所有的查询都是在一个事务中,直到显示的执行COMMIT提交或者ROLLBACK回滚,该事务结束,同时有开始了一个新的事务。修改AUTOCOMMIT对非事务型的表,比如MyISAM或者内存表,不会有任何影响,对这类表来说,没有COMMIT或者ROLLBACK的概念,也可以说是一直处于AUTOCOMMIT启用的模式
在事务中混合使用存储引擎 如果在事务中混合使用了事务型和非事务型的表(例如InnoDB和MyISAM表),在正常的提交情况下不会有什么问题 但如果事务需要回滚,非事务型表上的变更就无法撤销,这会导致数据库处于不一致的状态,这种情况很难修复,事务的最终结果无法确定 在非事务的表上执行事务相关的操作时,MySQL通常不会发出提醒,也不会报错,有时候只有回滚的时候才会发出一个警告
隐式和显式锁定 InnoDB采用的是两阶段锁定协议,在事务执行过程中,所示都可以执行锁定,锁只有在执行COMMIT或ROLLBACK的时候才会释放,并且所有的锁都是在同一时刻被释放,这种锁定是隐式锁定,InnoDB会根据隔离级别在需要的时候自动加锁 另外,InnoDB也支持通过特定的语句进行显示锁定,这些语句不属于SQL规范: select *** lock In Share mode select *** for update
1.4多版本并发控制 MySQL的大多数事务型存储引擎实现的都不是简单的行级锁,基于提升并发性能的考虑。他们一般都同时实现了多版本并发控制(MVCC)。 MVCC的实现是通过保存数据在某个时间点的快照来实现的,也就是说,不管需要执行多长时间,每个事务看到的数据都是一致的,根据事务开始的时间不同,每个事务对同一张,同一时刻的数据可能是不一样的。 不同的存储引擎的MVCC实现也是不同的,典型的有乐观并发控制和悲观并发控制。 InnoDB的MVCC是通过在每行记录后面保存两个隐藏的列来实现的,这两个列一个保存了行的创建时间,一个保存了行的过期时间(或删除时间),当然存储的并不是实际的时间值,而是系统版本号,没开始一个新的事务,系统版本号都是自动递增,事务开始时刻的系统版本号作为事务的版本号,用来查询到的每行记录的版本号来进行比较。下面看一下在REPEATABLE READ 隔离级别下,MVCC具体如何操作的; SELECT InnoDB会根据以下两个条件检查每行记录: a.InnoDB只查找版本早于当前事务版本的数据行,这样可以确保事务读取的行,要么是在事务开始前已经存在的,要么是事务自身插入或者修改过的, b.行的删除版本要么未定义,要么大于当前事务版本号,这样可以确保事务读取到的行,在事务开始之前未被删除。 只有满足以上两个条件的记录,才能作为查询结果 INSERT InnoDB为每新插入的每一行保存当前系统版本号作为行版本号; DELETE InnoDB为删除的每一行保存当前系统版本号作为删除标识; UPDATE InnoDB为插入一行新记录,保存当前系统版本号作为行版本号,同时保存当前系统的版本号到原来的行作为删除标识。
保存这两个额外的系统版本号,是大多数读操作都可以不用加锁,这样设计使得读数据操作很简单,性能很哈,并且也能保证只会读取到符合标准的行,不足之处是每行记录都需要额外的存储空间,没要跟多的行检查工作以及一些额外的维护工作。
MVCC只在REPEATABLE READ 和 READ COMMITED 两个隔离级别下工作,其他两个隔离级别都和MVCC不兼容,因为READ UNCOMMITED总是读到最新的数据行,而不是符合当前事务版本的数据行,而SERIALIZABLE会对所有的行都加锁