diff options
author | Sujatha <sujatha.sivakumar@mariadb.com> | 2019-12-18 14:59:44 +0530 |
---|---|---|
committer | Sujatha <sujatha.sivakumar@mariadb.com> | 2020-01-07 18:27:05 +0530 |
commit | a6dd827a4d987a5c779ac0ce2658214f8678832f (patch) | |
tree | 58614e557774094a685558bdf15a050b83df022b /sql/sql_repl.cc | |
parent | 1adc559370cc53ca69e225739a942287eba1b974 (diff) | |
download | mariadb-git-a6dd827a4d987a5c779ac0ce2658214f8678832f.tar.gz |
MDEV-18046: Assortment of crashes, assertion failures and ASAN errors in mysql_show_binlog_events
Problem:
========
SHOW BINLOG EVENTS FROM <pos> causes a variety of failures, some of which are
listed below. It is not a race condition issue, but there is some
non-determinism in it.
Analysis:
========
"show binlog events from <pos>" code considers the user given position as a
valid event start position. The code starts reading data from this event start
position onwards and tries to map it to a set of known events. Each event has
a specific event structure and asserts have been added to ensure that read
event data satisfies the event specific requirements. When a random position
is supplied to "show binlog events command" the event structure specific
checks will fail and they result in assert.
Fix:
====
The fix is split into different parts. Each part addresses either an ASAN
issue or an assert/crash.
**Part1: Checksum based position validation when checksum is enabled**
Using checksum validate the very first event read at the user specified
position. If there is a checksum mismatch report an appropriate error for the
invalid event.
Diffstat (limited to 'sql/sql_repl.cc')
-rw-r--r-- | sql/sql_repl.cc | 23 |
1 files changed, 17 insertions, 6 deletions
diff --git a/sql/sql_repl.cc b/sql/sql_repl.cc index 48d2781cd46..851bff5fd24 100644 --- a/sql/sql_repl.cc +++ b/sql/sql_repl.cc @@ -3840,6 +3840,11 @@ bool mysql_show_binlog_events(THD* thd) List<Item> field_list; const char *errmsg = 0; bool ret = TRUE; + /* + Using checksum validate the correctness of event pos specified in show + binlog events command. + */ + bool verify_checksum_once= false; IO_CACHE log; File file = -1; MYSQL_BIN_LOG *binary_log= NULL; @@ -3895,6 +3900,10 @@ bool mysql_show_binlog_events(THD* thd) mi= 0; } + /* Validate user given position using checksum */ + if (lex_mi->pos == pos && !opt_master_verify_checksum) + verify_checksum_once= true; + unit->set_limit(thd->lex->current_select); limit_start= unit->offset_limit_cnt; limit_end= unit->select_limit_cnt; @@ -3977,15 +3986,16 @@ bool mysql_show_binlog_events(THD* thd) for (event_count = 0; (ev = Log_event::read_log_event(&log, (mysql_mutex_t*) 0, description_event, - opt_master_verify_checksum)); ) + (opt_master_verify_checksum || + verify_checksum_once))); ) { if (event_count >= limit_start && - ev->net_send(protocol, linfo.log_file_name, pos)) + ev->net_send(protocol, linfo.log_file_name, pos)) { - errmsg = "Net error"; - delete ev; + errmsg = "Net error"; + delete ev; mysql_mutex_unlock(log_lock); - goto err; + goto err; } if (ev->get_type_code() == FORMAT_DESCRIPTION_EVENT) @@ -4011,10 +4021,11 @@ bool mysql_show_binlog_events(THD* thd) delete ev; } + verify_checksum_once= false; pos = my_b_tell(&log); if (++event_count >= limit_end) - break; + break; } if (event_count < limit_end && log.error) |