mysql 中一致性读的read_view 创建以及可见性判断
//在查询的时候进行判断是否是一致性读,是就创建一个read——view
if (node->consistent_read) {
/* Assign a read view for the query */
node->read_view = trx_assign_read_view(
thr_get_trx(thr));
}
//这个是分配read_view的函数
read_view_t*
trx_assign_read_view(
/*=================*/
/* out: consistent read view */
trx_t* trx) /* in: active transaction */
{
ut_ad(trx->conc_state == TRX_ACTIVE);
if (trx->read_view) {
return(trx->read_view);
}
mutex_enter(&kernel_mutex);
if (!trx->read_view) {
trx->read_view = read_view_open_now(trx, trx->read_view_heap);
}
mutex_exit(&kernel_mutex);
return(trx->read_view);
}
//在read_view_open_now中,
//还未分配的最小事务号分配给low_limit_no,所有 >=这个id 的事务都是不可见的。未来的事务
view->low_limit_no = trx_sys->max_trx_id;
view->low_limit_id = view->low_limit_no;
// 最小活跃事务ID给up_limit_id,所有< 这个id的事务都是可见的。已经提交的
view->up_limit_id = read_view_get_nth_trx_id(view, n - 1);
//read view可见性判断
UNIV_INLINE
ibool
read_view_sees_trx_id(
/*==================*/
/* out: TRUE if sees */
read_view_t* view, /* in: read view */
dulint trx_id) /* in: trx id */
{
ulint n_ids;
int cmp;
ulint i;
//事务ID小于up_limit_id,可见
if (ut_dulint_cmp(trx_id, view->up_limit_id) < 0) {
return(TRUE);
}
//事务大于等于low_limit_id 不可见
if (ut_dulint_cmp(trx_id, view->low_limit_id) >= 0) {
return(FALSE);
}
/* We go through the trx ids in the array smallest first: this order
may save CPU time, because if there was a very long running
transaction in the trx id array, its trx id is looked at first, and
the first two comparisons may well decide the visibility of trx_id. */
// 因为事务开始时候的活跃事务跟创建view时候的事务状态可能不一致,所以判断可见性的时候,需要跟创建view时候的活跃事务对比下
// 针对事务>=最小活跃事务ID,并且 < 最大事务的事务,遍历view开始时候的活跃事务列表。如果是活跃事务返回false,返回true
n_ids = view->n_trx_ids;
for (i = 0; i < n_ids; i++) {
cmp = ut_dulint_cmp(trx_id,
read_view_get_nth_trx_id(view, n_ids - i - 1));
if (0 == cmp) {
return(FALSE);
} else if (cmp < 0) {
return(TRUE);
}
}
return(TRUE);
}
有兴趣学习源码的加群一起学习啊 QQ: 700072075
