事务实现原理-回滚原理

1. 每个事务都有个事务id

 2. 最终落到 每一个块的原子性。 

     写一个块,部分写完部分未写完。如何判断是否全写完,如何回滚 如何重写,如何幂等重写?

和mysql的事务比较起来:

1. 对page的写是加锁串行的.  (这样lsn大小判断幂等法才有意义)

2. 回滚操作是要实现的.回滚后才能执行下一个对page的改动.

     每次操作有事务id,放在块最后。重写的时候发现有就不重写。没有,部分写了怎么办?double write。如果大事务回滚,只不过改成原来的操作逆写。对块来说另外一种写。省磁盘,只double write,不备份之前的。


正常思考逻辑.

  

    1. 写undo log

    2. 对字段更新

    3. 如回滚,利用undo回滚

    4. 如提交,不做任何操作.

问题: 回滚到一半宕机了怎么办?

我的理解是

    1. update了就加锁了,  加锁以后就可以串行了, 可以大小判断幂等法进行幂等重试.

    其他点: 查看源代码,是否在rollback的时候修改了事务的持久化信息.

事务一旦到达终态.(commit 或者roll back完毕)就,可以从持久化中删除.


考虑性能问题后的改造以及引发的一致性问题解决--:

解决性能问题,引入redo日志

    不时时刷新. 为了保持持久性,引入redo, 这样就引入了脏页的刷新. 和多次刷新问题. 引入lsn进行幂等刷新.


参考文档:

[1] MySQL数据库InnoDB存储引擎Log漫游 http://www.zhdba.com/mysqlops/2012/04/06/innodb-log1/ --回过头再看 老码农 老师的mvcc

[2]  MySQL · 引擎特性 · InnoDB 事务子系统介绍 . 和"老码农mysql mvcc" 都说到一点 PostgreSQL 回滚性能更好.

引文"

当由于各种原因(例如死锁,或者显式ROLLBACK)需要将事务回滚时,会调用handler接口ha_rollback_low,进而调用InnoDB函数trx_rollback_for_mysql来回滚事务。回滚的方式是提取undo日志,做逆向操作。

由于InnoDB的undo是单独写在表空间中的,本质上和普通的数据页是一样的。如果在事务回滚时,undo页已经被从内存淘汰,回滚操作(特别是大事务变更回滚)就可能伴随大量的磁盘IO。因此InnoDB的回滚效率非常低。有的数据库管理系统,例如PostgreSQL,通过在数据页上冗余数据产生版本链的方式来实现多版本,因此回滚起来非常方便,只需要设置标记即可,但额外带来的问题就是无效数据清理开销。

"

[3] 老码农 mysql mvcc 引文:"Rollback则稍微复杂点,需要根据当前回滚指针从undo log中找出事务修改前的版本,并恢复。如果事务影响的行非常多,回滚则可能会变的效率不高,根据经验值没事务行数在1000~10000之间,Innodb效率还是非常高的。很显然,Innodb是一个COMMIT效率比Rollback高的存储引擎。据说,Postgress的实现恰好与此相反。"

你可能感兴趣的:(数据库)