Files
oceanbase/src/storage/ob_multi_version_table_store.h

219 lines
9.2 KiB
C++

/**
* Copyright (c) 2021 OceanBase
* OceanBase CE is licensed under Mulan PubL v2.
* You can use this software according to the terms and conditions of the Mulan PubL v2.
* You may obtain a copy of Mulan PubL v2 at:
* http://license.coscl.org.cn/MulanPubL-2.0
* THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
* EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
* MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
* See the Mulan PubL v2 for more details.
*/
#ifndef SRC_STORAGE_OB_MULTI_VERSION_TABLE_STORE_H_
#define SRC_STORAGE_OB_MULTI_VERSION_TABLE_STORE_H_
#include "ob_table_store.h"
#include "ob_i_table.h"
#include "share/config/ob_server_config.h"
namespace oceanbase {
namespace storage {
class ObPGMemtableMgr;
class ObMultiVersionTableStore {
public:
typedef common::hash::ObHashSet<int64_t, common::hash::NoPthreadDefendMode> TableSet;
static const int64_t MAX_KETP_VERSION_SHIFT_NUM = 4L;
static const int64_t MAX_KETP_VERSION_NUM = 1LL << MAX_KETP_VERSION_SHIFT_NUM;
static const int64_t MAX_DEFERRED_GC_MINOR_SSTABLE_COUNT = MAX_SSTABLE_CNT_IN_STORAGE;
ObMultiVersionTableStore();
virtual ~ObMultiVersionTableStore();
int init(const common::ObPartitionKey& pkey, const uint64_t table_id, ObFreezeInfoSnapshotMgr* freeze_info_mgr,
ObPGMemtableMgr* pg_memtable_mgr, const int64_t schema_version = 0);
uint64_t get_table_id() const
{
return table_id_;
}
int set_reference_tables(
ObTablesHandle& handle, ObTableStore*& new_table_store, const int64_t memtable_base_version, bool& need_update);
int prepare_update_split_table_store(
const bool is_major_split, ObTablesHandle& handle, bool& need_update, ObTableStore*& new_table_store);
int check_need_split(common::ObVersion& split_version, bool& need_split, bool& need_minor_split);
int check_can_split(bool& can_split);
int check_can_migrate(bool& can_migrate);
int check_complete(bool& is_complete);
int is_physical_split_finished(bool& is_physical_split_finish);
int get_physical_split_info(ObVirtualPartitionSplitInfo& split_info);
int prepare_add_sstable(AddTableParam& param, ObTableStore*& new_table_store, bool& need_update);
int prepare_remove_sstable(
AddTableParam& param, ObTablesHandle& handle, ObTableStore*& new_table_store, bool& is_equal);
int alloc_table_store(ObTableStore*& new_table_store);
void free_table_store(ObTableStore*& new_table_store);
int enable_table_store(const bool need_prewarm, ObTableStore& new_table_store);
int get_read_tables(const int64_t snapshot_version, ObTablesHandle& handle, const bool allow_not_ready,
const bool print_dropped_alert);
int get_reference_tables(ObTablesHandle& handle);
int get_sample_read_tables(const common::SampleInfo& sample_info, ObTablesHandle& handle);
int get_major_sstable(const common::ObVersion& version, ObTablesHandle& handle);
int get_all_tables(TableSet& table_set, ObTablesHandle& handle);
int check_memtable_merged(const memtable::ObMemtable& memtable, bool& all_merged, bool& can_release);
int get_latest_major_sstable(ObTableHandle& handle);
int get_sstable_schema_version(int64_t& schema_version);
int get_merge_tables(
const ObGetMergeTablesParam& param, const int64_t multi_version_start, ObGetMergeTablesResult& result);
int get_split_tables(const bool is_major_split, ObTablesHandle& handle);
int retire_prewarm_store(const int64_t duration, const int64_t minor_deferred_gc_time);
int get_latest_table_count(int64_t& latest_table_count);
int check_latest_table_count_safe(bool& is_safe);
int latest_has_major_sstable(bool& has_major);
int get_effective_tables(const bool include_active_memtable, ObTablesHandle& handle);
int finish_replay(const int64_t multi_version_start);
int check_ready_for_read(bool& is_ready);
int need_remove_old_table(const common::ObVersion& kept_min_version, const int64_t multi_version_start,
const int64_t backup_snapshot_verison, int64_t& real_kept_major_num, bool& need_remove);
int set_table_store(const ObTableStore& table_store);
OB_INLINE ObTableStore* get_latest_store();
int get_replay_tables(ObIArray<ObITable::TableKey>& replay_tables);
int set_replay_sstables(const bool is_replay_old, const common::ObIArray<ObSSTable*>& sstables);
int check_need_minor_merge(const bool is_follower_data_rep, const ObMergeType merge_type, bool& need_merge);
int get_oldest_read_tables(const int64_t snapshot_version, ObTablesHandle& handle);
int get_gc_sstables(ObTablesHandle& handle);
int get_multi_version_start(int64_t& multi_version_start);
int get_max_major_sstable_snapshot(int64_t& max_snapshot_version);
int get_min_max_major_version(int64_t& min_version, int64_t& max_version);
int get_latest_minor_sstables(ObTablesHandle& handle);
int get_latest_continue_tables(ObTablesHandle& handle);
int get_flashback_major_tables(const int64_t flashback_scn, ObTablesHandle& handle);
int get_mark_deletion_tables(const int64_t end_log_ts, const int64_t snapshot_version, ObTablesHandle& handle);
int clear_complement_minor_sstable();
bool is_data_table()
{
return table_id_ == pkey_.get_table_id();
}
int get_min_schema_version(int64_t& min_schema_version);
int get_schema_version(int64_t& schema_version);
void set_is_dropped_schema()
{
is_dropped_schema_ = true;
}
bool is_dropped_schema() const
{
return is_dropped_schema_;
}
int get_migrate_tables(ObTablesHandle& handle, bool& is_ready_for_read);
int get_needed_local_tables_for_migrate(const ObMigrateRemoteTableInfo& remote_table_info, ObTablesHandle& handle);
int set_drop_schema_info(const int64_t drop_schema_version);
int get_drop_schema_info(int64_t& drop_schema_version, int64_t& drop_schema_refreshed_ts);
int get_recovery_point_tables(const int64_t snapshot_version, ObTablesHandle& handle);
void set_create_schema_version(const int64_t schema_version) { create_schema_version_ = schema_version; }
DECLARE_VIRTUAL_TO_STRING;
private:
struct ObGCSSTableInfo final {
ObSSTable* sstable_;
int64_t retired_ts_;
ObGCSSTableInfo();
~ObGCSSTableInfo();
void reset();
DECLARE_TO_STRING;
};
OB_INLINE int64_t get_idx(const int64_t pos) const;
OB_INLINE ObTableStore* get_store(const int64_t pos);
OB_INLINE ObTableStore* get_read_store();
int retire_head_store();
OB_INLINE ObTableStore* get_oldest_store();
int record_gc_minor_sstable(ObTableStore& new_table_store);
int add_gc_minor_sstable(const int64_t gc_ts, ObSSTable* table, const int64_t max_deferred_gc_count);
int add_complement_minor_sstable_if_needed_(AddTableParam& param, ObTableStore& store);
private:
bool is_inited_;
common::ObPartitionKey pkey_;
uint64_t table_id_;
ObTableStore* table_stores_[MAX_KETP_VERSION_NUM];
int64_t head_;
int64_t tail_;
common::ObRandom rand_;
ObFreezeInfoSnapshotMgr* freeze_info_mgr_;
ObPGMemtableMgr* pg_memtable_mgr_;
// Currently, only mini sstables are recorded, sorted by release time, and those released earlier are later
ObGCSSTableInfo gc_sstable_infos_[MAX_DEFERRED_GC_MINOR_SSTABLE_COUNT];
int64_t gc_sstable_count_;
int64_t create_schema_version_;
bool is_dropped_schema_;
// Record the version number of the drop in the index table,
// which is expected to be greater than the version number when it is actually deleted
int64_t drop_schema_version_;
// Record the timestamp corresponding to the version number of the index table drop,
// which is a local timestamp, which may be greater than the actual drop time of the index table
int64_t drop_schema_refreshed_ts_;
DISALLOW_COPY_AND_ASSIGN(ObMultiVersionTableStore);
};
OB_INLINE int64_t ObMultiVersionTableStore::get_idx(const int64_t pos) const
{
return pos & ((1L << MAX_KETP_VERSION_SHIFT_NUM) - 1L);
}
OB_INLINE ObTableStore* ObMultiVersionTableStore::get_store(const int64_t pos)
{
return table_stores_[get_idx(pos)];
}
OB_INLINE ObTableStore* ObMultiVersionTableStore::get_latest_store()
{
ObTableStore* table_store = NULL;
if (tail_ > head_) {
table_store = table_stores_[get_idx(tail_ - 1L)];
}
return table_store;
}
OB_INLINE ObTableStore* ObMultiVersionTableStore::get_read_store()
{
int64_t index = get_idx(head_);
const int64_t duration = GCONF.minor_warm_up_duration_time;
if (duration > 0 && tail_ - head_ > 1L) {
const int64_t now = ObTimeUtility::current_time();
const int64_t rand = rand_.get(0L, duration);
for (int64_t i = tail_ - 1L; i > head_; --i) {
const int64_t start_time = table_stores_[get_idx(i)]->get_uptime();
// The function is transformed into a quadratic function,
// and the flow rate increases slowly during warm-up and then increases rapidly
const double x = static_cast<int>(now - start_time) / static_cast<double>(duration);
const double y = x * x;
if (rand < y * static_cast<int>(duration)) {
index = get_idx(i);
break; // stop searching
}
}
}
return table_stores_[index];
}
OB_INLINE ObTableStore* ObMultiVersionTableStore::get_oldest_store()
{
ObTableStore* table_store = NULL;
if (head_ < tail_) {
table_store = table_stores_[get_idx(head_)];
}
return table_store;
}
} // namespace storage
} // namespace oceanbase
#endif /* SRC_STORAGE_OB_MULTI_VERSION_TABLE_STORE_H_ */