/*创建一个connection evict cache*/ int __wt_cache_create(WT_SESSION_IMPL* session, const char* cfg[]) { WT_CACHE *cache; WT_CONNECTION_IMPL *conn; WT_DECL_RET; conn = S2C(session); WT_RET(__wt_calloc_one(session, &conn->cache)); cache = conn->cache; /*对cache进行配置*/ WT_RET(__wt_cache_config(session, 0, cfg)); if (cache->eviction_target >= cache->eviction_trigger) WT_ERR_MSG(session, EINVAL, "eviction target must be lower than the eviction trigger"); /*创建evict cond信号量*/ WT_ERR(__wt_cond_alloc(session, "cache eviction server", 0, &cache->evict_cond)); WT_ERR(__wt_cond_alloc(session, "eviction waiters", 0, &cache->evict_waiter_cond)); WT_ERR(__wt_spin_init(session, &cache->evict_lock, "cache eviction")); WT_ERR(__wt_spin_init(session, &cache->evict_walk_lock, "cache walk")); /* Allocate the LRU eviction queue. */ cache->evict_slots = WT_EVICT_WALK_BASE + WT_EVICT_WALK_INCR; WT_ERR(__wt_calloc_def(session, cache->evict_slots, &cache->evict)); /*初始化cache stat统计模块*/ __wt_cache_stats_update(session); return 0; err: WT_RET(__wt_cache_destroy(session)); return ret; }
/* * __wt_cache_create -- * Create the underlying cache. */ int __wt_cache_create(WT_SESSION_IMPL *session, const char *cfg[]) { WT_CACHE *cache; WT_CONNECTION_IMPL *conn; WT_DECL_RET; conn = S2C(session); WT_ASSERT(session, conn->cache == NULL); WT_RET(__wt_calloc_one(session, &conn->cache)); cache = conn->cache; /* Use a common routine for run-time configuration options. */ WT_RET(__wt_cache_config(session, false, cfg)); /* * The lowest possible page read-generation has a special meaning, it * marks a page for forcible eviction; don't let it happen by accident. */ cache->read_gen = WT_READGEN_START_VALUE; /* * The target size must be lower than the trigger size or we will never * get any work done. */ if (cache->eviction_target >= cache->eviction_trigger) WT_ERR_MSG(session, EINVAL, "eviction target must be lower than the eviction trigger"); WT_ERR(__wt_cond_auto_alloc(session, "cache eviction server", false, 10000, WT_MILLION, &cache->evict_cond)); WT_ERR(__wt_cond_alloc(session, "eviction waiters", false, &cache->evict_waiter_cond)); WT_ERR(__wt_spin_init(session, &cache->evict_lock, "cache eviction")); WT_ERR(__wt_spin_init(session, &cache->evict_walk_lock, "cache walk")); /* Allocate the LRU eviction queue. */ cache->evict_slots = WT_EVICT_WALK_BASE + WT_EVICT_WALK_INCR; WT_ERR(__wt_calloc_def(session, cache->evict_slots, &cache->evict_queue)); /* * We get/set some values in the cache statistics (rather than have * two copies), configure them. */ __wt_cache_stats_update(session); return (0); err: WT_RET(__wt_cache_destroy(session)); return (ret); }
/* * __wt_cache_create -- * Create the underlying cache. */ int __wt_cache_create(WT_SESSION_IMPL *session, const char *cfg[]) { WT_CACHE *cache; WT_CONNECTION_IMPL *conn; WT_DECL_RET; conn = S2C(session); WT_ASSERT(session, conn->cache == NULL); WT_RET(__wt_calloc_one(session, &conn->cache)); cache = conn->cache; /* Use a common routine for run-time configuration options. */ WT_RET(__wt_cache_config(session, 0, cfg)); /* * The target size must be lower than the trigger size or we will never * get any work done. */ if (cache->eviction_target >= cache->eviction_trigger) WT_ERR_MSG(session, EINVAL, "eviction target must be lower than the eviction trigger"); WT_ERR(__wt_cond_alloc(session, "cache eviction server", 0, &cache->evict_cond)); WT_ERR(__wt_cond_alloc(session, "eviction waiters", 0, &cache->evict_waiter_cond)); WT_ERR(__wt_spin_init(session, &cache->evict_lock, "cache eviction")); WT_ERR(__wt_spin_init(session, &cache->evict_walk_lock, "cache walk")); /* Allocate the LRU eviction queue. */ cache->evict_slots = WT_EVICT_WALK_BASE + WT_EVICT_WALK_INCR; WT_ERR(__wt_calloc_def(session, cache->evict_slots, &cache->evict)); /* * We get/set some values in the cache statistics (rather than have * two copies), configure them. */ __wt_cache_stats_update(session); return (0); err: WT_RET(__wt_cache_destroy(session)); return (ret); }
/* * __conn_reconfigure -- * WT_CONNECTION->reconfigure method. */ static int __conn_reconfigure(WT_CONNECTION *wt_conn, const char *config) { WT_CONFIG_ITEM cval; WT_CONNECTION_IMPL *conn; WT_DECL_RET; WT_SESSION_IMPL *session; /* * Special version of cfg that doesn't include the default config: used * to limit changes to values that the application sets explicitly. * Note that any function using this value has to be prepared to handle * not-found as a valid option return. */ const char *raw_cfg[] = { config, NULL }; conn = (WT_CONNECTION_IMPL *)wt_conn; CONNECTION_API_CALL(conn, session, reconfigure, config, cfg); /* Turning on statistics clears any existing values. */ if ((ret = __wt_config_gets(session, raw_cfg, "statistics", &cval)) == 0) { conn->statistics = cval.val == 0 ? 0 : 1; if (conn->statistics) __wt_stat_clear_connection_stats(&conn->stats); } WT_ERR_NOTFOUND_OK(ret); WT_ERR(__wt_conn_cache_pool_config(session, cfg)); WT_ERR(__wt_cache_config(conn, raw_cfg)); WT_ERR(__conn_verbose_config(session, raw_cfg)); /* Wake up the cache pool server so any changes are noticed. */ if (F_ISSET(conn, WT_CONN_CACHE_POOL)) WT_ERR(__wt_cond_signal( session, __wt_process.cache_pool->cache_pool_cond)); err: API_END(session); return (ret); }
/* * __wt_conn_reconfig -- * Reconfigure a connection (internal version). */ int __wt_conn_reconfig(WT_SESSION_IMPL *session, const char **cfg) { WT_CONNECTION_IMPL *conn; WT_DECL_RET; const char *p; conn = S2C(session); /* Serialize reconfiguration. */ __wt_spin_lock(session, &conn->reconfig_lock); /* * The configuration argument has been checked for validity, update the * previous connection configuration. * * DO NOT merge the configuration before the reconfigure calls. Some * of the underlying reconfiguration functions do explicit checks with * the second element of the configuration array, knowing the defaults * are in slot #1 and the application's modifications are in slot #2. * * Replace the base configuration set up by CONNECTION_API_CALL with * the current connection configuration, otherwise reconfiguration * functions will find the base value instead of previously configured * value. */ cfg[0] = conn->cfg; /* * Reconfigure the system. * * The compatibility version check is special: upgrade / downgrade * cannot be done with transactions active, and checkpoints must not * span a version change. Hold the checkpoint lock to avoid conflicts * with WiredTiger's checkpoint thread, and rely on the documentation * specifying that no new operations can start until the upgrade / * downgrade completes. */ WT_WITH_CHECKPOINT_LOCK(session, ret = __wt_conn_compat_config(session, cfg)); WT_ERR(ret); WT_ERR(__wt_conn_statistics_config(session, cfg)); WT_ERR(__wt_async_reconfig(session, cfg)); WT_ERR(__wt_cache_config(session, true, cfg)); WT_ERR(__wt_checkpoint_server_create(session, cfg)); WT_ERR(__wt_logmgr_reconfig(session, cfg)); WT_ERR(__wt_lsm_manager_reconfig(session, cfg)); WT_ERR(__wt_statlog_create(session, cfg)); WT_ERR(__wt_sweep_config(session, cfg)); WT_ERR(__wt_verbose_config(session, cfg)); WT_ERR(__wt_timing_stress_config(session, cfg)); /* Third, merge everything together, creating a new connection state. */ WT_ERR(__wt_config_merge(session, cfg, NULL, &p)); __wt_free(session, conn->cfg); conn->cfg = p; err: __wt_spin_unlock(session, &conn->reconfig_lock); return (ret); }
/* * __wt_cache_create -- * Create the underlying cache. */ int __wt_cache_create(WT_SESSION_IMPL *session, const char *cfg[]) { WT_CACHE *cache; WT_CONNECTION_IMPL *conn; WT_DECL_RET; int i; conn = S2C(session); WT_ASSERT(session, conn->cache == NULL); WT_RET(__wt_calloc_one(session, &conn->cache)); cache = conn->cache; /* Use a common routine for run-time configuration options. */ WT_RET(__wt_cache_config(session, false, cfg)); /* * The lowest possible page read-generation has a special meaning, it * marks a page for forcible eviction; don't let it happen by accident. */ cache->read_gen = WT_READGEN_START_VALUE; /* * The target size must be lower than the trigger size or we will never * get any work done. */ if (cache->eviction_target >= cache->eviction_trigger) WT_ERR_MSG(session, EINVAL, "eviction target must be lower than the eviction trigger"); WT_ERR(__wt_cond_auto_alloc(session, "cache eviction server", false, 10000, WT_MILLION, &cache->evict_cond)); WT_ERR(__wt_spin_init(session, &cache->evict_pass_lock, "evict pass")); WT_ERR(__wt_spin_init(session, &cache->evict_queue_lock, "cache eviction queue")); WT_ERR(__wt_spin_init(session, &cache->evict_walk_lock, "cache walk")); if ((ret = __wt_open_internal_session(conn, "evict pass", false, WT_SESSION_NO_DATA_HANDLES, &cache->walk_session)) != 0) WT_ERR_MSG(NULL, ret, "Failed to create session for eviction walks"); /* Allocate the LRU eviction queue. */ cache->evict_slots = WT_EVICT_WALK_BASE + WT_EVICT_WALK_INCR; for (i = 0; i < WT_EVICT_QUEUE_MAX; ++i) { WT_ERR(__wt_calloc_def(session, cache->evict_slots, &cache->evict_queues[i].evict_queue)); WT_ERR(__wt_spin_init(session, &cache->evict_queues[i].evict_lock, "cache eviction")); } /* Ensure there are always non-NULL queues. */ cache->evict_current_queue = cache->evict_fill_queue = &cache->evict_queues[0]; cache->evict_other_queue = &cache->evict_queues[1]; cache->evict_urgent_queue = &cache->evict_queues[WT_EVICT_URGENT_QUEUE]; /* * We get/set some values in the cache statistics (rather than have * two copies), configure them. */ __wt_cache_stats_update(session); return (0); err: WT_RET(__wt_cache_destroy(session)); return (ret); }