diff --git a/storage/rocksdb/ha_rocksdb.cc b/storage/rocksdb/ha_rocksdb.cc index d0ab517a4823..543f4ab3ebe1 100644 --- a/storage/rocksdb/ha_rocksdb.cc +++ b/storage/rocksdb/ha_rocksdb.cc @@ -7434,6 +7434,8 @@ static int rocksdb_init_internal(void *const p) { rocksdb_hton->clone_interface.clone_apply_end = rocksdb_clone_apply_end; rocksdb_hton->dict_register_dd_table_id = rocksdb_dict_register_dd_table_id; + rocksdb_hton->dict_get_server_version = rocksdb_dict_get_server_version; + rocksdb_hton->dict_set_server_version = rocksdb_dict_set_server_version; rocksdb_hton->flags = HTON_SUPPORTS_EXTENDED_KEYS | HTON_CAN_RECREATE; diff --git a/storage/rocksdb/rdb_datadic.cc b/storage/rocksdb/rdb_datadic.cc index 2030773be3e4..51fc2fe49a93 100644 --- a/storage/rocksdb/rdb_datadic.cc +++ b/storage/rocksdb/rdb_datadic.cc @@ -5311,6 +5311,11 @@ bool Rdb_dict_manager::init(rocksdb::TransactionDB *const rdb_dict, rocksdb::Slice(reinterpret_cast(m_key_buf_max_index_id), Rdb_key_def::INDEX_NUMBER_SIZE); + rdb_netbuf_store_index(m_key_buf_server_version, Rdb_key_def::SERVER_VERSION); + m_key_slice_server_version = + rocksdb::Slice(reinterpret_cast(m_key_buf_server_version), + Rdb_key_def::INDEX_NUMBER_SIZE); + resume_drop_indexes(); rollback_ongoing_index_creation(); @@ -6033,6 +6038,39 @@ bool Rdb_dict_manager::update_max_index_id(rocksdb::WriteBatch *const batch, return false; } +bool Rdb_dict_manager::get_server_version(uint *const ser_version) const { + std::string value; + + const rocksdb::Status status = get_value(m_key_slice_server_version, &value); + if (status.ok()) { + Rdb_string_reader reader(value); + uint version = 0; + reader.read_uint16(&version); + if (version == Rdb_key_def::SERVER_VERSION_VERSION) { + return reader.read_uint32(ser_version); + } + } + + return true; +} + +bool Rdb_dict_manager::set_server_version() const { + const std::unique_ptr batch = begin(); + + Rdb_buf_writer + value_writer; + + uint32 server_ver = MYSQL_VERSION_ID; + value_writer.write_uint16(Rdb_key_def::SERVER_VERSION_VERSION); + value_writer.write_uint32(server_ver); + const rocksdb::Status status = batch.get()->Put( + m_system_cfh, m_key_slice_server_version, value_writer.to_slice()); + + commit(batch.get()); + + return !status.ok(); +} + void Rdb_dict_manager::add_stats( rocksdb::WriteBatch *const batch, const std::vector &stats) const { diff --git a/storage/rocksdb/rdb_datadic.h b/storage/rocksdb/rdb_datadic.h index 99dc213c159f..1ec46828c688 100644 --- a/storage/rocksdb/rdb_datadic.h +++ b/storage/rocksdb/rdb_datadic.h @@ -421,6 +421,7 @@ class Rdb_key_def { CF_NUMBER_SIZE = 4, CF_FLAG_SIZE = 4, PACKED_SIZE = 4, // one int + SERVER_VERSION_SIZE = 4, }; // bit flags for combining bools when writing to disk @@ -457,6 +458,7 @@ class Rdb_key_def { AUTO_INC = 9, DROPPED_CF = 10, MAX_DD_INDEX_ID = 11, + SERVER_VERSION = 12, END_DICT_INDEX_ID = 255 }; @@ -472,6 +474,7 @@ class Rdb_key_def { DDL_CREATE_INDEX_ONGOING_VERSION = 1, AUTO_INCREMENT_VERSION = 1, DROPPED_CF_VERSION = 1, + SERVER_VERSION_VERSION = 1, // Version for index stats is stored in IndexStats struct }; @@ -1559,6 +1562,11 @@ class Rdb_binlog_manager { value: version, index_id index_id is 4 bytes + 12. server version + key: Rdb_key_def::SERVER_VERSION(0xc) + value: version, {server version} + server version is 4 bytes + Data dictionary operations are atomic inside RocksDB. For example, when creating a table with two indexes, it is necessary to call Put three times. They have to be atomic. Rdb_dict_manager has a wrapper function @@ -1578,6 +1586,9 @@ class Rdb_dict_manager : public Ensure_initialized { uchar m_key_buf_max_dd_index_id[Rdb_key_def::INDEX_NUMBER_SIZE] = {0}; rocksdb::Slice m_key_slice_max_dd_index_id; + uchar m_key_buf_server_version[Rdb_key_def::INDEX_NUMBER_SIZE] = {0}; + rocksdb::Slice m_key_slice_server_version; + static void dump_index_id(uchar *const netbuf, Rdb_key_def::DATA_DICT_TYPE dict_type, const GL_INDEX_ID &gl_index_id); @@ -1725,6 +1736,22 @@ class Rdb_dict_manager : public Ensure_initialized { bool update_max_index_id(rocksdb::WriteBatch *const batch, const uint32_t index_id, bool is_dd_tbl = false) const; + + /** + Get the server version from the private data dictionary table + @param version out parameter + @retval false ok + @retval true error + */ + bool get_server_version(uint *const version) const; + + /** + Set the server version to the private data dictionary table + @retval false ok + @retval true error + */ + bool set_server_version() const; + void add_stats(rocksdb::WriteBatch *const batch, const std::vector &stats) const; Rdb_index_stats get_stats(GL_INDEX_ID gl_index_id) const; diff --git a/storage/rocksdb/rdb_native_dd.cc b/storage/rocksdb/rdb_native_dd.cc index 9e0e3d1fc598..2c9680a71698 100644 --- a/storage/rocksdb/rdb_native_dd.cc +++ b/storage/rocksdb/rdb_native_dd.cc @@ -22,6 +22,8 @@ /* MyRocks header files */ #include "ha_rocksdb.h" +#include "storage/rocksdb/ha_rocksdb_proto.h" +#include "storage/rocksdb/rdb_datadic.h" namespace myrocks { std::unordered_set native_dd::s_dd_table_ids = {}; @@ -50,4 +52,16 @@ void rocksdb_dict_register_dd_table_id(dd::Object_id dd_table_id) { native_dd::insert_dd_table_ids(dd_table_id); }; +bool rocksdb_dict_get_server_version(uint *version) { + return rdb_get_dict_manager() + ->get_dict_manager_selector_non_const(false /*is_tmp_table*/) + ->get_server_version(version); +}; + +bool rocksdb_dict_set_server_version() { + return rdb_get_dict_manager() + ->get_dict_manager_selector_non_const(false /*is_tmp_table*/) + ->set_server_version(); +}; + } // namespace myrocks diff --git a/storage/rocksdb/rdb_native_dd.h b/storage/rocksdb/rdb_native_dd.h index 72673689b0c6..0b702aacbc5d 100644 --- a/storage/rocksdb/rdb_native_dd.h +++ b/storage/rocksdb/rdb_native_dd.h @@ -16,6 +16,7 @@ #pragma once /* C++ standard header files */ +#include #include /* MySQL header files */ @@ -28,6 +29,8 @@ class Table; namespace myrocks { void rocksdb_dict_register_dd_table_id(dd::Object_id dd_table_id); +bool rocksdb_dict_get_server_version(uint *version); +bool rocksdb_dict_set_server_version(); class native_dd { private: