summaryrefslogtreecommitdiff
path: root/sql
diff options
context:
space:
mode:
authorunknown <guilhem@mysql.com>2006-02-25 22:21:03 +0100
committerunknown <guilhem@mysql.com>2006-02-25 22:21:03 +0100
commit7cac0ddfd01a6cdb4a8779fe1fb2edf10c1dc751 (patch)
treed3a16d5f3b8f1c0bd0941caf3ae057efca391ea7 /sql
parent5e02bec9ceefe1889db8b0dfc04e90d0b34a690f (diff)
downloadmariadb-git-7cac0ddfd01a6cdb4a8779fe1fb2edf10c1dc751.tar.gz
WL#2977 and WL#2712 global and session-level variable to set the binlog format (row/statement),
and new binlog format called "mixed" (which is statement-based except if only row-based is correct, in this cset it means if UDF or UUID is used; more cases could be added in later 5.1 release): SET GLOBAL|SESSION BINLOG_FORMAT=row|statement|mixed|default; the global default is statement unless cluster is enabled (then it's row) as in 5.1-alpha. It's not possible to use SET on this variable if a session is currently in row-based mode and has open temporary tables (because CREATE TEMPORARY TABLE was not binlogged so temp table is not known on slave), or if NDB is enabled (because NDB does not support such change on-the-fly, though it will later), of if in a stored function (see below). The added tests test the possibility or impossibility to SET, their effects, and the mixed mode, including in prepared statements and in stored procedures and functions. Caveats: a) The mixed mode will not work for stored functions: in mixed mode, a stored function will always be binlogged as one call and in a statement-based way (e.g. INSERT VALUES(myfunc()) or SELECT myfunc()). b) for the same reason, changing the thread's binlog format inside a stored function is refused with an error message. c) the same problems apply to triggers; implementing b) for triggers will be done later (will ask Dmitri). Additionally, as the binlog format is now changeable by each user for his session, I remove the implication which was done at startup, where row-based automatically set log-bin-trust-routine-creators to 1 (not possible anymore as a user can now switch to stmt-based and do nasty things again), and automatically set --innodb-locks-unsafe-for-binlog to 1 (was anyway theoretically incorrect as it disabled phantom protection). Plus fixes for compiler warnings. mysql-test/r/rpl_row_4_bytes.result: update mysql-test/t/rpl_row_4_bytes.test: don't influence next tests sql/ha_archive.cc: please pay attention to this structure when you change it... sql/ha_berkeley.cc: please pay attention to this structure when you change it... sql/ha_blackhole.cc: please pay attention to this structure when you change it... sql/ha_federated.cc: please pay attention to this structure when you change it... sql/ha_heap.cc: please pay attention to this structure when you change it... sql/ha_innodb.cc: please pay attention to this structure when you change it... sql/ha_myisam.cc: please pay attention to this structure when you change it... sql/ha_myisammrg.cc: please pay attention to this structure when you change it... sql/ha_ndbcluster_binlog.cc: no more global 'binlog_row_based' sql/ha_partition.cc: please pay attention to this structure when you change it... sql/handler.cc: please pay attention to this structure when you change it... sql/handler.h: it's good to initialize statically (to get no compiler warning) even if to a null value. sql/item_func.cc: UDFs require row-based if this is the "mixed" binlog format. sql/item_strfunc.cc: UUID() requires row-based binlogging if this is the "mixed" binlog format sql/log.cc: binlog_row_based -> thd->current_stmt_binlog_row_based sql/log.h: the enum enum_binlog_format moves to log.h from mysqld.cc as we need it in several places. sql/log_event.cc: binlog_row_based -> thd->current_stmt_binlog_row_based sql/log_event.h: this global variable not used anymore sql/mysql_priv.h: these global variables not used anymore sql/mysqld.cc: simplification in the handling of --binlog-format (but with no user-visible change), thanks to the new global system variable. RBR does not anymore turn on --log-bin-trust-function-creators and --innodb-locks-unsafe-for-binlog as these are global options and RBR is now settable per session. sql/partition_info.cc: compiler warnings sql/set_var.cc: new class of thread's variable, to handle the binlog_format (like sys_var_thd_enum except that is_readonly() is overriden for more checks before update). compiler warnings (ok'd by Serg) sql/set_var.h: new class for the thread's binlog_format (see set_var.cc) sql/share/errmsg.txt: some messages for when one can't toggle from one binlog format to another sql/sp_head.cc: binlog_row_based -> thd->current_stmt_binlog_row_based sql/sql_base.cc: binlog_row_based -> thd->current_stmt_binlog_row_based sql/sql_class.cc: When a THD is initialized, we set its current_stmt_binlog_row_based sql/sql_class.h: new THD::variables.binlog_format (the value of the session variable set by SET or inherited from the global value), and THD::current_stmt_binlog_row_based which tells if the current statement does row-based or statement-based binlogging. Both members are needed as the 2nd one cannot be derived only from the first one (the statement's type plays a role too), and the 1st one is needed to reset the 2nd one. sql/sql_delete.cc: binlog_row_based -> thd->current_stmt_binlog_row_based sql/sql_insert.cc: binlog_row_based -> thd->current_stmt_binlog_row_based sql/sql_load.cc: binlog_row_based -> thd->current_stmt_binlog_row_based. sql/sql_parse.cc: when we are done with a statement, we reset the current_stmt_binlog_row_based to the value derived from THD::variables.binlog_format. sql/sql_partition.cc: compiler warning sql/sql_show.cc: compiler warning sql/sql_table.cc: binlog_row_based -> thd->current_stmt_binlog_row_based tests/mysql_client_test.c: compiler warning mysql-test/r/ndb_binlog_basic2.result: new result mysql-test/r/rpl_switch_stm_row_mixed.result: new result mysql-test/t/ndb_binlog_basic2.test: new test to verify that if cluster is enabled, can't change binlog format on the fly. mysql-test/t/rpl_switch_stm_row_mixed.test: test to see if one can switch between SBR, RBR, and "mixed" mode, and when one cannot, and test to see if the switching, and the mixed mode, work properly (using UUID() to test, as using UDFs is not possible in the testsuite for portability reasons).
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);
/*