summaryrefslogtreecommitdiff
path: root/sql
diff options
context:
space:
mode:
Diffstat (limited to 'sql')
-rw-r--r--sql/ha_archive.cc5
-rw-r--r--sql/ha_berkeley.cc4
-rw-r--r--sql/ha_blackhole.cc4
-rw-r--r--sql/ha_federated.cc4
-rw-r--r--sql/ha_heap.cc4
-rw-r--r--sql/ha_innodb.cc5
-rw-r--r--sql/ha_myisam.cc4
-rw-r--r--sql/ha_myisammrg.cc4
-rw-r--r--sql/ha_ndbcluster_binlog.cc2
-rw-r--r--sql/ha_partition.cc6
-rw-r--r--sql/handler.cc8
-rw-r--r--sql/handler.h7
-rw-r--r--sql/item_func.cc1
-rw-r--r--sql/item_strfunc.cc1
-rw-r--r--sql/log.cc10
-rw-r--r--sql/log.h20
-rw-r--r--sql/log_event.cc6
-rw-r--r--sql/log_event.h8
-rw-r--r--sql/mysql_priv.h4
-rw-r--r--sql/mysqld.cc89
-rw-r--r--sql/partition_info.cc8
-rw-r--r--sql/set_var.cc57
-rw-r--r--sql/set_var.h12
-rw-r--r--sql/share/errmsg.txt10
-rw-r--r--sql/sp_head.cc2
-rw-r--r--sql/sql_base.cc2
-rw-r--r--sql/sql_class.cc21
-rw-r--r--sql/sql_class.h15
-rw-r--r--sql/sql_delete.cc2
-rw-r--r--sql/sql_insert.cc8
-rw-r--r--sql/sql_load.cc7
-rw-r--r--sql/sql_parse.cc1
-rw-r--r--sql/sql_partition.cc2
-rw-r--r--sql/sql_show.cc2
-rw-r--r--sql/sql_table.cc18
35 files changed, 225 insertions, 138 deletions
diff --git a/sql/ha_archive.cc b/sql/ha_archive.cc
index 8ed16949edd..a8bc0822a85 100644
--- a/sql/ha_archive.cc
+++ b/sql/ha_archive.cc
@@ -177,9 +177,10 @@ handlerton archive_hton = {
NULL, /* Partition flags */
NULL, /* Alter table flags */
NULL, /* Alter interface */
+ NULL, /* fill_files_table */
HTON_NO_FLAGS,
- NULL, /* binlog_func */
- NULL /* binlog_log_query */
+ NULL, /* binlog_func */
+ NULL /* binlog_log_query */
};
static handler *archive_create_handler(TABLE_SHARE *table)
diff --git a/sql/ha_berkeley.cc b/sql/ha_berkeley.cc
index 6866b50fd19..910a703fdeb 100644
--- a/sql/ha_berkeley.cc
+++ b/sql/ha_berkeley.cc
@@ -153,7 +153,9 @@ handlerton berkeley_hton = {
NULL, /* Alter table flags */
NULL, /* Alter Tablespace */
NULL, /* Fill Files Table */
- HTON_CLOSE_CURSORS_AT_COMMIT | HTON_FLUSH_AFTER_RENAME
+ HTON_CLOSE_CURSORS_AT_COMMIT | HTON_FLUSH_AFTER_RENAME,
+ NULL, /* binlog_func */
+ NULL /* binlog_log_query */
};
handler *berkeley_create_handler(TABLE_SHARE *table)
diff --git a/sql/ha_blackhole.cc b/sql/ha_blackhole.cc
index 42c785e2003..7d28344a0a4 100644
--- a/sql/ha_blackhole.cc
+++ b/sql/ha_blackhole.cc
@@ -61,7 +61,9 @@ handlerton blackhole_hton= {
NULL, /* Alter table flags */
NULL, /* Alter Tablespace */
NULL, /* Fill FILES table */
- HTON_CAN_RECREATE
+ HTON_CAN_RECREATE,
+ NULL, /* binlog_func */
+ NULL /* binlog_log_query */
};
diff --git a/sql/ha_federated.cc b/sql/ha_federated.cc
index f7e0c1242fe..976f3739386 100644
--- a/sql/ha_federated.cc
+++ b/sql/ha_federated.cc
@@ -398,7 +398,9 @@ handlerton federated_hton= {
NULL, /* Alter table flags */
NULL, /* Alter Tablespace */
NULL, /* Fill FILES table */
- HTON_ALTER_NOT_SUPPORTED
+ HTON_ALTER_NOT_SUPPORTED,
+ NULL, /* binlog_func */
+ NULL /* binlog_log_query */
};
diff --git a/sql/ha_heap.cc b/sql/ha_heap.cc
index d4790cf7d01..96f760a7a44 100644
--- a/sql/ha_heap.cc
+++ b/sql/ha_heap.cc
@@ -58,7 +58,9 @@ handlerton heap_hton= {
NULL, /* Alter table flags */
NULL, /* Alter Tablespace */
NULL, /* Fill Files Table */
- HTON_CAN_RECREATE
+ HTON_CAN_RECREATE,
+ NULL, /* binlog_func */
+ NULL /* binlog_log_query */
};
static handler *heap_create_handler(TABLE_SHARE *table)
diff --git a/sql/ha_innodb.cc b/sql/ha_innodb.cc
index 0002ab0123f..153c456c06c 100644
--- a/sql/ha_innodb.cc
+++ b/sql/ha_innodb.cc
@@ -237,8 +237,11 @@ handlerton innobase_hton = {
innobase_show_status, /* Show status */
NULL, /* Partition flags */
NULL, /* Alter table flags */
+ NULL, /* alter_tablespace */
NULL, /* Fill FILES table */
- HTON_NO_FLAGS
+ HTON_NO_FLAGS,
+ NULL, /* binlog_func */
+ NULL /* binlog_log_query */
};
diff --git a/sql/ha_myisam.cc b/sql/ha_myisam.cc
index 4b84d3efa7f..fba36450d81 100644
--- a/sql/ha_myisam.cc
+++ b/sql/ha_myisam.cc
@@ -90,7 +90,9 @@ handlerton myisam_hton= {
NULL, /* Alter table flags */
NULL, /* Alter Tablespace */
NULL, /* Fill Files Table */
- HTON_CAN_RECREATE
+ HTON_CAN_RECREATE,
+ NULL, /* binlog_func */
+ NULL /* binlog_log_query */
};
diff --git a/sql/ha_myisammrg.cc b/sql/ha_myisammrg.cc
index 32b67cd23e5..a24b32435a8 100644
--- a/sql/ha_myisammrg.cc
+++ b/sql/ha_myisammrg.cc
@@ -68,7 +68,9 @@ handlerton myisammrg_hton= {
NULL, /* Alter table flags */
NULL, /* Alter Tablespace */
NULL, /* Fill Files Table */
- HTON_CAN_RECREATE
+ HTON_CAN_RECREATE,
+ NULL, /* binlog_func */
+ NULL /* binlog_log_query */
};
static handler *myisammrg_create_handler(TABLE_SHARE *table)
diff --git a/sql/ha_ndbcluster_binlog.cc b/sql/ha_ndbcluster_binlog.cc
index 892a5e02453..72c03819b8a 100644
--- a/sql/ha_ndbcluster_binlog.cc
+++ b/sql/ha_ndbcluster_binlog.cc
@@ -2774,7 +2774,7 @@ pthread_handler_t ndb_binlog_thread_func(void *arg)
ndb_binlog_thread_running= 1;
if (opt_bin_log)
{
- if (binlog_row_based)
+ if (global_system_variables.binlog_format == BINLOG_FORMAT_ROW)
{
ndb_binlog_running= TRUE;
}
diff --git a/sql/ha_partition.cc b/sql/ha_partition.cc
index 7e92f8a7739..e7a324481db 100644
--- a/sql/ha_partition.cc
+++ b/sql/ha_partition.cc
@@ -102,7 +102,9 @@ handlerton partition_hton = {
alter_table_flags, /* Partition flags */
NULL, /* Alter Tablespace */
NULL, /* Fill FILES table */
- HTON_NOT_USER_SELECTABLE | HTON_HIDDEN
+ HTON_NOT_USER_SELECTABLE | HTON_HIDDEN,
+ NULL, /* binlog_func */
+ NULL /* binlog_log_query */
};
/*
@@ -2609,7 +2611,7 @@ void ha_partition::unlock_row()
ADDITIONAL INFO:
Most handlers set timestamp when calling write row if any such fields
- exists. Since we are calling an underlying handler we assume the“
+ exists. Since we are calling an underlying handler we assume theĀ“
underlying handler will assume this responsibility.
Underlying handlers will also call update_auto_increment to calculate
diff --git a/sql/handler.cc b/sql/handler.cc
index 68ca3855158..3c79a1af8bd 100644
--- a/sql/handler.cc
+++ b/sql/handler.cc
@@ -64,7 +64,11 @@ const handlerton default_hton =
NULL, NULL, NULL,
create_default,
NULL, NULL, NULL, NULL, NULL, NULL, NULL,
- HTON_NO_FLAGS
+ NULL, /* alter_tablespace */
+ NULL, /* fill_files_table */
+ HTON_NO_FLAGS, /* flags */
+ NULL, /* binlog_func */
+ NULL /* binlog_log_query */
};
static SHOW_COMP_OPTION have_yes= SHOW_OPTION_YES;
@@ -3147,7 +3151,7 @@ namespace {
bool check_table_binlog_row_based(THD *thd, TABLE *table)
{
return
- binlog_row_based &&
+ thd->current_stmt_binlog_row_based &&
thd && (thd->options & OPTION_BIN_LOG) &&
(table->s->tmp_table == NO_TMP_TABLE) &&
binlog_filter->db_ok(table->s->db.str);
diff --git a/sql/handler.h b/sql/handler.h
index 2d415854d2b..b0cc3116288 100644
--- a/sql/handler.h
+++ b/sql/handler.h
@@ -543,10 +543,9 @@ typedef struct
struct st_table_list *tables,
class Item *cond);
uint32 flags; /* global handler flags */
- /*
- Handlerton functions are not set in the different storage
- engines static initialization. They are initialized at handler init.
- Thus, leave them last in the struct.
+ /*
+ Those handlerton functions below are properly initialized at handler
+ init.
*/
int (*binlog_func)(THD *thd, enum_binlog_func fn, void *arg);
void (*binlog_log_query)(THD *thd, enum_binlog_command binlog_command,
diff --git a/sql/item_func.cc b/sql/item_func.cc
index 22200732861..d2e0911557f 100644
--- a/sql/item_func.cc
+++ b/sql/item_func.cc
@@ -2657,6 +2657,7 @@ udf_handler::fix_fields(THD *thd, Item_result_field *func,
u_d->name.str, ER(ER_UNKNOWN_ERROR));
DBUG_RETURN(TRUE);
}
+ thd->set_current_stmt_binlog_row_based_if_mixed();
DBUG_RETURN(FALSE);
}
diff --git a/sql/item_strfunc.cc b/sql/item_strfunc.cc
index a3e47154bc3..eb89eb7708c 100644
--- a/sql/item_strfunc.cc
+++ b/sql/item_strfunc.cc
@@ -3002,6 +3002,7 @@ String *Item_func_uuid::val_str(String *str)
char *s;
THD *thd= current_thd;
+ thd->set_current_stmt_binlog_row_based_if_mixed();
pthread_mutex_lock(&LOCK_uuid_generator);
if (! uuid_time) /* first UUID() call. initializing data */
{
diff --git a/sql/log.cc b/sql/log.cc
index 323b6df86d9..ff14b986aa4 100644
--- a/sql/log.cc
+++ b/sql/log.cc
@@ -102,7 +102,9 @@ handlerton binlog_hton = {
NULL, /* Alter table flags */
NULL, /* Alter Tablespace */
NULL, /* Fill FILES table */
- HTON_NOT_USER_SELECTABLE | HTON_HIDDEN
+ HTON_NOT_USER_SELECTABLE | HTON_HIDDEN,
+ NULL, /* binlog_func */
+ NULL /* binlog_log_query */
};
@@ -2630,7 +2632,7 @@ THD::binlog_set_pending_rows_event(Rows_log_event* ev)
int MYSQL_LOG::flush_and_set_pending_rows_event(THD *thd, Rows_log_event* event)
{
DBUG_ENTER("MYSQL_LOG::flush_and_set_pending_rows_event(event)");
- DBUG_ASSERT(binlog_row_based && mysql_bin_log.is_open());
+ DBUG_ASSERT(thd->current_stmt_binlog_row_based && mysql_bin_log.is_open());
DBUG_PRINT("enter", ("event=%p", event));
int error= 0;
@@ -2847,7 +2849,7 @@ bool MYSQL_LOG::write(Log_event *event_info)
*/
if (thd)
{
- if (!binlog_row_based)
+ if (!thd->current_stmt_binlog_row_based)
{
if (thd->last_insert_id_used)
{
@@ -3517,7 +3519,7 @@ bool MYSQL_LOG::write_table_map(THD *thd, IO_CACHE *file, TABLE* table,
table, table->s->table_name, table->s->table_map_id));
/* Pre-conditions */
- DBUG_ASSERT(binlog_row_based && is_open());
+ DBUG_ASSERT(thd->current_stmt_binlog_row_based && is_open());
DBUG_ASSERT(table->s->table_map_id != ULONG_MAX);
#ifndef DBUG_OFF
diff --git a/sql/log.h b/sql/log.h
index 98a86072fca..8a83e7b66d0 100644
--- a/sql/log.h
+++ b/sql/log.h
@@ -507,4 +507,24 @@ public:
void init_general_log(uint general_log_printer);
};
+
+enum enum_binlog_format {
+ BINLOG_FORMAT_STMT= 0, // statement-based
+#ifdef HAVE_ROW_BASED_REPLICATION
+ BINLOG_FORMAT_ROW= 1, // row_based
+ /*
+ statement-based except for cases where only row-based can work (UUID()
+ etc):
+ */
+ BINLOG_FORMAT_MIXED= 2,
+#endif
+/*
+ This value is last, after the end of binlog_format_typelib: it has no
+ corresponding cell in this typelib. We use this value to be able to know if
+ the user has explicitely specified a binlog format at startup or not.
+*/
+ BINLOG_FORMAT_UNSPEC= 3
+};
+extern TYPELIB binlog_format_typelib;
+
#endif /* LOG_H */
diff --git a/sql/log_event.cc b/sql/log_event.cc
index 5b95b87bcd2..15905731577 100644
--- a/sql/log_event.cc
+++ b/sql/log_event.cc
@@ -5854,13 +5854,17 @@ int Table_map_log_event::exec_event(st_relay_log_info *rli)
(!rpl_filter->is_on() || rpl_filter->tables_ok("", &table_list)))
{
/*
+ TODO: Mats will soon change this test below so that a SBR slave always
+ accepts RBR events from the master (and binlogs them RBR).
+ */
+ /*
Check if the slave is set to use SBR. If so, the slave should
stop immediately since it is not possible to daisy-chain from
RBR to SBR. Once RBR is used, the rest of the chain has to use
RBR.
*/
if (mysql_bin_log.is_open() && (thd->options & OPTION_BIN_LOG) &&
- !binlog_row_based)
+ !thd->current_stmt_binlog_row_based)
{
slave_print_msg(ERROR_LEVEL, rli, ER_BINLOG_ROW_RBR_TO_SBR,
"It is not possible to use statement-based binlogging "
diff --git a/sql/log_event.h b/sql/log_event.h
index a7c532d4c24..d7212c5a195 100644
--- a/sql/log_event.h
+++ b/sql/log_event.h
@@ -28,14 +28,6 @@
#include <my_bitmap.h>
-#if !defined(MYSQL_CLIENT)
-#ifdef HAVE_ROW_BASED_REPLICATION
-extern my_bool binlog_row_based;
-#else
-extern const my_bool binlog_row_based;
-#endif
-#endif
-
#define LOG_READ_EOF -1
#define LOG_READ_BOGUS -2
#define LOG_READ_IO -3
diff --git a/sql/mysql_priv.h b/sql/mysql_priv.h
index 8e85e70fccd..4db6dafcd59 100644
--- a/sql/mysql_priv.h
+++ b/sql/mysql_priv.h
@@ -1288,12 +1288,8 @@ extern ulong what_to_log,flush_time;
extern ulong query_buff_size, thread_stack;
extern ulong binlog_cache_size, max_binlog_cache_size, open_files_limit;
extern ulong max_binlog_size, max_relay_log_size;
-extern const char *opt_binlog_format;
#ifdef HAVE_ROW_BASED_REPLICATION
-extern my_bool binlog_row_based;
extern ulong opt_binlog_rows_event_max_size;
-#else
-extern const my_bool binlog_row_based;
#endif
extern ulong rpl_recovery_rank, thread_cache_size;
extern ulong back_log;
diff --git a/sql/mysqld.cc b/sql/mysqld.cc
index e1c8ed966ee..1147b8a82cf 100644
--- a/sql/mysqld.cc
+++ b/sql/mysqld.cc
@@ -465,31 +465,14 @@ my_bool opt_noacl;
my_bool sp_automatic_privileges= 1;
#ifdef HAVE_ROW_BASED_REPLICATION
-/*
- This variable below serves as an optimization for (opt_binlog_format ==
- BF_ROW) as we need to do this test for every row. Stmt-based is default.
-*/
-my_bool binlog_row_based= FALSE;
ulong opt_binlog_rows_event_max_size;
-const char *binlog_format_names[]= {"STATEMENT", "ROW", NullS};
-/*
- Note that BF_UNSPECIFIED is last, after the end of binlog_format_names: it
- has no corresponding cell in this array. We use this value to be able to
- know if the user has explicitely specified a binlog format (then we require
- also --log-bin) or not (then we fall back to statement-based).
-*/
-enum binlog_format { BF_STMT= 0, BF_ROW= 1, BF_UNSPECIFIED= 2 };
+const char *binlog_format_names[]= {"STATEMENT", "ROW", "MIXED", NullS};
#else
-const my_bool binlog_row_based= FALSE;
const char *binlog_format_names[]= {"STATEMENT", NullS};
-enum binlog_format { BF_STMT= 0, BF_UNSPECIFIED= 2 };
#endif
-
TYPELIB binlog_format_typelib=
{ array_elements(binlog_format_names)-1,"",
binlog_format_names, NULL };
-const char *opt_binlog_format= 0;
-enum binlog_format opt_binlog_format_id= BF_UNSPECIFIED;
#ifdef HAVE_INITGROUPS
static bool calling_initgroups= FALSE; /* Used in SIGSEGV handler. */
@@ -3187,42 +3170,25 @@ with --log-bin instead.");
unireg_abort(1);
}
- if (!opt_bin_log && (opt_binlog_format_id != BF_UNSPECIFIED))
+ if (!opt_bin_log && (global_system_variables.binlog_format != BINLOG_FORMAT_UNSPEC))
{
sql_print_warning("You need to use --log-bin to make "
"--binlog-format work.");
unireg_abort(1);
}
- if (opt_binlog_format_id == BF_UNSPECIFIED)
+ if (global_system_variables.binlog_format == BINLOG_FORMAT_UNSPEC)
{
#ifdef HAVE_NDB_BINLOG
if (opt_bin_log && have_ndbcluster == SHOW_OPTION_YES)
- opt_binlog_format_id= BF_ROW;
+ global_system_variables.binlog_format= BINLOG_FORMAT_ROW;
else
#endif
- opt_binlog_format_id= BF_STMT;
- }
-#ifdef HAVE_ROW_BASED_REPLICATION
- if (opt_binlog_format_id == BF_ROW)
- {
- binlog_row_based= TRUE;
- /*
- Row-based binlogging turns on InnoDB unsafe locking, because the locks
- are not needed when using row-based binlogging. In fact
- innodb-locks-unsafe-for-binlog is unsafe only for stmt-based, it's
- safe for row-based.
- */
-#ifdef HAVE_INNOBASE_DB
- innobase_locks_unsafe_for_binlog= TRUE;
-#endif
- /* Trust stored function creators because they can do no harm */
- trust_function_creators= 1;
+ global_system_variables.binlog_format= BINLOG_FORMAT_STMT;
}
-#endif
+
/* Check that we have not let the format to unspecified at this point */
- DBUG_ASSERT((uint)opt_binlog_format_id <=
+ DBUG_ASSERT((uint)global_system_variables.binlog_format <=
array_elements(binlog_format_names)-1);
- opt_binlog_format= binlog_format_names[opt_binlog_format_id];
#ifdef HAVE_REPLICATION
if (opt_log_slave_updates && replicate_same_server_id)
@@ -4929,23 +4895,23 @@ Disable with --skip-bdb (will save memory).",
{"bind-address", OPT_BIND_ADDRESS, "IP address to bind to.",
(gptr*) &my_bind_addr_str, (gptr*) &my_bind_addr_str, 0, GET_STR,
REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
- {"binlog-format", OPT_BINLOG_FORMAT,
+ {"binlog_format", OPT_BINLOG_FORMAT,
#ifdef HAVE_ROW_BASED_REPLICATION
"Tell the master the form of binary logging to use: either 'row' for "
- "row-based binary logging (which automatically turns on "
- "innodb_locks_unsafe_for_binlog as it is safe in this case), or "
- "'statement' for statement-based logging. "
+ "row-based binary logging, or 'statement' for statement-based binary "
+ "logging, or 'mixed'. 'mixed' is statement-based binary logging except "
+ "for those statements where only row-based is correct: those which "
+ "involve user-defined functions (i.e. UDFs) or the UUID() function; for "
+ "those, row-based binary logging is automatically used. "
#ifdef HAVE_NDB_BINLOG
- "If ndbcluster is enabled, the default will be set to 'row'."
+ "If ndbcluster is enabled, the default is 'row'."
#endif
- ,
#else
- "Tell the master the form of binary logging to use: this release build "
+ "Tell the master the form of binary logging to use: this build "
"supports only statement-based binary logging, so only 'statement' is "
- "a legal value; MySQL-Max release builds support row-based binary logging "
- "in addition.",
+ "a legal value."
#endif
- 0, 0, 0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0 },
+ , 0, 0, 0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0 },
{"binlog-do-db", OPT_BINLOG_DO_DB,
"Tells the master it should log updates for the specified database, and exclude all others not explicitly mentioned.",
0, 0, 0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
@@ -5148,9 +5114,7 @@ Disable with --skip-innodb-doublewrite.", (gptr*) &innobase_use_doublewrite,
(gptr*) &innobase_unix_file_flush_method, 0, GET_STR, REQUIRED_ARG, 0, 0, 0,
0, 0, 0},
{"innodb_locks_unsafe_for_binlog", OPT_INNODB_LOCKS_UNSAFE_FOR_BINLOG,
- "Force InnoDB not to use next-key locking, to use only row-level locking."
- " This is unsafe if you are using statement-based binary logging, and safe"
- " if you are using row-based binary logging.",
+ "Force InnoDB to not use next-key locking, to use only row-level locking.",
(gptr*) &innobase_locks_unsafe_for_binlog,
(gptr*) &innobase_locks_unsafe_for_binlog, 0, GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0},
{"innodb_log_arch_dir", OPT_INNODB_LOG_ARCH_DIR,
@@ -5231,8 +5195,9 @@ Disable with --skip-innodb-doublewrite.", (gptr*) &innobase_use_doublewrite,
"a stored function (or trigger) is allowed only to users having the SUPER privilege "
"and only if this stored function (trigger) may not break binary logging."
#ifdef HAVE_ROW_BASED_REPLICATION
- " If using --binlog-format=row, the security issues do not exist and the "
- "binary logging cannot break so this option is automatically set to 1."
+ "Note that if ALL connections to this server ALWAYS use row-based binary "
+ "logging, the security issues do not exist and the binary logging cannot "
+ "break, so you can safely set this to 1."
#endif
,(gptr*) &trust_function_creators, (gptr*) &trust_function_creators, 0,
GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0},
@@ -7070,6 +7035,7 @@ static void mysql_init_variables(void)
max_system_variables.max_join_size= (ulonglong) HA_POS_ERROR;
global_system_variables.old_passwords= 0;
global_system_variables.old_alter_table= 0;
+ global_system_variables.binlog_format= BINLOG_FORMAT_UNSPEC;
/*
Default behavior for 4.1 and 5.0 is to treat NULL values as unequal
when collecting index statistics for MyISAM tables.
@@ -7314,18 +7280,19 @@ get_one_option(int optid, const struct my_option *opt __attribute__((unused)),
#ifdef HAVE_ROW_BASED_REPLICATION
fprintf(stderr,
"Unknown binary log format: '%s' "
- "(should be '%s' or '%s')\n",
+ "(should be one of '%s', '%s', '%s')\n",
argument,
- binlog_format_names[BF_STMT],
- binlog_format_names[BF_ROW]);
+ binlog_format_names[BINLOG_FORMAT_STMT],
+ binlog_format_names[BINLOG_FORMAT_ROW],
+ binlog_format_names[BINLOG_FORMAT_MIXED]);
#else
fprintf(stderr,
"Unknown binary log format: '%s' (only legal value is '%s')\n",
- argument, binlog_format_names[BF_STMT]);
+ argument, binlog_format_names[BINLOG_FORMAT_STMT]);
#endif
exit(1);
}
- opt_binlog_format_id= (enum binlog_format)(id-1);
+ global_system_variables.binlog_format= id-1;
break;
}
case (int)OPT_BINLOG_DO_DB:
diff --git a/sql/partition_info.cc b/sql/partition_info.cc
index 5d30dba5fbd..89f54a6497a 100644
--- a/sql/partition_info.cc
+++ b/sql/partition_info.cc
@@ -278,7 +278,7 @@ bool partition_info::has_unique_name(partition_element *element)
List_iterator<partition_element> parts_it(partitions);
partition_element *el;
- while (el= (parts_it++))
+ while ((el= (parts_it++)))
{
if (!(my_strcasecmp(system_charset_info, el->partition_name,
name_to_check)) && el != element)
@@ -288,7 +288,7 @@ bool partition_info::has_unique_name(partition_element *element)
{
partition_element *sub_el;
List_iterator<partition_element> subparts_it(el->subpartitions);
- while (sub_el= (subparts_it++))
+ while ((sub_el= (subparts_it++)))
{
if (!(my_strcasecmp(system_charset_info, sub_el->partition_name,
name_to_check)) && sub_el != element)
@@ -323,7 +323,7 @@ char *partition_info::has_unique_names()
List_iterator<partition_element> parts_it(partitions);
partition_element *el;
- while (el= (parts_it++))
+ while ((el= (parts_it++)))
{
if (! has_unique_name(el))
DBUG_RETURN(el->partition_name);
@@ -332,7 +332,7 @@ char *partition_info::has_unique_names()
{
List_iterator<partition_element> subparts_it(el->subpartitions);
partition_element *subel;
- while (subel= (subparts_it++))
+ while ((subel= (subparts_it++)))
{
if (! has_unique_name(subel))
DBUG_RETURN(subel->partition_name);
diff --git a/sql/set_var.cc b/sql/set_var.cc
index 12f3a61aa4e..7ff3401b102 100644
--- a/sql/set_var.cc
+++ b/sql/set_var.cc
@@ -141,6 +141,7 @@ static int check_log_update(THD *thd, set_var *var);
static bool set_log_update(THD *thd, set_var *var);
static int check_pseudo_thread_id(THD *thd, set_var *var);
static bool set_log_bin(THD *thd, set_var *var);
+void fix_binlog_format_after_update(THD *thd, enum_var_type type);
static void fix_low_priority_updates(THD *thd, enum_var_type type);
static int check_tx_isolation(THD *thd, set_var *var);
static void fix_tx_isolation(THD *thd, enum_var_type type);
@@ -185,6 +186,8 @@ sys_var_bool_ptr sys_automatic_sp_privileges("automatic_sp_privileges",
sys_var_long_ptr sys_binlog_cache_size("binlog_cache_size",
&binlog_cache_size);
+sys_var_thd_binlog_format sys_binlog_format("binlog_format",
+ &SV::binlog_format);
sys_var_thd_ulong sys_bulk_insert_buff_size("bulk_insert_buffer_size",
&SV::bulk_insert_buff_size);
sys_var_character_set_server sys_character_set_server("character_set_server");
@@ -653,11 +656,11 @@ static int show_slave_skip_errors(THD *thd, SHOW_VAR *var, char *buff)
var->value= buff;
if (!use_slave_mask || bitmap_is_clear_all(&slave_error_mask))
{
- var->value= "OFF";
+ var->value= const_cast<char *>("OFF");
}
else if (bitmap_is_set_all(&slave_error_mask))
{
- var->value= "ALL";
+ var->value= const_cast<char *>("ALL");
}
else
{
@@ -706,7 +709,7 @@ SHOW_VAR init_vars[]= {
{"bdb_shared_data", (char*) &berkeley_shared_data, SHOW_BOOL},
{"bdb_tmpdir", (char*) &berkeley_tmpdir, SHOW_CHAR_PTR},
{sys_binlog_cache_size.name,(char*) &sys_binlog_cache_size, SHOW_SYS},
- {"binlog_format", (char*) &opt_binlog_format, SHOW_CHAR_PTR},
+ {sys_binlog_format.name, (char*) &sys_binlog_format, SHOW_SYS},
{sys_bulk_insert_buff_size.name,(char*) &sys_bulk_insert_buff_size,SHOW_SYS},
{sys_character_set_client.name,(char*) &sys_character_set_client, SHOW_SYS},
{sys_character_set_connection.name,(char*) &sys_character_set_connection,SHOW_SYS},
@@ -1243,6 +1246,54 @@ extern void fix_delay_key_write(THD *thd, enum_var_type type)
}
}
+
+bool sys_var_thd_binlog_format::is_readonly() const
+{
+ /*
+ Under certain circumstances, the variable is read-only (unchangeable):
+ */
+ THD *thd= current_thd;
+ /*
+ If RBR and open temporary tables, their CREATE TABLE may not be in the
+ binlog, so we can't toggle to SBR in this connection.
+ The test below will also prevent SET GLOBAL, well it was not easy to test
+ if global or not here.
+ And this test will also prevent switching from RBR to RBR (a no-op which
+ should not happen too often).
+ */
+ if ((thd->variables.binlog_format == BINLOG_FORMAT_ROW) &&
+ thd->temporary_tables)
+ {
+ my_error(ER_TEMP_TABLE_PREVENTS_SWITCH_OUT_OF_RBR, MYF(0));
+ return 1;
+ }
+ /*
+ if in a stored function, it's too late to change mode
+ */
+ if (thd->spcont && thd->prelocked_mode)
+ {
+ DBUG_ASSERT(thd->variables.binlog_format != BINLOG_FORMAT_ROW);
+ my_error(ER_STORED_FUNCTION_PREVENTS_SWITCH_BINLOG_FORMAT, MYF(0));
+ return 1;
+ }
+#ifdef HAVE_NDB_BINLOG
+ /*
+ Cluster does not support changing the binlog format on the fly yet.
+ */
+ if (opt_bin_log && (have_ndbcluster == SHOW_OPTION_YES))
+ {
+ my_error(ER_NDB_CANT_SWITCH_BINLOG_FORMAT, MYF(0));
+ return 1;
+ }
+#endif
+ return sys_var_thd_enum::is_readonly();
+}
+
+void fix_binlog_format_after_update(THD *thd, enum_var_type type)
+{
+ thd->reset_current_stmt_binlog_row_based();
+}
+
static void fix_max_binlog_size(THD *thd, enum_var_type type)
{
DBUG_ENTER("fix_max_binlog_size");
diff --git a/sql/set_var.h b/sql/set_var.h
index 0961f6d4325..f62d6ce8d2a 100644
--- a/sql/set_var.h
+++ b/sql/set_var.h
@@ -826,6 +826,18 @@ public:
bool update(THD *thd, set_var *var);
};
+extern void fix_binlog_format_after_update(THD *thd, enum_var_type type);
+
+class sys_var_thd_binlog_format :public sys_var_thd_enum
+{
+public:
+ sys_var_thd_binlog_format(const char *name_arg, ulong SV::*offset_arg)
+ :sys_var_thd_enum(name_arg, offset_arg,
+ &binlog_format_typelib,
+ fix_binlog_format_after_update)
+ {};
+ bool is_readonly() const;
+};
/****************************************************************************
Classes for parsing of the SET command
diff --git a/sql/share/errmsg.txt b/sql/share/errmsg.txt
index e1bea5009ff..376f4b7da7a 100644
--- a/sql/share/errmsg.txt
+++ b/sql/share/errmsg.txt
@@ -5812,8 +5812,12 @@ ER_CANT_CHANGE_TX_ISOLATION 25001
eng "Transaction isolation level can't be changed while a transaction is in progress"
ER_WARN_DEPRECATED_STATEMENT
eng "The '%s' statement is deprecated and will be removed in MySQL %s. Please use client programs (e.g. %s) instead."
-
-ER_TABLE_NEEDS_UPGRADE
- eng "Table upgrade required. Please do \"REPAIR TABLE `%-.32s`\" to fix it!"
ER_SP_NO_AGGREGATE 42000
eng "AGGREGATE is not supported for stored functions"
+ER_TEMP_TABLE_PREVENTS_SWITCH_OUT_OF_RBR
+ eng "Cannot switch out of the row-based binary log format when the session has open temporary tables"
+ER_STORED_FUNCTION_PREVENTS_SWITCH_BINLOG_FORMAT
+ eng "Cannot change the binary logging format inside a stored function or trigger"
+ER_NDB_CANT_SWITCH_BINLOG_FORMAT
+ eng "The NDB cluster engine does not support changing the binlog format on the fly yet"
+
diff --git a/sql/sp_head.cc b/sql/sp_head.cc
index 1f29468a61f..22311322322 100644
--- a/sql/sp_head.cc
+++ b/sql/sp_head.cc
@@ -1301,7 +1301,7 @@ sp_head::execute_function(THD *thd, Item **argp, uint argcount,
each substatement be binlogged its way.
*/
need_binlog_call= mysql_bin_log.is_open() &&
- (thd->options & OPTION_BIN_LOG) && !binlog_row_based;
+ (thd->options & OPTION_BIN_LOG) && !thd->current_stmt_binlog_row_based;
if (need_binlog_call)
{
reset_dynamic(&thd->user_var_events);
diff --git a/sql/sql_base.cc b/sql/sql_base.cc
index c4cb7ddbc4a..e519c976aa4 100644
--- a/sql/sql_base.cc
+++ b/sql/sql_base.cc
@@ -1189,7 +1189,7 @@ void close_temporary_tables(THD *thd)
close_temporary(table, 1, 1);
}
if (query && found_user_tables && mysql_bin_log.is_open() &&
- !binlog_row_based) // CREATE TEMP TABLE not binlogged if row-based
+ !thd->current_stmt_binlog_row_based) // CREATE TEMP TABLE not binlogged if row-based
{
/* The -1 is to remove last ',' */
thd->clear_error();
diff --git a/sql/sql_class.cc b/sql/sql_class.cc
index e68bcb9e281..4da71593b83 100644
--- a/sql/sql_class.cc
+++ b/sql/sql_class.cc
@@ -329,6 +329,7 @@ void THD::init(void)
bzero((char*) warn_count, sizeof(warn_count));
total_warn_count= 0;
update_charset();
+ reset_current_stmt_binlog_row_based();
bzero((char *) &status_var, sizeof(status_var));
}
@@ -2026,12 +2027,12 @@ void THD::reset_sub_statement_state(Sub_statement_state *backup,
INSERT INTO t1 VALUES (1), (foo()), (2);
*/
- if (binlog_row_based)
+ if (current_stmt_binlog_row_based)
binlog_flush_pending_rows_event(false);
#endif /* HAVE_ROW_BASED_REPLICATION */
if ((!lex->requires_prelocking() || is_update_query(lex->sql_command)) &&
- !binlog_row_based)
+ !current_stmt_binlog_row_based)
options&= ~OPTION_BIN_LOG;
/* Disable result sets */
client_capabilities &= ~CLIENT_MULTI_RESULTS;
@@ -2394,7 +2395,7 @@ int THD::binlog_write_row(TABLE* table, bool is_trans,
MY_BITMAP const* cols, my_size_t colcnt,
byte const *record)
{
- DBUG_ASSERT(binlog_row_based && mysql_bin_log.is_open());
+ DBUG_ASSERT(current_stmt_binlog_row_based && mysql_bin_log.is_open());
/*
Pack records into format for transfer. We are allocating more
@@ -2441,7 +2442,7 @@ int THD::binlog_update_row(TABLE* table, bool is_trans,
const byte *before_record,
const byte *after_record)
{
- DBUG_ASSERT(binlog_row_based && mysql_bin_log.is_open());
+ DBUG_ASSERT(current_stmt_binlog_row_based && mysql_bin_log.is_open());
bool error= 0;
my_size_t const before_maxlen = max_row_length(table, before_record);
@@ -2489,7 +2490,7 @@ int THD::binlog_delete_row(TABLE* table, bool is_trans,
MY_BITMAP const* cols, my_size_t colcnt,
byte const *record)
{
- DBUG_ASSERT(binlog_row_based && mysql_bin_log.is_open());
+ DBUG_ASSERT(current_stmt_binlog_row_based && mysql_bin_log.is_open());
/*
Pack records into format for transfer. We are allocating more
@@ -2520,7 +2521,7 @@ int THD::binlog_delete_row(TABLE* table, bool is_trans,
int THD::binlog_flush_pending_rows_event(bool stmt_end)
{
DBUG_ENTER("THD::binlog_flush_pending_rows_event");
- if (!binlog_row_based || !mysql_bin_log.is_open())
+ if (!current_stmt_binlog_row_based || !mysql_bin_log.is_open())
DBUG_RETURN(0);
/*
@@ -2561,8 +2562,8 @@ void THD::binlog_delete_pending_rows_event()
/*
Member function that will log query, either row-based or
- statement-based depending on the value of the 'binlog_row_based'
- variable and the value of the 'qtype' flag.
+ statement-based depending on the value of the 'current_stmt_binlog_row_based'
+ the value of the 'qtype' flag.
This function should be called after the all calls to ha_*_row()
functions have been issued, but before tables are unlocked and
@@ -2586,11 +2587,11 @@ int THD::binlog_query(THD::enum_binlog_query_type qtype,
moving back and forth between using RBR for replication of
system tables and not using it.
- Make sure to change in check_table_binlog_row_based() according
+ Make sure to change in check_table_current_stmt_binlog_row_based according
to how you treat this.
*/
case THD::ROW_QUERY_TYPE:
- if (binlog_row_based)
+ if (current_stmt_binlog_row_based)
DBUG_RETURN(binlog_flush_pending_rows_event(true));
/* Otherwise, we fall through */
case THD::STMT_QUERY_TYPE:
diff --git a/sql/sql_class.h b/sql/sql_class.h
index 00440449be8..e7fe8f448d7 100644
--- a/sql/sql_class.h
+++ b/sql/sql_class.h
@@ -248,13 +248,15 @@ struct system_variables
#endif /* HAVE_REPLICATION */
my_bool innodb_table_locks;
my_bool innodb_support_xa;
- ulong ndb_autoincrement_prefetch_sz;
my_bool ndb_force_send;
my_bool ndb_use_exact_count;
my_bool ndb_use_transactions;
my_bool ndb_index_stat_enable;
+ ulong ndb_autoincrement_prefetch_sz;
ulong ndb_index_stat_cache_entries;
ulong ndb_index_stat_update_freq;
+ ulong binlog_format; // binlog format for this thd (see enum_binlog_format)
+
my_bool old_alter_table;
my_bool old_passwords;
@@ -1123,6 +1125,8 @@ public:
char scramble[SCRAMBLE_LENGTH+1];
bool slave_thread, one_shot_set;
+ /* tells if current statement should binlog row-based(1) or stmt-based(0) */
+ bool current_stmt_binlog_row_based;
bool locked, some_tables_deleted;
bool last_cuted_field;
bool no_errors, password, is_fatal_error;
@@ -1377,6 +1381,15 @@ public:
void restore_sub_statement_state(Sub_statement_state *backup);
void set_n_backup_active_arena(Query_arena *set, Query_arena *backup);
void restore_active_arena(Query_arena *set, Query_arena *backup);
+ inline void set_current_stmt_binlog_row_based_if_mixed()
+ {
+ if (variables.binlog_format == BINLOG_FORMAT_MIXED)
+ current_stmt_binlog_row_based= 1;
+ }
+ inline void reset_current_stmt_binlog_row_based()
+ {
+ current_stmt_binlog_row_based= test(variables.binlog_format == BINLOG_FORMAT_ROW);
+ }
};
diff --git a/sql/sql_delete.cc b/sql/sql_delete.cc
index c9cb1ccd5c2..34947e35b17 100644
--- a/sql/sql_delete.cc
+++ b/sql/sql_delete.cc
@@ -962,7 +962,7 @@ end:
{
/*
TRUNCATE must always be statement-based binlogged (not row-based) so
- we don't test binlog_row_based.
+ we don't test current_stmt_binlog_row_based.
*/
thd->clear_error();
thd->binlog_query(THD::STMT_QUERY_TYPE,
diff --git a/sql/sql_insert.cc b/sql/sql_insert.cc
index 6655491ca57..bd7be110b88 100644
--- a/sql/sql_insert.cc
+++ b/sql/sql_insert.cc
@@ -2411,7 +2411,7 @@ void select_insert::send_error(uint errcode,const char *err)
thd->binlog_query(THD::ROW_QUERY_TYPE, thd->query, thd->query_length,
table->file->has_transactions(), FALSE);
}
- if (!binlog_row_based && !table->s->tmp_table)
+ if (!thd->current_stmt_binlog_row_based && !table->s->tmp_table)
thd->options|=OPTION_STATUS_NO_TRANS_UPDATE;
}
if (info.copied || info.deleted || info.updated)
@@ -2556,7 +2556,7 @@ select_create::binlog_show_create_table()
on rollback, we clear the OPTION_STATUS_NO_TRANS_UPDATE bit of
thd->options.
*/
- DBUG_ASSERT(binlog_row_based && !create_table_written);
+ DBUG_ASSERT(thd->current_stmt_binlog_row_based && !create_table_written);
thd->options&= ~OPTION_STATUS_NO_TRANS_UPDATE;
char buf[2048];
@@ -2582,7 +2582,7 @@ void select_create::store_values(List<Item> &values)
Before writing the first row, we write the CREATE TABLE statement
to the binlog.
*/
- if (binlog_row_based && !create_table_written)
+ if (thd->current_stmt_binlog_row_based && !create_table_written)
{
binlog_show_create_table();
create_table_written= TRUE;
@@ -2611,7 +2611,7 @@ bool select_create::send_eof()
If no rows where written to the binary log, we write the CREATE
TABLE statement to the binlog.
*/
- if (binlog_row_based && !create_table_written)
+ if (thd->current_stmt_binlog_row_based && !create_table_written)
{
binlog_show_create_table();
create_table_written= TRUE;
diff --git a/sql/sql_load.cc b/sql/sql_load.cc
index 1d6442ba7d6..e816b792005 100644
--- a/sql/sql_load.cc
+++ b/sql/sql_load.cc
@@ -426,7 +426,7 @@ bool mysql_load(THD *thd,sql_exchange *ex,TABLE_LIST *table_list,
version for the binary log to mark that table maps are invalid
after this point.
*/
- if (binlog_row_based)
+ if (thd->current_stmt_binlog_row_based)
thd->binlog_flush_pending_rows_event(true);
else
#endif
@@ -491,7 +491,7 @@ bool mysql_load(THD *thd,sql_exchange *ex,TABLE_LIST *table_list,
version for the binary log to mark that table maps are invalid
after this point.
*/
- if (binlog_row_based)
+ if (thd->current_stmt_binlog_row_based)
thd->binlog_flush_pending_rows_event(true);
else
#endif
@@ -948,7 +948,8 @@ READ_INFO::READ_INFO(File file_par, uint tot_length, CHARSET_INFO *cs,
if (get_it_from_net)
cache.read_function = _my_b_net_read;
- if (!binlog_row_based && mysql_bin_log.is_open())
+ if (((LOAD_FILE_INFO*)cache.arg)->thd->current_stmt_binlog_row_based &&
+ mysql_bin_log.is_open())
cache.pre_read = cache.pre_close =
(IO_CACHE_CALLBACK) log_loaded_block;
#endif
diff --git a/sql/sql_parse.cc b/sql/sql_parse.cc
index b84eb1cfcb8..f779f6e8c21 100644
--- a/sql/sql_parse.cc
+++ b/sql/sql_parse.cc
@@ -4990,6 +4990,7 @@ end_with_restore_list:
*/
if (thd->one_shot_set && lex->sql_command != SQLCOM_SET_OPTION)
reset_one_shot_variables(thd);
+ thd->reset_current_stmt_binlog_row_based();
/*
The return value for ROW_COUNT() is "implementation dependent" if the
diff --git a/sql/sql_partition.cc b/sql/sql_partition.cc
index 7f4518c2b85..e6b26223752 100644
--- a/sql/sql_partition.cc
+++ b/sql/sql_partition.cc
@@ -697,7 +697,7 @@ bool check_partition_info(partition_info *part_info,handlerton **eng_type,
my_error(ER_TOO_MANY_PARTITIONS_ERROR, MYF(0));
goto end;
}
- if (same_name= part_info->has_unique_names())
+ if ((same_name= part_info->has_unique_names()))
{
my_error(ER_SAME_NAME_PARTITION, MYF(0), same_name);
goto end;
diff --git a/sql/sql_show.cc b/sql/sql_show.cc
index b8ab46f21cb..66cc0db6ac7 100644
--- a/sql/sql_show.cc
+++ b/sql/sql_show.cc
@@ -1654,7 +1654,7 @@ static int show_var_cmp(const void *var1, const void *var2)
*/
static void shrink_var_array(DYNAMIC_ARRAY *array)
{
- int a,b;
+ uint a,b;
SHOW_VAR *all= dynamic_element(array, 0, SHOW_VAR *);
for (a= b= 0; b < array->elements; b++)
diff --git a/sql/sql_table.cc b/sql/sql_table.cc
index 2737e9448f9..861d7ffeb8f 100644
--- a/sql/sql_table.cc
+++ b/sql/sql_table.cc
@@ -565,7 +565,7 @@ int mysql_rm_table_part2(THD *thd, TABLE_LIST *tables, bool if_exists,
String built_query;
DBUG_ENTER("mysql_rm_table_part2");
- if (binlog_row_based && !dont_log_query)
+ if (thd->current_stmt_binlog_row_based && !dont_log_query)
{
built_query.set_charset(system_charset_info);
if (if_exists)
@@ -612,7 +612,7 @@ int mysql_rm_table_part2(THD *thd, TABLE_LIST *tables, bool if_exists,
being built. The string always end in a comma and the comma
will be chopped off before being written to the binary log.
*/
- if (binlog_row_based && !dont_log_query)
+ if (thd->current_stmt_binlog_row_based && !dont_log_query)
{
++non_temp_tables_count;
/*
@@ -722,7 +722,7 @@ int mysql_rm_table_part2(THD *thd, TABLE_LIST *tables, bool if_exists,
query_cache_invalidate3(thd, tables, 0);
if (!dont_log_query)
{
- if (!binlog_row_based ||
+ if (!thd->current_stmt_binlog_row_based ||
non_temp_tables_count > 0 && !tmp_table_deleted)
{
/*
@@ -734,7 +734,7 @@ int mysql_rm_table_part2(THD *thd, TABLE_LIST *tables, bool if_exists,
*/
write_bin_log(thd, !error, thd->query, thd->query_length);
}
- else if (binlog_row_based &&
+ else if (thd->current_stmt_binlog_row_based &&
non_temp_tables_count > 0 &&
tmp_table_deleted)
{
@@ -2248,8 +2248,8 @@ bool mysql_create_table_internal(THD *thd,
Otherwise, the statement shall be binlogged.
*/
if (!internal_tmp_table &&
- (!binlog_row_based ||
- (binlog_row_based &&
+ (!thd->current_stmt_binlog_row_based ||
+ (thd->current_stmt_binlog_row_based &&
!(create_info->options & HA_LEX_CREATE_TMP_TABLE))))
write_bin_log(thd, TRUE, thd->query, thd->query_length);
error= FALSE;
@@ -3475,7 +3475,7 @@ bool mysql_create_like_table(THD* thd, TABLE_LIST* table,
/*
We have to write the query before we unlock the tables.
*/
- if (binlog_row_based)
+ if (thd->current_stmt_binlog_row_based)
{
/*
Since temporary tables are not replicated under row-based
@@ -4861,7 +4861,7 @@ bool mysql_alter_table(THD *thd,char *new_db, char *new_name,
goto err;
}
/* We don't replicate alter table statement on temporary tables */
- if (!binlog_row_based)
+ if (!thd->current_stmt_binlog_row_based)
write_bin_log(thd, TRUE, thd->query, thd->query_length);
goto end_temporary;
}
@@ -5031,7 +5031,7 @@ bool mysql_alter_table(THD *thd,char *new_db, char *new_name,
thd->query, thd->query_length,
db, table_name);
- DBUG_ASSERT(!(mysql_bin_log.is_open() && binlog_row_based &&
+ DBUG_ASSERT(!(mysql_bin_log.is_open() && thd->current_stmt_binlog_row_based &&
(create_info->options & HA_LEX_CREATE_TMP_TABLE)));
write_bin_log(thd, TRUE, thd->query, thd->query_length);
/*