diff options
author | Sergei Golubchik <sergii@pisem.net> | 2010-03-24 23:12:39 +0100 |
---|---|---|
committer | Sergei Golubchik <sergii@pisem.net> | 2010-03-24 23:12:39 +0100 |
commit | 1fbf8458f8fdabf25e42e0d9c2c3eb0b345b152c (patch) | |
tree | 16b54ffebc238c567e4481122a877e627f23d585 | |
parent | 71b3e46b0160936596195682a731703900fb4fff (diff) | |
download | mariadb-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.result | 18 | ||||
-rw-r--r-- | mysql-test/suite/pbxt/t/pbxt_xa.test | 23 | ||||
-rw-r--r-- | sql/log.cc | 12 |
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; } |