zoukankan      html  css  js  c++  java
  • 关于MySQL变量innodb_rollback_on_timeout一些讨论

    1innodb_rollback_on_timeout变量

    下面是MySQL官方手册关开innodb_rollback_on_timeout变量的说明:

    In MySQL 5.0.13 and up, InnoDB rolls back only the last statement on a transaction timeout by default. If --innodb_rollback_on_timeout is specified, a transaction timeout causes InnoDB to abort and roll back the entire transaction (the same behavior as before MySQL 5.0.13). This variable was added in MySQL 5.0.32.

    该变量默认值为OFF,如果事务因为加锁超时,会回滚上一条语句执行的操作。如果设置ON,则整个事务都会回滚。

     

    下面通过一个示例来验证上面这段话。

    2、示例

    (1) innodb_rollback_on_timeoutOFF

    Session 1

    Session 2

    mysql> create table tt(c1 int primary key, c2 int)engine=innodb;

    Query OK, 0 rows affected (0.01 sec)

    mysql> insert into tt values(1, 1);

    Query OK, 1 row affected (0.00 sec)

    mysql> begin;

    Query OK, 0 rows affected (0.00 sec)

    mysql> select * from tt where c1=1 lock in share mode;

    +----+------+

    | c1 | c2   |

    +----+------+

    |  1 |    1 |

    +----+------+

    1 row in set (0.00 sec)

     

     

    mysql> begin;

    Query OK, 0 rows affected (0.00 sec)

     

    mysql> insert into tt values(10,10);

    Query OK, 1 row affected (0.00 sec)

     

    mysql> delete from tt where c1=1;

    ERROR 1205 (HY000): Lock wait timeout exceeded; try restarting transaction

    mysql> select * from tt;

    +----+------+

    | c1 | c2   |

    +----+------+

    |  1 |    1 |

    | 10 |   10 |

    +----+------+

    2 rows in set (0.00 sec)

     

    mysql> rollback;

    Query OK, 0 rows affected (0.01 sec)

     

    mysql> select * from tt;

    +----+------+

    | c1 | c2   |

    +----+------+

    |  1 |    1 |

    +----+------+

    1 row in set (0.00 sec)

    mysql> select * from tt;

    +----+------+

    | c1 | c2   |

    +----+------+

    |  1 |    1 |

    +----+------+

    1 row in set (0.00 sec)

     

     

    mysql> begin;

    Query OK, 0 rows affected (0.00 sec)

     

    mysql> insert into tt values(10,10);

    Query OK, 1 row affected (0.00 sec)

     

    mysql> delete from tt where c1=1;

    ERROR 1205 (HY000): Lock wait timeout exceeded; try restarting transaction

    mysql> commit;

    Query OK, 0 rows affected (0.02 sec)

     

    mysql> select * from tt;

    +----+------+

    | c1 | c2   |

    +----+------+

    |  1 |    1 |

    | 10 |   10 |

    +----+------+

    2 rows in set (0.00 sec)

    session2因为加锁超时,事务回退到上一条语句。 

     

    (2) innodb_rollback_on_timeoutON

    Session 1

    Session 2

    mysql> begin;

    Query OK, 0 rows affected (0.00 sec)

     

    mysql> select * from tt where c1=1 lock in share mode;

    +----+------+

    | c1 | c2   |

    +----+------+

    |  1 |    1 |

    +----+------+

    1 row in set (0.00 sec)

     

     

    mysql> begin;

    Query OK, 0 rows affected (0.00 sec)

     

    mysql> insert into tt values(11,11);

    Query OK, 1 row affected (0.00 sec)

     

    mysql> delete from tt where c1=1;

    ERROR 1205 (HY000): Lock wait timeout exceeded; try restarting transaction

    mysql> select * from tt;

    +----+------+

    | c1 | c2   |

    +----+------+

    |  1 |    1 |

    | 10 |   10 |

    +----+------+

    2 rows in set (0.00 sec)

    mysql> commit;

    Query OK, 0 rows affected (0.00 sec)

     

    mysql> select * from tt;

    +----+------+

    | c1 | c2   |

    +----+------+

    |  1 |    1 |

    | 10 |   10 |

    +----+------+

    2 rows in set (0.00 sec)

    session2加锁超时,整个事务回滚。

    3、总结

    innodb_rollback_on_timeoutOFF,事务会回滚到上一个保存点,InnoDB在执行每条SQL语句之前,都会创建一个保存点,参见代码:

    int

    row_insert_for_mysql(

                                                   /* out: error code or DB_SUCCESS */

             byte*                 mysql_rec,       /* in: row in the MySQL format */

             row_prebuilt_t*     prebuilt)  /* in: prebuilt struct in MySQL

                                                   handle */

    {

    。。。

             savept = trx_savept_take(trx);

    。。。

    如果事务因为加锁超时,相当于回滚到上一条语句。但是报错后,事务还没有完成,用户可以选择是继续提交,或者回滚之前的操作,由用户选择是否进一步提交或者回滚事务。

    innodb_rollback_on_timeoutON,整个事务都会回滚。这可以从row_mysql_handle_errors函数中得到验证。

    ibool
    row_mysql_handle_errors(
    /*====================*/
                    /* out: TRUE if it was a lock wait and
                    we should continue running the query thread 
    */
        ulint*        new_err,/* out: possible new error encountered in
                    lock wait, or if no new error, the value
                    of trx->error_state at the entry of this
                    function 
    */
        trx_t*        trx,    /* in: transaction */
        que_thr_t*    thr,    /* in: query thread */
        trx_savept_t*    savept)    /* in: savepoint or NULL */
    {
    ...
    else if (err == DB_DEADLOCK //发生死锁
               || err == DB_LOCK_TABLE_FULL
               || (err == DB_LOCK_WAIT_TIMEOUT
                   && row_rollback_on_timeout)) {
            /* Roll back the whole transaction; this resolution was added
            to version 3.23.43 
    */

            trx_general_rollback_for_mysql(trx, FALSE, NULL); //事务全部回滚
                    
        } else if (err == DB_OUT_OF_FILE_SPACE
               || err == DB_LOCK_WAIT_TIMEOUT) {

            ut_ad(!(err == DB_LOCK_WAIT_TIMEOUT
                    && row_rollback_on_timeout));

                   if (savept) { //回滚到上一个保存点
                /* Roll back the latest, possibly incomplete
                insertion or update 
    */

                trx_general_rollback_for_mysql(trx, TRUE, savept);
            }
            /* MySQL will roll back the latest SQL statement */
    ...

     

    问题:innodb_rollback_on_timeout为OFF,事务的原子性被破坏了吗?

    答:NO,从示例中可以看到,事务只是回退上一条语句的状态,而整个事务实际上没有完成(提交或者回滚),而作为应用程序在检测这个错误时,应该选择是提交或者回滚事务。如果严格要求事务的原子性,当然是执行ROLLBACK,回滚事务。


    作者:MrDB
    出处:http://www.cnblogs.com/hustcat/
    本文版权归作者和博客园共有,欢迎转载,但未经作者同意必须保留此段声明,且在文章页面明显位置给出原文连接,否则保留追究法律责任的权利。

  • 相关阅读:
    CodeForces 681D Gifts by the List (树上DFS)
    UVa 12342 Tax Calculator (水题,纳税)
    CodeForces 681C Heap Operations (模拟题,优先队列)
    CodeForces 682C Alyona and the Tree (树上DFS)
    CodeForces 682B Alyona and Mex (题意水题)
    CodeForces 682A Alyona and Numbers (水题,数学)
    Virtualizing memory type
    页面跳转
    PHP Misc. 函数
    PHP 5 Math 函数
  • 原文地址:https://www.cnblogs.com/hustcat/p/2775487.html
Copyright © 2011-2022 走看看