Commit cbb1e6f1 authored by Sergei Golubchik's avatar Sergei Golubchik

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
parent d7c0ca65
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;
-- 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;
...@@ -5387,7 +5387,7 @@ int TC_LOG_MMAP::open(const char *opt_name) ...@@ -5387,7 +5387,7 @@ int TC_LOG_MMAP::open(const char *opt_name)
pg->state=POOL; pg->state=POOL;
pthread_mutex_init(&pg->lock, MY_MUTEX_INIT_FAST); pthread_mutex_init(&pg->lock, MY_MUTEX_INIT_FAST);
pthread_cond_init (&pg->cond, 0); 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->size=pg->free=tc_log_page_size/sizeof(my_xid);
pg->end=pg->start + pg->size; pg->end=pg->start + pg->size;
} }
...@@ -5622,7 +5622,15 @@ int TC_LOG_MMAP::sync() ...@@ -5622,7 +5622,15 @@ int TC_LOG_MMAP::sync()
/* marking 'syncing' slot free */ /* marking 'syncing' slot free */
pthread_mutex_lock(&LOCK_sync); pthread_mutex_lock(&LOCK_sync);
syncing=0; 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); pthread_mutex_unlock(&LOCK_sync);
return err; return err;
} }
......
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