03 | 事务隔离:为什么你改了我还看不见?

引擎层实现事务。MySQL 支持多引擎,MyISAM 不支持事务, InnoDB 支持。

一、隔离性(Isolation)与隔离级别

隔离级别解决:多事务同时执行,脏读、不可重复读(non-repeatable read)、幻读(phantom read)的问题

四种隔离级别https://www.jianshu.com/p/6ed305b67c8c

1、读未提交,事务没提交时,变更被看到。

2、读提交,事务提交,变更才被看到。

3、可重复读,事务执行过程中,启动时看到数据是一致未提交变更对其他事务也是不可见。

4、串行化,对同一行记录,“写”加“写锁”,“读”加“读锁”。冲突时,等前一个完成,才可继续。

表 T 中只有一列,其中一行的值为 1,按照时间顺序执行两个事务的行为。

mysql> create  table T(c int) engine=InnoDB;    insert into T(c)  values(1);

读未提交”, V1 = 2。 B 虽没提交, A 看到了。V2、V3 = 2。

“读提交”,V1 = 1,V2 = 2。B 更新提交后, A 看到。 V3 = 2。

“可重复读”,V1、V2 = 1,V3 = 2。

“串行化”,V1、V2 = 1,V3 = 2。

db里创建视图,访问时候以逻辑结果为准。

    “读未提交”返回记录上最新值没有视图概念;

   “读提交” SQL 语句执行时创建。

    “可重复读”启动时创建(可认为是静态,不受其他事务更新影响),整个事务存在期间都用。。

    “串行化”加锁避免并行

Oracle 默认“读提交”,从 Oracle 迁移到MySQL 的应用,为保证一致, MySQL设置为“读提交”。

配置的方式,启动参数transaction-isolation 设置 READ-COMMITTED

mysql> show  variables like 'transaction_isolation';

| Variable_name |  Value |

|  transaction_isolation | READ-COMMITTED |

可重复读场景呢:

银行月底对账,判断上个月和当前差额,与本月账单明细是否一致。过程中,新交易,不影响结果

二、事务隔离的实现

展开说明“可重复读”。MySQL 更新时记录回滚操作。

从 1 被按顺序改成 2、3、4,回滚日志:

当前值是 4,查询有不同 read-view。同一记录在系统中可多版本(MVCC)。read-view A得到 1,依次执行所有的回滚

即将 4 改成 5,跟A、B、C 会冲突

系统判断,没有事务用回滚日志时(例:没有比这个回滚日志更早 read-view)、删除

尽量不要使用长事务

提交之前,回滚记录保留,占大量存储空间、锁资源,可能拖垮整个库

在 MySQL 5.5 及以前的版本,回滚日志是跟数据字典一起放在ibdata文件里的,即使长事务最终提交,回滚段被清理,文件也不会变小。我见过数据只有 20GB,而回滚段有 200GB 的库。最终只好为了清理回滚段,重建整个库。

三、事务的启动方式

MySQL 的事务启动方式有以下几种:

1.  显式启动事务语句, begin 或 start transaction。配套的提交语句是 commit,回滚语句是 rollback。

2.  set auto commit=0,线程自动提交关掉。执行select 语句,事务启动不会提交。直到 commit 或 rollback或断开连接。

如果是长连接,导致意外长事务。建议 set auto commit=1,显式启动事务。

auto commit 为 1 情况,begin 显式启动,commit 。如果执行 commit work and chain,提交事务并自动启动下一个事务,省去再次begin开销。知道每个语句是否处于事务中

查找持续时间超过 60s 的事务:

select * from  information_schema.innodb_trx where  TIME_TO_SEC (time diff(now(),trx_started) )>60

问题

长事务风险,如何避免

应用开发端来看:

1.  是否set autocommit=0。可在测试环境中,把 MySQL 的 general_log 开起来,然后随便跑一个业务逻辑,通过 general_log 的日志来确认。改成 1。

2.  是否有不必要只读事务。有些框架不管什么先用 begin/commit框起来。我见过有些是业务并没有这个需要,但是也把好几个 select 语句放到了事务中。这种只读事务可以去掉。

3.  业务连接数据库的时候,根据业务本身的预估,通过 SET MAX_EXECUTION_TIME 命令,来控制每个语句执行的最长时间,避免单个语句意外执行太长时间。(为什么会意外?在后续的文章中会提到这类案例)

数据库端来看:

1.  监控information_schema.Innodb_trx 表,设置长事务阈值,超过就报警 / 或者 kill;

2.  Percona 的 pt-kill 这个工具不错

3. 在业务功能测试阶段要求输出所有的 general_log,分析日志行为提前发现问题;

4. 如果使用的是 MySQL 5.6 或者更新版本,把innodb_undo_tablespaces 设置成 2(或更大的值)。如果真的出现大事务导致回滚段过大,这样设置后清理更方便

评论1

SET GLOBAL MAX_EXECUTION_TIME=3000. 确保单条语句执行时间

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 204,293评论 6 478
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 85,604评论 2 381
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 150,958评论 0 337
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,729评论 1 277
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,719评论 5 366
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,630评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 38,000评论 3 397
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,665评论 0 258
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,909评论 1 299
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,646评论 2 321
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,726评论 1 330
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,400评论 4 321
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 38,986评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,959评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,197评论 1 260
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 44,996评论 2 349
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,481评论 2 342

推荐阅读更多精彩内容