/* * __logmgr_config -- * Parse and setup the logging server options. */ static int __logmgr_config(WT_SESSION_IMPL *session, const char **cfg, int *runp) { WT_CONFIG_ITEM cval; WT_CONNECTION_IMPL *conn; conn = S2C(session); /* * The logging configuration is off by default. */ WT_RET(__wt_config_gets(session, cfg, "log.enabled", &cval)); *runp = cval.val != 0; /* * Setup a log path, compression and encryption even if logging is * disabled in case we are going to print a log. */ conn->log_compressor = NULL; WT_RET(__wt_config_gets_none(session, cfg, "log.compressor", &cval)); WT_RET(__wt_compressor_config(session, &cval, &conn->log_compressor)); WT_RET(__wt_config_gets(session, cfg, "log.path", &cval)); WT_RET(__wt_strndup(session, cval.str, cval.len, &conn->log_path)); /* We are done if logging isn't enabled. */ if (*runp == 0) return (0); WT_RET(__wt_config_gets(session, cfg, "log.archive", &cval)); if (cval.val != 0) FLD_SET(conn->log_flags, WT_CONN_LOG_ARCHIVE); WT_RET(__wt_config_gets(session, cfg, "log.file_max", &cval)); conn->log_file_max = (wt_off_t)cval.val; WT_STAT_FAST_CONN_SET(session, log_max_filesize, conn->log_file_max); WT_RET(__wt_config_gets(session, cfg, "log.prealloc", &cval)); /* * If pre-allocation is configured, set the initial number to one. * We'll adapt as load dictates. */ if (cval.val != 0) { FLD_SET(conn->log_flags, WT_CONN_LOG_PREALLOC); conn->log_prealloc = 1; } WT_RET(__wt_config_gets_def(session, cfg, "log.recover", 0, &cval)); if (cval.len != 0 && WT_STRING_MATCH("error", cval.str, cval.len)) FLD_SET(conn->log_flags, WT_CONN_LOG_RECOVER_ERR); WT_RET(__logmgr_sync_cfg(session, cfg)); return (0); }
/* * __wt_cache_config -- * Configure or reconfigure the current cache and shared cache. */ int __wt_cache_config(WT_SESSION_IMPL *session, bool reconfigure, const char *cfg[]) { WT_CONFIG_ITEM cval; WT_CONNECTION_IMPL *conn; bool now_shared, was_shared; conn = S2C(session); WT_ASSERT(session, conn->cache != NULL); WT_RET(__wt_config_gets_none(session, cfg, "shared_cache.name", &cval)); now_shared = cval.len != 0; was_shared = F_ISSET(conn, WT_CONN_CACHE_POOL); /* Cleanup if reconfiguring */ if (reconfigure && was_shared && !now_shared) /* Remove ourselves from the pool if necessary */ WT_RET(__wt_conn_cache_pool_destroy(session)); else if (reconfigure && !was_shared && now_shared) /* * Cache size will now be managed by the cache pool - the * start size always needs to be zero to allow the pool to * manage how much memory is in-use. */ conn->cache_size = 0; /* * Always setup the local cache - it's used even if we are * participating in a shared cache. */ WT_RET(__cache_config_local(session, now_shared, cfg)); if (now_shared) { WT_RET(__wt_cache_pool_config(session, cfg)); WT_ASSERT(session, F_ISSET(conn, WT_CONN_CACHE_POOL)); if (!was_shared) WT_RET(__wt_conn_cache_pool_open(session)); } /* * Resize the thread group if reconfiguring, otherwise the thread group * will be initialized as part of creating the cache. */ if (reconfigure) WT_RET(__wt_thread_group_resize( session, &conn->evict_threads, conn->evict_threads_min, conn->evict_threads_max, WT_THREAD_CAN_WAIT | WT_THREAD_PANIC_FAIL)); return (0); }
/* * __wt_cache_config -- * Configure or reconfigure the current cache and shared cache. */ int __wt_cache_config(WT_SESSION_IMPL *session, int reconfigure, const char *cfg[]) { WT_CONFIG_ITEM cval; WT_CONNECTION_IMPL *conn; int now_shared, was_shared; conn = S2C(session); WT_ASSERT(session, conn->cache != NULL); WT_RET(__wt_config_gets_none(session, cfg, "shared_cache.name", &cval)); now_shared = cval.len != 0; was_shared = F_ISSET(conn, WT_CONN_CACHE_POOL); /* Cleanup if reconfiguring */ if (reconfigure && was_shared && !now_shared) /* Remove ourselves from the pool if necessary */ WT_RET(__wt_conn_cache_pool_destroy(session)); else if (reconfigure && !was_shared && now_shared) /* * Cache size will now be managed by the cache pool - the * start size always needs to be zero to allow the pool to * manage how much memory is in-use. */ conn->cache_size = 0; /* * Always setup the local cache - it's used even if we are * participating in a shared cache. */ WT_RET(__cache_config_local(session, now_shared, cfg)); if (now_shared) { WT_RET(__wt_cache_pool_config(session, cfg)); WT_ASSERT(session, F_ISSET(conn, WT_CONN_CACHE_POOL)); if (!was_shared) WT_RET(__wt_conn_cache_pool_open(session)); } return (0); }
/*读取配置信息,将配置信息设置到当前conn的cache信息*/ int __wt_cache_config(WT_SESSION_IMPL *session, int reconfigure, const char *cfg[]) { WT_CONFIG_ITEM cval; WT_CONNECTION_IMPL *conn; int now_shared, was_shared; conn = S2C(session); WT_ASSERT(session, conn->cache != NULL); WT_RET(__wt_config_gets_none(session, cfg, "shared_cache.name", &cval)); now_shared = cval.len != 0; was_shared = F_ISSET(conn, WT_CONN_CACHE_POOL); /* Cleanup if reconfiguring */ if (reconfigure && was_shared && !now_shared) /* Remove ourselves from the pool if necessary */ WT_RET(__wt_conn_cache_pool_destroy(session)); /*如果原来是cache pool管理connection cache,现在的配置设置成独立的cache管理,那么从cache pool中删除管理关系*/ else if (reconfigure && !was_shared && now_shared) /* * Cache size will now be managed by the cache pool - the * start size always needs to be zero to allow the pool to * manage how much memory is in-use. */ conn->cache_size = 0; /*配置connection的cache*/ WT_RET(__cache_config_local(session, now_shared, cfg)); if (now_shared) { WT_RET(__wt_cache_pool_config(session, cfg)); /*对cache pool的配置更新*/ WT_ASSERT(session, F_ISSET(conn, WT_CONN_CACHE_POOL)); if (!was_shared) WT_RET(__wt_conn_cache_pool_open(session)); /*将connection cache加入到cache pool当中进行管理*/ } return 0; }
/* * __logmgr_config -- * Parse and setup the logging server options. */ static int __logmgr_config( WT_SESSION_IMPL *session, const char **cfg, bool *runp, bool reconfig) { WT_CONFIG_ITEM cval; WT_CONNECTION_IMPL *conn; bool enabled; conn = S2C(session); WT_RET(__wt_config_gets(session, cfg, "log.enabled", &cval)); enabled = cval.val != 0; /* * If we're reconfiguring, enabled must match the already * existing setting. * * If it is off and the user it turning it on, or it is on * and the user is turning it off, return an error. */ if (reconfig && ((enabled && !FLD_ISSET(conn->log_flags, WT_CONN_LOG_ENABLED)) || (!enabled && FLD_ISSET(conn->log_flags, WT_CONN_LOG_ENABLED)))) return (EINVAL); /* Logging is incompatible with in-memory */ if (enabled) { WT_RET(__wt_config_gets(session, cfg, "in_memory", &cval)); if (cval.val != 0) WT_RET_MSG(session, EINVAL, "In memory configuration incompatible with " "log=(enabled=true)"); } *runp = enabled; /* * Setup a log path and compression even if logging is disabled in case * we are going to print a log. Only do this on creation. Once a * compressor or log path are set they cannot be changed. */ if (!reconfig) { conn->log_compressor = NULL; WT_RET(__wt_config_gets_none( session, cfg, "log.compressor", &cval)); WT_RET(__wt_compressor_config( session, &cval, &conn->log_compressor)); WT_RET(__wt_config_gets(session, cfg, "log.path", &cval)); WT_RET(__wt_strndup( session, cval.str, cval.len, &conn->log_path)); } /* We are done if logging isn't enabled. */ if (!*runp) return (0); WT_RET(__wt_config_gets(session, cfg, "log.archive", &cval)); if (cval.val != 0) FLD_SET(conn->log_flags, WT_CONN_LOG_ARCHIVE); if (!reconfig) { /* * Ignore if the user tries to change the file size. The * amount of memory allocated to the log slots may be based * on the log file size at creation and we don't want to * re-allocate that memory while running. */ WT_RET(__wt_config_gets(session, cfg, "log.file_max", &cval)); conn->log_file_max = (wt_off_t)cval.val; WT_STAT_FAST_CONN_SET(session, log_max_filesize, conn->log_file_max); } /* * If pre-allocation is configured, set the initial number to a few. * We'll adapt as load dictates. */ WT_RET(__wt_config_gets(session, cfg, "log.prealloc", &cval)); if (cval.val != 0) conn->log_prealloc = 1; /* * Note that it is meaningless to reconfigure this value during * runtime. It only matters on create before recovery runs. */ WT_RET(__wt_config_gets_def(session, cfg, "log.recover", 0, &cval)); if (cval.len != 0 && WT_STRING_MATCH("error", cval.str, cval.len)) FLD_SET(conn->log_flags, WT_CONN_LOG_RECOVER_ERR); WT_RET(__wt_config_gets(session, cfg, "log.zero_fill", &cval)); if (cval.val != 0) { if (F_ISSET(conn, WT_CONN_READONLY)) WT_RET_MSG(session, EINVAL, "Read-only configuration incompatible with " "zero-filling log files"); FLD_SET(conn->log_flags, WT_CONN_LOG_ZERO_FILL); } WT_RET(__logmgr_sync_cfg(session, cfg)); if (conn->log_cond != NULL) WT_RET(__wt_cond_auto_signal(session, conn->log_cond)); return (0); }
/* * __wt_btree_huffman_open -- * Configure Huffman encoding for the tree. */ int __wt_btree_huffman_open(WT_SESSION_IMPL *session) { struct __wt_huffman_table *table; WT_BTREE *btree; WT_CONFIG_ITEM key_conf, value_conf; WT_DECL_RET; const char **cfg; u_int entries, numbytes; btree = S2BT(session); cfg = btree->dhandle->cfg; WT_RET(__wt_config_gets_none(session, cfg, "huffman_key", &key_conf)); WT_RET(__wt_huffman_confchk(session, &key_conf)); WT_RET( __wt_config_gets_none(session, cfg, "huffman_value", &value_conf)); WT_RET(__wt_huffman_confchk(session, &value_conf)); if (key_conf.len == 0 && value_conf.len == 0) return (0); switch (btree->type) { /* Check file type compatibility. */ case BTREE_COL_FIX: WT_RET_MSG(session, EINVAL, "fixed-size column-store files may not be Huffman encoded"); /* NOTREACHED */ case BTREE_COL_VAR: if (key_conf.len != 0) WT_RET_MSG(session, EINVAL, "the keys of variable-length column-store files " "may not be Huffman encoded"); break; case BTREE_ROW: break; } if (key_conf.len == 0) { ; } else if (strncmp(key_conf.str, "english", key_conf.len) == 0) { struct __wt_huffman_table copy[WT_ELEMENTS(__wt_huffman_nytenglish)]; memcpy(copy, __wt_huffman_nytenglish, sizeof(__wt_huffman_nytenglish)); WT_RET(__wt_huffman_open( session, copy, WT_ELEMENTS(__wt_huffman_nytenglish), 1, &btree->huffman_key)); /* Check for a shared key/value table. */ if (value_conf.len != 0 && strncmp( value_conf.str, "english", value_conf.len) == 0) { btree->huffman_value = btree->huffman_key; return (0); } } else { WT_RET(__wt_huffman_read( session, &key_conf, &table, &entries, &numbytes)); ret = __wt_huffman_open( session, table, entries, numbytes, &btree->huffman_key); __wt_free(session, table); if (ret != 0) return (ret); /* Check for a shared key/value table. */ if (value_conf.len != 0 && key_conf.len == value_conf.len && memcmp(key_conf.str, value_conf.str, key_conf.len) == 0) { btree->huffman_value = btree->huffman_key; return (0); } } if (value_conf.len == 0) { ; } else if (strncmp(value_conf.str, "english", value_conf.len) == 0) { struct __wt_huffman_table copy[WT_ELEMENTS(__wt_huffman_nytenglish)]; memcpy(copy, __wt_huffman_nytenglish, sizeof(__wt_huffman_nytenglish)); WT_RET(__wt_huffman_open( session, copy, WT_ELEMENTS(__wt_huffman_nytenglish), 1, &btree->huffman_value)); } else { WT_RET(__wt_huffman_read( session, &value_conf, &table, &entries, &numbytes)); ret = __wt_huffman_open( session, table, entries, numbytes, &btree->huffman_value); __wt_free(session, table); if (ret != 0) return (ret); } return (0); }
/* * __wt_curds_open -- * Initialize a data-source cursor. */ int __wt_curds_open( WT_SESSION_IMPL *session, const char *uri, WT_CURSOR *owner, const char *cfg[], WT_DATA_SOURCE *dsrc, WT_CURSOR **cursorp) { WT_CURSOR_STATIC_INIT(iface, __wt_cursor_get_key, /* get-key */ __wt_cursor_get_value, /* get-value */ __wt_cursor_set_key, /* set-key */ __wt_cursor_set_value, /* set-value */ __curds_compare, /* compare */ __wt_cursor_equals, /* equals */ __curds_next, /* next */ __curds_prev, /* prev */ __curds_reset, /* reset */ __curds_search, /* search */ __curds_search_near, /* search-near */ __curds_insert, /* insert */ __curds_update, /* update */ __curds_remove, /* remove */ __wt_cursor_reconfigure_notsup, /* reconfigure */ __curds_close); /* close */ WT_CONFIG_ITEM cval, metadata; WT_CURSOR *cursor, *source; WT_CURSOR_DATA_SOURCE *data_source; WT_DECL_RET; char *metaconf; WT_STATIC_ASSERT(offsetof(WT_CURSOR_DATA_SOURCE, iface) == 0); data_source = NULL; metaconf = NULL; WT_RET(__wt_calloc_one(session, &data_source)); cursor = &data_source->iface; *cursor = iface; cursor->session = &session->iface; /* * XXX * The underlying data-source may require the object's key and value * formats. This isn't a particularly elegant way of getting that * information to the data-source, this feels like a layering problem * to me. */ WT_ERR(__wt_metadata_search(session, uri, &metaconf)); WT_ERR(__wt_config_getones(session, metaconf, "key_format", &cval)); WT_ERR(__wt_strndup(session, cval.str, cval.len, &cursor->key_format)); WT_ERR(__wt_config_getones(session, metaconf, "value_format", &cval)); WT_ERR( __wt_strndup(session, cval.str, cval.len, &cursor->value_format)); WT_ERR(__wt_cursor_init(cursor, uri, owner, cfg, cursorp)); /* Data-source cursors may have a custom collator. */ WT_ERR( __wt_config_getones(session, metaconf, "app_metadata", &metadata)); WT_ERR(__wt_config_gets_none(session, cfg, "collator", &cval)); if (cval.len != 0) WT_ERR(__wt_collator_config(session, uri, &cval, &metadata, &data_source->collator, &data_source->collator_owned)); WT_ERR(dsrc->open_cursor(dsrc, &session->iface, uri, (WT_CONFIG_ARG *)cfg, &data_source->source)); source = data_source->source; source->session = (WT_SESSION *)session; memset(&source->q, 0, sizeof(source->q)); source->recno = WT_RECNO_OOB; memset(source->raw_recno_buf, 0, sizeof(source->raw_recno_buf)); memset(&source->key, 0, sizeof(source->key)); memset(&source->value, 0, sizeof(source->value)); source->saved_err = 0; source->flags = 0; if (0) { err: WT_TRET(__curds_close(cursor)); *cursorp = NULL; } __wt_free(session, metaconf); return (ret); }
/* * __logmgr_config -- * Parse and setup the logging server options. */ static int __logmgr_config( WT_SESSION_IMPL *session, const char **cfg, bool *runp, bool reconfig) { WT_CONFIG_ITEM cval; WT_CONNECTION_IMPL *conn; bool enabled; /* * A note on reconfiguration: the standard "is this configuration string * allowed" checks should fail if reconfiguration has invalid strings, * for example, "log=(enabled)", or "statistics_log=(path=XXX)", because * the connection reconfiguration method doesn't allow those strings. * Additionally, the base configuration values during reconfiguration * are the currently configured values (so we don't revert to default * values when repeatedly reconfiguring), and configuration processing * of a currently set value should not change the currently set value. * * In this code path, log server reconfiguration does not stop/restart * the log server, so there's no point in re-evaluating configuration * strings that cannot be reconfigured, risking bugs in configuration * setup, and depending on evaluation of currently set values to always * result in the currently set value. Skip tests for any configuration * strings which don't make sense during reconfiguration, but don't * worry about error reporting because it should never happen. */ conn = S2C(session); WT_RET(__wt_config_gets(session, cfg, "log.enabled", &cval)); enabled = cval.val != 0; /* * If we're reconfiguring, enabled must match the already * existing setting. * * If it is off and the user it turning it on, or it is on * and the user is turning it off, return an error. * * See above: should never happen. */ if (reconfig && ((enabled && !FLD_ISSET(conn->log_flags, WT_CONN_LOG_ENABLED)) || (!enabled && FLD_ISSET(conn->log_flags, WT_CONN_LOG_ENABLED)))) return (EINVAL); /* Logging is incompatible with in-memory */ if (enabled) { WT_RET(__wt_config_gets(session, cfg, "in_memory", &cval)); if (cval.val != 0) WT_RET_MSG(session, EINVAL, "In memory configuration incompatible with " "log=(enabled=true)"); } *runp = enabled; /* * Setup a log path and compression even if logging is disabled in case * we are going to print a log. Only do this on creation. Once a * compressor or log path are set they cannot be changed. * * See above: should never happen. */ if (!reconfig) { conn->log_compressor = NULL; WT_RET(__wt_config_gets_none( session, cfg, "log.compressor", &cval)); WT_RET(__wt_compressor_config( session, &cval, &conn->log_compressor)); WT_RET(__wt_config_gets(session, cfg, "log.path", &cval)); WT_RET(__wt_strndup( session, cval.str, cval.len, &conn->log_path)); } /* We are done if logging isn't enabled. */ if (!*runp) return (0); WT_RET(__wt_config_gets(session, cfg, "log.archive", &cval)); if (cval.val != 0) FLD_SET(conn->log_flags, WT_CONN_LOG_ARCHIVE); /* * The file size cannot be reconfigured. The amount of memory allocated * to the log slots may be based on the log file size at creation and we * don't want to re-allocate that memory while running. * * See above: should never happen. */ if (!reconfig) { WT_RET(__wt_config_gets(session, cfg, "log.file_max", &cval)); conn->log_file_max = (wt_off_t)cval.val; WT_STAT_FAST_CONN_SET(session, log_max_filesize, conn->log_file_max); } /* * If pre-allocation is configured, set the initial number to a few. * We'll adapt as load dictates. */ WT_RET(__wt_config_gets(session, cfg, "log.prealloc", &cval)); if (cval.val != 0) conn->log_prealloc = 1; /* * Note it's meaningless to reconfigure this value during runtime, it * only matters on create before recovery runs. * * See above: should never happen. */ if (!reconfig) { WT_RET(__wt_config_gets_def( session, cfg, "log.recover", 0, &cval)); if (WT_STRING_MATCH("error", cval.str, cval.len)) FLD_SET(conn->log_flags, WT_CONN_LOG_RECOVER_ERR); } WT_RET(__wt_config_gets(session, cfg, "log.zero_fill", &cval)); if (cval.val != 0) { if (F_ISSET(conn, WT_CONN_READONLY)) WT_RET_MSG(session, EINVAL, "Read-only configuration incompatible with " "zero-filling log files"); FLD_SET(conn->log_flags, WT_CONN_LOG_ZERO_FILL); } WT_RET(__logmgr_sync_cfg(session, cfg)); if (conn->log_cond != NULL) WT_RET(__wt_cond_auto_signal(session, conn->log_cond)); return (0); }