1 /* Copyright (c) 2014, 2017, Oracle and/or its affiliates. All rights reserved. 2 3 This program is free software; you can redistribute it and/or modify 4 it under the terms of the GNU General Public License, version 2.0, 5 as published by the Free Software Foundation. 6 7 This program is also distributed with certain software (including 8 but not limited to OpenSSL) that is licensed under separate terms, 9 as designated in a particular file or component or in included license 10 documentation. The authors of MySQL hereby grant you an additional 11 permission to link the program and your derivative works with the 12 separately licensed software that they have included with MySQL. 13 14 This program is distributed in the hope that it will be useful, 15 but WITHOUT ANY WARRANTY; without even the implied warranty of 16 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 17 GNU General Public License, version 2.0, for more details. 18 19 You should have received a copy of the GNU General Public License 20 along with this program; if not, write to the Free Software Foundation, 21 51 Franklin Street, Suite 500, Boston, MA 02110-1335 USA */ 22 23 #ifndef GCS_EVENT_HANDLERS_INCLUDE 24 #define GCS_EVENT_HANDLERS_INCLUDE 25 26 #include <set> 27 #include <vector> 28 29 #include <mysql/gcs/gcs_control_event_listener.h> 30 #include <mysql/gcs/gcs_communication_event_listener.h> 31 32 #include "applier.h" 33 #include "compatibility_module.h" 34 #include "gcs_plugin_messages.h" 35 #include "gcs_view_modification_notifier.h" 36 #include "plugin_constants.h" 37 #include "recovery.h" 38 #include "recovery_message.h" 39 #include "read_mode_handler.h" 40 41 42 /* 43 The server version in which member weight was introduced. 44 */ 45 #define PRIMARY_ELECTION_MEMBER_WEIGHT_VERSION 0x050720 46 47 /** 48 Group_member_info_pointer_comparator to guarantee uniqueness 49 */ 50 struct Group_member_info_pointer_comparator 51 { operatorGroup_member_info_pointer_comparator52 bool operator()(Group_member_info* one, 53 Group_member_info* other) const 54 { 55 return one->has_lower_uuid(other); 56 } 57 }; 58 59 60 /* 61 @class Plugin_gcs_events_handler 62 63 Implementation of all GCS event handlers to the plugin 64 */ 65 class Plugin_gcs_events_handler: public Gcs_communication_event_listener, 66 public Gcs_control_event_listener 67 { 68 public: 69 /** 70 Plugin_gcs_events_handler constructor 71 72 It receives, via the constructor, all the necessary dependencies to work. 73 */ 74 Plugin_gcs_events_handler(Applier_module_interface* applier_module, 75 Recovery_module* recovery_module, 76 Plugin_gcs_view_modification_notifier* vc_notifier, 77 Compatibility_module* compatibility_manager, 78 ulong components_stop_timeout); 79 virtual ~Plugin_gcs_events_handler(); 80 81 /* 82 Implementation of all callback methods 83 */ 84 void on_message_received(const Gcs_message& message) const; 85 void on_view_changed(const Gcs_view &new_view, 86 const Exchanged_data &exchanged_data) const; 87 Gcs_message_data* get_exchangeable_data() const; 88 void on_suspicions(const std::vector<Gcs_member_identifier>& members, 89 const std::vector<Gcs_member_identifier>& unreachable) const; 90 91 /** 92 Sets the component stop timeout. 93 94 @param[in] timeout the timeout 95 */ set_stop_wait_timeout(ulong timeout)96 void set_stop_wait_timeout (ulong timeout){ 97 stop_wait_timeout= timeout; 98 } 99 100 private: 101 /* 102 Individual handling methods for all possible message types 103 received via on_message_received(...) 104 */ 105 void handle_transactional_message(const Gcs_message& message) const; 106 void handle_certifier_message(const Gcs_message& message) const; 107 void handle_recovery_message(const Gcs_message& message) const; 108 void handle_stats_message(const Gcs_message& message) const; 109 void handle_single_primary_message(const Gcs_message& message) const; 110 111 /* 112 Methods to act upon members after a on_view_change(...) is called 113 */ 114 int update_group_info_manager(const Gcs_view& new_view, 115 const Exchanged_data &exchanged_data, 116 bool is_joining, 117 bool is_leaving) 118 const; 119 void handle_joining_members(const Gcs_view& new_view, 120 bool is_joining, 121 bool is_leaving) 122 const; 123 void handle_leaving_members(const Gcs_view& new_view, 124 bool is_joining, 125 bool is_leaving) 126 const; 127 128 /** 129 This method updates the status of the members in the list according to the 130 given parameters. 131 132 @param members the vector with members to change the status to 133 @param status the status to change to. 134 @param old_equal_to change if the old status is equal to 135 @param old_different_from change if the old status if different from 136 137 @note When not using the old_equal_to and old_different_from parameters, you 138 can pass the Group_member_info::MEMBER_END value. 139 */ 140 void 141 update_member_status(const std::vector<Gcs_member_identifier>& members, 142 Group_member_info::Group_member_status status, 143 Group_member_info::Group_member_status old_equal_to, 144 Group_member_info::Group_member_status old_different_from) 145 const; 146 147 /** 148 This method handles the election of a new primary node when the plugin runs 149 in single primary mode. 150 151 @note This function unsets the super read only mode on primary node 152 and sets it on secondary nodes 153 */ 154 void handle_leader_election_if_needed() const; 155 156 /** 157 Sort lower version members based on member weight if member version 158 is greater than equal to PRIMARY_ELECTION_MEMBER_WEIGHT_VERSION or uuid. 159 160 @param all_members_info the vector with members info 161 @param lowest_version_end first iterator position where members version 162 increases. 163 */ 164 void sort_members_for_election( 165 std::vector<Group_member_info*>* all_members_info, 166 std::vector<Group_member_info*>::iterator lowest_version_end) const; 167 168 /** 169 Sort members based on member_version and get first iterator position 170 where member version differs. 171 172 @param all_members_info the vector with members info 173 174 @return the first iterator position where members version increase. 175 176 @note from the start of the list to the returned iterator, all members have 177 the lowest version in the group. 178 */ 179 std::vector<Group_member_info*>::iterator 180 sort_and_get_lowest_version_member_position( 181 std::vector<Group_member_info*>* all_members_info) const; 182 183 int 184 process_local_exchanged_data(const Exchanged_data &exchanged_data, 185 bool is_joining) 186 const; 187 188 /** 189 Verifies if a certain Vector of Member Ids contains a given member id. 190 191 @param members the vector with members to verify 192 @param member_id the member to check if it contained. 193 194 @return true if member_id occurs in members. 195 */ 196 bool is_member_on_vector(const std::vector<Gcs_member_identifier>& members, 197 const Gcs_member_identifier& member_id) 198 const; 199 200 /** 201 Checks the compatibility of the member with the group. 202 It checks: 203 1) If the number of members was exceeded 204 2) If member version is compatible with the group 205 3) If the gtid_assignment_block_size is equal to the group 206 4) If the hash algorithm used is equal to the group 207 5) If the member has more known transactions than the group 208 209 @param number_of_members the number of members in the new view 210 211 @retval 0 compatible 212 @retval >0 not compatible with the group 213 */ 214 int check_group_compatibility(size_t number_of_members) const; 215 216 /** 217 When the member is joining, cycle through all members on group and see if it 218 is compatible with them. 219 220 @return the compatibility with the group 221 @retval INCOMPATIBLE //Versions not compatible 222 @retval COMPATIBLE //Versions compatible 223 @retval READ_COMPATIBLE //Member can read but not write 224 */ 225 st_compatibility_types check_version_compatibility_with_group() const; 226 227 /** 228 Method that compares the group's aggregated GTID set against the joiner 229 GTID set. These sets contain executed and received GTIDs present 230 in the relay log files belonging to each member plugin applier channel. 231 232 @return if the joiner has more GTIDs then the group. 233 @retval 0 Joiner has less GTIDs than the group 234 @retval >0 Joiner has more GTIDS than the group 235 @retval <0 Error when processing GTID information 236 */ 237 int compare_member_transaction_sets() const; 238 239 /** 240 This method takes all the group executed sets and adds those belonging to 241 non recovering member to the view change packet 242 243 @param[in] joining_members the joining members for this view 244 @param[in] view_packet the view change packet 245 */ 246 void 247 collect_members_executed_sets(const std::vector<Gcs_member_identifier> &joining_members, 248 View_change_packet *view_packet) const; 249 250 /** 251 Method that compares the member options with 252 the value of the same option on all other members. 253 It compares: 254 1) GTID assignment block size 255 2) Write set hash algorithm 256 257 @return 258 @retval 0 Joiner has the same value as all other members 259 @retval !=0 Otherwise 260 */ 261 int compare_member_option_compatibility() const; 262 263 /** 264 This method submits a request to leave the group 265 */ 266 void leave_group_on_error() const; 267 268 /** 269 This method checks if member was expelled from the group due 270 to network failures. 271 272 @param[in] view the view delivered by the GCS 273 274 @return 275 @retval true the member was expelled 276 @retval false otherwise 277 */ 278 bool was_member_expelled_from_group(const Gcs_view& view) const; 279 280 /** 281 Logs member joining message to error logs from view. 282 283 @param[in] new_view the view delivered by the GCS 284 */ 285 void log_members_joining_message(const Gcs_view& new_view) const; 286 287 /** 288 Logs member leaving message to error logs from view. 289 290 @param[in] new_view the view delivered by the GCS 291 */ 292 void log_members_leaving_message(const Gcs_view& new_view) const; 293 294 /** 295 This function return all members present in vector of Gcs_member_identifier 296 in HOST:PORT format separated by comma. 297 Function also return PRIMARY member if any in HOST:PORT format. 298 299 @param[in] members joining or leaving members for this view 300 @param[out] all_hosts host and port of all members from view 301 @param[out] primary_host primary member hosts and port of all members from view 302 */ 303 void get_hosts_from_view(const std::vector<Gcs_member_identifier> &members, 304 std::string& all_hosts, std::string& primary_host) const; 305 306 Applier_module_interface* applier_module; 307 Recovery_module* recovery_module; 308 309 /* 310 Holds, until view can be installed, all Member information received from 311 other members 312 */ 313 std::set<Group_member_info*, 314 Group_member_info_pointer_comparator>* temporary_states; 315 316 Plugin_gcs_view_modification_notifier* view_change_notifier; 317 318 Compatibility_module* compatibility_manager; 319 320 /**The status of this member when it joins*/ 321 st_compatibility_types* joiner_compatibility_status; 322 323 /* Component stop timeout on shutdown */ 324 ulong stop_wait_timeout; 325 326 #ifndef DBUG_OFF 327 bool set_number_of_members_on_view_changed_to_10; 328 #endif 329 }; 330 331 #endif /* GCS_EVENT_HANDLERS_INCLUDE */ 332