对于事务操作的统计

因为InnoDB存储引擎是支持事务的,因此对于InnoDB存储引擎的应用,在考虑每秒请求数(Question Per Second,QPS)的同时,也许更应该关注每秒事务处理的能力(Transaction Per Second,TPS)。

计算TPS的方法是(com_commit+com_rollback)/time。但是用这种方法计算的前提是:所有的事务必须都是显式提交的,如果存在隐式的提交和回滚(默认autocommit=1),不会计算到com_commit和com_rollback变量中。如:

show global status like 'com_commit'\G  5

insert into t select 3;

select * from t\G

show global status like'com_commit'\G  5

MySQL另外还有2个参数handler_commit和handler_rollback。但是我注意到,这两个参数在MySQL 5.1中可以很好地用来统计InnoDB存储引擎显式和隐式的事务提交操作,而在InnoDB Plugin中该参数的表现有些“怪异”,并不能很好地统计事务的次数。所以,如果你的程序都是显式控制事务的提交和回滚,那么可以通过com_commit和com_rollback进行统计。如果不是,那么情况就显得复杂了。

事务的隔离级别

令人惊讶的是,大部分数据库系统都没有提供真正的隔离性,最初或许是因为系统实现者并没有真正理解这些问题。如今这些问题已经弄清楚了,但是数据库实现者在正确性和性能之间做了妥协。ISO和ANIS SQL标准制定了四种事务隔离级别的标准,但是很少有数据库开发厂商遵循这些标准,比如Oracle数据库就不支持read uncommitted和repeatable read的事务隔离级别。

SQL标准定义的四个隔离级别为:

  1. READ UNCOMMITTED
  2. READ COMMITTED
  3. REPEATABLE READ
  4. SERIALIZABLE

READ UNCOMMITTED称为浏览访问(browse access),仅仅只对事务而言的。

READ COMMITTED称为游标稳定(cursor stability)。

REPEATABLE READ是2.9999˚的隔离,没有幻读的保护。

SERIALIZABLE称为隔离,或3˚。SQL和SQL 2标准的默认事务隔离级别是SERIALIZABLE。

InnoDB存储引擎默认的支持隔离级别是REPEATABLE READ,但是与标准SQL不同的是,InnoDB存储引擎在REPEATABLE READ事务隔离级别下,使用Next-Key Lock锁的算法,因此避免幻读的产生。这与其他数据库系统(如Microsoft SQL Server数据库)是不同的。所以说,InnoDB存储引擎在默认REPEATABLE READ的事务隔离级别下已经能完全保证事务的隔离性要求,即达到SQL标准的SERIALIZABLE隔离级别。

隔离级别越低,事务请求的锁越少,或者保持锁的时间就越短。这也是为什么大多数数据库系统默认的事务隔离级别是READ COMMITTED。

在InnoDB存储引擎中,可以使用以下命令来设置当前会话或者全局的事务隔离级别:

SET [GLOBAL|SESSION] TRANSACTION ISOLATION LEVEL

{

  READ UNCOMMITTED

  |READ COMMITTED

  |REPEATABLE READ

  |SERIALIZABLE

}

如果想在MySQL库启动时就设置事务的默认隔离级别,那就需要修改MySQL的配置文件,在[mysqld]中添加如下行:

[mysqld]

transaction-isolation=READ-COMMITTED

查看当前会话的事务隔离级别,可以使用:

select @@tx_isolation\G

查看全局的事务隔离级别,可以使用:

select @@global.tx_isolation\G

在SERIALIABLE的事务隔离级别,InnoDB存储引擎会对每个SELECT语句后自动加上LOCK IN SHARE MODE,即给每个读取操作加一个共享锁。因此在这个事务隔离级别下,读占用锁了,一致性的非锁定读不再予以支持。因为InnoDB存储引擎在REPEATABLE READ隔离级别下就可以达到3˚的隔离,所以一般不在本地事务中使用SERIALIABLE的隔离级别,SERIALIABLE的事务隔离级别主要用于InnoDB存储引擎的分布式事务。

在READ COMMITTED的事务隔离级别下,除了唯一性的约束检查以及外键约束的检查需要Gap Lock,InnoDB存储引擎不会使用Gap Lock的锁算法。但是使用这个事务隔离级别需要注意一些问题。首先,在MySQL 5.1中,READ COMMITTED事务隔离级别默认只能工作在Replication(复制)的二进制日志为ROW的格式下。如果二进制日志工作在默认的STATEMENT下,则会指出如下的错误:

create table a(b int,primary key(b))engine=innodb;

set @@tx_isolation='read-committed';

select @@tx_isolation\G

begin;

insert into a select 1;

ERROR 1598(HY000):Binary logging not possible.Message:Transaction level

'READ-COMMITTED'in InnoDB is not safe for binlog mode'STATEMENT'

MySQL 5. 0版本之前不支持ROW格式的二进制日志时,也许有人知道,可以通过将参数innodb_locks_unsafe_for_binlog设置为1,来使得可以在二进制日志为STATEMENT下使用READ COMMITTED的事务隔离级别:

select @@version\G

system cat/etc/my.cnf | grep innodb_locks_unsafe_for_binlog

innodb_locks_unsafe_for_binlog=1

show variables like 'innodb_locks_unsafe_for_binlog'\G

***************************1.row***************************

Variable_name:innodb_locks_unsafe_for_binlog

Value:ON

set @@tx_isolation='read-committed';

begin;

insert into a select 1;

commit;

是的,的确可以通过上述办法使得在MySQL 5.0的版本之前使用READ COMMITED事务隔离级别。但是就像参数innodb_locks_unsafe_for_binlog的名称一样,它是unsafe的。在某些情况下,可能会导致master和slave之间数据的不一致。

接着来演示一种可能导致不同步的情况,首先来看下表a中的数据:

select * from a\G

***************************1.row***************************

b:1

***************************2.row***************************

b:2

***************************3.row***************************

b:4

***************************4.row***************************

b:5

4 rows in set(0.00 sec)

接着在master上开启一个会话A执行如下事务,并且不要提交:

#Session A on master

begin;

delete from a where b<=5;

在master上开启另一个会话B,执行如下事务,并且提交:

#Session B on master

begin;

insert into a select 3;

commit;

接着会话A提交,并查看表a中的数据:

#Session A on master

commit;

select * from a\G

***************************1.row***************************

b:3

但是在slave上看到的结果却是:

#Slave

select * from a;

可以看到,数据产生了不一致。导致这个问题发生的原因有两点:首先,在READ COMMITTED事务隔离级别下,事务是没有Gap Lock锁的,因此我们可以在小于等于5的范围内再插入一条记录;其次,statement记录的是master上产生的SQL语句,因此在master上是先删后插,但是在STATEMENT格式中记录的却是先插后删,逻辑上就产生了不一致。因此,使用READ REPEATABLE事务隔离级别就可以避免第一种情况的发生,因而也就避免了master和slave不一致问题的产生。

在MySQL 5.1的版本之后,因为支持了ROW格式的二进制日志记录格式,所以避免了第二种情况的发生,因此可以放心使用READ COMMITTED的事务隔离级别。即使不使用READ COMMITTED的事务隔离级别,也应该考虑将二进制日志的格式更换成ROW,因为这个格式记录的是行的变更,而不是简单的SQL语句,因此可以避免一些不同步现象的产生。

事务操作的统计,TPS的计算,隔离级别的读提交的更多相关文章

  1. 大数据学习day33----spark13-----1.两种方式管理偏移量并将偏移量写入redis 2. MySQL事务的测试 3.利用MySQL事务实现数据统计的ExactlyOnce(sql语句中出现相同key时如何进行累加(此处时出现相同的单词))4 将数据写入kafka

    1.两种方式管理偏移量并将偏移量写入redis (1)第一种:rdd的形式 一般是使用这种直连的方式,但其缺点是没法调用一些更加高级的api,如窗口操作.如果想更加精确的控制偏移量,就使用这种方式 代 ...

  2. 事务操作(BEGIN/COMMIT/ROLLBACK/SAVE TRANSACTION)

    BEGIN TRANSACTION 标记一个显式本地事务的起始点. BEGIN TRANSACTION 使 @@TRANCOUNT 按 1 递增. BEGIN TRANSACTION 代表一点,由连接 ...

  3. Django 事务操作

    如何在Django中进行事务操作 案例: 客户A要给客户B转一笔钱,这个在数据库中需要进行两步: 1.客户A减钱 2.客户B加钱 如果在第一步结束后,服务器出现异常,停下了,第二步没有进行,如果数据库 ...

  4. Spring 中的事务操作、注解、以及 XML 配置

    事务 事务全称叫数据库事务,是数据库并发控制时的基本单位,它是一个操作集合,这些操作要么不执行,要么都执行,不可分割.例如我们的转账这个业务,就需要进行数据库事务的处理. 转账中至少会涉及到两条 SQ ...

  5. Django中-事务操作

    如何在Django中进行事务操作呢? 近期,公司里要使用Django开发一套金融相关的系统. 涉及钱了.....安全安全安全 如果钱转到一半,系统崩了,咋办? 如果钱汇到一半,系统崩了,咋办? 如果东 ...

  6. Django orm进阶查询(聚合、分组、F查询、Q查询)、常见字段、查询优化及事务操作

    Django orm进阶查询(聚合.分组.F查询.Q查询).常见字段.查询优化及事务操作 聚合查询 记住用到关键字aggregate然后还有几个常用的聚合函数就好了 from django.db.mo ...

  7. Django---Django的ORM的一对多操作(外键操作),ORM的多对多操作(关系管理对象),ORM的分组聚合,ORM的F字段查询和Q字段条件查询,Django的事务操作,额外(Django的终端打印SQL语句,脚本调试)

    Django---Django的ORM的一对多操作(外键操作),ORM的多对多操作(关系管理对象),ORM的分组聚合,ORM的F字段查询和Q字段条件查询,Django的事务操作,额外(Django的终 ...

  8. Spring事务传播及数据库事务操作

    从Spring 事务配置说起 先看看Spring 事务的基础配置 <aop:aspectj-autoproxy proxy-target-class="true"/> ...

  9. Redis事务操作

    Redis事务操作 Redis事务本质: ​ 一组命令的集合 , 一个事务中的所有命令都会被序列化 , 在事务执行过程中 , 会按照顺序执行 一次性 : 事务之间的事情,会一次性执行,而不是立刻执行 ...

随机推荐

  1. [label][phalcon] How to install Phalcon extension for Zend Server 6.3.0 for windows 7 64bit

    At first , you should download Phalcon DLL file. You can download from this link under. http://stati ...

  2. [leetcode] 6. Balanced Binary Tree

    这个题目纠结了一会儿,终于从二叉树转化到AVL了.题目如下: Given a binary tree, determine if it is height-balanced. For this pro ...

  3. java性能分析工具 jconsole.exe

    通过 Java visualMv结合 jconsole.exe   工具即可查看如图所示(Jconsole在JDK文件夹内,非JRE文件夹) 在Java Visualvm工具里面安装JTA插件,分析线 ...

  4. 使用像素单位设置 EXCEL 列宽或行高

    在导出 Excel 的时候, 经常要需要给列设置宽度或给行设置高度, 在使用 NPOI 或 EppPlus 等组件进行操作的时候, 列宽和行高的单位都不是像素, 好像是英寸,具体是啥也说不清. 平常在 ...

  5. 用.msi安装node时安装失败,出现rolling back action(转载)

    转载地址:https://blog.csdn.net/qq_33295622/article/details/52956369在重装node时出现了上图所示情况,解决方法如下: 1.在官网下载稳定版本 ...

  6. vs2015上使用github进行版本控制

    我是用的是vs2015企业版 一.首先创建项目,右下角选择新建git存储库 二.在工具栏选择团队-管理连接,打开团队资源管理器,点击同步 . 三.选择下面的发布选项 四.在gitgub上新建仓库,得到 ...

  7. 【Unity】Domina-Game总结与反思

    [Unity]Domina-Game总结与反思 2018/6/15 我总算是把物理课作业--Domina-Game给赶完了,这也算是我用Unity做的第一个游戏吧(不得不说我的脚本写的超烂的)...纪 ...

  8. uwp获取版本信息win10 VersionInfo

    using Windows.System.Profile; Después vamos a agregar una propiedad que va a contener un mensaje con ...

  9. poj 1006 Biorhythms (中国剩余定理模板)

    http://poj.org/problem?id=1006 题目大意: 人生来就有三个生理周期,分别为体力.感情和智力周期,它们的周期长度为23天.28天和33天.每一个周期中有一天是高峰.在高峰这 ...

  10. textarea 高度自动

    <textarea id="suggest" type="text" name="suggest" class="form- ...