[CP] Add schema history cache
This commit is contained in:
parent
b041a0bf20
commit
97d8e0fc71
@ -204,6 +204,9 @@ STAT_EVENT_ADD_DEF(STORAGE_META_CACHE_MISS, "storage meta cache miss", ObStatCla
|
||||
STAT_EVENT_ADD_DEF(TABLET_CACHE_HIT, "tablet cache hit", ObStatClassIds::CACHE, "tablet cache hit", 50059, true, true)
|
||||
STAT_EVENT_ADD_DEF(TABLET_CACHE_MISS, "tablet cache miss", ObStatClassIds::CACHE, "tablet cache miss", 50060, true, true)
|
||||
|
||||
STAT_EVENT_ADD_DEF(SCHEMA_HISTORY_CACHE_HIT, "schema history cache hit", ObStatClassIds::CACHE, "schema cache history hit", 50061, false, true)
|
||||
STAT_EVENT_ADD_DEF(SCHEMA_HISTORY_CACHE_MISS, "schema history cache miss", ObStatClassIds::CACHE, "schema cache history miss", 50062, false, true)
|
||||
|
||||
// STORAGE
|
||||
//STAT_EVENT_ADD_DEF(MEMSTORE_LOGICAL_READS, "MEMSTORE_LOGICAL_READS", STORAGE, "MEMSTORE_LOGICAL_READS")
|
||||
//STAT_EVENT_ADD_DEF(MEMSTORE_LOGICAL_BYTES, "MEMSTORE_LOGICAL_BYTES", STORAGE, "MEMSTORE_LOGICAL_BYTES")
|
||||
|
@ -193,6 +193,9 @@ int ObInfoSchemaKvCacheTable::set_diagnose_info(ObKVCacheInst *inst, ObDiagnoseT
|
||||
} else if (0 == strcmp(inst->status_.config_->cache_name_,"schema_cache")) {
|
||||
inst->status_.total_miss_cnt_ = GLOBAL_EVENT_GET(ObStatEventIds::SCHEMA_CACHE_MISS);
|
||||
inst->status_.total_hit_cnt_.set(GLOBAL_EVENT_GET(ObStatEventIds::SCHEMA_CACHE_HIT));
|
||||
} else if (0 == strcmp(inst->status_.config_->cache_name_,"schema_history_cache")) {
|
||||
inst->status_.total_miss_cnt_ = GLOBAL_EVENT_GET(ObStatEventIds::SCHEMA_HISTORY_CACHE_MISS);
|
||||
inst->status_.total_hit_cnt_.set(GLOBAL_EVENT_GET(ObStatEventIds::SCHEMA_HISTORY_CACHE_HIT));
|
||||
} else if (0 == strcmp(inst->status_.config_->cache_name_,"opt_table_stat_cache")) {
|
||||
inst->status_.total_miss_cnt_ = GLOBAL_EVENT_GET(ObStatEventIds::OPT_TABLE_STAT_CACHE_MISS);
|
||||
inst->status_.total_hit_cnt_.set(GLOBAL_EVENT_GET(ObStatEventIds::OPT_TABLE_STAT_CACHE_HIT));
|
||||
|
1
src/share/cache/ob_cache_name_define.h
vendored
1
src/share/cache/ob_cache_name_define.h
vendored
@ -19,6 +19,7 @@ namespace share
|
||||
{
|
||||
const char *const OB_LOCATION_CACHE_NAME = "location_cache";
|
||||
const char *const OB_SCHEMA_CACHE_NAME = "schema_cache";
|
||||
const char *const OB_SCHEMA_HISTORY_CACHE_NAME = "schema_history_cache";
|
||||
const char *const OB_LS_LOCATION_CACHE_NAME = "ls_location_cache";
|
||||
const char *const OB_TABLET_CACHE_NAME = "tablet_ls_cache";
|
||||
const char *const OB_TABLET_TABLE_CACHE_NAME = "tablet_table_cache";
|
||||
|
@ -385,6 +385,7 @@ int ObMultiVersionSchemaService::get_schema(const ObSchemaMgr *mgr,
|
||||
int ret = OB_SUCCESS;
|
||||
const bool is_lazy = (NULL == mgr);
|
||||
uint64_t tenant_id = schema_status.tenant_id_;
|
||||
bool update_history_cache = false;
|
||||
schema = NULL;
|
||||
if (TENANT_SCHEMA == schema_type && !is_sys_tenant(tenant_id)) {
|
||||
ret = OB_INVALID_ARGUMENT;
|
||||
@ -473,51 +474,66 @@ int ObMultiVersionSchemaService::get_schema(const ObSchemaMgr *mgr,
|
||||
}
|
||||
if (OB_SUCC(ret) && !not_exist) {
|
||||
int i = 0;
|
||||
int64_t precise_version = OB_INVALID_VERSION;
|
||||
for (; i < val.valid_cnt_; ++i) {
|
||||
if (val.versions_[i] <= schema_version) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (i < val.valid_cnt_) {
|
||||
const int64_t precise_version = val.versions_[i];
|
||||
if (0 == i && val.is_deleted_) {
|
||||
not_exist = true;
|
||||
LOG_INFO("schema has been deleted under specified version", K(ret),
|
||||
LOG_INFO("schema has been deleted under specified version", KR(ret),
|
||||
K(key), K(val), K(schema_version), K(precise_version));
|
||||
} else {
|
||||
// Access cache with accurate version
|
||||
if (OB_FAIL(schema_cache_.get_schema(schema_type,
|
||||
tenant_id,
|
||||
schema_id,
|
||||
precise_version,
|
||||
handle,
|
||||
schema))) {
|
||||
if (ret != OB_ENTRY_NOT_EXIST) {
|
||||
LOG_WARN("get schema from cache failed", K(tenant_id), K(key),
|
||||
K(schema_version), K(precise_version), K(ret));
|
||||
} else {
|
||||
ret = OB_SUCCESS;
|
||||
}
|
||||
} else {
|
||||
// Accurate version hits, return directly
|
||||
LOG_TRACE("precise version hit", K(tenant_id), K(key),
|
||||
K(schema_version), K(precise_version), K(schema_id),
|
||||
"schema_type", schema_type_str(schema_type));
|
||||
has_hit = true;
|
||||
}
|
||||
precise_version = val.versions_[i];
|
||||
}
|
||||
} else if (schema_version < val.min_version_) {
|
||||
not_exist = true;
|
||||
LOG_INFO("schema has not been created under specified version", K(ret),
|
||||
K(tenant_id), K(key), K(val), K(schema_version));
|
||||
LOG_INFO("schema has not been created under specified version",
|
||||
KR(ret), K(key), K(val), K(schema_version));
|
||||
} else if (schema_version == val.min_version_) {
|
||||
precise_version = val.min_version_;
|
||||
LOG_INFO("use min schema version as precise schema version",
|
||||
KR(ret), K(key), K(val), K(schema_version));
|
||||
} else {
|
||||
// i >= cnt
|
||||
// Older than the cached version, this situation is considered to be a very rare scenario,
|
||||
// the "two" in the 28 theory
|
||||
// directly uses the given schema_version to look up the table
|
||||
LOG_INFO("precise version not founded since schema version is too old, " \
|
||||
"will retrieve it from inner table", K(tenant_id), K(key), K(val),
|
||||
K(schema_version), "schema_type", schema_type_str(schema_type));
|
||||
// i >= cnt && schema_version > val.min_version_
|
||||
// try use discrete schema version relationship
|
||||
if (OB_FAIL(schema_cache_.get_schema_history_cache(
|
||||
schema_type, tenant_id, schema_id, schema_version, precise_version))) {
|
||||
if (OB_ENTRY_NOT_EXIST != ret) {
|
||||
LOG_WARN("get schema history cache failed",
|
||||
KR(ret), K(schema_type), K(tenant_id), K(schema_id), K(schema_version));
|
||||
} else {
|
||||
ret = OB_SUCCESS;
|
||||
update_history_cache = true;
|
||||
LOG_INFO("precise version not founded since schema version is too old, " \
|
||||
"will retrieve it from inner table", KR(ret), K(key), K(val),
|
||||
K(schema_version), "schema_type", schema_type_str(schema_type));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// try use precise_version
|
||||
if (OB_SUCC(ret) && precise_version > 0) {
|
||||
if (OB_FAIL(schema_cache_.get_schema(schema_type,
|
||||
tenant_id,
|
||||
schema_id,
|
||||
precise_version,
|
||||
handle,
|
||||
schema))) {
|
||||
if (ret != OB_ENTRY_NOT_EXIST) {
|
||||
LOG_WARN("get schema from cache failed", KR(ret), K(key),
|
||||
K(schema_version), K(precise_version));
|
||||
} else {
|
||||
ret = OB_SUCCESS;
|
||||
}
|
||||
} else {
|
||||
LOG_TRACE("precise version hit", K(key), K(schema_version), K(precise_version),
|
||||
K(tenant_id), K(schema_id), "schema_type", schema_type_str(schema_type));
|
||||
has_hit = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -642,6 +658,11 @@ int ObMultiVersionSchemaService::get_schema(const ObSchemaMgr *mgr,
|
||||
schema))) {
|
||||
LOG_WARN("put and fetch schema failed", K(tenant_id), K(schema_type),
|
||||
K(schema_id), K(precise_version), K(schema_version), KR(ret));
|
||||
} else if (update_history_cache
|
||||
&& OB_FAIL(schema_cache_.put_schema_history_cache(
|
||||
schema_type, tenant_id, schema_id, schema_version, precise_version))) {
|
||||
LOG_WARN("fail to put schema history cache", KR(ret), K(schema_type),
|
||||
K(tenant_id), K(schema_id), K(schema_version), K(precise_version));
|
||||
}
|
||||
|
||||
#ifndef NDEBUG
|
||||
|
@ -251,6 +251,39 @@ int ObSchemaCacheValue::deep_copy(char *buf,
|
||||
return ret;
|
||||
}
|
||||
|
||||
ObSchemaHistoryCacheValue::ObSchemaHistoryCacheValue()
|
||||
: schema_version_(OB_INVALID_VERSION)
|
||||
{
|
||||
}
|
||||
|
||||
ObSchemaHistoryCacheValue::ObSchemaHistoryCacheValue(
|
||||
const int64_t schema_version)
|
||||
: schema_version_(schema_version)
|
||||
{
|
||||
}
|
||||
|
||||
int64_t ObSchemaHistoryCacheValue::size() const
|
||||
{
|
||||
return sizeof(*this);
|
||||
}
|
||||
|
||||
int ObSchemaHistoryCacheValue::deep_copy(
|
||||
char *buf,
|
||||
const int64_t buf_len,
|
||||
ObIKVCacheValue *&value) const
|
||||
{
|
||||
int ret = OB_SUCCESS;
|
||||
ObSchemaHistoryCacheValue *schema_history_value = NULL;
|
||||
if (OB_ISNULL(buf) || buf_len < size()) {
|
||||
ret = OB_INVALID_ARGUMENT;
|
||||
LOG_WARN("invaild arg", KR(ret), KP(buf), K(buf_len));
|
||||
} else {
|
||||
schema_history_value = new (buf) ObSchemaHistoryCacheValue(schema_version_);
|
||||
value = schema_history_value;
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
ObTabletCacheKey::ObTabletCacheKey()
|
||||
: tenant_id_(OB_INVALID_TENANT_ID),
|
||||
tablet_id_(),
|
||||
@ -379,11 +412,11 @@ int ObTabletCacheValue::deep_copy(char *buf,
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
ObSchemaCache::ObSchemaCache()
|
||||
: mem_context_(nullptr),
|
||||
sys_cache_(),
|
||||
cache_(),
|
||||
history_cache_(),
|
||||
is_inited_(false)
|
||||
{
|
||||
}
|
||||
@ -464,6 +497,8 @@ int ObSchemaCache::init()
|
||||
const int64_t priority = 1001;
|
||||
if (OB_FAIL(cache_.init(OB_SCHEMA_CACHE_NAME, priority))) {
|
||||
LOG_WARN("init schema cache failed", KR(ret));
|
||||
} else if (OB_FAIL(history_cache_.init(OB_SCHEMA_HISTORY_CACHE_NAME, priority))) {
|
||||
LOG_WARN("init schema history cache failed", K(ret));
|
||||
} else if (OB_FAIL(tablet_cache_.init(OB_TABLET_TABLE_CACHE_NAME, priority))) {
|
||||
LOG_WARN("init tablet-table cache failed", KR(ret));
|
||||
} else if (OB_FAIL(sys_cache_.create(OB_SCHEMA_CACHE_SYS_CACHE_MAP_BUCKET_NUM,
|
||||
@ -585,7 +620,7 @@ int ObSchemaCache::get_schema(
|
||||
if (OB_SUCC(ret)) {
|
||||
if (OB_ISNULL(cache_value)) {
|
||||
ret = OB_ERR_UNEXPECTED;
|
||||
LOG_WARN("cache_value is NULL", K(cache_value), K(ret));
|
||||
LOG_WARN("cache_value is NULL", KP(cache_value), K(ret));
|
||||
} else {
|
||||
schema = cache_value->schema_;
|
||||
}
|
||||
@ -626,18 +661,18 @@ int ObSchemaCache::put_sys_schema(
|
||||
K(deep_copy_size));
|
||||
} else if (OB_ISNULL(kv_cache_value)) {
|
||||
ret = OB_ERR_UNEXPECTED;
|
||||
LOG_WARN("cache value is NULL", KR(ret), K(kv_cache_value));
|
||||
LOG_WARN("cache value is NULL", KR(ret), KP(kv_cache_value));
|
||||
} else {
|
||||
ObSchemaCacheValue *cache_value = static_cast<ObSchemaCacheValue *>(kv_cache_value);
|
||||
int overwrite_flag = 1;
|
||||
int hash_ret = sys_cache_.set_refactored(cache_key, cache_value, overwrite_flag);
|
||||
if (OB_SUCCESS == hash_ret) {
|
||||
LOG_DEBUG("put value to sys cache succeed", K(hash_ret), K(cache_key),
|
||||
K(*cache_value));
|
||||
KPC(cache_value));
|
||||
} else {
|
||||
ret = OB_ERR_UNEXPECTED;
|
||||
LOG_WARN("put value to sys cache failed", KR(ret), K(hash_ret),
|
||||
K(cache_key), K(*cache_value));
|
||||
K(cache_key), KPC(cache_value));
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -771,6 +806,71 @@ int ObSchemaCache::put_tablet_cache(
|
||||
return ret;
|
||||
}
|
||||
|
||||
int ObSchemaCache::get_schema_history_cache(
|
||||
const ObSchemaType schema_type,
|
||||
const uint64_t tenant_id,
|
||||
const uint64_t schema_id,
|
||||
const int64_t schema_version,
|
||||
int64_t &precise_schema_version)
|
||||
{
|
||||
int ret = OB_SUCCESS;
|
||||
precise_schema_version = OB_INVALID_VERSION;
|
||||
if (OB_UNLIKELY(!check_inner_stat())) {
|
||||
ret = OB_INNER_STAT_ERROR;
|
||||
LOG_WARN("inner stat error", KR(ret));
|
||||
} else if (OB_UNLIKELY(!is_valid_key(schema_type, tenant_id, schema_id, schema_version))) {
|
||||
ret = OB_INVALID_ARGUMENT;
|
||||
LOG_WARN("invalid argument", KR(ret), K(schema_type), K(tenant_id), K(schema_id), K(schema_version));
|
||||
} else {
|
||||
ObSchemaCacheKey cache_key(schema_type, tenant_id, schema_id, schema_version);
|
||||
const ObSchemaHistoryCacheValue *cache_value = NULL;
|
||||
ObKVCacheHandle handle;
|
||||
if (OB_FAIL(history_cache_.get(cache_key, cache_value, handle))) {
|
||||
if (OB_ENTRY_NOT_EXIST != ret) {
|
||||
LOG_WARN("fail to get schema history value", KR(ret), K(cache_key));
|
||||
}
|
||||
EVENT_INC(ObStatEventIds::SCHEMA_HISTORY_CACHE_MISS);
|
||||
} else if (OB_ISNULL(cache_value)) {
|
||||
ret = OB_ERR_UNEXPECTED;
|
||||
LOG_WARN("cache_value is null", KR(ret), KP(cache_value));
|
||||
} else {
|
||||
precise_schema_version = cache_value->schema_version_;
|
||||
EVENT_INC(ObStatEventIds::SCHEMA_HISTORY_CACHE_HIT);
|
||||
LOG_TRACE("get schema history cache succeed", KR(ret), K(cache_key));
|
||||
}
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
int ObSchemaCache::put_schema_history_cache(
|
||||
const ObSchemaType schema_type,
|
||||
const uint64_t tenant_id,
|
||||
const uint64_t schema_id,
|
||||
const int64_t schema_version,
|
||||
const int64_t precise_schema_version)
|
||||
{
|
||||
int ret = OB_SUCCESS;
|
||||
if (OB_UNLIKELY(!check_inner_stat())) {
|
||||
ret = OB_INNER_STAT_ERROR;
|
||||
LOG_WARN("inner stat error", KR(ret));
|
||||
} else if (OB_UNLIKELY(
|
||||
!is_valid_key(schema_type, tenant_id, schema_id, schema_version)
|
||||
|| precise_schema_version <= 0)) {
|
||||
ret = OB_INVALID_ARGUMENT;
|
||||
LOG_WARN("invalid argument", KR(ret), K(schema_type), K(tenant_id), K(schema_id),
|
||||
K(schema_version), K(precise_schema_version));
|
||||
} else {
|
||||
ObSchemaCacheKey cache_key(schema_type, tenant_id, schema_id, schema_version);
|
||||
ObSchemaHistoryCacheValue cache_value(precise_schema_version);
|
||||
if (OB_FAIL(history_cache_.put(cache_key, cache_value))) {
|
||||
LOG_WARN("put value to schema cache failed", KR(ret), K(cache_key), K(cache_value));
|
||||
} else {
|
||||
LOG_TRACE("put schema history cache succeed", KR(ret), K(cache_key), K(cache_value));
|
||||
}
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
ObSchemaFetcher::ObSchemaFetcher()
|
||||
: schema_service_(NULL),
|
||||
sql_client_(NULL),
|
||||
|
@ -86,6 +86,21 @@ public:
|
||||
const ObSchema *schema_;
|
||||
};
|
||||
|
||||
class ObSchemaHistoryCacheValue : public common::ObIKVCacheValue
|
||||
{
|
||||
public:
|
||||
ObSchemaHistoryCacheValue();
|
||||
ObSchemaHistoryCacheValue(const int64_t schema_version);
|
||||
virtual ~ObSchemaHistoryCacheValue() {}
|
||||
virtual int64_t size() const;
|
||||
virtual int deep_copy(char *buf,
|
||||
int64_t buf_len,
|
||||
ObIKVCacheValue *&value) const;
|
||||
TO_STRING_KV(K_(schema_version));
|
||||
|
||||
int64_t schema_version_;
|
||||
};
|
||||
|
||||
class ObTabletCacheKey : public common::ObIKVCacheKey
|
||||
{
|
||||
public:
|
||||
@ -161,6 +176,16 @@ public:
|
||||
const ObSchema &schema,
|
||||
common::ObKVCacheHandle &handle,
|
||||
const ObSchema *&new_schema);
|
||||
int get_schema_history_cache(const ObSchemaType schema_type,
|
||||
const uint64_t tenant_id,
|
||||
const uint64_t schema_id,
|
||||
const int64_t schema_version,
|
||||
int64_t &precise_schema_version);
|
||||
int put_schema_history_cache(const ObSchemaType schema_type,
|
||||
const uint64_t tenant_id,
|
||||
const uint64_t schema_id,
|
||||
const int64_t schema_version,
|
||||
const int64_t precise_schema_version);
|
||||
const ObTableSchema *get_all_core_table() const;
|
||||
const ObSimpleTenantSchema *get_simple_gts_tenant() const;
|
||||
const ObTenantSchema *get_full_gts_tenant() const;
|
||||
@ -198,11 +223,13 @@ private:
|
||||
const ObSchemaCacheValue*,
|
||||
common::hash::ReadWriteDefendMode> NoSwapCache;
|
||||
typedef common::ObKVCache<ObSchemaCacheKey, ObSchemaCacheValue> KVCache;
|
||||
typedef common::ObKVCache<ObSchemaCacheKey, ObSchemaHistoryCacheValue> HistoryCache;
|
||||
typedef common::ObKVCache<ObTabletCacheKey, ObTabletCacheValue> TabletCache;
|
||||
|
||||
lib::MemoryContext mem_context_;
|
||||
NoSwapCache sys_cache_;
|
||||
KVCache cache_;
|
||||
HistoryCache history_cache_;
|
||||
bool is_inited_;
|
||||
ObTableSchema all_core_table_;
|
||||
ObSimpleTenantSchema simple_gts_tenant_;
|
||||
|
Loading…
x
Reference in New Issue
Block a user