暂无图片
暂无图片
暂无图片
暂无图片
暂无图片

MySQL tips(二)——事务

爱可可的人生记录仪 2019-12-14
176

什么是事务:一组数据库操作就是事务,事务保证一组数据库操作,要么全部成功,要么全部失败。在 MySQL 中,事务支持是在引擎层实现的。MyISAM 引擎就不支持事务。

事务的特性:原子性(要么成功要么失败)、一致性(写入数据符合规则,不会破坏数据库完整性)、隔离性(防止事务并发执行导致的数据不一致)、持久性(数据修改永久性,不会丢失)

多事务同时执行的时候,可能会出现的问题:脏读、不可重复读、幻读


事务隔离级别:读未提交、读提交、可重复读、串行化

不同事务隔离级别的区别:

读未提交:一个事务还未提交,它所做的变更就可以被别的事务看到

读提交:一个事务提交之后,它所做的变更才可以被别的事务看到(oracle默认)

可重复读:一个事务执行过程中看到的数据是一致的。未提交的更改对其他事务是不可见的(MySQL默认,SELECT @@tx_isolation/show variables like 'transaction_isolation'查询当前隔离级别)

串行化:对应一个记录会加读写锁,出现冲突的时候,后访问的事务必须等前一个事务执行完成才能继续执行


如何实现各级别?数据库里面会创建一个视图,访问的时候以视图的逻辑结果为准。在“可重复读”隔离级别下,这个视图是在事务启动时创建的,整个事务存在期间都用这个视图,事务启动时的视图可以认为是静态的,不受其他事务更新的影响。在“读提交”隔离级别下,这个视图是在每个 SQL 语句开始执行的时候创建的。这里需要注意的是,“读未提交”隔离级别下直接返回记录上的最新值,没有视图概念;而“串行化”隔离级别下直接用加锁的方式来避免并行访问。


事务隔离的实现?每条记录在更新的时候都会同时记录一条回滚操作。但是在查询这条记录的时候,不同时刻启动的事务会有不同的 read-view。同一条记录在系统中可以存在多个版本,这就是数据库的多版本并发控制(MVCC)。

回滚日志什么时候删除?系统会判断当没有事务需要用到这些回滚日志的时候,回滚日志会被删除。什么时候不需要了?当系统里么有比这个回滚日志更早的read-view的时候。


为什么尽量不要使用长事务?长事务意味着系统里面会存在很老的事务视图,在这个事务提交之前,回滚记录都要保留,这会导致大量占用存储空间。除此之外,长事务还占用锁资源,可能会拖垮库。

事务启动方式:1、显式启动事务语句,begin或者start transaction,提交commit,回滚rollback;2、set autocommit=0,该命令会把这个线程的自动提交关掉。这样只要执行一个select语句,事务就启动,并不会自动提交,直到主动执行commit或rollback或断开连接。


建议使用方法一,如果考虑多一次交互问题,可以使用commit work and chain语法。在autocommit=1的情况下用begin显式启动事务,如果执行commit则提交事务。如果执行commit work and chain则提交事务并自动启动下一个事务。

查询长事务:

    select * from information_schema.innodb_trx where TIME_TO_SEC(timediff(now(),trx_started))>60;

    如何避免长事务对业务的影响?

    开发端:确认set autocommit=1。确认是否有不必要的只读事务。业务连接数据库的时候,根据业务本身的预估,通过 SET MAX_EXECUTION_TIME 命令,来控制每个语句执行的最长时间,避免单个语句意外执行太长时间。

    数据库端:监控 information_schema.Innodb_trx 表,设置长事务阈值,超过就报警 或者 kill;推荐使用Percona 的 pt-kill 这个工具;在测试阶段要求输出所有的 general_log,分析日志行为提前发现问题;如果使用的是 MySQL 5.6 或者更新版本,把 innodb_undo_tablespaces 设置成 2(或更大的值)。如果真的出现大事务导致回滚段过大,这样设置后清理起来更方便。


    题外话:周末愉快,不知道你有没有在加班呢?周末是弯道超车的绝好机会,不要随意浪费哈(虽然我经常浪费)。切记,人外有人,与君共勉。


    参考资料:丁奇,MySQL实战45讲



    部分内容来自网络,如有侵权请联系作者删除。



    文章转载自爱可可的人生记录仪,如果涉嫌侵权,请发送邮件至:contact@modb.pro进行举报,并提供相关证据,一经查实,墨天轮将立刻删除相关内容。

    评论