MYSQL事务及存储引擎对比

Innodb支持事务,而myisam不支持事务。

事务的定义:

当多个用户访问同一份数据时,一个用户在更改数据的过程中可能有其他用户同时发起更改请求,为保证数据的更新从一个一致性状态变更为另一个一致性状态,这时有必要引入事务的概念。

Mysql提供了多种引擎支持Innodb和BDB。Innodb存储引擎事务主要通过UNDO日志和REDO日志实现,Myisam和memory引擎则不支持事务。下图分别给出三种mysql引擎的区别和特性:

Myisam存储引擎:由于该引擎不支持事务、也不支持外键,所以访问速度很快。因此对事务完整性没有要求并以访问为主的应用适合使用该存储引擎。

Innodb存储引擎:

由于该存储引擎在事务上具有优势,即支持具有提交、回滚和崩溃恢复能力的事务安装,所以比myisam存储引擎占用更多的磁盘空间。因此需要进行频繁的更新、删除操作,同时对事务的完整性要求比较高,需要实现并发控制,此时适合使用该存储引擎。

Memory存储引擎:

该存储引擎使用内存来存储数据,因此该存储引擎的数据访问速度非常快,但是安全上没有保障,(redis也是一个内存存储引擎)。如果应用中涉及数据比较小,需要进行快速访问,则适合使用该存储引擎。

本文主要从以下四个方面来介绍mysql的事务:

  1. 事务概述
  2. 事务控制语句
  3. 事务隔离级别
  4. innodb锁机制


事务概述:

事务具有ACID四个性质来保证数据库的更新从一个一致性状态到另一个一致性状态:

原子性(atomicity):事务中所有的操作视为一个原子单元,即对事务所进行的数据修改等操作只能是完全提交或者完全回滚。

一致性(consistency):事务在完成时,必须使所有的数据从一种一致性状态变更为另外一种一致性状态,所有的变更都必须应用于事务的修改,以确保数据的完整性。

隔离性(insolation):一个事物中的操作语句所做的修改必须与其他事物所做的修改相隔离。在进行事务查看数据时数据所处的状态,要么是被另一并发事务修改之前的状态,要么是被另一并发事务修改之后的状态,即当前事务不会查看由另外一个并发事务正在修改的数据。这种特性主要由锁机制实现。

持久性(durability):事务完成之后,所做的修改对数据的影响是永久的,即使系统重启或者系统出现故障,数据仍可恢复。

REDO日志和UNDO日志:

REDO日志:

事务执行时需要将执行的事务日志写入到日志文件里,对应的文件为redo日志。当每条sql语句进行数据库更新操作时,首先将redo日志写入到日志缓冲区。当客户端执行commit命令提交时,日志缓冲区的内容将被刷新到磁盘,日志缓冲区的刷新方式或者时间间隔可以通过参数innodb_flush_log_at_trx_commit控制。

REDO日志对应磁盘上的ib_logfileN(ib_logfile0,ib_logfile1)文件,该文件默认为5MB,建议设置为512MB以便容纳较大的事务。在mysql崩溃恢复时会重新执行redo日志中的记录。

UNDO日志:

与redo日志相反,undo日志主要用于事务异常时的数据回滚,具体内容就是复制事务前的数据库内容到undo缓冲区,然后在合适的时间将内容刷新到磁盘。

与redo日志不同的是,磁盘上不存在单独的undo日志文件,所有的undo日志文件均存放在表空间对应的.idb数据文件中,undo日志又被成为回滚段。



Mysql事务控制语句:

START TRANSACTION | BEGIN [WORK]                  //开启一个事务
COMMIT [WORK] [AND [NO] CHAIN] [[NO] RELEASE]       //提交一个事务
ROLLBACK [WORK] [AND [NO] CHAIN] [[NO] RELEASE]     //回滚一个事务
SET AUTOCOMMIT = {0 | 1}    //自动提交事务开启或者关闭

查看事务的隔离级别:

show variables like ‘tx_isolation‘;

例子:commit之后才会对表进行插入

回滚之后,表不会有变动

SET AUTOCOMMIT =1;当自动提交被打开以后,我们rollback也没用,会自动提交。


Mysql事务隔离级别

sql标准定义了四种隔离级别,指出了哪些改变其他事务可见,哪些数据改变其他数据不可见。低级别的隔离级别可以支持更高的并发处理,同时占用的系统资源更少。

查看事务的隔离级别:

show variables like ‘tx_isolation‘;
#未提交读,以下是设置隔离级别语句,更改默认隔离级别,需要重新登录
SET GLOBAL TRANSACTION ISOLATION LEVEL READ UNCOMMITTED;
#提交读
SET GLOBAL TRANSACTION ISOLATION LEVEL READ COMMITTED;
#可重复读
SET GLOBAL TRANSACTION ISOLATION LEVEL  REPEATABLE READ;
#可串行化
SET GLOBAL TRANSACTION ISOLATION LEVEL SERIALIZABLE;

READ-UNCOMMITTED(读取未提交内容):

在该隔离级别,所有事物都可以看到其他未提交事务的执行结果。因为其性能也不必其他级别高很多,因此该隔离级别很少使用。读取未提交的数据被称为脏读。

两个事物在更新前,数据一致,但是左边的事务还未提交更改,右边的事务也读到其更改数据,这种情况称为脏读。

READ_COMMITED(读取提交内容):

这是大多数数据库默认的隔离级别,但并不是mysql默认的隔离级别。其满足了隔离的简单定义:一个事务从开始到提交前所做的任何改变都是不可见的,事务职能看见已经提交的事务所做的改变。

该隔离级别可能导致不可重复读问题,因为同一事务的其他实例在该实例的处理期间可能会有新的数据提交导致数据改变,所以同一个查询可能在不同时刻返回不同结果。

以下例子:A事务虽然没有提交,但是却看到不同数据。同一事务中,两次看到的数据是不一致的。

REPEATABLE-READ(可重读):

这是mysql的默认隔离级别。

该隔离级别能保证同一事务的多个实例在并发读取数据时,会看到同样的数据行,理论上会导致另一问题:幻读。

幻读:例如事务A对一个表中的数据修改涉及到全部的数据行。此时,事务B对该表插入一个数据行。那么出现的问题就是,该表中出现了事务A还没有修改的数据行。

Innodb和falcon存储引擎通过mvcc(多版本控制)机制解决了该问题。

innodb存储引擎的MVCC机制:innodb通过为每个数据行增加两个隐含值的方式来实现。这两个隐含值记录了行的创建时间,及过期时间。每一行存储事件发生时的系统版本号,每一次开始一个新的事物,版本号会自动加1,每个事物都会保存开始时的版本号,每个查询根据事物的版本来查询结果。

Serializable(可串行化):

这是最高的隔离级别,通过强制事物排序,使之不可能相互冲突,从而解决幻读问题。简言之,是在每个读的数据行上加上共享锁实现。在这个级别,可能会导致大量的超时现象和锁竞争,一般不推荐使用。

该隔离级别采用不同的锁类型来实现。

事务的隐式提交:例如alter table会造成隐式事务提交,尽管我们没有提交事务,但是在其他事务中却看到了我们的数据变化。



Innodb的锁机制:

锁的类型:

共享锁:

共享锁又称为S锁,是share的缩写,共享锁的锁粒度是行或者元组(多个行)。一个事务获取了共享锁之后,可以对锁定范围的数据执行读操作。

排它锁:

排它锁的代号是X,是eXclusive的缩写,排它锁的锁粒度也是行或者元组,一个事务获取了排它锁以后,可以对锁定范围内的数据执行写操作。

意向锁:

意向锁是一种表锁,锁的粒度是整张表,分为意向共享锁(IS)和意向排它锁(IX)两类。意向锁表示一个事务有意对数据上共享锁或者排它锁。”有意“表示事务想执行操作,但还没有真正执行。

锁和锁之间要么是相容的,要么是互斥的:

锁粒度:

锁的粒度主要分为行锁和表锁。锁的粒度越小,其耗费的系统资源越多,但是并发性却更好。

表锁的开销最小,同时允许的并发量也是最小的锁机制。Myisam使用该锁机制。

行锁支持最大的并发,innodb存储引擎使用该锁机制,如果支持并发读写,建议采用innodb锁机制。

select语句会加上一个共享锁,如果查找的数据已经被加上排它锁的话,共享锁会等待期结束再加,若等待时间过长就会显示需要等待的锁超时。

insert、update、delete会被加上排它锁。

时间: 2024-08-05 19:35:56

MYSQL事务及存储引擎对比的相关文章

DML 事务 隔离级别 存储引擎对比

DML 事务 隔离级别 存储引擎对比 DML insert into 第一种: insert into tb_name [(col1,col2,....)]{values|value}(val1,val2,...)[,(val21,val22,....),....] 第二种: insert into tb_name set col_name=val1,col2=val2,.... 第三种(将一个表中的数据插入到另外一张表中): insert into tb_name select clause

mysql常识以及存储引擎,锁和事务

常见的数据库系统: 1.甲骨文的Oracle 2.IBM的DB2 3.微软的Access和 SQL Server 4.开源PostgreSQL 5.开源MySQL mysql数据库三阶段: 初期开源数据库阶段 sun mysql阶段 oracle mysql阶段 OLTP:联机事务处理,面向基本的.日常的事务处理. OLAP:联机分析处理,数据仓库的主要应用. mysql分支版本(一些): MariaDB : Maria引擎室myisam存储引擎的升级版本,增加了对Hash join的支持和Se

转!!MySQL中的存储引擎讲解(InnoDB,MyISAM,Memory等各存储引擎对比)

MySQL中的存储引擎: 1.存储引擎的概念 2.查看MySQL所支持的存储引擎 3.MySQL中几种常用存储引擎的特点 4.存储引擎之间的相互转化 一.存储引擎: 1.存储引擎其实就是如何实现存储数据,如何为存储的数据建立索引以及如何更新,查询数据等技术实现的方法. 2.MySQL中的数据用各种不同的技术存储在文件(或内存)中,这些技术中的每一种技术都使用不同的存储机制,索引技巧,锁定水平并且最终提供广泛的不同功能和能力.在MySQL中将这些不同的技术及配套的相关功能称为存储引擎. 二.MyS

mysql数据库之 存储引擎、事务、视图、触发器、存储过程、函数、流程控制

目录 一.存储引擎 1.什么是存储引擎? 2.mysql支持的存储引擎 3. 使用存储引擎 二.事务 三.视图 1.什么是视图 2.为什么要用视图 3.如何用视图 四.触发器 为何要用触发器 创建触发器语法 五.存储过程 六.函数 七.流程控制 八.数据库备份(运维方向) 一.存储引擎 1.什么是存储引擎? mysql中建立的库===>文件夹 库中建立的表===>文件 现实生活中我们用来存储数据的文件有不同的类型,每种文件类型对应各自不同的处理机制:比如处理文本用txt类型,处理表格用exce

MySQL索引与事务、存储引擎MyISAM和InnoDB (理论+实践篇)

索引的概念 数据库中的索引与书籍中的目录类似 在一本书中,无须阅读整本书,利用目录就可以快速查找所需信息 书中的目录是一个词语列表,其中注明了包含各个词的页码 数据库索引 在数据库中,索引使数据库程序无须对整个表进行扫描,就可以在其中找到所需数据 数据库中的索引|是某个表中一-列或者若干列值的集合,以及物理标识这些值的数据页的逻辑指针清单 索引的的作用 设置了合适的索引之后,数据库利用各种快速的定位技术,能够大大加快查询速率 特别是当表很大时,或者查询涉及到多个表时,使用索引可使查询加快成3 F

原创 MySQL的索引与事务、存储引擎

索引的概念 数据库中的索引与书籍中的目录类似 在一本书中,无须阅读整本书,利用目录就可以快速查找所需信息书中的目录是一个词语列表,其中注明了包含各个词的页码 数据库索引 在数据库中,索引数据库程序无须对整个表进行扫描,就可以在其中找到所需数据数据库中的索引是某个表中一列或者若干列值的集合,以及物理标识这些值的数据页的逻辑指针清单 索引的作用 设置了合适的索引之后,数据库利用各种快速的定位技术,能够大大加快查询速率:特别是当表很大时,或者查询涉及到多个表时,使用索引可使查询加快成千倍:可以降低数据

MySQL数据库InnoDB存储引擎多版本控制(MVCC)实现原理分析

文/何登成 导读:   来自网易研究院的MySQL内核技术研究人何登成,把MySQL数据库InnoDB存储引擎的多版本控制(简称:MVCC)实现原理,做了深入的研究与详细的文字图表分析,方便大家理解InnoDB存储引擎实现的多版本控制技术(简称:MVCC). 基本知识 假设对于多版本控制(MVCC)的基础知识,有所了解.MySQL数据库InnoDB存储引擎为了实现多版本的一致性读,采用的是基于回滚段的协议. 行结构 MySQL数据库InnoDB存储引擎表数据的组织方式为主键聚簇索引.由于采用索引

MySQL数据库InnoDB存储引擎中的锁机制

MySQL数据库InnoDB存储引擎中的锁机制    http://www.uml.org.cn/sjjm/201205302.asp   00 – 基本概念 当并发事务同时访问一个资源的时候,有可能导致数据不一致.因此需要一种致机制来将访问顺序化. 锁就是其中的一种机制.我们用商场的试衣间来做一个比喻.试衣间供许多消费者使用.因此可能有多个消费者同时要试衣服.为了避免冲突,试衣间的门上装了锁.试衣服的人在里边锁住,其他人就不能从外边打开了.只有里边的人开门出来,外边的人才能进去. - 锁的基本

如何查看MySQL的当前存储引擎?

一般情况下,mysql会默认提供多种存储引擎,你可以通过下面的查看: 看你的mysql现在已提供什么存储引擎:mysql> show engines; 看你的mysql当前默认的存储引擎:mysql> show variables like '%storage_engine%'; 你要看某个表用了什么引擎(在显示结果里参数engine后面的就表示该表当前用的存储引擎):mysql> show create table 表名; 如何查看Mysql服务器上的版本额 系统函数啊select v