polardbxengine/storage/xengine/dict/log_ddl.h

204 lines
5.8 KiB
C++

/*
* Copyright (c) 2020, Alibaba Group Holding Limited
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#pragma once
#include <iostream>
#include <string>
#include "xdb_datadic.h"
namespace myx {
using namespace xengine;
using namespace std;
#define DDL_RECORD_MAX_KEY_LENGTH (1024)
#define DDL_RECORD_MAX_VALUE_LENGTH (1024)
/** all type of ddl-log key start (log_dict_type(4bytes), thread_id(8bytes), seqno(4bytes) */
#define DDL_LOG_PREFIX_KEY_LEN (4 + 8 + 4)
#define DDL_LOG_DICT_PREFIX_KEY_LEN (4)
/** print action of ddl-record */
#define DDL_LOG_INSERT "DDL LOG INSERT"
#define DDL_LOG_DELETE "DDL LOG DELETE"
#define DDL_LOG_REPLAY "DDL LOG REPLAY"
enum Log_Type: uint32_t {
DDL_INVALID_LOG = 1,
DDL_SMALLEST_LOG = 2,
DDL_DROP_SUBTABLE_LOG = 2,
DDL_REMOVE_CACHE_LOG = 3,
DDL_RENAME_CACHE_LOG = 4,
DDL_BIGGEST_LOG = DDL_RENAME_CACHE_LOG
};
class DDL_Record {
public:
DDL_Record()
: m_type(DDL_INVALID_LOG), m_thread_id(-1), m_seqno(-1),
m_subtable_id(-1), m_table_name(""), m_dst_table_name(""),
m_key(""), m_value("") {}
~DDL_Record() {}
DDL_Record(common::Slice &key, common::Slice &value);
void initialize();
bool convert_to_kv();
common::Slice& get_key() { return m_key; }
common::Slice& get_value() { return m_value; }
void set_type(Log_Type type) { m_type = type; }
Log_Type get_type() { return m_type; }
void set_thread_id(ulong thread_id) { m_thread_id = thread_id; }
ulong get_thread_id() { return m_thread_id; }
void set_seqno(uint32_t seqno) { m_seqno = seqno; }
uint32_t get_seqno() { return m_seqno; }
void set_subtable_id(uint subtable_id) { m_subtable_id = subtable_id;}
uint get_subtable_id() { return m_subtable_id; }
/** set/get subtable name */
void set_subtable_name(std::string table_name) { m_subtable_name = table_name; }
void set_subtable_name(const char* buf, size_t len) { set_subtable_name(std::string(buf, len)); }
std::string& get_subtable_name() { return m_subtable_name; }
/** set/get table name */
void set_table_name(std::string table_name) { m_table_name = table_name; }
void set_table_name(const char* buf, size_t len) { set_table_name(std::string(buf, len)); }
std::string& get_table_name() { return m_table_name; }
/** set/get dest table name for rename case */
void set_dst_table_name(std::string table_name) { m_dst_table_name = table_name; }
void set_dst_table_name(const char* buf, size_t len) { set_dst_table_name(std::string(buf, len)); }
std::string& get_dst_table_name() { return m_dst_table_name; }
/** Print the DDL record to specified output stream
@param[in,out] out output stream
@return output stream */
std::ostream &print(std::ostream &out) const;
private:
Log_Type m_type;
ulong m_thread_id;
uint m_seqno; //make sure ddl_log is orderly, we need replay reversely
uint m_subtable_id;
uint m_index_number; //just for test
std::string m_subtable_name;
std::string m_table_name;
uchar key_buf[DDL_RECORD_MAX_KEY_LENGTH];
uchar val_buf[DDL_RECORD_MAX_VALUE_LENGTH];
/** only used for rename record */
std::string m_dst_table_name;
common::Slice m_key;
common::Slice m_value;
};
/** Array of DDL records */
using DDL_Records = std::vector<DDL_Record *>;
using DDL_Records_iter = std::vector<DDL_Record *>::iterator;
class Xdb_dict_manager;
class Xdb_ddl_manager;
class Xdb_cf_manager;
class Xdb_drop_index_thread;
class Xdb_ddl_log_manager {
private:
Xdb_dict_manager *m_dict;
Xdb_ddl_manager *m_ddl_manager;
Xdb_cf_manager *m_cf_manager;
Xdb_drop_index_thread *m_drop_subtable_thread;
public:
Xdb_ddl_log_manager()
: m_dict(nullptr), m_ddl_manager(nullptr), m_cf_manager(nullptr),
m_drop_subtable_thread(nullptr) {}
~Xdb_ddl_log_manager() {}
bool init(Xdb_dict_manager *dict_manager, Xdb_ddl_manager *ddl_manager,
Xdb_cf_manager *cf_manager,
Xdb_drop_index_thread *drop_subtable_thread) {
m_dict = dict_manager;
m_ddl_manager = ddl_manager;
m_cf_manager = cf_manager;
m_drop_subtable_thread = drop_subtable_thread;
return false;
}
bool write_drop_subtable_log_test(xengine::db::WriteBatch *const xa_batch,
string &subtable_name, uint subtable_id,
uint index_number, ulong thread_id,
bool is_drop);
bool write_drop_subtable_log(xengine::db::WriteBatch *const xa_batch,
uint subtable_id, ulong thread_id, bool is_drop);
bool write_remove_cache_log(xengine::db::WriteBatch *const xa_batch,
const std::string &table_name, ulong thread_id);
bool write_rename_cache_log(xengine::db::WriteBatch *const xa_batch,
std::string &table_name,
std::string &dst_table_name, ulong thread_id);
bool search_all(DDL_Records &records);
bool search_by_thread_id(ulong thread_id, DDL_Records &records);
bool replay_all();
bool replay_by_thread_id(ulong thread_id);
bool replay(DDL_Record *record);
bool replay_drop_subtable(uint subtable_id);
bool replay_remove_cache(string &table_name);
bool replay_rename_cache(string &table_name, string &dst_table_name);
bool post_ddl(THD *thd);
bool recover();
void delete_records(DDL_Records &records, bool all = false);
};
} //namespace myx