summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--mysql-test/suite/galera/r/galera_wsrep_xid.result14
-rw-r--r--mysql-test/suite/galera/t/galera_wsrep_xid.test33
-rw-r--r--storage/innobase/include/trx0rseg.h11
-rw-r--r--storage/innobase/trx/trx0rseg.cc55
4 files changed, 92 insertions, 21 deletions
diff --git a/mysql-test/suite/galera/r/galera_wsrep_xid.result b/mysql-test/suite/galera/r/galera_wsrep_xid.result
new file mode 100644
index 00000000000..683ef362f6a
--- /dev/null
+++ b/mysql-test/suite/galera/r/galera_wsrep_xid.result
@@ -0,0 +1,14 @@
+CREATE TABLE t1 (f1 INT PRIMARY KEY) ENGINE=InnoDB;
+INSERT INTO t1 VALUES (1);
+connection node_2;
+SELECT * FROM t1;
+f1
+1
+SET SESSION wsrep_on=0;
+INSERT INTO t1 VALUES (2);
+DELETE FROM t1 WHERE f1 = 2;
+connection node_1;
+INSERT INTO t1 VALUES (2);
+connection node_2;
+connection node_1;
+DROP TABLE t1;
diff --git a/mysql-test/suite/galera/t/galera_wsrep_xid.test b/mysql-test/suite/galera/t/galera_wsrep_xid.test
new file mode 100644
index 00000000000..bbf582aa96c
--- /dev/null
+++ b/mysql-test/suite/galera/t/galera_wsrep_xid.test
@@ -0,0 +1,33 @@
+--source include/have_innodb.inc
+--source include/galera_cluster.inc
+
+# Initialize table on node_1
+CREATE TABLE t1 (f1 INT PRIMARY KEY) ENGINE=InnoDB;
+INSERT INTO t1 VALUES (1);
+
+# Go to node_2, verify that the previous INSERT completed.
+# Take node_2 out of the cluster, insert and delete a record
+# on a table with wsrep_on.
+--connection node_2
+SELECT * FROM t1;
+SET SESSION wsrep_on=0;
+INSERT INTO t1 VALUES (2);
+DELETE FROM t1 WHERE f1 = 2;
+
+# Shutdown node_2
+--source include/shutdown_mysqld.inc
+
+# On node_1, verify that the node has left the cluster.
+--connection node_1
+--let $wait_condition = SELECT VARIABLE_VALUE = 1 FROM INFORMATION_SCHEMA.GLOBAL_STATUS WHERE VARIABLE_NAME = 'wsrep_cluster_size';
+--source include/wait_condition.inc
+
+# Insert into t1 to enforce IST on node_2 when it is restarted.
+INSERT INTO t1 VALUES (2);
+
+# Restart node_2
+--connection node_2
+--source include/start_mysqld.inc
+
+--connection node_1
+DROP TABLE t1;
diff --git a/storage/innobase/include/trx0rseg.h b/storage/innobase/include/trx0rseg.h
index d68ece39911..f57b8e7fa06 100644
--- a/storage/innobase/include/trx0rseg.h
+++ b/storage/innobase/include/trx0rseg.h
@@ -245,15 +245,16 @@ If no binlog information is present, the first byte is NUL. */
#ifdef WITH_WSREP
/** The offset to WSREP XID headers */
#define TRX_RSEG_WSREP_XID_INFO TRX_RSEG_MAX_TRX_ID + 16 + 512
-
+/** Sequence number of WSREP XID. It is used to find latest WSREP XID info. */
+#define TRX_RSEG_WSREP_XID_SEQNO TRX_RSEG_WSREP_XID_INFO
/** WSREP XID format (1 if present and valid, 0 if not present) */
-#define TRX_RSEG_WSREP_XID_FORMAT TRX_RSEG_WSREP_XID_INFO
+#define TRX_RSEG_WSREP_XID_FORMAT TRX_RSEG_WSREP_XID_INFO + 8
/** WSREP XID GTRID length */
-#define TRX_RSEG_WSREP_XID_GTRID_LEN TRX_RSEG_WSREP_XID_INFO + 4
+#define TRX_RSEG_WSREP_XID_GTRID_LEN TRX_RSEG_WSREP_XID_INFO + 12
/** WSREP XID bqual length */
-#define TRX_RSEG_WSREP_XID_BQUAL_LEN TRX_RSEG_WSREP_XID_INFO + 8
+#define TRX_RSEG_WSREP_XID_BQUAL_LEN TRX_RSEG_WSREP_XID_INFO + 16
/** WSREP XID data (XIDDATASIZE bytes) */
-#define TRX_RSEG_WSREP_XID_DATA TRX_RSEG_WSREP_XID_INFO + 12
+#define TRX_RSEG_WSREP_XID_DATA TRX_RSEG_WSREP_XID_INFO + 20
#endif /* WITH_WSREP*/
/*-------------------------------------------------------------*/
diff --git a/storage/innobase/trx/trx0rseg.cc b/storage/innobase/trx/trx0rseg.cc
index b9ca2481681..9932977f37b 100644
--- a/storage/innobase/trx/trx0rseg.cc
+++ b/storage/innobase/trx/trx0rseg.cc
@@ -83,6 +83,9 @@ trx_rseg_update_wsrep_checkpoint(
trx_sys_cur_xid_seqno = xid_seqno;
#endif /* UNIV_DEBUG */
+ mlog_write_ull(TRX_RSEG_WSREP_XID_SEQNO + rseg_header,
+ trx_sys.get_max_trx_id(), mtr);
+
mlog_write_ulint(TRX_RSEG_WSREP_XID_FORMAT + rseg_header,
uint32_t(xid->formatID),
MLOG_4BYTES, mtr);
@@ -209,7 +212,7 @@ bool trx_rseg_read_wsrep_checkpoint(XID& xid)
}
trx_id_t id = mach_read_from_8(rseg_header
- + TRX_RSEG_MAX_TRX_ID);
+ + TRX_RSEG_WSREP_XID_SEQNO);
if (id < max_id) {
continue;
@@ -398,44 +401,60 @@ trx_undo_lists_init(trx_rseg_t* rseg, trx_id_t& max_trx_id,
}
/** Restore the state of a persistent rollback segment.
-@param[in,out] rseg persistent rollback segment
-@param[in,out] max_trx_id maximum observed transaction identifier
-@param[in,out] max_rseg_trx_id maximum observed TRX_RSEG_MAX_TRX_ID
+@param[in,out] rseg persistent rollback segment
+@param[in,out] max_trx_id maximum observed transaction identifier
+@param[in,out] max_rseg_xid_seqno maximum observed sequence number for
+ WSREP XID info
@param[in,out] mtr mini-transaction */
static
void
trx_rseg_mem_restore(
trx_rseg_t* rseg,
trx_id_t& max_trx_id,
- trx_id_t& max_rseg_trx_id,
+#ifdef WITH_WSREP
+ trx_id_t& max_rseg_xid_seqno,
+#endif
mtr_t* mtr)
{
trx_rsegf_t* rseg_header = trx_rsegf_get_new(
rseg->space, rseg->page_no, mtr);
+ lint binlog_offset;
if (mach_read_from_4(rseg_header + TRX_RSEG_FORMAT) == 0) {
trx_id_t id = mach_read_from_8(rseg_header
+ TRX_RSEG_MAX_TRX_ID);
-
+#ifdef WITH_WSREP
+ trx_id_t xid_seqno = mach_read_from_8(rseg_header
+ + TRX_RSEG_WSREP_XID_SEQNO);
+#endif /* WITH_WSRSEP */
if (id > max_trx_id) {
max_trx_id = id;
}
- if (id > max_rseg_trx_id) {
- max_rseg_trx_id = id;
+ if (rseg_header[TRX_RSEG_BINLOG_NAME]) {
+
+ binlog_offset = mach_read_from_8(
+ rseg_header + TRX_RSEG_BINLOG_OFFSET);
+
+ if (strncmp((char*) rseg_header + TRX_RSEG_BINLOG_NAME,
+ trx_sys.recovered_binlog_filename,
+ TRX_RSEG_BINLOG_NAME_LEN) >= 0
+ && (trx_sys.recovered_binlog_offset
+ < binlog_offset)) {
- if (rseg_header[TRX_RSEG_BINLOG_NAME]) {
memcpy(trx_sys.recovered_binlog_filename,
rseg_header + TRX_RSEG_BINLOG_NAME,
TRX_RSEG_BINLOG_NAME_LEN);
- trx_sys.recovered_binlog_offset = mach_read_from_8(
- rseg_header
- + TRX_RSEG_BINLOG_OFFSET);
+ trx_sys.recovered_binlog_offset =
+ binlog_offset;
}
#ifdef WITH_WSREP
- trx_rseg_read_wsrep_checkpoint(
- rseg_header, trx_sys.recovered_wsrep_xid);
+ if (xid_seqno > max_rseg_xid_seqno) {
+ max_rseg_xid_seqno = xid_seqno;
+ trx_rseg_read_wsrep_checkpoint(
+ rseg_header, trx_sys.recovered_wsrep_xid);
+ }
#endif
}
}
@@ -513,11 +532,12 @@ static void trx_rseg_init_binlog_info(const page_t* page)
void
trx_rseg_array_init()
{
- trx_id_t max_trx_id = 0, max_rseg_trx_id = 0;
+ trx_id_t max_trx_id = 0;
*trx_sys.recovered_binlog_filename = '\0';
trx_sys.recovered_binlog_offset = -1;
#ifdef WITH_WSREP
+ trx_id_t max_rseg_xid_seqno = 0;
memset(&trx_sys.recovered_wsrep_xid, 0,
sizeof trx_sys.recovered_wsrep_xid);
trx_sys.recovered_wsrep_xid.formatID = -1;
@@ -549,7 +569,10 @@ trx_rseg_array_init()
ut_ad(!trx_sys.rseg_array[rseg_id]);
trx_sys.rseg_array[rseg_id] = rseg;
trx_rseg_mem_restore(
- rseg, max_trx_id, max_rseg_trx_id,
+ rseg, max_trx_id,
+#ifdef WITH_WSREP
+ max_rseg_xid_seqno,
+#endif
&mtr);
}
}