Skip to content

Commit

Permalink
Bug#23490641 ASSERTION FAILURE IN 'MYSQL_BIN_LOG::PREPARE()' IF DML IS
Browse files Browse the repository at this point in the history
             PASSED IN --INIT-FILE

Problem:

In order to avoid polluting the binary log (and generating GTIDs) for
MySQL initialization statements, the initialize process was refactored
to disable binary logging before processing the compiled statements,
and enabling the binary logging again once finishing processing the
compiled statements and before processing any file passed as parameter
to the initialize process.

The change above failed when the script/fill_help_tables.sql is updated
with current help script that included a "SET sql_log_bin=0;" on it.

Analysis:

The MYSQL_BIN_LOG::prepare function has an assertion to ensure that
the session sql_log_bin variable is true when a statement are prepared
to go to the binary log.

The bootstrap function that handle the initialize process started with
sql_log_bin = true, but disabled the internal representation of it by
resetting the OPTION_BIN_LOG bit from thd->variables.option_bits.

The fill_help_tables.sql script is disabling the sql_log_bin session
variable and it is compiled into the server code.

When the initialize process starts to apply a file passed as parameter,
it has the internal representation of the binary logging restored
(OPTION_BIN_LOG bit of thd->variables.option_bits) but the sql_log_bin
session variable was disabled, making the MYSQL_BIN_LOG::prepare
assertion to fail.

Fix:

The initialize process now will check if binary log is enabled while
processing compiled statement. It will disable binary logging on such
cases.
  • Loading branch information
Joao Gramacho committed Jun 30, 2016
1 parent 30d98bb commit 1f1b47e
Show file tree
Hide file tree
Showing 2 changed files with 27 additions and 3 deletions.
5 changes: 5 additions & 0 deletions mysql-test/t/initialize_gtid.test
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,11 @@ CREATE TABLE test.t1(a INT) ENGINE=innodb;
BEGIN;
INSERT INTO test.t1 VALUES (1);
COMMIT;
SET sql_log_bin= 0;
BEGIN;
INSERT INTO test.t1 VALUES (2);
COMMIT;
SET sql_log_bin= 1;
DROP TABLE test.t1;
DROP DATABASE test;
EOF
Expand Down
25 changes: 22 additions & 3 deletions sql/bootstrap.cc
Original file line number Diff line number Diff line change
Expand Up @@ -88,6 +88,7 @@ static void handle_bootstrap_impl(THD *thd)
File_command_iterator file_iter(bootstrap_file, mysql_file_fgets_fn);
Compiled_in_command_iterator comp_iter;
bool has_binlog_option= thd->variables.option_bits & OPTION_BIN_LOG;
int query_source, last_query_source= -1;

thd->thread_stack= (char*) &thd;
thd->security_context()->assign_user(STRING_WITH_LEN("boot"));
Expand All @@ -113,7 +114,6 @@ static void handle_bootstrap_impl(THD *thd)
{
int error= 0;
int rc;
int query_source, last_query_source= -1;

rc= Command_iterator::current_iterator->next(query, &error, &query_source);

Expand All @@ -133,6 +133,12 @@ static void handle_bootstrap_impl(THD *thd)
thd->variables.option_bits&= ~OPTION_BIN_LOG;
break;
case QUERY_SOURCE_FILE:
/*
Some compiled script might have disable binary logging session
variable during compiled scripts. Enabling it again as it was
enabled before applying the compiled statements.
*/
thd->variables.sql_log_bin= true;
thd->variables.option_bits|= OPTION_BIN_LOG;
break;
default:
Expand Down Expand Up @@ -222,16 +228,29 @@ static void handle_bootstrap_impl(THD *thd)

free_root(thd->mem_root,MYF(MY_KEEP_PREALLOC));
thd->get_transaction()->free_memory(MYF(MY_KEEP_PREALLOC));

/*
If the last statement has enabled the session binary logging while
processing queries that are compiled and must not be binary logged,
we must disable binary logging again.
*/
if (last_query_source == QUERY_SOURCE_COMPILED &&
thd->variables.option_bits & OPTION_BIN_LOG)
thd->variables.option_bits&= ~OPTION_BIN_LOG;

}

Command_iterator::current_iterator->end();

/*
We should re-enable SQL_LOG_BIN session if it was enabled during
bootstrap/initialization.
We should re-enable SQL_LOG_BIN session if it was enabled by default
but disabled during bootstrap/initialization.
*/
if (has_binlog_option)
{
thd->variables.sql_log_bin= true;
thd->variables.option_bits|= OPTION_BIN_LOG;
}

DBUG_VOID_RETURN;
}
Expand Down

0 comments on commit 1f1b47e

Please sign in to comment.