#define VER "3.5" #define MYSQL_CLIENT #undef MYSQL_SERVER #define TABLE TABLE_CLIENT /* This hack is here to avoid adding COMPRESSED data types to libmariadb. */ #define MYSQL_TYPE_TIME2 MYSQL_TYPE_TIME2,MYSQL_TYPE_BLOB_COMPRESSED=140,MYSQL_TYPE_VARCHAR_COMPRESSED=141 #include"client_priv.h" #undef MYSQL_TYPE_TIME2 #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"sql_basic_types.h" #include <atomic> #include"handler_binlog_reader.h" #include"mysqlbinlog-engine.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 #include"rpl_gtid.h" #include"sql_string.h"// needed for Rpl_filter #include"sql_list.h"// needed for Rpl_filter #include"rpl_filter.h" #include"charset_collations.h"
/* Needed for Rpl_filter */
CHARSET_INFO* system_charset_info= &my_charset_utf8mb3_general_ci;
/* Needed for Flashback */
DYNAMIC_ARRAY binlog_events; // Storing the events output string
DYNAMIC_ARRAY events_in_stmt; // Storing the events that in one statement
String stop_event_string; // Storing the STOP_EVENT output string
/** Exitstatusforfunctionsinthisfile.
*/ enum Exit_status { /** No error occurred and execution should continue. */
OK_CONTINUE= 0, /** An error occurred and execution should stop. */
ERROR_STOP, /** No error occurred but execution should stop. */
OK_STOP, /** No error occurred - end of file reached. */
OK_EOF,
};
if (fname)
{
File file;
Exit_status retval= OK_CONTINUE; if (((file= my_open(fname,
O_APPEND|O_BINARY|O_WRONLY,MYF(MY_WME))) < 0))
{
error("Failed opening file %s", fname);
DBUG_RETURN(ERROR_STOP);
} if (my_write(file,(uchar*)ae->block,ae->block_len,MYF(MY_WME|MY_NABP)))
{
error("Failed writing to file %s", fname);
retval= ERROR_STOP;
} if (my_close(file,MYF(MY_WME)))
{
error("Failed closing file %s", fname);
retval= ERROR_STOP;
}
DBUG_RETURN(retval);
}
/* ThereisnoCreate_fileevent(abadbinlogorabig --start-position).Assumingit'sabig--start-position,wejustdo nothingandprintawarning.
*/
warning("Ignoring Append_block as there is no " "Create_file event for file_id: %u", ae->file_id);
DBUG_RETURN(OK_CONTINUE);
}
// pinfo->db is the current db. // If current db is the same as required db, do nothing. if ((ev->flags & LOG_EVENT_SUPPRESS_USE_F) || !db ||
!memcmp(pinfo->db, db, db_len + 1)) return;
// Current db and required db are different. // Check for rewrite rule for required db. (Note that in a rewrite rule // neither db_from nor db_to part can be empty).
size_t len_to= 0; constchar *db_to= binlog_filter->get_rewrite_db(db, &len_to);
// If there is no rewrite rule for db (in this case len_to is left = 0), // printing of the corresponding USE statement is left for log event // print-function. if (!len_to) return;
// In case of rewrite rule print USE statement for db_to
my_fprintf(result_file, "use %sQ%s\n", db_to, pinfo->delimiter);
// Copy the *original* db to pinfo to suppress emitting // of USE stmts by log_event print-functions.
memcpy(pinfo->db, db, db_len + 1);
}
if (binlog_format == ORIGINAL_BINLOG_FORMAT &&
!print_event_info->printed_fd_event && !short_form &&
opt_base64_output_mode != BASE64_OUTPUT_DECODE_ROWS &&
opt_base64_output_mode != BASE64_OUTPUT_NEVER)
{ constchar* type_str= ev->get_type_str();
error("malformed binlog: it does not contain any " "Format_description_log_event. Found a %s event, which " "is not safe to process without a " "Format_description_log_event.",
type_str); return1;
}
if (print_event_info->m_table_map_ignored.get_table(table_id))
print_event_info->deactivate_current_partial_rows_ev_group();
}
if (print_event_info->is_partial_rows_ev_group_active())
result= prle->print(result_file, print_event_info);
/* Last fragment */ if (prle->seq_no == prle->total_fragments)
{ /* IfthisisthelastPartial_rows_log_eventinthegroupandthe underlyingRows_log_eventisthelastinthetransaction,thenitissafe toclearthetable_mapsbecausetheywon'tbeusedagain.
*/ if (print_event_info->partial_rows_rows_ev_flags &
Rows_log_event::STMT_END_F)
print_event_info->m_table_map_ignored.clear_tables();
if (opt_flashback)
{
Rows_log_event *e= (Rows_log_event*) ev; // The last Row_log_event will be the first event in Flashback if (is_stmt_end)
e->clear_flags(Rows_log_event::STMT_END_F); // The first Row_log_event will be the last event in Flashback if (events_in_stmt.elements == 0)
e->set_flags(Rows_log_event::STMT_END_F); // Update the temp_buf
e->update_flags();
if (insert_dynamic(&events_in_stmt, (uchar *) &ev))
{
error("Out of memory: can't allocate memory to store the flashback events."); exit(1);
}
}
/* skip the event check */ if (skip_event) return0;
if (!opt_flashback)
result= print_base64(print_event_info, ev); else
{ if (is_stmt_end)
{
Log_event *e= NULL;
// Print the row_event from the last one to the first one for (size_t i= events_in_stmt.elements; i > 0; --i)
{
e= *(dynamic_element(&events_in_stmt, i - 1, Log_event**)); if ((result= print_base64(print_event_info, e))) break;
} // Copy all output into the Log_event if (!result)
ev->output_buf.copy(e->output_buf); // Delete Log_event for (size_t i= 0; i < events_in_stmt.elements-1; ++i)
{
e= *(dynamic_element(&events_in_stmt, i, Log_event**)); delete e;
}
reset_dynamic(&events_in_stmt); if (result) return result;
}
}
if (is_stmt_end && !result)
{ if (print_event_info->print_row_count)
fprintf(result_file, "# Number of rows: %s\n",
llstr(print_event_info->row_events, ll_buff));
print_event_info->row_events= 0;
} return result;
}
/* Checkiftheserveridshouldbeexcludedfromtheoutput.
*/ staticinline my_bool is_server_id_excluded(uint32 server_id)
{ static rpl_gtid server_tester_gtid;
server_tester_gtid.server_id= server_id; return server_id_gtid_filter == NULL
? FALSE// No server id filter exists
: server_id_gtid_filter->exclude(&server_tester_gtid);
}
#ifdef WHEN_FLASHBACK_REVIEW_READY /* Create review table for Flashback */ if (opt_flashback_review)
{ // Check if the table was already created?
Table_map_log_event *exist_table;
exist_table= print_event_info->m_table_map.get_table(map->get_table_id());
if (!exist_table)
{
MYSQL *conn;
MYSQL_RES *res;
MYSQL_ROW row; char tmp_sql[8096]; int tmp_sql_offset;
/* TheTablemapistobeprinted,soit'sjustthetimewhenwemay printthekeptAnnotateevent(ifthereisany). print_annotate_event()alsodeletesthekeptAnnotateevent.
*/ if (print_annotate_event(print_event_info)) goto err;
size_t len_to= 0; constchar* db_to= binlog_filter->get_rewrite_db(map->get_db_name(), &len_to); if (len_to && map->rewrite_db(db_to, len_to, glob_description_event))
{
error("Could not rewrite database name"); goto err;
} if (print_base64(print_event_info, ev)) goto err; if (opt_flashback)
reset_dynamic(&events_in_stmt); break;
} 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: case WRITE_ROWS_COMPRESSED_EVENT: case DELETE_ROWS_COMPRESSED_EVENT: case UPDATE_ROWS_COMPRESSED_EVENT: case WRITE_ROWS_COMPRESSED_EVENT_V1: case UPDATE_ROWS_COMPRESSED_EVENT_V1: case DELETE_ROWS_COMPRESSED_EVENT_V1:
{
Rows_log_event *e= (Rows_log_event*) ev; bool is_stmt_end= e->get_flags(Rows_log_event::STMT_END_F); if (!print_event_info->found_row_event)
{
print_event_info->found_row_event= 1;
print_event_info->row_events= 0;
} if (print_row_event(print_event_info, ev, e->get_table_id(),
e->get_flags(Rows_log_event::STMT_END_F))) goto err;
DBUG_PRINT("info", ("is_stmt_end: %d", (int) is_stmt_end)); if (is_stmt_end)
print_event_info->found_row_event= 0; elseif (opt_flashback)
destroy_evt= FALSE; break;
} case PARTIAL_ROW_DATA_EVENT:
{ if (print_partial_row_event(print_event_info, ev)) goto err; break;
} case START_ENCRYPTION_EVENT:
glob_description_event->start_decryption((Start_encryption_log_event*)ev); /* fall through */ case PRE_GA_WRITE_ROWS_EVENT: case PRE_GA_DELETE_ROWS_EVENT: case PRE_GA_UPDATE_ROWS_EVENT: case CREATE_FILE_EVENT: case EXEC_LOAD_EVENT: default:
print_skip_replication_statement(print_event_info, ev); if (ev->print(result_file, print_event_info)) goto err;
}
}
if (opt_flashback)
{ if (ev_type == STOP_EVENT)
stop_event_string.reset(tmp_str.str, tmp_str.length, tmp_str.length,
&my_charset_bin); else
{ if (insert_dynamic(&binlog_events, (uchar *) &tmp_str))
{
error("Out of memory: can't allocate memory to store the flashback events."); exit(1);
}
}
} else
{
my_fwrite(result_file, (const uchar *) tmp_str.str, tmp_str.length,
MYF(MY_NABP));
fflush(result_file);
my_free(tmp_str.str);
}
}
if (destroy_evt) /* destroy it later if not set (ignored table map) */ delete ev;
}
DBUG_PRINT("exit",("return: %d", retval));
DBUG_RETURN(retval);
}
staticstruct my_option my_options[] =
{
{"help", '?', "Display this help and exit.", 0, 0, 0, GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0},
{"base64-output", OPT_BASE64_OUTPUT_MODE, /* 'unspec' is not mentioned because it is just a placeholder. */ "Determine when the output statements should be base64-encoded BINLOG " "statements: " "‘never’ neither prints base64 encodings nor verbose event data, and " "will exit on error if a row-based event is found. " "'decode-rows' decodes row events into commented SQL statements if the " "--verbose option is also given. " "‘auto’ outputs base64 encoded entries for row-based and format " "description events. " "If no option is given at all, the default is ‘auto', and is " "consequently the only option that should be used when row-format events " "are processed for re-execution.",
&opt_base64_output_mode_str, &opt_base64_output_mode_str, 0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0}, /* mysqlbinlogneedscharsetsknowledge,tobeabletoconvertacharset numberfoundinbinlogtoacharsetname(tobeabletoprintthings likethis: SET@`a`:=_cp8500x4DFC6C6C6572COLLATE`cp850_general_ci`;
*/
{"character-sets-dir", 0, "Directory for character set files.", &charsets_dir,
&charsets_dir, 0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
{"database", 'd', "List entries for just this database (local log only).",
&database, &database, 0, GET_STR_ALLOC, REQUIRED_ARG, 0, 0, 0, 0, 0, 0}, #ifndef DBUG_OFF
{"debug", '#', "Output debug log.", ¤t_dbug_option,
¤t_dbug_option, 0, GET_STR, OPT_ARG, 0, 0, 0, 0, 0, 0}, #endif
{"debug-check", 0, "Check memory and open file usage at exit .",
&debug_check_flag, &debug_check_flag, 0,
GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0},
{"debug-info", 0, "Print some debug info at exit.",
&debug_info_flag, &debug_info_flag, 0, GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0},
{"default_auth", 0, "Default authentication client-side plugin to use.",
&opt_default_auth, &opt_default_auth, 0,
GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
{"disable-log-bin", 'D', "Disable binary log. This is useful, if you " "enabled --to-last-log and are sending the output to the same MariaDB server. " "This way you could avoid an endless loop. You would also like to use it " "when restoring after a crash to avoid duplication of the statements you " "already have. NOTE: you will need a SUPER privilege to use this option.",
&disable_log_bin, &disable_log_bin, 0, GET_BOOL,
NO_ARG, 0, 0, 0, 0, 0, 0},
{"flashback", 'B', "Flashback feature can rollback you committed data to a special time point.", #ifdef WHEN_FLASHBACK_REVIEW_READY "before Flashback feature writing a row, original row can insert to review-dbname.review-tablename," "and mysqlbinlog will login mysql by user(-u) and password(-p) and host(-h).", #endif
&opt_flashback, &opt_flashback, 0, GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0},
{"force-if-open", 'F', "Force if binlog was not closed properly.",
&force_if_open_opt, &force_if_open_opt, 0, GET_BOOL, NO_ARG, 1, 0, 0, 0, 0, 0},
{"force-read", 'f', "Force reading unknown binlog events.",
&force_opt, &force_opt, 0, GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0},
{"hexdump", 'H', "Augment output with hexadecimal and ASCII event dump.",
&opt_hexdump, &opt_hexdump, 0, GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0},
{"host", 'h', "Get the binlog from server. Defaults in the following order: " "$MARIADB_HOST, and then localhost",
&host, &host, 0, GET_STR_ALLOC, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
{"local-load", 'l', "Prepare local temporary files for LOAD DATA INFILE in the specified directory.",
&dirname_for_local_load, &dirname_for_local_load, 0,
GET_STR_ALLOC, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
{"offset", 'o', "Skip the first N entries.", &offset, &offset, 0, GET_ULL, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
{"password", 'p', "Password to connect to remote server.", 0, 0, 0, GET_STR, OPT_ARG, 0, 0, 0, 0, 0, 0},
{"plugin_dir", 0, "Directory for client-side plugins.",
&opt_plugindir, &opt_plugindir, 0,
GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
{"port", 'P', "Port number to use for connection or 0 for default to, in " "order of preference, my.cnf, $MYSQL_TCP_PORT, " #if MYSQL_PORT_DEFAULT == 0 "/etc/services, " #endif "built-in default (" STRINGIFY_ARG(MYSQL_PORT) ").",
&opt_mysql_port, &opt_mysql_port, 0, GET_INT, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
{"protocol", OPT_MYSQL_PROTOCOL, "The protocol to use for connection (tcp, socket, pipe).", 0, 0, 0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
{"read-from-remote-server", 'R', "Read binary logs from a MariaDB server.",
&remote_opt, &remote_opt, 0, GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0},
{"raw", 0, "Requires -R. Output raw binlog data instead of SQL " "statements. Output files named after server logs.",
&opt_raw_mode, &opt_raw_mode, 0, GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0},
{"result-file", 'r', "Direct output to a given file. With --raw this is a " "prefix for the file names.",
&result_file_name, &result_file_name, 0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0}, #ifdef WHEN_FLASHBACK_REVIEW_READY
{"review", 0, "Print review sql in output file.",
&opt_flashback_review, &opt_flashback_review, 0, GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0},
{"review-dbname", 0, "Writing flashback original row data into this db",
&flashback_review_dbname, &flashback_review_dbname, 0, GET_STR_ALLOC, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
{"review-tablename", 0, "Writing flashback original row data into this table",
&flashback_review_tablename, &flashback_review_tablename, 0, GET_STR_ALLOC, REQUIRED_ARG, 0, 0, 0, 0, 0, 0}, #endif
{"print-row-count", OPT_PRINT_ROW_COUNT, "Print row counts for each row events",
&print_row_count, &print_row_count, 0, GET_BOOL, NO_ARG, 1, 0, 0, 0, 0, 0},
{"print-row-event-positions", OPT_PRINT_ROW_EVENT_POSITIONS, "Print row event positions",
&print_row_event_positions, &print_row_event_positions, 0, GET_BOOL,
NO_ARG, 1, 0, 0, 0, 0, 0},
{"ignore-domain-ids", OPT_IGNORE_DOMAIN_IDS, "A list of positive integers, separated by commas, that form a blacklist " "of domain ids. Any log event with a GTID that originates from a domain id " "specified in this list is hidden. Cannot be used with " "--do-domain-ids. When used with --(ignore|do)-server-ids, the result is the " "intersection between the two datasets.",
&ignore_domain_ids_str, &ignore_domain_ids_str, 0, GET_STR_ALLOC,
REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
{"do-domain-ids", OPT_DO_DOMAIN_IDS, "A list of positive integers, separated by commas, that form a whitelist " "of domain ids. Any log event with a GTID that originates from a domain id " "specified in this list is displayed. Cannot be used with " "--ignore-domain-ids. When used with --(ignore|do)-server-ids, the result " "is the intersection between the two datasets.",
&do_domain_ids_str, &do_domain_ids_str, 0, GET_STR_ALLOC, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
{"ignore-server-ids", OPT_IGNORE_SERVER_IDS, "A list of positive integers, separated by commas, that form a blacklist " "of server ids. Any log event originating from a server id " "specified in this list is hidden. Cannot be used with " "--do-server-ids. When used with --(ignore|do)-domain-ids, the result is " "the intersection between the two datasets.",
&ignore_server_ids_str, &ignore_server_ids_str, 0, GET_STR_ALLOC,
REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
{"do-server-ids", OPT_DO_SERVER_IDS, "A list of positive integers, separated by commas, that form a whitelist " "of server ids. Any log event originating from a server id " "specified in this list is displayed. Cannot be used with " "--ignore-server-ids. When used with --(ignore|do)-domain-ids, the result " "is the intersection between the two datasets. Alias for --server-id.",
&do_server_ids_str, &do_server_ids_str, 0, GET_STR_ALLOC,
REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
{"server-id", OPT_SERVER_ID, "Extract only binlog entries created by the server having the given id. " "Alias for --do-server-ids.",
&server_id_str, &server_id_str, 0, GET_STR_ALLOC,
REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
{"set-charset", 0, "Add 'SET NAMES character_set' to the output.", &charset,
&charset, 0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
{"short-form", 's', "Just show regular queries: no extra info, no " "row-based events and no row counts. This is mainly for testing only, " "and should not be used to feed to the MariaDB server. " "If you want to just suppress base64-output, you can instead " "use --base64-output=never",
&short_form, &short_form, 0, GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0},
{"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 " "in the local time zone, in any format accepted by the MariaDB server " "for DATETIME and TIMESTAMP types, for example: 2004-12-25 11:25:56 " "(you should probably use quotes for your shell to set it properly).",
&start_datetime_str, &start_datetime_str, 0, GET_STR_ALLOC, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
{"start-position", 'j', "Start reading the binlog at this position. Type can either be a positive " "integer or a GTID list. When using a positive integer, the value only " "applies to the first binlog passed on the command line. In GTID mode, " "multiple GTIDs can be passed as a comma separated list, where each must " "have a unique domain id. The list represents the gtid binlog state that " "the client (another \"slave\" server) is aware of. Therefore, each GTID " "is exclusive; only events after a given sequence number will be printed to " "allow users to receive events after their current state.",
&start_pos_str, &start_pos_str, 0, GET_STR_ALLOC, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
{"gtid-strict-mode", 0, "Process binlog according to gtid-strict-mode " "specification. The start, stop positions are verified to satisfy " "start < stop comparison condition. Sequence numbers of any gtid domain " "must comprise monotically growing sequence",
&opt_gtid_strict_mode, &opt_gtid_strict_mode, 0,
GET_BOOL, NO_ARG, 1, 0, 0, 0, 0, 0},
{"stop-datetime", OPT_STOP_DATETIME, "Stop reading the binlog at first event having a datetime equal or " "posterior to the argument; the argument must be a date and time " "in the local time zone, in any format accepted by the MariaDB server " "for DATETIME and TIMESTAMP types, for example: 2004-12-25 11:25:56 " "(you should probably use quotes for your shell to set it properly).",
&stop_datetime_str, &stop_datetime_str, 0, GET_STR_ALLOC, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
{"stop-never", 0, "Wait for more data from the server " "instead of stopping at the end of the last log. Implies --to-last-log.",
&opt_stop_never, &opt_stop_never, 0,
GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0},
{"stop-never-slave-server-id", 0, "The slave server_id used for --read-from-remote-server --stop-never.",
&opt_stop_never_slave_server_id, &opt_stop_never_slave_server_id, 0,
GET_ULONG, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
{"stop-position", OPT_STOP_POSITION, "Stop reading the binlog at this position. Type can either be a positive " "integer or a GTID list. When using a positive integer, the value only " "applies to the last binlog passed on the command line. In GTID mode, " "multiple GTIDs can be passed as a comma separated list, where each must " "have a unique domain id. Each GTID is inclusive; only events up to the " "given sequence numbers are printed.",
&stop_pos_str, &stop_pos_str, 0, GET_STR_ALLOC, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
{"table", 'T', "List entries for just this table (affects only row events).",
&table, &table, 0, GET_STR_ALLOC, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
{"to-last-log", 't', "Requires -R. Will not stop at the end of the \
requested binlog but rather continue printing until the end of the last \
binlog of the MariaDB server. If you send the output to the same MariaDB server, \
that may lead to an endless loop.",
&to_last_remote_log, &to_last_remote_log, 0, GET_BOOL,
NO_ARG, 0, 0, 0, 0, 0, 0},
{"user", 'u', "Connect to the remote server as username.",
&user, &user, 0, GET_STR_ALLOC, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
{"verbose", 'v', "Reconstruct SQL statements out of row events. " "-v -v adds comments on column data types. " "-v -v -v adds diagnostic warnings about event " "integrity before program exit.", 0, 0, 0, GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0},
{"version", 'V', "Print version and exit.", 0, 0, 0, GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0},
{"open_files_limit", 0, "Used to reserve file descriptors for use by this program.",
&open_files_limit, &open_files_limit, 0, GET_ULONG,
REQUIRED_ARG, MY_NFILE, 8, OS_FILE_LIMIT, 0, 1, 0},
{"binlog-row-event-max-size", 0, "The maximum size of a row-based binary log event in bytes. Rows will be " "grouped into events smaller than this size if possible. " "This value must be a multiple of 256.",
&opt_binlog_rows_event_max_size, &opt_binlog_rows_event_max_size, 0,
GET_ULONG, REQUIRED_ARG, UINT_MAX, 256, ULONG_MAX, 0, 256, 0}, #ifndef DBUG_OFF
{"debug-binlog-row-event-max-encoded-size", 0, "The maximum size of base64-encoded rows-event in one BINLOG pseudo-query " "instance. When the computed actual size exceeds the limit " "the BINLOG's argument string is fragmented in two.",
&opt_binlog_rows_event_max_encoded_size,
&opt_binlog_rows_event_max_encoded_size, 0,
GET_ULONG, REQUIRED_ARG, UINT_MAX/4, 256, ULONG_MAX, 0, 256, 0}, #endif
{"verify-binlog-checksum", 'c', "Verify binlog event checksums.",
(uchar**) &opt_verify_binlog_checksum, (uchar**) &opt_verify_binlog_checksum, 0, GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0},
{"rewrite-db", OPT_REWRITE_DB, "Updates to a database with a different name than the original. \
Example: rewrite-db='from->to'.", 0, 0, 0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
{"skip-annotate-row-events", 0, "Don't print Annotate_rows events stored in the binary log.",
(uchar**) &opt_skip_annotate_row_events,
(uchar**) &opt_skip_annotate_row_events, 0, GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0},
{"print-table-metadata", 0, "Print metadata stored in Table_map_log_event",
&opt_print_table_metadata, &opt_print_table_metadata, 0,
GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0},
{0, 0, 0, 0, 0, 0, GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0}
};
staticvoid usage()
{
print_version();
puts(ORACLE_WELCOME_COPYRIGHT_NOTICE("2000"));
printf("\
Dumps a MariaDB binary log in a format usable for viewing orfor piping to\n\
the mysql command line client.\n\n");
printf("Usage: %s [options] log-files\n", my_progname);
print_defaults("my",load_groups);
puts("");
my_print_help(my_options);
my_print_variables(my_options);
}
if (gtid_list == NULL)
{ int err= 0; char *end_ptr= NULL; /* NoGTIDsspecifiedinpositionspecification.Treatthevalue asasingularindex.
*/
*fallback= my_strtoll10(option_val, &end_ptr, &err);
if (err || *end_ptr)
{ // Can't parse the position from the user
sql_print_error("%s argument value is invalid. Should be either a " "positive integer or GTID.",
option_name); return1;
}
} elseif (n_gtids > 0)
{
uint32 gtid_idx;
if (position_gtid_filter == NULL)
position_gtid_filter= new Domain_gtid_event_filter();
if (id_list == NULL)
{
DBUG_ASSERT(n_ids == 0);
sql_print_error( "Input for %s is invalid. Should be a list of positive integers",
option_name); return1;
}
if (!(*filter))
(*filter)= new T();
int err= (*filter)->set_id_restrictions(id_list, n_ids, mode);
my_free(id_list); return err;
}
switch (opt->id) { #ifndef DBUG_OFF case'#': if (!argument)
argument= (char*) default_dbug_option;
current_dbug_option= argument;
DBUG_PUSH(argument); break; #endif #include <sslopt-case.h> case'B':
opt_flashback= 1; break; case'd':
one_database = 1; break; case'p': if (argument == disabled_my_option)
argument= (char*) ""; // Don't require password if (argument)
{ /* Oneshouldnotreallychangetheargument,butwemakean exceptionforpasswords
*/
my_free(opt_password); char *start= (char*) argument;
opt_password= my_strdup(PSI_NOT_INSTRUMENTED, argument,MYF(MY_FAE)); while (*argument)
*(char*)argument++= 'x'; /* Destroy argument */ if (*start)
start[1]=0; /* Cut length of argument */
} else
tty_password=1; break; case'R':
remote_opt= 1; break; case'T':
one_table= 1; break; case OPT_MYSQL_PROTOCOL: if ((opt_protocol= find_type_with_warning(argument, &sql_protocol_typelib,
opt->name)) <= 0)
{
sf_leaking_memory= 1; /* no memory leak reports here */
die(1);
} break; case OPT_START_DATETIME:
start_datetime= convert_str_to_timestamp(start_datetime_str); break; case OPT_STOP_DATETIME:
stop_datetime= convert_str_to_timestamp(stop_datetime_str);
stop_datetime_given= true; break; case OPT_BASE64_OUTPUT_MODE: int val;
if ((val= find_type_with_warning(argument, &base64_output_mode_typelib,
opt->name)) <= 0)
{
sf_leaking_memory= 1; /* no memory leak reports here */
die(1);
}
opt_base64_output_mode= (enum_base64_output_mode)(val - 1); break; case OPT_REWRITE_DB: // db_from->db_to
{ /* See also handling of OPT_REPLICATE_REWRITE_DB in sql/mysqld.cc */ if (binlog_filter->add_rewrite_db(argument))
{
sql_print_error("Bad syntax in rewrite-db. Expected syntax is FROM->TO."); return1;
} break;
} case OPT_PRINT_ROW_COUNT:
print_row_count_used= 1; break; case OPT_PRINT_ROW_EVENT_POSITIONS:
print_row_event_positions_used= 1; break; case'P': if (filename[0] == '\0')
{ /* Port given on command line, switch protocol to use TCP */
opt_protocol= MYSQL_PROTOCOL_TCP;
} break; case'S': if (filename[0] == '\0')
{ /* Socketgivenoncommandline,switchprotocoltouseSOCKETSt ExceptonWindowsif'protocol=pipe'hasbeenprovidedin theconfigfileorcommandline.
*/ if (opt_protocol != MYSQL_PROTOCOL_PIPE)
{
opt_protocol= MYSQL_PROTOCOL_SOCKET;
}
} break; case'v': if (argument == disabled_my_option)
verbose= 0; else
verbose++; break; case'V':
print_version();
opt_version= 1; break; case OPT_STOP_POSITION:
{ /* Stop position was already specified, so reset it and use the new list */ if (position_gtid_filter &&
position_gtid_filter->get_num_stop_gtids() > 0)
position_gtid_filter->clear_stop_gtids();
if (parse_position_argument( "--stop-position", stop_pos_str, &stop_position,
&Domain_gtid_event_filter::add_stop_gtid, TRUE)) return1; break;
} case'j':
{ /* Start position was already specified, so reset it and use the new list */ if (position_gtid_filter &&
position_gtid_filter->get_num_start_gtids() > 0)
position_gtid_filter->clear_start_gtids();
if (parse_position_argument( "--start-position", start_pos_str, &start_position,
&Domain_gtid_event_filter::add_start_gtid, FALSE)) return1; break;
} case OPT_IGNORE_DOMAIN_IDS:
{ if (parse_gtid_filter_option<Domain_gtid_event_filter>( "--ignore-domain-ids", ignore_domain_ids_str,
&domain_id_gtid_filter,
Gtid_event_filter::id_restriction_mode::BLACKLIST_MODE)) return1; break;
} case OPT_DO_DOMAIN_IDS:
{ if (parse_gtid_filter_option<Domain_gtid_event_filter>( "--do-domain-ids", do_domain_ids_str,
&domain_id_gtid_filter,
Gtid_event_filter::id_restriction_mode::WHITELIST_MODE)) return1; break;
} case OPT_IGNORE_SERVER_IDS:
{ if (parse_gtid_filter_option<Server_gtid_event_filter>( "--ignore-server-ids", ignore_server_ids_str,
&server_id_gtid_filter,
Gtid_event_filter::id_restriction_mode::BLACKLIST_MODE)) return1; break;
} case OPT_DO_SERVER_IDS:
{ if (parse_gtid_filter_option<Server_gtid_event_filter>( "--do-server-ids", do_server_ids_str,
&server_id_gtid_filter,
Gtid_event_filter::id_restriction_mode::WHITELIST_MODE)) return1; break;
} case OPT_SERVER_ID:
{ if (parse_gtid_filter_option<Server_gtid_event_filter>( "--server-id", server_id_str,
&server_id_gtid_filter,
Gtid_event_filter::id_restriction_mode::WHITELIST_MODE)) return1; break;
} case'?':
usage();
opt_version= 1; break;
} if (tty_password)
opt_password= my_get_tty_password(NullS);
return0;
}
staticint parse_args(int *argc, char*** argv)
{ int ho_error; char *tmp;
if ((ho_error=handle_options(argc, argv, my_options, get_one_option)))
{
die(ho_error);
} if (debug_info_flag)
my_end_arg= MY_CHECK_ERROR | MY_GIVE_INFO; elseif (debug_check_flag)
my_end_arg= MY_CHECK_ERROR; if (start_position > UINT_MAX32 && remote_opt)
{ /* Here we just emulate old behaviour of option limit handling */
fprintf(stderr, "Warning: option 'start-position': unsigned value %llu " "adjusted to 4294967295 (limitation of the client-server protocol)",
start_position);
start_position= UINT_MAX32;
}
/* Alwaysinitializethestreamauditorinitiallybecauseitisusedtocheck theinitialstateofthebinarylogiscorrect.Ifwedon'twantitlater (i.e.--skip-gtid-strict-modeor-vvvisnotgiven),itisdeletedwhenwe arecertaintheinitialgtidstateisset.
*/
gtid_state_validator= new Binlog_gtid_state_validator();
if (position_gtid_filter)
{ if (opt_gtid_strict_mode &&
position_gtid_filter->validate_window_filters())
{ /* Instrictmode,ifany--start/stop-positionGTIDrangesareinvalid, quitinerror.Notethatanyspecificerrormessageswillhave alreadybeenwritten.
*/
die(1);
}
extend_main_gtid_event_filter(position_gtid_filter);
@retvalERROR_STOPAnerroroccurred-theprogramshouldterminate. @retvalOK_CONTINUENoerror,theprogramshouldcontinue.
*/ static Exit_status safe_connect()
{
my_bool reconnect= 1; /* Close any old connections to MySQL */ if (mysql)
mysql_close(mysql);
mysql= mysql_init(NULL);
if (!mysql)
{
error("Failed on mysql_init."); return ERROR_STOP;
}
SET_SSL_OPTS_WITH_CHECK(mysql);
if (opt_plugindir && *opt_plugindir)
mysql_options(mysql, MYSQL_PLUGIN_DIR, opt_plugindir);
if (opt_default_auth && *opt_default_auth)
mysql_options(mysql, MYSQL_DEFAULT_AUTH, opt_default_auth);
if (short_form)
{ if (!print_row_event_positions_used)
print_row_event_positions= 0; if (!print_row_count_used)
print_row_count = 0;
} if (opt_flashback)
{ if (!print_row_event_positions_used)
print_row_event_positions= 0;
}
/* Set delimiter back to semicolon */ if (!opt_raw_mode && !opt_flashback)
fprintf(result_file, "DELIMITER ;\n");
strmov(print_event_info.delimiter, ";"); return rc;
}
if (mysql_query(mysql, "SELECT VERSION()") ||
!(res = mysql_store_result(mysql)))
{
error("Could not find server version: " "Query failed when checking master version: %s", mysql_error(mysql)); return ERROR_STOP;
} if (!(row = mysql_fetch_row(res)))
{
error("Could not find server version: " "Master returned no rows for SELECT VERSION()."); goto err;
}
if (!(version = atoi(row[0])))
{
error("Could not find server version: " "Master reported NULL for the version."); goto err;
} /* Makeanoticetotheserverthatthisclient ischecksum-aware.ItdoesnotneedthefirstfakeRotate necessarychecksummed. Thatpreferenceisspecifiedbelow.
*/ if (mysql_query(mysql, "SET @master_binlog_checksum='NONE'"))
{
error("Could not notify master about checksum awareness." "Master returned '%s'", mysql_error(mysql)); goto err;
}
/* Announceourcapabilitiestotheserver,soitwillsendusalltheevents thatweknowabout.
*/ 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;
}
if (!(result_file= my_fopen(out_file_name,
O_WRONLY | O_BINARY, MYF(MY_WME))))
{
error("Could not create output log file: %s", out_file_name);
DBUG_RETURN(ERROR_STOP);
} /* TODO - add write error simulation here */
if (my_fwrite(result_file, (const uchar *) BINLOG_MAGIC,
BIN_LOG_HEADER_SIZE, MYF(MY_NABP)))
{
error("Could not write into log file '%s'", out_file_name);
DBUG_RETURN(ERROR_STOP);
}
print_event_info->file= result_file;
delete glob_description_event;
glob_description_event= (Format_description_log_event*) ev;
print_event_info->common_header_len=
glob_description_event->common_header_len;
ev->temp_buf= 0; /* We do not want to delete the event here. */
}
}
if (my_fwrite(result_file, read_pos, *len - 1, MYF(MY_NABP)))
{
error("Could not write into log file '%s'", out_file_name);
DBUG_RETURN(ERROR_STOP);
}
fflush(result_file);
delete glob_description_event; if (!(glob_description_event= new Format_description_log_event(4)))
{
error("Failed creating Format_description_log_event; out of memory?"); return ERROR_STOP;
}
pos= my_b_tell(file);
/* fstat the file to check if the file is a regular file. */ if (my_fstat(file->file, &my_file_stat, MYF(0)) == -1)
{
error("Unable to stat the file."); return ERROR_STOP;
} if ((my_file_stat.st_mode & S_IFMT) == S_IFREG)
my_b_seek(file, (my_off_t)0);
if (my_b_read(file, header, sizeof(header)))
{
error("Failed reading header; probably an empty file."); return ERROR_STOP;
} if (0 == memcmp(header, INNODB_BINLOG_MAGIC, sizeof(header)))
{
binlog_format= INNODB_BINLOG_FORMAT; if (!engine_binlog_reader)
{
engine_binlog_reader= get_binlog_reader_innodb(); if (!engine_binlog_reader)
{
error("Out of memory setting up reader for InnoDB-implemented binlog."); return ERROR_STOP;
}
} /* Newengine-implementedbinlogalwaysdoeschecksumverificationonthe pagelevel.
*/
opt_verify_binlog_checksum= 0; /* Newengine-implementedbinlogdoesnotcontainformatdescription events.
*/ goto end;
} elseif (header[0] == '\0' && !memcmp(header, header+1, sizeof(header)-1))
{ /* This is an empty InnoDB binlog file, pre-allocated but not yet used. */ return OK_EOF;
} elseif (memcmp(header, BINLOG_MAGIC, sizeof(header)))
{
error("File is not a binary log file."); return ERROR_STOP;
}
/* Imaginewearerunningwith--start-position=1000.Westillneed toknowthebinlogformat's.Sowestillneedtofind,ifthereis one,theFormat_descevent,ortoknowifthisisa3.23 binlog.Soweneedtofirstreadthefirsteventsofthelog, thosearoundoffset4.Evenifwearereadinga3.23binlogfrom thestart(no--start-position):weneedtoknowtheheaderlength (whichis13in3.23,19in4.x)tobeabletosuccessfullyprint thefirstevent(Start_log_event_v3).Soeveninthiscase,we needto"probe"thefirstbytesofthelog*before*wedoareal read_log_event().Becauseread_log_event()needstoknowthe header'slengthtoworkfine.
*/ for(;;)
{
tmp_pos= my_b_tell(file); /* should be 4 the first time */ if (my_b_read(file, buf, sizeof(buf)))
{ if (file->error)
{
error("Could not read entry at offset %llu: " "Error in log format or read error.", (ulonglong)tmp_pos); return ERROR_STOP;
} /* OtherwisethisisjustEOF:thislogcurrentlycontains0-2 events.Maybeit'sgoingtobefilledinthenext milliseconds;thenwearegoingtohaveaproblemifthisa 3.23log(imaginewearelocallyreadinga3.23binlogwhich isbeingwrittenpresently):wewon'tknowitin read_log_event()andwillfail().Similarproblemscould happenwithhotrelaylogsif--start-positionisused(buta --start-positionwhichisposteriortothecurrentsizeofthelog). Thesearerareproblemsanyway(readingahotlog+whenwe readthefirsteventstherearenotallthereyet+whenwe readabitlatertherearemoreevents+usingastrange --start-position).
*/ break;
} else
{
DBUG_PRINT("info",("buf[EVENT_TYPE_OFFSET=%d]=%d",
EVENT_TYPE_OFFSET, buf[EVENT_TYPE_OFFSET])); if (tmp_pos >= start_position) break; elseif (buf[EVENT_TYPE_OFFSET] == FORMAT_DESCRIPTION_EVENT)
{ /* This is 5.0 */
Format_description_log_event *new_description_event;
my_b_seek(file, tmp_pos); /* seek back to event's start */ if (!(new_description_event= (Format_description_log_event*)
Log_event::read_log_event(file, &read_error,
glob_description_event,
opt_verify_binlog_checksum))) /* EOF can't be hit here normally, so it's a real error */
{
error("Could not read a Format_description_log_event event at " "offset %llu; this could be a log format error or read error.",
(ulonglong)tmp_pos); return ERROR_STOP;
} if (opt_base64_output_mode == BASE64_OUTPUT_AUTO)
{ /* process_eventwilldelete*description_eventandsetitto thenewone,soweshouldnotdoitourselvesinthis case.
*/
DBUG_ASSERT(tmp_pos + new_description_event->data_written ==
my_b_tell(file));
Exit_status retval= process_event(print_event_info,
new_description_event, tmp_pos,
logname); if (retval != OK_CONTINUE) return retval;
} else
{ delete glob_description_event;
glob_description_event= new_description_event;
}
DBUG_PRINT("info",("Setting description_event"));
} elseif (buf[EVENT_TYPE_OFFSET] == ROTATE_EVENT)
{
Log_event *ev;
my_b_seek(file, tmp_pos); /* seek back to event's start */ if (!(ev= Log_event::read_log_event(file, &read_error,
glob_description_event,
opt_verify_binlog_checksum)))
{ /* EOF can't be hit here normally, so it's a real error */
error("Could not read a Rotate_log_event event at offset %llu;" " this could be a log format error or read error.",
(ulonglong)tmp_pos); return ERROR_STOP;
} delete ev;
} else break;
}
}
end:
my_b_seek(file, pos); return OK_CONTINUE;
}
if (logname && strcmp(logname, "-") != 0)
{ /* read from normal file */ if ((fd = my_open(logname, O_RDONLY | O_BINARY, MYF(MY_WME))) < 0) return ERROR_STOP; if (init_io_cache(file, fd, 0, READ_CACHE, start_position_mot, 0,
MYF(MY_WME | MY_NABP)))
{
my_close(fd, MYF(MY_WME)); return ERROR_STOP;
}
retval= check_header(file, print_event_info, logname); if (retval != OK_CONTINUE)
{ if (retval == OK_EOF)
{ /* EmptyInnoDB-implementedbinlogfile.Justskipit(butstill continuewithanyfollowingfilesuserspecified).
*/
retval= OK_CONTINUE;
} goto end;
}
} else
{ /* read from stdin */ /* Windowsopensstdinintextmodebydefault.Certaincharacters suchasCTRL-Zareinterpretedaseventsandtheread()method willstop.CTRL-ZistheEOFmarkerinWindows.togetpastthis youhavetoopenstdininbinarymode.Setmode()isusedtoset stdininbinarymode.Errorsonsettingthismoderesultin haltingthefunctionandprintinganerrormessagetostderr.
*/ #ifdefined (_WIN32) if (_setmode(fileno(stdin), O_BINARY) == -1)
{
error("Could not set binary mode on stdin."); return ERROR_STOP;
} #endif if (init_io_cache(file, my_fileno(stdin), 0, READ_CACHE, (my_off_t) 0, 0, MYF(MY_WME | MY_NABP | MY_DONT_CHECK_FILESIZE)))
{
error("Failed to init IO cache."); return ERROR_STOP;
}
retval= check_header(file, print_event_info, logname); if (retval != OK_CONTINUE)
{ if (retval == OK_EOF)
retval= OK_CONTINUE; goto end;
} if (start_position)
{ /* skip 'start_position' characters from stdin */
uchar buff[IO_SIZE];
my_off_t length,tmp; for (length= start_position_mot ; length > 0 ; length-=tmp)
{
tmp= MY_MIN(length,sizeof(buff)); if (my_b_read(file, buff, (uint) tmp))
{
error("Failed reading from file."); goto err;
}
}
}
}
if (!glob_description_event || !glob_description_event->is_valid())
{
error("Invalid Format_description log event; could be out of memory."); goto err;
}
if (!start_position && my_b_read(file, tmp_buff, BIN_LOG_HEADER_SIZE))
{
error("Failed reading from file."); goto err;
} if (binlog_format == INNODB_BINLOG_FORMAT)
{ if (open_engine_binlog(engine_binlog_reader, start_position, logname, file)) goto err;
} for (;;)
{ char llbuff[21];
my_off_t old_off = my_b_tell(file); int read_error;
Log_event* ev;
if (binlog_format == INNODB_BINLOG_FORMAT)
{
String packet; int res= engine_binlog_reader->read_log_event(&packet, 0, MAX_MAX_ALLOWED_PACKET); if (res == LOG_READ_EOF)
{
ev= nullptr;
read_error= 0;
} elseif (res < 0)
{
ev= nullptr;
read_error= -1;
} else
{ constchar *errmsg= nullptr;
ev= Log_event::read_log_event((uchar *)packet.ptr(), packet.length(),
&errmsg, glob_description_event, FALSE, FALSE); if (!ev)
{
error("Error reading event: %s", errmsg);
read_error= -1;
} else
{
ev->register_temp_buf((uchar *)packet.release(), true);
read_error= 0;
}
}
} else
{
ev= Log_event::read_log_event(file, &read_error,
glob_description_event,
opt_verify_binlog_checksum);
} if (!ev)
{ /* ifbinlogwasn'tclosedproperly("inuse"flagisset)don'tcomplain aboutacorruption,buttreatitasEOFandmovetothenextbinlog.
*/ if (glob_description_event->flags & LOG_EVENT_BINLOG_IN_USE_F)
read_error= 0; elseif (read_error)
{
error("Could not read entry at offset %s: " "Error in log format or read error.",
llstr(old_off,llbuff)); goto err;
} // else read_error == 0 means EOF, that's OK, we break in this case
if (!(binlog_filter= new Rpl_filter))
{
error("Failed to create Rpl_filter"); goto err;
}
parse_args(&argc, (char***)&argv);
if (!argc || opt_version)
{ if (!opt_version)
{
error("Please provide the log file(s). Run with '--help' for usage " "instructions.");
retval= ERROR_STOP;
} goto err;
}
if (opt_base64_output_mode == BASE64_OUTPUT_UNSPEC)
opt_base64_output_mode= BASE64_OUTPUT_AUTO;
my_set_max_open_files(open_files_limit);
if (opt_flashback && opt_raw_mode)
{
error("The --raw mode is not allowed with --flashback mode");
die(1);
}
if (opt_flashback)
{
my_init_dynamic_array(PSI_NOT_INSTRUMENTED, &binlog_events, sizeof(LEX_STRING), 1024, 1024, MYF(0));
my_init_dynamic_array(PSI_NOT_INSTRUMENTED, &events_in_stmt, sizeof(Rows_log_event*), 1024, 1024, MYF(0));
} if (opt_stop_never)
to_last_remote_log= TRUE;
if (opt_raw_mode)
{ if (!remote_opt)
{
error("The --raw mode only works with --read-from-remote-server");
die(1);
} if (one_database)
warning("The --database option is ignored in raw mode");
if (stop_position != (ulonglong)(~(my_off_t)0))
warning("The --stop-position option is ignored in raw mode");
if (stop_datetime_given)
warning("The --stop-datetime option is ignored in raw mode");
result_file= 0; if (result_file_name)
output_prefix= result_file_name;
} else
{ if (result_file_name)
{ if (!(result_file= my_fopen(result_file_name,
O_WRONLY | O_BINARY, MYF(MY_WME))))
{
error("Could not create log file '%s'", result_file_name);
die(1);
}
} else
result_file= stdout;
}
if (load_processor.init())
{
retval= ERROR_STOP; goto err;
} if (dirname_for_local_load)
load_processor.init_by_dir_name(dirname_for_local_load); else
load_processor.init_by_cur_dir();
if (!opt_raw_mode)
{
fprintf(result_file, "/*!50530 SET @@SESSION.PSEUDO_SLAVE_MODE=1*/;\n");
fprintf(result_file, "/*!40019 SET @@session.max_delayed_threads=0*/;\n");
if (disable_log_bin)
fprintf(result_file, "/*!32316 SET @OLD_SQL_LOG_BIN=@@SQL_LOG_BIN, SQL_LOG_BIN=0*/;\n");
/* Inmysqlbinlog|mysql,don'twantmysqltobedisconnectedaftereach transaction(whichwouldbethecasewithGLOBAL.COMPLETION_TYPE==2).
*/
fprintf(result_file, "/*!50003 SET @OLD_COMPLETION_TYPE=@@COMPLETION_TYPE," "COMPLETION_TYPE=0*/;\n");
if (charset)
fprintf(result_file, "\n/*!40101 SET @OLD_CHARACTER_SET_CLIENT=@@CHARACTER_SET_CLIENT */;" "\n/*!40101 SET @OLD_CHARACTER_SET_RESULTS=@@CHARACTER_SET_RESULTS */;" "\n/*!40101 SET @OLD_COLLATION_CONNECTION=@@COLLATION_CONNECTION */;" "\n/*!40101 SET NAMES %s */;\n", charset);
}
for (save_stop_position= stop_position, stop_position= ~(my_off_t)0 ;
(--argc >= 0) ; )
{ if (argc == 0) // last log, --stop-position applies
stop_position= save_stop_position; if ((retval= dump_log_entries(*argv++)) != OK_CONTINUE) break;
// For next log, --start-position does not apply
start_position= BIN_LOG_HEADER_SIZE;
}
/* Emitwarning(s)(inGtid_event_filter::verify_completed_state()forGTID(s)) ifwefinishedprocessinginputbeforereachingthestop boundariesindicatedby--stop-datetimeor--stop-position.
*/ if (stop_datetime_given && stop_datetime > last_processed_ev.datetime)
warning("Did not reach stop datetime '%s' before end of input",
stop_datetime_str); if ((static_cast<longlong>(stop_position) != stop_position_default) &&
stop_position > last_processed_ev.position)
warning("Did not reach stop position %llu before end of input",
stop_position); if (position_gtid_filter)
position_gtid_filter->verify_final_state();
/* Ifenableflashback,needtoprinttheeventsfromtheendtothe beginning
*/ if (opt_flashback && retval != ERROR_STOP)
{ for (size_t i= binlog_events.elements; i > 0; --i)
{
LEX_STRING *event_str= dynamic_element(&binlog_events, i - 1,
LEX_STRING*);
fprintf(result_file, "%s", event_str->str);
my_free(event_str->str);
}
fprintf(result_file, "COMMIT\n/*!*/;\n");
delete_dynamic(&binlog_events);
delete_dynamic(&events_in_stmt);
}
/* Set delimiter back to semicolon */ if (retval != ERROR_STOP)
{ if (!stop_event_string.is_empty() && result_file)
fprintf(result_file, "%s", stop_event_string.ptr()); if (!opt_raw_mode && opt_flashback)
fprintf(result_file, "DELIMITER ;\n");
}
if (retval != ERROR_STOP && !opt_raw_mode)
{ /* IssueaROLLBACKincasethelastprintedbinlogwascrashedandhadhalf oftransaction.
*/
fprintf(result_file, "# End of log file\nROLLBACK /* added by mysqlbinlog */;\n" "/*!50003 SET COMPLETION_TYPE=@OLD_COMPLETION_TYPE*/;\n"); if (disable_log_bin)
fprintf(result_file, "/*!32316 SET SQL_LOG_BIN=@OLD_SQL_LOG_BIN*/;\n");
if (charset)
fprintf(result_file, "/*!40101 SET CHARACTER_SET_CLIENT=@OLD_CHARACTER_SET_CLIENT */;\n" "/*!40101 SET CHARACTER_SET_RESULTS=@OLD_CHARACTER_SET_RESULTS */;\n" "/*!40101 SET COLLATION_CONNECTION=@OLD_COLLATION_CONNECTION */;\n");
fprintf(result_file, "/*!50530 SET @@SESSION.PSEUDO_SLAVE_MODE=0*/;\n");
if (gtid_event_filter)
{
fprintf(result_file, "/*!100001 SET @@SESSION.SERVER_ID=@@GLOBAL.SERVER_ID */;\n" "/*!100001 SET @@SESSION.GTID_DOMAIN_ID=@@GLOBAL.GTID_DOMAIN_ID " "*/;\n");
}
}
if (tmpdir.list)
free_tmpdir(&tmpdir); if (result_file)
{ if (result_file != stdout)
my_fclose(result_file, MYF(0)); else
fflush(result_file);
}
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.