summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSergei Golubchik <sergii@pisem.net>2010-03-24 23:12:39 +0100
committerSergei Golubchik <sergii@pisem.net>2010-03-24 23:12:39 +0100
commit1fbf8458f8fdabf25e42e0d9c2c3eb0b345b152c (patch)
tree16b54ffebc238c567e4481122a877e627f23d585
parent71b3e46b0160936596195682a731703900fb4fff (diff)
downloadmariadb-git-1fbf8458f8fdabf25e42e0d9c2c3eb0b345b152c.tar.gz
two crashes in the TC_LOG_MMAP:
1. don't forget to initialize page->ptr 2. don't signal active->cond, if active is NULL
-rw-r--r--mysql-test/suite/pbxt/r/pbxt_xa.result18
-rw-r--r--mysql-test/suite/pbxt/t/pbxt_xa.test23
-rw-r--r--sql/log.cc12
3 files changed, 51 insertions, 2 deletions
diff --git a/mysql-test/suite/pbxt/r/pbxt_xa.result b/mysql-test/suite/pbxt/r/pbxt_xa.result
new file mode 100644
index 00000000000..8bcab926998
--- /dev/null
+++ b/mysql-test/suite/pbxt/r/pbxt_xa.result
@@ -0,0 +1,18 @@
+drop table if exists t1, t2;
+CREATE TABLE t1 (a INT PRIMARY KEY) ENGINE=innodb;
+CREATE TABLE t2 (b INT PRIMARY KEY) ENGINE=pbxt;
+BEGIN;
+SELECT @@log_bin;
+@@log_bin
+0
+INSERT INTO t1 VALUES (1);
+INSERT INTO t2 VALUES (2);
+COMMIT;
+select * from t1;
+a
+1
+select * from t2;
+b
+2
+drop table t1, t2;
+drop database pbxt;
diff --git a/mysql-test/suite/pbxt/t/pbxt_xa.test b/mysql-test/suite/pbxt/t/pbxt_xa.test
new file mode 100644
index 00000000000..a9d1c5c38e8
--- /dev/null
+++ b/mysql-test/suite/pbxt/t/pbxt_xa.test
@@ -0,0 +1,23 @@
+-- source include/have_innodb.inc
+
+--disable_warnings
+drop table if exists t1, t2;
+--enable_warnings
+
+#
+# bug lp:544173, xa crash with two 2pc-capable storage engines without binlog
+#
+
+CREATE TABLE t1 (a INT PRIMARY KEY) ENGINE=innodb;
+CREATE TABLE t2 (b INT PRIMARY KEY) ENGINE=pbxt;
+BEGIN;
+# verify that binlog is off
+SELECT @@log_bin;
+INSERT INTO t1 VALUES (1);
+INSERT INTO t2 VALUES (2);
+COMMIT;
+select * from t1;
+select * from t2;
+drop table t1, t2;
+drop database pbxt;
+
diff --git a/sql/log.cc b/sql/log.cc
index 95b38f7ccd7..6d0314b1d19 100644
--- a/sql/log.cc
+++ b/sql/log.cc
@@ -5387,7 +5387,7 @@ int TC_LOG_MMAP::open(const char *opt_name)
pg->state=POOL;
pthread_mutex_init(&pg->lock, MY_MUTEX_INIT_FAST);
pthread_cond_init (&pg->cond, 0);
- pg->start=(my_xid *)(data + i*tc_log_page_size);
+ pg->ptr= pg->start=(my_xid *)(data + i*tc_log_page_size);
pg->size=pg->free=tc_log_page_size/sizeof(my_xid);
pg->end=pg->start + pg->size;
}
@@ -5622,7 +5622,15 @@ int TC_LOG_MMAP::sync()
/* marking 'syncing' slot free */
pthread_mutex_lock(&LOCK_sync);
syncing=0;
- pthread_cond_signal(&active->cond); // wake up a new syncer
+ /*
+ we check the "active" pointer without LOCK_active. Still, it's safe -
+ "active" can change from NULL to not NULL any time, but it
+ will take LOCK_sync before waiting on active->cond. That is, it can never
+ miss a signal.
+ And "active" can change to NULL only after LOCK_sync, so this is safe too.
+ */
+ if (active)
+ pthread_cond_signal(&active->cond); // wake up a new syncer
pthread_mutex_unlock(&LOCK_sync);
return err;
}