Bug #29222 Statement mode replicates both statement and rows when writing to an NDB table

- only log statements locally (changes will not be logged on other servers)
parent f7a1a076
drop table if exists t1, t2, t3;
CREATE TABLE t1 (m INT, n INT) ENGINE=MYISAM;
CREATE TABLE t2 (b INT, c INT) ENGINE=BLACKHOLE;
CREATE TABLE t3 (e INT, f INT) ENGINE=NDB;
RESET MASTER;
SET SESSION BINLOG_FORMAT=STATEMENT;
INSERT INTO t1 VALUES (1,1), (1,2), (2,1), (2,2);
INSERT INTO t2 VALUES (1,1), (1,2), (2,1), (2,2);
UPDATE t1, t2 SET m = 2, b = 3 WHERE n = c;
START TRANSACTION;
INSERT INTO t3 VALUES (1,1), (1,2), (2,1), (2,2);
UPDATE t1, t3 SET m = 2, e = 3 WHERE n = f;
UPDATE t3, t2 SET e = 2, b = 3 WHERE f = c;
COMMIT;
show binlog events from <binlog_start>;
Log_name Pos Event_type Server_id End_log_pos Info
master-bin.000001 # Query # # use `test`; INSERT INTO t1 VALUES (1,1), (1,2), (2,1), (2,2)
master-bin.000001 # Query # # use `test`; INSERT INTO t2 VALUES (1,1), (1,2), (2,1), (2,2)
master-bin.000001 # Query # # use `test`; UPDATE t1, t2 SET m = 2, b = 3 WHERE n = c
master-bin.000001 # Query # # use `test`; BEGIN
master-bin.000001 # Query # # use `test`; INSERT INTO t3 VALUES (1,1), (1,2), (2,1), (2,2)
master-bin.000001 # Query # # use `test`; UPDATE t1, t3 SET m = 2, e = 3 WHERE n = f
master-bin.000001 # Query # # use `test`; UPDATE t3, t2 SET e = 2, b = 3 WHERE f = c
master-bin.000001 # Query # # use `test`; COMMIT
master-bin.000001 # Query # # BEGIN
master-bin.000001 # Table_map # # table_id: # (test.t3)
master-bin.000001 # Table_map # # table_id: # (mysql.ndb_apply_status)
master-bin.000001 # Write_rows # # table_id: # flags: STMT_END_F
master-bin.000001 # Query # # COMMIT
DROP TABLE t1, t2, t3;
#
# test different behavior of ndb using different binlog formats
#
-- source include/have_ndb.inc
-- source include/have_log_bin.inc
--disable_warnings
drop table if exists t1, t2, t3;
--enable_warnings
#
# Bug #29222 Statement mode replicates both statement and
# rows when writing to an NDB table
#
CREATE TABLE t1 (m INT, n INT) ENGINE=MYISAM;
CREATE TABLE t2 (b INT, c INT) ENGINE=BLACKHOLE;
CREATE TABLE t3 (e INT, f INT) ENGINE=NDB;
RESET MASTER;
SET SESSION BINLOG_FORMAT=STATEMENT;
INSERT INTO t1 VALUES (1,1), (1,2), (2,1), (2,2);
INSERT INTO t2 VALUES (1,1), (1,2), (2,1), (2,2);
UPDATE t1, t2 SET m = 2, b = 3 WHERE n = c;
# A transaction here is not necessary, but I wanted to group the bad statements
START TRANSACTION;
INSERT INTO t3 VALUES (1,1), (1,2), (2,1), (2,2);
UPDATE t1, t3 SET m = 2, e = 3 WHERE n = f;
UPDATE t3, t2 SET e = 2, b = 3 WHERE f = c;
COMMIT;
--source include/show_binlog_events.inc
DROP TABLE t1, t2, t3;
......@@ -2812,7 +2812,8 @@ int ha_ndbcluster::write_row(uchar *record)
if (unlikely(m_slow_path))
{
if (!(thd->options & OPTION_BIN_LOG))
Thd_ndb *thd_ndb= get_thd_ndb(thd);
if (thd_ndb->trans_options & TNTO_NO_LOGGING)
op->setAnyValue(NDB_ANYVALUE_FOR_NOLOGGING);
else if (thd->slave_thread)
op->setAnyValue(thd->server_id);
......@@ -3101,7 +3102,8 @@ int ha_ndbcluster::update_row(const uchar *old_data, uchar *new_data)
if (unlikely(m_slow_path))
{
if (!(thd->options & OPTION_BIN_LOG))
Thd_ndb *thd_ndb= get_thd_ndb(thd);
if (thd_ndb->trans_options & TNTO_NO_LOGGING)
op->setAnyValue(NDB_ANYVALUE_FOR_NOLOGGING);
else if (thd->slave_thread)
op->setAnyValue(thd->server_id);
......@@ -3168,7 +3170,8 @@ int ha_ndbcluster::delete_row(const uchar *record)
if (unlikely(m_slow_path))
{
if (!(thd->options & OPTION_BIN_LOG))
Thd_ndb *thd_ndb= get_thd_ndb(thd);
if (thd_ndb->trans_options & TNTO_NO_LOGGING)
((NdbOperation *)trans->getLastDefinedOperation())->
setAnyValue(NDB_ANYVALUE_FOR_NOLOGGING);
else if (thd->slave_thread)
......@@ -3207,7 +3210,8 @@ int ha_ndbcluster::delete_row(const uchar *record)
if (unlikely(m_slow_path))
{
if (!(thd->options & OPTION_BIN_LOG))
Thd_ndb *thd_ndb= get_thd_ndb(thd);
if (thd_ndb->trans_options & TNTO_NO_LOGGING)
op->setAnyValue(NDB_ANYVALUE_FOR_NOLOGGING);
else if (thd->slave_thread)
op->setAnyValue(thd->server_id);
......@@ -4385,8 +4389,13 @@ int ha_ndbcluster::external_lock(THD *thd, int lock_type)
thd_ndb->query_state&= NDB_QUERY_NORMAL;
thd_ndb->trans_options= 0;
thd_ndb->m_slow_path= FALSE;
if (thd->slave_thread ||
!(thd->options & OPTION_BIN_LOG))
if (!(thd->options & OPTION_BIN_LOG) ||
thd->variables.binlog_format == BINLOG_FORMAT_STMT)
{
thd_ndb->trans_options|= TNTO_NO_LOGGING;
thd_ndb->m_slow_path= TRUE;
}
else if (thd->slave_thread)
thd_ndb->m_slow_path= TRUE;
trans_register_ha(thd, FALSE, ndbcluster_hton);
}
......@@ -4406,8 +4415,13 @@ int ha_ndbcluster::external_lock(THD *thd, int lock_type)
thd_ndb->query_state&= NDB_QUERY_NORMAL;
thd_ndb->trans_options= 0;
thd_ndb->m_slow_path= FALSE;
if (thd->slave_thread ||
!(thd->options & OPTION_BIN_LOG))
if (!(thd->options & OPTION_BIN_LOG) ||
thd->variables.binlog_format == BINLOG_FORMAT_STMT)
{
thd_ndb->trans_options|= TNTO_NO_LOGGING;
thd_ndb->m_slow_path= TRUE;
}
else if (thd->slave_thread)
thd_ndb->m_slow_path= TRUE;
trans_register_ha(thd, TRUE, ndbcluster_hton);
......
......@@ -178,6 +178,7 @@ enum THD_NDB_OPTIONS
enum THD_NDB_TRANS_OPTIONS
{
TNTO_INJECTED_APPLY_STATUS= 1 << 0
,TNTO_NO_LOGGING= 1 << 1
};
struct Ndb_local_table_statistics {
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment