Uploaded image for project: 'WiredTiger'
  1. WiredTiger
  2. WT-937

discarding a dirty page (new-split branch)

    • Type: Icon: Task Task
    • Resolution: Done
    • WT2.2
    • Affects Version/s: None
    • Component/s: None

      @michaelcahill, I think I just saw the eviction attempt to discard modified pages core you reported in WT-932.

      Here's the stack:

      WT-6  0x00000000004abc2c in __wt_page_out (session=0x8024fe400, 
          pagep=0x8065c7070) at ../src/btree/bt_discard.c:54
      WT-7  0x00000000004abbc2 in __wt_ref_out (session=0x8024fe400, ref=0x8065c7070)
          at ../src/btree/bt_discard.c:32
      WT-8  0x000000000045ce7e in __rec_page_dirty_update (session=0x8024fe400, 
          ref=0x8065c7070, exclusive=0) at ../src/btree/rec_evict.c:178
      WT-9  0x000000000045cb53 in __wt_rec_evict (session=0x8024fe400, 
          ref=0x8065c7070, exclusive=0) at ../src/btree/rec_evict.c:77
      WT-10 0x0000000000445e20 in __wt_evict_page (session=0x8024fe400, 
          ref=0x8065c7070) at ../src/btree/bt_evict.c:393
      WT-11 0x000000000044786e in __wt_evict_lru_page (session=0x8024fe400, is_app=1)
          at ../src/btree/bt_evict.c:1210
      WT-12 0x00000000004a64eb in __wt_cache_full_check (session=0x8024fe400)
          at cache.i:93
      

      It's a WT_PAGE_COL_VAR replacement page, page->modify->flags = 4, and it's dirty, page->modify->write_gen = 2.

      I think this is a problem with the changes in __rec_review in new-split, but enough has changed that I'm not 100% sure of the details.

      There are two interesting chunks of code. First, in __rec_review:

      if (__wt_page_is_modified(page)) {
              flags = WT_EVICTION_LOCKED;
              if (exclusive)
                      LF_SET(WT_SKIP_UPDATE_ERR);
              else if (top && !WT_PAGE_IS_INTERNAL(page) &&
                  page->memory_footprint > 10 * btree->maxleafpage)
                      LF_SET(WT_SKIP_UPDATE_RESTORE);
              WT_RET(__wt_rec_write(session, ref, NULL, flags));
      } else {
              /*
               * If the page was ever modified, make sure all of the updates
               * on the page are old enough they can be discarded from cache.
               */
              if (!exclusive && mod != NULL &&
                  !__wt_txn_visible_all`(session, mod->rec_max_txn))
                      return (EBUSY);
      }
      

      Notes:

      • the develop branch applies the __wt_txn_visible_all test to all pages, including the ones "cleaned" by reconciliation, in new-split I changed it to apply only to pages on which we didn't call reconciliation, that is, clean pages we're evicting.
      • the develop branch asserts the page is clean after writing it, so there must be conditions in new-split where a page can return success that it didn't before. (I removed that assertion for some reason, but I'll put it back shortly.)
      • the develop branch had 2 flags, SERVER_LOCKED and UPDATE_QUIT; I got rid of UPDATE_QUIT because I thought it was the same as SERVER_LOCKED, that is, if you're reconciling for eviction, quit if you can't skip an update. That may have introduced a bug, but I don't see it – anyway, given how much __rec_txn_read has changed, it's hard to tell.

      The second chunk of code is this one, in reconciliation wrapup:

      /*
       * If no updates were skipped, we have a new maximum transaction written
       * for the page (used to decide if a clean page can be evicted).  The
       * page only might be clean; if the write generation is unchanged since
       * reconciliation started, clear it and update cache dirty statistics,
       * if the write generation changed, then the page has been written since
       * we started reconciliation, it cannot be discarded.
       */
      if (!r->leave_dirty) {
              mod->rec_max_txn = r->max_txn;
      
              if (WT_ATOMIC_CAS(mod->write_gen, r->orig_write_gen, 0))
                      __wt_cache_dirty_decr(session, page);
      }
      

      Where we can return 0 even if the page will remain dirty.

            Assignee:
            keith.bostic@mongodb.com Keith Bostic (Inactive)
            Reporter:
            keith.bostic@mongodb.com Keith Bostic (Inactive)
            Votes:
            0 Vote for this issue
            Watchers:
            1 Start watching this issue

              Created:
              Updated:
              Resolved: