/* * __wt_las_cursor -- * Return a lookaside cursor. */ int __wt_las_cursor( WT_SESSION_IMPL *session, WT_CURSOR **cursorp, uint32_t *session_flags) { WT_CONNECTION_IMPL *conn; WT_DECL_RET; *cursorp = NULL; /* * We don't want to get tapped for eviction after we start using the * lookaside cursor; save a copy of the current eviction state, we'll * turn eviction off before we return. * * Don't cache lookaside table pages, we're here because of eviction * problems and there's no reason to believe lookaside pages will be * useful more than once. */ *session_flags = F_ISSET(session, WT_SESSION_NO_CACHE | WT_SESSION_NO_EVICTION); conn = S2C(session); /* Eviction and sweep threads have their own lookaside table cursors. */ if (F_ISSET(session, WT_SESSION_LOOKASIDE_CURSOR)) { if (session->las_cursor == NULL) { WT_WITHOUT_DHANDLE(session, ret = __las_cursor_create(session, &session->las_cursor)); WT_RET(ret); } *cursorp = session->las_cursor; } else { /* Lock the shared lookaside cursor. */ __wt_spin_lock(session, &conn->las_lock); *cursorp = conn->las_cursor; } /* Turn caching and eviction off. */ F_SET(session, WT_SESSION_NO_CACHE | WT_SESSION_NO_EVICTION); return (0); }
/* * __wt_metadata_cursor_open -- * Opens a cursor on the metadata. */ int __wt_metadata_cursor_open( WT_SESSION_IMPL *session, const char *config, WT_CURSOR **cursorp) { WT_BTREE *btree; WT_DECL_RET; const char *open_cursor_cfg[] = { WT_CONFIG_BASE(session, WT_SESSION_open_cursor), config, NULL }; WT_WITHOUT_DHANDLE(session, ret = __wt_open_cursor( session, WT_METAFILE_URI, NULL, open_cursor_cfg, cursorp)); WT_RET(ret); /* * Retrieve the btree from the cursor, rather than the session because * we don't always switch the metadata handle in to the session before * entering this function. */ btree = ((WT_CURSOR_BTREE *)(*cursorp))->btree; /* * Special settings for metadata: skew eviction so metadata almost * always stays in cache and make sure metadata is logged if possible. * * Test before setting so updates can't race in subsequent opens (the * first update is safe because it's single-threaded from * wiredtiger_open). */ if (btree->evict_priority == 0) WT_WITH_BTREE(session, btree, __wt_evict_priority_set(session, WT_EVICT_INT_SKEW)); if (F_ISSET(btree, WT_BTREE_NO_LOGGING)) F_CLR(btree, WT_BTREE_NO_LOGGING); /* The metadata file always uses checkpoint IDs in visibility checks. */ btree->include_checkpoint_txn = true; return (0); }
/* * __wt_metadata_cursor_open -- * Opens a cursor on the metadata. */ int __wt_metadata_cursor_open( WT_SESSION_IMPL *session, const char *config, WT_CURSOR **cursorp) { WT_BTREE *btree; WT_DECL_RET; const char *open_cursor_cfg[] = { WT_CONFIG_BASE(session, WT_SESSION_open_cursor), config, NULL }; WT_WITHOUT_DHANDLE(session, ret = __wt_open_cursor( session, WT_METAFILE_URI, NULL, open_cursor_cfg, cursorp)); WT_RET(ret); /* * Retrieve the btree from the cursor, rather than the session because * we don't always switch the metadata handle in to the session before * entering this function. */ btree = ((WT_CURSOR_BTREE *)(*cursorp))->btree; /* * Set special flags for the metadata file: eviction (the metadata file * is in-memory and never evicted), logging (the metadata file is always * logged if possible). * * Test flags before setting them so updates can't race in subsequent * opens (the first update is safe because it's single-threaded from * wiredtiger_open). */ if (!F_ISSET(btree, WT_BTREE_IN_MEMORY)) F_SET(btree, WT_BTREE_IN_MEMORY); if (!F_ISSET(btree, WT_BTREE_NO_EVICTION)) F_SET(btree, WT_BTREE_NO_EVICTION); if (F_ISSET(btree, WT_BTREE_NO_LOGGING)) F_CLR(btree, WT_BTREE_NO_LOGGING); return (0); }
/* * __wt_las_create -- * Initialize the database's lookaside store. */ int __wt_las_create(WT_SESSION_IMPL *session) { WT_CONNECTION_IMPL *conn; WT_DECL_RET; const char *drop_cfg[] = { WT_CONFIG_BASE(session, WT_SESSION_drop), "force=true", NULL }; conn = S2C(session); /* * Done at startup: we cannot do it on demand because we require the * schema lock to create and drop the file, and it may not always be * available. * * Open an internal session, used for the shared lookaside cursor. * * Sessions associated with a lookaside cursor should never be tapped * for eviction. */ WT_RET(__wt_open_internal_session( conn, "lookaside table", 1, 1, &conn->las_session)); session = conn->las_session; F_SET(session, WT_SESSION_LOOKASIDE_CURSOR | WT_SESSION_NO_EVICTION); /* Discard any previous incarnation of the file. */ WT_RET(__wt_session_drop(session, WT_LAS_URI, drop_cfg)); /* Re-create the file. */ WT_RET(__wt_session_create(session, WT_LAS_URI, WT_LAS_FORMAT)); /* Open the shared cursor. */ WT_WITHOUT_DHANDLE(session, ret = __las_cursor_create(session, &conn->las_cursor)); return (ret); }
/* * __wt_las_cursor_open -- * Open a new lookaside table cursor. */ int __wt_las_cursor_open(WT_SESSION_IMPL *session, WT_CURSOR **cursorp) { WT_BTREE *btree; WT_DECL_RET; const char *open_cursor_cfg[] = { WT_CONFIG_BASE(session, WT_SESSION_open_cursor), NULL }; WT_WITHOUT_DHANDLE(session, ret = __wt_open_cursor( session, WT_LAS_URI, NULL, open_cursor_cfg, cursorp)); WT_RET(ret); /* * Retrieve the btree from the cursor, rather than the session because * we don't always switch the LAS handle in to the session before * entering this function. */ btree = ((WT_CURSOR_BTREE *)(*cursorp))->btree; /* * Set special flags for the lookaside table: the lookaside flag (used, * for example, to avoid writing records during reconciliation), also * turn off checkpoints and logging. * * Test flags before setting them so updates can't race in subsequent * opens (the first update is safe because it's single-threaded from * wiredtiger_open). */ if (!F_ISSET(btree, WT_BTREE_LOOKASIDE)) F_SET(btree, WT_BTREE_LOOKASIDE); if (!F_ISSET(btree, WT_BTREE_NO_CHECKPOINT)) F_SET(btree, WT_BTREE_NO_CHECKPOINT); if (!F_ISSET(btree, WT_BTREE_NO_LOGGING)) F_SET(btree, WT_BTREE_NO_LOGGING); return (0); }