MySQL innodb中的只读事物以及事物id的分配方式(3)

trx->id = trx->preallocated_id
        ? trx->preallocated_id : trx_sys_get_new_trx_id();
    //先判断是否是这个事物分配过事物ID,因为从事物池中拿出来
    //很可能以前用过,那么就不需要再次分配了,否则新分配

if (trx->preallocated_id) { //如果是以前使用过的不一定是最大需要加入到vertor中间
        // Maintain ordering in rw_trx_ids
        trx_sys->rw_trx_ids.insert(
            std::upper_bound(trx_sys->rw_trx_ids.begin(),
                    trx_sys->rw_trx_ids.end(),
                    trx->id), trx->id);
    } else {
        // The id is known to be greatest 新分配的肯定是最大 如果是最大加到某位即可
        trx_sys->rw_trx_ids.push_back(trx->id);
    }
}
这里涉及到事物池。
而对于trx_sys_get_new_trx_id如下:

trx_sys_get_new_trx_id()

/*====================*/
{
    ut_ad(trx_sys_mutex_own());

/* VERY important: after the database is started, max_trx_id value is
    divisible by TRX_SYS_TRX_ID_WRITE_MARGIN, and the following if
    will evaluate to TRUE when this function is first time called,
    and the value for trx id will be written to disk-based
    Thus trx id values will not overlap when the database is
    repeatedly */

if (!(trx_sys->max_trx_id % TRX_SYS_TRX_ID_WRITE_MARGIN)) {

trx_sys_flush_max_trx_id(); //TRX_SYS_TRX_ID_WRITE_MARGIN为256 如果trx_sys->max_trx_id达到256的整数倍需要刷盘
        //到TRX_SYS_TRX_ID_STORE中.
    }

return(trx_sys->max_trx_id++);//然后自身+1返回
}

如此我们看到DML事物的事物ID是innodb分配的,而只读事物或者not start事物的事物ID是在show engine的时候根据trx_t结构体
所在内存的指针算法出来的,没有实际的意义。


三、验证只读事物的存在
对于只读事物我们在show engine innodb 只会打印出not start的事物或者活跃的已经获得了锁结构的事物一般是DML操作
但是可以再innodb_trx中观察到,我这里就简单修改show engine innodb 源码打印输出将只读事物打印出来标记为RO TRX,
并且和innodb_trx对比

下面是我修改后show engine innodb的输出

LIST OF TRANSACTIONS FOR EACH SESSION(1)(CHANGE BY GAOPENG ALL mysql_trx_list and rw_trx_list):
(MYSQL)---TRANSACTION 422212177402680, ACTIVE 3 sec fetching rows
mysql tables in use 1, locked 0
0 lock struct(s), heap size 1160, 0 row lock(s), RO TRX
MySQL thread id 7, OS thread handle 140737153619712, query id 411 localhost root Sending data
select * from test.tuser
这里看到我们的只读事物为RO TRX,lock struct(s)为0,没有undo entries,因为有会打印出来。
再来看看innodb_trx的输出:

mysql> select * from information_schema.innodb_trx \G

*************************** 1. row ***************************
                    trx_id: 422212177402680
                trx_state: RUNNING
              trx_started: 2017-07-19 16:52:53
    trx_requested_lock_id: NULL
          trx_wait_started: NULL
                trx_weight: 0
      trx_mysql_thread_id: 7
                trx_query: select * from test.tuser
      trx_operation_state: fetching rows
        trx_tables_in_use: 1
        trx_tables_locked: 0
          trx_lock_structs: 0
    trx_lock_memory_bytes: 1160
          trx_rows_locked: 0
        trx_rows_modified: 0
  trx_concurrency_tickets: 0
      trx_isolation_level: REPEATABLE READ
        trx_unique_checks: 1
    trx_foreign_key_checks: 1
trx_last_foreign_key_error: NULL
 trx_adaptive_hash_latched: 0
 trx_adaptive_hash_timeout: 0
          trx_is_read_only: 1
trx_autocommit_non_locking: 1
没有问题都能观察到,同样我们也如我们所说只读事物的事物ID是422212177402680,只是TRX_T结构体指针所在位置算出来的
算法在上面。这里注意事物也是有状态标识的比如这里的fetching rows。

内容版权声明:除非注明,否则皆为本站原创文章。

转载注明出处:https://www.heiqu.com/983f4776a5c77fc4bd441070e311f44d.html