每日三思-20200828

前言

主要是分享讨论一些有意思的问题,也可以用这个当做MySQL知识体系的自查表

问题项

  1. 事务的隔离级别及其含义?
  2. 事务隔离的实现原理?
  3. 长事务的问题以及如何避免长事务?
会飞的大象
讨论数量: 2

自答:
问题1:

  • 读未提交(READ UNCOMMITTED):一个事务还没提交时,它做的事情能被其他事务看到
  • 读已提交(Read Committed):事务提交后,它做的变更才能被其他事务看到
  • 可重复读(Repeatable Read):一个事务在执行过程中所查看到的数据,与事务启动时能看到的数据是一致的。当然它做的变更也只能事务提交后,其他事务才能看到
  • 可串行化(SERIALIZABLE):对于同一行记录了,写操作时会加写锁,读操作是会加读锁。当出现读写冲突的时候,只有当这个事务完成时,下一个事务才能继续执行。

问题2 :

在Mysql中,每条记录在更新的时候都会同时记录一条回滚操作。记录上的最新值可以通过回滚操作,得到前一个状态的值,分别是redolog(重做)和undolog(回滚日志)。另外在读层面,根据不同的事务隔离界别,例如可重复读会在创建事务时创建视图,同时记录当前数据版本,来保证在事务执行过程中所读数据的一致性。同一条记录在系统中可以存在多个版本,这就是数据库的多版本并发控制(MVCC)

问题3:

  • 缺点:长事务意味着需要保留很多事务视图,来保证能够访问数据库中的任何数据,在该次事务提交前,数据库中可能使用的回滚段都要保留,导致占用大量的存储空间。 长事务还会占用锁资源,会出现锁争抢的情况
  • 解决方案:
    • 开发端
      • 确认是否使用了set autocommit=0,确认逻辑可以在测试环境展示,将MySql的general_log开启来观察,如果使用了,将其改为1
      • 确认是否有不必要的只读事务,该项检查的目的是为了防止有些PDO处理逻辑会默认用到begin/commit,导致一些查询语句也走事务。
      • 业务链接数据库时,根据对业务的预估,通过 SET MAX_EXECUTION_TIME 命令来控制每个语句执行的最大时间,避免单个语句执行太长时间
    • 数据库端
      • 设定长事务时间阈值,监控innodb_trx表长事务
      • Percona-Toolkit系列之pt-kill工具使用
3年前 评论

讨论应以学习和精进为目的。请勿发布不友善或者负能量的内容,与人为善,比聪明更重要!