1 /* 2 Copyright (c) 2012, 2021, Oracle and/or its affiliates. 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_REPL_TAB_H 26 #define NDB_REPL_TAB_H 27 28 #include <my_global.h> 29 30 #ifdef HAVE_NDB_BINLOG 31 #include <mysql_com.h> /* NAME_CHAR_LEN */ 32 #include <ndbapi/NdbApi.hpp> 33 34 /* 35 Ndb_rep_tab_key 36 37 This class represents the key columns of the 38 mysql.ndb_replication system table 39 It is used when reading values from that table 40 */ 41 class Ndb_rep_tab_key 42 { 43 public: 44 static const uint DB_MAXLEN= NAME_CHAR_LEN - 1; 45 static const uint TABNAME_MAXLEN= NAME_CHAR_LEN - 1; 46 47 /* Char arrays in varchar format with 1 length byte and 48 * trailing 0 49 */ 50 char db[ DB_MAXLEN + 2 ]; 51 char table_name[ TABNAME_MAXLEN + 2 ]; 52 uint server_id; 53 Ndb_rep_tab_key()54 Ndb_rep_tab_key() 55 { 56 db[0] = 0; 57 table_name[0] = 0; 58 server_id = 0; 59 } 60 61 /* Constructor from normal null terminated strings */ 62 Ndb_rep_tab_key(const char* _db, 63 const char* _table_name, 64 uint _server_id); 65 66 /* Add null terminators to VARCHAR format string values */ 67 void null_terminate_strings(); 68 get_db()69 const char* get_db() const 70 { 71 return &db[1]; 72 }; 73 get_table_name()74 const char* get_table_name() const 75 { 76 return &table_name[1]; 77 }; 78 79 static const int MIN_MATCH_VAL = 1; 80 static const int EXACT_MATCH_DB = 4; 81 static const int EXACT_MATCH_TABLE_NAME = 2; 82 static const int EXACT_MATCH_SERVER_ID = 1; 83 84 static const int EXACT_MATCH_QUALITY = 85 MIN_MATCH_VAL + 86 EXACT_MATCH_DB + 87 EXACT_MATCH_TABLE_NAME + 88 EXACT_MATCH_SERVER_ID; 89 90 /* 91 This static method attempts an exact, then a wild 92 match between the passed key (with optional wild 93 characters), and the passed candidate row 94 returns : 95 1 : Exact match 96 0 : Wild match 97 -1 : No match 98 */ 99 static int attempt_match(const char* keyptr, 100 const uint keylen, 101 const char* candidateptr, 102 const uint candidatelen, 103 const int exactmatchvalue); 104 105 /* This static method compares a fixed key value with 106 * a possibly wildcard containing candidate_row. 107 * If there is no match, 0 is returned. 108 * >0 means there is a match, with larger numbers 109 * indicating a better match quality. 110 * An exact match returns EXACT_MATCH_QUALITY 111 */ 112 static int get_match_quality(const Ndb_rep_tab_key* key, 113 const Ndb_rep_tab_key* candidate_row); 114 }; 115 116 /* 117 Ndb_rep_tab_row 118 119 This class represents a row in the mysql.ndb_replication table 120 */ 121 class Ndb_rep_tab_row 122 { 123 public: 124 static const uint MAX_CONFLICT_FN_SPEC_LEN = 255; 125 static const uint CONFLICT_FN_SPEC_BUF_LEN = 126 MAX_CONFLICT_FN_SPEC_LEN + 1; /* Trailing '\0' */ 127 128 Ndb_rep_tab_key key; 129 uint binlog_type; 130 bool cfs_is_null; 131 /* Buffer has space for leading length byte */ 132 char conflict_fn_spec[ CONFLICT_FN_SPEC_BUF_LEN + 1 ]; 133 134 Ndb_rep_tab_row(); 135 null_terminate_strings()136 void null_terminate_strings() 137 { 138 key.null_terminate_strings(); 139 uint speclen= 0; 140 speclen = conflict_fn_spec[0]; 141 142 assert(speclen <= MAX_CONFLICT_FN_SPEC_LEN); 143 conflict_fn_spec[1 + speclen] = '\0'; 144 } 145 get_conflict_fn_spec()146 const char* get_conflict_fn_spec() 147 { 148 return &conflict_fn_spec[1]; 149 } 150 set_conflict_fn_spec_null(bool null)151 void set_conflict_fn_spec_null(bool null) 152 { 153 if (null) 154 { 155 cfs_is_null = true; 156 conflict_fn_spec[0] = 0; 157 conflict_fn_spec[1] = 0; 158 } 159 else 160 { 161 cfs_is_null = false; 162 } 163 } 164 }; 165 166 /** 167 Ndb_rep_tab_reader 168 169 A helper class for accessing the mysql.ndb_replication 170 table 171 */ 172 class Ndb_rep_tab_reader 173 { 174 private: 175 static const char *ndb_rep_db; 176 static const char *ndb_replication_table; 177 static const char *nrt_db; 178 static const char *nrt_table_name; 179 static const char *nrt_server_id; 180 static const char *nrt_binlog_type; 181 static const char *nrt_conflict_fn; 182 183 Uint32 binlog_flags; 184 char conflict_fn_buffer[ Ndb_rep_tab_row::CONFLICT_FN_SPEC_BUF_LEN ]; 185 char warning_msg_buffer[ FN_REFLEN ]; 186 187 const char* conflict_fn_spec; 188 const char* warning_msg; 189 190 /** 191 check_schema 192 193 Checks that the schema of the mysql.ndb_replication table 194 is acceptable. 195 Returns 196 0 if ok 197 -1 if a column has an error. Col name in error_str 198 -2 if there's a more general error. Error description in 199 error_str 200 */ 201 static 202 int check_schema(const NdbDictionary::Table* reptab, 203 NdbDictionary::Dictionary* dict, 204 const char** error_str); 205 206 /** 207 scan_candidates 208 209 Scans the ndb_replication table for rows matching the 210 passed db, table_name, server_id triple. 211 Returns the quality of the match made. 212 213 -1 = Error in processing, see msg 214 0 = No match, use defaults. 215 >0 = Use data in best_match 216 217 if msg is set on return it contains a warning. 218 Warnings may be produces in non error scenarios 219 */ 220 int scan_candidates(Ndb* ndb, 221 const NdbDictionary::Table* reptab, 222 const char* db, 223 const char* table_name, 224 uint server_id, 225 Ndb_rep_tab_row& best_match); 226 public: 227 Ndb_rep_tab_reader(); ~Ndb_rep_tab_reader()228 ~Ndb_rep_tab_reader() {}; 229 230 /** 231 lookup 232 233 lookup scans the mysql.ndb_replication table for 234 the best matching entry for the supplied db, 235 table_name, server_id triple. 236 A buffer for the conflict_fn spec, and for any 237 error or warning messages must be supplied. 238 The passed binlog_flags, conflict_fn_spec and 239 message may be updated as a result 240 241 Returns : 242 0 : Success. 243 <0 : Error. 244 */ 245 int lookup(Ndb* ndb, 246 /* Keys */ 247 const char* db, 248 const char* table_name, 249 uint server_id); 250 251 /* Following only valid after a call to lookup() */ 252 Uint32 get_binlog_flags() const; 253 const char* get_conflict_fn_spec() const; 254 const char* get_warning_message() const; 255 }; 256 257 /* #ifdef HAVE_NDB_BINLOG */ 258 #endif 259 260 /* #ifdef NDB_REPL_TAB_H */ 261 #endif 262