事务

事务

事务就是一组原子性的SQL查询,或者说一个独立的工作单元。如果数据库引擎能够成功地对数据库应用该组查询的全部语句,那么就执行该组查询。如果其中有任何一条语句因为崩溃或其他原因无法执行,那么所有的语句都不会执行。也就是说,事务内的语句,要么全部执行成功,要么全部执行失败。

ACID

  • atomicity(原子性) :要么全执行,要么全都不执行;
  • consistency(一致性):在事务开始和完成时,数据都必须保持一致状态;
  • isolation(隔离性) :事务处理过程中的中间状态对外部是不可见的;
  • durability(持久性) :事务完成之后,它对于数据的修改是永久性的。

InnoDB 采用 redo log 机制来保证事务更新的一致性和持久性。

Redo log

Redo log称为重做日志,用于记录事务操作变化,记录的是数据被修改之后的值。

Redo log 由两部分组成:

  • 内存中的重做日志缓冲(redo log buffer)
  • 重做日志文件(redo log file)

每次数据更新会先更新 redo log buffer,然后根据 innodb_flush_log_at_trx_commit 来控制 redo log buffer 更新到redo log file 的时机。innodb_flush_log_at_trx_commit 有三个值可选:

  • 0:事务提交时,在事务提交时,每秒触发一次 redo log buffer 写磁盘操作,并调用操作系统 fsync 刷新 IO 缓存。
  • 1:事务提交时,InnoDB 立即将缓存中的 redo 日志写到日志文件中,并调用操作系统 fsync 刷新 IO 缓存;
  • 2:事务提交时,InnoDB 立即将缓存中的 redo 日志写到日志文件中,但不是马上调用 fsync 刷新 IO 缓存,而是每秒只做一次磁盘 IO 缓存刷新操作。
    innodb_flush_log_at_trx_commit 参数的默认值是 1,

Binlog

二进制日志(binlog)记录了所有的 DDL(数据定义语句)和 DML(数据操纵语句)

Binlog 有以下几个作用:

  • 恢复:数据恢复时可以使用二进制日志
  • 复制:通过传输二进制日志到从库,然后进行恢复,以实现主从同步
  • 审计:可以通过二进制日志进行审计数据的变更操作

sync_binlog 来控制累积多少个事务后才将二进制日志 fsync 到磁盘。

  • sync_binlog=0,表示每次提交事务都只write,不fsync
  • sync_binlog=1,表示每次提交事务都会执行fsync
  • sync_binlog=N(N>1),表示每次提交事务都write,累积N个事务后才fsync

数据库突然断电不丢数据

只要 innodb_flush_log_at_trx_commit 和 sync_binlog 都为 1(通常称为:双一),就能确保MySQL 机器断电重启后,数据不丢失。

事务建议

  • 循环写入的情况,如果循环次数不是太多,建议在循环前开启一个事务,循环结束后统一提交。
  • 优化事务里的语句顺序,减少锁时间。
  • 关注不同事务访问资源的顺序,避免死锁。
  • 创建事务之前,关注事务隔离级别。
  • 不在事务中混合使用存储引擎(MyISAM无法回滚)

分布式事务

分布式事务使用两阶段提交协议:
第一阶段:所有分支事务都开始准备,告诉事务管理器自己已经准备好了;
第二阶段:确定是 rollback 还是 commit,如果有一个节点不能提交,则所有节点都要回滚。

MySQL 自带的分布式事务

xa start 'a','a_1'; //启动分支事务
xa end 'a','a_1'; //结束分支事务
xa prepare 'a','a_1'; //进入准备状态
xa commit 'a','a_1';  //提交分支事务
xa recover;  //返回当前数据库中处于 prepare 状态的分支事务的详细信息
原文地址:https://www.cnblogs.com/hainingwyx/p/14533863.html