33 #include "client_priv.h"
34 #include "my_default.h"
45 static void error(
const char *format, ...) ATTRIBUTE_FORMAT(printf, 1, 2);
46 static
void warning(const
char *format, ...) ATTRIBUTE_FORMAT(printf, 1, 2);
51 #include "sql_common.h"
53 #include <welcome_copyright_notice.h>
54 #include "sql_string.h"
56 #include "rpl_constants.h"
63 #define BIN_LOG_HEADER_SIZE 4U
64 #define PROBE_HEADER_LEN (EVENT_LEN_OFFSET+4)
65 #define INTVAR_DYNAMIC_INIT 16
66 #define INTVAR_DYNAMIC_INCR 1
69 #define CLIENT_CAPABILITIES (CLIENT_LONG_PASSWORD | CLIENT_LONG_FLAG | CLIENT_LOCAL_FILES)
71 char server_version[SERVER_VERSION_LENGTH];
86 ulong bytes_sent = 0L, bytes_received = 0L;
87 ulong mysqld_net_retry_count = 10L;
88 ulong open_files_limit;
89 ulong opt_binlog_rows_event_max_size;
91 static uint opt_protocol= 0;
92 static FILE *result_file;
95 static const char* default_dbug_option =
"d:t:o,/tmp/mysqlbinlog.trace";
97 static const char *load_default_groups[]= {
"mysqlbinlog",
"client",0 };
99 static my_bool one_database=0, disable_log_bin= 0;
100 static my_bool opt_hexdump= 0;
101 const char *base64_output_mode_names[]=
102 {
"NEVER",
"AUTO",
"UNSPEC",
"DECODE-ROWS", NullS};
103 TYPELIB base64_output_mode_typelib=
104 { array_elements(base64_output_mode_names) - 1,
"",
105 base64_output_mode_names, NULL };
106 static enum_base64_output_mode opt_base64_output_mode= BASE64_OUTPUT_UNSPEC;
107 static char *opt_base64_output_mode_str= 0;
108 static my_bool opt_remote_alias= 0;
109 const char *remote_proto_names[]=
110 {
"BINLOG-DUMP-NON-GTIDS",
"BINLOG-DUMP-GTIDS", NullS};
112 { array_elements(remote_proto_names) - 1,
"",
113 remote_proto_names, NULL };
114 static enum enum_remote_proto {
115 BINLOG_DUMP_NON_GTID= 0,
118 } opt_remote_proto= BINLOG_LOCAL;
119 static char *opt_remote_proto_str= 0;
120 static char *database= 0;
121 static char *output_file= 0;
122 static my_bool force_opt= 0, short_form= 0;
123 static my_bool debug_info_flag, debug_check_flag;
124 static my_bool force_if_open_opt= 1, raw_mode= 0;
125 static my_bool to_last_remote_log= 0, stop_never= 0;
126 static my_bool opt_verify_binlog_checksum= 1;
127 static ulonglong
offset = 0;
128 static uint stop_never_server_id= 1;
129 static char* host = 0;
131 static uint my_end_arg;
132 static const char* sock= 0;
133 static char *opt_plugin_dir= 0, *opt_default_auth= 0;
136 static char *shared_memory_base_name= 0;
138 static char* user = 0;
139 static char* pass = 0;
140 static char *opt_bind_addr = NULL;
141 static char *charset= 0;
143 static uint verbose= 0;
145 static ulonglong start_position, stop_position;
146 #define start_position_mot ((my_off_t)start_position)
147 #define stop_position_mot ((my_off_t)stop_position)
149 static char *start_datetime_str, *stop_datetime_str;
150 static my_time_t start_datetime= 0, stop_datetime= MY_TIME_T_MAX;
151 static ulonglong rec_count= 0;
152 static ushort binlog_flags = 0;
153 static MYSQL* mysql = NULL;
154 static char* dirname_for_local_load= 0;
155 static uint opt_server_id_bits = 0;
156 static ulong opt_server_id_mask = 0;
186 static char *opt_include_gtids_str= NULL,
187 *opt_exclude_gtids_str= NULL;
188 static my_bool opt_skip_gtids= 0;
189 static bool filter_based_on_gtids=
false;
191 static bool in_transaction=
false;
192 static bool seen_gtids=
false;
194 static Exit_status dump_local_log_entries(PRINT_EVENT_INFO *print_event_info,
195 const char* logname);
196 static Exit_status dump_remote_log_entries(PRINT_EVENT_INFO *print_event_info,
197 const char* logname);
198 static Exit_status dump_log_entries(
const char* logname);
199 static Exit_status safe_connect();
218 char target_dir_name[FN_REFLEN];
219 size_t target_dir_name_len;
231 struct File_name_record
260 File create_unique_file(
char *filename,
char *file_name_end)
264 for (uint version= 0; version<1000; version++)
266 sprintf(file_name_end,
"-%x",version);
267 if ((res= my_create(filename,0,
268 O_CREAT|O_EXCL|O_BINARY|O_WRONLY,MYF(0)))!=-1)
280 return init_dynamic_array(&file_names,
sizeof(File_name_record),
284 void init_by_dir_name(
const char *dir)
286 target_dir_name_len= (convert_dirname(target_dir_name, dir, NullS) -
289 void init_by_cur_dir()
291 if (my_getwd(target_dir_name,
sizeof(target_dir_name),MYF(MY_WME)))
293 target_dir_name_len= strlen(target_dir_name);
297 File_name_record *ptr= (File_name_record *)file_names.buffer;
298 File_name_record *end= ptr + file_names.elements;
299 for (; ptr < end; ptr++)
305 memset(ptr, 0,
sizeof(File_name_record));
309 delete_dynamic(&file_names);
329 File_name_record *ptr;
332 if (file_id >= file_names.elements)
334 ptr= dynamic_element(&file_names, file_id, File_name_record*);
335 if ((res= ptr->event))
336 memset(ptr, 0,
sizeof(File_name_record));
357 File_name_record *ptr;
360 if (file_id >= file_names.elements)
362 ptr= dynamic_element(&file_names, file_id, File_name_record*);
366 memset(ptr, 0,
sizeof(File_name_record));
375 uint server_fname_len, File
file);
378 size_t block_len, uint file_id,
400 fn_format(filename, le->fname, target_dir_name,
"", MY_REPLACE_DIR);
401 len= strlen(filename);
402 tail= filename + len;
404 if ((file= create_unique_file(filename,tail)) < 0)
406 error(
"Could not construct local filename %s.",filename);
410 le->set_fname_outside_temp_buf(filename,len+(uint) strlen(tail));
432 const char*server_fname,
433 uint server_fname_len,
436 uchar
buf[FN_REFLEN+1];
438 memcpy(buf + 1, server_fname, server_fname_len + 1);
441 error(
"Failed requesting the remote dump of %s.", server_fname);
452 error(
"Failed sending the ack packet.");
462 else if (packet_len == packet_error)
464 error(
"Failed reading a packet during the dump of %s.", server_fname);
468 if (packet_len > UINT_MAX)
470 error(
"Illegal length of packet read from net.");
473 if (my_write(file, (uchar*) net->read_pos,
474 (uint) packet_len, MYF(MY_WME|MY_NABP)))
508 uint full_len= target_dir_name_len + blen + 9 + 9 + 1;
509 Exit_status retval= OK_CONTINUE;
512 File_name_record
rec;
513 DBUG_ENTER(
"Load_log_processor::process_first_event");
515 if (!(fname= (
char*) my_malloc(full_len,MYF(MY_WME))))
517 error(
"Out of memory.");
519 DBUG_RETURN(ERROR_STOP);
522 memcpy(fname, target_dir_name, target_dir_name_len);
523 ptr= fname + target_dir_name_len;
524 memcpy(ptr,bname,blen);
526 ptr+= sprintf(ptr,
"-%x", file_id);
528 if ((file= create_unique_file(fname,ptr)) < 0)
530 error(
"Could not construct local filename %s%s.",
531 target_dir_name,bname);
534 DBUG_RETURN(ERROR_STOP);
545 if (set_dynamic(&file_names, &rec, file_id))
547 error(
"Out of memory.");
550 DBUG_RETURN(ERROR_STOP);
554 ce->set_fname_outside_temp_buf(fname, (uint) strlen(fname));
556 if (my_write(file, (uchar*)block, block_len, MYF(MY_WME|MY_NABP)))
558 error(
"Failed writing to file.");
561 if (my_close(file, MYF(MY_WME)))
563 error(
"Failed closing file.");
582 const char *bname= ce->fname + dirname_length(ce->fname);
583 uint blen= ce->fname_len - (bname-ce->fname);
631 DBUG_ENTER(
"Load_log_processor::process");
632 const char* fname= ((ae->file_id < file_names.elements) ?
633 dynamic_element(&file_names, ae->file_id,
634 File_name_record*)->fname : 0);
639 Exit_status retval= OK_CONTINUE;
640 if (((file= my_open(fname,
641 O_APPEND|O_BINARY|O_WRONLY,MYF(MY_WME))) < 0))
643 error(
"Failed opening file %s", fname);
644 DBUG_RETURN(ERROR_STOP);
646 if (my_write(file,(uchar*)ae->block,ae->block_len,MYF(MY_WME|MY_NABP)))
648 error(
"Failed writing to file %s", fname);
651 if (my_close(file,MYF(MY_WME)))
653 error(
"Failed closing file %s", fname);
664 warning(
"Ignoring Append_block as there is no "
665 "Create_file event for file_id: %u", ae->file_id);
666 DBUG_RETURN(OK_CONTINUE);
687 static void convert_path_to_forward_slashes(
char *fname)
707 static bool shall_skip_database(
const char *log_dbname)
709 return one_database &&
710 (log_dbname != NULL) &&
711 strcmp(log_dbname, database);
725 static bool shall_skip_gtids(
Log_event* ev)
727 bool filtered=
false;
729 switch (ev->get_type_code())
732 case ANONYMOUS_GTID_LOG_EVENT:
735 if (opt_include_gtids_str != NULL)
737 filtered= filtered ||
742 if (opt_exclude_gtids_str != NULL)
744 filtered= filtered ||
748 filter_based_on_gtids= filtered;
749 filtered= filtered || opt_skip_gtids;
753 case PREVIOUS_GTIDS_LOG_EVENT:
754 filtered= opt_skip_gtids;
772 filtered= filter_based_on_gtids;
773 filter_based_on_gtids=
false;
776 filtered= filter_based_on_gtids;
778 filter_based_on_gtids=
false;
800 case FORMAT_DESCRIPTION_EVENT:
802 case IGNORABLE_LOG_EVENT:
807 filtered= filter_based_on_gtids;
834 Exit_status process_event(PRINT_EVENT_INFO *print_event_info,
Log_event *ev,
835 my_off_t pos,
const char *logname)
839 my_bool destroy_evt= TRUE;
840 DBUG_ENTER(
"process_event");
841 print_event_info->short_form= short_form;
842 Exit_status retval= OK_CONTINUE;
843 IO_CACHE *
const head= &print_event_info->head_cache;
849 if (((rec_count >= offset) &&
850 ((my_time_t) (ev->when.tv_sec) >= start_datetime)) ||
851 (ev_type == FORMAT_DESCRIPTION_EVENT))
853 if (ev_type != FORMAT_DESCRIPTION_EVENT)
870 if (ev_type != ROTATE_EVENT &&
871 server_id && (server_id != ev->server_id))
874 if (((my_time_t) (ev->when.tv_sec) >= stop_datetime)
875 || (pos >= stop_position_mot))
882 my_b_printf(&print_event_info->head_cache,
883 "# at %s\n",llstr(pos,ll_buff));
886 print_event_info->hexdump_from= 0;
888 print_event_info->hexdump_from= pos;
890 print_event_info->base64_output_mode= opt_base64_output_mode;
892 DBUG_PRINT(
"debug", (
"event_type: %s", ev->
get_type_str()));
894 if (shall_skip_gtids(ev))
900 bool parent_query_skips=
906 for (uint
i= 0;
i < buff_ev.elements;
i++)
909 Log_event *temp_event= pop_event_array.event;
910 my_off_t temp_log_pos= pop_event_array.event_pos;
911 print_event_info->hexdump_from= (opt_hexdump ? temp_log_pos : 0);
912 if (!parent_query_skips)
913 temp_event->print(result_file, print_event_info);
917 print_event_info->hexdump_from= (opt_hexdump ? pos : 0);
918 reset_dynamic(&buff_ev);
920 if (parent_query_skips)
929 if (seen_gtids && !in_transaction && !starts_group && !ends_group)
934 fprintf(result_file,
"COMMIT /* added by mysqlbinlog */%s\n", print_event_info->delimiter);
935 print_event_info->skipped_event_in_transaction=
false;
936 in_transaction=
false;
939 print_event_info->skipped_event_in_transaction=
true;
945 in_transaction=
false;
946 print_event_info->skipped_event_in_transaction=
false;
948 else if (starts_group)
949 in_transaction=
true;
951 ev->print(result_file, print_event_info);
952 if (head->error == -1)
962 buff_event.event= ev;
963 buff_event.event_pos= pos;
964 insert_dynamic(&buff_ev, (uchar*) &buff_event);
971 buff_event.event= ev;
972 buff_event.event_pos= pos;
973 insert_dynamic(&buff_ev, (uchar*) &buff_event);
980 buff_event.event= ev;
981 buff_event.event_pos= pos;
982 insert_dynamic(&buff_ev, (uchar*) &buff_event);
987 case CREATE_FILE_EVENT:
996 if (shall_skip_database(ce->db))
998 print_event_info->skipped_event_in_transaction=
true;
1009 ce->print(result_file, print_event_info, TRUE);
1010 if (head->error == -1)
1014 if (glob_description_event->binlog_version >= 3)
1021 if ((retval= load_processor.
process(ce)) != OK_CONTINUE)
1027 case APPEND_BLOCK_EVENT:
1033 ev->print(result_file, print_event_info);
1034 if (head->error == -1)
1041 case EXEC_LOAD_EVENT:
1043 ev->print(result_file, print_event_info);
1044 if (head->error == -1)
1059 convert_path_to_forward_slashes((
char*) ce->fname);
1060 ce->print(result_file, print_event_info, TRUE);
1061 my_free((
void*)ce->fname);
1063 if (head->error == -1)
1067 warning(
"Ignoring Execute_load_log_event as there is no "
1068 "Create_file event for file_id: %u", exv->file_id);
1071 case FORMAT_DESCRIPTION_EVENT:
1072 delete glob_description_event;
1074 print_event_info->common_header_len=
1075 glob_description_event->common_header_len;
1076 ev->print(result_file, print_event_info);
1077 if (head->error == -1)
1079 if (opt_remote_proto == BINLOG_LOCAL)
1081 ev->free_temp_buf();
1097 if (!force_if_open_opt &&
1098 (glob_description_event->
flags & LOG_EVENT_BINLOG_IN_USE_F))
1100 error(
"Attempting to dump binlog '%s', which was not closed properly. "
1101 "Most probably, mysqld is still writing it, or it crashed. "
1102 "Rerun with --force-if-open to ignore this problem.", logname);
1103 DBUG_RETURN(ERROR_STOP);
1106 case BEGIN_LOAD_QUERY_EVENT:
1107 ev->print(result_file, print_event_info);
1108 if (head->error == -1)
1114 case EXECUTE_LOAD_QUERY_EVENT:
1117 char *fname= load_processor.
grab_fname(exlq->file_id);
1119 if (shall_skip_database(exlq->db))
1120 print_event_info->skipped_event_in_transaction=
true;
1125 convert_path_to_forward_slashes(fname);
1126 exlq->print(result_file, print_event_info, fname);
1127 if (head->error == -1)
1135 warning(
"Ignoring Execute_load_query since there is no "
1136 "Begin_load_query event for file_id: %u", exlq->file_id);
1143 case TABLE_MAP_EVENT:
1146 if (shall_skip_database(map->get_db_name()))
1148 print_event_info->skipped_event_in_transaction=
true;
1149 print_event_info->m_table_map_ignored.set_table(map->get_table_id(), map);
1154 case ROWS_QUERY_LOG_EVENT:
1155 case WRITE_ROWS_EVENT:
1156 case DELETE_ROWS_EVENT:
1157 case UPDATE_ROWS_EVENT:
1158 case WRITE_ROWS_EVENT_V1:
1159 case UPDATE_ROWS_EVENT_V1:
1160 case DELETE_ROWS_EVENT_V1:
1161 case PRE_GA_WRITE_ROWS_EVENT:
1162 case PRE_GA_DELETE_ROWS_EVENT:
1163 case PRE_GA_UPDATE_ROWS_EVENT:
1165 bool stmt_end= FALSE;
1167 if (ev_type == WRITE_ROWS_EVENT ||
1168 ev_type == DELETE_ROWS_EVENT ||
1169 ev_type == UPDATE_ROWS_EVENT ||
1170 ev_type == WRITE_ROWS_EVENT_V1 ||
1171 ev_type == DELETE_ROWS_EVENT_V1 ||
1172 ev_type == UPDATE_ROWS_EVENT_V1)
1175 if (new_ev->get_flags(Rows_log_event::STMT_END_F))
1177 ignored_map= print_event_info->m_table_map_ignored.get_table(new_ev->get_table_id());
1179 else if (ev_type == PRE_GA_WRITE_ROWS_EVENT ||
1180 ev_type == PRE_GA_DELETE_ROWS_EVENT ||
1181 ev_type == PRE_GA_UPDATE_ROWS_EVENT)
1184 if (old_ev->get_flags(Rows_log_event::STMT_END_F))
1186 ignored_map= print_event_info->m_table_map_ignored.get_table(old_ev->get_table_id());
1189 bool skip_event= (ignored_map != NULL);
1205 if (print_event_info->m_table_map_ignored.count() > 0)
1206 print_event_info->m_table_map_ignored.clear_tables();
1219 print_event_info->have_unflushed_events= FALSE;
1222 IO_CACHE *
const body_cache= &print_event_info->body_cache;
1223 if (my_b_tell(body_cache))
1224 my_b_printf(body_cache,
"'%s\n", print_event_info->delimiter);
1227 if ((copy_event_cache_to_file_and_reinit(&print_event_info->head_cache,
1228 result_file, stop_never ) ||
1229 copy_event_cache_to_file_and_reinit(&print_event_info->body_cache,
1230 result_file, stop_never )))
1238 print_event_info->skipped_event_in_transaction=
true;
1249 if (!print_event_info->printed_fd_event && !short_form &&
1250 ev_type != TABLE_MAP_EVENT && ev_type != ROWS_QUERY_LOG_EVENT &&
1251 opt_base64_output_mode != BASE64_OUTPUT_DECODE_ROWS)
1254 if (opt_base64_output_mode == BASE64_OUTPUT_NEVER)
1255 error(
"--base64-output=never specified, but binlog contains a "
1256 "%s event which must be printed in base64.",
1259 error(
"malformed binlog: it does not contain any "
1260 "Format_description_log_event. I now found a %s event, which "
1261 "is not safe to process without a "
1262 "Format_description_log_event.",
1267 ev->print(result_file, print_event_info);
1268 print_event_info->have_unflushed_events= TRUE;
1272 print_event_info->have_unflushed_events= FALSE;
1273 if (copy_event_cache_to_file_and_reinit(&print_event_info->head_cache,
1274 result_file, stop_never ) ||
1275 copy_event_cache_to_file_and_reinit(&print_event_info->body_cache,
1276 result_file, stop_never ))
1282 case ANONYMOUS_GTID_LOG_EVENT:
1283 case GTID_LOG_EVENT:
1286 if (print_event_info->skipped_event_in_transaction ==
true)
1287 fprintf(result_file,
"COMMIT /* added by mysqlbinlog */%s\n", print_event_info->delimiter);
1288 print_event_info->skipped_event_in_transaction=
false;
1290 ev->print(result_file, print_event_info);
1291 if (head->error == -1)
1297 in_transaction=
false;
1298 print_event_info->skipped_event_in_transaction=
false;
1299 ev->print(result_file, print_event_info);
1300 if (head->error == -1)
1313 bool is_fake= (rev->when.tv_sec == 0);
1314 if (!in_transaction && !is_fake)
1321 fprintf(result_file,
"SET @@SESSION.GTID_NEXT= 'AUTOMATIC' "
1322 "/* added by mysqlbinlog */ %s\n",
1323 print_event_info->delimiter);
1326 ev->print(result_file, print_event_info);
1327 if (head->error == -1)
1331 case PREVIOUS_GTIDS_LOG_EVENT:
1332 if (one_database && !opt_skip_gtids)
1333 warning(
"The option --database has been used. It may filter "
1334 "parts of transactions, but will include the GTIDs in "
1335 "any case. If you want to exclude or include transactions, "
1336 "you should use the options --exclude-gtids or "
1337 "--include-gtids, respectively, instead.");
1340 ev->print(result_file, print_event_info);
1341 if (head->error == -1)
1345 if (copy_event_cache_to_file_and_reinit(&print_event_info->head_cache,
1346 result_file, stop_never ))
1362 if (opt_remote_proto != BINLOG_LOCAL)
1367 DBUG_RETURN(retval);
1371 static struct my_option my_long_options[] =
1373 {
"help",
'?',
"Display this help and exit.",
1374 0, 0, 0, GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0},
1375 {
"base64-output", OPT_BASE64_OUTPUT_MODE,
1377 "Determine when the output statements should be base64-encoded BINLOG "
1378 "statements: 'never' disables it and works only for binlogs without "
1379 "row-based events; 'decode-rows' decodes row events into commented pseudo-SQL "
1380 "statements if the --verbose option is also given; 'auto' prints base64 "
1381 "only when necessary (i.e., for row-based events and format description "
1382 "events). If no --base64-output[=name] option is given at all, the "
1383 "default is 'auto'.",
1384 &opt_base64_output_mode_str, &opt_base64_output_mode_str,
1385 0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
1386 {
"bind-address", 0,
"IP address to bind to.",
1387 (uchar**) &opt_bind_addr, (uchar**) &opt_bind_addr, 0, GET_STR,
1388 REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
1395 {
"character-sets-dir", OPT_CHARSETS_DIR,
1396 "Directory for character set files.", &charsets_dir,
1397 &charsets_dir, 0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
1398 {
"database",
'd',
"List entries for just this database (local log only).",
1399 &database, &database, 0, GET_STR_ALLOC, REQUIRED_ARG,
1402 {
"debug",
'#',
"Output debug log.", &default_dbug_option,
1403 &default_dbug_option, 0, GET_STR, OPT_ARG, 0, 0, 0, 0, 0, 0},
1405 {
"debug-check", OPT_DEBUG_CHECK,
"Check memory and open file usage at exit .",
1406 &debug_check_flag, &debug_check_flag, 0,
1407 GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0},
1408 {
"debug-info", OPT_DEBUG_INFO,
"Print some debug info at exit.",
1409 &debug_info_flag, &debug_info_flag,
1410 0, GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0},
1411 {
"default_auth", OPT_DEFAULT_AUTH,
1412 "Default authentication client-side plugin to use.",
1413 &opt_default_auth, &opt_default_auth, 0,
1414 GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
1415 {
"disable-log-bin",
'D',
"Disable binary log. This is useful, if you "
1416 "enabled --to-last-log and are sending the output to the same MySQL server. "
1417 "This way you could avoid an endless loop. You would also like to use it "
1418 "when restoring after a crash to avoid duplication of the statements you "
1419 "already have. NOTE: you will need a SUPER privilege to use this option.",
1420 &disable_log_bin, &disable_log_bin, 0, GET_BOOL,
1421 NO_ARG, 0, 0, 0, 0, 0, 0},
1422 {
"force-if-open",
'F',
"Force if binlog was not closed properly.",
1423 &force_if_open_opt, &force_if_open_opt, 0, GET_BOOL, NO_ARG,
1425 {
"force-read",
'f',
"Force reading unknown binlog events.",
1426 &force_opt, &force_opt, 0, GET_BOOL, NO_ARG, 0, 0, 0, 0,
1428 {
"hexdump",
'H',
"Augment output with hexadecimal and ASCII event dump.",
1429 &opt_hexdump, &opt_hexdump, 0, GET_BOOL, NO_ARG,
1431 {
"host",
'h',
"Get the binlog from server.", &host, &host,
1432 0, GET_STR_ALLOC, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
1433 {
"local-load",
'l',
"Prepare local temporary files for LOAD DATA INFILE in the specified directory.",
1434 &dirname_for_local_load, &dirname_for_local_load, 0,
1435 GET_STR_ALLOC, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
1436 {
"offset",
'o',
"Skip the first N entries.", &
offset, &
offset,
1437 0, GET_ULL, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
1438 {
"password",
'p',
"Password to connect to remote server.",
1439 0, 0, 0, GET_PASSWORD, OPT_ARG, 0, 0, 0, 0, 0, 0},
1440 {
"plugin_dir", OPT_PLUGIN_DIR,
"Directory for client-side plugins.",
1441 &opt_plugin_dir, &opt_plugin_dir, 0,
1442 GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
1443 {
"port",
'P',
"Port number to use for connection or 0 for default to, in "
1444 "order of preference, my.cnf, $MYSQL_TCP_PORT, "
1445 #if MYSQL_PORT_DEFAULT == 0
1448 "built-in default (" STRINGIFY_ARG(MYSQL_PORT)
").",
1449 &port, &port, 0, GET_INT, REQUIRED_ARG,
1451 {
"protocol", OPT_MYSQL_PROTOCOL,
1452 "The protocol to use for connection (tcp, socket, pipe, memory).",
1453 0, 0, 0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
1454 {
"read-from-remote-server",
'R',
"Read binary logs from a MySQL server. "
1455 "This is an alias for read-from-remote-master=BINLOG-DUMP-NON-GTIDS.",
1456 &opt_remote_alias, &opt_remote_alias, 0, GET_BOOL, NO_ARG,
1458 {
"read-from-remote-master", OPT_REMOTE_PROTO,
1459 "Read binary logs from a MySQL server through the COM_BINLOG_DUMP or "
1460 "COM_BINLOG_DUMP_GTID commands by setting the option to either "
1461 "BINLOG-DUMP-NON-GTIDS or BINLOG-DUMP-GTIDS, respectively. If "
1462 "--read-from-remote-master=BINLOG-DUMP-GTIDS is combined with "
1463 "--exclude-gtids, transactions can be filtered out on the master "
1464 "avoiding unnecessary network traffic.",
1465 &opt_remote_proto_str, &opt_remote_proto_str, 0, GET_STR, REQUIRED_ARG,
1467 {
"raw", OPT_RAW_OUTPUT,
"Requires -R. Output raw binlog data instead of SQL "
1468 "statements, output is to log files.",
1469 &raw_mode, &raw_mode, 0, GET_BOOL, NO_ARG, 0, 0, 0, 0,
1471 {
"result-file",
'r',
"Direct output to a given file. With --raw this is a "
1472 "prefix for the file names.",
1473 &output_file, &output_file, 0, GET_STR, REQUIRED_ARG,
1475 {
"server-id", OPT_SERVER_ID,
1476 "Extract only binlog entries created by the server having the given id.",
1477 &server_id, &server_id, 0, GET_ULONG,
1478 REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
1479 {
"server-id-bits", 0,
1480 "Set number of significant bits in server-id",
1481 &opt_server_id_bits, &opt_server_id_bits,
1483 0, GET_UINT, REQUIRED_ARG, 32, 7, 32, 0, 0, 0},
1484 {
"set-charset", OPT_SET_CHARSET,
1485 "Add 'SET NAMES character_set' to the output.", &charset,
1486 &charset, 0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
1488 {
"shared-memory-base-name", OPT_SHARED_MEMORY_BASE_NAME,
1489 "Base name of shared memory.", &shared_memory_base_name,
1490 &shared_memory_base_name,
1491 0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
1493 {
"short-form",
's',
"Just show regular queries: no extra info and no "
1494 "row-based events. This is for testing only, and should not be used in "
1495 "production systems. If you want to suppress base64-output, consider "
1496 "using --base64-output=never instead.",
1497 &short_form, &short_form, 0, GET_BOOL, NO_ARG, 0, 0, 0, 0,
1499 {
"socket",
'S',
"The socket file to use for connection.",
1500 &sock, &sock, 0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0,
1502 {
"start-datetime", OPT_START_DATETIME,
1503 "Start reading the binlog at first event having a datetime equal or "
1504 "posterior to the argument; the argument must be a date and time "
1505 "in the local time zone, in any format accepted by the MySQL server "
1506 "for DATETIME and TIMESTAMP types, for example: 2004-12-25 11:25:56 "
1507 "(you should probably use quotes for your shell to set it properly).",
1508 &start_datetime_str, &start_datetime_str,
1509 0, GET_STR_ALLOC, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
1510 {
"start-position",
'j',
1511 "Start reading the binlog at position N. Applies to the first binlog "
1512 "passed on the command line.",
1513 &start_position, &start_position, 0, GET_ULL,
1514 REQUIRED_ARG, BIN_LOG_HEADER_SIZE, BIN_LOG_HEADER_SIZE,
1516 (ulonglong)(~(uint32)0), 0, 0, 0},
1517 {
"stop-datetime", OPT_STOP_DATETIME,
1518 "Stop reading the binlog at first event having a datetime equal or "
1519 "posterior to the argument; the argument must be a date and time "
1520 "in the local time zone, in any format accepted by the MySQL server "
1521 "for DATETIME and TIMESTAMP types, for example: 2004-12-25 11:25:56 "
1522 "(you should probably use quotes for your shell to set it properly).",
1523 &stop_datetime_str, &stop_datetime_str,
1524 0, GET_STR_ALLOC, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
1525 {
"stop-never", OPT_STOP_NEVER,
"Wait for more data from the server "
1526 "instead of stopping at the end of the last log. Implicitly sets "
1527 "--to-last-log but instead of stopping at the end of the last log "
1528 "it continues to wait till the server disconnects.",
1529 &stop_never, &stop_never, 0,
1530 GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0},
1531 {
"stop-never-slave-server-id", OPT_WAIT_SERVER_ID,
1532 "The slave server ID used for stop-never",
1533 &stop_never_server_id, &stop_never_server_id, 0,
1534 GET_UINT, REQUIRED_ARG, 65535, 1, 65535, 0, 0, 0},
1535 {
"stop-position", OPT_STOP_POSITION,
1536 "Stop reading the binlog at position N. Applies to the last binlog "
1537 "passed on the command line.",
1538 &stop_position, &stop_position, 0, GET_ULL,
1539 REQUIRED_ARG, (longlong)(~(my_off_t)0), BIN_LOG_HEADER_SIZE,
1540 (ulonglong)(~(my_off_t)0), 0, 0, 0},
1541 {
"to-last-log",
't',
"Requires -R. Will not stop at the end of the "
1542 "requested binlog but rather continue printing until the end of the last "
1543 "binlog of the MySQL server. If you send the output to the same MySQL "
1544 "server, that may lead to an endless loop.",
1545 &to_last_remote_log, &to_last_remote_log, 0, GET_BOOL,
1546 NO_ARG, 0, 0, 0, 0, 0, 0},
1547 {
"user",
'u',
"Connect to the remote server as username.",
1548 &user, &user, 0, GET_STR_ALLOC, REQUIRED_ARG, 0, 0, 0, 0,
1550 {
"verbose",
'v',
"Reconstruct pseudo-SQL statements out of row events. "
1551 "-v -v adds comments on column data types.",
1552 0, 0, 0, GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0},
1553 {
"version",
'V',
"Print version and exit.", 0, 0, 0, GET_NO_ARG, NO_ARG, 0,
1555 {
"open_files_limit", OPT_OPEN_FILES_LIMIT,
1556 "Used to reserve file descriptors for use by this program.",
1557 &open_files_limit, &open_files_limit, 0, GET_ULONG,
1558 REQUIRED_ARG, MY_NFILE, 8, OS_FILE_LIMIT, 0, 1, 0},
1559 {
"verify-binlog-checksum",
'c',
"Verify checksum binlog events.",
1560 (uchar**) &opt_verify_binlog_checksum, (uchar**) &opt_verify_binlog_checksum,
1561 0, GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0},
1562 {
"binlog-row-event-max-size", OPT_BINLOG_ROWS_EVENT_MAX_SIZE,
1563 "The maximum size of a row-based binary log event in bytes. Rows will be "
1564 "grouped into events smaller than this size if possible. "
1565 "This value must be a multiple of 256.",
1566 &opt_binlog_rows_event_max_size,
1567 &opt_binlog_rows_event_max_size, 0,
1568 GET_ULONG, REQUIRED_ARG,
1572 {
"skip-gtids", OPT_MYSQLBINLOG_SKIP_GTIDS,
1573 "Do not print Global Transaction Identifier information "
1574 "(SET GTID_NEXT=... etc).",
1575 &opt_skip_gtids, &opt_skip_gtids, 0,
1576 GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0},
1577 {
"include-gtids", OPT_MYSQLBINLOG_INCLUDE_GTIDS,
1578 "Print events whose Global Transaction Identifiers "
1580 &opt_include_gtids_str, &opt_include_gtids_str, 0,
1581 GET_STR_ALLOC, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
1582 {
"exclude-gtids", OPT_MYSQLBINLOG_EXCLUDE_GTIDS,
1583 "Print all events but those whose Global Transaction "
1584 "Identifiers were provided.",
1585 &opt_exclude_gtids_str, &opt_exclude_gtids_str, 0,
1586 GET_STR_ALLOC, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
1587 {0, 0, 0, 0, 0, 0, GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0}
1601 static void error_or_warning(
const char *format, va_list args,
const char *
msg)
1603 fprintf(stderr,
"%s: ", msg);
1604 vfprintf(stderr, format, args);
1605 fprintf(stderr,
"\n");
1615 static void error(
const char *format,...)
1618 va_start(args, format);
1619 error_or_warning(format, args,
"ERROR");
1630 static void sql_print_error(
const char *format,...)
1633 va_start(args, format);
1634 error_or_warning(format, args,
"ERROR");
1645 static void warning(
const char *format,...)
1648 va_start(args, format);
1649 error_or_warning(format, args,
"WARNING");
1656 static void cleanup()
1662 my_free(dirname_for_local_load);
1664 for (uint
i= 0;
i < buff_ev.elements;
i++)
1667 delete (pop_event_array.event);
1669 delete_dynamic(&buff_ev);
1671 delete glob_description_event;
1677 static void print_version()
1679 printf(
"%s Ver 3.4 for %s at %s\n", my_progname, SYSTEM_TYPE, MACHINE_TYPE);
1686 puts(ORACLE_WELCOME_COPYRIGHT_NOTICE(
"2000"));
1688 Dumps a MySQL binary log in a format usable for viewing or for piping to\n\
1689 the mysql command line client.\n\n");
1690 printf(
"Usage: %s [options] log-files\n", my_progname);
1691 my_print_help(my_long_options);
1692 my_print_variables(my_long_options);
1696 static my_time_t convert_str_to_timestamp(
const char* str)
1700 long dummy_my_timezone;
1701 my_bool dummy_in_dst_time_gap;
1703 if (str_to_datetime(str, (uint) strlen(str), &l_time, 0, &status) ||
1704 l_time.time_type != MYSQL_TIMESTAMP_DATETIME || status.warnings)
1706 error(
"Incorrect date and time argument: %s", str);
1715 my_system_gmt_sec(&l_time, &dummy_my_timezone, &dummy_in_dst_time_gap);
1720 get_one_option(
int optid,
const struct my_option *opt __attribute__((unused)),
1723 bool tty_password=0;
1727 DBUG_PUSH(argument ? argument : default_dbug_option);
1734 if (argument == disabled_my_option)
1735 argument= (
char*)
"";
1739 char *start=argument;
1740 pass= my_strdup(argument,MYF(MY_FAE));
1741 while (*argument) *argument++=
'x';
1749 opt_remote_alias= 1;
1750 opt_remote_proto= BINLOG_DUMP_NON_GTID;
1752 case OPT_REMOTE_PROTO:
1753 opt_remote_proto= (enum_remote_proto)
1754 (find_type_or_exit(argument, &remote_proto_typelib, opt->name) - 1);
1756 case OPT_MYSQL_PROTOCOL:
1757 opt_protocol= find_type_or_exit(argument, &sql_protocol_typelib,
1760 case OPT_START_DATETIME:
1761 start_datetime= convert_str_to_timestamp(start_datetime_str);
1763 case OPT_STOP_DATETIME:
1764 stop_datetime= convert_str_to_timestamp(stop_datetime_str);
1766 case OPT_BASE64_OUTPUT_MODE:
1767 opt_base64_output_mode= (enum_base64_output_mode)
1768 (find_type_or_exit(argument, &base64_output_mode_typelib, opt->name)-1);
1771 if (argument == disabled_my_option)
1779 case OPT_STOP_NEVER:
1781 to_last_remote_log= 1;
1788 pass= get_tty_password(NullS);
1794 static int parse_args(
int *argc,
char*** argv)
1798 result_file = stdout;
1799 if ((ho_error=handle_options(argc, argv, my_long_options, get_one_option)))
1801 if (debug_info_flag)
1802 my_end_arg= MY_CHECK_ERROR | MY_GIVE_INFO;
1803 if (debug_check_flag)
1804 my_end_arg= MY_CHECK_ERROR;
1816 static Exit_status safe_connect()
1818 mysql= mysql_init(NULL);
1822 error(
"Failed on mysql_init.");
1826 if (opt_plugin_dir && *opt_plugin_dir)
1827 mysql_options(mysql, MYSQL_PLUGIN_DIR, opt_plugin_dir);
1829 if (opt_default_auth && *opt_default_auth)
1830 mysql_options(mysql, MYSQL_DEFAULT_AUTH, opt_default_auth);
1833 mysql_options(mysql, MYSQL_OPT_PROTOCOL, (
char*) &opt_protocol);
1835 mysql_options(mysql, MYSQL_OPT_BIND, opt_bind_addr);
1837 if (shared_memory_base_name)
1838 mysql_options(mysql, MYSQL_SHARED_MEMORY_BASE_NAME,
1839 shared_memory_base_name);
1841 mysql_options(mysql, MYSQL_OPT_CONNECT_ATTR_RESET, 0);
1842 mysql_options4(mysql, MYSQL_OPT_CONNECT_ATTR_ADD,
1843 "program_name",
"mysqlbinlog");
1844 if (!mysql_real_connect(mysql, host, user, pass, 0, port, sock, 0))
1846 error(
"Failed on connect: %s", mysql_error(mysql));
1849 mysql->reconnect= 1;
1867 static Exit_status dump_log_entries(
const char* logname)
1869 DBUG_ENTER(
"dump_log_entries");
1871 Exit_status rc= OK_CONTINUE;
1872 PRINT_EVENT_INFO print_event_info;
1873 if (!print_event_info.init_ok())
1874 DBUG_RETURN(ERROR_STOP);
1881 fprintf(result_file,
"DELIMITER /*!*/;\n");
1883 strmov(print_event_info.delimiter,
"/*!*/;");
1885 print_event_info.verbose= short_form ? 0 : verbose;
1887 switch (opt_remote_proto)
1890 rc= dump_local_log_entries(&print_event_info, logname);
1892 case BINLOG_DUMP_NON_GTID:
1893 case BINLOG_DUMP_GTID:
1894 rc= dump_remote_log_entries(&print_event_info, logname);
1901 if (buff_ev.elements > 0)
1902 warning(
"The range of printed events ends with an Intvar_event, "
1903 "Rand_event or User_var_event with no matching Query_log_event. "
1904 "This might be because the last statement was not fully written "
1905 "to the log, or because you are using a --stop-position or "
1906 "--stop-datetime that refers to an event in the middle of a "
1907 "statement. The event(s) from the partial statement have not been "
1908 "written to output. ");
1910 else if (print_event_info.have_unflushed_events)
1911 warning(
"The range of printed events ends with a row event or "
1912 "a table map event that does not have the STMT_END_F "
1913 "flag set. This might be because the last statement "
1914 "was not fully written to the log, or because you are "
1915 "using a --stop-position or --stop-datetime that refers "
1916 "to an event in the middle of a statement. The event(s) "
1917 "from the partial statement have not been written to output.");
1922 if (print_event_info.skipped_event_in_transaction)
1923 fprintf(result_file,
"COMMIT /* added by mysqlbinlog */%s\n", print_event_info.delimiter);
1925 fprintf(result_file,
"DELIMITER ;\n");
1926 strmov(print_event_info.delimiter,
";");
1942 static Exit_status check_master_version()
1944 DBUG_ENTER(
"check_master_version");
1947 const char* version;
1949 if (mysql_query(mysql,
"SELECT VERSION()") ||
1950 !(res = mysql_store_result(mysql)))
1952 error(
"Could not find server version: "
1953 "Query failed when checking master version: %s", mysql_error(mysql));
1954 DBUG_RETURN(ERROR_STOP);
1956 if (!(row = mysql_fetch_row(res)))
1958 error(
"Could not find server version: "
1959 "Master returned no rows for SELECT VERSION().");
1963 if (!(version = row[0]))
1965 error(
"Could not find server version: "
1966 "Master reported NULL for the version.");
1975 if (mysql_query(mysql,
"SET @master_binlog_checksum='NONE'"))
1977 error(
"Could not notify master about checksum awareness."
1978 "Master returned '%s'", mysql_error(mysql));
1981 delete glob_description_event;
1999 glob_description_event= NULL;
2000 error(
"Could not find server version: "
2001 "Master reported unrecognized MySQL version '%s'.", version);
2004 if (!glob_description_event || !glob_description_event->is_valid())
2006 error(
"Failed creating Format_description_log_event; out of memory?");
2010 mysql_free_result(res);
2011 DBUG_RETURN(OK_CONTINUE);
2014 mysql_free_result(res);
2015 DBUG_RETURN(ERROR_STOP);
2032 static Exit_status dump_remote_log_entries(PRINT_EVENT_INFO *print_event_info,
2033 const char* logname)
2035 uchar *command_buffer= NULL;
2036 size_t command_size= 0;
2038 uint logname_len= 0;
2041 my_off_t old_off= start_position_mot;
2042 char fname[FN_REFLEN + 1];
2043 char log_file_name[FN_REFLEN + 1];
2044 Exit_status retval= OK_CONTINUE;
2045 enum enum_server_command command= COM_END;
2047 DBUG_ENTER(
"dump_remote_log_entries");
2049 fname[0]= log_file_name[0]= 0;
2056 if ((retval= safe_connect()) != OK_CONTINUE)
2057 DBUG_RETURN(retval);
2060 if ((retval= check_master_version()) != OK_CONTINUE)
2061 DBUG_RETURN(retval);
2067 server_id= ((to_last_remote_log && stop_never) ? stop_never_server_id : 0);
2068 size_t tlen = strlen(logname);
2069 if (tlen > UINT_MAX)
2071 error(
"Log name too long.");
2072 DBUG_RETURN(ERROR_STOP);
2074 const uint BINLOG_NAME_INFO_SIZE= logname_len= tlen;
2076 if (opt_remote_proto == BINLOG_DUMP_NON_GTID)
2078 command= COM_BINLOG_DUMP;
2079 size_t allocation_size= ::BINLOG_POS_OLD_INFO_SIZE +
2080 BINLOG_NAME_INFO_SIZE + ::BINLOG_FLAGS_INFO_SIZE +
2081 ::BINLOG_SERVER_ID_INFO_SIZE + 1;
2082 if (!(command_buffer= (uchar *) my_malloc(allocation_size, MYF(MY_WME))))
2084 error(
"Got fatal error allocating memory.");
2085 DBUG_RETURN(ERROR_STOP);
2087 uchar* ptr_buffer= command_buffer;
2093 int4store(ptr_buffer, (uint32) start_position);
2094 ptr_buffer+= ::BINLOG_POS_OLD_INFO_SIZE;
2095 int2store(ptr_buffer, binlog_flags);
2096 ptr_buffer+= ::BINLOG_FLAGS_INFO_SIZE;
2097 int4store(ptr_buffer, server_id);
2098 ptr_buffer+= ::BINLOG_SERVER_ID_INFO_SIZE;
2099 memcpy(ptr_buffer, logname, BINLOG_NAME_INFO_SIZE);
2100 ptr_buffer+= BINLOG_NAME_INFO_SIZE;
2102 command_size= ptr_buffer - command_buffer;
2103 DBUG_ASSERT(command_size == (allocation_size - 1));
2107 command= COM_BINLOG_DUMP_GTID;
2109 global_sid_lock->
rdlock();
2113 size_t allocation_size=
2114 ::BINLOG_FLAGS_INFO_SIZE + ::BINLOG_SERVER_ID_INFO_SIZE +
2115 ::BINLOG_NAME_SIZE_INFO_SIZE + BINLOG_NAME_INFO_SIZE +
2116 ::BINLOG_POS_INFO_SIZE + ::BINLOG_DATA_SIZE_INFO_SIZE +
2117 encoded_data_size + 1;
2118 if (!(command_buffer= (uchar *) my_malloc(allocation_size, MYF(MY_WME))))
2120 error(
"Got fatal error allocating memory.");
2121 global_sid_lock->
unlock();
2122 DBUG_RETURN(ERROR_STOP);
2124 uchar* ptr_buffer= command_buffer;
2126 int2store(ptr_buffer, binlog_flags);
2127 ptr_buffer+= ::BINLOG_FLAGS_INFO_SIZE;
2128 int4store(ptr_buffer, server_id);
2129 ptr_buffer+= ::BINLOG_SERVER_ID_INFO_SIZE;
2130 int4store(ptr_buffer, BINLOG_NAME_INFO_SIZE);
2131 ptr_buffer+= ::BINLOG_NAME_SIZE_INFO_SIZE;
2132 memcpy(ptr_buffer, logname, BINLOG_NAME_INFO_SIZE);
2133 ptr_buffer+= BINLOG_NAME_INFO_SIZE;
2134 int8store(ptr_buffer, start_position);
2135 ptr_buffer+= ::BINLOG_POS_INFO_SIZE;
2136 int4store(ptr_buffer, encoded_data_size);
2137 ptr_buffer+= ::BINLOG_DATA_SIZE_INFO_SIZE;
2138 gtid_set_excluded->
encode(ptr_buffer);
2139 ptr_buffer+= encoded_data_size;
2141 global_sid_lock->
unlock();
2143 command_size= ptr_buffer - command_buffer;
2144 DBUG_ASSERT(command_size == (allocation_size - 1));
2147 if (simple_command(mysql, command, command_buffer, command_size, 1))
2149 error(
"Got fatal error sending the log dump command.");
2150 my_free(command_buffer);
2151 DBUG_RETURN(ERROR_STOP);
2153 my_free(command_buffer);
2157 const char *error_msg= NULL;
2161 len= cli_safe_read(mysql);
2162 if (len == packet_error)
2164 error(
"Got error reading packet from server: %s", mysql_error(mysql));
2165 DBUG_RETURN(ERROR_STOP);
2167 if (len < 8 && net->read_pos[0] == 254)
2169 DBUG_PRINT(
"info",(
"len: %lu net->read_pos[5]: %d\n",
2170 len, net->read_pos[5]));
2189 if (type == HEARTBEAT_LOG_EVENT)
2192 if (!raw_mode || (type == ROTATE_EVENT) || (type == FORMAT_DESCRIPTION_EVENT))
2194 if (!(ev= Log_event::read_log_event((
const char*) net->read_pos + 1 ,
2195 len - 1, &error_msg,
2196 glob_description_event,
2197 opt_verify_binlog_checksum)))
2199 error(
"Could not construct log event object: %s", error_msg);
2200 DBUG_RETURN(ERROR_STOP);
2206 ev->register_temp_buf((
char *) net->read_pos + 1);
2208 if (raw_mode || (type != LOAD_EVENT))
2219 if (type == ROTATE_EVENT)
2231 if (output_file != 0)
2233 my_snprintf(log_file_name,
sizeof(log_file_name),
"%s%s",
2234 output_file, rev->new_log_ident);
2238 strmov(log_file_name, rev->new_log_ident);
2242 if (rev->when.tv_sec == 0)
2244 if (!to_last_remote_log)
2246 if ((rev->ident_len != logname_len) ||
2247 memcmp(rev->new_log_ident, logname, logname_len))
2249 DBUG_RETURN(OK_CONTINUE);
2263 old_off= start_position_mot;
2267 else if (type == FORMAT_DESCRIPTION_EVENT)
2277 if ((old_off != BIN_LOG_HEADER_SIZE) && (!raw_mode))
2281 if (result_file && (result_file != stdout))
2282 my_fclose(result_file, MYF(0));
2283 if (!(result_file = my_fopen(log_file_name, O_WRONLY | O_BINARY,
2286 error(
"Could not create log file '%s'", log_file_name);
2287 DBUG_RETURN(ERROR_STOP);
2289 my_fwrite(result_file, (
const uchar*) BINLOG_MAGIC,
2290 BIN_LOG_HEADER_SIZE, MYF(0));
2295 delete glob_description_event;
2297 print_event_info->common_header_len= glob_description_event->common_header_len;
2303 if (type == LOAD_EVENT)
2305 DBUG_ASSERT(raw_mode);
2306 warning(
"Attempting to load a remote pre-4.0 binary log that contains "
2307 "LOAD DATA INFILE statements. The file will not be copied from "
2308 "the remote server. ");
2313 my_fwrite(result_file, net->read_pos + 1 , len - 1, MYF(0));
2322 retval= process_event(print_event_info, ev, old_off, logname);
2325 if (retval != OK_CONTINUE)
2326 DBUG_RETURN(retval);
2331 const char *old_fname= le->fname;
2332 uint old_len= le->fname_len;
2336 DBUG_RETURN(ERROR_STOP);
2338 retval= process_event(print_event_info, ev, old_off, logname);
2339 if (retval != OK_CONTINUE)
2341 my_close(file,MYF(MY_WME));
2342 DBUG_RETURN(retval);
2345 my_close(file,MYF(MY_WME));
2346 if (retval != OK_CONTINUE)
2347 DBUG_RETURN(retval);
2356 DBUG_RETURN(OK_CONTINUE);
2386 static Exit_status check_header(
IO_CACHE* file,
2387 PRINT_EVENT_INFO *print_event_info,
2388 const char* logname)
2390 DBUG_ENTER(
"check_header");
2391 uchar header[BIN_LOG_HEADER_SIZE];
2392 uchar
buf[PROBE_HEADER_LEN];
2393 my_off_t tmp_pos, pos;
2394 MY_STAT my_file_stat;
2396 delete glob_description_event;
2399 error(
"Failed creating Format_description_log_event; out of memory?");
2400 DBUG_RETURN(ERROR_STOP);
2403 pos= my_b_tell(file);
2406 if (my_fstat(file->file, &my_file_stat, MYF(0)) == -1)
2408 error(
"Unable to stat the file.");
2409 DBUG_RETURN(ERROR_STOP);
2411 if ((my_file_stat.st_mode & S_IFMT) == S_IFREG)
2412 my_b_seek(file, (my_off_t)0);
2414 if (my_b_read(file, header,
sizeof(header)))
2416 error(
"Failed reading header; probably an empty file.");
2417 DBUG_RETURN(ERROR_STOP);
2419 if (memcmp(header, BINLOG_MAGIC,
sizeof(header)))
2421 error(
"File is not a binary log file.");
2422 DBUG_RETURN(ERROR_STOP);
2440 tmp_pos= my_b_tell(file);
2441 if (my_b_read(file, buf,
sizeof(buf)))
2445 error(
"Could not read entry at offset %llu: "
2446 "Error in log format or read error.", (ulonglong)tmp_pos);
2447 DBUG_RETURN(ERROR_STOP);
2467 DBUG_PRINT(
"info",(
"buf[EVENT_TYPE_OFFSET=%d]=%d",
2468 EVENT_TYPE_OFFSET, buf[EVENT_TYPE_OFFSET]));
2470 if (buf[EVENT_TYPE_OFFSET] == START_EVENT_V3)
2473 if (uint4korr(buf + EVENT_LEN_OFFSET) <
2474 (LOG_EVENT_MINIMAL_HEADER_LEN + START_V3_HEADER_LEN))
2477 delete glob_description_event;
2480 error(
"Failed creating Format_description_log_event; "
2482 DBUG_RETURN(ERROR_STOP);
2487 else if (tmp_pos >= start_position)
2489 else if (buf[EVENT_TYPE_OFFSET] == FORMAT_DESCRIPTION_EVENT)
2493 my_b_seek(file, tmp_pos);
2495 Log_event::read_log_event(file, glob_description_event,
2496 opt_verify_binlog_checksum)))
2499 error(
"Could not read a Format_description_log_event event at "
2500 "offset %llu; this could be a log format error or read error.",
2501 (ulonglong)tmp_pos);
2502 DBUG_RETURN(ERROR_STOP);
2504 if (opt_base64_output_mode == BASE64_OUTPUT_AUTO)
2511 Exit_status retval= process_event(print_event_info,
2512 new_description_event, tmp_pos,
2514 if (retval != OK_CONTINUE)
2515 DBUG_RETURN(retval);
2519 delete glob_description_event;
2520 glob_description_event= new_description_event;
2522 DBUG_PRINT(
"info",(
"Setting description_event"));
2524 else if (buf[EVENT_TYPE_OFFSET] == ROTATE_EVENT)
2527 my_b_seek(file, tmp_pos);
2528 if (!(ev= Log_event::read_log_event(file, glob_description_event,
2529 opt_verify_binlog_checksum)))
2532 error(
"Could not read a Rotate_log_event event at offset %llu;"
2533 " this could be a log format error or read error.",
2534 (ulonglong)tmp_pos);
2535 DBUG_RETURN(ERROR_STOP);
2543 my_b_seek(file, pos);
2544 DBUG_RETURN(OK_CONTINUE);
2561 static Exit_status dump_local_log_entries(PRINT_EVENT_INFO *print_event_info,
2562 const char* logname)
2566 uchar tmp_buff[BIN_LOG_HEADER_SIZE];
2567 Exit_status retval= OK_CONTINUE;
2569 if (logname && strcmp(logname,
"-") != 0)
2572 if ((fd = my_open(logname, O_RDONLY | O_BINARY, MYF(MY_WME))) < 0)
2574 if (init_io_cache(file, fd, 0, READ_CACHE, start_position_mot, 0,
2575 MYF(MY_WME | MY_NABP)))
2577 my_close(fd, MYF(MY_WME));
2580 if ((retval= check_header(file, print_event_info, logname)) != OK_CONTINUE)
2594 #if defined (__WIN__) || (_WIN64)
2595 if (_setmode(fileno(stdin), O_BINARY) == -1)
2597 error(
"Could not set binary mode on stdin.");
2601 if (init_io_cache(file, my_fileno(stdin), 0, READ_CACHE, (my_off_t) 0,
2602 0, MYF(MY_WME | MY_NABP | MY_DONT_CHECK_FILESIZE)))
2604 error(
"Failed to init IO cache.");
2607 if ((retval= check_header(file, print_event_info, logname)) != OK_CONTINUE)
2612 uchar buff[IO_SIZE];
2613 my_off_t length,tmp;
2614 for (length= start_position_mot ; length > 0 ; length-=tmp)
2616 tmp= min<size_t>(length,
sizeof(buff));
2617 if (my_b_read(file, buff, (uint) tmp))
2619 error(
"Failed reading from file.");
2626 if (!glob_description_event || !glob_description_event->is_valid())
2628 error(
"Invalid Format_description log event; could be out of memory.");
2632 if (!start_position && my_b_read(file, tmp_buff, BIN_LOG_HEADER_SIZE))
2634 error(
"Failed reading from file.");
2640 my_off_t old_off = my_b_tell(file);
2642 Log_event* ev = Log_event::read_log_event(file, glob_description_event,
2643 opt_verify_binlog_checksum);
2650 if (glob_description_event->
flags & LOG_EVENT_BINLOG_IN_USE_F)
2652 else if (file->error)
2654 error(
"Could not read entry at offset %s: "
2655 "Error in log format or read error.",
2656 llstr(old_off,llbuff));
2662 if ((retval= process_event(print_event_info, ev, old_off, logname)) !=
2674 my_close(fd, MYF(MY_WME));
2679 if (end_io_cache(file))
2686 static int args_post_process(
void)
2688 DBUG_ENTER(
"args_post_process");
2690 if (opt_remote_alias && opt_remote_proto != BINLOG_DUMP_NON_GTID)
2692 error(
"The option read-from-remote-server cannot be used when "
2693 "read-from-remote-master is defined and is not equal to "
2694 "BINLOG-DUMP-NON-GTIDS");
2695 DBUG_RETURN(ERROR_STOP);
2701 warning(
"The --database option is ignored with --raw mode");
2703 if (opt_remote_proto == BINLOG_LOCAL)
2705 error(
"You need to set --read-from-remote-master={BINLOG_DUMP_NON_GTID, "
2706 "BINLOG_DUMP_GTID} for --raw mode");
2707 DBUG_RETURN(ERROR_STOP);
2710 if (opt_remote_proto == BINLOG_DUMP_NON_GTID &&
2711 (opt_exclude_gtids_str != NULL || opt_include_gtids_str != NULL))
2713 error(
"You cannot set --exclude-gtids or --include-gtids for --raw-mode "
2714 "when --read-from-remote-master=BINLOG_DUMP_NON_GTID");
2715 DBUG_RETURN(ERROR_STOP);
2718 if (opt_remote_proto == BINLOG_DUMP_GTID && opt_include_gtids_str != NULL)
2720 error(
"You cannot set --include-gtids for --raw-mode "
2721 "when --read-from-remote-master=BINLOG_DUMP_GTID for");
2722 DBUG_RETURN(ERROR_STOP);
2725 if (stop_position != (ulonglong)(~(my_off_t)0))
2726 warning(
"The --stop-position option is ignored in raw mode");
2728 if (stop_datetime != MY_TIME_T_MAX)
2729 warning(
"The --stop-datetime option is ignored in raw mode");
2731 else if (output_file)
2733 if (!(result_file = my_fopen(output_file, O_WRONLY | O_BINARY, MYF(MY_WME))))
2735 error(
"Could not create log file '%s'", output_file);
2736 DBUG_RETURN(ERROR_STOP);
2740 global_sid_lock->
rdlock();
2742 if (opt_include_gtids_str != NULL)
2744 if (gtid_set_included->
add_gtid_text(opt_include_gtids_str) !=
2747 error(
"Could not configure --include-gtids '%s'", opt_include_gtids_str);
2748 global_sid_lock->
unlock();
2749 DBUG_RETURN(ERROR_STOP);
2753 if (opt_exclude_gtids_str != NULL)
2755 if (gtid_set_excluded->
add_gtid_text(opt_exclude_gtids_str) !=
2758 error(
"Could not configure --exclude-gtids '%s'", opt_exclude_gtids_str);
2759 global_sid_lock->
unlock();
2760 DBUG_RETURN(ERROR_STOP);
2764 global_sid_lock->
unlock();
2766 DBUG_RETURN(OK_CONTINUE);
2773 inline void gtid_client_cleanup()
2775 delete global_sid_lock;
2776 delete global_sid_map;
2777 delete gtid_set_excluded;
2778 delete gtid_set_included;
2779 global_sid_lock= NULL;
2780 global_sid_map= NULL;
2781 gtid_set_excluded= NULL;
2782 gtid_set_included= NULL;
2791 inline bool gtid_client_init()
2795 !(global_sid_map=
new Sid_map(global_sid_lock)) ||
2796 !(gtid_set_excluded=
new Gtid_set(global_sid_map)) ||
2797 !(gtid_set_included=
new Gtid_set(global_sid_map)));
2800 gtid_client_cleanup();
2805 int main(
int argc,
char** argv)
2807 char **defaults_argv;
2808 Exit_status retval= OK_CONTINUE;
2809 ulonglong save_stop_position;
2812 DBUG_PROCESS(argv[0]);
2825 INTVAR_DYNAMIC_INIT, INTVAR_DYNAMIC_INCR)))
2828 my_getopt_use_args_separator= TRUE;
2829 if (load_defaults(
"my", load_default_groups, &argc, &argv))
2831 my_getopt_use_args_separator= FALSE;
2832 defaults_argv= argv;
2834 parse_args(&argc, &argv);
2839 free_defaults(defaults_argv);
2844 if (gtid_client_init())
2846 error(
"Could not initialize GTID structuress.");
2851 if (args_post_process() == ERROR_STOP)
2854 if (opt_base64_output_mode == BASE64_OUTPUT_UNSPEC)
2855 opt_base64_output_mode= BASE64_OUTPUT_AUTO;
2857 opt_server_id_mask = (opt_server_id_bits == 32)?
2858 ~ ulong(0) : (1 << opt_server_id_bits) -1;
2860 my_set_max_open_files(open_files_limit);
2864 if (!dirname_for_local_load)
2866 if (init_tmpdir(&tmpdir, 0))
2868 dirname_for_local_load= my_strdup(my_tmpdir(&tmpdir), MY_WME);
2871 if (load_processor.init())
2873 if (dirname_for_local_load)
2874 load_processor.init_by_dir_name(dirname_for_local_load);
2876 load_processor.init_by_cur_dir();
2880 fprintf(result_file,
"/*!50530 SET @@SESSION.PSEUDO_SLAVE_MODE=1*/;\n");
2882 fprintf(result_file,
2883 "/*!40019 SET @@session.max_insert_delayed_threads=0*/;\n");
2885 if (disable_log_bin)
2886 fprintf(result_file,
2887 "/*!32316 SET @OLD_SQL_LOG_BIN=@@SQL_LOG_BIN, SQL_LOG_BIN=0*/;\n");
2893 fprintf(result_file,
2894 "/*!50003 SET @OLD_COMPLETION_TYPE=@@COMPLETION_TYPE,"
2895 "COMPLETION_TYPE=0*/;\n");
2898 fprintf(result_file,
2899 "\n/*!40101 SET @OLD_CHARACTER_SET_CLIENT=@@CHARACTER_SET_CLIENT */;"
2900 "\n/*!40101 SET @OLD_CHARACTER_SET_RESULTS=@@CHARACTER_SET_RESULTS */;"
2901 "\n/*!40101 SET @OLD_COLLATION_CONNECTION=@@COLLATION_CONNECTION */;"
2902 "\n/*!40101 SET NAMES %s */;\n", charset);
2905 for (save_stop_position= stop_position, stop_position= ~(my_off_t)0 ;
2909 stop_position= save_stop_position;
2910 if ((retval= dump_log_entries(*argv++)) != OK_CONTINUE)
2914 start_position= BIN_LOG_HEADER_SIZE;
2923 fprintf(result_file,
2924 "# End of log file\nROLLBACK /* added by mysqlbinlog */;\n"
2925 "/*!50003 SET COMPLETION_TYPE=@OLD_COMPLETION_TYPE*/;\n");
2926 if (disable_log_bin)
2927 fprintf(result_file,
"/*!32316 SET SQL_LOG_BIN=@OLD_SQL_LOG_BIN*/;\n");
2930 fprintf(result_file,
2931 "/*!40101 SET CHARACTER_SET_CLIENT=@OLD_CHARACTER_SET_CLIENT */;\n"
2932 "/*!40101 SET CHARACTER_SET_RESULTS=@OLD_CHARACTER_SET_RESULTS */;\n"
2933 "/*!40101 SET COLLATION_CONNECTION=@OLD_COLLATION_CONNECTION */;\n");
2935 fprintf(result_file,
"/*!50530 SET @@SESSION.PSEUDO_SLAVE_MODE=0*/;\n");
2939 free_tmpdir(&tmpdir);
2940 if (result_file && (result_file != stdout))
2941 my_fclose(result_file, MYF(0));
2945 free_defaults(defaults_argv);
2946 my_free_open_file_info();
2947 load_processor.destroy();
2949 my_end(my_end_arg | MY_DONT_FREE_DBUG);
2950 gtid_client_cleanup();
2952 exit(retval == ERROR_STOP ? 1 : 0);
2954 DBUG_RETURN(retval == ERROR_STOP ? 1 : 0);
2962 #include "decimal.c"
2963 #include "my_decimal.cc"
2964 #include "log_event.cc"
2965 #include "log_event_old.cc"
2966 #include "rpl_utility.cc"
2967 #include "rpl_gtid_sid_map.cc"
2968 #include "rpl_gtid_misc.cc"
2970 #include "rpl_gtid_set.cc"
2971 #include "rpl_gtid_specification.cc"
2972 #include "rpl_tblmap.cc"