1 /* 2 Copyright (c) 2017, 2020, Oracle and/or its affiliates. All rights reserved. 3 4 This program is free software; you can redistribute it and/or modify 5 it under the terms of the GNU General Public License, version 2.0, 6 as published by the Free Software Foundation. 7 8 This program is also distributed with certain software (including 9 but not limited to OpenSSL) that is licensed under separate terms, 10 as designated in a particular file or component or in included license 11 documentation. The authors of MySQL hereby grant you an additional 12 permission to link the program and your derivative works with the 13 separately licensed software that they have included with MySQL. 14 15 This program is distributed in the hope that it will be useful, 16 but WITHOUT ANY WARRANTY; without even the implied warranty of 17 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 18 GNU General Public License, version 2.0, for more details. 19 20 You should have received a copy of the GNU General Public License 21 along with this program; if not, write to the Free Software 22 Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA 23 */ 24 25 #ifndef NDB_DD_CLIENT_H 26 #define NDB_DD_CLIENT_H 27 28 #include <map> 29 #include <set> 30 #include <string> 31 #include <unordered_set> 32 #include <vector> 33 34 #include "my_inttypes.h" 35 #include "sql/dd/object_id.h" 36 #include "sql/dd/string_type.h" 37 #include "sql/mdl.h" 38 39 namespace dd { 40 typedef String_type sdi_t; 41 namespace cache { 42 class Dictionary_client; 43 } 44 class Schema; 45 class Table; 46 class Tablespace; 47 } // namespace dd 48 49 /* 50 * Helper class to Ndb_dd_client to fetch and 51 * invalidate tables referenced by foreign keys. 52 * Used by the schema distribution participant 53 */ 54 class Ndb_referenced_tables_invalidator { 55 std::set<std::pair<std::string, std::string>> m_referenced_tables; 56 class THD *const m_thd; 57 class Ndb_dd_client &m_dd_client; 58 59 bool add_and_lock_referenced_table(const char *schema_name, 60 const char *table_name); 61 62 public: Ndb_referenced_tables_invalidator(class THD * thd,class Ndb_dd_client & dd_client)63 Ndb_referenced_tables_invalidator(class THD *thd, 64 class Ndb_dd_client &dd_client) 65 : m_thd(thd), m_dd_client(dd_client) {} 66 bool fetch_referenced_tables_to_invalidate(const char *schema_name, 67 const char *table_name, 68 const dd::Table *table_def, 69 bool skip_ndb_dict_fetch = false); 70 bool invalidate() const; 71 }; 72 73 /* 74 Class encapculating the code for accessing the DD 75 from ndbcluster 76 77 Handles: 78 - locking and releasing MDL(metadata locks) 79 - disabling and restoring autocommit 80 - transaction commit and rollback, will automatically 81 rollback in case commit has not been called(unless 82 auto rollback has been turned off) 83 */ 84 85 class Ndb_dd_client { 86 class THD *const m_thd; 87 dd::cache::Dictionary_client *m_client; 88 void *m_auto_releaser; // Opaque pointer 89 // List of MDL locks taken in EXPLICIT scope by Ndb_dd_client 90 std::vector<class MDL_ticket *> m_acquired_mdl_tickets; 91 // MDL savepoint which allows releasing MDL locks taken by called 92 // functions in TRANSACTIONAL and STATEMENT scope 93 const MDL_savepoint m_save_mdl_locks; 94 ulonglong m_save_option_bits{0}; 95 bool m_comitted{false}; 96 bool m_auto_rollback{true}; 97 98 void disable_autocommit(); 99 100 bool store_table(dd::Table *install_table, int ndb_table_id); 101 102 public: 103 Ndb_dd_client(class THD *thd); 104 105 ~Ndb_dd_client(); 106 107 /** 108 @brief Acquire IX MDL on the schema 109 110 @param schema_name Schema name 111 112 @return true if the MDL was acquired successfully, false if not 113 */ 114 bool mdl_lock_schema(const char *schema_name); 115 bool mdl_lock_schema_exclusive(const char *schema_name, 116 bool custom_lock_wait = false, 117 ulong lock_wait_timeout = 0); 118 bool mdl_lock_table(const char *schema_name, const char *table_name); 119 bool mdl_locks_acquire_exclusive(const char *schema_name, 120 const char *table_name, 121 bool custom_lock_wait = false, 122 ulong lock_wait_timeout = 0); 123 bool mdl_lock_logfile_group(const char *logfile_group_name, 124 bool intention_exclusive); 125 bool mdl_lock_logfile_group_exclusive(const char *logfile_group_name, 126 bool custom_lock_wait = false, 127 ulong lock_wait_timeout = 0); 128 bool mdl_lock_tablespace(const char *tablespace_name, 129 bool intention_exclusive); 130 bool mdl_lock_tablespace_exclusive(const char *tablespace_name, 131 bool custom_lock_wait = false, 132 ulong lock_wait_timeout = 0); 133 void mdl_locks_release(); 134 135 // Transaction handling functions 136 void commit(); 137 void rollback(); 138 139 /* 140 @brief Turn off automatic rollback which otherwise occurs automatically 141 when Ndb_dd_client instance goes out of scope and no commit has 142 been called 143 This is useful when running as part of a higher level DDL command 144 which manages the transaction 145 */ disable_auto_rollback()146 void disable_auto_rollback() { m_auto_rollback = false; } 147 148 bool get_engine(const char *schema_name, const char *table_name, 149 dd::String_type *engine); 150 151 bool rename_table(const char *old_schema_name, const char *old_table_name, 152 const char *new_schema_name, const char *new_table_name, 153 int new_table_id, int new_table_version, 154 Ndb_referenced_tables_invalidator *invalidator = nullptr); 155 bool remove_table(const char *schema_name, const char *table_name, 156 Ndb_referenced_tables_invalidator *invalidator = nullptr); 157 bool deserialize_table(const dd::sdi_t &sdi, dd::Table *table_def); 158 bool install_table(const char *schema_name, const char *table_name, 159 const dd::sdi_t &sdi, int ndb_table_id, 160 int ndb_table_version, size_t ndb_num_partitions, 161 const std::string &tablespace_name, bool force_overwrite, 162 Ndb_referenced_tables_invalidator *invalidator = nullptr); 163 bool migrate_table(const char *schema_name, const char *table_name, 164 const unsigned char *frm_data, unsigned int unpacked_len, 165 bool force_overwrite); 166 bool get_table(const char *schema_name, const char *table_name, 167 const dd::Table **table_def); 168 bool table_exists(const char *schema_name, const char *table_name, 169 bool &exists); 170 bool set_tablespace_id_in_table(const char *schema_name, 171 const char *table_name, 172 dd::Object_id tablespace_id); 173 bool set_object_id_and_version_in_table(const char *schema_name, 174 const char *table_name, int object_id, 175 int object_version); 176 bool store_table(dd::Table *install_table) const; 177 178 bool fetch_all_schemas(std::map<std::string, const dd::Schema *> &); 179 bool fetch_schema_names(std::vector<std::string> *); 180 bool get_ndb_table_names_in_schema(const char *schema_name, 181 std::unordered_set<std::string> *names); 182 bool get_table_names_in_schema(const char *schema_name, 183 std::unordered_set<std::string> *ndb_tables, 184 std::unordered_set<std::string> *local_tables); 185 bool have_local_tables_in_schema(const char *schema_name, 186 bool *found_local_tables); 187 bool is_local_table(const char *schema_name, const char *table_name, 188 bool &local_table); 189 bool get_schema(const char *schema_name, const dd::Schema **schema_def) const; 190 bool schema_exists(const char *schema_name, bool *schema_exists); 191 bool update_schema_version(const char *schema_name, unsigned int counter, 192 unsigned int node_id); 193 194 /* 195 @brief Lookup tablespace id from tablespace name 196 197 @tablespace_name Name of tablespace 198 @tablespace_id Id of the tablespace 199 200 @return true if tablespace found 201 */ 202 bool lookup_tablespace_id(const char *tablespace_name, 203 dd::Object_id *tablespace_id); 204 bool get_tablespace(const char *tablespace_name, 205 const dd::Tablespace **tablespace_def); 206 bool tablespace_exists(const char *tablespace_name, bool &exists); 207 bool fetch_ndb_tablespace_names(std::unordered_set<std::string> &names); 208 bool install_tablespace(const char *tablespace_name, 209 const std::vector<std::string> &data_file_names, 210 int tablespace_id, int tablespace_version, 211 bool force_overwrite); 212 bool drop_tablespace(const char *tablespace_name, 213 bool fail_if_not_exists = true); 214 bool get_logfile_group(const char *logfile_group_name, 215 const dd::Tablespace **logfile_group_def); 216 bool logfile_group_exists(const char *logfile_group_name, bool &exists); 217 bool fetch_ndb_logfile_group_names(std::unordered_set<std::string> &names); 218 bool install_logfile_group(const char *logfile_group_name, 219 const std::vector<std::string> &undo_file_names, 220 int logfile_group_id, int logfile_group_version, 221 bool force_overwrite); 222 bool install_undo_file(const char *logfile_group_name, 223 const char *undo_file_name); 224 bool drop_logfile_group(const char *logfile_group_name, 225 bool fail_if_not_exists = true); 226 bool get_schema_uuid(dd::String_type *value) const; 227 bool update_schema_uuid(const char *value) const; 228 }; 229 230 #endif 231