Mysql 事务日志为什么提高事务的效率

前言

今天被抛出一个问题:系统奔溃,用日志恢复,那么日志事务又是什么原理呢?

事务日志——预写式日志

我们可以了解到,事务日志的工作过程:修改表的数据(存储引擎控制) ==》 拷贝到内存中 ==》 把该修改行为记录到持久在硬盘上的事务日志中 ==》 后台慢慢把内存数据刷回磁盘持久化保存。
此方式称之为,预写式日志,修改数据需要写两次磁盘。

MySQL中的事务

MySQL提供了两种事务存储引擎:InnoDB和NDB Cluster。另外还有一些第三方的存储引擎(例如,XtraDB)也支持事务。

自动提交(AUTOCOMMIT)

MySQL默认采用自动提交模式。如果不是显示地开始一个事务,则每个查询都被当作一个事务执行提交操作。在当前连接中,可以通过设置AUTOCOMMIT变量来启用或禁用自动提交模式。1或者ON表示启用,0或者OFF表示禁用。
>1)当AUTOCOMMIT=0时,所有的查询都是在一个事务中,直到显示地执行COMMIT,或者ROLLBACK时,该事务结束。 

(2)修改AUTOCOMMIT对非事务型的表(例如,MyISAM),不会有任何影响,相当于一直处于AUTOCOMMIT启用的模式。
(3)一些命令,在执行前会强制执行COMMIT提交当前的事务。例如,使用DDL(数据定义语言)。
(4)MySQL可以通过执行SET TRANSACTION ISOLATION LEVEL命令来设置隔离级别,新的隔离级别会在下一个事务开始时生效。

# 查看AUTOCOMMIT状态和启用
SHOW VARIABLES LIKE 'AUTOCOMMIT';
SET AUTOCOMMIT = 1;

# 设置下一个会话的隔离级别为READ COMMITED
SET TRANSACTION ISOLATION LEVEL READ COMMITED;

在事务中混合使用存储引擎

如果在事务中混合使用了事务型和非事务型的表(InnoDB和MyISAM表),如果该事务需要回滚,非事务型表(MyISAM)的变更无法撤销,导致数据库处于不一致状态。

隐式和显式锁定

InnoDB采用的是两阶段锁定协议(two-phase locking protocol)。

  • 隐式锁定,InnoDB会根据隔离级别在需要的时候自动加锁,并在执行COMMIT或ROLLBACK时释放。
  • 显式锁定,InnoDB也支持通过特定的语句进行显式锁定,这些语句不属于SQL规范。
    SELECT ... LOCK IN SHARE MODE;
    SELECT ... FOR UPDATE;
    

在InnoDB下,使用表锁要注意

(1)使用LOCK TABLES虽然可以给InnoDB加表级锁,但必须说明的是,表锁不是由InnoDB存储引擎层管理的,而是由其上一层──MySQL Server负责的,仅当autocommit=0、InnoDB_table_locks=1(默认设置)时,InnoDB层才能知道MySQL加的表锁,MySQL Server也才能感知InnoDB加的行锁,这种情况下,InnoDB才能自动识别涉及表级锁的死锁,否则,InnoDB将无法自动检测并处理这种死锁。
  (2)在用 LOCK TABLES对InnoDB表加锁时要注意,要将AUTOCOMMIT设为0,否则MySQL不会给表加锁;事务结束前,不要用UNLOCK TABLES释放表锁,因为UNLOCK TABLES会隐含地提交事务;COMMIT或ROLLBACK并不能释放用LOCK TABLES加的表级锁,必须用UNLOCK TABLES释放表锁。正确的方式见如下语句:
  例如,如果需要写表t1并从表t读,可以按如下做:

SET AUTOCOMMIT=0;
LOCK TABLES t1 WRITE, t2 READ, ...;
[do something with tables t1 and t2 here];
COMMIT;
UNLOCK TABLES;

参考

MySQL读书笔记-事务日志,MySQL中的事务
mysql锁——innodb的行级锁

相关推荐
©️2020 CSDN 皮肤主题: 大白 设计师:CSDN官方博客 返回首页