berkeley db write ahead logging的代码实现

下面的代码保证了BDB 的write ahead logging机制. 在写database page之前, 确保此page buffer对应的log lsn已经 sync到 disk上.

    //src/mp/mp_bh.c, __memp_pgwrite()

    /*
     * If the page is in a file for which we have LSN information, we have
     * to ensure the appropriate log records are on disk.
     */
    if (LOGGING_ON(env) && mfp->lsn_off != DB_LSN_OFF_NOTSET &&
        !IS_CLIENT_PGRECOVER(env)) {
        memcpy(&lsn, bhp->buf + mfp->lsn_off, sizeof(DB_LSN));
        if (!IS_NOT_LOGGED_LSN(lsn) &&
            (ret = __log_flush(env, &lsn)) != 0)
            goto err;
    }
   // ...
    /* Write the page. */
    if ((ret = __os_io(env, DB_IO_WRITE, dbmfp->fhp, bhp->pgno,
        mfp->pagesize, 0, mfp->pagesize, buf, &nw)) != 0) {
#ifndef HAVE_ATOMICFILEREAD
        atomic_dec(env, &mfp->writers);
#endif
        __db_errx(env, DB_STR_A("3015",
            "%s: write failed for page %lu", "%s %lu"),
            __memp_fn(dbmfp), (u_long)bhp->pgno);
        goto err;
    }
//   ...

思考: 

1. 若写buffer page前, 不保证log lsn已经 sync到 disk上. 则可能程序crash时, database page已经修改, 但没有对应的 log. 则db recover时对 db page的修改无法回滚.

2. 若在 log sync和 写buffer page之间, 程序crash, 则db page没有修改, 但对应的log已经在磁盘上. 这没有关系, recover时 此log record的lsn和db page lsn不一致, 表明 此db修改未被写磁盘, 忽略.

posted @ 2016-02-26 14:11  brayden  阅读(370)  评论(0编辑  收藏  举报