1 /* Copyright (c) 2015, 2019, 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 21 Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ 22 23 #ifndef SQL_SERVICE_COMMAND_INCLUDE 24 #define SQL_SERVICE_COMMAND_INCLUDE 25 26 #include <stddef.h> 27 28 #include "my_inttypes.h" 29 #include "plugin/group_replication/include/plugin_utils.h" 30 #include "plugin/group_replication/include/sql_service/sql_service_interface.h" 31 32 #define GR_PLUGIN_SESSION_THREAD_TIMEOUT 10 33 34 /** 35 What is the policy when creation a new server session for SQL execution. 36 */ 37 enum enum_plugin_con_isolation { 38 PSESSION_USE_THREAD, ///< Use the current thread 39 PSESSION_INIT_THREAD, ///< Use the current thread but initialize it 40 PSESSION_DEDICATED_THREAD ///< Use a dedicated thread to open a session 41 }; 42 43 class Sql_service_commands { 44 public: 45 /** 46 Internal method to set the super read only mode. 47 48 @param sql_interface the server session interface for query execution 49 @param arg a generic argument to give the method info or get a result 50 51 @return error code during execution of the sql query. 52 @retval 0 - success 53 @retval >0 - failure 54 */ 55 long internal_set_super_read_only(Sql_service_interface *sql_interface, 56 void *arg = nullptr); 57 58 /** 59 Internal method to reset the super read only mode. 60 61 @param sql_interface the server session interface for query execution 62 @param arg a generic argument to give the method info or get a result 63 64 @return error code during execution of the sql query. 65 @retval 0 - success 66 @retval >0 - failure 67 */ 68 long internal_reset_super_read_only(Sql_service_interface *sql_interface, 69 void *arg = nullptr); 70 71 /** 72 Internal method to reset the super read only mode. 73 74 @param sql_interface the server session interface for query execution 75 @param arg a generic argument to give the method info or get a result 76 77 @return error code during execution of the sql query. 78 @retval 0 - success 79 @retval >0 - failure 80 */ 81 long internal_reset_read_only(Sql_service_interface *sql_interface, 82 void *arg = nullptr); 83 84 /** 85 Internal method to get the super read only mode. 86 87 @param sql_interface the server session interface for query execution 88 @param arg a generic argument to give the method info or get a result 89 90 @retval -1 Error reading the value 91 @retval 0 Not in super read mode 92 @retval 1 In read super mode 93 */ 94 long internal_get_server_super_read_only(Sql_service_interface *sql_interface, 95 void *arg = nullptr); 96 97 /** 98 Internal method to get the super read only mode. 99 100 @param sql_interface the server session interface for query execution 101 @param arg a generic argument to give the method info or get a result 102 103 @retval -1 Error reading the value 104 @retval 0 Not in super read mode 105 @retval 1 In read super mode 106 */ 107 long internal_get_server_read_only(Sql_service_interface *sql_interface, 108 void *arg = nullptr); 109 110 /** 111 Method to return the server gtid_executed by executing the corresponding 112 sql query. 113 114 @param sql_interface the server session interface for query execution 115 @param [out] gtid_executed The string where the result will be appended 116 117 @return the error value returned 118 @retval 0 OK 119 @retval !=0 Error 120 */ 121 long internal_get_server_gtid_executed(Sql_service_interface *sql_interface, 122 void *gtid_executed); 123 124 /** 125 Method to return the server gtid_purged by executing the corresponding 126 sql query. 127 128 @param sql_interface the server session interface for query execution 129 @param [out] gtid_purged The string where the result will be appended 130 131 @return the error value returned 132 @retval 0 OK 133 @retval !=0 Error 134 */ 135 long internal_get_server_gtid_purged(Sql_service_interface *sql_interface, 136 void *gtid_purged); 137 138 /** 139 Method to wait for the server gtid_executed to match the given GTID string 140 141 @param sql_interface the server session interface for query execution 142 @param [in] gtid_executed The GTID string to check 143 @param [in] timeout The timeout after which the method should break 144 145 @return the error value returned 146 @retval 0 OK 147 @retval !=0 Error when executed or timeout. 148 */ 149 long internal_wait_for_server_gtid_executed( 150 Sql_service_interface *sql_interface, std::string >id_executed, 151 int timeout = 0); 152 153 /** 154 Method to kill the session identified by the given session id in those 155 cases where the server hangs while executing the sql query. 156 157 @param sql_interface the server session interface for query execution 158 @param session_id id of the session to be killed. 159 160 @return the error value returned 161 @retval 0 - success 162 @retval >0 - Failure 163 */ 164 long internal_kill_session(Sql_service_interface *sql_interface, 165 void *session_id = nullptr); 166 167 /** 168 Method to set a variable using SET PERSIST_ONLY 169 @param sql_interface the server session interface for query execution 170 @param variable_args arg void pointer, should be pair <string,string> 171 @return the error value returned 172 @retval 0 OK 173 @retval !=0 Error 174 */ 175 long internal_set_persist_only_variable(Sql_service_interface *sql_interface, 176 void *variable_args = nullptr); 177 178 /** 179 Method to remotely clone a server 180 181 @param[in] sql_interface The connection where to execute the query 182 @param[in] variable_args Tuple <string,string,string,string,bool,string> 183 184 @return the error value returned 185 @retval 0 OK 186 @retval !=0 Error on execution 187 */ 188 long internal_clone_server(Sql_service_interface *sql_interface, 189 void *variable_args = nullptr); 190 191 /** 192 Method to execute a given query 193 194 @param[in] sql_interface The connection where to execute the query 195 @param[in] variable_args Tuple <string, string> 196 197 @return the error value returned 198 @retval 0 OK 199 @retval !=0 Error on execution 200 */ 201 long internal_execute_query(Sql_service_interface *sql_interface, 202 void *variable_args = nullptr); 203 204 /** 205 Method to execute a given conditional query 206 207 @param[in] sql_interface The connection where to execute the query 208 @param[in] variable_args Tuple <string, bool, string> 209 210 @return the error value returned 211 @retval 0 OK 212 @retval !=0 Error on execution 213 */ 214 long internal_execute_conditional_query(Sql_service_interface *sql_interface, 215 void *variable_args = nullptr); 216 217 /** 218 Internal method to set the offline mode. 219 220 @param sql_interface the server session interface for query execution 221 @param arg a generic argument to give the method info or get a result 222 223 @return error code during execution of the sql query. 224 @retval 0 - success 225 @retval >0 - failure 226 */ 227 long internal_set_offline_mode(Sql_service_interface *sql_interface, 228 void *arg = nullptr); 229 }; 230 231 struct st_session_method { 232 long (Sql_service_commands::*method)(Sql_service_interface *, void *); 233 bool terminated; 234 }; 235 236 class Session_plugin_thread { 237 public: 238 Session_plugin_thread(Sql_service_commands *command_interface); 239 240 ~Session_plugin_thread(); 241 242 /** 243 Launch a new thread that will create a new server session. 244 245 @param plugin_pointer_var the plugin pointer for session creation 246 @param user the user for the connection 247 248 @return the operation was successful 249 @retval 0 OK 250 @retval !=0 Error 251 */ 252 int launch_session_thread(void *plugin_pointer_var, const char *user); 253 254 /** 255 Terminate the thread and close the session. 256 257 @return the operation was successful 258 @retval 0 OK 259 @retval !=0 Error 260 */ 261 int terminate_session_thread(); 262 263 /** 264 Thread handler for session creation. 265 */ 266 int session_thread_handler(); 267 268 /** 269 Method to submit a new method into execution on the session thread 270 @param method method to executed 271 @param terminate termination flag to the class 272 */ 273 void queue_new_method_for_application( 274 long (Sql_service_commands::*method)(Sql_service_interface *, void *), 275 bool terminate = false); 276 277 /** 278 Wait for the queued method to return. 279 @return the return value of the submitted method 280 */ 281 long wait_for_method_execution(); 282 283 Sql_service_interface *get_service_interface(); 284 285 /** 286 Sets a pointer that the next queued method will use to return a value 287 @param pointer the pointer where the method will store some return value 288 */ set_return_pointer(void * pointer)289 void set_return_pointer(void *pointer) { return_object = pointer; } 290 291 private: 292 Sql_service_commands *command_interface; 293 294 Sql_service_interface *m_server_interface; 295 296 Synchronized_queue<st_session_method *> *incoming_methods; 297 298 void *m_plugin_pointer; 299 300 /** The value for returning on methods */ 301 void *return_object; 302 303 /** Session thread handle */ 304 my_thread_handle m_plugin_session_pthd; 305 /* run conditions and locks */ 306 mysql_mutex_t m_run_lock; 307 mysql_cond_t m_run_cond; 308 /* method completion conditions and locks */ 309 mysql_mutex_t m_method_lock; 310 mysql_cond_t m_method_cond; 311 312 /**The user for the session connection*/ 313 const char *session_user; 314 /** Session thread method completion flag */ 315 bool m_method_execution_completed; 316 /** The method return value */ 317 long m_method_execution_return_value; 318 /** Session thread state */ 319 thread_state m_session_thread_state; 320 /** Session termination flag */ 321 bool m_session_thread_terminate; 322 /** Session tread error flag */ 323 int m_session_thread_error; 324 }; 325 326 class Sql_service_command_interface { 327 public: 328 Sql_service_command_interface(); 329 ~Sql_service_command_interface(); 330 331 /** 332 Establishes the connection to the server. 333 334 @param isolation_param session creation requirements: use current thread, 335 use thread but initialize it or create it in a 336 dedicated thread 337 @param user the user for the connection 338 @param plugin_pointer the plugin pointer for threaded connections 339 340 @return the connection was successful 341 @retval 0 OK 342 @retval !=0 Error 343 */ 344 int establish_session_connection(enum_plugin_con_isolation isolation_param, 345 const char *user, 346 void *plugin_pointer = nullptr); 347 348 /** 349 Terminates the old connection and creates a new one to the server. 350 351 @param isolation_param session creation requirements: use current thread, 352 use thread but initialize it or create it in a 353 dedicated thread 354 @param user the user for the connection 355 @param plugin_pointer the plugin pointer for threaded connections 356 357 @return the connection was successful 358 @retval 0 OK 359 @retval !=0 Error 360 */ 361 int reestablish_connection(enum_plugin_con_isolation isolation_param, 362 const char *user, void *plugin_pointer = nullptr); 363 /** 364 Was this session killed? 365 366 @retval true session was killed 367 @retval false session was not killed 368 */ 369 bool is_session_killed(); 370 371 /** 372 Stops and deletes all connection related structures 373 */ 374 void terminate_connection_fields(); 375 376 /** 377 Returns the SQL service interface associated to this class 378 379 @return the sql service interface field 380 */ 381 Sql_service_interface *get_sql_service_interface(); 382 383 /** 384 Sets the SQL API user to be used on security checks 385 386 @param user the user to be used 387 388 @return the operation was successful 389 @retval 0 OK 390 @retval !=0 Error 391 */ 392 int set_interface_user(const char *user); 393 394 /** 395 Method to kill the session identified by the given session id in those 396 cases where the server hangs while executing the sql query. 397 398 @param session_id id of the session to be killed. 399 400 @return the error value returned 401 @retval 0 - success 402 @retval >0 - Failure 403 */ 404 long kill_session(unsigned long session_id); 405 406 /** 407 Checks if there is an existing session 408 409 @return the error value returned 410 @retval true valid 411 @retval false some issue prob happened on connection 412 */ 413 bool is_session_valid(); 414 415 /** 416 Method to set the super_read_only variable "ON". 417 418 @return error code during execution of the sql query. 419 @retval 0 - success 420 @retval >0 - failure 421 */ 422 long set_super_read_only(); 423 424 /** 425 Method to reset the super_read_only mode back to "OFF" on the 426 server. 427 428 @return error code during execution of the sql query. 429 @retval 0 - success 430 @retval >0 - failure 431 */ 432 long reset_super_read_only(); 433 434 /** 435 Method to reset the read_only mode back to "OFF" on the 436 server. 437 438 @return error code during execution of the sql query. 439 @retval 0 - success 440 @retval >0 - failure 441 */ 442 long reset_read_only(); 443 444 /** 445 Method to return the server gtid_executed by executing the corresponding 446 sql query. 447 448 @param [out] gtid_executed The string where the result will be appended 449 450 @return the error value returned 451 @retval 0 OK 452 @retval !=0 Error 453 */ 454 int get_server_gtid_executed(std::string >id_executed); 455 456 /** 457 Method to return the server gtid_purged by executing the corresponding 458 sql query. 459 460 @param [out] gtid_purged The string where the result will be appended 461 462 @return the error value returned 463 @retval 0 OK 464 @retval !=0 Error 465 */ 466 int get_server_gtid_purged(std::string >id_purged); 467 468 /** 469 Method to wait for the server gtid_executed to match the given GTID string 470 471 @param [in] gtid_executed The GTID string to check 472 @param [in] timeout The timeout after which the method should break 473 474 @return the error value returned 475 @retval 0 OK 476 @retval -1 Timeout on the GTID wait 477 @retval 1 Error when executed 478 */ 479 long wait_for_server_gtid_executed(std::string >id_executed, 480 int timeout = 0); 481 482 /** 483 Method to get the value of the super_read_only variable on the server. 484 485 @retval -1 Error reading the value 486 @retval 0 Not in super read mode 487 @retval 1 In read super mode 488 */ 489 long get_server_super_read_only(); 490 491 /** 492 Method to get the value of the read_only variable on the server. 493 494 @retval -1 Error reading the value 495 @retval 0 Not in super read mode 496 @retval 1 In read super mode 497 */ 498 long get_server_read_only(); 499 500 /** 501 Method to set a variable using SET PERSIST_ONLY 502 @param variable the variable name 503 @param value the value for the variable 504 @return the error value returned 505 @retval 0 OK 506 @retval !=0 Error 507 */ 508 long set_persist_only_variable(std::string &variable, std::string &value); 509 510 /** 511 Method to remotely clone a server 512 513 @param [in] host The host to clone 514 @param [in] port The host port 515 @param [in] username The username to authenticate in the remote server 516 @param [in] password The password to authenticate in the remote server 517 @param [in] use_ssl Is ssl configured for the clone process 518 @param [out] error The error message in case of error 519 520 @return the error value returned 521 @retval 0 OK 522 @retval !=0 Error on execution 523 */ 524 long clone_server(std::string &host, std::string &port, std::string &username, 525 std::string &password, bool use_ssl, std::string &error); 526 527 /** 528 Execute a query passed as parameter. 529 530 @param [in] query The query to execute 531 532 @return the error value returned 533 @retval 0 OK 534 @retval !=0 Error on execution 535 */ 536 long execute_query(std::string &query); 537 538 /** 539 Execute a query passed as parameter. 540 541 @param [in] query The query to execute 542 @param [out] error The error message in case of error 543 544 @return the error value returned 545 @retval 0 OK 546 @retval !=0 Error on execution 547 */ 548 long execute_query(std::string &query, std::string &error); 549 550 /** 551 Execute a conditional query passed as parameter. 552 553 @param [in] query The query to execute 554 @param [in] result The result of the query 555 556 @return the error value returned 557 @retval 0 OK 558 @retval !=0 Error on execution 559 */ 560 long execute_conditional_query(std::string &query, bool *result); 561 562 /** 563 Execute a conditional query passed as parameter. 564 565 @param [in] query The query to execute 566 @param [in] result The result of the query 567 @param [out] error The error message in case of error 568 569 @return the error value returned 570 @retval 0 OK 571 @retval !=0 Error on execution 572 */ 573 long execute_conditional_query(std::string &query, bool *result, 574 std::string &error); 575 576 /** 577 Method to set the offline_mode variable "ON". 578 579 @return error code during execution of the sql query. 580 @retval 0 - success 581 @retval >0 - failure 582 */ 583 long set_offline_mode(); 584 585 private: 586 enum_plugin_con_isolation connection_thread_isolation; 587 588 Sql_service_commands sql_service_commands; 589 590 /** The internal SQL session service interface to the server */ 591 Sql_service_interface *m_server_interface; 592 593 /* The thread where the connection leaves if isolation is needed*/ 594 Session_plugin_thread *m_plugin_session_thread; 595 }; 596 597 #endif // SQL_SERVICE_COMMAND_INCLUDE 598