• unknown's avatar
    BUG#22864 (Rollback following CREATE... SELECT discards 'CREATE TABLE' · 3d68c135
    unknown authored
    from log):
    When row-based logging is used, the CREATE-SELECT is written as two
    parts: as a CREATE TABLE statement and as the rows for the table. For
    both transactional and non-transactional tables, the CREATE TABLE
    statement was written to the transaction cache, as were the rows, and
    on statement end, the entire transaction cache was written to the binary
    log if the table was non-transactional. For transactional tables, the
    events were kept in the transaction cache until end of transaction (or
    statement that were not part of a transaction).
    
    For the case when AUTOCOMMIT=0 and we are creating a transactional table
    using a create select, we would then keep the CREATE TABLE statement and
    the rows for the CREATE-SELECT, while executing the following statements.
    On a rollback, the transaction cache would then be cleared, which would
    also remove the CREATE TABLE statement. Hence no table would be created
    on the slave, while there is an empty table on the master.
    
    This relates to BUG#22865 where the table being created exists on the
    master, but not on the slave during insertion of rows into the newly
    created table. This occurs since the CREATE TABLE statement were still
    in the transaction cache until the statement finished executing, and
    possibly longer if the table was transactional.
    
    This patch changes the behaviour of the CREATE-SELECT statement by
    adding an implicit commit at the end of the statement when creating
    non-temporary tables. Hence, non-temporary tables will be written to the
    binary log on completion, and in the even of AUTOCOMMIT=0, a new
    transaction will be started. Temporary tables do not commit an ongoing
    transaction: neither as a pre- not a post-commit.
    
    The events for both transactional and non-transactional tables are
    saved in the transaction cache, and written to the binary log at end
    of the statement.
    
    
    mysql-test/r/rpl_row_create_table.result:
      Result change
    mysql-test/t/rpl_row_create_table.test:
      Requring InnoDB for slave as well.
      Adding test CREATE-SELECT that is rolled back explicitly.
      Changing binlog positions.
    sql/log.cc:
      Adding helper class to handle lock/unlock of mutexes using RAII.
      Factoring out code into write_cache() function to transaction cache
        to binary log.
      Adding function THD::binlog_flush_transaction_cache() to flush the
        transaction cache to the binary log file.
      Factoring out code into binlog_set_stmt_begin() to set the beginning
        of statement savepoint.
      Clearing before statement point when transaction cache is truncated
       so that these points are out of range.
    sql/log.h:
      Adding method MYSQL_BIN_LOG::write_cache()
    sql/log_event.h:
      Replicating OPTION_NOT_AUTOCOMMIT flag (see changeset comment)
    sql/mysql_priv.h:
      Although left-shifting signed integer values is well-defined,
      it has potential for strange errors. Using unsigned long long
      instead of signed long long since this is the type of the options
      flags.
    sql/slave.cc:
      Adding printout of transaction-critical thread flags.
    sql/sql_class.h:
      Adding function THD::binlog_flush_transaction_cache()
      Adding function THD::binlog_set_stmt_begin()
    sql/sql_insert.cc:
      Adding code to cache events for a CREATE-SELECT statement.
      Disabling binlog for SBR (but not RBR) when sending error for select part
      of CREATE-SELECT statement.
      Adding implicit commit at end of statement for non-temporary tables.
    mysql-test/t/rpl_row_create_table-slave.opt:
      New BitKeeper file ``mysql-test/t/rpl_row_create_table-slave.opt''
    3d68c135
mysql_priv.h 77.3 KB