Skip to content

Commit da88c90

Browse files
authored andcommitted
Auto Merge fix for bug#50157
2 parents 2af3bac + 8558957 commit da88c90

File tree

5 files changed

+335
-48
lines changed

5 files changed

+335
-48
lines changed

mysql-test/suite/rpl/r/rpl_semi_sync.result

Lines changed: 25 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -120,8 +120,27 @@ min(a)
120120
select max(a) from t1;
121121
max(a)
122122
300
123+
124+
# BUG#50157
125+
# semi-sync replication crashes when replicating a transaction which
126+
# include 'CREATE TEMPORARY TABLE `MyISAM_t` SELECT * FROM `Innodb_t` ;
127+
[ on master ]
128+
SET SESSION AUTOCOMMIT= 0;
129+
CREATE TABLE t2(c1 INT) ENGINE=innodb;
130+
BEGIN;
131+
132+
# Even though it is in a transaction, this statement is binlogged into binlog
133+
# file immediately.
134+
CREATE TEMPORARY TABLE t3 SELECT c1 FROM t2 where 1=1;
135+
136+
# These statements will not be binlogged until the transaction is committed
137+
INSERT INTO t2 VALUES(11);
138+
INSERT INTO t2 VALUES(22);
139+
COMMIT;
140+
DROP TABLE t2, t3;
141+
SET SESSION AUTOCOMMIT= 1;
123142
#
124-
# Test semi-sync master will switch OFF after one transacton
143+
# Test semi-sync master will switch OFF after one transaction
125144
# timeout waiting for slave reply.
126145
#
127146
include/stop_slave.inc
@@ -135,7 +154,7 @@ Variable_name Value
135154
Rpl_semi_sync_master_no_tx 0
136155
show status like 'Rpl_semi_sync_master_yes_tx';
137156
Variable_name Value
138-
Rpl_semi_sync_master_yes_tx 301
157+
Rpl_semi_sync_master_yes_tx 304
139158
show status like 'Rpl_semi_sync_master_clients';
140159
Variable_name Value
141160
Rpl_semi_sync_master_clients 1
@@ -150,7 +169,7 @@ Variable_name Value
150169
Rpl_semi_sync_master_no_tx 1
151170
show status like 'Rpl_semi_sync_master_yes_tx';
152171
Variable_name Value
153-
Rpl_semi_sync_master_yes_tx 301
172+
Rpl_semi_sync_master_yes_tx 304
154173
insert into t1 values (100);
155174
[ master status should be OFF ]
156175
show status like 'Rpl_semi_sync_master_status';
@@ -161,7 +180,7 @@ Variable_name Value
161180
Rpl_semi_sync_master_no_tx 302
162181
show status like 'Rpl_semi_sync_master_yes_tx';
163182
Variable_name Value
164-
Rpl_semi_sync_master_yes_tx 301
183+
Rpl_semi_sync_master_yes_tx 304
165184
#
166185
# Test semi-sync status on master will be ON again when slave catches up
167186
#
@@ -194,7 +213,7 @@ Variable_name Value
194213
Rpl_semi_sync_master_no_tx 302
195214
show status like 'Rpl_semi_sync_master_yes_tx';
196215
Variable_name Value
197-
Rpl_semi_sync_master_yes_tx 301
216+
Rpl_semi_sync_master_yes_tx 304
198217
show status like 'Rpl_semi_sync_master_clients';
199218
Variable_name Value
200219
Rpl_semi_sync_master_clients 1
@@ -213,7 +232,7 @@ Variable_name Value
213232
Rpl_semi_sync_master_no_tx 302
214233
SHOW STATUS LIKE 'Rpl_semi_sync_master_yes_tx';
215234
Variable_name Value
216-
Rpl_semi_sync_master_yes_tx 302
235+
Rpl_semi_sync_master_yes_tx 305
217236
FLUSH NO_WRITE_TO_BINLOG STATUS;
218237
[ Semi-sync master status variables after FLUSH STATUS ]
219238
SHOW STATUS LIKE 'Rpl_semi_sync_master_no_tx';

mysql-test/suite/rpl/t/rpl_semi_sync.test

Lines changed: 32 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@ disable_query_log;
1111
connection master;
1212
call mtr.add_suppression("Timeout waiting for reply of binlog");
1313
call mtr.add_suppression("Read semi-sync reply");
14+
call mtr.add_suppression("Unsafe statement binlogged in statement format since BINLOG_FORMAT = STATEMENT.");
1415
connection slave;
1516
call mtr.add_suppression("Master server does not support semi-sync");
1617
call mtr.add_suppression("Semi-sync slave .* reply");
@@ -193,8 +194,38 @@ select count(distinct a) from t1;
193194
select min(a) from t1;
194195
select max(a) from t1;
195196

197+
--echo
198+
--echo # BUG#50157
199+
--echo # semi-sync replication crashes when replicating a transaction which
200+
--echo # include 'CREATE TEMPORARY TABLE `MyISAM_t` SELECT * FROM `Innodb_t` ;
201+
202+
connection master;
203+
echo [ on master ];
204+
SET SESSION AUTOCOMMIT= 0;
205+
CREATE TABLE t2(c1 INT) ENGINE=innodb;
206+
sync_slave_with_master;
207+
208+
connection master;
209+
BEGIN;
210+
--echo
211+
--echo # Even though it is in a transaction, this statement is binlogged into binlog
212+
--echo # file immediately.
213+
--disable_warnings
214+
CREATE TEMPORARY TABLE t3 SELECT c1 FROM t2 where 1=1;
215+
--enable_warnings
216+
--echo
217+
--echo # These statements will not be binlogged until the transaction is committed
218+
INSERT INTO t2 VALUES(11);
219+
INSERT INTO t2 VALUES(22);
220+
COMMIT;
221+
222+
DROP TABLE t2, t3;
223+
SET SESSION AUTOCOMMIT= 1;
224+
sync_slave_with_master;
225+
226+
196227
--echo #
197-
--echo # Test semi-sync master will switch OFF after one transacton
228+
--echo # Test semi-sync master will switch OFF after one transaction
198229
--echo # timeout waiting for slave reply.
199230
--echo #
200231
connection slave;

plugin/semisync/semisync_master.cc

Lines changed: 4 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -65,7 +65,7 @@ static int gettimeofday(struct timeval *tv, void *tz)
6565

6666
ActiveTranx::ActiveTranx(pthread_mutex_t *lock,
6767
unsigned long trace_level)
68-
: Trace(trace_level),
68+
: Trace(trace_level), allocator_(max_connections),
6969
num_entries_(max_connections << 1), /* Transaction hash table size
7070
* is set to double the size
7171
* of max_connections */
@@ -115,25 +115,6 @@ unsigned int ActiveTranx::get_hash_value(const char *log_file_name,
115115
return (hash1 + hash2) % num_entries_;
116116
}
117117

118-
ActiveTranx::TranxNode* ActiveTranx::alloc_tranx_node()
119-
{
120-
MYSQL_THD thd= (MYSQL_THD)current_thd;
121-
/* The memory allocated for TranxNode will be automatically freed at
122-
the end of the command of current THD. And because
123-
ha_autocommit_or_rollback() will always be called before that, so
124-
we are sure that the node will be removed from the active list
125-
before it get freed. */
126-
TranxNode *trx_node = (TranxNode *)thd_alloc(thd, sizeof(TranxNode));
127-
if (trx_node)
128-
{
129-
trx_node->log_name_[0] = '\0';
130-
trx_node->log_pos_= 0;
131-
trx_node->next_= 0;
132-
trx_node->hash_next_= 0;
133-
}
134-
return trx_node;
135-
}
136-
137118
int ActiveTranx::compare(const char *log_file_name1, my_off_t log_file_pos1,
138119
const char *log_file_name2, my_off_t log_file_pos2)
139120
{
@@ -159,7 +140,7 @@ int ActiveTranx::insert_tranx_node(const char *log_file_name,
159140

160141
function_enter(kWho);
161142

162-
ins_node = alloc_tranx_node();
143+
ins_node = allocator_.allocate_node();
163144
if (!ins_node)
164145
{
165146
sql_print_error("%s: transaction node allocation failed for: (%s, %lu)",
@@ -271,6 +252,7 @@ int ActiveTranx::clear_active_tranx_nodes(const char *log_file_name,
271252

272253
/* Clear the hash table. */
273254
memset(trx_htb_, 0, num_entries_ * sizeof(TranxNode *));
255+
allocator_.free_all_nodes();
274256

275257
/* Clear the active transaction list. */
276258
if (trx_front_ != NULL)
@@ -311,6 +293,7 @@ int ActiveTranx::clear_active_tranx_nodes(const char *log_file_name,
311293
}
312294

313295
trx_front_ = new_front;
296+
allocator_.free_nodes_before(trx_front_);
314297

315298
if (trace_level_ & kTraceDetail)
316299
sql_print_information("%s: cleared %d nodes back until pos (%s, %lu)",

0 commit comments

Comments
 (0)