summaryrefslogtreecommitdiff
path: root/client/mysqlbinlog.cc
diff options
context:
space:
mode:
Diffstat (limited to 'client/mysqlbinlog.cc')
-rw-r--r--client/mysqlbinlog.cc171
1 files changed, 100 insertions, 71 deletions
diff --git a/client/mysqlbinlog.cc b/client/mysqlbinlog.cc
index 87198347b10..c099459f61e 100644
--- a/client/mysqlbinlog.cc
+++ b/client/mysqlbinlog.cc
@@ -818,6 +818,88 @@ write_event_header_and_base64(Log_event *ev, FILE *result_file,
}
+static bool print_base64(PRINT_EVENT_INFO *print_event_info, Log_event *ev)
+{
+ /*
+ These events must be printed in base64 format, if printed.
+ base64 format requires a FD event to be safe, so if no FD
+ event has been printed, we give an error. Except if user
+ passed --short-form, because --short-form disables printing
+ row events.
+ */
+ if (!print_event_info->printed_fd_event && !short_form &&
+ opt_base64_output_mode != BASE64_OUTPUT_DECODE_ROWS)
+ {
+ const char* type_str= ev->get_type_str();
+ if (opt_base64_output_mode == BASE64_OUTPUT_NEVER)
+ error("--base64-output=never specified, but binlog contains a "
+ "%s event which must be printed in base64.",
+ type_str);
+ else
+ error("malformed binlog: it does not contain any "
+ "Format_description_log_event. I now found a %s event, which "
+ "is not safe to process without a "
+ "Format_description_log_event.",
+ type_str);
+ return 1;
+ }
+ ev->print(result_file, print_event_info);
+ return print_event_info->head_cache.error == -1;
+}
+
+
+static bool print_row_event(PRINT_EVENT_INFO *print_event_info, Log_event *ev,
+ ulong table_id, bool is_stmt_end)
+{
+ Table_map_log_event *ignored_map=
+ print_event_info->m_table_map_ignored.get_table(table_id);
+ bool skip_event= (ignored_map != NULL);
+
+ /*
+ end of statement check:
+ i) destroy/free ignored maps
+ ii) if skip event, flush cache now
+ */
+ if (is_stmt_end)
+ {
+ /*
+ Now is safe to clear ignored map (clear_tables will also
+ delete original table map events stored in the map).
+ */
+ if (print_event_info->m_table_map_ignored.count() > 0)
+ print_event_info->m_table_map_ignored.clear_tables();
+
+ /*
+ If there is a kept Annotate event and all corresponding
+ rbr-events were filtered away, the Annotate event was not
+ freed and it is just the time to do it.
+ */
+ free_annotate_event();
+
+ /*
+ One needs to take into account an event that gets
+ filtered but was last event in the statement. If this is
+ the case, previous rows events that were written into
+ IO_CACHEs still need to be copied from cache to
+ result_file (as it would happen in ev->print(...) if
+ event was not skipped).
+ */
+ if (skip_event)
+ {
+ if ((copy_event_cache_to_file_and_reinit(&print_event_info->head_cache, result_file) ||
+ copy_event_cache_to_file_and_reinit(&print_event_info->body_cache, result_file)))
+ return 1;
+ }
+ }
+
+ /* skip the event check */
+ if (skip_event)
+ return 0;
+
+ return print_base64(print_event_info, ev);
+}
+
+
/**
Print the given event, and either delete it or delegate the deletion
to someone else.
@@ -1130,86 +1212,29 @@ Exit_status process_event(PRINT_EVENT_INFO *print_event_info, Log_event *ev,
error("Could not rewrite database name");
goto err;
}
+ if (print_base64(print_event_info, ev))
+ goto err;
+ break;
}
case WRITE_ROWS_EVENT:
case DELETE_ROWS_EVENT:
case UPDATE_ROWS_EVENT:
+ {
+ Rows_log_event *e= (Rows_log_event*) ev;
+ if (print_row_event(print_event_info, ev, e->get_table_id(),
+ e->get_flags(Rows_log_event::STMT_END_F)))
+ goto err;
+ break;
+ }
case PRE_GA_WRITE_ROWS_EVENT:
case PRE_GA_DELETE_ROWS_EVENT:
case PRE_GA_UPDATE_ROWS_EVENT:
{
- if (ev_type != TABLE_MAP_EVENT)
- {
- Rows_log_event *e= (Rows_log_event*) ev;
- Table_map_log_event *ignored_map=
- print_event_info->m_table_map_ignored.get_table(e->get_table_id());
- bool skip_event= (ignored_map != NULL);
-
- /*
- end of statement check:
- i) destroy/free ignored maps
- ii) if skip event, flush cache now
- */
- if (e->get_flags(Rows_log_event::STMT_END_F))
- {
- /*
- Now is safe to clear ignored map (clear_tables will also
- delete original table map events stored in the map).
- */
- if (print_event_info->m_table_map_ignored.count() > 0)
- print_event_info->m_table_map_ignored.clear_tables();
-
- /*
- If there is a kept Annotate event and all corresponding
- rbr-events were filtered away, the Annotate event was not
- freed and it is just the time to do it.
- */
- free_annotate_event();
-
- /*
- One needs to take into account an event that gets
- filtered but was last event in the statement. If this is
- the case, previous rows events that were written into
- IO_CACHEs still need to be copied from cache to
- result_file (as it would happen in ev->print(...) if
- event was not skipped).
- */
- if (skip_event)
- {
- if ((copy_event_cache_to_file_and_reinit(&print_event_info->head_cache, result_file) ||
- copy_event_cache_to_file_and_reinit(&print_event_info->body_cache, result_file)))
- goto err;
- }
- }
-
- /* skip the event check */
- if (skip_event)
- goto end;
- }
- /*
- These events must be printed in base64 format, if printed.
- base64 format requires a FD event to be safe, so if no FD
- event has been printed, we give an error. Except if user
- passed --short-form, because --short-form disables printing
- row events.
- */
- if (!print_event_info->printed_fd_event && !short_form &&
- opt_base64_output_mode != BASE64_OUTPUT_DECODE_ROWS)
- {
- const char* type_str= ev->get_type_str();
- if (opt_base64_output_mode == BASE64_OUTPUT_NEVER)
- error("--base64-output=never specified, but binlog contains a "
- "%s event which must be printed in base64.",
- type_str);
- else
- error("malformed binlog: it does not contain any "
- "Format_description_log_event. I now found a %s event, which "
- "is not safe to process without a "
- "Format_description_log_event.",
- type_str);
+ Old_rows_log_event *e= (Old_rows_log_event*) ev;
+ if (print_row_event(print_event_info, ev, e->get_table_id(),
+ e->get_flags(Old_rows_log_event::STMT_END_F)))
goto err;
- }
- /* FALL THROUGH */
+ break;
}
default:
print_skip_replication_statement(print_event_info, ev);
@@ -2444,6 +2469,8 @@ int main(int argc, char** argv)
else
load_processor.init_by_cur_dir();
+ fprintf(result_file, "/*!50530 SET @@SESSION.PSEUDO_SLAVE_MODE=1*/;\n");
+
fprintf(result_file,
"/*!40019 SET @@session.max_insert_delayed_threads=0*/;\n");
@@ -2494,6 +2521,8 @@ int main(int argc, char** argv)
"/*!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 (tmpdir.list)
free_tmpdir(&tmpdir);
if (result_file != stdout)