List:Commits« Previous MessageNext Message »
From:Dao-Gang.Qu Date:December 30 2010 11:58am
Subject:bzr commit into mysql-trunk branch (Dao-Gang.Qu:3446) WL#4925
View as plain text  
#At file:///home/daogang/bzrwork/wl4925/mysql-trunk/ based on revid:alexander.nozdrin@strippedt3ibtd32wd9qaw

 3446 Dao-Gang.Qu@stripped	2010-12-30
      WL#4925 Preallocating binary log for improving write performance
      
      The performance problem of binlog is caused by the architecture of writing
      to binlog, "extending file per each commit" Currently binlog file is not
      pre-allocated, but extending per each transaction commit. In contrast,
      InnoDB log file is pre-allocated and file size is not changed. In other
      words, binlog adopts “appending” architecture, InnoDB log adopts
      “overwriting” architecture. For most of operating systems/file systems
      (including Solaris ufs and Linux ext3), overwriting is much faster than
      appending. So binlog should pre-allocate large file size (e.g. 128MB at
      once), then overwriting per commit.
     @ client/mysqlbinlogalloc.cc
        Added the tool for static preallocation of binlog.
     @ mysql-test/extra/rpl_tests/prealloc_binlog_base.test
        Added the file to verefy if binlog files of automatic/static
        preallocation will work fine with normal restart and
        concurrency execution.
     @ mysql-test/extra/rpl_tests/prealloc_binlog_crash_base.test
        Added the file to verify if binlog files of automatic/static
        preallocation will work fine with crash shutdown.
     @ mysql-test/r/mysqld--help-notwin.result
        Updated for the patch of WL#4925.
     @ mysql-test/suite/rpl/r/rpl_mixed_prealloc_binlog.result
        Test result of WL#4925.
     @ mysql-test/suite/rpl/r/rpl_mixed_prealloc_binlog_crash.result
        Test result of WL#4925.
     @ mysql-test/suite/rpl/r/rpl_row_prealloc_binlog.result
        Test result of WL#4925.
     @ mysql-test/suite/rpl/r/rpl_row_prealloc_binlog_crash.result
        Test result of WL#4925.
     @ mysql-test/suite/rpl/r/rpl_row_prealloc_binlog_max_cache_size.result
        Test result of WL#4925.
     @ mysql-test/suite/rpl/r/rpl_stmt_prealloc_binlog.result
        Test result of WL#4925.
     @ mysql-test/suite/rpl/r/rpl_stmt_prealloc_binlog_crash.result
        Test result of WL#4925.
     @ mysql-test/suite/rpl/r/rpl_stmt_prealloc_binlog_max_cache_size.result
        Test result of WL#4925.
     @ mysql-test/suite/rpl/t/rpl_mixed_prealloc_binlog_max_cache_size.test
        Added the file to verify if binlog files of automatic preallocation
        will work fine with max_cache_size in mixed mode.
     @ mysql-test/suite/rpl/t/rpl_row_prealloc_binlog_max_cache_size.test
        Added the file to verify if binlog files of automatic preallocation
        will work fine with max_cache_size in row mode.
     @ mysql-test/suite/rpl/t/rpl_stmt_prealloc_binlog_max_cache_size.test
        Added the file to verify if binlog files of automatic preallocation
        will work fine with max_cache_size in statement mode.
     @ mysql-test/suite/sys_vars/r/all_vars.result
        Updated for the patch of WL#4925.
     @ mysys/my_winfile.c
        Added code to preallocate a binlog file by SetFilePointerEx()
        and SetEndOfFile() on Windows.
     @ mysys/my_write.c
        Added code to preallocate a binlog file by invoking posix_fallocate()
     @ sql/binlog.cc
        Added code to automatically preallocate binlog files base on
        the biggest number of binlog file in the binlog index file
        and update actual_size when flushing binlog into disk:
        - writing format descriptor event (initial event)
        - transactional commit
        - non-transactional commit
        - rotating binlog file
        - closing binlog file
     @ sql/log.cc
        Redefine the 'test_if_number' function as globle function
        for using it in the outside of the file.
     @ sql/log_event.cc
        Added code to make SHOW BINLOG EVENTS read active binlog
        to mysql_bin_log.actual_size instead of EOF.
     @ sql/sys_vars.cc
        Added "binlog_preallocate" system variable to do the following:
        0: Neither doing automatic preallocation nor detecting statically
        preallocated files (default behavior)
        N (N>=1) : Automatically preallocating N binlog files if the next
        binlog file does not exist. mysqld also detects statically
        preallocated files.

    added:
      client/mysqlbinlogalloc.cc
      mysql-test/extra/rpl_tests/prealloc_binlog_base.test
      mysql-test/extra/rpl_tests/prealloc_binlog_crash_base.test
      mysql-test/suite/rpl/r/rpl_mixed_prealloc_binlog.result
      mysql-test/suite/rpl/r/rpl_mixed_prealloc_binlog_crash.result
      mysql-test/suite/rpl/r/rpl_mixed_prealloc_binlog_max_cache_size.result
      mysql-test/suite/rpl/r/rpl_row_prealloc_binlog.result
      mysql-test/suite/rpl/r/rpl_row_prealloc_binlog_crash.result
      mysql-test/suite/rpl/r/rpl_row_prealloc_binlog_max_cache_size.result
      mysql-test/suite/rpl/r/rpl_stmt_prealloc_binlog.result
      mysql-test/suite/rpl/r/rpl_stmt_prealloc_binlog_crash.result
      mysql-test/suite/rpl/r/rpl_stmt_prealloc_binlog_max_cache_size.result
      mysql-test/suite/rpl/t/rpl_mixed_prealloc_binlog-master.opt
      mysql-test/suite/rpl/t/rpl_mixed_prealloc_binlog-slave.opt
      mysql-test/suite/rpl/t/rpl_mixed_prealloc_binlog.test
      mysql-test/suite/rpl/t/rpl_mixed_prealloc_binlog_crash-master.opt
      mysql-test/suite/rpl/t/rpl_mixed_prealloc_binlog_crash.cnf
      mysql-test/suite/rpl/t/rpl_mixed_prealloc_binlog_crash.test
      mysql-test/suite/rpl/t/rpl_mixed_prealloc_binlog_max_cache_size-master.opt
      mysql-test/suite/rpl/t/rpl_mixed_prealloc_binlog_max_cache_size.test
      mysql-test/suite/rpl/t/rpl_row_prealloc_binlog-master.opt
      mysql-test/suite/rpl/t/rpl_row_prealloc_binlog-slave.opt
      mysql-test/suite/rpl/t/rpl_row_prealloc_binlog.test
      mysql-test/suite/rpl/t/rpl_row_prealloc_binlog_crash-master.opt
      mysql-test/suite/rpl/t/rpl_row_prealloc_binlog_crash.cnf
      mysql-test/suite/rpl/t/rpl_row_prealloc_binlog_crash.test
      mysql-test/suite/rpl/t/rpl_row_prealloc_binlog_max_cache_size-master.opt
      mysql-test/suite/rpl/t/rpl_row_prealloc_binlog_max_cache_size.test
      mysql-test/suite/rpl/t/rpl_stmt_prealloc_binlog-master.opt
      mysql-test/suite/rpl/t/rpl_stmt_prealloc_binlog-slave.opt
      mysql-test/suite/rpl/t/rpl_stmt_prealloc_binlog.test
      mysql-test/suite/rpl/t/rpl_stmt_prealloc_binlog_crash-master.opt
      mysql-test/suite/rpl/t/rpl_stmt_prealloc_binlog_crash.cnf
      mysql-test/suite/rpl/t/rpl_stmt_prealloc_binlog_crash.test
      mysql-test/suite/rpl/t/rpl_stmt_prealloc_binlog_max_cache_size-master.opt
      mysql-test/suite/rpl/t/rpl_stmt_prealloc_binlog_max_cache_size.test
    modified:
      client/CMakeLists.txt
      include/my_sys.h
      include/mysql/psi/mysql_file.h
      mysql-test/r/mysqld--help-notwin.result
      mysql-test/suite/sys_vars/r/all_vars.result
      mysys/my_winfile.c
      mysys/my_write.c
      mysys/mysys_priv.h
      sql/binlog.cc
      sql/binlog.h
      sql/log.cc
      sql/log.h
      sql/log_event.cc
      sql/mysqld.cc
      sql/mysqld.h
      sql/rpl_master.cc
      sql/rpl_rli.cc
      sql/rpl_slave.cc
      sql/sys_vars.cc
=== modified file 'client/CMakeLists.txt'
--- a/client/CMakeLists.txt	2010-09-20 14:17:32 +0000
+++ b/client/CMakeLists.txt	2010-12-30 11:58:25 +0000
@@ -57,6 +57,9 @@ TARGET_LINK_LIBRARIES(mysqlshow mysqlcli
 MYSQL_ADD_EXECUTABLE(mysqlbinlog mysqlbinlog.cc)
 TARGET_LINK_LIBRARIES(mysqlbinlog mysqlclient)
 
+MYSQL_ADD_EXECUTABLE(mysqlbinlogalloc mysqlbinlogalloc.cc)
+TARGET_LINK_LIBRARIES(mysqlbinlogalloc mysqlclient)
+
 MYSQL_ADD_EXECUTABLE(mysqladmin mysqladmin.cc)
 TARGET_LINK_LIBRARIES(mysqladmin mysqlclient)
 

=== added file 'client/mysqlbinlogalloc.cc'
--- a/client/mysqlbinlogalloc.cc	1970-01-01 00:00:00 +0000
+++ b/client/mysqlbinlogalloc.cc	2010-12-30 11:58:25 +0000
@@ -0,0 +1,314 @@
+/* Copyright (C) 2000 MySQL AB
+
+   This program is free software; you can redistribute it and/or modify
+   it under the terms of the GNU General Public License as published by
+   the Free Software Foundation; version 2 of the License.
+
+   This program is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+   GNU General Public License for more details.
+
+   You should have received a copy of the GNU General Public License
+   along with this program; if not, write to the Free Software
+   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA */
+
+
+#define MYSQL_CLIENT
+#undef MYSQL_SERVER
+#include "client_priv.h"
+#include <my_time.h>
+/* That one is necessary for defines of OPTION_NO_FOREIGN_KEY_CHECKS etc */
+#include "sql_priv.h"
+#include <signal.h>
+#include <my_dir.h>
+#include "log_event.h"
+#include "sql_common.h"
+
+#include <stdio.h>
+
+#define BIN_LOG_HEADER_SIZE	4
+#define PROBE_HEADER_LEN	(EVENT_LEN_OFFSET+4)
+
+
+char server_version[SERVER_VERSION_LENGTH];
+static my_bool force_opt= 0, short_form= 0;
+/**
+  Pointer to the Format_description_log_event of the currently active binlog.
+
+  This will be changed each time a new Format_description_log_event is
+  found in the binlog. It is finally destroyed at program termination.
+*/
+static Format_description_log_event* glob_description_event= NULL;
+
+#ifndef DBUG_OFF
+static const char* default_dbug_option = "d:t:o,/tmp/mysqlbinlogalloc.trace";
+#endif
+
+// needed by net_serv.c
+ulong bytes_sent = 0L, bytes_received = 0L;
+ulong mysqld_net_retry_count = 10L;
+ulong open_files_limit;
+ulong opt_binlog_rows_event_max_size;
+uint test_flags = 0;
+
+static uint start_suffix, end_suffix;
+static ulong binlog_size;
+static char* bin_logname= 0;
+static char* pass = 0;
+static FILE* result_file;
+static const char *load_default_groups[]= { "mysqlbinlogalloc","client",0 };
+
+static struct my_option my_long_options[] =
+{
+  {"help", '?', "Display this help and exit.",
+   0, 0, 0, GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0},
+#ifndef DBUG_OFF
+  {"debug", '#', "Output debug log.", (uchar**) &default_dbug_option,
+   (uchar**) &default_dbug_option, 0, GET_STR, OPT_ARG, 0, 0, 0, 0, 0, 0},
+#endif
+  {"binlog-name", 'b',
+   "Binary log name. For example, set --binlog-name=mysqlbin if \
+binlog name is mysqlbin.NNNNNN .",
+   (uchar**) &bin_logname, (uchar**) &bin_logname, 0, GET_STR_ALLOC,
+   REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
+  {"binlog-size", 'S',
+   "Preallocated binlog size(bytes). The default is 1GB. ",
+   (uchar**) &binlog_size, (uchar**) &binlog_size, 0, GET_ULONG,
+   OPT_ARG, 1024*1024L*1024L, IO_SIZE, 1024*1024L*1024L, 0, IO_SIZE, 0},
+  {"start-suffix", 's',
+   "Binlog file starting suffix. For example, --binlog-name=mysqlbin \
+--start-suffix=1 --end-suffix=5 generates five 1GB binlog files \
+from mysqlbin.000001 to mysqlbin.000005. ",
+   (uchar**) &start_suffix, (uchar**) &start_suffix, 0, GET_UINT,
+   REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
+  {"end-suffix", 'e',
+   "Binlog file stopping suffix. Must be equal to or higher than start-suffix. \
+For example, --binlog-name=mysqlbin --start-suffix=1 --end-suffix=5 \
+generates five 1GB binlog files from mysqlbin.000001 to mysqlbin.000005. ",
+   (uchar**) &end_suffix, (uchar**) &end_suffix, 0, GET_UINT,
+   REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
+  {"version", 'V', "Print version and exit.", 0, 0, 0, GET_NO_ARG, NO_ARG, 0,
+   0, 0, 0, 0, 0},
+  {0, 0, 0, 0, 0, 0, GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0}
+};
+
+
+/**
+  Auxiliary function used by error() and warning().
+
+  Prints the given text (normally "WARNING: " or "ERROR: "), followed
+  by the given vprintf-style string, followed by a newline.
+
+  @param format Printf-style format string.
+  @param args List of arguments for the format string.
+  @param msg Text to print before the string.
+*/
+static void error_or_warning(const char *format, va_list args, const char *msg)
+{
+  fprintf(stderr, "%s: ", msg);
+  vfprintf(stderr, format, args);
+  fprintf(stderr, "\n");
+}
+
+
+/**
+  This function is used in log_event.cc to report errors.
+
+  @param format Printf-style format string, followed by printf
+  varargs.
+*/
+static void sql_print_error(const char *format,...)
+{
+  va_list args;
+  va_start(args, format);
+  error_or_warning(format, args, "ERROR");
+  va_end(args);
+}
+
+
+static void print_version()
+{
+  printf("%s Ver 3.3 for %s at %s\n", my_progname, SYSTEM_TYPE, MACHINE_TYPE);
+}
+
+
+static void usage()
+{
+  print_version();
+  puts("By Yoshinori Matsunobu, Sept 2009, Sun Microsystems\n");
+  puts("This software comes with ABSOLUTELY NO WARRANTY. This is free software,\n");
+  puts("and you are welcome to modify and redistribute it under the GPL license.\n");
+
+  printf("Preallocating binary logfile. This dramatically improves write performance \
+         when using with sync-binlog=1 and traditional filesystem such as ext3. \
+         You can simply move preallocated binlog files into binlog directy on mysqld \
+         then mysqld automatically detects preallocated binlog files then using them. \
+         Note that preallocated binlog works on MySQL x.x.x or later. \n\n");
+  printf("Usage: %s --binlog-name=<prefix_of_binlog> --binlog-size=<preallocated_size> \
+         --start-suffix=<starting binlog number> --end-suffix=<stopping binlog number> \
+         \n", my_progname);
+  my_print_help(my_long_options);
+  my_print_variables(my_long_options);
+}
+
+
+extern "C" my_bool
+get_one_option(int optid, const struct my_option *opt __attribute__((unused)),
+	       char *argument)
+{
+  bool tty_password= 0;
+  switch (optid) {
+#ifndef DBUG_OFF
+  case '#':
+    DBUG_PUSH(argument ? argument : default_dbug_option);
+    break;
+#endif
+  case 'V':
+    print_version();
+    exit(0);
+  case 'p':
+    if (argument == disabled_my_option)
+      argument= (char*) "";                     // Don't require password
+    if (argument)
+    {
+      my_free(pass);
+      char *start=argument;
+      pass= my_strdup(argument,MYF(MY_FAE));
+      while (*argument) *argument++= 'x';               /* Destroy argument */
+      if (*start)
+        start[1]=0;                             /* Cut length of argument */
+    }
+    else
+      tty_password=1;
+    break;
+  case '?':
+    usage();
+    exit(0);
+  }
+  if (tty_password)
+    pass= get_tty_password(NullS);
+
+  return 0;
+}
+
+
+static int parse_args(int *argc, char*** argv)
+{
+  int ho_error;
+
+  result_file = stdout;
+  load_defaults("my",load_default_groups,argc,argv);
+  if ((ho_error=handle_options(argc, argv, my_long_options, get_one_option)))
+    exit(ho_error);
+  return 0;
+}
+
+
+int preallocate(File fd)
+{
+#ifdef HAVE_POSIX_FALLOCATE
+  if (posix_fallocate(fd, 0L, binlog_size))
+    goto err;
+#else
+  uchar buf[IO_SIZE]; 
+  memset(buf,0,IO_SIZE);
+  uint i;
+  for (i=0; i < binlog_size/IO_SIZE; i++){
+    if (my_write(fd, buf, IO_SIZE, MYF(MY_WME | MY_NABP)))
+      goto err;
+  }
+#endif
+  // writing 4-byte binlog header
+  if (my_seek(fd, 0L, MY_SEEK_SET, MYF(0))
+    && my_write(fd, (uchar*) BINLOG_MAGIC,
+       BIN_LOG_HEADER_SIZE,MYF(MY_WME | MY_NABP)))
+    goto err;
+
+  if (my_sync(fd, MYF(MY_WME)))
+    goto err;
+  return 0;
+err:
+  return -1;
+}
+
+
+bool open_and_preallocate(const char *log_file_name)
+{
+  File file= -1;
+  int open_flags= O_CREAT | O_WRONLY | O_EXCL ;
+
+  DBUG_ENTER("open");
+  DBUG_PRINT("enter", ("log_file_name: %s", log_file_name));
+
+  if ((file= my_create(log_file_name, 0, open_flags, MYF(MY_WME))) < 0)
+    goto err;
+
+  if(preallocate(file))
+      goto err;
+
+  my_close(file, MYF(0));
+  DBUG_RETURN(0);
+
+err:
+  if (file >= 0)
+    my_close(file, MYF(0));
+  DBUG_RETURN(1);
+}
+
+
+int create_files()
+{
+  uint i, err=0;
+  char log_file_name[FN_REFLEN];
+  char* work;
+
+  for (i= start_suffix; i<= end_suffix; i++)
+  {
+    work= strmake(log_file_name, bin_logname, strlen(bin_logname));
+    sprintf(work, ".%06d", i);
+    if ((err= open_and_preallocate(log_file_name)))
+      break;
+  }
+  return err;
+}
+
+
+
+int main(int argc, char **argv)
+{
+  char **defaults_argv;
+  MY_INIT(argv[0]);
+  DBUG_ENTER("main");
+  DBUG_PROCESS(argv[0]);
+
+  int ret;
+
+  ret= parse_args(&argc, (char***)&argv);
+  defaults_argv=argv;
+
+  if (ret || !bin_logname || start_suffix <= 0 || 
+    end_suffix <= 0 || start_suffix > end_suffix)
+  {
+    usage();
+    free_defaults(defaults_argv);
+    exit(1);
+  }
+  create_files();
+
+  DBUG_RETURN(0);
+}
+
+
+/*
+  We must include this here as it's compiled with different options for
+  the server
+*/
+
+#include "my_decimal.h"
+#include "decimal.c"
+#include "my_decimal.cc"
+#include "log_event.cc"
+#include "log_event_old.cc"
+#include "rpl_utility.cc"
+

=== modified file 'include/my_sys.h'
--- a/include/my_sys.h	2010-12-20 13:26:51 +0000
+++ b/include/my_sys.h	2010-12-30 11:58:25 +0000
@@ -589,6 +589,8 @@ extern my_off_t my_seek(File fd,my_off_t
 extern my_off_t my_tell(File fd,myf MyFlags);
 extern size_t my_write(File Filedes,const uchar *Buffer,size_t Count,
 		     myf MyFlags);
+extern int my_fallocate(File fd, ulong alloc_size);
+extern int my_zerofill(File fd, ulong alloc_size);
 extern size_t my_pwrite(File Filedes,const uchar *Buffer,size_t Count,
 		      my_off_t offset,myf MyFlags);
 extern size_t my_fread(FILE *stream,uchar *Buffer,size_t Count,myf MyFlags);

=== modified file 'include/mysql/psi/mysql_file.h'
--- a/include/mysql/psi/mysql_file.h	2010-12-21 15:27:40 +0000
+++ b/include/mysql/psi/mysql_file.h	2010-12-30 11:58:25 +0000
@@ -476,6 +476,18 @@
 #endif
 
 /**
+  @def mysql_file_allocate(FD, SIZE)
+  Instrumented large file allocation.
+*/
+#ifdef HAVE_PSI_INTERFACE
+  #if defined (HAVE_POSIX_FALLOCATE) || defined(__WIN__)
+    #define mysql_file_allocate(FD, SIZE) my_fallocate(FD, SIZE)
+  #else
+    #define mysql_file_allocate(FD, SIZE) my_zerofill(FD, SIZE)
+  #endif
+#endif
+
+/**
   An instrumented FILE structure.
   @sa MYSQL_FILE
 */

=== added file 'mysql-test/extra/rpl_tests/prealloc_binlog_base.test'
--- a/mysql-test/extra/rpl_tests/prealloc_binlog_base.test	1970-01-01 00:00:00 +0000
+++ b/mysql-test/extra/rpl_tests/prealloc_binlog_base.test	2010-12-30 11:58:25 +0000
@@ -0,0 +1,210 @@
+#
+# WL#4925
+# The test verifies if binlog files of automatic/static
+# preallocation will work fine with normal restart and
+# concurrency execution.
+#
+--source include/not_embedded.inc
+--source include/master-slave.inc
+
+call mtr.add_suppression("MYSQL_BIN_LOG::purge_logs was called with file ./master-bin.000009 not listed in the index");
+
+let $MYSQLD_BASEDIR= `select @@basedir`;
+let $MYSQLD_DATADIR= `select @@datadir`;
+connection slave;
+let $SLAVE_DATADIR= `select @@datadir`; 
+
+connection master;
+reset master;
+# Test that three binlogs are preallocated on master.
+file_exists $MYSQLD_DATADIR/master-bin.000001;
+file_exists $MYSQLD_DATADIR/master-bin.000002;
+file_exists $MYSQLD_DATADIR/master-bin.000003;
+
+# Test that five binlogs are preallocated on slave
+file_exists $SLAVE_DATADIR/slave-bin.000001;
+file_exists $SLAVE_DATADIR/slave-bin.000002;
+file_exists $SLAVE_DATADIR/slave-bin.000003;
+file_exists $SLAVE_DATADIR/slave-bin.000004;
+file_exists $SLAVE_DATADIR/slave-bin.000005;
+
+connection slave;
+--source include/stop_slave.inc
+--source include/wait_for_slave_to_stop.inc
+--replace_result $MASTER_MYPORT MASTER_PORT
+eval change master to master_host='127.0.0.1',master_port=$MASTER_MYPORT, master_user='root', master_connect_retry=5;
+--source include/start_slave.inc
+--source include/wait_for_slave_to_start.inc
+
+# Normal query + rotating logs test
+connection master;
+--echo # [On master]
+create table t1 (id int primary key, value int) engine=myisam;
+insert into t1 values(1, 100);
+insert into t1 values(2, 200);
+insert into t1 values(3, 100);
+update t1 set value=1000 where id=2;
+--let $binlog_file= query_get_value(SHOW MASTER STATUS, File, 1)
+--source include/show_binlog_events.inc
+
+flush logs;
+flush logs;
+insert into t1 values(4, 100);
+insert into t1 values(5, 200);
+insert into t1 values(6, 100);
+--let $binlog_file= query_get_value(SHOW MASTER STATUS, File, 1)
+--source include/show_binlog_events.inc
+
+flush logs;
+insert into t1 values(7, 100);
+insert into t1 values(8, 200);
+insert into t1 values(9, 100);
+--let $binlog_file= query_get_value(SHOW MASTER STATUS, File, 1)
+--source include/show_binlog_events.inc
+
+# Test that another three binlogs will be preallocated,
+# after the previous binlogs are consumed.
+file_exists $MYSQLD_DATADIR/master-bin.000004;
+file_exists $MYSQLD_DATADIR/master-bin.000005;
+file_exists $MYSQLD_DATADIR/master-bin.000006;
+
+sync_slave_with_master;
+--echo # Test that the binlog files of automatic preallocation 
+--echo # will work fine on slave.
+--let $binlog_file= query_get_value(SHOW MASTER STATUS, File, 1)
+--source include/show_binlog_events.inc
+flush logs;
+
+--echo # Test that the binlog files of automatic preallocation
+--echo # will work fine and the new active binlog file should
+--echo # be master-bin.000005 when master restarts.
+connection master;
+--let $rpl_server_number= 1
+--source include/rpl_restart_server.inc
+
+--let $binlog_file= master-bin.000004
+--source include/show_binlog_events.inc
+--let $binlog_file= master-bin.000005
+--source include/show_binlog_events.inc
+--error 1220
+show binlog events in 'master-bin.000006';
+flush logs;
+
+connection master;
+sync_slave_with_master;
+--echo # Test that the binlog files of automatic preallocation
+--echo # will work fine on slave.
+--let $binlog_file= query_get_value(SHOW MASTER STATUS, File, 1)
+--source include/show_binlog_events.inc
+flush logs;
+
+--echo # Test that the binlog files of static preallocation 
+--echo # will work fine when master restarts.
+connection master;
+--let $rpl_server_number= 1
+--source include/rpl_stop_server.inc
+
+# Generate files
+--exec $MYSQLD_BASEDIR/client/mysqlbinlogalloc --binlog-name=$MYSQLD_DATADIR/master-bin  --binlog-size=5000  --start-suffix=7  --end-suffix=12
+
+--let $rpl_server_number= 1
+--source include/rpl_start_server.inc
+
+--let $binlog_file= master-bin.000005
+--source include/show_binlog_events.inc
+file_exists $MYSQLD_DATADIR/master-bin.000007;
+file_exists $MYSQLD_DATADIR/master-bin.000008;
+file_exists $MYSQLD_DATADIR/master-bin.000009;
+file_exists $MYSQLD_DATADIR/master-bin.000010;
+file_exists $MYSQLD_DATADIR/master-bin.000011;
+file_exists $MYSQLD_DATADIR/master-bin.000012;
+flush logs;
+drop table t1;
+
+connection master;
+sync_slave_with_master;
+--echo # Test that the binlog files of automatic preallocation 
+--echo # will work fine on slave.
+--let $binlog_file= query_get_value(SHOW MASTER STATUS, File, 1)
+--source include/show_binlog_events.inc
+flush logs;
+
+connection master;
+--echo # Test that we just can successfully purge log to
+--echo # the last binlog file name in the index file.
+purge master logs to 'master-bin.000008';
+--error 1373
+purge master logs to 'master-bin.000009';
+
+--remove_file $MYSQLD_DATADIR/master-bin.000009
+--remove_file $MYSQLD_DATADIR/master-bin.000010
+--remove_file $MYSQLD_DATADIR/master-bin.000011
+--remove_file $MYSQLD_DATADIR/master-bin.000012
+
+
+--echo # Test that the binlog files of static preallocation
+--echo # will work fine with concurrency insert.
+connection master;
+reset master;
+
+--echo # Stop master server
+--let $rpl_server_number= 1
+--source include/rpl_stop_server.inc
+
+# Remove binlogs
+--cat_file $MYSQLD_DATADIR/master-bin.index
+--remove_file $MYSQLD_DATADIR/master-bin.index
+--remove_file $MYSQLD_DATADIR/master-bin.000001
+
+# Generate files
+--exec $MYSQLD_BASEDIR/client/mysqlbinlogalloc --binlog-name=$MYSQLD_DATADIR/master-bin  --binlog-size=20000  --start-suffix=1  --end-suffix=20
+
+--echo # Start master server
+--let $rpl_server_number= 1
+--source include/rpl_start_server.inc
+
+connection slave;
+--source include/stop_slave.inc
+--replace_result $MASTER_MYPORT MASTER_PORT
+eval change master to master_host='127.0.0.1',master_port=$MASTER_MYPORT, master_user='root', master_connect_retry=5;
+--source include/start_slave.inc
+--source include/wait_for_slave_to_start.inc
+
+# Concurrency insert
+connection master;
+create database if not exists mysqlslap;
+create table mysqlslap.t1 (id int auto_increment primary key, int_value int, vchar_value varchar(10)) engine=myisam;
+--exec $MYSQLD_BASEDIR/client/mysqlslap --iterations=1 --concurrency=10 --query="insert into mysqlslap.t1(id, int_value, vchar_value) values(null, 1, 'a'); " --host=127.0.0.1 --port=$MASTER_MYPORT --csv=mysqlslap_result.csv
+select count(*) from mysqlslap.t1;
+
+connection master;
+sync_slave_with_master;
+--echo #[On slave]
+select count(*) from mysqlslap.t1;
+
+connection master;
+drop database mysqlslap;
+
+# concurrent flush logs
+--echo # Test that the binlog files of static/automatic preallocation
+--echo # will work fine with concurrency insert and flush logs.
+--echo #[On master]
+create database if not exists mysqlslap;
+create table mysqlslap.t1 (id int auto_increment primary key, int_value int, vchar_value varchar(10)) engine=myisam;
+--exec $MYSQLD_BASEDIR/client/mysqlslap --iterations=1 --concurrency=30 --query="insert into mysqlslap.t1(id, int_value, vchar_value) values(null, 1, 'a'); flush logs;" --host=127.0.0.1 --port=$MASTER_MYPORT --csv=mysqlslap_result.csv
+select count(*) from mysqlslap.t1;
+--let $binlog_file= query_get_value(SHOW MASTER STATUS, File, 1)
+--source include/show_binlog_events.inc
+
+connection master;
+sync_slave_with_master;
+--echo #[On slave]
+select count(*) from mysqlslap.t1;
+
+--echo *** Clean up ***
+connection master;
+drop database mysqlslap;
+sync_slave_with_master;
+--source include/stop_slave.inc
+--source include/wait_for_slave_to_stop.inc
+

=== added file 'mysql-test/extra/rpl_tests/prealloc_binlog_crash_base.test'
--- a/mysql-test/extra/rpl_tests/prealloc_binlog_crash_base.test	1970-01-01 00:00:00 +0000
+++ b/mysql-test/extra/rpl_tests/prealloc_binlog_crash_base.test	2010-12-30 11:58:25 +0000
@@ -0,0 +1,84 @@
+#
+# WL#4925
+# The test verifies if binlog files of automatic/static
+# preallocation will work fine with crash shutdown.
+#
+--source include/not_embedded.inc
+--source include/master-slave.inc
+call mtr.add_suppression("Error in Log_event::read_log_event(): 'Event too small'");
+
+let $MYSQLD_BASEDIR= `select @@basedir`;
+let $MYSQLD_DATADIR= `select @@datadir`;
+
+--echo # Test that the binlog files of automatic preallocation
+--echo # will work fine when crash shutdown and restart master.
+create table t2 (id int primary key, value int) engine=myisam;
+insert into t2 values(1, 11);
+--echo # Setup the mysqld to crash at certain point
+SET SESSION debug="d,crash_before_flush_keys";
+--exec echo "wait" > $MYSQLTEST_VARDIR/tmp/mysqld.1.expect
+
+--echo # Run the crashing query
+--error 2013
+FLUSH TABLES;
+
+--exec echo "restart" > $MYSQLTEST_VARDIR/tmp/mysqld.1.expect
+--enable_reconnect
+--source include/wait_until_connected_again.inc
+--disable_reconnect
+
+insert into t2 values(2, 12);
+insert into t2 values(3, 13);
+insert into t2 values(4, 14);
+
+--let $binlog_file= master-bin.000001
+--source include/show_binlog_events.inc
+--let $binlog_file= master-bin.000002
+--source include/show_binlog_events.inc
+
+connection master;
+sync_slave_with_master;
+--echo # Test that the binlog files of automatic preallocation 
+--echo # will work fine on slave.
+--let $binlog_file= query_get_value(SHOW MASTER STATUS, File, 1)
+--source include/show_binlog_events.inc
+flush logs;
+
+--echo # Test that the binlog files of static preallocation will
+--echo # work fine when crash shutdown and restart master.
+connection master;
+# Generate files
+--exec $MYSQLD_BASEDIR/client/mysqlbinlogalloc --binlog-name=$MYSQLD_DATADIR/master-bin  --binlog-size=50000  --start-suffix=4  --end-suffix=9
+
+--echo # Setup the mysqld to crash at certain point
+SET SESSION debug="d,crash_before_flush_keys";
+--exec echo "wait" > $MYSQLTEST_VARDIR/tmp/mysqld.1.expect
+
+--echo # Run the crashing query
+--error 2013
+FLUSH TABLES;
+
+--exec echo "restart" > $MYSQLTEST_VARDIR/tmp/mysqld.1.expect
+--enable_reconnect
+--source include/wait_until_connected_again.inc
+--disable_reconnect
+
+--let $binlog_file= master-bin.000003
+--source include/show_binlog_events.inc
+file_exists $MYSQLD_DATADIR/master-bin.000004;
+file_exists $MYSQLD_DATADIR/master-bin.000005;
+file_exists $MYSQLD_DATADIR/master-bin.000006;
+file_exists $MYSQLD_DATADIR/master-bin.000007;
+file_exists $MYSQLD_DATADIR/master-bin.000008;
+file_exists $MYSQLD_DATADIR/master-bin.000009;
+drop table t2;
+
+sync_slave_with_master slave;
+connection slave;
+--echo # Test that the binlog files of automatic preallocation 
+--echo # will work fine on slave.
+--let $binlog_file= query_get_value(SHOW MASTER STATUS, File, 1)
+--source include/show_binlog_events.inc
+--source include/stop_slave.inc
+--source include/wait_for_slave_to_stop.inc
+

=== modified file 'mysql-test/r/mysqld--help-notwin.result'
--- a/mysql-test/r/mysqld--help-notwin.result	2010-12-20 13:24:37 +0000
+++ b/mysql-test/r/mysqld--help-notwin.result	2010-12-30 11:58:25 +0000
@@ -66,6 +66,33 @@ The following options may be given as th
  --binlog-ignore-db=name 
  Tells the master that updates to the given database
  should not be logged to the binary log.
+ --binlog-preallocate=# 
+ This variable is used to dynamically preallocating binlog
+ file(s) to improve binary logging performance. This is
+ epecially effective if sync-binlog=1.The default value is
+ 0, which does neither preallocate binlog automatically
+ nor uses preallocated binlog files(generated by
+ mysqlbinlogalloc). This is the as same behavior as
+ previous versions. If binlog_preallocate is 1, mysqld
+ does not preallocate binlogs automatically, but detect
+ statically preallocated binlog files. If
+ binlog_preallocate >=2, mysqld works as follows when
+ switching binlog. (1)If new binlog file does not exist,
+ mysqld creates and preallocates binlog file(s).
+ Preallocated file size is equal to max_binlog_size.
+ binlog_preallocate=N (N>=2) means N binlog files are
+ automatically generated at this point. (2)If new binlog
+ file is created beforehand(by mysqlbinlogalloc), mysqld
+ opens and uses it instead of creating new binlog file
+ (creating new binlog file is the default behavior in
+ MySQL). It is recommended that allocating many binlog
+ files by mysqlbinlogalloc before starting mysqld, and
+ setting binlog_preallocate=1 and sync_binlog=1 in my.cnf.
+ Then you can avoid overheads of writing huge amounts of
+ data to preallocate binlog. If posix_fallocate() is
+ accurately supported on targetted filesystems, setting
+ high binlog_preallocate value is fine because
+ preallocation cost is almost zero.
  --binlog-row-event-max-size=# 
  The maximum size of a row-based binary log event in
  bytes. Rows will be grouped into events smaller than this
@@ -757,6 +784,7 @@ binlog-cache-size 32768
 binlog-checksum NONE
 binlog-direct-non-transactional-updates FALSE
 binlog-format STATEMENT
+binlog-preallocate 0
 binlog-row-event-max-size 1024
 binlog-row-image FULL
 binlog-rows-query-log-events FALSE

=== added file 'mysql-test/suite/rpl/r/rpl_mixed_prealloc_binlog.result'
--- a/mysql-test/suite/rpl/r/rpl_mixed_prealloc_binlog.result	1970-01-01 00:00:00 +0000
+++ b/mysql-test/suite/rpl/r/rpl_mixed_prealloc_binlog.result	2010-12-30 11:58:25 +0000
@@ -0,0 +1,186 @@
+include/master-slave.inc
+[connection master]
+call mtr.add_suppression("MYSQL_BIN_LOG::purge_logs was called with file ./master-bin.000009 not listed in the index");
+reset master;
+include/stop_slave.inc
+include/wait_for_slave_to_stop.inc
+change master to master_host='127.0.0.1',master_port=MASTER_PORT, master_user='root', master_connect_retry=5;
+include/start_slave.inc
+include/wait_for_slave_to_start.inc
+# [On master]
+create table t1 (id int primary key, value int) engine=myisam;
+insert into t1 values(1, 100);
+insert into t1 values(2, 200);
+insert into t1 values(3, 100);
+update t1 set value=1000 where id=2;
+show binlog events in 'master-bin.000001' from <binlog_start>;
+Log_name	Pos	Event_type	Server_id	End_log_pos	Info
+master-bin.000001	#	Query	#	#	use `test`; create table t1 (id int primary key, value int) engine=myisam
+master-bin.000001	#	Query	#	#	BEGIN
+master-bin.000001	#	Query	#	#	use `test`; insert into t1 values(1, 100)
+master-bin.000001	#	Query	#	#	COMMIT
+master-bin.000001	#	Query	#	#	BEGIN
+master-bin.000001	#	Query	#	#	use `test`; insert into t1 values(2, 200)
+master-bin.000001	#	Query	#	#	COMMIT
+master-bin.000001	#	Query	#	#	BEGIN
+master-bin.000001	#	Query	#	#	use `test`; insert into t1 values(3, 100)
+master-bin.000001	#	Query	#	#	COMMIT
+master-bin.000001	#	Query	#	#	BEGIN
+master-bin.000001	#	Query	#	#	use `test`; update t1 set value=1000 where id=2
+master-bin.000001	#	Query	#	#	COMMIT
+flush logs;
+flush logs;
+insert into t1 values(4, 100);
+insert into t1 values(5, 200);
+insert into t1 values(6, 100);
+show binlog events in 'master-bin.000003' from <binlog_start>;
+Log_name	Pos	Event_type	Server_id	End_log_pos	Info
+master-bin.000003	#	Query	#	#	BEGIN
+master-bin.000003	#	Query	#	#	use `test`; insert into t1 values(4, 100)
+master-bin.000003	#	Query	#	#	COMMIT
+master-bin.000003	#	Query	#	#	BEGIN
+master-bin.000003	#	Query	#	#	use `test`; insert into t1 values(5, 200)
+master-bin.000003	#	Query	#	#	COMMIT
+master-bin.000003	#	Query	#	#	BEGIN
+master-bin.000003	#	Query	#	#	use `test`; insert into t1 values(6, 100)
+master-bin.000003	#	Query	#	#	COMMIT
+flush logs;
+insert into t1 values(7, 100);
+insert into t1 values(8, 200);
+insert into t1 values(9, 100);
+show binlog events in 'master-bin.000004' from <binlog_start>;
+Log_name	Pos	Event_type	Server_id	End_log_pos	Info
+master-bin.000004	#	Query	#	#	BEGIN
+master-bin.000004	#	Query	#	#	use `test`; insert into t1 values(7, 100)
+master-bin.000004	#	Query	#	#	COMMIT
+master-bin.000004	#	Query	#	#	BEGIN
+master-bin.000004	#	Query	#	#	use `test`; insert into t1 values(8, 200)
+master-bin.000004	#	Query	#	#	COMMIT
+master-bin.000004	#	Query	#	#	BEGIN
+master-bin.000004	#	Query	#	#	use `test`; insert into t1 values(9, 100)
+master-bin.000004	#	Query	#	#	COMMIT
+# Test that the binlog files of automatic preallocation 
+# will work fine on slave.
+show binlog events in 'slave-bin.000001' from <binlog_start>;
+Log_name	Pos	Event_type	Server_id	End_log_pos	Info
+slave-bin.000001	#	Query	#	#	BEGIN
+slave-bin.000001	#	Query	#	#	use `mtr`; INSERT INTO test_suppressions (pattern) VALUES ( NAME_CONST('pattern',_latin1'MYSQL_BIN_LOG::purge_logs was called with file ./master-bin.000009 not listed in the index' COLLATE 'latin1_swedish_ci'))
+slave-bin.000001	#	Query	#	#	COMMIT
+slave-bin.000001	#	Query	#	#	use `test`; create table t1 (id int primary key, value int) engine=myisam
+slave-bin.000001	#	Query	#	#	BEGIN
+slave-bin.000001	#	Query	#	#	use `test`; insert into t1 values(1, 100)
+slave-bin.000001	#	Query	#	#	COMMIT
+slave-bin.000001	#	Query	#	#	BEGIN
+slave-bin.000001	#	Query	#	#	use `test`; insert into t1 values(2, 200)
+slave-bin.000001	#	Query	#	#	COMMIT
+slave-bin.000001	#	Query	#	#	BEGIN
+slave-bin.000001	#	Query	#	#	use `test`; insert into t1 values(3, 100)
+slave-bin.000001	#	Query	#	#	COMMIT
+slave-bin.000001	#	Query	#	#	BEGIN
+slave-bin.000001	#	Query	#	#	use `test`; update t1 set value=1000 where id=2
+slave-bin.000001	#	Query	#	#	COMMIT
+slave-bin.000001	#	Query	#	#	BEGIN
+slave-bin.000001	#	Query	#	#	use `test`; insert into t1 values(4, 100)
+slave-bin.000001	#	Query	#	#	COMMIT
+slave-bin.000001	#	Query	#	#	BEGIN
+slave-bin.000001	#	Query	#	#	use `test`; insert into t1 values(5, 200)
+slave-bin.000001	#	Query	#	#	COMMIT
+slave-bin.000001	#	Query	#	#	BEGIN
+slave-bin.000001	#	Query	#	#	use `test`; insert into t1 values(6, 100)
+slave-bin.000001	#	Query	#	#	COMMIT
+slave-bin.000001	#	Query	#	#	BEGIN
+slave-bin.000001	#	Query	#	#	use `test`; insert into t1 values(7, 100)
+slave-bin.000001	#	Query	#	#	COMMIT
+slave-bin.000001	#	Query	#	#	BEGIN
+slave-bin.000001	#	Query	#	#	use `test`; insert into t1 values(8, 200)
+slave-bin.000001	#	Query	#	#	COMMIT
+slave-bin.000001	#	Query	#	#	BEGIN
+slave-bin.000001	#	Query	#	#	use `test`; insert into t1 values(9, 100)
+slave-bin.000001	#	Query	#	#	COMMIT
+flush logs;
+# Test that the binlog files of automatic preallocation
+# will work fine and the new active binlog file should
+# be master-bin.000005 when master restarts.
+include/rpl_restart_server.inc [server_number=1]
+show binlog events in 'master-bin.000004' from <binlog_start>;
+Log_name	Pos	Event_type	Server_id	End_log_pos	Info
+master-bin.000004	#	Query	#	#	BEGIN
+master-bin.000004	#	Query	#	#	use `test`; insert into t1 values(7, 100)
+master-bin.000004	#	Query	#	#	COMMIT
+master-bin.000004	#	Query	#	#	BEGIN
+master-bin.000004	#	Query	#	#	use `test`; insert into t1 values(8, 200)
+master-bin.000004	#	Query	#	#	COMMIT
+master-bin.000004	#	Query	#	#	BEGIN
+master-bin.000004	#	Query	#	#	use `test`; insert into t1 values(9, 100)
+master-bin.000004	#	Query	#	#	COMMIT
+master-bin.000004	#	Stop	#	#	
+show binlog events in 'master-bin.000005' from <binlog_start>;
+Log_name	Pos	Event_type	Server_id	End_log_pos	Info
+show binlog events in 'master-bin.000006';
+ERROR HY000: Error when executing command SHOW BINLOG EVENTS: Could not find target log
+flush logs;
+# Test that the binlog files of automatic preallocation
+# will work fine on slave.
+show binlog events in 'slave-bin.000002' from <binlog_start>;
+Log_name	Pos	Event_type	Server_id	End_log_pos	Info
+flush logs;
+# Test that the binlog files of static preallocation 
+# will work fine when master restarts.
+include/rpl_stop_server.inc [server_number=1]
+include/rpl_start_server.inc [server_number=1]
+show binlog events in 'master-bin.000005' from <binlog_start>;
+Log_name	Pos	Event_type	Server_id	End_log_pos	Info
+master-bin.000005	#	Rotate	#	#	master-bin.000006;pos=4
+flush logs;
+drop table t1;
+# Test that the binlog files of automatic preallocation 
+# will work fine on slave.
+show binlog events in 'slave-bin.000003' from <binlog_start>;
+Log_name	Pos	Event_type	Server_id	End_log_pos	Info
+slave-bin.000003	#	Query	#	#	use `test`; DROP TABLE `t1` /* generated by server */
+flush logs;
+# Test that we just can successfully purge log to
+# the last binlog file name in the index file.
+purge master logs to 'master-bin.000008';
+purge master logs to 'master-bin.000009';
+ERROR HY000: Target log not found in binlog index
+# Test that the binlog files of static preallocation
+# will work fine with concurrency insert.
+reset master;
+# Stop master server
+include/rpl_stop_server.inc [server_number=1]
+./master-bin.000001
+# Start master server
+include/rpl_start_server.inc [server_number=1]
+include/stop_slave.inc
+change master to master_host='127.0.0.1',master_port=MASTER_PORT, master_user='root', master_connect_retry=5;
+include/start_slave.inc
+include/wait_for_slave_to_start.inc
+create database if not exists mysqlslap;
+create table mysqlslap.t1 (id int auto_increment primary key, int_value int, vchar_value varchar(10)) engine=myisam;
+select count(*) from mysqlslap.t1;
+count(*)
+10
+#[On slave]
+select count(*) from mysqlslap.t1;
+count(*)
+10
+drop database mysqlslap;
+# Test that the binlog files of static/automatic preallocation
+# will work fine with concurrency insert and flush logs.
+#[On master]
+create database if not exists mysqlslap;
+create table mysqlslap.t1 (id int auto_increment primary key, int_value int, vchar_value varchar(10)) engine=myisam;
+select count(*) from mysqlslap.t1;
+count(*)
+30
+show binlog events in 'master-bin.000031' from <binlog_start>;
+Log_name	Pos	Event_type	Server_id	End_log_pos	Info
+#[On slave]
+select count(*) from mysqlslap.t1;
+count(*)
+30
+*** Clean up ***
+drop database mysqlslap;
+include/stop_slave.inc
+include/wait_for_slave_to_stop.inc

=== added file 'mysql-test/suite/rpl/r/rpl_mixed_prealloc_binlog_crash.result'
--- a/mysql-test/suite/rpl/r/rpl_mixed_prealloc_binlog_crash.result	1970-01-01 00:00:00 +0000
+++ b/mysql-test/suite/rpl/r/rpl_mixed_prealloc_binlog_crash.result	2010-12-30 11:58:25 +0000
@@ -0,0 +1,75 @@
+include/master-slave.inc
+[connection master]
+call mtr.add_suppression("Error in Log_event::read_log_event(): 'Event too small'");
+# Test that the binlog files of automatic preallocation
+# will work fine when crash shutdown and restart master.
+create table t2 (id int primary key, value int) engine=myisam;
+insert into t2 values(1, 11);
+# Setup the mysqld to crash at certain point
+SET SESSION debug="d,crash_before_flush_keys";
+# Run the crashing query
+FLUSH TABLES;
+ERROR HY000: Lost connection to MySQL server during query
+insert into t2 values(2, 12);
+insert into t2 values(3, 13);
+insert into t2 values(4, 14);
+show binlog events in 'master-bin.000001' from <binlog_start>;
+Log_name	Pos	Event_type	Server_id	End_log_pos	Info
+master-bin.000001	#	Query	#	#	BEGIN
+master-bin.000001	#	Query	#	#	use `mtr`; INSERT INTO test_suppressions (pattern) VALUES ( NAME_CONST('pattern',_latin1'Error in Log_event::read_log_event(): \'Event too small\'' COLLATE 'latin1_swedish_ci'))
+master-bin.000001	#	Query	#	#	COMMIT
+master-bin.000001	#	Query	#	#	use `test`; create table t2 (id int primary key, value int) engine=myisam
+master-bin.000001	#	Query	#	#	BEGIN
+master-bin.000001	#	Query	#	#	use `test`; insert into t2 values(1, 11)
+master-bin.000001	#	Query	#	#	COMMIT
+Warnings:
+Warning	#	Wrong offset or I/O error. It was likely that preallocated binlog file was not closed properly (i.e. mysqld crash).
+show binlog events in 'master-bin.000002' from <binlog_start>;
+Log_name	Pos	Event_type	Server_id	End_log_pos	Info
+master-bin.000002	#	Query	#	#	BEGIN
+master-bin.000002	#	Query	#	#	use `test`; insert into t2 values(2, 12)
+master-bin.000002	#	Query	#	#	COMMIT
+master-bin.000002	#	Query	#	#	BEGIN
+master-bin.000002	#	Query	#	#	use `test`; insert into t2 values(3, 13)
+master-bin.000002	#	Query	#	#	COMMIT
+master-bin.000002	#	Query	#	#	BEGIN
+master-bin.000002	#	Query	#	#	use `test`; insert into t2 values(4, 14)
+master-bin.000002	#	Query	#	#	COMMIT
+# Test that the binlog files of automatic preallocation 
+# will work fine on slave.
+show binlog events in 'slave-bin.000001' from <binlog_start>;
+Log_name	Pos	Event_type	Server_id	End_log_pos	Info
+slave-bin.000001	#	Query	#	#	BEGIN
+slave-bin.000001	#	Query	#	#	use `mtr`; INSERT INTO test_suppressions (pattern) VALUES ( NAME_CONST('pattern',_latin1'Error in Log_event::read_log_event(): \'Event too small\'' COLLATE 'latin1_swedish_ci'))
+slave-bin.000001	#	Query	#	#	COMMIT
+slave-bin.000001	#	Query	#	#	use `test`; create table t2 (id int primary key, value int) engine=myisam
+slave-bin.000001	#	Query	#	#	BEGIN
+slave-bin.000001	#	Query	#	#	use `test`; insert into t2 values(1, 11)
+slave-bin.000001	#	Query	#	#	COMMIT
+slave-bin.000001	#	Query	#	#	BEGIN
+slave-bin.000001	#	Query	#	#	use `test`; insert into t2 values(2, 12)
+slave-bin.000001	#	Query	#	#	COMMIT
+slave-bin.000001	#	Query	#	#	BEGIN
+slave-bin.000001	#	Query	#	#	use `test`; insert into t2 values(3, 13)
+slave-bin.000001	#	Query	#	#	COMMIT
+slave-bin.000001	#	Query	#	#	BEGIN
+slave-bin.000001	#	Query	#	#	use `test`; insert into t2 values(4, 14)
+slave-bin.000001	#	Query	#	#	COMMIT
+flush logs;
+# Test that the binlog files of static preallocation will
+# work fine when crash shutdown and restart master.
+# Setup the mysqld to crash at certain point
+SET SESSION debug="d,crash_before_flush_keys";
+# Run the crashing query
+FLUSH TABLES;
+ERROR HY000: Lost connection to MySQL server during query
+show binlog events in 'master-bin.000003' from <binlog_start>;
+Log_name	Pos	Event_type	Server_id	End_log_pos	Info
+drop table t2;
+# Test that the binlog files of automatic preallocation 
+# will work fine on slave.
+show binlog events in 'slave-bin.000002' from <binlog_start>;
+Log_name	Pos	Event_type	Server_id	End_log_pos	Info
+slave-bin.000002	#	Query	#	#	use `test`; DROP TABLE `t2` /* generated by server */
+include/stop_slave.inc
+include/wait_for_slave_to_stop.inc

=== added file 'mysql-test/suite/rpl/r/rpl_mixed_prealloc_binlog_max_cache_size.result'
--- a/mysql-test/suite/rpl/r/rpl_mixed_prealloc_binlog_max_cache_size.result	1970-01-01 00:00:00 +0000
+++ b/mysql-test/suite/rpl/r/rpl_mixed_prealloc_binlog_max_cache_size.result	2010-12-30 11:58:25 +0000
@@ -0,0 +1,205 @@
+include/master-slave.inc
+[connection master]
+call mtr.add_suppression("Unsafe statement written to the binary log using statement format since BINLOG_FORMAT = STATEMENT");
+call mtr.add_suppression("Option binlog_cache_size ");
+SET GLOBAL max_binlog_cache_size = 4096;
+Warnings:
+Warning	1712	Option binlog_cache_size (32768) is greater than max_binlog_cache_size (4096); setting binlog_cache_size equal to max_binlog_cache_size.
+SET GLOBAL binlog_cache_size = 4096;
+SET GLOBAL max_binlog_stmt_cache_size = 4096;
+Warnings:
+Warning	1725	Option binlog_stmt_cache_size (32768) is greater than max_binlog_stmt_cache_size (4096); setting binlog_stmt_cache_size equal to max_binlog_stmt_cache_size.
+SET GLOBAL binlog_stmt_cache_size = 4096;
+CREATE TABLE t1(a INT PRIMARY KEY, data VARCHAR(30000)) ENGINE=Innodb;
+CREATE TABLE t2(a INT PRIMARY KEY, data VARCHAR(30000)) ENGINE=MyIsam;
+CREATE TABLE t3(a INT PRIMARY KEY, data VARCHAR(30000)) ENGINE=Innodb;
+########################################################################################
+#                                   1 - SINGLE STATEMENT
+########################################################################################
+*** Single statement on transactional table ***
+Got one of the listed errors
+*** Single statement on non-transactional table ***
+Got one of the listed errors
+include/wait_for_slave_sql_error_and_skip.inc [errno=1590]
+*** Single statement on both transactional and non-transactional tables. ***
+Got one of the listed errors
+include/wait_for_slave_sql_error_and_skip.inc [errno=1590]
+include/diff_tables.inc [master:t1,slave:t1]
+########################################################################################
+#                             2 - BEGIN - IMPLICIT COMMIT by DDL
+########################################################################################
+TRUNCATE TABLE t1;
+TRUNCATE TABLE t2;
+TRUNCATE TABLE t3;
+BEGIN;
+Got one of the listed errors
+Got one of the listed errors
+Got one of the listed errors
+BEGIN;
+Got one of the listed errors
+Got one of the listed errors
+BEGIN;
+Got one of the listed errors
+Got one of the listed errors
+include/diff_tables.inc [master:t1,slave:t1]
+########################################################################################
+#                                     3 - BEGIN - COMMIT
+########################################################################################
+TRUNCATE TABLE t1;
+TRUNCATE TABLE t2;
+TRUNCATE TABLE t3;
+BEGIN;
+Got one of the listed errors
+Got one of the listed errors
+Got one of the listed errors
+COMMIT;
+include/diff_tables.inc [master:t1,slave:t1]
+########################################################################################
+#                                      4 - BEGIN - ROLLBACK
+########################################################################################
+TRUNCATE TABLE t1;
+TRUNCATE TABLE t2;
+TRUNCATE TABLE t3;
+BEGIN;
+Got one of the listed errors
+Got one of the listed errors
+Got one of the listed errors
+ROLLBACK;
+Warnings:
+Warning	1196	Some non-transactional changed tables couldn't be rolled back
+include/diff_tables.inc [master:t1,slave:t1]
+########################################################################################
+#                                         5 - PROCEDURE 
+########################################################################################
+TRUNCATE TABLE t1;
+TRUNCATE TABLE t2;
+TRUNCATE TABLE t3;
+CREATE PROCEDURE p1(pd VARCHAR(30000))
+BEGIN
+INSERT INTO t1 (a, data) VALUES (1, pd);
+INSERT INTO t1 (a, data) VALUES (2, pd);
+INSERT INTO t1 (a, data) VALUES (3, pd);
+INSERT INTO t1 (a, data) VALUES (4, pd);
+INSERT INTO t1 (a, data) VALUES (5, 's');
+END//
+TRUNCATE TABLE t1;
+TRUNCATE TABLE t1;
+BEGIN;
+Got one of the listed errors
+COMMIT;
+TRUNCATE TABLE t1;
+BEGIN;
+Got one of the listed errors
+ROLLBACK;
+include/diff_tables.inc [master:t1,slave:t1]
+########################################################################################
+#                                           6 - XID
+########################################################################################
+TRUNCATE TABLE t1;
+TRUNCATE TABLE t2;
+TRUNCATE TABLE t3;
+BEGIN;
+Got one of the listed errors
+Got one of the listed errors
+Got one of the listed errors
+ROLLBACK TO sv;
+Warnings:
+Warning	1196	Some non-transactional changed tables couldn't be rolled back
+COMMIT;
+include/diff_tables.inc [master:t1,slave:t1]
+########################################################################################
+#                                        7 - NON-TRANS TABLE
+########################################################################################
+TRUNCATE TABLE t1;
+TRUNCATE TABLE t2;
+TRUNCATE TABLE t3;
+BEGIN;
+Got one of the listed errors
+Got one of the listed errors
+Got one of the listed errors
+COMMIT;
+BEGIN;
+Got one of the listed errors
+COMMIT;
+include/diff_tables.inc [master:t1,slave:t1]
+########################################################################
+#      8 - Bug#55375(Regression Bug) Transaction bigger than
+#          max_binlog_cache_size crashes slave
+########################################################################
+# [ On Slave ]
+SET GLOBAL max_binlog_cache_size = 4096;
+Warnings:
+Warning	1712	Option binlog_cache_size (32768) is greater than max_binlog_cache_size (4096); setting binlog_cache_size equal to max_binlog_cache_size.
+SET GLOBAL binlog_cache_size = 4096;
+SET GLOBAL max_binlog_stmt_cache_size = 4096;
+Warnings:
+Warning	1725	Option binlog_stmt_cache_size (32768) is greater than max_binlog_stmt_cache_size (4096); setting binlog_stmt_cache_size equal to max_binlog_stmt_cache_size.
+SET GLOBAL binlog_stmt_cache_size = 4096;
+include/stop_slave.inc
+include/start_slave.inc
+CALL mtr.add_suppression("Multi-statement transaction required more than 'max_binlog_cache_size' bytes of storage.*");
+CALL mtr.add_suppression("Multi-statement transaction required more than 'max_binlog_stmt_cache_size' bytes of storage.*");
+CALL mtr.add_suppression("Writing one row to the row-based binary log failed.*");
+TRUNCATE t1;
+SET GLOBAL max_binlog_cache_size= ORIGINAL_VALUE;
+SET GLOBAL binlog_cache_size= ORIGINAL_VALUE;
+SET GLOBAL max_binlog_stmt_cache_size= ORIGINAL_VALUE;
+SET GLOBAL binlog_stmt_cache_size= ORIGINAL_VALUE;
+BEGIN;
+Repeat statement 'INSERT INTO t1 VALUES($n, repeat("a", 32))' 128 times
+COMMIT;
+include/wait_for_slave_sql_error.inc [errno=1197]
+SELECT count(*) FROM t1;
+count(*)
+0
+show binlog events in 'slave-bin.000001' from <binlog_start>;
+Log_name	Pos	Event_type	Server_id	End_log_pos	Info
+SET GLOBAL max_binlog_cache_size= ORIGINAL_VALUE;
+SET GLOBAL binlog_cache_size= ORIGINAL_VALUE;
+SET GLOBAL max_binlog_stmt_cache_size= ORIGINAL_VALUE;
+SET GLOBAL binlog_stmt_cache_size= ORIGINAL_VALUE;
+include/stop_slave.inc
+include/start_slave.inc
+SELECT count(*) FROM t1;
+count(*)
+128
+########################################################################################
+#                       CHECK MAX_BINLOG_CACHE_SIZE and BINLOG_CACHE_SIZE
+########################################################################################
+SET @@GLOBAL.MAX_BINLOG_CACHE_SIZE= 8192;
+Warnings:
+Warning	1712	Option binlog_cache_size (32768) is greater than max_binlog_cache_size (8192); setting binlog_cache_size equal to max_binlog_cache_size.
+SHOW VARIABLES LIKE 'MAX_BINLOG_CACHE_SIZE';
+Variable_name	Value
+max_binlog_cache_size	8192
+SHOW VARIABLES LIKE 'BINLOG_CACHE_SIZE';
+Variable_name	Value
+binlog_cache_size	8192
+SET @@GLOBAL.BINLOG_CACHE_SIZE= 16384;
+Warnings:
+Warning	1712	Option binlog_cache_size (16384) is greater than max_binlog_cache_size (8192); setting binlog_cache_size equal to max_binlog_cache_size.
+SHOW VARIABLES LIKE 'MAX_BINLOG_CACHE_SIZE';
+Variable_name	Value
+max_binlog_cache_size	8192
+SHOW VARIABLES LIKE 'BINLOG_CACHE_SIZE';
+Variable_name	Value
+binlog_cache_size	8192
+SET @@GLOBAL.MAX_BINLOG_CACHE_SIZE= 4096;
+Warnings:
+Warning	1712	Option binlog_cache_size (8192) is greater than max_binlog_cache_size (4096); setting binlog_cache_size equal to max_binlog_cache_size.
+SHOW VARIABLES LIKE 'MAX_BINLOG_CACHE_SIZE';
+Variable_name	Value
+max_binlog_cache_size	4096
+SHOW VARIABLES LIKE 'BINLOG_CACHE_SIZE';
+Variable_name	Value
+binlog_cache_size	4096
+########################################################################################
+#                                        CLEAN
+########################################################################################
+DROP TABLE t1;
+DROP TABLE t2;
+DROP TABLE t3;
+DROP TABLE IF EXISTS t4;
+DROP TABLE t5;
+DROP PROCEDURE p1;
+include/rpl_end.inc

=== added file 'mysql-test/suite/rpl/r/rpl_row_prealloc_binlog.result'
--- a/mysql-test/suite/rpl/r/rpl_row_prealloc_binlog.result	1970-01-01 00:00:00 +0000
+++ b/mysql-test/suite/rpl/r/rpl_row_prealloc_binlog.result	2010-12-30 11:58:25 +0000
@@ -0,0 +1,210 @@
+include/master-slave.inc
+[connection master]
+call mtr.add_suppression("MYSQL_BIN_LOG::purge_logs was called with file ./master-bin.000009 not listed in the index");
+reset master;
+include/stop_slave.inc
+include/wait_for_slave_to_stop.inc
+change master to master_host='127.0.0.1',master_port=MASTER_PORT, master_user='root', master_connect_retry=5;
+include/start_slave.inc
+include/wait_for_slave_to_start.inc
+# [On master]
+create table t1 (id int primary key, value int) engine=myisam;
+insert into t1 values(1, 100);
+insert into t1 values(2, 200);
+insert into t1 values(3, 100);
+update t1 set value=1000 where id=2;
+show binlog events in 'master-bin.000001' from <binlog_start>;
+Log_name	Pos	Event_type	Server_id	End_log_pos	Info
+master-bin.000001	#	Query	#	#	use `test`; create table t1 (id int primary key, value int) engine=myisam
+master-bin.000001	#	Query	#	#	BEGIN
+master-bin.000001	#	Table_map	#	#	table_id: # (test.t1)
+master-bin.000001	#	Write_rows	#	#	table_id: # flags: STMT_END_F
+master-bin.000001	#	Query	#	#	COMMIT
+master-bin.000001	#	Query	#	#	BEGIN
+master-bin.000001	#	Table_map	#	#	table_id: # (test.t1)
+master-bin.000001	#	Write_rows	#	#	table_id: # flags: STMT_END_F
+master-bin.000001	#	Query	#	#	COMMIT
+master-bin.000001	#	Query	#	#	BEGIN
+master-bin.000001	#	Table_map	#	#	table_id: # (test.t1)
+master-bin.000001	#	Write_rows	#	#	table_id: # flags: STMT_END_F
+master-bin.000001	#	Query	#	#	COMMIT
+master-bin.000001	#	Query	#	#	BEGIN
+master-bin.000001	#	Table_map	#	#	table_id: # (test.t1)
+master-bin.000001	#	Update_rows	#	#	table_id: # flags: STMT_END_F
+master-bin.000001	#	Query	#	#	COMMIT
+flush logs;
+flush logs;
+insert into t1 values(4, 100);
+insert into t1 values(5, 200);
+insert into t1 values(6, 100);
+show binlog events in 'master-bin.000003' from <binlog_start>;
+Log_name	Pos	Event_type	Server_id	End_log_pos	Info
+master-bin.000003	#	Query	#	#	BEGIN
+master-bin.000003	#	Table_map	#	#	table_id: # (test.t1)
+master-bin.000003	#	Write_rows	#	#	table_id: # flags: STMT_END_F
+master-bin.000003	#	Query	#	#	COMMIT
+master-bin.000003	#	Query	#	#	BEGIN
+master-bin.000003	#	Table_map	#	#	table_id: # (test.t1)
+master-bin.000003	#	Write_rows	#	#	table_id: # flags: STMT_END_F
+master-bin.000003	#	Query	#	#	COMMIT
+master-bin.000003	#	Query	#	#	BEGIN
+master-bin.000003	#	Table_map	#	#	table_id: # (test.t1)
+master-bin.000003	#	Write_rows	#	#	table_id: # flags: STMT_END_F
+master-bin.000003	#	Query	#	#	COMMIT
+flush logs;
+insert into t1 values(7, 100);
+insert into t1 values(8, 200);
+insert into t1 values(9, 100);
+show binlog events in 'master-bin.000004' from <binlog_start>;
+Log_name	Pos	Event_type	Server_id	End_log_pos	Info
+master-bin.000004	#	Query	#	#	BEGIN
+master-bin.000004	#	Table_map	#	#	table_id: # (test.t1)
+master-bin.000004	#	Write_rows	#	#	table_id: # flags: STMT_END_F
+master-bin.000004	#	Query	#	#	COMMIT
+master-bin.000004	#	Query	#	#	BEGIN
+master-bin.000004	#	Table_map	#	#	table_id: # (test.t1)
+master-bin.000004	#	Write_rows	#	#	table_id: # flags: STMT_END_F
+master-bin.000004	#	Query	#	#	COMMIT
+master-bin.000004	#	Query	#	#	BEGIN
+master-bin.000004	#	Table_map	#	#	table_id: # (test.t1)
+master-bin.000004	#	Write_rows	#	#	table_id: # flags: STMT_END_F
+master-bin.000004	#	Query	#	#	COMMIT
+# Test that the binlog files of automatic preallocation 
+# will work fine on slave.
+show binlog events in 'slave-bin.000001' from <binlog_start>;
+Log_name	Pos	Event_type	Server_id	End_log_pos	Info
+slave-bin.000001	#	Query	#	#	BEGIN
+slave-bin.000001	#	Table_map	#	#	table_id: # (mtr.test_suppressions)
+slave-bin.000001	#	Write_rows	#	#	table_id: # flags: STMT_END_F
+slave-bin.000001	#	Query	#	#	COMMIT
+slave-bin.000001	#	Query	#	#	use `test`; create table t1 (id int primary key, value int) engine=myisam
+slave-bin.000001	#	Query	#	#	BEGIN
+slave-bin.000001	#	Table_map	#	#	table_id: # (test.t1)
+slave-bin.000001	#	Write_rows	#	#	table_id: # flags: STMT_END_F
+slave-bin.000001	#	Query	#	#	COMMIT
+slave-bin.000001	#	Query	#	#	BEGIN
+slave-bin.000001	#	Table_map	#	#	table_id: # (test.t1)
+slave-bin.000001	#	Write_rows	#	#	table_id: # flags: STMT_END_F
+slave-bin.000001	#	Query	#	#	COMMIT
+slave-bin.000001	#	Query	#	#	BEGIN
+slave-bin.000001	#	Table_map	#	#	table_id: # (test.t1)
+slave-bin.000001	#	Write_rows	#	#	table_id: # flags: STMT_END_F
+slave-bin.000001	#	Query	#	#	COMMIT
+slave-bin.000001	#	Query	#	#	BEGIN
+slave-bin.000001	#	Table_map	#	#	table_id: # (test.t1)
+slave-bin.000001	#	Update_rows	#	#	table_id: # flags: STMT_END_F
+slave-bin.000001	#	Query	#	#	COMMIT
+slave-bin.000001	#	Query	#	#	BEGIN
+slave-bin.000001	#	Table_map	#	#	table_id: # (test.t1)
+slave-bin.000001	#	Write_rows	#	#	table_id: # flags: STMT_END_F
+slave-bin.000001	#	Query	#	#	COMMIT
+slave-bin.000001	#	Query	#	#	BEGIN
+slave-bin.000001	#	Table_map	#	#	table_id: # (test.t1)
+slave-bin.000001	#	Write_rows	#	#	table_id: # flags: STMT_END_F
+slave-bin.000001	#	Query	#	#	COMMIT
+slave-bin.000001	#	Query	#	#	BEGIN
+slave-bin.000001	#	Table_map	#	#	table_id: # (test.t1)
+slave-bin.000001	#	Write_rows	#	#	table_id: # flags: STMT_END_F
+slave-bin.000001	#	Query	#	#	COMMIT
+slave-bin.000001	#	Query	#	#	BEGIN
+slave-bin.000001	#	Table_map	#	#	table_id: # (test.t1)
+slave-bin.000001	#	Write_rows	#	#	table_id: # flags: STMT_END_F
+slave-bin.000001	#	Query	#	#	COMMIT
+slave-bin.000001	#	Query	#	#	BEGIN
+slave-bin.000001	#	Table_map	#	#	table_id: # (test.t1)
+slave-bin.000001	#	Write_rows	#	#	table_id: # flags: STMT_END_F
+slave-bin.000001	#	Query	#	#	COMMIT
+slave-bin.000001	#	Query	#	#	BEGIN
+slave-bin.000001	#	Table_map	#	#	table_id: # (test.t1)
+slave-bin.000001	#	Write_rows	#	#	table_id: # flags: STMT_END_F
+slave-bin.000001	#	Query	#	#	COMMIT
+flush logs;
+# Test that the binlog files of automatic preallocation
+# will work fine and the new active binlog file should
+# be master-bin.000005 when master restarts.
+include/rpl_restart_server.inc [server_number=1]
+show binlog events in 'master-bin.000004' from <binlog_start>;
+Log_name	Pos	Event_type	Server_id	End_log_pos	Info
+master-bin.000004	#	Query	#	#	BEGIN
+master-bin.000004	#	Table_map	#	#	table_id: # (test.t1)
+master-bin.000004	#	Write_rows	#	#	table_id: # flags: STMT_END_F
+master-bin.000004	#	Query	#	#	COMMIT
+master-bin.000004	#	Query	#	#	BEGIN
+master-bin.000004	#	Table_map	#	#	table_id: # (test.t1)
+master-bin.000004	#	Write_rows	#	#	table_id: # flags: STMT_END_F
+master-bin.000004	#	Query	#	#	COMMIT
+master-bin.000004	#	Query	#	#	BEGIN
+master-bin.000004	#	Table_map	#	#	table_id: # (test.t1)
+master-bin.000004	#	Write_rows	#	#	table_id: # flags: STMT_END_F
+master-bin.000004	#	Query	#	#	COMMIT
+master-bin.000004	#	Stop	#	#	
+show binlog events in 'master-bin.000005' from <binlog_start>;
+Log_name	Pos	Event_type	Server_id	End_log_pos	Info
+show binlog events in 'master-bin.000006';
+ERROR HY000: Error when executing command SHOW BINLOG EVENTS: Could not find target log
+flush logs;
+# Test that the binlog files of automatic preallocation
+# will work fine on slave.
+show binlog events in 'slave-bin.000002' from <binlog_start>;
+Log_name	Pos	Event_type	Server_id	End_log_pos	Info
+flush logs;
+# Test that the binlog files of static preallocation 
+# will work fine when master restarts.
+include/rpl_stop_server.inc [server_number=1]
+include/rpl_start_server.inc [server_number=1]
+show binlog events in 'master-bin.000005' from <binlog_start>;
+Log_name	Pos	Event_type	Server_id	End_log_pos	Info
+master-bin.000005	#	Rotate	#	#	master-bin.000006;pos=4
+flush logs;
+drop table t1;
+# Test that the binlog files of automatic preallocation 
+# will work fine on slave.
+show binlog events in 'slave-bin.000003' from <binlog_start>;
+Log_name	Pos	Event_type	Server_id	End_log_pos	Info
+slave-bin.000003	#	Query	#	#	use `test`; DROP TABLE `t1` /* generated by server */
+flush logs;
+# Test that we just can successfully purge log to
+# the last binlog file name in the index file.
+purge master logs to 'master-bin.000008';
+purge master logs to 'master-bin.000009';
+ERROR HY000: Target log not found in binlog index
+# Test that the binlog files of static preallocation
+# will work fine with concurrency insert.
+reset master;
+# Stop master server
+include/rpl_stop_server.inc [server_number=1]
+./master-bin.000001
+# Start master server
+include/rpl_start_server.inc [server_number=1]
+include/stop_slave.inc
+change master to master_host='127.0.0.1',master_port=MASTER_PORT, master_user='root', master_connect_retry=5;
+include/start_slave.inc
+include/wait_for_slave_to_start.inc
+create database if not exists mysqlslap;
+create table mysqlslap.t1 (id int auto_increment primary key, int_value int, vchar_value varchar(10)) engine=myisam;
+select count(*) from mysqlslap.t1;
+count(*)
+10
+#[On slave]
+select count(*) from mysqlslap.t1;
+count(*)
+10
+drop database mysqlslap;
+# Test that the binlog files of static/automatic preallocation
+# will work fine with concurrency insert and flush logs.
+#[On master]
+create database if not exists mysqlslap;
+create table mysqlslap.t1 (id int auto_increment primary key, int_value int, vchar_value varchar(10)) engine=myisam;
+select count(*) from mysqlslap.t1;
+count(*)
+30
+show binlog events in 'master-bin.000031' from <binlog_start>;
+Log_name	Pos	Event_type	Server_id	End_log_pos	Info
+#[On slave]
+select count(*) from mysqlslap.t1;
+count(*)
+30
+*** Clean up ***
+drop database mysqlslap;
+include/stop_slave.inc
+include/wait_for_slave_to_stop.inc

=== added file 'mysql-test/suite/rpl/r/rpl_row_prealloc_binlog_crash.result'
--- a/mysql-test/suite/rpl/r/rpl_row_prealloc_binlog_crash.result	1970-01-01 00:00:00 +0000
+++ b/mysql-test/suite/rpl/r/rpl_row_prealloc_binlog_crash.result	2010-12-30 11:58:25 +0000
@@ -0,0 +1,85 @@
+include/master-slave.inc
+[connection master]
+call mtr.add_suppression("Error in Log_event::read_log_event(): 'Event too small'");
+# Test that the binlog files of automatic preallocation
+# will work fine when crash shutdown and restart master.
+create table t2 (id int primary key, value int) engine=myisam;
+insert into t2 values(1, 11);
+# Setup the mysqld to crash at certain point
+SET SESSION debug="d,crash_before_flush_keys";
+# Run the crashing query
+FLUSH TABLES;
+ERROR HY000: Lost connection to MySQL server during query
+insert into t2 values(2, 12);
+insert into t2 values(3, 13);
+insert into t2 values(4, 14);
+show binlog events in 'master-bin.000001' from <binlog_start>;
+Log_name	Pos	Event_type	Server_id	End_log_pos	Info
+master-bin.000001	#	Query	#	#	BEGIN
+master-bin.000001	#	Table_map	#	#	table_id: # (mtr.test_suppressions)
+master-bin.000001	#	Write_rows	#	#	table_id: # flags: STMT_END_F
+master-bin.000001	#	Query	#	#	COMMIT
+master-bin.000001	#	Query	#	#	use `test`; create table t2 (id int primary key, value int) engine=myisam
+master-bin.000001	#	Query	#	#	BEGIN
+master-bin.000001	#	Table_map	#	#	table_id: # (test.t2)
+master-bin.000001	#	Write_rows	#	#	table_id: # flags: STMT_END_F
+master-bin.000001	#	Query	#	#	COMMIT
+Warnings:
+Warning	#	Wrong offset or I/O error. It was likely that preallocated binlog file was not closed properly (i.e. mysqld crash).
+show binlog events in 'master-bin.000002' from <binlog_start>;
+Log_name	Pos	Event_type	Server_id	End_log_pos	Info
+master-bin.000002	#	Query	#	#	BEGIN
+master-bin.000002	#	Table_map	#	#	table_id: # (test.t2)
+master-bin.000002	#	Write_rows	#	#	table_id: # flags: STMT_END_F
+master-bin.000002	#	Query	#	#	COMMIT
+master-bin.000002	#	Query	#	#	BEGIN
+master-bin.000002	#	Table_map	#	#	table_id: # (test.t2)
+master-bin.000002	#	Write_rows	#	#	table_id: # flags: STMT_END_F
+master-bin.000002	#	Query	#	#	COMMIT
+master-bin.000002	#	Query	#	#	BEGIN
+master-bin.000002	#	Table_map	#	#	table_id: # (test.t2)
+master-bin.000002	#	Write_rows	#	#	table_id: # flags: STMT_END_F
+master-bin.000002	#	Query	#	#	COMMIT
+# Test that the binlog files of automatic preallocation 
+# will work fine on slave.
+show binlog events in 'slave-bin.000001' from <binlog_start>;
+Log_name	Pos	Event_type	Server_id	End_log_pos	Info
+slave-bin.000001	#	Query	#	#	BEGIN
+slave-bin.000001	#	Table_map	#	#	table_id: # (mtr.test_suppressions)
+slave-bin.000001	#	Write_rows	#	#	table_id: # flags: STMT_END_F
+slave-bin.000001	#	Query	#	#	COMMIT
+slave-bin.000001	#	Query	#	#	use `test`; create table t2 (id int primary key, value int) engine=myisam
+slave-bin.000001	#	Query	#	#	BEGIN
+slave-bin.000001	#	Table_map	#	#	table_id: # (test.t2)
+slave-bin.000001	#	Write_rows	#	#	table_id: # flags: STMT_END_F
+slave-bin.000001	#	Query	#	#	COMMIT
+slave-bin.000001	#	Query	#	#	BEGIN
+slave-bin.000001	#	Table_map	#	#	table_id: # (test.t2)
+slave-bin.000001	#	Write_rows	#	#	table_id: # flags: STMT_END_F
+slave-bin.000001	#	Query	#	#	COMMIT
+slave-bin.000001	#	Query	#	#	BEGIN
+slave-bin.000001	#	Table_map	#	#	table_id: # (test.t2)
+slave-bin.000001	#	Write_rows	#	#	table_id: # flags: STMT_END_F
+slave-bin.000001	#	Query	#	#	COMMIT
+slave-bin.000001	#	Query	#	#	BEGIN
+slave-bin.000001	#	Table_map	#	#	table_id: # (test.t2)
+slave-bin.000001	#	Write_rows	#	#	table_id: # flags: STMT_END_F
+slave-bin.000001	#	Query	#	#	COMMIT
+flush logs;
+# Test that the binlog files of static preallocation will
+# work fine when crash shutdown and restart master.
+# Setup the mysqld to crash at certain point
+SET SESSION debug="d,crash_before_flush_keys";
+# Run the crashing query
+FLUSH TABLES;
+ERROR HY000: Lost connection to MySQL server during query
+show binlog events in 'master-bin.000003' from <binlog_start>;
+Log_name	Pos	Event_type	Server_id	End_log_pos	Info
+drop table t2;
+# Test that the binlog files of automatic preallocation 
+# will work fine on slave.
+show binlog events in 'slave-bin.000002' from <binlog_start>;
+Log_name	Pos	Event_type	Server_id	End_log_pos	Info
+slave-bin.000002	#	Query	#	#	use `test`; DROP TABLE `t2` /* generated by server */
+include/stop_slave.inc
+include/wait_for_slave_to_stop.inc

=== added file 'mysql-test/suite/rpl/r/rpl_row_prealloc_binlog_max_cache_size.result'
--- a/mysql-test/suite/rpl/r/rpl_row_prealloc_binlog_max_cache_size.result	1970-01-01 00:00:00 +0000
+++ b/mysql-test/suite/rpl/r/rpl_row_prealloc_binlog_max_cache_size.result	2010-12-30 11:58:25 +0000
@@ -0,0 +1,206 @@
+include/master-slave.inc
+[connection master]
+call mtr.add_suppression("Unsafe statement written to the binary log using statement format since BINLOG_FORMAT = STATEMENT");
+call mtr.add_suppression("Option binlog_cache_size ");
+SET GLOBAL max_binlog_cache_size = 4096;
+Warnings:
+Warning	1712	Option binlog_cache_size (32768) is greater than max_binlog_cache_size (4096); setting binlog_cache_size equal to max_binlog_cache_size.
+SET GLOBAL binlog_cache_size = 4096;
+SET GLOBAL max_binlog_stmt_cache_size = 4096;
+Warnings:
+Warning	1725	Option binlog_stmt_cache_size (32768) is greater than max_binlog_stmt_cache_size (4096); setting binlog_stmt_cache_size equal to max_binlog_stmt_cache_size.
+SET GLOBAL binlog_stmt_cache_size = 4096;
+CREATE TABLE t1(a INT PRIMARY KEY, data VARCHAR(30000)) ENGINE=Innodb;
+CREATE TABLE t2(a INT PRIMARY KEY, data VARCHAR(30000)) ENGINE=MyIsam;
+CREATE TABLE t3(a INT PRIMARY KEY, data VARCHAR(30000)) ENGINE=Innodb;
+########################################################################################
+#                                   1 - SINGLE STATEMENT
+########################################################################################
+*** Single statement on transactional table ***
+Got one of the listed errors
+*** Single statement on non-transactional table ***
+Got one of the listed errors
+include/wait_for_slave_sql_error_and_skip.inc [errno=1590]
+*** Single statement on both transactional and non-transactional tables. ***
+Got one of the listed errors
+include/wait_for_slave_sql_error_and_skip.inc [errno=1590]
+include/diff_tables.inc [master:t1,slave:t1]
+########################################################################################
+#                             2 - BEGIN - IMPLICIT COMMIT by DDL
+########################################################################################
+TRUNCATE TABLE t1;
+TRUNCATE TABLE t2;
+TRUNCATE TABLE t3;
+BEGIN;
+Got one of the listed errors
+Got one of the listed errors
+Got one of the listed errors
+BEGIN;
+Got one of the listed errors
+Got one of the listed errors
+Got one of the listed errors
+BEGIN;
+Got one of the listed errors
+Got one of the listed errors
+include/diff_tables.inc [master:t1,slave:t1]
+########################################################################################
+#                                     3 - BEGIN - COMMIT
+########################################################################################
+TRUNCATE TABLE t1;
+TRUNCATE TABLE t2;
+TRUNCATE TABLE t3;
+BEGIN;
+Got one of the listed errors
+Got one of the listed errors
+Got one of the listed errors
+COMMIT;
+include/diff_tables.inc [master:t1,slave:t1]
+########################################################################################
+#                                      4 - BEGIN - ROLLBACK
+########################################################################################
+TRUNCATE TABLE t1;
+TRUNCATE TABLE t2;
+TRUNCATE TABLE t3;
+BEGIN;
+Got one of the listed errors
+Got one of the listed errors
+Got one of the listed errors
+ROLLBACK;
+Warnings:
+Warning	1196	Some non-transactional changed tables couldn't be rolled back
+include/diff_tables.inc [master:t1,slave:t1]
+########################################################################################
+#                                         5 - PROCEDURE 
+########################################################################################
+TRUNCATE TABLE t1;
+TRUNCATE TABLE t2;
+TRUNCATE TABLE t3;
+CREATE PROCEDURE p1(pd VARCHAR(30000))
+BEGIN
+INSERT INTO t1 (a, data) VALUES (1, pd);
+INSERT INTO t1 (a, data) VALUES (2, pd);
+INSERT INTO t1 (a, data) VALUES (3, pd);
+INSERT INTO t1 (a, data) VALUES (4, pd);
+INSERT INTO t1 (a, data) VALUES (5, 's');
+END//
+TRUNCATE TABLE t1;
+TRUNCATE TABLE t1;
+BEGIN;
+Got one of the listed errors
+COMMIT;
+TRUNCATE TABLE t1;
+BEGIN;
+Got one of the listed errors
+ROLLBACK;
+include/diff_tables.inc [master:t1,slave:t1]
+########################################################################################
+#                                           6 - XID
+########################################################################################
+TRUNCATE TABLE t1;
+TRUNCATE TABLE t2;
+TRUNCATE TABLE t3;
+BEGIN;
+Got one of the listed errors
+Got one of the listed errors
+Got one of the listed errors
+ROLLBACK TO sv;
+Warnings:
+Warning	1196	Some non-transactional changed tables couldn't be rolled back
+COMMIT;
+include/diff_tables.inc [master:t1,slave:t1]
+########################################################################################
+#                                        7 - NON-TRANS TABLE
+########################################################################################
+TRUNCATE TABLE t1;
+TRUNCATE TABLE t2;
+TRUNCATE TABLE t3;
+BEGIN;
+Got one of the listed errors
+Got one of the listed errors
+Got one of the listed errors
+COMMIT;
+BEGIN;
+Got one of the listed errors
+COMMIT;
+include/diff_tables.inc [master:t1,slave:t1]
+########################################################################
+#      8 - Bug#55375(Regression Bug) Transaction bigger than
+#          max_binlog_cache_size crashes slave
+########################################################################
+# [ On Slave ]
+SET GLOBAL max_binlog_cache_size = 4096;
+Warnings:
+Warning	1712	Option binlog_cache_size (32768) is greater than max_binlog_cache_size (4096); setting binlog_cache_size equal to max_binlog_cache_size.
+SET GLOBAL binlog_cache_size = 4096;
+SET GLOBAL max_binlog_stmt_cache_size = 4096;
+Warnings:
+Warning	1725	Option binlog_stmt_cache_size (32768) is greater than max_binlog_stmt_cache_size (4096); setting binlog_stmt_cache_size equal to max_binlog_stmt_cache_size.
+SET GLOBAL binlog_stmt_cache_size = 4096;
+include/stop_slave.inc
+include/start_slave.inc
+CALL mtr.add_suppression("Multi-statement transaction required more than 'max_binlog_cache_size' bytes of storage.*");
+CALL mtr.add_suppression("Multi-statement transaction required more than 'max_binlog_stmt_cache_size' bytes of storage.*");
+CALL mtr.add_suppression("Writing one row to the row-based binary log failed.*");
+TRUNCATE t1;
+SET GLOBAL max_binlog_cache_size= ORIGINAL_VALUE;
+SET GLOBAL binlog_cache_size= ORIGINAL_VALUE;
+SET GLOBAL max_binlog_stmt_cache_size= ORIGINAL_VALUE;
+SET GLOBAL binlog_stmt_cache_size= ORIGINAL_VALUE;
+BEGIN;
+Repeat statement 'INSERT INTO t1 VALUES($n, repeat("a", 32))' 128 times
+COMMIT;
+include/wait_for_slave_sql_error.inc [errno=1534]
+SELECT count(*) FROM t1;
+count(*)
+0
+show binlog events in 'slave-bin.000001' from <binlog_start>;
+Log_name	Pos	Event_type	Server_id	End_log_pos	Info
+SET GLOBAL max_binlog_cache_size= ORIGINAL_VALUE;
+SET GLOBAL binlog_cache_size= ORIGINAL_VALUE;
+SET GLOBAL max_binlog_stmt_cache_size= ORIGINAL_VALUE;
+SET GLOBAL binlog_stmt_cache_size= ORIGINAL_VALUE;
+include/stop_slave.inc
+include/start_slave.inc
+SELECT count(*) FROM t1;
+count(*)
+128
+########################################################################################
+#                       CHECK MAX_BINLOG_CACHE_SIZE and BINLOG_CACHE_SIZE
+########################################################################################
+SET @@GLOBAL.MAX_BINLOG_CACHE_SIZE= 8192;
+Warnings:
+Warning	1712	Option binlog_cache_size (32768) is greater than max_binlog_cache_size (8192); setting binlog_cache_size equal to max_binlog_cache_size.
+SHOW VARIABLES LIKE 'MAX_BINLOG_CACHE_SIZE';
+Variable_name	Value
+max_binlog_cache_size	8192
+SHOW VARIABLES LIKE 'BINLOG_CACHE_SIZE';
+Variable_name	Value
+binlog_cache_size	8192
+SET @@GLOBAL.BINLOG_CACHE_SIZE= 16384;
+Warnings:
+Warning	1712	Option binlog_cache_size (16384) is greater than max_binlog_cache_size (8192); setting binlog_cache_size equal to max_binlog_cache_size.
+SHOW VARIABLES LIKE 'MAX_BINLOG_CACHE_SIZE';
+Variable_name	Value
+max_binlog_cache_size	8192
+SHOW VARIABLES LIKE 'BINLOG_CACHE_SIZE';
+Variable_name	Value
+binlog_cache_size	8192
+SET @@GLOBAL.MAX_BINLOG_CACHE_SIZE= 4096;
+Warnings:
+Warning	1712	Option binlog_cache_size (8192) is greater than max_binlog_cache_size (4096); setting binlog_cache_size equal to max_binlog_cache_size.
+SHOW VARIABLES LIKE 'MAX_BINLOG_CACHE_SIZE';
+Variable_name	Value
+max_binlog_cache_size	4096
+SHOW VARIABLES LIKE 'BINLOG_CACHE_SIZE';
+Variable_name	Value
+binlog_cache_size	4096
+########################################################################################
+#                                        CLEAN
+########################################################################################
+DROP TABLE t1;
+DROP TABLE t2;
+DROP TABLE t3;
+DROP TABLE IF EXISTS t4;
+DROP TABLE t5;
+DROP PROCEDURE p1;
+include/rpl_end.inc

=== added file 'mysql-test/suite/rpl/r/rpl_stmt_prealloc_binlog.result'
--- a/mysql-test/suite/rpl/r/rpl_stmt_prealloc_binlog.result	1970-01-01 00:00:00 +0000
+++ b/mysql-test/suite/rpl/r/rpl_stmt_prealloc_binlog.result	2010-12-30 11:58:25 +0000
@@ -0,0 +1,186 @@
+include/master-slave.inc
+[connection master]
+call mtr.add_suppression("MYSQL_BIN_LOG::purge_logs was called with file ./master-bin.000009 not listed in the index");
+reset master;
+include/stop_slave.inc
+include/wait_for_slave_to_stop.inc
+change master to master_host='127.0.0.1',master_port=MASTER_PORT, master_user='root', master_connect_retry=5;
+include/start_slave.inc
+include/wait_for_slave_to_start.inc
+# [On master]
+create table t1 (id int primary key, value int) engine=myisam;
+insert into t1 values(1, 100);
+insert into t1 values(2, 200);
+insert into t1 values(3, 100);
+update t1 set value=1000 where id=2;
+show binlog events in 'master-bin.000001' from <binlog_start>;
+Log_name	Pos	Event_type	Server_id	End_log_pos	Info
+master-bin.000001	#	Query	#	#	use `test`; create table t1 (id int primary key, value int) engine=myisam
+master-bin.000001	#	Query	#	#	BEGIN
+master-bin.000001	#	Query	#	#	use `test`; insert into t1 values(1, 100)
+master-bin.000001	#	Query	#	#	COMMIT
+master-bin.000001	#	Query	#	#	BEGIN
+master-bin.000001	#	Query	#	#	use `test`; insert into t1 values(2, 200)
+master-bin.000001	#	Query	#	#	COMMIT
+master-bin.000001	#	Query	#	#	BEGIN
+master-bin.000001	#	Query	#	#	use `test`; insert into t1 values(3, 100)
+master-bin.000001	#	Query	#	#	COMMIT
+master-bin.000001	#	Query	#	#	BEGIN
+master-bin.000001	#	Query	#	#	use `test`; update t1 set value=1000 where id=2
+master-bin.000001	#	Query	#	#	COMMIT
+flush logs;
+flush logs;
+insert into t1 values(4, 100);
+insert into t1 values(5, 200);
+insert into t1 values(6, 100);
+show binlog events in 'master-bin.000003' from <binlog_start>;
+Log_name	Pos	Event_type	Server_id	End_log_pos	Info
+master-bin.000003	#	Query	#	#	BEGIN
+master-bin.000003	#	Query	#	#	use `test`; insert into t1 values(4, 100)
+master-bin.000003	#	Query	#	#	COMMIT
+master-bin.000003	#	Query	#	#	BEGIN
+master-bin.000003	#	Query	#	#	use `test`; insert into t1 values(5, 200)
+master-bin.000003	#	Query	#	#	COMMIT
+master-bin.000003	#	Query	#	#	BEGIN
+master-bin.000003	#	Query	#	#	use `test`; insert into t1 values(6, 100)
+master-bin.000003	#	Query	#	#	COMMIT
+flush logs;
+insert into t1 values(7, 100);
+insert into t1 values(8, 200);
+insert into t1 values(9, 100);
+show binlog events in 'master-bin.000004' from <binlog_start>;
+Log_name	Pos	Event_type	Server_id	End_log_pos	Info
+master-bin.000004	#	Query	#	#	BEGIN
+master-bin.000004	#	Query	#	#	use `test`; insert into t1 values(7, 100)
+master-bin.000004	#	Query	#	#	COMMIT
+master-bin.000004	#	Query	#	#	BEGIN
+master-bin.000004	#	Query	#	#	use `test`; insert into t1 values(8, 200)
+master-bin.000004	#	Query	#	#	COMMIT
+master-bin.000004	#	Query	#	#	BEGIN
+master-bin.000004	#	Query	#	#	use `test`; insert into t1 values(9, 100)
+master-bin.000004	#	Query	#	#	COMMIT
+# Test that the binlog files of automatic preallocation 
+# will work fine on slave.
+show binlog events in 'slave-bin.000001' from <binlog_start>;
+Log_name	Pos	Event_type	Server_id	End_log_pos	Info
+slave-bin.000001	#	Query	#	#	BEGIN
+slave-bin.000001	#	Query	#	#	use `mtr`; INSERT INTO test_suppressions (pattern) VALUES ( NAME_CONST('pattern',_latin1'MYSQL_BIN_LOG::purge_logs was called with file ./master-bin.000009 not listed in the index' COLLATE 'latin1_swedish_ci'))
+slave-bin.000001	#	Query	#	#	COMMIT
+slave-bin.000001	#	Query	#	#	use `test`; create table t1 (id int primary key, value int) engine=myisam
+slave-bin.000001	#	Query	#	#	BEGIN
+slave-bin.000001	#	Query	#	#	use `test`; insert into t1 values(1, 100)
+slave-bin.000001	#	Query	#	#	COMMIT
+slave-bin.000001	#	Query	#	#	BEGIN
+slave-bin.000001	#	Query	#	#	use `test`; insert into t1 values(2, 200)
+slave-bin.000001	#	Query	#	#	COMMIT
+slave-bin.000001	#	Query	#	#	BEGIN
+slave-bin.000001	#	Query	#	#	use `test`; insert into t1 values(3, 100)
+slave-bin.000001	#	Query	#	#	COMMIT
+slave-bin.000001	#	Query	#	#	BEGIN
+slave-bin.000001	#	Query	#	#	use `test`; update t1 set value=1000 where id=2
+slave-bin.000001	#	Query	#	#	COMMIT
+slave-bin.000001	#	Query	#	#	BEGIN
+slave-bin.000001	#	Query	#	#	use `test`; insert into t1 values(4, 100)
+slave-bin.000001	#	Query	#	#	COMMIT
+slave-bin.000001	#	Query	#	#	BEGIN
+slave-bin.000001	#	Query	#	#	use `test`; insert into t1 values(5, 200)
+slave-bin.000001	#	Query	#	#	COMMIT
+slave-bin.000001	#	Query	#	#	BEGIN
+slave-bin.000001	#	Query	#	#	use `test`; insert into t1 values(6, 100)
+slave-bin.000001	#	Query	#	#	COMMIT
+slave-bin.000001	#	Query	#	#	BEGIN
+slave-bin.000001	#	Query	#	#	use `test`; insert into t1 values(7, 100)
+slave-bin.000001	#	Query	#	#	COMMIT
+slave-bin.000001	#	Query	#	#	BEGIN
+slave-bin.000001	#	Query	#	#	use `test`; insert into t1 values(8, 200)
+slave-bin.000001	#	Query	#	#	COMMIT
+slave-bin.000001	#	Query	#	#	BEGIN
+slave-bin.000001	#	Query	#	#	use `test`; insert into t1 values(9, 100)
+slave-bin.000001	#	Query	#	#	COMMIT
+flush logs;
+# Test that the binlog files of automatic preallocation
+# will work fine and the new active binlog file should
+# be master-bin.000005 when master restarts.
+include/rpl_restart_server.inc [server_number=1]
+show binlog events in 'master-bin.000004' from <binlog_start>;
+Log_name	Pos	Event_type	Server_id	End_log_pos	Info
+master-bin.000004	#	Query	#	#	BEGIN
+master-bin.000004	#	Query	#	#	use `test`; insert into t1 values(7, 100)
+master-bin.000004	#	Query	#	#	COMMIT
+master-bin.000004	#	Query	#	#	BEGIN
+master-bin.000004	#	Query	#	#	use `test`; insert into t1 values(8, 200)
+master-bin.000004	#	Query	#	#	COMMIT
+master-bin.000004	#	Query	#	#	BEGIN
+master-bin.000004	#	Query	#	#	use `test`; insert into t1 values(9, 100)
+master-bin.000004	#	Query	#	#	COMMIT
+master-bin.000004	#	Stop	#	#	
+show binlog events in 'master-bin.000005' from <binlog_start>;
+Log_name	Pos	Event_type	Server_id	End_log_pos	Info
+show binlog events in 'master-bin.000006';
+ERROR HY000: Error when executing command SHOW BINLOG EVENTS: Could not find target log
+flush logs;
+# Test that the binlog files of automatic preallocation
+# will work fine on slave.
+show binlog events in 'slave-bin.000002' from <binlog_start>;
+Log_name	Pos	Event_type	Server_id	End_log_pos	Info
+flush logs;
+# Test that the binlog files of static preallocation 
+# will work fine when master restarts.
+include/rpl_stop_server.inc [server_number=1]
+include/rpl_start_server.inc [server_number=1]
+show binlog events in 'master-bin.000005' from <binlog_start>;
+Log_name	Pos	Event_type	Server_id	End_log_pos	Info
+master-bin.000005	#	Rotate	#	#	master-bin.000006;pos=4
+flush logs;
+drop table t1;
+# Test that the binlog files of automatic preallocation 
+# will work fine on slave.
+show binlog events in 'slave-bin.000003' from <binlog_start>;
+Log_name	Pos	Event_type	Server_id	End_log_pos	Info
+slave-bin.000003	#	Query	#	#	use `test`; DROP TABLE `t1` /* generated by server */
+flush logs;
+# Test that we just can successfully purge log to
+# the last binlog file name in the index file.
+purge master logs to 'master-bin.000008';
+purge master logs to 'master-bin.000009';
+ERROR HY000: Target log not found in binlog index
+# Test that the binlog files of static preallocation
+# will work fine with concurrency insert.
+reset master;
+# Stop master server
+include/rpl_stop_server.inc [server_number=1]
+./master-bin.000001
+# Start master server
+include/rpl_start_server.inc [server_number=1]
+include/stop_slave.inc
+change master to master_host='127.0.0.1',master_port=MASTER_PORT, master_user='root', master_connect_retry=5;
+include/start_slave.inc
+include/wait_for_slave_to_start.inc
+create database if not exists mysqlslap;
+create table mysqlslap.t1 (id int auto_increment primary key, int_value int, vchar_value varchar(10)) engine=myisam;
+select count(*) from mysqlslap.t1;
+count(*)
+10
+#[On slave]
+select count(*) from mysqlslap.t1;
+count(*)
+10
+drop database mysqlslap;
+# Test that the binlog files of static/automatic preallocation
+# will work fine with concurrency insert and flush logs.
+#[On master]
+create database if not exists mysqlslap;
+create table mysqlslap.t1 (id int auto_increment primary key, int_value int, vchar_value varchar(10)) engine=myisam;
+select count(*) from mysqlslap.t1;
+count(*)
+30
+show binlog events in 'master-bin.000031' from <binlog_start>;
+Log_name	Pos	Event_type	Server_id	End_log_pos	Info
+#[On slave]
+select count(*) from mysqlslap.t1;
+count(*)
+30
+*** Clean up ***
+drop database mysqlslap;
+include/stop_slave.inc
+include/wait_for_slave_to_stop.inc

=== added file 'mysql-test/suite/rpl/r/rpl_stmt_prealloc_binlog_crash.result'
--- a/mysql-test/suite/rpl/r/rpl_stmt_prealloc_binlog_crash.result	1970-01-01 00:00:00 +0000
+++ b/mysql-test/suite/rpl/r/rpl_stmt_prealloc_binlog_crash.result	2010-12-30 11:58:25 +0000
@@ -0,0 +1,75 @@
+include/master-slave.inc
+[connection master]
+call mtr.add_suppression("Error in Log_event::read_log_event(): 'Event too small'");
+# Test that the binlog files of automatic preallocation
+# will work fine when crash shutdown and restart master.
+create table t2 (id int primary key, value int) engine=myisam;
+insert into t2 values(1, 11);
+# Setup the mysqld to crash at certain point
+SET SESSION debug="d,crash_before_flush_keys";
+# Run the crashing query
+FLUSH TABLES;
+ERROR HY000: Lost connection to MySQL server during query
+insert into t2 values(2, 12);
+insert into t2 values(3, 13);
+insert into t2 values(4, 14);
+show binlog events in 'master-bin.000001' from <binlog_start>;
+Log_name	Pos	Event_type	Server_id	End_log_pos	Info
+master-bin.000001	#	Query	#	#	BEGIN
+master-bin.000001	#	Query	#	#	use `mtr`; INSERT INTO test_suppressions (pattern) VALUES ( NAME_CONST('pattern',_latin1'Error in Log_event::read_log_event(): \'Event too small\'' COLLATE 'latin1_swedish_ci'))
+master-bin.000001	#	Query	#	#	COMMIT
+master-bin.000001	#	Query	#	#	use `test`; create table t2 (id int primary key, value int) engine=myisam
+master-bin.000001	#	Query	#	#	BEGIN
+master-bin.000001	#	Query	#	#	use `test`; insert into t2 values(1, 11)
+master-bin.000001	#	Query	#	#	COMMIT
+Warnings:
+Warning	#	Wrong offset or I/O error. It was likely that preallocated binlog file was not closed properly (i.e. mysqld crash).
+show binlog events in 'master-bin.000002' from <binlog_start>;
+Log_name	Pos	Event_type	Server_id	End_log_pos	Info
+master-bin.000002	#	Query	#	#	BEGIN
+master-bin.000002	#	Query	#	#	use `test`; insert into t2 values(2, 12)
+master-bin.000002	#	Query	#	#	COMMIT
+master-bin.000002	#	Query	#	#	BEGIN
+master-bin.000002	#	Query	#	#	use `test`; insert into t2 values(3, 13)
+master-bin.000002	#	Query	#	#	COMMIT
+master-bin.000002	#	Query	#	#	BEGIN
+master-bin.000002	#	Query	#	#	use `test`; insert into t2 values(4, 14)
+master-bin.000002	#	Query	#	#	COMMIT
+# Test that the binlog files of automatic preallocation 
+# will work fine on slave.
+show binlog events in 'slave-bin.000001' from <binlog_start>;
+Log_name	Pos	Event_type	Server_id	End_log_pos	Info
+slave-bin.000001	#	Query	#	#	BEGIN
+slave-bin.000001	#	Query	#	#	use `mtr`; INSERT INTO test_suppressions (pattern) VALUES ( NAME_CONST('pattern',_latin1'Error in Log_event::read_log_event(): \'Event too small\'' COLLATE 'latin1_swedish_ci'))
+slave-bin.000001	#	Query	#	#	COMMIT
+slave-bin.000001	#	Query	#	#	use `test`; create table t2 (id int primary key, value int) engine=myisam
+slave-bin.000001	#	Query	#	#	BEGIN
+slave-bin.000001	#	Query	#	#	use `test`; insert into t2 values(1, 11)
+slave-bin.000001	#	Query	#	#	COMMIT
+slave-bin.000001	#	Query	#	#	BEGIN
+slave-bin.000001	#	Query	#	#	use `test`; insert into t2 values(2, 12)
+slave-bin.000001	#	Query	#	#	COMMIT
+slave-bin.000001	#	Query	#	#	BEGIN
+slave-bin.000001	#	Query	#	#	use `test`; insert into t2 values(3, 13)
+slave-bin.000001	#	Query	#	#	COMMIT
+slave-bin.000001	#	Query	#	#	BEGIN
+slave-bin.000001	#	Query	#	#	use `test`; insert into t2 values(4, 14)
+slave-bin.000001	#	Query	#	#	COMMIT
+flush logs;
+# Test that the binlog files of static preallocation will
+# work fine when crash shutdown and restart master.
+# Setup the mysqld to crash at certain point
+SET SESSION debug="d,crash_before_flush_keys";
+# Run the crashing query
+FLUSH TABLES;
+ERROR HY000: Lost connection to MySQL server during query
+show binlog events in 'master-bin.000003' from <binlog_start>;
+Log_name	Pos	Event_type	Server_id	End_log_pos	Info
+drop table t2;
+# Test that the binlog files of automatic preallocation 
+# will work fine on slave.
+show binlog events in 'slave-bin.000002' from <binlog_start>;
+Log_name	Pos	Event_type	Server_id	End_log_pos	Info
+slave-bin.000002	#	Query	#	#	use `test`; DROP TABLE `t2` /* generated by server */
+include/stop_slave.inc
+include/wait_for_slave_to_stop.inc

=== added file 'mysql-test/suite/rpl/r/rpl_stmt_prealloc_binlog_max_cache_size.result'
--- a/mysql-test/suite/rpl/r/rpl_stmt_prealloc_binlog_max_cache_size.result	1970-01-01 00:00:00 +0000
+++ b/mysql-test/suite/rpl/r/rpl_stmt_prealloc_binlog_max_cache_size.result	2010-12-30 11:58:25 +0000
@@ -0,0 +1,205 @@
+include/master-slave.inc
+[connection master]
+call mtr.add_suppression("Unsafe statement written to the binary log using statement format since BINLOG_FORMAT = STATEMENT");
+call mtr.add_suppression("Option binlog_cache_size ");
+SET GLOBAL max_binlog_cache_size = 4096;
+Warnings:
+Warning	1712	Option binlog_cache_size (32768) is greater than max_binlog_cache_size (4096); setting binlog_cache_size equal to max_binlog_cache_size.
+SET GLOBAL binlog_cache_size = 4096;
+SET GLOBAL max_binlog_stmt_cache_size = 4096;
+Warnings:
+Warning	1725	Option binlog_stmt_cache_size (32768) is greater than max_binlog_stmt_cache_size (4096); setting binlog_stmt_cache_size equal to max_binlog_stmt_cache_size.
+SET GLOBAL binlog_stmt_cache_size = 4096;
+CREATE TABLE t1(a INT PRIMARY KEY, data VARCHAR(30000)) ENGINE=Innodb;
+CREATE TABLE t2(a INT PRIMARY KEY, data VARCHAR(30000)) ENGINE=MyIsam;
+CREATE TABLE t3(a INT PRIMARY KEY, data VARCHAR(30000)) ENGINE=Innodb;
+########################################################################################
+#                                   1 - SINGLE STATEMENT
+########################################################################################
+*** Single statement on transactional table ***
+Got one of the listed errors
+*** Single statement on non-transactional table ***
+Got one of the listed errors
+include/wait_for_slave_sql_error_and_skip.inc [errno=1590]
+*** Single statement on both transactional and non-transactional tables. ***
+Got one of the listed errors
+include/wait_for_slave_sql_error_and_skip.inc [errno=1590]
+include/diff_tables.inc [master:t1,slave:t1]
+########################################################################################
+#                             2 - BEGIN - IMPLICIT COMMIT by DDL
+########################################################################################
+TRUNCATE TABLE t1;
+TRUNCATE TABLE t2;
+TRUNCATE TABLE t3;
+BEGIN;
+Got one of the listed errors
+Got one of the listed errors
+Got one of the listed errors
+BEGIN;
+Got one of the listed errors
+Got one of the listed errors
+BEGIN;
+Got one of the listed errors
+Got one of the listed errors
+include/diff_tables.inc [master:t1,slave:t1]
+########################################################################################
+#                                     3 - BEGIN - COMMIT
+########################################################################################
+TRUNCATE TABLE t1;
+TRUNCATE TABLE t2;
+TRUNCATE TABLE t3;
+BEGIN;
+Got one of the listed errors
+Got one of the listed errors
+Got one of the listed errors
+COMMIT;
+include/diff_tables.inc [master:t1,slave:t1]
+########################################################################################
+#                                      4 - BEGIN - ROLLBACK
+########################################################################################
+TRUNCATE TABLE t1;
+TRUNCATE TABLE t2;
+TRUNCATE TABLE t3;
+BEGIN;
+Got one of the listed errors
+Got one of the listed errors
+Got one of the listed errors
+ROLLBACK;
+Warnings:
+Warning	1196	Some non-transactional changed tables couldn't be rolled back
+include/diff_tables.inc [master:t1,slave:t1]
+########################################################################################
+#                                         5 - PROCEDURE 
+########################################################################################
+TRUNCATE TABLE t1;
+TRUNCATE TABLE t2;
+TRUNCATE TABLE t3;
+CREATE PROCEDURE p1(pd VARCHAR(30000))
+BEGIN
+INSERT INTO t1 (a, data) VALUES (1, pd);
+INSERT INTO t1 (a, data) VALUES (2, pd);
+INSERT INTO t1 (a, data) VALUES (3, pd);
+INSERT INTO t1 (a, data) VALUES (4, pd);
+INSERT INTO t1 (a, data) VALUES (5, 's');
+END//
+TRUNCATE TABLE t1;
+TRUNCATE TABLE t1;
+BEGIN;
+Got one of the listed errors
+COMMIT;
+TRUNCATE TABLE t1;
+BEGIN;
+Got one of the listed errors
+ROLLBACK;
+include/diff_tables.inc [master:t1,slave:t1]
+########################################################################################
+#                                           6 - XID
+########################################################################################
+TRUNCATE TABLE t1;
+TRUNCATE TABLE t2;
+TRUNCATE TABLE t3;
+BEGIN;
+Got one of the listed errors
+Got one of the listed errors
+Got one of the listed errors
+ROLLBACK TO sv;
+Warnings:
+Warning	1196	Some non-transactional changed tables couldn't be rolled back
+COMMIT;
+include/diff_tables.inc [master:t1,slave:t1]
+########################################################################################
+#                                        7 - NON-TRANS TABLE
+########################################################################################
+TRUNCATE TABLE t1;
+TRUNCATE TABLE t2;
+TRUNCATE TABLE t3;
+BEGIN;
+Got one of the listed errors
+Got one of the listed errors
+Got one of the listed errors
+COMMIT;
+BEGIN;
+Got one of the listed errors
+COMMIT;
+include/diff_tables.inc [master:t1,slave:t1]
+########################################################################
+#      8 - Bug#55375(Regression Bug) Transaction bigger than
+#          max_binlog_cache_size crashes slave
+########################################################################
+# [ On Slave ]
+SET GLOBAL max_binlog_cache_size = 4096;
+Warnings:
+Warning	1712	Option binlog_cache_size (32768) is greater than max_binlog_cache_size (4096); setting binlog_cache_size equal to max_binlog_cache_size.
+SET GLOBAL binlog_cache_size = 4096;
+SET GLOBAL max_binlog_stmt_cache_size = 4096;
+Warnings:
+Warning	1725	Option binlog_stmt_cache_size (32768) is greater than max_binlog_stmt_cache_size (4096); setting binlog_stmt_cache_size equal to max_binlog_stmt_cache_size.
+SET GLOBAL binlog_stmt_cache_size = 4096;
+include/stop_slave.inc
+include/start_slave.inc
+CALL mtr.add_suppression("Multi-statement transaction required more than 'max_binlog_cache_size' bytes of storage.*");
+CALL mtr.add_suppression("Multi-statement transaction required more than 'max_binlog_stmt_cache_size' bytes of storage.*");
+CALL mtr.add_suppression("Writing one row to the row-based binary log failed.*");
+TRUNCATE t1;
+SET GLOBAL max_binlog_cache_size= ORIGINAL_VALUE;
+SET GLOBAL binlog_cache_size= ORIGINAL_VALUE;
+SET GLOBAL max_binlog_stmt_cache_size= ORIGINAL_VALUE;
+SET GLOBAL binlog_stmt_cache_size= ORIGINAL_VALUE;
+BEGIN;
+Repeat statement 'INSERT INTO t1 VALUES($n, repeat("a", 32))' 128 times
+COMMIT;
+include/wait_for_slave_sql_error.inc [errno=1197]
+SELECT count(*) FROM t1;
+count(*)
+0
+show binlog events in 'slave-bin.000001' from <binlog_start>;
+Log_name	Pos	Event_type	Server_id	End_log_pos	Info
+SET GLOBAL max_binlog_cache_size= ORIGINAL_VALUE;
+SET GLOBAL binlog_cache_size= ORIGINAL_VALUE;
+SET GLOBAL max_binlog_stmt_cache_size= ORIGINAL_VALUE;
+SET GLOBAL binlog_stmt_cache_size= ORIGINAL_VALUE;
+include/stop_slave.inc
+include/start_slave.inc
+SELECT count(*) FROM t1;
+count(*)
+128
+########################################################################################
+#                       CHECK MAX_BINLOG_CACHE_SIZE and BINLOG_CACHE_SIZE
+########################################################################################
+SET @@GLOBAL.MAX_BINLOG_CACHE_SIZE= 8192;
+Warnings:
+Warning	1712	Option binlog_cache_size (32768) is greater than max_binlog_cache_size (8192); setting binlog_cache_size equal to max_binlog_cache_size.
+SHOW VARIABLES LIKE 'MAX_BINLOG_CACHE_SIZE';
+Variable_name	Value
+max_binlog_cache_size	8192
+SHOW VARIABLES LIKE 'BINLOG_CACHE_SIZE';
+Variable_name	Value
+binlog_cache_size	8192
+SET @@GLOBAL.BINLOG_CACHE_SIZE= 16384;
+Warnings:
+Warning	1712	Option binlog_cache_size (16384) is greater than max_binlog_cache_size (8192); setting binlog_cache_size equal to max_binlog_cache_size.
+SHOW VARIABLES LIKE 'MAX_BINLOG_CACHE_SIZE';
+Variable_name	Value
+max_binlog_cache_size	8192
+SHOW VARIABLES LIKE 'BINLOG_CACHE_SIZE';
+Variable_name	Value
+binlog_cache_size	8192
+SET @@GLOBAL.MAX_BINLOG_CACHE_SIZE= 4096;
+Warnings:
+Warning	1712	Option binlog_cache_size (8192) is greater than max_binlog_cache_size (4096); setting binlog_cache_size equal to max_binlog_cache_size.
+SHOW VARIABLES LIKE 'MAX_BINLOG_CACHE_SIZE';
+Variable_name	Value
+max_binlog_cache_size	4096
+SHOW VARIABLES LIKE 'BINLOG_CACHE_SIZE';
+Variable_name	Value
+binlog_cache_size	4096
+########################################################################################
+#                                        CLEAN
+########################################################################################
+DROP TABLE t1;
+DROP TABLE t2;
+DROP TABLE t3;
+DROP TABLE IF EXISTS t4;
+DROP TABLE t5;
+DROP PROCEDURE p1;
+include/rpl_end.inc

=== added file 'mysql-test/suite/rpl/t/rpl_mixed_prealloc_binlog-master.opt'
--- a/mysql-test/suite/rpl/t/rpl_mixed_prealloc_binlog-master.opt	1970-01-01 00:00:00 +0000
+++ b/mysql-test/suite/rpl/t/rpl_mixed_prealloc_binlog-master.opt	2010-12-30 11:58:25 +0000
@@ -0,0 +1 @@
+--binlog-preallocate=3 --max_binlog_size=65536

=== added file 'mysql-test/suite/rpl/t/rpl_mixed_prealloc_binlog-slave.opt'
--- a/mysql-test/suite/rpl/t/rpl_mixed_prealloc_binlog-slave.opt	1970-01-01 00:00:00 +0000
+++ b/mysql-test/suite/rpl/t/rpl_mixed_prealloc_binlog-slave.opt	2010-12-30 11:58:25 +0000
@@ -0,0 +1 @@
+--binlog-preallocate=5 --max_binlog_size=65536

=== added file 'mysql-test/suite/rpl/t/rpl_mixed_prealloc_binlog.test'
--- a/mysql-test/suite/rpl/t/rpl_mixed_prealloc_binlog.test	1970-01-01 00:00:00 +0000
+++ b/mysql-test/suite/rpl/t/rpl_mixed_prealloc_binlog.test	2010-12-30 11:58:25 +0000
@@ -0,0 +1,3 @@
+--source include/have_binlog_format_mixed.inc
+--source extra/rpl_tests/prealloc_binlog_base.test
+

=== added file 'mysql-test/suite/rpl/t/rpl_mixed_prealloc_binlog_crash-master.opt'
--- a/mysql-test/suite/rpl/t/rpl_mixed_prealloc_binlog_crash-master.opt	1970-01-01 00:00:00 +0000
+++ b/mysql-test/suite/rpl/t/rpl_mixed_prealloc_binlog_crash-master.opt	2010-12-30 11:58:25 +0000
@@ -0,0 +1 @@
+--skip-stack-trace --skip-core-file

=== added file 'mysql-test/suite/rpl/t/rpl_mixed_prealloc_binlog_crash.cnf'
--- a/mysql-test/suite/rpl/t/rpl_mixed_prealloc_binlog_crash.cnf	1970-01-01 00:00:00 +0000
+++ b/mysql-test/suite/rpl/t/rpl_mixed_prealloc_binlog_crash.cnf	2010-12-30 11:58:25 +0000
@@ -0,0 +1,12 @@
+!include ../my.cnf
+
+[mysqld.1]
+binlog-preallocate=3
+max-binlog-size=65536
+
+[mysqld.2]
+server_id=2
+binlog-preallocate=5
+max-binlog-size=65536
+log-slave-updates
+

=== added file 'mysql-test/suite/rpl/t/rpl_mixed_prealloc_binlog_crash.test'
--- a/mysql-test/suite/rpl/t/rpl_mixed_prealloc_binlog_crash.test	1970-01-01 00:00:00 +0000
+++ b/mysql-test/suite/rpl/t/rpl_mixed_prealloc_binlog_crash.test	2010-12-30 11:58:25 +0000
@@ -0,0 +1,3 @@
+--source include/have_binlog_format_mixed.inc
+--source extra/rpl_tests/prealloc_binlog_crash_base.test
+

=== added file 'mysql-test/suite/rpl/t/rpl_mixed_prealloc_binlog_max_cache_size-master.opt'
--- a/mysql-test/suite/rpl/t/rpl_mixed_prealloc_binlog_max_cache_size-master.opt	1970-01-01 00:00:00 +0000
+++ b/mysql-test/suite/rpl/t/rpl_mixed_prealloc_binlog_max_cache_size-master.opt	2010-12-30 11:58:25 +0000
@@ -0,0 +1 @@
+--binlog_preallocate=4 --max_binlog_size=65536

=== added file 'mysql-test/suite/rpl/t/rpl_mixed_prealloc_binlog_max_cache_size.test'
--- a/mysql-test/suite/rpl/t/rpl_mixed_prealloc_binlog_max_cache_size.test	1970-01-01 00:00:00 +0000
+++ b/mysql-test/suite/rpl/t/rpl_mixed_prealloc_binlog_max_cache_size.test	2010-12-30 11:58:25 +0000
@@ -0,0 +1,13 @@
+#
+# WL#4925
+# The test verifies if binlog files of automatic preallocation
+# will work fine with max_cache_size in mixed mode.
+#
+--source include/have_innodb.inc
+--source include/master-slave.inc
+--source include/not_embedded.inc
+--source include/not_windows.inc
+--source include/have_binlog_format_mixed.inc
+
+--source extra/rpl_tests/rpl_binlog_max_cache_size.test
+--source include/rpl_end.inc

=== added file 'mysql-test/suite/rpl/t/rpl_row_prealloc_binlog-master.opt'
--- a/mysql-test/suite/rpl/t/rpl_row_prealloc_binlog-master.opt	1970-01-01 00:00:00 +0000
+++ b/mysql-test/suite/rpl/t/rpl_row_prealloc_binlog-master.opt	2010-12-30 11:58:25 +0000
@@ -0,0 +1 @@
+--binlog-preallocate=3 --max_binlog_size=65536

=== added file 'mysql-test/suite/rpl/t/rpl_row_prealloc_binlog-slave.opt'
--- a/mysql-test/suite/rpl/t/rpl_row_prealloc_binlog-slave.opt	1970-01-01 00:00:00 +0000
+++ b/mysql-test/suite/rpl/t/rpl_row_prealloc_binlog-slave.opt	2010-12-30 11:58:25 +0000
@@ -0,0 +1 @@
+--binlog-preallocate=5 --max_binlog_size=65536

=== added file 'mysql-test/suite/rpl/t/rpl_row_prealloc_binlog.test'
--- a/mysql-test/suite/rpl/t/rpl_row_prealloc_binlog.test	1970-01-01 00:00:00 +0000
+++ b/mysql-test/suite/rpl/t/rpl_row_prealloc_binlog.test	2010-12-30 11:58:25 +0000
@@ -0,0 +1,3 @@
+--source include/have_binlog_format_row.inc
+--source extra/rpl_tests/prealloc_binlog_base.test
+

=== added file 'mysql-test/suite/rpl/t/rpl_row_prealloc_binlog_crash-master.opt'
--- a/mysql-test/suite/rpl/t/rpl_row_prealloc_binlog_crash-master.opt	1970-01-01 00:00:00 +0000
+++ b/mysql-test/suite/rpl/t/rpl_row_prealloc_binlog_crash-master.opt	2010-12-30 11:58:25 +0000
@@ -0,0 +1 @@
+--skip-stack-trace --skip-core-file

=== added file 'mysql-test/suite/rpl/t/rpl_row_prealloc_binlog_crash.cnf'
--- a/mysql-test/suite/rpl/t/rpl_row_prealloc_binlog_crash.cnf	1970-01-01 00:00:00 +0000
+++ b/mysql-test/suite/rpl/t/rpl_row_prealloc_binlog_crash.cnf	2010-12-30 11:58:25 +0000
@@ -0,0 +1,12 @@
+!include ../my.cnf
+
+[mysqld.1]
+binlog-preallocate=1
+max-binlog-size=65536
+
+[mysqld.2]
+server_id=2
+binlog-preallocate=5
+max-binlog-size=65536
+log-slave-updates
+

=== added file 'mysql-test/suite/rpl/t/rpl_row_prealloc_binlog_crash.test'
--- a/mysql-test/suite/rpl/t/rpl_row_prealloc_binlog_crash.test	1970-01-01 00:00:00 +0000
+++ b/mysql-test/suite/rpl/t/rpl_row_prealloc_binlog_crash.test	2010-12-30 11:58:25 +0000
@@ -0,0 +1,3 @@
+--source include/have_binlog_format_row.inc
+--source extra/rpl_tests/prealloc_binlog_crash_base.test
+

=== added file 'mysql-test/suite/rpl/t/rpl_row_prealloc_binlog_max_cache_size-master.opt'
--- a/mysql-test/suite/rpl/t/rpl_row_prealloc_binlog_max_cache_size-master.opt	1970-01-01 00:00:00 +0000
+++ b/mysql-test/suite/rpl/t/rpl_row_prealloc_binlog_max_cache_size-master.opt	2010-12-30 11:58:25 +0000
@@ -0,0 +1 @@
+--binlog-preallocate=3 --max_binlog_size=65536

=== added file 'mysql-test/suite/rpl/t/rpl_row_prealloc_binlog_max_cache_size.test'
--- a/mysql-test/suite/rpl/t/rpl_row_prealloc_binlog_max_cache_size.test	1970-01-01 00:00:00 +0000
+++ b/mysql-test/suite/rpl/t/rpl_row_prealloc_binlog_max_cache_size.test	2010-12-30 11:58:25 +0000
@@ -0,0 +1,13 @@
+#
+# WL#4925
+# The test verifies if binlog files of automatic preallocation
+# will work fine with max_cache_size in row mode.
+#
+--source include/have_innodb.inc
+--source include/master-slave.inc
+--source include/not_embedded.inc
+--source include/not_windows.inc
+--source include/have_binlog_format_row.inc
+
+--source extra/rpl_tests/rpl_binlog_max_cache_size.test
+--source include/rpl_end.inc

=== added file 'mysql-test/suite/rpl/t/rpl_stmt_prealloc_binlog-master.opt'
--- a/mysql-test/suite/rpl/t/rpl_stmt_prealloc_binlog-master.opt	1970-01-01 00:00:00 +0000
+++ b/mysql-test/suite/rpl/t/rpl_stmt_prealloc_binlog-master.opt	2010-12-30 11:58:25 +0000
@@ -0,0 +1 @@
+--binlog-preallocate=3 --max_binlog_size=65536

=== added file 'mysql-test/suite/rpl/t/rpl_stmt_prealloc_binlog-slave.opt'
--- a/mysql-test/suite/rpl/t/rpl_stmt_prealloc_binlog-slave.opt	1970-01-01 00:00:00 +0000
+++ b/mysql-test/suite/rpl/t/rpl_stmt_prealloc_binlog-slave.opt	2010-12-30 11:58:25 +0000
@@ -0,0 +1 @@
+--binlog-preallocate=5 --max_binlog_size=65536

=== added file 'mysql-test/suite/rpl/t/rpl_stmt_prealloc_binlog.test'
--- a/mysql-test/suite/rpl/t/rpl_stmt_prealloc_binlog.test	1970-01-01 00:00:00 +0000
+++ b/mysql-test/suite/rpl/t/rpl_stmt_prealloc_binlog.test	2010-12-30 11:58:25 +0000
@@ -0,0 +1,2 @@
+--source include/have_binlog_format_statement.inc
+--source extra/rpl_tests/prealloc_binlog_base.test

=== added file 'mysql-test/suite/rpl/t/rpl_stmt_prealloc_binlog_crash-master.opt'
--- a/mysql-test/suite/rpl/t/rpl_stmt_prealloc_binlog_crash-master.opt	1970-01-01 00:00:00 +0000
+++ b/mysql-test/suite/rpl/t/rpl_stmt_prealloc_binlog_crash-master.opt	2010-12-30 11:58:25 +0000
@@ -0,0 +1 @@
+--skip-stack-trace --skip-core-file

=== added file 'mysql-test/suite/rpl/t/rpl_stmt_prealloc_binlog_crash.cnf'
--- a/mysql-test/suite/rpl/t/rpl_stmt_prealloc_binlog_crash.cnf	1970-01-01 00:00:00 +0000
+++ b/mysql-test/suite/rpl/t/rpl_stmt_prealloc_binlog_crash.cnf	2010-12-30 11:58:25 +0000
@@ -0,0 +1,12 @@
+!include ../my.cnf
+
+[mysqld.1]
+binlog-preallocate=3
+max-binlog-size=65536
+
+[mysqld.2]
+server_id=2
+binlog-preallocate=5
+max-binlog-size=65536
+log-slave-updates
+

=== added file 'mysql-test/suite/rpl/t/rpl_stmt_prealloc_binlog_crash.test'
--- a/mysql-test/suite/rpl/t/rpl_stmt_prealloc_binlog_crash.test	1970-01-01 00:00:00 +0000
+++ b/mysql-test/suite/rpl/t/rpl_stmt_prealloc_binlog_crash.test	2010-12-30 11:58:25 +0000
@@ -0,0 +1,3 @@
+--source include/have_binlog_format_statement.inc
+--source extra/rpl_tests/prealloc_binlog_crash_base.test
+

=== added file 'mysql-test/suite/rpl/t/rpl_stmt_prealloc_binlog_max_cache_size-master.opt'
--- a/mysql-test/suite/rpl/t/rpl_stmt_prealloc_binlog_max_cache_size-master.opt	1970-01-01 00:00:00 +0000
+++ b/mysql-test/suite/rpl/t/rpl_stmt_prealloc_binlog_max_cache_size-master.opt	2010-12-30 11:58:25 +0000
@@ -0,0 +1 @@
+--binlog-preallocate=3 --max_binlog_size=65536

=== added file 'mysql-test/suite/rpl/t/rpl_stmt_prealloc_binlog_max_cache_size.test'
--- a/mysql-test/suite/rpl/t/rpl_stmt_prealloc_binlog_max_cache_size.test	1970-01-01 00:00:00 +0000
+++ b/mysql-test/suite/rpl/t/rpl_stmt_prealloc_binlog_max_cache_size.test	2010-12-30 11:58:25 +0000
@@ -0,0 +1,13 @@
+#
+# WL#4925
+# The test verifies if binlog files of automatic preallocation
+# will work fine with max_cache_size in statement mode.
+#
+--source include/have_innodb.inc
+--source include/master-slave.inc
+--source include/not_embedded.inc
+--source include/not_windows.inc
+--source include/have_binlog_format_statement.inc
+
+--source extra/rpl_tests/rpl_binlog_max_cache_size.test
+--source include/rpl_end.inc

=== modified file 'mysql-test/suite/sys_vars/r/all_vars.result'
--- a/mysql-test/suite/sys_vars/r/all_vars.result	2010-12-14 08:07:25 +0000
+++ b/mysql-test/suite/sys_vars/r/all_vars.result	2010-12-30 11:58:25 +0000
@@ -19,6 +19,7 @@ LOG_BIN_BASENAME
 INNODB_ANALYZE_IS_PERSISTENT
 INNODB_PRINT_ALL_DEADLOCKS
 INNODB_RESET_MONITOR_COUNTER
+BINLOG_PREALLOCATE
 INNODB_RESET_ALL_MONITOR_COUNTER
 LOG_BIN_INDEX
 INNODB_DISABLE_MONITOR_COUNTER
@@ -31,6 +32,7 @@ LOG_BIN_BASENAME
 INNODB_ANALYZE_IS_PERSISTENT
 INNODB_PRINT_ALL_DEADLOCKS
 INNODB_RESET_MONITOR_COUNTER
+BINLOG_PREALLOCATE
 INNODB_RESET_ALL_MONITOR_COUNTER
 LOG_BIN_INDEX
 INNODB_DISABLE_MONITOR_COUNTER

=== modified file 'mysys/my_winfile.c'
--- a/mysys/my_winfile.c	2010-10-05 12:18:16 +0000
+++ b/mysys/my_winfile.c	2010-12-30 11:58:25 +0000
@@ -678,4 +678,27 @@ int my_win_dup(File fd)
   DBUG_RETURN(-1);
 }
 
+
+/**
+  Preallocate a binlog file by SetFilePointerEx()
+  and SetEndOfFile() on Windows.
+
+  @param fd            File descriptor.
+  @param alloc_size    The preallocated size of the file.
+
+  @retval
+    0    ok
+  @retval
+    -1   error
+*/
+int my_win_fallocate(File fd, ulong alloc_size)
+{
+  LARGE_INTEGER length;
+  HANDLE hFile= (HANDLE) my_get_osfhandle(fd);
+  length.QuadPart= alloc_size;
+  if (!SetFilePointerEx(hFile, length , NULL , FILE_BEGIN)
+      || !SetEndOfFile(hFile))
+    return -1;
+  return 0;
+}
 #endif /*_WIN32*/

=== modified file 'mysys/my_write.c'
--- a/mysys/my_write.c	2009-09-11 20:26:35 +0000
+++ b/mysys/my_write.c	2010-12-30 11:58:25 +0000
@@ -99,3 +99,58 @@ size_t my_write(File Filedes, const ucha
     DBUG_RETURN(0);			/* Want only errors */
   DBUG_RETURN(writtenbytes+written);
 } /* my_write */
+
+
+/**
+  Preallocate a binlog file by invoking posix_fallocate().
+
+  @note
+    It is supported by SetFilePointerEx() and SetEndOfFile()
+    on Windows
+
+  @param fd            File descriptor.
+  @param alloc_size    The preallocated size of the file.
+
+  @retval
+    0    ok
+  @retval
+    -1   error
+*/
+int my_fallocate(File fd, ulong alloc_size)
+{
+#if defined (__WIN__)
+  if (my_win_fallocate(fd, alloc_size))
+#else
+  if (posix_fallocate(fd, 0L, alloc_size))
+#endif
+    return -1;
+  return 0;
+}
+
+
+/**
+  Preallocate a binlog file by zero-filling.
+
+  @note
+    posix_fallocate() is not supported on
+  Solaris with ufs/zfs file system.
+
+  @param fd            File descriptor.
+  @param alloc_size    The preallocated size of the file.
+
+  @retval
+    0    ok
+  @retval
+    -1   error
+*/
+int my_zerofill(File fd, ulong alloc_size)
+{
+  uchar buf[IO_SIZE];
+  uint i;
+  memset(buf,0,IO_SIZE);
+  for (i= 0; i < alloc_size / IO_SIZE; i++){
+    if (mysql_file_write(fd, buf, IO_SIZE, MYF(MY_WME | MY_NABP)))
+      return -1;
+  }
+  return 0;
+}

=== modified file 'mysys/mysys_priv.h'
--- a/mysys/mysys_priv.h	2010-01-11 16:46:16 +0000
+++ b/mysys/mysys_priv.h	2010-12-30 11:58:25 +0000
@@ -106,6 +106,7 @@ extern int      my_win_stat(const char *
 extern int      my_win_fstat(File fd, struct _stati64 *buf);
 extern int      my_win_fsync(File fd);
 extern File     my_win_dup(File fd);
+extern int      my_win_fallocate(File fd, ulong alloc_size);
 extern File     my_win_sopen(const char *path, int oflag, int shflag, int perm);
 extern File     my_open_osfhandle(HANDLE handle, int oflag);
 #endif

=== modified file 'sql/binlog.cc'
--- a/sql/binlog.cc	2010-12-17 02:01:32 +0000
+++ b/sql/binlog.cc	2010-12-30 11:58:25 +0000
@@ -1027,7 +1027,8 @@ int check_binlog_magic(IO_CACHE* log, co
 }
 
 
-File open_binlog(IO_CACHE *log, const char *log_file_name, const char **errmsg)
+File open_binlog(IO_CACHE *log, const char *log_file_name, const char **errmsg,
+                 mysql_mutex_t* log_lock)
 {
   File file;
   DBUG_ENTER("open_binlog");
@@ -1049,6 +1050,22 @@ File open_binlog(IO_CACHE *log, const ch
     *errmsg = "Could not open log file";
     goto err;
   }
+#ifndef MYSQL_CLIENT
+  if (binlog_preallocate)
+  {
+    log->file_name= (char*)log_file_name;
+    if (log_lock)
+      mysql_mutex_lock(log_lock);
+    if (mysql_bin_log.is_active(log_file_name))
+    {
+      mysql_mutex_assert_owner(mysql_bin_log.get_log_lock());
+      log->end_of_file= mysql_bin_log.actual_size;
+      DBUG_ASSERT(log->end_of_file >= BIN_LOG_HEADER_SIZE);
+    }
+    if (log_lock)
+      mysql_mutex_unlock(log_lock);
+  }
+#endif
   if (check_binlog_magic(log,errmsg))
     goto err;
   DBUG_RETURN(file);
@@ -1425,7 +1442,8 @@ bool show_binlog_events(THD *thd, MYSQL_
     thd->current_linfo = &linfo;
     mysql_mutex_unlock(&LOCK_thread_count);
 
-    if ((file=open_binlog(&log, linfo.log_file_name, &errmsg)) < 0)
+    if ((file=open_binlog(&log, linfo.log_file_name, &errmsg,
+                          mysql_bin_log.get_log_lock())) < 0)
       goto err;
 
     /*
@@ -1509,8 +1527,20 @@ err:
   }
 
   if (errmsg)
-    my_error(ER_ERROR_WHEN_EXECUTING_COMMAND, MYF(0),
-             "SHOW BINLOG EVENTS", errmsg);
+  {
+    if (binlog_preallocate && !strcmp(errmsg, "Wrong offset or I/O error"))
+    {
+      push_warning_printf(thd, MYSQL_ERROR::WARN_LEVEL_WARN,
+                          ER_ERROR_WHEN_EXECUTING_COMMAND,
+                          "Wrong offset or I/O error. It was likely that "
+                          "preallocated binlog file was not closed "
+                          "properly (i.e. mysqld crash).");
+      my_eof(thd);
+    }
+    else
+      my_error(ER_ERROR_WHEN_EXECUTING_COMMAND, MYF(0),
+               "SHOW BINLOG EVENTS", errmsg);
+  }
   else
     my_eof(thd);
 
@@ -1563,7 +1593,7 @@ MYSQL_BIN_LOG::MYSQL_BIN_LOG(uint *sync_
    is_relay_log(0), signal_cnt(0),
    checksum_alg_reset(BINLOG_CHECKSUM_ALG_UNDEF),
    relay_log_checksum_alg(BINLOG_CHECKSUM_ALG_UNDEF),
-   description_event_for_exec(0), description_event_for_queue(0)
+   description_event_for_exec(0), description_event_for_queue(0), actual_size(0)
 {
   /*
     We don't want to initialize locks here as such initialization depends on
@@ -1584,7 +1614,9 @@ void MYSQL_BIN_LOG::cleanup()
   if (inited)
   {
     inited= 0;
+    mysql_mutex_lock(&LOCK_log);
     close(LOG_CLOSE_INDEX|LOG_CLOSE_STOP_EVENT);
+    mysql_mutex_unlock(&LOCK_log);
     delete description_event_for_queue;
     delete description_event_for_exec;
     mysql_mutex_destroy(&LOCK_log);
@@ -1683,6 +1715,111 @@ bool MYSQL_BIN_LOG::open_index_file(cons
 
 
 /**
+  Generate a new binlog file name from binlog index file.
+
+  @note
+    Using the index file as authoritative source of information
+    and create files based on that. So that mysqld opens "the
+    biggest number of binlog file in the binlog index file + 1"
+
+  @param new_log_name  New binlog file name
+  @param log_name      *******************
+  @param need_lock     Set it to FALSE if its caller already has a
+                       lock on LOCK_index
+
+  @retval
+    0    ok
+  @retval
+    -1   error
+*/
+int MYSQL_BIN_LOG::new_log_name_from_index(char* new_log_name,
+                                           const char* opt_name, bool need_lock)
+{
+  LOG_INFO log_info;
+  int      error= 1;
+  ulong binlog_suffix;
+  bool no_entry_in_index= true;
+  char buff[FN_REFLEN];
+  DBUG_ASSERT(opt_name && opt_name[0]);
+
+  while (!(error= find_next_log(&log_info, need_lock)))
+  {
+    no_entry_in_index= false;
+    strmake(new_log_name, log_info.log_file_name, FN_REFLEN - 1);
+  }
+
+  if (error !=  LOG_INFO_EOF)
+  {
+    sql_print_error("find_log_pos() failed (error: %d)", error);
+    goto err;
+  }
+  fn_format(buff, opt_name, mysql_data_home, "", 4);
+  if (no_entry_in_index)
+  {
+    binlog_suffix= 1;
+    sprintf(new_log_name, "%s.%06ld", buff, binlog_suffix);
+  }
+  else if (test_if_number(new_log_name + strlen(buff) + 1,
+           &binlog_suffix, 0))
+  {
+    binlog_suffix++;
+    sprintf(new_log_name + strlen(buff) + 1, "%06ld", binlog_suffix);
+  }
+  else
+    goto err;
+
+  return 0;
+err:
+  return error;
+}
+
+
+/**
+  Preallocate a binlog file.
+
+  @param fd    File descriptor.
+
+  @retval
+    0    ok
+  @retval
+    -1   error
+*/
+int MYSQL_BIN_LOG::preallocate(File fd)
+{
+  if (mysql_file_allocate(fd, max_binlog_size) && 
+      mysql_file_sync(fd, MYF(MY_WME)))
+    goto err;
+  return 0;
+err:
+  return -1;
+}
+
+
+/**
+  Create a new preallocated binary log
+
+  @retval
+    0  ok
+  @retval
+    1  error happens when creating file
+    2  error happens when preallocating file
+*/
+int MYSQL_BIN_LOG::create_preallocate(char* new_log_path)
+{
+  int fd, err=0;
+  if ((fd= my_open(new_log_path, O_CREAT | O_WRONLY,
+      MYF(MY_WME))) >= 0)
+  {
+    if (preallocate(fd))
+      err=2;
+    my_close(fd, MYF(0));
+  } else
+      err=1;
+  return err;
+}
+
+
+/**
   Open a (new) binlog file.
 
   - Open the log file and the index file. Register the new
@@ -1710,11 +1847,18 @@ bool MYSQL_BIN_LOG::open(const char *log
   DBUG_ENTER("MYSQL_BIN_LOG::open");
   DBUG_PRINT("enter",("log_type: %d",(int) log_type_arg));
 
-  if (init_and_set_log_file_name(log_name, new_name, log_type_arg,
-                                 io_cache_type_arg))
+  if (!binlog_preallocate)
   {
-    sql_print_error("MSYQL_BIN_LOG::open failed to generate new file name.");
-    DBUG_RETURN(1);
+    if (init_and_set_log_file_name(log_name, new_name, log_type_arg,
+                                   io_cache_type_arg))
+    {
+      sql_print_error("MSYQL_BIN_LOG::open failed to generate new file name.");
+      DBUG_RETURN(1);
+    }
+  } else if (!new_name)
+  {
+    new_log_name_from_index(log_file_name, log_name, need_mutex);
+    new_name= log_file_name;
   }
 
 #ifdef HAVE_REPLICATION
@@ -1767,6 +1911,55 @@ bool MYSQL_BIN_LOG::open(const char *log
 
   DBUG_ASSERT(log_type == LOG_BIN);
 
+  if ((binlog_preallocate && io_cache_type_arg == WRITE_CACHE))
+  {
+    /* Preallocating binlog if newly activated binlog size is zero */
+    if (!my_seek(log_file.file, 0L, MY_SEEK_END, MYF(0)))
+    {
+      ulong i= 0;
+      char next_log_name[FN_REFLEN];
+      char log_name_buff[FN_REFLEN];
+      ulong binlog_suffix= 0;
+
+      if (preallocate(log_file.file))
+        goto err;
+
+      /*
+        If binlog_preallocate >= 2, creating and preallocating
+        (binlog_preallocate - 1) files here (if not exists)
+      */
+      fn_format(log_name_buff, log_name, mysql_data_home, "", 4);
+      if (test_if_number((new_name)
+          + strlen(log_name_buff) + 1, &binlog_suffix, 0))
+      {
+        for (i=0; i< binlog_preallocate - 1; i++)
+        {
+          binlog_suffix++;
+          sprintf(next_log_name, "%s.%06ld", log_name_buff, binlog_suffix);
+          MY_STAT s;
+          if (!my_stat(next_log_name, &s, MYF(0)))
+          {
+            int error= create_preallocate(next_log_name);
+            if (error == 1)
+            {
+              sql_print_error("Error happens when creating the %ldth "
+                              "file: %s\n", i+2, next_log_name);
+              DBUG_RETURN(1);
+            }
+            else if (error == 2)
+            {
+              sql_print_error("Error happens when preallocating the %ldth "
+                              "file: %s\n", i+2, next_log_name);
+              DBUG_RETURN(1);
+            }
+          }
+        }
+      }
+    }
+    if (my_seek(log_file.file, 0L, MY_SEEK_SET, MYF(0)))
+      goto err;
+  }
+
   {
     bool write_file_name_to_index_file=0;
 
@@ -1855,6 +2048,12 @@ bool MYSQL_BIN_LOG::open(const char *log
         mysql_file_sync(log_file.file, MYF(MY_WME)))
       goto err;
 
+    /*
+      Updating actual_size when flushing binlog into disk
+      for writing format descriptor event.
+    */
+    actual_size= log_file.pos_in_file;
+
     if (write_file_name_to_index_file)
     {
 #ifdef HAVE_REPLICATION
@@ -2976,13 +3175,22 @@ int MYSQL_BIN_LOG::new_file_impl(bool ne
   /* Reuse old name if not binlog and not update log */
   new_name_ptr= name;
 
-  /*
-    If user hasn't specified an extension, generate a new log name
-    We have to do this here and not in open as we want to store the
-    new file name in the current binary log file.
-  */
-  if ((error= generate_new_name(new_name, name)))
-    goto end;
+  if (binlog_preallocate)
+  {
+    if (new_log_name_from_index(new_name, name, 0))
+      goto end;
+  }
+  else
+  {
+    /*
+      If user hasn't specified an extension, generate a new log name
+      We have to do this here and not in open as we want to store the
+      new file name in the current binary log file.
+    */
+    if (generate_new_name(new_name, name))
+      goto end;
+  }
+
   new_name_ptr=new_name;
 
   if (log_type == LOG_BIN)
@@ -3448,6 +3656,11 @@ err:
         if ((error= flush_and_sync(&synced)))
           goto unlock;
 
+        /*
+          Updating actual_size when flushing binlog into disk
+          for writing direct logging event.
+        */
+        actual_size= event_info->log_pos;
         if ((error= RUN_HOOK(binlog_storage, after_flush,
                  (thd, log_file_name, file->pos_in_file, synced))))
         {
@@ -3830,6 +4043,11 @@ bool MYSQL_BIN_LOG::write_incident(THD *
       signal_update();
       error= rotate_and_purge(RP_LOCK_LOG_IS_ALREADY_LOCKED);
     }
+    /*
+      Updating actual_size when flushing binlog into disk
+      for writing incident event.
+    */
+    actual_size= ev.log_pos;
     mysql_mutex_unlock(&LOCK_log);
   }
   DBUG_RETURN(error);
@@ -3903,6 +4121,12 @@ bool MYSQL_BIN_LOG::write(THD *thd, IO_C
       bool synced= 0;
       if (flush_and_sync(&synced))
         goto err;
+
+      /*
+        Updating actual_size when flushing binlog into disk
+        for transaction/non-transaction commit.
+      */
+      actual_size= commit_event->log_pos;
       DBUG_EXECUTE_IF("half_binlogged_transaction", DBUG_SUICIDE(););
       if (cache->error)				// Error on read
       {
@@ -4061,6 +4285,20 @@ void MYSQL_BIN_LOG::close(uint exiting)
         original position on system that doesn't support pwrite().
       */
       mysql_file_seek(log_file.file, org_position, MY_SEEK_SET, MYF(0));
+
+      end_io_cache(&log_file);
+      DBUG_ASSERT(is_active(log_file_name));
+      mysql_mutex_assert_owner(&LOCK_log);
+      /*
+        Updating actual_size when closing the binlog file.
+      */
+      actual_size= log_file.pos_in_file;
+      if (binlog_preallocate && my_chsize(log_file.file,
+          log_file.pos_in_file, 0, MYF(MY_WME)))
+      {
+        write_error= 1;
+        sql_print_error(ER(ER_ERROR_ON_WRITE), name, errno);
+      }
     }
 
     /* this will cleanup IO_CACHE, sync and close the file */
@@ -4182,7 +4420,7 @@ int MYSQL_BIN_LOG::open(const char *opt_
       goto err;
     }
 
-    if ((file= open_binlog(&log, log_name, &errmsg)) < 0)
+    if ((file= open_binlog(&log, log_name, &errmsg, get_log_lock())) < 0)
     {
       sql_print_error("%s", errmsg);
       goto err;

=== modified file 'sql/binlog.h'
--- a/sql/binlog.h	2010-12-10 16:55:50 +0000
+++ b/sql/binlog.h	2010-12-30 11:58:25 +0000
@@ -271,6 +271,12 @@ public:
   inline void unlock_index() { mysql_mutex_unlock(&LOCK_index);}
   inline IO_CACHE *get_index_file() { return &index_file;}
   inline uint32 get_open_count() { return open_count; }
+
+  ulonglong actual_size;
+  int preallocate(File fd);
+  int create_preallocate(char* new_log_path);
+  int new_log_name_from_index(char* new_binlog_name,
+                              const char* opt_name, bool need_lock);
 };
 
 typedef struct st_load_file_info
@@ -292,7 +298,7 @@ bool stmt_has_updated_non_trans_table(co
 
 int log_loaded_block(IO_CACHE* file);
 File open_binlog(IO_CACHE *log, const char *log_file_name,
-                 const char **errmsg);
+                 const char **errmsg, mysql_mutex_t* log_lock);
 int check_binlog_magic(IO_CACHE* log, const char** errmsg);
 bool purge_master_logs(THD* thd, const char* to_log);
 bool purge_master_logs_before_date(THD* thd, time_t purge_time);

=== modified file 'sql/log.cc'
--- a/sql/log.cc	2010-12-17 02:01:32 +0000
+++ b/sql/log.cc	2010-12-30 11:58:25 +0000
@@ -37,7 +37,6 @@
 
 #include <my_dir.h>
 #include <stdarg.h>
-#include <m_ctype.h>				// For test_if_number
 
 #ifdef _WIN32
 #include "message.h"
@@ -49,8 +48,6 @@
 
 LOGGER logger;
 
-static bool test_if_number(const char *str,
-			   ulong *res, bool allow_wildcards);
 
 /**
    purge logs, master and slave sides both, related error code
@@ -1966,8 +1963,8 @@ bool general_log_write(THD *thd, enum en
     0	String is not a number
 */
 
-static bool test_if_number(register const char *str,
-			   ulong *res, bool allow_wildcards)
+bool test_if_number(register const char *str,
+                    ulong *res, bool allow_wildcards)
 {
   reg2 int flag;
   const char *start;

=== modified file 'sql/log.h'
--- a/sql/log.h	2010-12-10 16:55:50 +0000
+++ b/sql/log.h	2010-12-30 11:58:25 +0000
@@ -18,6 +18,11 @@
 
 #include "unireg.h"                    // REQUIRED: for other includes
 #include "handler.h"                            /* my_xid */
+#include <m_ctype.h>                            // For test_if_number
+
+
+bool test_if_number(const char *str,
+                    ulong *res, bool allow_wildcards);
 
 /*
   Transaction Coordinator log - a base abstract class

=== modified file 'sql/log_event.cc'
--- a/sql/log_event.cc	2010-12-21 10:39:20 +0000
+++ b/sql/log_event.cc	2010-12-30 11:58:25 +0000
@@ -1129,6 +1129,21 @@ int Log_event::read_log_event(IO_CACHE*
 
   if (log_lock)
     mysql_mutex_lock(log_lock);
+
+  /* mysql_bin_log.is_active() might be true if binlog dump thread
+    reads currently active binlog. If the binlog is preallocated,
+    binlog dump thread should not read active binlog until EOF,
+    but should read until mysql_bin_log.actual_size. By updating
+    file->end_of_file to mysql_bin_log.actual_size, my_b_read() reads
+    until mysql_bin_log.actual_size then detects as EOF. */
+  if (binlog_preallocate && file->file_name  && file->type == READ_CACHE)
+  {
+    if (mysql_bin_log.is_active(file->file_name))
+      file->end_of_file= mysql_bin_log.actual_size;
+    else
+      file->end_of_file= ~(my_off_t) 0;
+  }
+
   if (my_b_read(file, (uchar*) buf, sizeof(buf)))
   {
     /*
@@ -1257,6 +1272,23 @@ Log_event* Log_event::read_log_event(IO_
 
   LOCK_MUTEX;
   DBUG_PRINT("info", ("my_b_tell: %lu", (ulong) my_b_tell(file)));
+
+  /* mysql_bin_log.is_active() might be true if SHOW BINLOG EVENTS
+    reads currently active binlog. If the binlog is preallocated,
+    SHOW BINLOG EVENTS should not read active binlog until EOF,
+    but should read until mysql_bin_log.actual_size. By updating
+    file->end_of_file to mysql_bin_log.actual_size, my_b_read() reads
+    until mysql_bin_log.actual_size then detects as EOF. */
+#ifndef MYSQL_CLIENT
+  if (binlog_preallocate && file->file_name && file->type == READ_CACHE)
+  {
+    if (mysql_bin_log.is_active(file->file_name))
+      file->end_of_file= mysql_bin_log.actual_size;
+    else
+      file->end_of_file= ~(my_off_t) 0;
+  }
+#endif
+
   if (my_b_read(file, (uchar *) head, header_size))
   {
     DBUG_PRINT("info", ("Log_event::read_log_event(IO_CACHE*,Format_desc*) \

=== modified file 'sql/mysqld.cc'
--- a/sql/mysqld.cc	2010-12-22 09:28:27 +0000
+++ b/sql/mysqld.cc	2010-12-30 11:58:25 +0000
@@ -464,6 +464,7 @@ ulong slave_exec_mode_options;
 ulonglong slave_type_conversions_options;
 ulong thread_cache_size=0;
 ulong binlog_cache_size=0;
+ulong binlog_preallocate=0;
 ulonglong  max_binlog_cache_size=0;
 ulong binlog_stmt_cache_size=0;
 ulonglong  max_binlog_stmt_cache_size=0;

=== modified file 'sql/mysqld.h'
--- a/sql/mysqld.h	2010-12-17 11:28:59 +0000
+++ b/sql/mysqld.h	2010-12-30 11:58:25 +0000
@@ -180,6 +180,7 @@ extern ulong what_to_log,flush_time;
 extern ulong max_prepared_stmt_count, prepared_stmt_count;
 extern ulong open_files_limit;
 extern ulong binlog_cache_size, binlog_stmt_cache_size;
+extern ulong binlog_preallocate;
 extern ulonglong max_binlog_cache_size, max_binlog_stmt_cache_size;
 extern ulong max_binlog_size, max_relay_log_size;
 extern ulong opt_binlog_rows_event_max_size;

=== modified file 'sql/rpl_master.cc'
--- a/sql/rpl_master.cc	2010-12-17 10:07:30 +0000
+++ b/sql/rpl_master.cc	2010-12-30 11:58:25 +0000
@@ -725,7 +725,8 @@ void mysql_binlog_send(THD* thd, char* l
   thd->current_linfo = &linfo;
   mysql_mutex_unlock(&LOCK_thread_count);
 
-  if ((file=open_binlog(&log, log_file_name, &errmsg)) < 0)
+  if ((file=open_binlog(&log, log_file_name, &errmsg,
+       mysql_bin_log.get_log_lock())) < 0)
   {
     my_errno= ER_MASTER_FATAL_ERROR_READING_BINLOG;
     goto err;
@@ -1208,7 +1209,8 @@ impossible position";
         position.  If the binlog is 5.0, the next event we are going to
         read and send is Format_description_log_event.
       */
-      if ((file=open_binlog(&log, log_file_name, &errmsg)) < 0 ||
+      if ((file=open_binlog(&log, log_file_name, &errmsg,
+                            mysql_bin_log.get_log_lock())) < 0 ||
 	  fake_rotate_event(net, packet, log_file_name, BIN_LOG_HEADER_SIZE,
                             &errmsg, current_checksum_alg))
       {

=== modified file 'sql/rpl_rli.cc'
--- a/sql/rpl_rli.cc	2010-12-21 09:33:41 +0000
+++ b/sql/rpl_rli.cc	2010-12-30 11:58:25 +0000
@@ -267,7 +267,7 @@ int Relay_log_info::init_relay_log_pos(c
       Open the relay log and set cur_log to point at this one
     */
     if ((cur_log_fd=open_binlog(&cache_buf,
-                                linfo.log_file_name,errmsg)) < 0)
+                                linfo.log_file_name,errmsg, NULL)) < 0)
       goto err;
     cur_log = &cache_buf;
   }

=== modified file 'sql/rpl_slave.cc'
--- a/sql/rpl_slave.cc	2010-12-10 16:55:50 +0000
+++ b/sql/rpl_slave.cc	2010-12-30 11:58:25 +0000
@@ -4945,7 +4945,7 @@ static IO_CACHE *reopen_relay_log(Relay_
 
   IO_CACHE *cur_log = rli->cur_log=&rli->cache_buf;
   if ((rli->cur_log_fd=open_binlog(cur_log,rli->get_event_relay_log_name(),
-                                   errmsg)) <0)
+                                   errmsg, NULL)) <0)
     DBUG_RETURN(0);
   /*
     We want to start exactly where we was before:
@@ -5365,7 +5365,7 @@ static Log_event* next_event(Relay_log_i
 #endif
       // open_binlog() will check the magic header
       if ((rli->cur_log_fd=open_binlog(cur_log,rli->linfo.log_file_name,
-                                       &errmsg)) <0)
+                                       &errmsg, NULL)) <0)
         goto err;
     }
     else

=== modified file 'sql/sys_vars.cc'
--- a/sql/sys_vars.cc	2010-12-20 13:26:51 +0000
+++ b/sql/sys_vars.cc	2010-12-30 11:58:25 +0000
@@ -291,6 +291,33 @@ static Sys_var_ulong Sys_binlog_stmt_cac
        NO_MUTEX_GUARD, NOT_IN_BINLOG, ON_CHECK(0),
        ON_UPDATE(fix_binlog_stmt_cache_size));
 
+static Sys_var_ulong Sys_binlog_preallocate(
+       "binlog_preallocate", "This variable is used to dynamically "
+       "preallocating binlog file(s) to improve binary logging performance. "
+       "This is epecially effective if sync-binlog=1." 
+       "The default value is 0, which does neither preallocate binlog "
+       "automatically nor uses preallocated binlog files(generated by "
+       "mysqlbinlogalloc). This is the as same behavior as previous versions. " 
+       "If binlog_preallocate is 1, mysqld does not preallocate binlogs "
+       "automatically, but detect statically preallocated binlog files. "
+       "If binlog_preallocate >=2, mysqld works as follows when "
+       "switching binlog. (1)If new binlog file does not exist, mysqld creates "
+       "and preallocates binlog file(s). Preallocated file size is equal to "
+       "max_binlog_size. binlog_preallocate=N (N>=2) means N binlog files are "
+       "automatically generated at this point. (2)If new binlog file is "
+       "created beforehand(by mysqlbinlogalloc), mysqld opens and uses it "
+       "instead of creating new binlog file (creating new binlog file is "
+       "the default behavior in MySQL). It is recommended that allocating "
+       "many binlog files by mysqlbinlogalloc before starting mysqld, "
+       "and setting binlog_preallocate=1 and sync_binlog=1 in my.cnf. "
+       "Then you can avoid overheads of writing huge amounts of data "
+       "to preallocate binlog. If posix_fallocate() is accurately supported "
+       "on targetted filesystems, setting high binlog_preallocate value "
+       "is fine because preallocation cost is almost zero.",
+       GLOBAL_VAR(binlog_preallocate),
+       CMD_LINE(REQUIRED_ARG),
+       VALID_RANGE(0, 512), DEFAULT(0), BLOCK_SIZE(1));
+
 static bool check_has_super(sys_var *self, THD *thd, set_var *var)
 {
   DBUG_ASSERT(self->scope() != sys_var::GLOBAL);// don't abuse check_has_super()

Attachment: [text/bzr-bundle] bzr/dao-gang.qu@sun.com-20101230115825-1a5df7j8f1w4702e.bundle
Thread
bzr commit into mysql-trunk branch (Dao-Gang.Qu:3446) WL#4925Dao-Gang.Qu30 Dec