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。