• Alfranio Correia's avatar
    BUG#43929 binlog corruption when max_binlog_cache_size is exceeded · 3cf052b7
    Alfranio Correia authored
    Large transactions and statements may corrupt the binary log if the size of the
    cache, which is set by the max_binlog_cache_size, is not enough to store the
    the changes.
    
    In a nutshell, to fix the bug, we save the position of the next character in the
    cache before starting processing a statement. If there is a problem, we simply
    restore the position thus removing any effect of the statement from the cache.
    Unfortunately, to avoid corrupting the binary log, we may end up loosing changes
    on non-transactional tables if they do not fit in the cache. In such cases, we
    store an Incident_log_event in order to stop the slave and alert users that some
    changes were not logged.
    
    Precisely, for every non-transactional changes that do not fit into the cache,
    we do the following:
      a) the statement is *not* logged
      b) an incident event is logged after committing/rolling back the transaction,
      if any. Note that if a failure happens before writing the incident event to
      the binary log, the slave will not stop and the master will not have reported
      any error.
      c) its respective statement gives an error
    
    For transactional changes that do not fit into the cache, we do the following:
      a) the statement is *not* logged
      b) its respective statement gives an error
    
    To work properly, this patch requires two additional things. Firstly, callers to
    MYSQL_BIN_LOG::write and THD::binlog_query must handle any error returned and
    take the appropriate actions such as undoing the effects of a statement. We
    already changed some calls in the sql_insert.cc, sql_update.cc and sql_insert.cc
    modules but the remaining calls spread all over the code should be handled in
    BUG#37148. Secondly, statements must be either classified as DDL or DML because
    DDLs that do not get into the cache must generate an incident event since they
    cannot be rolled back.
    3cf052b7
sql_insert.cc 124 KB