bdb mvcc: buffer 何时可以被 看到; mvcc trans何时被移除

# txn.h

struct __db_txnregion
    SH_TAILQ_HEAD(__active) active_txn;
    SH_TAILQ_HEAD(__mvcc) mvcc_txn;
    
# txn.c, 

__txn_begin_int(), txn 加入的 buffer version 不可以被看见.
        MAX_LSN(td->visible_lsn);

__txn_commit(txn, flags), commit时, td->visible_lsn 被设置, 意味着 从此时起, 此txn 加入的 buffer version 可以被看见了.
    ...
    if (DBENV_LOGGING(env) && (!IS_ZERO_LSN(td->last_lsn) ||
        STAILQ_FIRST(&txn->logs) != NULL)) {
        if (txn->parent == NULL) {
            ...
            if (ret == 0 && !IS_ZERO_LSN(td->last_lsn)) {
                ret = __txn_flush_fe_files(txn);
                if (ret == 0)
                    ret = __txn_regop_log(env, txn,
                        &td->visible_lsn, LOG_FLAGS(txn),
                        TXN_COMMIT,
                        (int32_t)time(NULL), id,
                        request.obj);

txn_end():  trans从active queue里移除, 如果其向 cache 加入了 mvcc page buffer, 则放入mvcc queue中.
    TXN_SYSTEM_LOCK(env);
    td->status = is_commit ? TXN_COMMITTED : TXN_ABORTED;
    SH_TAILQ_REMOVE(&region->active_txn, td, links, __txn_detail);
    ...
    if (txn->parent != NULL) {
        ptd = txn->parent->td;
        SH_TAILQ_REMOVE(&ptd->kids, td, klinks, __txn_detail);
    } else if ((mvcc_mtx = td->mvcc_mtx) != MUTEX_INVALID) {
        MUTEX_LOCK(env, mvcc_mtx);
        if (td->mvcc_ref != 0) {
            SH_TAILQ_INSERT_HEAD(&region->mvcc_txn,
                td, links, __txn_detail);
                
# txn_region.c

__txn_remove_buffer(), 若 mvcc txn 创建的buffer 全部被移除, 则此txn可以free

    MUTEX_LOCK(env, td->mvcc_mtx);
    DB_ASSERT(env, td->mvcc_ref > 0);

    /*
     * We free the transaction detail here only if this is the last
     * reference and td is on the list of committed snapshot transactions
     * with active pages.
     */
    need_free = (--td->mvcc_ref == 0) && F_ISSET(td, TXN_DTL_SNAPSHOT);
    MUTEX_UNLOCK(env, td->mvcc_mtx);

    if (need_free) {
        MUTEX_UNLOCK(env, hash_mtx);

        ret = __mutex_free(env, &td->mvcc_mtx);
        td->mvcc_mtx = MUTEX_INVALID;

        TXN_SYSTEM_LOCK(env);
        SH_TAILQ_REMOVE(&region->mvcc_txn, td, links, __txn_detail);
        STAT_DEC(env,
            txn, nsnapshot, region->stat.st_nsnapshot, td->txnid);
        __env_alloc_free(&mgr->reginfo, td);
        TXN_SYSTEM_UNLOCK(env);

        MUTEX_READLOCK(env, hash_mtx);
    }

    return (ret);
}

 

posted @ 2016-08-19 15:49  brayden  阅读(247)  评论(0)    收藏  举报