mirror of
https://github.com/MariaDB/server.git
synced 2025-09-02 09:41:40 +03:00
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
This commit is contained in:
18
mysql-test/suite/pbxt/r/pbxt_xa.result
Normal file
18
mysql-test/suite/pbxt/r/pbxt_xa.result
Normal file
@@ -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;
|
23
mysql-test/suite/pbxt/t/pbxt_xa.test
Normal file
23
mysql-test/suite/pbxt/t/pbxt_xa.test
Normal file
@@ -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;
|
||||||
|
|
12
sql/log.cc
12
sql/log.cc
@@ -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()
|
|||||||
/* 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;
|
||||||
}
|
}
|
||||||
|
Reference in New Issue
Block a user