MySQL ReadView

aoerqileng發表於2022-05-04
mysql 中一致性讀的read_view 建立以及可見性判斷
//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

來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/25719946/viewspace-2890697/,如需轉載,請註明出處,否則將追究法律責任。

相關文章