Files
oceanbase/src/storage/ob_reserved_data_mgr.h
oceanbase-admin cea7de1475 init push
2021-05-31 22:56:52 +08:00

374 lines
14 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 OB_BACKUP_META_DATA_MGR_H
#define OB_BACKUP_META_DATA_MGR_H
#include "lib/allocator/ob_malloc.h"
#include "lib/list/ob_dlist.h"
#include "lib/container/ob_se_array.h"
#include "lib/lock/ob_tc_rwlock.h"
#include "storage/ob_i_table.h"
#include "storage/ob_storage_struct.h"
#include "storage/blocksstable/ob_store_file_system.h"
namespace oceanbase {
namespace storage {
class ObPGSSTableMgr;
class ObRecoveryPointInfo;
class ObRecoveryTableData {
public:
static const int64_t OB_RECOVERY_TABLE_DATA_VERSION = 1;
ObRecoveryTableData();
virtual ~ObRecoveryTableData();
int init(const uint64_t tenant_id, const ObTablesHandle& tables_handle);
void reset();
int get_tables(ObTablesHandle& handle);
int get_tables(const ObPartitionKey& pkey, ObTablesHandle& handle);
int get_table(const ObITable::TableKey& table_key, ObTableHandle& handle);
int replay(
const uint64_t tenant_id, const common::ObIArray<ObITable::TableKey>& table_keys, ObPGSSTableMgr& sstable_mgr);
bool is_inited() const
{
return is_inited_;
}
bool is_valid() const;
int is_below_given_snapshot(const int64_t snapshot_version, bool& is_below);
TO_STRING_KV(K(tables_.count()));
OB_UNIS_VERSION(OB_RECOVERY_TABLE_DATA_VERSION);
private:
// members won't be serialized
bool is_inited_;
common::ObFixedArray<ObITable*> tables_;
common::ObMalloc allocator_;
DISALLOW_COPY_AND_ASSIGN(ObRecoveryTableData);
};
class ObRecoveryPointData : public ObDLinkBase<ObRecoveryPointData> {
public:
typedef common::ObSEArray<ObITable::TableKey, 1> TableKeyArray;
static const int64_t OB_RECOVERY_POINT_DATA_VERSION = 1;
static const int64_t MAX_TABLE_CNT_IN_BUCKET = 10;
ObRecoveryPointData();
virtual ~ObRecoveryPointData();
bool is_inited() const
{
return is_inited_;
}
uint64_t get_tenant_id() const
{
return pg_meta_.pg_key_.get_tenant_id();
}
int64_t get_snapshot_version() const
{
return snapshot_version_;
};
bool is_valid() const;
int init(const int64_t snapshot_version, const ObPartitionGroupMeta& pg_meta,
const ObIArray<ObPGPartitionStoreMeta>& partition_store_metas);
void reset();
int check_table_exist(const int64_t table_id, bool& exist);
int add_table_sstables(const int64_t table_id, const ObTablesHandle& handle);
int get_table_sstables(const int64_t table_id, ObTablesHandle& handle) const;
int clear_table_sstables(const int64_t table_id);
int add_sstables(const ObTablesHandle& handle);
int get_all_tables(ObTablesHandle& handle) const;
ObPGKey get_pg_key() const
{
return pg_meta_.pg_key_;
}
// for replay
int finish_replay(ObPGSSTableMgr& sstable_mgr);
int assign(const ObRecoveryPointData& other);
int serialize(char* buf, const int64_t serialize_size, int64_t& pos) const;
int deserialize(const char* buf, const int64_t buf_len, int64_t& pos);
int deserialize_assign(const ObRecoveryPointData& other);
int64_t get_serialize_size() const;
int get_table_keys_map(common::hash::ObHashMap<int64_t, TableKeyArray>& table_keys_map) const;
// for backup
const ObPartitionGroupMeta& get_pg_meta() const
{
return pg_meta_;
}
int is_below_given_snapshot(const int64_t snapshot_version, bool& is_below);
int64_t get_last_replay_log_ts() const
{
return pg_meta_.storage_info_.get_data_info().get_last_replay_log_ts();
}
int get_partition_store_meta(const ObPartitionKey& pkey, ObPGPartitionStoreMeta& partition_store_meta);
int get_sstable(const ObITable::TableKey& table_key, ObTableHandle& handle);
int get_partition_tables(const ObPartitionKey& pkey, ObTablesHandle& handle);
DECLARE_VIRTUAL_TO_STRING;
private:
int add_table_(const int64_t table_id, const TableKeyArray& table_keys, const ObTablesHandle& tables_handle);
void clear_table_map_();
void clear_table_keys_map_();
int64_t get_table_id(ObITable* table)
{
ObITable::TableKey table_key = table->get_key();
return table_key.table_id_;
}
void free_table_data_(ObRecoveryTableData* table_data);
private:
// members won't be serialized
bool is_inited_;
common::hash::ObHashMap<int64_t, ObRecoveryTableData*> table_map_;
// TODO: Fix me: the allocation is not FIFO, pages may not be released because of small piece memory in use.
common::ObMalloc allocator_;
// members to be serialized
int64_t snapshot_version_; // the restore point snapshot version
ObPartitionGroupMeta pg_meta_;
common::ObSEArray<ObPGPartitionStoreMeta, 1> partition_store_metas_;
common::hash::ObHashMap<int64_t, TableKeyArray> table_keys_map_;
DISALLOW_COPY_AND_ASSIGN(ObRecoveryPointData);
};
// WARNING: not thread safe, must be protected
class ObRecoveryData {
public:
ObRecoveryData();
virtual ~ObRecoveryData();
void destroy();
int init(const ObPartitionKey& pg_key);
ObRecoveryPointData* get_header()
{
return recover_point_list_.get_header();
}
ObRecoveryPointData* get_first()
{
return recover_point_list_.get_first();
}
// create a recovery point but not insert into recover_point_list_
int create_recovery_point(const int64_t snapshot_version, const ObPartitionGroupMeta& pg_meta,
const ObIArray<ObPGPartitionStoreMeta>& partition_store_metas, const ObTablesHandle& tables_handle,
ObRecoveryPointData*& new_data);
void free_recovery_point(ObRecoveryPointData* new_data);
int insert_recovery_point(ObRecoveryPointData* new_data);
int remove_recovery_point(ObRecoveryPointData* del_data);
int check_recovery_point_exist(const int64_t snapshot_version, bool& is_exist) const;
int check_recovery_point_exist(const int64_t table_id, const int64_t snapshot_version, bool& is_exist);
int get_recovery_point(const int64_t snapshot_version, ObRecoveryPointData*& point_data);
int get_recovery_point_below_given_snapshot(const int64_t snapshot_version, ObRecoveryPointData*& point_data);
int get_unneed_recovery_points(const ObIArray<int64_t>& versions_needs, const int64_t snapshot_gc_ts,
ObIArray<ObRecoveryPointData*>& points_data);
int get_unneed_recovery_points(
const int64_t smaller_snapshot, const int64_t larger_snapshot, ObIArray<ObRecoveryPointData*>& points_data);
int get_recovery_point_data(const int64_t snapshot_version, // maybe deleted
ObTablesHandle& handle);
int get_recovery_point_table_data(
const int64_t table_id, const int64_t snapshot_version, ObTablesHandle& handle) const;
int update_recovery_point(const int64_t table_id, const int64_t snapshot_version, ObTablesHandle& handle);
int64_t get_serialize_size();
// for replay
int serialize(common::ObIAllocator& allocator, char*& buf, int64_t& serialize_size);
int deserialize(const char* buf, const int64_t buf_len, int64_t& pos);
int replay_add_recovery_point(const ObRecoveryPointData& point_data);
int replay_remove_recovery_point(ObRecoveryPointData* del_data);
int64_t get_recovery_point_cnt()
{
return recover_point_list_.get_size();
}
void set_pg_key(ObPGKey& pg_key)
{
pg_key_ = pg_key;
}
int finish_replay(ObPGSSTableMgr& pg_sstable_mgr);
int remove_recovery_points(const ObIArray<ObRecoveryPointData*>& point_list);
DECLARE_VIRTUAL_TO_STRING;
private:
static const int64_t OB_RECOVERY_DATA_VERSION = 1;
ObPartitionKey pg_key_;
ObDList<ObRecoveryPointData> recover_point_list_;
common::ObMalloc allocator_;
bool is_inited_;
DISALLOW_COPY_AND_ASSIGN(ObRecoveryData);
};
enum ObRecoveryPointType {
UNKNOWN_TYPE = 0,
RESTORE_POINT = 1,
BACKUP = 2,
};
class ObRecoveryDataMgr {
public:
struct SerializePair {
SerializePair(char* buf, int64_t size) : buf_(buf), size_(size)
{}
SerializePair() : buf_(nullptr), size_(0)
{}
TO_STRING_KV(KP_(buf), K_(size));
char* buf_;
int64_t size_;
};
ObRecoveryDataMgr();
virtual ~ObRecoveryDataMgr();
void destroy();
int init(const ObPartitionKey& pg_key);
int enable_write_slog(ObPGSSTableMgr& pg_sstable_mgr);
int serialize(common::ObIAllocator& allocator, char*& buf, int64_t& serialize_size);
int deserialize(const char* buf, const int64_t buf_len, int64_t& pos);
int replay_add_recovery_point(const ObRecoveryPointType point_type, const ObRecoveryPointData& point_data);
int replay_remove_recovery_point(const ObRecoveryPointType point_type, const int64_t snapshot_version);
OB_INLINE int set_storage_file_handle(blocksstable::ObStorageFileHandle& file_handle)
{
return file_handle_.assign(file_handle);
}
void set_pg_key(ObPGKey& pg_key)
{
pg_key_ = pg_key;
restore_point_data_.set_pg_key(pg_key);
backup_point_data_.set_pg_key(pg_key);
}
int64_t get_recovery_point_cnt()
{
TCRLockGuard lock_guard(lock_);
return restore_point_data_.get_recovery_point_cnt() + backup_point_data_.get_recovery_point_cnt();
}
int get_all_points_info(ObIArray<ObRecoveryPointInfo>& points_info);
// for restore point
int add_restore_point(const int64_t snapshot_version, const ObPartitionGroupMeta& pg_meta,
const ObIArray<ObPGPartitionStoreMeta>& partition_store_metas, const ObTablesHandle& tables_handle);
int check_restore_point_exist(const int64_t snapshot_version, bool& is_exist);
int get_restore_point_read_tables(const int64_t table_id, const int64_t snapshot_version, ObTablesHandle& handle);
int remove_unneed_restore_point(const ObIArray<int64_t>& versions_need_left, const int64_t snapshot_gc_ts);
int get_restore_point_start_version(int64_t& start_version);
int set_restore_point_start_version(const int64_t start_version);
// for backup
int add_backup_point(const int64_t snapshot_version, const ObPartitionGroupMeta& pg_meta,
const ObIArray<ObPGPartitionStoreMeta>& partition_store_metas, const ObTablesHandle& tables_handle);
int get_backup_point_data(const int64_t snapshot_version, ObPartitionGroupMeta& pg_meta, ObTablesHandle& handle);
int remove_unneed_backup_point(const ObIArray<int64_t>& versions_need_left, const int64_t snapshot_gc_ts);
int get_backup_pg_meta_data(const int64_t snapshot_version, ObPartitionGroupMeta& pg_meta);
int get_backup_partition_meta_data(const ObPartitionKey& pkey, const int64_t snapshot_version,
ObPGPartitionStoreMeta& partition_store_meta, ObTablesHandle& handle);
int get_backup_sstable(const int64_t snapshot_version, const ObITable::TableKey& table_key, ObTableHandle& handle);
int check_backup_point_exist(const int64_t snapshot_version, bool& is_exist);
int get_all_backup_tables(const int64_t snapshot_version, ObTablesHandle& handle);
TO_STRING_KV(K_(pg_key), K_(restore_point_data), K_(backup_point_data));
private:
int add_recovery_point_(const ObRecoveryPointType point_type, const int64_t snapshot_version,
const ObPartitionGroupMeta& pg_meta, const ObIArray<ObPGPartitionStoreMeta>& partition_store_metas,
const ObTablesHandle& tables_handle, ObRecoveryData& recovery_data);
int write_add_data_slog_(const ObRecoveryPointType point_type, ObRecoveryPointData& point_data);
int write_remove_data_slogs_(const ObRecoveryPointType point_type, ObIArray<ObRecoveryPointData*>& points_data);
// for restore point
int replay_add_restore_point_(const ObRecoveryPointData& point_data);
int replay_remove_restore_point_(const int64_t snapshot_version);
// for backup
int replay_add_backup_point_(const ObRecoveryPointData& point_data);
int replay_remove_backup_point_(const int64_t replay_log_ts);
private:
static const int64_t OLD_MAGIC_NUM = -0xABCD;
static const int64_t MAGIC_NUM = -0xABCE;
static const int64_t OB_RECOVERY_DATA_MGR_VERSION = 1;
common::TCRWLock lock_; // used to protect restore_point_data_ and backup_point_data_
bool enable_write_slog_;
int64_t log_seq_num_;
ObPartitionKey pg_key_;
blocksstable::ObStorageFileHandle file_handle_;
bool is_inited_;
ObRecoveryData restore_point_data_;
ObRecoveryData backup_point_data_;
// no need serialize
int64_t restore_point_start_version_;
DISALLOW_COPY_AND_ASSIGN(ObRecoveryDataMgr);
};
class ObRecoveryPointInfo {
public:
ObRecoveryPointInfo() : type_(ObRecoveryPointType::UNKNOWN_TYPE), tables_handle_(), snapshot_version_(0)
{}
virtual ~ObRecoveryPointInfo()
{
reset();
}
void reset()
{
type_ = ObRecoveryPointType::UNKNOWN_TYPE;
tables_handle_.reset();
snapshot_version_ = 0;
}
int init(const ObRecoveryPointType type, ObRecoveryPointData* point);
int64_t get_snapshot_version() const
{
return snapshot_version_;
}
void get_type(ObRecoveryPointType& type) const
{
type = type_;
}
int get_tables(ObTablesHandle& handle) const;
int assign(const ObRecoveryPointInfo& other);
TO_STRING_KV(K_(type), K(tables_handle_.get_count()), K_(snapshot_version));
private:
ObRecoveryPointType type_;
ObTablesHandle tables_handle_;
int64_t snapshot_version_;
};
// Iterate all the recovery points in one PG
class ObIRecoveryPointIterator {
public:
ObIRecoveryPointIterator()
{}
virtual ~ObIRecoveryPointIterator()
{}
virtual int get_next(ObRecoveryPointInfo*& point_info) = 0;
};
class ObRecoveryPointIterator : public ObIRecoveryPointIterator {
public:
ObRecoveryPointIterator() : points_info_(), array_idx_(0), data_mgr_(NULL)
{}
virtual ~ObRecoveryPointIterator()
{
reset();
}
virtual int get_next(ObRecoveryPointInfo*& point_info);
void reset()
{
points_info_.reuse();
array_idx_ = 0;
data_mgr_ = NULL;
}
int init(ObRecoveryDataMgr& data_mgr);
bool is_valid()
{
return data_mgr_ != NULL;
}
private:
common::ObArray<ObRecoveryPointInfo> points_info_;
int64_t array_idx_;
ObRecoveryDataMgr* data_mgr_;
};
} // namespace storage
} // namespace oceanbase
#endif