diff options
Diffstat (limited to 'client/mysqlbinlog.cc')
-rw-r--r-- | client/mysqlbinlog.cc | 111 |
1 files changed, 85 insertions, 26 deletions
diff --git a/client/mysqlbinlog.cc b/client/mysqlbinlog.cc index a88c93516b5..c90b646b597 100644 --- a/client/mysqlbinlog.cc +++ b/client/mysqlbinlog.cc @@ -34,9 +34,11 @@ #define TABLE TABLE_CLIENT #include "client_priv.h" #include <my_time.h> +#include <sslopt-vars.h> /* That one is necessary for defines of OPTION_NO_FOREIGN_KEY_CHECKS etc */ #include "sql_priv.h" #include "log_event.h" +#include "compat56.h" #include "sql_common.h" #include "my_dir.h" #include <welcome_copyright_notice.h> // ORACLE_WELCOME_COPYRIGHT_NOTICE @@ -48,6 +50,8 @@ #include "mysqld.h" +#include <algorithm> + Rpl_filter *binlog_filter= 0; #define BIN_LOG_HEADER_SIZE 4 @@ -102,7 +106,7 @@ static const char* sock= 0; static char *opt_plugindir= 0, *opt_default_auth= 0; #ifdef HAVE_SMEM -static char *shared_memory_base_name= 0; +static const char *shared_memory_base_name= 0; #endif static char* user = 0; static char* pass = 0; @@ -277,8 +281,8 @@ public: int init() { - return init_dynamic_array(&file_names, sizeof(File_name_record), - 100, 100); + return my_init_dynamic_array(&file_names, sizeof(File_name_record), + 100, 100, MYF(0)); } void init_by_dir_name(const char *dir) @@ -1228,6 +1232,9 @@ Exit_status process_event(PRINT_EVENT_INFO *print_event_info, Log_event *ev, case WRITE_ROWS_EVENT: case DELETE_ROWS_EVENT: case UPDATE_ROWS_EVENT: + case WRITE_ROWS_EVENT_V1: + case UPDATE_ROWS_EVENT_V1: + case DELETE_ROWS_EVENT_V1: { Rows_log_event *e= (Rows_log_event*) ev; if (print_row_event(print_event_info, ev, e->get_table_id(), @@ -1386,6 +1393,7 @@ static struct my_option my_options[] = {"socket", 'S', "The socket file to use for connection.", &sock, &sock, 0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0}, +#include <sslopt-longopts.h> {"start-datetime", OPT_START_DATETIME, "Start reading the binlog at first event having a datetime equal or " "posterior to the argument; the argument must be a date and time " @@ -1527,6 +1535,8 @@ static void cleanup() my_free(host); my_free(user); my_free(const_cast<char*>(dirname_for_local_load)); + my_free(start_datetime_str); + my_free(stop_datetime_str); delete binlog_filter; delete glob_description_event; @@ -1558,13 +1568,14 @@ the mysql command line client.\n\n"); static my_time_t convert_str_to_timestamp(const char* str) { - int was_cut; + MYSQL_TIME_STATUS status; MYSQL_TIME l_time; long dummy_my_timezone; uint dummy_in_dst_time_gap; + /* We require a total specification (date AND time) */ - if (str_to_datetime(str, (uint) strlen(str), &l_time, 0, &was_cut) != - MYSQL_TIMESTAMP_DATETIME || was_cut) + if (str_to_datetime(str, (uint) strlen(str), &l_time, 0, &status) || + l_time.time_type != MYSQL_TIMESTAMP_DATETIME || status.warnings) { error("Incorrect date and time argument: %s", str); exit(1); @@ -1590,6 +1601,7 @@ get_one_option(int optid, const struct my_option *opt __attribute__((unused)), DBUG_PUSH(argument ? argument : default_dbug_option); break; #endif +#include <sslopt-case.h> case 'd': one_database = 1; break; @@ -1712,7 +1724,7 @@ static int parse_args(int *argc, char*** argv) exit(ho_error); if (debug_info_flag) my_end_arg= MY_CHECK_ERROR | MY_GIVE_INFO; - if (debug_check_flag) + else if (debug_check_flag) my_end_arg= MY_CHECK_ERROR; return 0; } @@ -1739,6 +1751,18 @@ static Exit_status safe_connect() return ERROR_STOP; } +#ifdef HAVE_OPENSSL + if (opt_use_ssl) + { + mysql_ssl_set(mysql, opt_ssl_key, opt_ssl_cert, opt_ssl_ca, + opt_ssl_capath, opt_ssl_cipher); + mysql_options(mysql, MYSQL_OPT_SSL_CRL, opt_ssl_crl); + mysql_options(mysql, MYSQL_OPT_SSL_CRLPATH, opt_ssl_crlpath); + } + mysql_options(mysql,MYSQL_OPT_SSL_VERIFY_SERVER_CERT, + (char*)&opt_ssl_verify_server_cert); +#endif /*HAVE_OPENSSL*/ + if (opt_plugindir && *opt_plugindir) mysql_options(mysql, MYSQL_PLUGIN_DIR, opt_plugindir); @@ -1752,6 +1776,9 @@ static Exit_status safe_connect() mysql_options(mysql, MYSQL_SHARED_MEMORY_BASE_NAME, shared_memory_base_name); #endif + mysql_options(mysql, MYSQL_OPT_CONNECT_ATTR_RESET, 0); + mysql_options4(mysql, MYSQL_OPT_CONNECT_ATTR_ADD, + "program_name", "mysqlbinlog"); if (!mysql_real_connect(mysql, host, user, pass, 0, port, sock, 0)) { error("Failed on connect: %s", mysql_error(mysql)); @@ -1815,7 +1842,7 @@ static Exit_status check_master_version() { MYSQL_RES* res = 0; MYSQL_ROW row; - const char* version; + uint version; if (mysql_query(mysql, "SELECT VERSION()") || !(res = mysql_store_result(mysql))) @@ -1831,7 +1858,7 @@ static Exit_status check_master_version() goto err; } - if (!(version = row[0])) + if (!(version = atoi(row[0]))) { error("Could not find server version: " "Master reported NULL for the version."); @@ -1849,15 +1876,29 @@ static Exit_status check_master_version() "Master returned '%s'", mysql_error(mysql)); goto err; } + + /* + Announce our capabilities to the server, so it will send us all the events + that we know about. + */ + if (mysql_query(mysql, "SET @mariadb_slave_capability=" + STRINGIFY_ARG(MARIA_SLAVE_CAPABILITY_MINE))) + { + error("Could not inform master about capability. Master returned '%s'", + mysql_error(mysql)); + goto err; + } + delete glob_description_event; - switch (*version) { - case '3': + switch (version) { + case 3: glob_description_event= new Format_description_log_event(1); break; - case '4': + case 4: glob_description_event= new Format_description_log_event(3); break; - case '5': + case 5: + case 10: /* The server is soon going to send us its Format_description log event, unless it is a 5.0 server with 3.23 or 4.0 binlogs. @@ -1869,7 +1910,7 @@ static Exit_status check_master_version() default: glob_description_event= NULL; error("Could not find server version: " - "Master reported unrecognized MySQL version '%s'.", version); + "Master reported unrecognized MySQL version '%s'.", row[0]); goto err; } if (!glob_description_event || !glob_description_event->is_valid()) @@ -1935,7 +1976,7 @@ static Exit_status dump_remote_log_entries(PRINT_EVENT_INFO *print_event_info, int2store(buf + BIN_LOG_HEADER_SIZE, binlog_flags); size_t tlen = strlen(logname); - if (tlen > UINT_MAX) + if (tlen > sizeof(buf) - 10) { error("Log name too long."); DBUG_RETURN(ERROR_STOP); @@ -2060,7 +2101,9 @@ static Exit_status dump_remote_log_entries(PRINT_EVENT_INFO *print_event_info, Exit_status retval; if ((file= load_processor.prepare_new_file_for_old_format(le,fname)) < 0) + { DBUG_RETURN(ERROR_STOP); + } retval= process_event(print_event_info, ev, old_off, logname); if (retval != OK_CONTINUE) @@ -2340,7 +2383,7 @@ static Exit_status dump_local_log_entries(PRINT_EVENT_INFO *print_event_info, my_off_t length,tmp; for (length= start_position_mot ; length > 0 ; length-=tmp) { - tmp=min(length,sizeof(buff)); + tmp= MY_MIN(length,sizeof(buff)); if (my_b_read(file, buff, (uint) tmp)) { error("Failed reading from file."); @@ -2424,27 +2467,28 @@ int main(int argc, char** argv) my_init_time(); // for time functions tzset(); // set tzname - init_alloc_root(&s_mem_root, 16384, 0); + init_alloc_root(&s_mem_root, 16384, 0, MYF(0)); if (load_defaults("my", load_groups, &argc, &argv)) exit(1); + defaults_argv= argv; + if (!(binlog_filter= new Rpl_filter)) { error("Failed to create Rpl_filter"); - exit(1); + goto err; } - defaults_argv= argv; parse_args(&argc, (char***)&argv); if (!argc || opt_version) { - if (!argc) + if (!opt_version) + { usage(); - cleanup(); - free_defaults(defaults_argv); - my_end(my_end_arg); - exit(!opt_version); + retval= ERROR_STOP; + } + goto err; } if (opt_base64_output_mode == BASE64_OUTPUT_UNSPEC) @@ -2464,12 +2508,18 @@ int main(int argc, char** argv) if (!dirname_for_local_load) { if (init_tmpdir(&tmpdir, 0)) - exit(1); + { + retval= ERROR_STOP; + goto err; + } dirname_for_local_load= my_strdup(my_tmpdir(&tmpdir), MY_WME); } if (load_processor.init()) - exit(1); + { + retval= ERROR_STOP; + goto err; + } if (dirname_for_local_load) load_processor.init_by_dir_name(dirname_for_local_load); else @@ -2539,12 +2589,20 @@ int main(int argc, char** argv) free_defaults(defaults_argv); my_free_open_file_info(); load_processor.destroy(); + mysql_server_end(); /* We cannot free DBUG, it is used in global destructors after exit(). */ my_end(my_end_arg | MY_DONT_FREE_DBUG); exit(retval == ERROR_STOP ? 1 : 0); /* Keep compilers happy. */ DBUG_RETURN(retval == ERROR_STOP ? 1 : 0); + +err: + cleanup(); + free_defaults(defaults_argv); + my_end(my_end_arg); + exit(retval == ERROR_STOP ? 1 : 0); + DBUG_RETURN(retval == ERROR_STOP ? 1 : 0); } @@ -2569,3 +2627,4 @@ void *sql_alloc(size_t size) #include "sql_string.cc" #include "sql_list.cc" #include "rpl_filter.cc" +#include "compat56.cc" |