mysql系列之事务

mysql系列之事务

ACID

  • 原子性 atomicity
  • 一致性 consistency
  • 隔离性 isolation
  • 持久性 durability

原子性: 数据库事务整个操作要么都做,要么都不做。

一致性: 如事务前后,完整性约束没有破坏, eg唯一约束

隔离性: 事务之间互相分离(通过锁)

事务分类

扁平事务

所有操作同一层次,不能提交或回滚部分事务。

带保存点的扁平事务

SavePoint

链事务

链事务只能回滚到最近保存点

嵌套事务

Screen Shot 2020-09-11 at 4.12.51 PM

分布式事务

Post not found: mysql系列之分布式事务 mysql系列之分布式事务

事务的实现

事务的隔离是锁来实现的

原子,一致,持久性是redo 和 undo。redo保证事务持久性,

redo

why redo log ? 数据的修改 就是对数据页里面保存的数据做修改 而一个数据页16kb 你每次修改一条或多条数据 如果就以页为单位刷回到硬盘里是得不偿失的,先写日志再刷盘。

重做日志实现持久性,

  • 重做日志缓冲
  • 日志文件

事务提交必须将日志写入文件 。参数innodb_flush_log_at_trx_commit控制redo日志刷新到磁盘的策略。

默认为1: 事务提交必须fsync,宕机重启不会丢失。

0: 事务提交不写入,master thread 每秒进行重做日志的fsync。

2: 事务提交,写入文件缓存,不fsync。

redo 记录的是物理层面非逻辑层面(bin log),记录每个页的修改。

binlog再事务提交时记录,每个事务只有一个记录。而redo log 记录页修改,同一事务可能对应多个条目。

mysql 重启后,不论是否是正常关闭,都会恢复redo。因为redo 记录是物理日志,速度很快,checkpoint 记录了已经刷新到磁盘页的LSN(日志序列号), 恢复checkpoint开始的日志部分

undo

事务回滚和MVCC,存放再共享表空间的undo segment。

逻辑日志,

事务控制语句

  • start transaction/being
  • commit
  • rollback
  • savepoint identifier
  • rollback to [Savepoint] identifier

隐式提交的sql ,即执行完会有隐式commit

Screen Shot 2020-09-11 at 5.13.10 PM

事务的统计

innodb支持事务,除了QPS(query per seconds)还要考虑TPS (transaction per seconds ),即关注每秒事务的处理能力。

  • handler-commit
  • handler-rollback

事务的隔离级别

SQL标准的四个隔离级别:

  • READ UNCOMMITTED
  • READ COMMITTED
  • REPEATABLE READ
  • SERIALIZABLE

默认级别 repeatable read, 不同的是在改隔离级别,innodb是有next-keylock 避免幻读。

隔离级别越低,锁越少或者保持锁时间越短, 大多数系统可以设置read commited.

幻读 : https://www.zhihu.com/question/47007926/answer/222348887

事务的使用

不要在循环中提交事务, 每次提交都写重做日志。

显式控制事务,不用自动提交- set autocommit=0

不自动回滚

长事务

LONG Lived transaction , 执行时间较长的事务。

例如为银行所有储户添加利息, 可能需要非常长的时间, 导致的问题:

出现问题是,重新开始代价非常大。

对于长事务,转成小批量的事务处理, 发生问题是只回滚一部分数据。


https://mp.weixin.qq.com/s?__biz=MzA3OTEyNzYxMg==&mid=2247483761&idx=1&sn=36e824810a4918b4e8707ec93388e437&scene=21#wechat_redirect