2.Mysql的死锁,及事务日志

2018-08-19  本文已影响9人  one_zheng

死锁

死锁是指两个或多个事务在同一资源上相互占用,并请求锁定对方占用的资源,从而导致恶性循环的现象。当多个事务试图以不同的顺序锁定资源时,也会长生死锁。例如,设想下面两个事务同事处理StockPrice表:

事务1
  START TRANSACTION;
  UPDATE StockPrice SET close = 45.50 WHERE stock_id = 4 and date = '2002-05-01';
  UPDATE StockPrice SET close = 19.80 WHERE stock_id = 3 and date = '2002-05-02';
  COMMIT;

事务2
  START TRANSACTION;
  UPDATE StockPrice SET high = 20.12 WHERE stock_id = 3 and date= '2002-05-02';
  UPDATE StockPrice SET high = 47.20 WHERE stock_id = 4 and date = '2002-05-01;'

 如果凑巧,两个事务都执行了第一条UPDATE语句,更新了一行数据,同时也锁定了该行数据,接着每个事务都尝试去执行第二条UPDATE语句,却发现该行已经被对方锁定,然后两个事务都等待对方释放锁,同时又持有对方需要的锁,则陷入死循环。除非有外部因素介入才可能解除死锁。
 解决这种问题:

事务日志

 事务日志可以帮助提高事务的效率。使用事务日志,存储引擎在修改表的数据时只需要修改其内存拷贝,再把该修改行为记录到持久在硬盘上的事务日志中,而不用每次都将修改的数据本身持久到磁盘。事务日志采用的是追加的方式,因此写日志的操作是磁盘上一小块区域的顺序I/O,而不像随机I/O需要在磁盘的多个地方移动磁头,所以采用事务日志的方式来说要快得多。事务日志持久以后,内存中被修改的数据在后台可以慢慢地刷回磁盘。目前大多数存储引擎都是这样实现的,我们通常称之为预写式日志,修改数据需要些两次磁盘。
 如果数据的修改已经记录到事务日志并持久化,但数据本身没有写回到磁盘,此时系统崩溃,存储引擎在重启时能够恢复这部分修改的数据,具体的恢复方式则视存储引擎而定。

Mysql中的事务

 提供了两种事务型的存储引:InnodDB和 NDB Cluster。

自动提交

 Mysql默认采用自动提交模式。也就是说,如果不是显式地开始一个事务,则每个查询都被当做一个事务执行操作。在当前连接中,可以通过设置AUTOCOMMIT变量来启用或者禁用自动提交模式:

image.png

1或者ON表示启用,0或者OFF表示禁用。当AUTOCOMMIT=0时,所有的查询都是在一个事务中,直到显示地执行COMMIT提交或者ROLLBACK回滚,该事物结束,同时又开启了另一个新事务。修改AUTOCOMMIT对非事务的表,比如MyISAL或者内存表,不会有任何影响。

在执行之前会强制执行COMMITt提交当前的活动事务的命令

image.png image.png

MVCC是行级锁的一个变种,但是它在很多情况下避免了加锁操作,因此开销更低。

MVCC的实现,是通过保存数据在某个时间点的快照来实现的。也就是说,不管需要执行多长时间,每个事务看到的数据都是一致的。根据事务开始的时间不同,每个事务对同一张表,同一时刻看到的数据可能是不一样的。

不同存储引擎的MVCC实现是不同的,典型的有乐观(optimist)并发控制和悲观(pessimistic)并发控制。

InnoDB的MVCC,是通过在每行记录后面保存两个隐藏的列来实现的。这俩个列,一个保存了行的创建时间,一个保存行的过期时间(或删除时间)。当然存储的并不是实际的时间值,而是系统版本号。每开始一个新的事务,系统版本号都会自动递增。事务开始时刻的系统版本号会作为事务的版本号,用来和查询到的每行记录的版本号进行比较。

image.png
上一篇 下一篇

猜你喜欢

热点阅读