Merge mysql-5.1-innodb -> mysql-5.1
This commit is contained in:
commit
bc7bf937c5
@ -4461,13 +4461,14 @@ static int my_kill(int pid, int sig)
|
|||||||
command called command
|
command called command
|
||||||
|
|
||||||
DESCRIPTION
|
DESCRIPTION
|
||||||
shutdown [<timeout>]
|
shutdown_server [<timeout>]
|
||||||
|
|
||||||
*/
|
*/
|
||||||
|
|
||||||
void do_shutdown_server(struct st_command *command)
|
void do_shutdown_server(struct st_command *command)
|
||||||
{
|
{
|
||||||
int timeout=60, pid;
|
long timeout=60;
|
||||||
|
int pid;
|
||||||
DYNAMIC_STRING ds_pidfile_name;
|
DYNAMIC_STRING ds_pidfile_name;
|
||||||
MYSQL* mysql = &cur_con->mysql;
|
MYSQL* mysql = &cur_con->mysql;
|
||||||
static DYNAMIC_STRING ds_timeout;
|
static DYNAMIC_STRING ds_timeout;
|
||||||
@ -4482,8 +4483,9 @@ void do_shutdown_server(struct st_command *command)
|
|||||||
|
|
||||||
if (ds_timeout.length)
|
if (ds_timeout.length)
|
||||||
{
|
{
|
||||||
timeout= atoi(ds_timeout.str);
|
char* endptr;
|
||||||
if (timeout == 0)
|
timeout= strtol(ds_timeout.str, &endptr, 10);
|
||||||
|
if (*endptr != '\0')
|
||||||
die("Illegal argument for timeout: '%s'", ds_timeout.str);
|
die("Illegal argument for timeout: '%s'", ds_timeout.str);
|
||||||
}
|
}
|
||||||
dynstr_free(&ds_timeout);
|
dynstr_free(&ds_timeout);
|
||||||
@ -4525,7 +4527,7 @@ void do_shutdown_server(struct st_command *command)
|
|||||||
DBUG_PRINT("info", ("Process %d does not exist anymore", pid));
|
DBUG_PRINT("info", ("Process %d does not exist anymore", pid));
|
||||||
DBUG_VOID_RETURN;
|
DBUG_VOID_RETURN;
|
||||||
}
|
}
|
||||||
DBUG_PRINT("info", ("Sleeping, timeout: %d", timeout));
|
DBUG_PRINT("info", ("Sleeping, timeout: %ld", timeout));
|
||||||
my_sleep(1000000L);
|
my_sleep(1000000L);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -7,7 +7,7 @@ let $counter= 500;
|
|||||||
let $mysql_errno= 0;
|
let $mysql_errno= 0;
|
||||||
while (!$mysql_errno)
|
while (!$mysql_errno)
|
||||||
{
|
{
|
||||||
--error 0,1053,2002,2006,2013
|
--error 0,1040,1053,2002,2003,2006,2013
|
||||||
show status;
|
show status;
|
||||||
|
|
||||||
dec $counter;
|
dec $counter;
|
||||||
|
17
mysql-test/suite/innodb/r/innodb_bug59410.result
Normal file
17
mysql-test/suite/innodb/r/innodb_bug59410.result
Normal file
@ -0,0 +1,17 @@
|
|||||||
|
create table `bug59410_1`(`a` int)engine=innodb;
|
||||||
|
insert into `bug59410_1` values (1),(2),(3);
|
||||||
|
select 1 from `bug59410_1` where `a` <> any (
|
||||||
|
select 1 from `bug59410_1` where `a` <> 1 for update)
|
||||||
|
for update;
|
||||||
|
1
|
||||||
|
1
|
||||||
|
1
|
||||||
|
drop table bug59410_1;
|
||||||
|
create table bug59410_2(`a` char(1),`b` int)engine=innodb;
|
||||||
|
insert into bug59410_2 values('0',0);
|
||||||
|
set transaction isolation level read uncommitted;
|
||||||
|
start transaction;
|
||||||
|
set @a=(select b from bug59410_2 where
|
||||||
|
(select 1 from bug59410_2 where a group by @a=b)
|
||||||
|
group by @a:=b);
|
||||||
|
drop table bug59410_2;
|
57
mysql-test/suite/innodb/r/innodb_bug59641.result
Normal file
57
mysql-test/suite/innodb/r/innodb_bug59641.result
Normal file
@ -0,0 +1,57 @@
|
|||||||
|
CREATE TABLE t(a INT PRIMARY KEY, b INT)ENGINE=InnoDB;
|
||||||
|
INSERT INTO t VALUES(2,2),(4,4),(8,8),(16,16),(32,32);
|
||||||
|
COMMIT;
|
||||||
|
XA START '123';
|
||||||
|
INSERT INTO t VALUES(1,1);
|
||||||
|
XA END '123';
|
||||||
|
XA PREPARE '123';
|
||||||
|
XA START '456';
|
||||||
|
INSERT INTO t VALUES(3,47),(5,67);
|
||||||
|
UPDATE t SET b=2*b WHERE a BETWEEN 5 AND 8;
|
||||||
|
XA END '456';
|
||||||
|
XA PREPARE '456';
|
||||||
|
XA START '789';
|
||||||
|
UPDATE t SET b=4*a WHERE a=32;
|
||||||
|
XA END '789';
|
||||||
|
XA PREPARE '789';
|
||||||
|
call mtr.add_suppression("Found 3 prepared XA transactions");
|
||||||
|
SET TRANSACTION ISOLATION LEVEL READ UNCOMMITTED;
|
||||||
|
SELECT * FROM t;
|
||||||
|
a b
|
||||||
|
1 1
|
||||||
|
2 2
|
||||||
|
3 47
|
||||||
|
4 4
|
||||||
|
5 134
|
||||||
|
8 16
|
||||||
|
16 16
|
||||||
|
32 128
|
||||||
|
COMMIT;
|
||||||
|
SET TRANSACTION ISOLATION LEVEL READ UNCOMMITTED;
|
||||||
|
SELECT * FROM t;
|
||||||
|
a b
|
||||||
|
1 1
|
||||||
|
2 2
|
||||||
|
3 47
|
||||||
|
4 4
|
||||||
|
5 134
|
||||||
|
8 16
|
||||||
|
16 16
|
||||||
|
32 128
|
||||||
|
COMMIT;
|
||||||
|
XA RECOVER;
|
||||||
|
formatID gtrid_length bqual_length data
|
||||||
|
1 3 0 789
|
||||||
|
1 3 0 456
|
||||||
|
1 3 0 123
|
||||||
|
XA ROLLBACK '123';
|
||||||
|
XA ROLLBACK '456';
|
||||||
|
XA COMMIT '789';
|
||||||
|
SELECT * FROM t;
|
||||||
|
a b
|
||||||
|
2 2
|
||||||
|
4 4
|
||||||
|
8 8
|
||||||
|
16 16
|
||||||
|
32 128
|
||||||
|
DROP TABLE t;
|
24
mysql-test/suite/innodb/t/innodb_bug59410.test
Normal file
24
mysql-test/suite/innodb/t/innodb_bug59410.test
Normal file
@ -0,0 +1,24 @@
|
|||||||
|
#
|
||||||
|
# Bug#59410 read uncommitted: unlock row could not find a 3 mode lock on the record
|
||||||
|
#
|
||||||
|
-- source include/have_innodb.inc
|
||||||
|
|
||||||
|
# only interested that the following do not produce something like
|
||||||
|
# InnoDB: Error: unlock row could not find a 2 mode lock on the record
|
||||||
|
# in the error log
|
||||||
|
|
||||||
|
create table `bug59410_1`(`a` int)engine=innodb;
|
||||||
|
insert into `bug59410_1` values (1),(2),(3);
|
||||||
|
select 1 from `bug59410_1` where `a` <> any (
|
||||||
|
select 1 from `bug59410_1` where `a` <> 1 for update)
|
||||||
|
for update;
|
||||||
|
drop table bug59410_1;
|
||||||
|
|
||||||
|
create table bug59410_2(`a` char(1),`b` int)engine=innodb;
|
||||||
|
insert into bug59410_2 values('0',0);
|
||||||
|
set transaction isolation level read uncommitted;
|
||||||
|
start transaction;
|
||||||
|
set @a=(select b from bug59410_2 where
|
||||||
|
(select 1 from bug59410_2 where a group by @a=b)
|
||||||
|
group by @a:=b);
|
||||||
|
drop table bug59410_2;
|
66
mysql-test/suite/innodb/t/innodb_bug59641.test
Normal file
66
mysql-test/suite/innodb/t/innodb_bug59641.test
Normal file
@ -0,0 +1,66 @@
|
|||||||
|
# Bug #59641 Prepared XA transaction causes shutdown hang after a crash
|
||||||
|
|
||||||
|
-- source include/not_embedded.inc
|
||||||
|
-- source include/have_innodb.inc
|
||||||
|
|
||||||
|
CREATE TABLE t(a INT PRIMARY KEY, b INT)ENGINE=InnoDB;
|
||||||
|
INSERT INTO t VALUES(2,2),(4,4),(8,8),(16,16),(32,32);
|
||||||
|
COMMIT;
|
||||||
|
XA START '123';
|
||||||
|
INSERT INTO t VALUES(1,1);
|
||||||
|
XA END '123';
|
||||||
|
XA PREPARE '123';
|
||||||
|
|
||||||
|
CONNECT (con1,localhost,root,,);
|
||||||
|
CONNECTION con1;
|
||||||
|
|
||||||
|
XA START '456';
|
||||||
|
INSERT INTO t VALUES(3,47),(5,67);
|
||||||
|
UPDATE t SET b=2*b WHERE a BETWEEN 5 AND 8;
|
||||||
|
XA END '456';
|
||||||
|
XA PREPARE '456';
|
||||||
|
|
||||||
|
CONNECT (con2,localhost,root,,);
|
||||||
|
CONNECTION con2;
|
||||||
|
|
||||||
|
XA START '789';
|
||||||
|
UPDATE t SET b=4*a WHERE a=32;
|
||||||
|
XA END '789';
|
||||||
|
XA PREPARE '789';
|
||||||
|
|
||||||
|
# The server would issue this warning on restart.
|
||||||
|
call mtr.add_suppression("Found 3 prepared XA transactions");
|
||||||
|
|
||||||
|
# Kill the server without sending a shutdown command
|
||||||
|
-- exec echo "wait" > $MYSQLTEST_VARDIR/tmp/mysqld.1.expect
|
||||||
|
-- shutdown_server 0
|
||||||
|
-- source include/wait_until_disconnected.inc
|
||||||
|
|
||||||
|
# Restart the server.
|
||||||
|
-- exec echo "restart" > $MYSQLTEST_VARDIR/tmp/mysqld.1.expect
|
||||||
|
-- enable_reconnect
|
||||||
|
-- source include/wait_until_connected_again.inc
|
||||||
|
SET TRANSACTION ISOLATION LEVEL READ UNCOMMITTED;
|
||||||
|
SELECT * FROM t;
|
||||||
|
COMMIT;
|
||||||
|
|
||||||
|
# Shut down the server. This would hang because of the bug.
|
||||||
|
-- exec echo "wait" > $MYSQLTEST_VARDIR/tmp/mysqld.1.expect
|
||||||
|
-- shutdown_server
|
||||||
|
-- source include/wait_until_disconnected.inc
|
||||||
|
|
||||||
|
# Restart the server.
|
||||||
|
-- exec echo "restart" > $MYSQLTEST_VARDIR/tmp/mysqld.1.expect
|
||||||
|
-- enable_reconnect
|
||||||
|
-- source include/wait_until_connected_again.inc
|
||||||
|
|
||||||
|
SET TRANSACTION ISOLATION LEVEL READ UNCOMMITTED;
|
||||||
|
SELECT * FROM t;
|
||||||
|
COMMIT;
|
||||||
|
XA RECOVER;
|
||||||
|
XA ROLLBACK '123';
|
||||||
|
XA ROLLBACK '456';
|
||||||
|
XA COMMIT '789';
|
||||||
|
SELECT * FROM t;
|
||||||
|
|
||||||
|
DROP TABLE t;
|
17
mysql-test/suite/innodb_plugin/r/innodb_bug59410.result
Normal file
17
mysql-test/suite/innodb_plugin/r/innodb_bug59410.result
Normal file
@ -0,0 +1,17 @@
|
|||||||
|
create table `bug59410_1`(`a` int)engine=innodb;
|
||||||
|
insert into `bug59410_1` values (1),(2),(3);
|
||||||
|
select 1 from `bug59410_1` where `a` <> any (
|
||||||
|
select 1 from `bug59410_1` where `a` <> 1 for update)
|
||||||
|
for update;
|
||||||
|
1
|
||||||
|
1
|
||||||
|
1
|
||||||
|
drop table bug59410_1;
|
||||||
|
create table bug59410_2(`a` char(1),`b` int)engine=innodb;
|
||||||
|
insert into bug59410_2 values('0',0);
|
||||||
|
set transaction isolation level read uncommitted;
|
||||||
|
start transaction;
|
||||||
|
set @a=(select b from bug59410_2 where
|
||||||
|
(select 1 from bug59410_2 where a group by @a=b)
|
||||||
|
group by @a:=b);
|
||||||
|
drop table bug59410_2;
|
57
mysql-test/suite/innodb_plugin/r/innodb_bug59641.result
Normal file
57
mysql-test/suite/innodb_plugin/r/innodb_bug59641.result
Normal file
@ -0,0 +1,57 @@
|
|||||||
|
CREATE TABLE t(a INT PRIMARY KEY, b INT)ENGINE=InnoDB;
|
||||||
|
INSERT INTO t VALUES(2,2),(4,4),(8,8),(16,16),(32,32);
|
||||||
|
COMMIT;
|
||||||
|
XA START '123';
|
||||||
|
INSERT INTO t VALUES(1,1);
|
||||||
|
XA END '123';
|
||||||
|
XA PREPARE '123';
|
||||||
|
XA START '456';
|
||||||
|
INSERT INTO t VALUES(3,47),(5,67);
|
||||||
|
UPDATE t SET b=2*b WHERE a BETWEEN 5 AND 8;
|
||||||
|
XA END '456';
|
||||||
|
XA PREPARE '456';
|
||||||
|
XA START '789';
|
||||||
|
UPDATE t SET b=4*a WHERE a=32;
|
||||||
|
XA END '789';
|
||||||
|
XA PREPARE '789';
|
||||||
|
call mtr.add_suppression("Found 3 prepared XA transactions");
|
||||||
|
SET TRANSACTION ISOLATION LEVEL READ UNCOMMITTED;
|
||||||
|
SELECT * FROM t;
|
||||||
|
a b
|
||||||
|
1 1
|
||||||
|
2 2
|
||||||
|
3 47
|
||||||
|
4 4
|
||||||
|
5 134
|
||||||
|
8 16
|
||||||
|
16 16
|
||||||
|
32 128
|
||||||
|
COMMIT;
|
||||||
|
SET TRANSACTION ISOLATION LEVEL READ UNCOMMITTED;
|
||||||
|
SELECT * FROM t;
|
||||||
|
a b
|
||||||
|
1 1
|
||||||
|
2 2
|
||||||
|
3 47
|
||||||
|
4 4
|
||||||
|
5 134
|
||||||
|
8 16
|
||||||
|
16 16
|
||||||
|
32 128
|
||||||
|
COMMIT;
|
||||||
|
XA RECOVER;
|
||||||
|
formatID gtrid_length bqual_length data
|
||||||
|
1 3 0 789
|
||||||
|
1 3 0 456
|
||||||
|
1 3 0 123
|
||||||
|
XA ROLLBACK '123';
|
||||||
|
XA ROLLBACK '456';
|
||||||
|
XA COMMIT '789';
|
||||||
|
SELECT * FROM t;
|
||||||
|
a b
|
||||||
|
2 2
|
||||||
|
4 4
|
||||||
|
8 8
|
||||||
|
16 16
|
||||||
|
32 128
|
||||||
|
DROP TABLE t;
|
24
mysql-test/suite/innodb_plugin/t/innodb_bug59410.test
Normal file
24
mysql-test/suite/innodb_plugin/t/innodb_bug59410.test
Normal file
@ -0,0 +1,24 @@
|
|||||||
|
#
|
||||||
|
# Bug#59410 read uncommitted: unlock row could not find a 3 mode lock on the record
|
||||||
|
#
|
||||||
|
-- source include/have_innodb_plugin.inc
|
||||||
|
|
||||||
|
# only interested that the following do not produce something like
|
||||||
|
# InnoDB: Error: unlock row could not find a 2 mode lock on the record
|
||||||
|
# in the error log
|
||||||
|
|
||||||
|
create table `bug59410_1`(`a` int)engine=innodb;
|
||||||
|
insert into `bug59410_1` values (1),(2),(3);
|
||||||
|
select 1 from `bug59410_1` where `a` <> any (
|
||||||
|
select 1 from `bug59410_1` where `a` <> 1 for update)
|
||||||
|
for update;
|
||||||
|
drop table bug59410_1;
|
||||||
|
|
||||||
|
create table bug59410_2(`a` char(1),`b` int)engine=innodb;
|
||||||
|
insert into bug59410_2 values('0',0);
|
||||||
|
set transaction isolation level read uncommitted;
|
||||||
|
start transaction;
|
||||||
|
set @a=(select b from bug59410_2 where
|
||||||
|
(select 1 from bug59410_2 where a group by @a=b)
|
||||||
|
group by @a:=b);
|
||||||
|
drop table bug59410_2;
|
70
mysql-test/suite/innodb_plugin/t/innodb_bug59641.test
Normal file
70
mysql-test/suite/innodb_plugin/t/innodb_bug59641.test
Normal file
@ -0,0 +1,70 @@
|
|||||||
|
# Bug #59641 Prepared XA transaction causes shutdown hang after a crash
|
||||||
|
|
||||||
|
-- source include/not_embedded.inc
|
||||||
|
-- source include/have_innodb_plugin.inc
|
||||||
|
|
||||||
|
let $innodb_file_format_check_orig=`select @@innodb_file_format_check`;
|
||||||
|
|
||||||
|
CREATE TABLE t(a INT PRIMARY KEY, b INT)ENGINE=InnoDB;
|
||||||
|
INSERT INTO t VALUES(2,2),(4,4),(8,8),(16,16),(32,32);
|
||||||
|
COMMIT;
|
||||||
|
XA START '123';
|
||||||
|
INSERT INTO t VALUES(1,1);
|
||||||
|
XA END '123';
|
||||||
|
XA PREPARE '123';
|
||||||
|
|
||||||
|
CONNECT (con1,localhost,root,,);
|
||||||
|
CONNECTION con1;
|
||||||
|
|
||||||
|
XA START '456';
|
||||||
|
INSERT INTO t VALUES(3,47),(5,67);
|
||||||
|
UPDATE t SET b=2*b WHERE a BETWEEN 5 AND 8;
|
||||||
|
XA END '456';
|
||||||
|
XA PREPARE '456';
|
||||||
|
|
||||||
|
CONNECT (con2,localhost,root,,);
|
||||||
|
CONNECTION con2;
|
||||||
|
|
||||||
|
XA START '789';
|
||||||
|
UPDATE t SET b=4*a WHERE a=32;
|
||||||
|
XA END '789';
|
||||||
|
XA PREPARE '789';
|
||||||
|
|
||||||
|
# The server would issue this warning on restart.
|
||||||
|
call mtr.add_suppression("Found 3 prepared XA transactions");
|
||||||
|
|
||||||
|
# Kill the server without sending a shutdown command
|
||||||
|
-- exec echo "wait" > $MYSQLTEST_VARDIR/tmp/mysqld.1.expect
|
||||||
|
-- shutdown_server 0
|
||||||
|
-- source include/wait_until_disconnected.inc
|
||||||
|
|
||||||
|
# Restart the server.
|
||||||
|
-- exec echo "restart" > $MYSQLTEST_VARDIR/tmp/mysqld.1.expect
|
||||||
|
-- enable_reconnect
|
||||||
|
-- source include/wait_until_connected_again.inc
|
||||||
|
SET TRANSACTION ISOLATION LEVEL READ UNCOMMITTED;
|
||||||
|
SELECT * FROM t;
|
||||||
|
COMMIT;
|
||||||
|
|
||||||
|
# Shut down the server. This would hang because of the bug.
|
||||||
|
-- exec echo "wait" > $MYSQLTEST_VARDIR/tmp/mysqld.1.expect
|
||||||
|
-- shutdown_server
|
||||||
|
-- source include/wait_until_disconnected.inc
|
||||||
|
|
||||||
|
# Restart the server.
|
||||||
|
-- exec echo "restart" > $MYSQLTEST_VARDIR/tmp/mysqld.1.expect
|
||||||
|
-- enable_reconnect
|
||||||
|
-- source include/wait_until_connected_again.inc
|
||||||
|
|
||||||
|
SET TRANSACTION ISOLATION LEVEL READ UNCOMMITTED;
|
||||||
|
SELECT * FROM t;
|
||||||
|
COMMIT;
|
||||||
|
XA RECOVER;
|
||||||
|
XA ROLLBACK '123';
|
||||||
|
XA ROLLBACK '456';
|
||||||
|
XA COMMIT '789';
|
||||||
|
SELECT * FROM t;
|
||||||
|
|
||||||
|
DROP TABLE t;
|
||||||
|
--disable_query_log
|
||||||
|
eval set global innodb_file_format_check=$innodb_file_format_check_orig;
|
@ -3383,6 +3383,7 @@ bool xid_cache_insert(XID *xid, enum xa_states xa_state)
|
|||||||
xs->xa_state=xa_state;
|
xs->xa_state=xa_state;
|
||||||
xs->xid.set(xid);
|
xs->xid.set(xid);
|
||||||
xs->in_thd=0;
|
xs->in_thd=0;
|
||||||
|
xs->rm_error=0;
|
||||||
res=my_hash_insert(&xid_cache, (uchar*)xs);
|
res=my_hash_insert(&xid_cache, (uchar*)xs);
|
||||||
}
|
}
|
||||||
pthread_mutex_unlock(&LOCK_xid_cache);
|
pthread_mutex_unlock(&LOCK_xid_cache);
|
||||||
|
@ -189,7 +189,7 @@ innobase_index_name_is_reserved(
|
|||||||
/*============================*/
|
/*============================*/
|
||||||
/* out: true if index name matches a
|
/* out: true if index name matches a
|
||||||
reserved name */
|
reserved name */
|
||||||
const trx_t* trx, /* in: InnoDB transaction handle */
|
THD* thd, /* in/out: MySQL connection */
|
||||||
const TABLE* form, /* in: information on table
|
const TABLE* form, /* in: information on table
|
||||||
columns and indexes */
|
columns and indexes */
|
||||||
const char* norm_name); /* in: table name */
|
const char* norm_name); /* in: table name */
|
||||||
@ -5285,10 +5285,6 @@ create_table_def(
|
|||||||
DBUG_PRINT("enter", ("table_name: %s", table_name));
|
DBUG_PRINT("enter", ("table_name: %s", table_name));
|
||||||
|
|
||||||
ut_a(trx->mysql_thd != NULL);
|
ut_a(trx->mysql_thd != NULL);
|
||||||
if (IS_MAGIC_TABLE_AND_USER_DENIED_ACCESS(table_name,
|
|
||||||
(THD*) trx->mysql_thd)) {
|
|
||||||
DBUG_RETURN(HA_ERR_GENERIC);
|
|
||||||
}
|
|
||||||
|
|
||||||
n_cols = form->s->fields;
|
n_cols = form->s->fields;
|
||||||
|
|
||||||
@ -5397,6 +5393,8 @@ err_col:
|
|||||||
col_len);
|
col_len);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
srv_lower_case_table_names = lower_case_table_names;
|
||||||
|
|
||||||
error = row_create_table_for_mysql(table, trx);
|
error = row_create_table_for_mysql(table, trx);
|
||||||
|
|
||||||
innodb_check_for_record_too_big_error(flags & DICT_TF_COMPACT, error);
|
innodb_check_for_record_too_big_error(flags & DICT_TF_COMPACT, error);
|
||||||
@ -5642,6 +5640,35 @@ ha_innobase::create(
|
|||||||
DBUG_RETURN(HA_ERR_TO_BIG_ROW);
|
DBUG_RETURN(HA_ERR_TO_BIG_ROW);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
strcpy(name2, name);
|
||||||
|
|
||||||
|
normalize_table_name(norm_name, name2);
|
||||||
|
|
||||||
|
/* Create the table definition in InnoDB */
|
||||||
|
|
||||||
|
flags = form->s->row_type != ROW_TYPE_REDUNDANT ? DICT_TF_COMPACT : 0;
|
||||||
|
|
||||||
|
/* Look for a primary key */
|
||||||
|
|
||||||
|
primary_key_no= (form->s->primary_key != MAX_KEY ?
|
||||||
|
(int) form->s->primary_key :
|
||||||
|
-1);
|
||||||
|
|
||||||
|
/* Our function row_get_mysql_key_number_for_index assumes
|
||||||
|
the primary key is always number 0, if it exists */
|
||||||
|
|
||||||
|
DBUG_ASSERT(primary_key_no == -1 || primary_key_no == 0);
|
||||||
|
|
||||||
|
/* Check for name conflicts (with reserved name) for
|
||||||
|
any user indices to be created. */
|
||||||
|
if (innobase_index_name_is_reserved(thd, form, norm_name)) {
|
||||||
|
DBUG_RETURN(-1);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (IS_MAGIC_TABLE_AND_USER_DENIED_ACCESS(norm_name, thd)) {
|
||||||
|
DBUG_RETURN(HA_ERR_GENERIC);
|
||||||
|
}
|
||||||
|
|
||||||
/* Get the transaction associated with the current thd, or create one
|
/* Get the transaction associated with the current thd, or create one
|
||||||
if not yet created */
|
if not yet created */
|
||||||
|
|
||||||
@ -5665,48 +5692,12 @@ ha_innobase::create(
|
|||||||
trx->check_unique_secondary = FALSE;
|
trx->check_unique_secondary = FALSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (lower_case_table_names) {
|
|
||||||
srv_lower_case_table_names = TRUE;
|
|
||||||
} else {
|
|
||||||
srv_lower_case_table_names = FALSE;
|
|
||||||
}
|
|
||||||
|
|
||||||
strcpy(name2, name);
|
|
||||||
|
|
||||||
normalize_table_name(norm_name, name2);
|
|
||||||
|
|
||||||
/* Latch the InnoDB data dictionary exclusively so that no deadlocks
|
/* Latch the InnoDB data dictionary exclusively so that no deadlocks
|
||||||
or lock waits can happen in it during a table create operation.
|
or lock waits can happen in it during a table create operation.
|
||||||
Drop table etc. do this latching in row0mysql.c. */
|
Drop table etc. do this latching in row0mysql.c. */
|
||||||
|
|
||||||
row_mysql_lock_data_dictionary(trx);
|
row_mysql_lock_data_dictionary(trx);
|
||||||
|
|
||||||
/* Create the table definition in InnoDB */
|
|
||||||
|
|
||||||
flags = 0;
|
|
||||||
|
|
||||||
if (form->s->row_type != ROW_TYPE_REDUNDANT) {
|
|
||||||
flags |= DICT_TF_COMPACT;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Look for a primary key */
|
|
||||||
|
|
||||||
primary_key_no= (form->s->primary_key != MAX_KEY ?
|
|
||||||
(int) form->s->primary_key :
|
|
||||||
-1);
|
|
||||||
|
|
||||||
/* Our function row_get_mysql_key_number_for_index assumes
|
|
||||||
the primary key is always number 0, if it exists */
|
|
||||||
|
|
||||||
DBUG_ASSERT(primary_key_no == -1 || primary_key_no == 0);
|
|
||||||
|
|
||||||
/* Check for name conflicts (with reserved name) for
|
|
||||||
any user indices to be created. */
|
|
||||||
if (innobase_index_name_is_reserved(trx, form, norm_name)) {
|
|
||||||
error = -1;
|
|
||||||
goto cleanup;
|
|
||||||
}
|
|
||||||
|
|
||||||
error = create_table_def(trx, form, norm_name,
|
error = create_table_def(trx, form, norm_name,
|
||||||
create_info->options & HA_LEX_CREATE_TMP_TABLE ? name2 : NULL,
|
create_info->options & HA_LEX_CREATE_TMP_TABLE ? name2 : NULL,
|
||||||
flags);
|
flags);
|
||||||
@ -5936,12 +5927,6 @@ ha_innobase::delete_table(
|
|||||||
|
|
||||||
trx_search_latch_release_if_reserved(parent_trx);
|
trx_search_latch_release_if_reserved(parent_trx);
|
||||||
|
|
||||||
if (lower_case_table_names) {
|
|
||||||
srv_lower_case_table_names = TRUE;
|
|
||||||
} else {
|
|
||||||
srv_lower_case_table_names = FALSE;
|
|
||||||
}
|
|
||||||
|
|
||||||
trx = trx_allocate_for_mysql();
|
trx = trx_allocate_for_mysql();
|
||||||
|
|
||||||
trx->mysql_thd = thd;
|
trx->mysql_thd = thd;
|
||||||
@ -5961,6 +5946,8 @@ ha_innobase::delete_table(
|
|||||||
|
|
||||||
/* Drop the table in InnoDB */
|
/* Drop the table in InnoDB */
|
||||||
|
|
||||||
|
srv_lower_case_table_names = lower_case_table_names;
|
||||||
|
|
||||||
error = row_drop_table_for_mysql(norm_name, trx,
|
error = row_drop_table_for_mysql(norm_name, trx,
|
||||||
thd_sql_command(thd)
|
thd_sql_command(thd)
|
||||||
== SQLCOM_DROP_DB);
|
== SQLCOM_DROP_DB);
|
||||||
@ -6089,12 +6076,6 @@ ha_innobase::rename_table(
|
|||||||
|
|
||||||
trx_search_latch_release_if_reserved(parent_trx);
|
trx_search_latch_release_if_reserved(parent_trx);
|
||||||
|
|
||||||
if (lower_case_table_names) {
|
|
||||||
srv_lower_case_table_names = TRUE;
|
|
||||||
} else {
|
|
||||||
srv_lower_case_table_names = FALSE;
|
|
||||||
}
|
|
||||||
|
|
||||||
trx = trx_allocate_for_mysql();
|
trx = trx_allocate_for_mysql();
|
||||||
trx->mysql_thd = thd;
|
trx->mysql_thd = thd;
|
||||||
INNOBASE_COPY_STMT(thd, trx);
|
INNOBASE_COPY_STMT(thd, trx);
|
||||||
@ -6114,6 +6095,8 @@ ha_innobase::rename_table(
|
|||||||
|
|
||||||
/* Rename the table in InnoDB */
|
/* Rename the table in InnoDB */
|
||||||
|
|
||||||
|
srv_lower_case_table_names = lower_case_table_names;
|
||||||
|
|
||||||
error = row_rename_table_for_mysql(norm_from, norm_to, trx);
|
error = row_rename_table_for_mysql(norm_from, norm_to, trx);
|
||||||
|
|
||||||
/* Flush the log to reduce probability that the .frm files and
|
/* Flush the log to reduce probability that the .frm files and
|
||||||
@ -8565,7 +8548,7 @@ innobase_commit_by_xid(
|
|||||||
|
|
||||||
if (trx) {
|
if (trx) {
|
||||||
innobase_commit_low(trx);
|
innobase_commit_low(trx);
|
||||||
|
trx_free_for_background(trx);
|
||||||
return(XA_OK);
|
return(XA_OK);
|
||||||
} else {
|
} else {
|
||||||
return(XAER_NOTA);
|
return(XAER_NOTA);
|
||||||
@ -8588,7 +8571,9 @@ innobase_rollback_by_xid(
|
|||||||
trx = trx_get_trx_by_xid(xid);
|
trx = trx_get_trx_by_xid(xid);
|
||||||
|
|
||||||
if (trx) {
|
if (trx) {
|
||||||
return(innobase_rollback_trx(trx));
|
int ret = innobase_rollback_trx(trx);
|
||||||
|
trx_free_for_background(trx);
|
||||||
|
return(ret);
|
||||||
} else {
|
} else {
|
||||||
return(XAER_NOTA);
|
return(XAER_NOTA);
|
||||||
}
|
}
|
||||||
@ -8824,7 +8809,7 @@ innobase_index_name_is_reserved(
|
|||||||
/*============================*/
|
/*============================*/
|
||||||
/* out: true if an index name
|
/* out: true if an index name
|
||||||
matches the reserved name */
|
matches the reserved name */
|
||||||
const trx_t* trx, /* in: InnoDB transaction handle */
|
THD* thd, /* in/out: MySQL connection */
|
||||||
const TABLE* form, /* in: information on table
|
const TABLE* form, /* in: information on table
|
||||||
columns and indexes */
|
columns and indexes */
|
||||||
const char* norm_name) /* in: table name */
|
const char* norm_name) /* in: table name */
|
||||||
@ -8838,7 +8823,7 @@ innobase_index_name_is_reserved(
|
|||||||
if (innobase_strcasecmp(key->name,
|
if (innobase_strcasecmp(key->name,
|
||||||
innobase_index_reserve_name) == 0) {
|
innobase_index_reserve_name) == 0) {
|
||||||
/* Push warning to mysql */
|
/* Push warning to mysql */
|
||||||
push_warning_printf((THD*) trx->mysql_thd,
|
push_warning_printf(thd,
|
||||||
MYSQL_ERROR::WARN_LEVEL_WARN,
|
MYSQL_ERROR::WARN_LEVEL_WARN,
|
||||||
ER_CANT_CREATE_TABLE,
|
ER_CANT_CREATE_TABLE,
|
||||||
"Cannot Create Index with name "
|
"Cannot Create Index with name "
|
||||||
|
@ -19,7 +19,12 @@ Created 3/26/1996 Heikki Tuuri
|
|||||||
#include "dict0types.h"
|
#include "dict0types.h"
|
||||||
#include "trx0xa.h"
|
#include "trx0xa.h"
|
||||||
|
|
||||||
|
/* Number of transactions currently allocated for MySQL: protected by
|
||||||
|
the kernel mutex */
|
||||||
extern ulint trx_n_mysql_transactions;
|
extern ulint trx_n_mysql_transactions;
|
||||||
|
/* Number of transactions currently in the XA PREPARED state: protected by
|
||||||
|
the kernel mutex */
|
||||||
|
extern ulint trx_n_prepared;
|
||||||
|
|
||||||
/************************************************************************
|
/************************************************************************
|
||||||
Releases the search latch if trx has reserved it. */
|
Releases the search latch if trx has reserved it. */
|
||||||
|
@ -3052,12 +3052,13 @@ loop:
|
|||||||
goto loop;
|
goto loop;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Check that there are no longer transactions. We need this wait even
|
/* Check that there are no longer transactions, except for
|
||||||
for the 'very fast' shutdown, because the InnoDB layer may have
|
PREPARED ones. We need this wait even for the 'very fast'
|
||||||
committed or prepared transactions and we don't want to lose them. */
|
shutdown, because the InnoDB layer may have committed or
|
||||||
|
prepared transactions and we don't want to lose them. */
|
||||||
|
|
||||||
if (trx_n_mysql_transactions > 0
|
if (trx_n_mysql_transactions > 0
|
||||||
|| UT_LIST_GET_LEN(trx_sys->trx_list) > 0) {
|
|| UT_LIST_GET_LEN(trx_sys->trx_list) > trx_n_prepared) {
|
||||||
|
|
||||||
mutex_exit(&kernel_mutex);
|
mutex_exit(&kernel_mutex);
|
||||||
|
|
||||||
|
@ -41,6 +41,9 @@ sess_t* trx_dummy_sess = NULL;
|
|||||||
/* Number of transactions currently allocated for MySQL: protected by
|
/* Number of transactions currently allocated for MySQL: protected by
|
||||||
the kernel mutex */
|
the kernel mutex */
|
||||||
ulint trx_n_mysql_transactions = 0;
|
ulint trx_n_mysql_transactions = 0;
|
||||||
|
/* Number of transactions currently in the XA PREPARED state: protected by
|
||||||
|
the kernel mutex */
|
||||||
|
ulint trx_n_prepared = 0;
|
||||||
|
|
||||||
/*****************************************************************
|
/*****************************************************************
|
||||||
Starts the transaction if it is not yet started. */
|
Starts the transaction if it is not yet started. */
|
||||||
@ -480,6 +483,7 @@ trx_lists_init_at_db_start(void)
|
|||||||
if (srv_force_recovery == 0) {
|
if (srv_force_recovery == 0) {
|
||||||
|
|
||||||
trx->conc_state = TRX_PREPARED;
|
trx->conc_state = TRX_PREPARED;
|
||||||
|
trx_n_prepared++;
|
||||||
} else {
|
} else {
|
||||||
fprintf(stderr,
|
fprintf(stderr,
|
||||||
"InnoDB: Since"
|
"InnoDB: Since"
|
||||||
@ -558,6 +562,7 @@ trx_lists_init_at_db_start(void)
|
|||||||
|
|
||||||
trx->conc_state
|
trx->conc_state
|
||||||
= TRX_PREPARED;
|
= TRX_PREPARED;
|
||||||
|
trx_n_prepared++;
|
||||||
} else {
|
} else {
|
||||||
fprintf(stderr,
|
fprintf(stderr,
|
||||||
"InnoDB: Since"
|
"InnoDB: Since"
|
||||||
@ -832,6 +837,11 @@ trx_commit_off_kernel(
|
|||||||
|| trx->conc_state == TRX_PREPARED);
|
|| trx->conc_state == TRX_PREPARED);
|
||||||
ut_ad(mutex_own(&kernel_mutex));
|
ut_ad(mutex_own(&kernel_mutex));
|
||||||
|
|
||||||
|
if (UNIV_UNLIKELY(trx->conc_state == TRX_PREPARED)) {
|
||||||
|
ut_a(trx_n_prepared > 0);
|
||||||
|
trx_n_prepared--;
|
||||||
|
}
|
||||||
|
|
||||||
/* The following assignment makes the transaction committed in memory
|
/* The following assignment makes the transaction committed in memory
|
||||||
and makes its changes to data visible to other transactions.
|
and makes its changes to data visible to other transactions.
|
||||||
NOTE that there is a small discrepancy from the strict formal
|
NOTE that there is a small discrepancy from the strict formal
|
||||||
@ -1882,6 +1892,7 @@ trx_prepare_off_kernel(
|
|||||||
|
|
||||||
/*--------------------------------------*/
|
/*--------------------------------------*/
|
||||||
trx->conc_state = TRX_PREPARED;
|
trx->conc_state = TRX_PREPARED;
|
||||||
|
trx_n_prepared++;
|
||||||
/*--------------------------------------*/
|
/*--------------------------------------*/
|
||||||
|
|
||||||
if (must_flush_log) {
|
if (must_flush_log) {
|
||||||
|
@ -1,3 +1,15 @@
|
|||||||
|
2011-04-07 The InnoDB Team
|
||||||
|
|
||||||
|
* handler/ha_innodb.cc, handler/ha_innodb.h, handler/handler0alter.cc:
|
||||||
|
Fix Bug #52409 Assertion failure: long semaphore wait
|
||||||
|
|
||||||
|
2011-04-07 The InnoDB Team
|
||||||
|
|
||||||
|
* handler/ha_innodb.cc, include/trx0trx.h, include/trx0undo.h,
|
||||||
|
log/log0log.c, trx/trx0sys.c, trx/trx0trx.c, trx/trx0undo.c:
|
||||||
|
Fix Bug #59641 Prepared XA transaction in system after hard crash
|
||||||
|
causes future shutdown hang
|
||||||
|
|
||||||
2011-03-30 The InnoDB Team
|
2011-03-30 The InnoDB Team
|
||||||
|
|
||||||
* srv/srv0srv.c, sync/sync0arr.h, sync/sync0arr.c:
|
* srv/srv0srv.c, sync/sync0arr.h, sync/sync0arr.c:
|
||||||
|
@ -6023,10 +6023,6 @@ create_table_def(
|
|||||||
DBUG_PRINT("enter", ("table_name: %s", table_name));
|
DBUG_PRINT("enter", ("table_name: %s", table_name));
|
||||||
|
|
||||||
ut_a(trx->mysql_thd != NULL);
|
ut_a(trx->mysql_thd != NULL);
|
||||||
if (IS_MAGIC_TABLE_AND_USER_DENIED_ACCESS(table_name,
|
|
||||||
(THD*) trx->mysql_thd)) {
|
|
||||||
DBUG_RETURN(HA_ERR_GENERIC);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* MySQL does the name length check. But we do additional check
|
/* MySQL does the name length check. But we do additional check
|
||||||
on the name length here */
|
on the name length here */
|
||||||
@ -6146,6 +6142,8 @@ err_col:
|
|||||||
col_len);
|
col_len);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
srv_lower_case_table_names = lower_case_table_names;
|
||||||
|
|
||||||
error = row_create_table_for_mysql(table, trx);
|
error = row_create_table_for_mysql(table, trx);
|
||||||
|
|
||||||
if (error == DB_DUPLICATE_KEY) {
|
if (error == DB_DUPLICATE_KEY) {
|
||||||
@ -6562,42 +6560,17 @@ ha_innobase::create(
|
|||||||
DBUG_RETURN(HA_ERR_TO_BIG_ROW);
|
DBUG_RETURN(HA_ERR_TO_BIG_ROW);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Get the transaction associated with the current thd, or create one
|
|
||||||
if not yet created */
|
|
||||||
|
|
||||||
parent_trx = check_trx_exists(thd);
|
|
||||||
|
|
||||||
/* In case MySQL calls this in the middle of a SELECT query, release
|
|
||||||
possible adaptive hash latch to avoid deadlocks of threads */
|
|
||||||
|
|
||||||
trx_search_latch_release_if_reserved(parent_trx);
|
|
||||||
|
|
||||||
trx = innobase_trx_allocate(thd);
|
|
||||||
|
|
||||||
if (lower_case_table_names) {
|
|
||||||
srv_lower_case_table_names = TRUE;
|
|
||||||
} else {
|
|
||||||
srv_lower_case_table_names = FALSE;
|
|
||||||
}
|
|
||||||
|
|
||||||
strcpy(name2, name);
|
strcpy(name2, name);
|
||||||
|
|
||||||
normalize_table_name(norm_name, name2);
|
normalize_table_name(norm_name, name2);
|
||||||
|
|
||||||
/* Latch the InnoDB data dictionary exclusively so that no deadlocks
|
|
||||||
or lock waits can happen in it during a table create operation.
|
|
||||||
Drop table etc. do this latching in row0mysql.c. */
|
|
||||||
|
|
||||||
row_mysql_lock_data_dictionary(trx);
|
|
||||||
|
|
||||||
/* Create the table definition in InnoDB */
|
/* Create the table definition in InnoDB */
|
||||||
|
|
||||||
flags = 0;
|
flags = 0;
|
||||||
|
|
||||||
/* Validate create options if innodb_strict_mode is set. */
|
/* Validate create options if innodb_strict_mode is set. */
|
||||||
if (!create_options_are_valid(thd, form, create_info)) {
|
if (!create_options_are_valid(thd, form, create_info)) {
|
||||||
error = ER_ILLEGAL_HA_CREATE_OPTION;
|
DBUG_RETURN(ER_ILLEGAL_HA_CREATE_OPTION);
|
||||||
goto cleanup;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (create_info->key_block_size) {
|
if (create_info->key_block_size) {
|
||||||
@ -6739,16 +6712,37 @@ ha_innobase::create(
|
|||||||
|
|
||||||
/* Check for name conflicts (with reserved name) for
|
/* Check for name conflicts (with reserved name) for
|
||||||
any user indices to be created. */
|
any user indices to be created. */
|
||||||
if (innobase_index_name_is_reserved(trx, form->key_info,
|
if (innobase_index_name_is_reserved(thd, form->key_info,
|
||||||
form->s->keys)) {
|
form->s->keys)) {
|
||||||
error = -1;
|
DBUG_RETURN(-1);
|
||||||
goto cleanup;
|
}
|
||||||
|
|
||||||
|
if (IS_MAGIC_TABLE_AND_USER_DENIED_ACCESS(norm_name, thd)) {
|
||||||
|
DBUG_RETURN(HA_ERR_GENERIC);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (create_info->options & HA_LEX_CREATE_TMP_TABLE) {
|
if (create_info->options & HA_LEX_CREATE_TMP_TABLE) {
|
||||||
flags |= DICT_TF2_TEMPORARY << DICT_TF2_SHIFT;
|
flags |= DICT_TF2_TEMPORARY << DICT_TF2_SHIFT;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Get the transaction associated with the current thd, or create one
|
||||||
|
if not yet created */
|
||||||
|
|
||||||
|
parent_trx = check_trx_exists(thd);
|
||||||
|
|
||||||
|
/* In case MySQL calls this in the middle of a SELECT query, release
|
||||||
|
possible adaptive hash latch to avoid deadlocks of threads */
|
||||||
|
|
||||||
|
trx_search_latch_release_if_reserved(parent_trx);
|
||||||
|
|
||||||
|
trx = innobase_trx_allocate(thd);
|
||||||
|
|
||||||
|
/* Latch the InnoDB data dictionary exclusively so that no deadlocks
|
||||||
|
or lock waits can happen in it during a table create operation.
|
||||||
|
Drop table etc. do this latching in row0mysql.c. */
|
||||||
|
|
||||||
|
row_mysql_lock_data_dictionary(trx);
|
||||||
|
|
||||||
error = create_table_def(trx, form, norm_name,
|
error = create_table_def(trx, form, norm_name,
|
||||||
create_info->options & HA_LEX_CREATE_TMP_TABLE ? name2 : NULL,
|
create_info->options & HA_LEX_CREATE_TMP_TABLE ? name2 : NULL,
|
||||||
flags);
|
flags);
|
||||||
@ -6992,18 +6986,14 @@ ha_innobase::delete_table(
|
|||||||
|
|
||||||
trx = innobase_trx_allocate(thd);
|
trx = innobase_trx_allocate(thd);
|
||||||
|
|
||||||
if (lower_case_table_names) {
|
|
||||||
srv_lower_case_table_names = TRUE;
|
|
||||||
} else {
|
|
||||||
srv_lower_case_table_names = FALSE;
|
|
||||||
}
|
|
||||||
|
|
||||||
name_len = strlen(name);
|
name_len = strlen(name);
|
||||||
|
|
||||||
ut_a(name_len < 1000);
|
ut_a(name_len < 1000);
|
||||||
|
|
||||||
/* Drop the table in InnoDB */
|
/* Drop the table in InnoDB */
|
||||||
|
|
||||||
|
srv_lower_case_table_names = lower_case_table_names;
|
||||||
|
|
||||||
error = row_drop_table_for_mysql(norm_name, trx,
|
error = row_drop_table_for_mysql(norm_name, trx,
|
||||||
thd_sql_command(thd)
|
thd_sql_command(thd)
|
||||||
== SQLCOM_DROP_DB);
|
== SQLCOM_DROP_DB);
|
||||||
@ -7119,12 +7109,6 @@ innobase_rename_table(
|
|||||||
char* norm_to;
|
char* norm_to;
|
||||||
char* norm_from;
|
char* norm_from;
|
||||||
|
|
||||||
if (lower_case_table_names) {
|
|
||||||
srv_lower_case_table_names = TRUE;
|
|
||||||
} else {
|
|
||||||
srv_lower_case_table_names = FALSE;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Magic number 64 arbitrary
|
// Magic number 64 arbitrary
|
||||||
norm_to = (char*) my_malloc(strlen(to) + 64, MYF(0));
|
norm_to = (char*) my_malloc(strlen(to) + 64, MYF(0));
|
||||||
norm_from = (char*) my_malloc(strlen(from) + 64, MYF(0));
|
norm_from = (char*) my_malloc(strlen(from) + 64, MYF(0));
|
||||||
@ -7139,6 +7123,8 @@ innobase_rename_table(
|
|||||||
row_mysql_lock_data_dictionary(trx);
|
row_mysql_lock_data_dictionary(trx);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
srv_lower_case_table_names = lower_case_table_names;
|
||||||
|
|
||||||
error = row_rename_table_for_mysql(
|
error = row_rename_table_for_mysql(
|
||||||
norm_from, norm_to, trx, lock_and_commit);
|
norm_from, norm_to, trx, lock_and_commit);
|
||||||
|
|
||||||
@ -9998,7 +9984,7 @@ innobase_commit_by_xid(
|
|||||||
|
|
||||||
if (trx) {
|
if (trx) {
|
||||||
innobase_commit_low(trx);
|
innobase_commit_low(trx);
|
||||||
|
trx_free_for_background(trx);
|
||||||
return(XA_OK);
|
return(XA_OK);
|
||||||
} else {
|
} else {
|
||||||
return(XAER_NOTA);
|
return(XAER_NOTA);
|
||||||
@ -10024,7 +10010,9 @@ innobase_rollback_by_xid(
|
|||||||
trx = trx_get_trx_by_xid(xid);
|
trx = trx_get_trx_by_xid(xid);
|
||||||
|
|
||||||
if (trx) {
|
if (trx) {
|
||||||
return(innobase_rollback_trx(trx));
|
int ret = innobase_rollback_trx(trx);
|
||||||
|
trx_free_for_background(trx);
|
||||||
|
return(ret);
|
||||||
} else {
|
} else {
|
||||||
return(XAER_NOTA);
|
return(XAER_NOTA);
|
||||||
}
|
}
|
||||||
@ -10698,19 +10686,19 @@ static int show_innodb_vars(THD *thd, SHOW_VAR *var, char *buff)
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
/***********************************************************************
|
/*********************************************************************//**
|
||||||
This function checks each index name for a table against reserved
|
This function checks each index name for a table against reserved
|
||||||
system default primary index name 'GEN_CLUST_INDEX'. If a name matches,
|
system default primary index name 'GEN_CLUST_INDEX'. If a name
|
||||||
this function pushes an warning message to the client, and returns true. */
|
matches, this function pushes an warning message to the client,
|
||||||
|
and returns true.
|
||||||
|
@return true if the index name matches the reserved name */
|
||||||
extern "C" UNIV_INTERN
|
extern "C" UNIV_INTERN
|
||||||
bool
|
bool
|
||||||
innobase_index_name_is_reserved(
|
innobase_index_name_is_reserved(
|
||||||
/*============================*/
|
/*============================*/
|
||||||
/* out: true if an index name
|
THD* thd, /*!< in/out: MySQL connection */
|
||||||
matches the reserved name */
|
const KEY* key_info, /*!< in: Indexes to be created */
|
||||||
const trx_t* trx, /* in: InnoDB transaction handle */
|
ulint num_of_keys) /*!< in: Number of indexes to
|
||||||
const KEY* key_info, /* in: Indexes to be created */
|
|
||||||
ulint num_of_keys) /* in: Number of indexes to
|
|
||||||
be created. */
|
be created. */
|
||||||
{
|
{
|
||||||
const KEY* key;
|
const KEY* key;
|
||||||
@ -10722,7 +10710,7 @@ innobase_index_name_is_reserved(
|
|||||||
if (innobase_strcasecmp(key->name,
|
if (innobase_strcasecmp(key->name,
|
||||||
innobase_index_reserve_name) == 0) {
|
innobase_index_reserve_name) == 0) {
|
||||||
/* Push warning to mysql */
|
/* Push warning to mysql */
|
||||||
push_warning_printf((THD*) trx->mysql_thd,
|
push_warning_printf(thd,
|
||||||
MYSQL_ERROR::WARN_LEVEL_WARN,
|
MYSQL_ERROR::WARN_LEVEL_WARN,
|
||||||
ER_WRONG_NAME_FOR_INDEX,
|
ER_WRONG_NAME_FOR_INDEX,
|
||||||
"Cannot Create Index with name "
|
"Cannot Create Index with name "
|
||||||
|
@ -317,15 +317,14 @@ innobase_trx_allocate(
|
|||||||
This function checks each index name for a table against reserved
|
This function checks each index name for a table against reserved
|
||||||
system default primary index name 'GEN_CLUST_INDEX'. If a name
|
system default primary index name 'GEN_CLUST_INDEX'. If a name
|
||||||
matches, this function pushes an warning message to the client,
|
matches, this function pushes an warning message to the client,
|
||||||
and returns true. */
|
and returns true.
|
||||||
|
@return true if the index name matches the reserved name */
|
||||||
extern "C"
|
extern "C"
|
||||||
bool
|
bool
|
||||||
innobase_index_name_is_reserved(
|
innobase_index_name_is_reserved(
|
||||||
/*============================*/
|
/*============================*/
|
||||||
/* out: true if the index name
|
THD* thd, /*!< in/out: MySQL connection */
|
||||||
matches the reserved name */
|
const KEY* key_info, /*!< in: Indexes to be created */
|
||||||
const trx_t* trx, /* in: InnoDB transaction handle */
|
ulint num_of_keys); /*!< in: Number of indexes to
|
||||||
const KEY* key_info, /* in: Indexes to be created */
|
|
||||||
ulint num_of_keys); /* in: Number of indexes to
|
|
||||||
be created. */
|
be created. */
|
||||||
|
|
||||||
|
@ -649,11 +649,30 @@ ha_innobase::add_index(
|
|||||||
|
|
||||||
update_thd();
|
update_thd();
|
||||||
|
|
||||||
heap = mem_heap_create(1024);
|
|
||||||
|
|
||||||
/* In case MySQL calls this in the middle of a SELECT query, release
|
/* In case MySQL calls this in the middle of a SELECT query, release
|
||||||
possible adaptive hash latch to avoid deadlocks of threads. */
|
possible adaptive hash latch to avoid deadlocks of threads. */
|
||||||
trx_search_latch_release_if_reserved(prebuilt->trx);
|
trx_search_latch_release_if_reserved(prebuilt->trx);
|
||||||
|
|
||||||
|
/* Check if the index name is reserved. */
|
||||||
|
if (innobase_index_name_is_reserved(user_thd, key_info, num_of_keys)) {
|
||||||
|
DBUG_RETURN(-1);
|
||||||
|
}
|
||||||
|
|
||||||
|
innodb_table = indexed_table
|
||||||
|
= dict_table_get(prebuilt->table->name, FALSE);
|
||||||
|
|
||||||
|
if (UNIV_UNLIKELY(!innodb_table)) {
|
||||||
|
DBUG_RETURN(HA_ERR_NO_SUCH_TABLE);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Check that index keys are sensible */
|
||||||
|
error = innobase_check_index_keys(key_info, num_of_keys, innodb_table);
|
||||||
|
|
||||||
|
if (UNIV_UNLIKELY(error)) {
|
||||||
|
DBUG_RETURN(error);
|
||||||
|
}
|
||||||
|
|
||||||
|
heap = mem_heap_create(1024);
|
||||||
trx_start_if_not_started(prebuilt->trx);
|
trx_start_if_not_started(prebuilt->trx);
|
||||||
|
|
||||||
/* Create a background transaction for the operations on
|
/* Create a background transaction for the operations on
|
||||||
@ -661,32 +680,6 @@ ha_innobase::add_index(
|
|||||||
trx = innobase_trx_allocate(user_thd);
|
trx = innobase_trx_allocate(user_thd);
|
||||||
trx_start_if_not_started(trx);
|
trx_start_if_not_started(trx);
|
||||||
|
|
||||||
innodb_table = indexed_table
|
|
||||||
= dict_table_get(prebuilt->table->name, FALSE);
|
|
||||||
|
|
||||||
if (UNIV_UNLIKELY(!innodb_table)) {
|
|
||||||
error = HA_ERR_NO_SUCH_TABLE;
|
|
||||||
goto err_exit;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Check if the index name is reserved. */
|
|
||||||
if (innobase_index_name_is_reserved(trx, key_info, num_of_keys)) {
|
|
||||||
error = -1;
|
|
||||||
} else {
|
|
||||||
/* Check that index keys are sensible */
|
|
||||||
error = innobase_check_index_keys(key_info, num_of_keys,
|
|
||||||
innodb_table);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (UNIV_UNLIKELY(error)) {
|
|
||||||
err_exit:
|
|
||||||
mem_heap_free(heap);
|
|
||||||
trx_general_rollback_for_mysql(trx, NULL);
|
|
||||||
trx_free_for_mysql(trx);
|
|
||||||
trx_commit_for_mysql(prebuilt->trx);
|
|
||||||
DBUG_RETURN(error);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Create table containing all indexes to be built in this
|
/* Create table containing all indexes to be built in this
|
||||||
alter table add index so that they are in the correct order
|
alter table add index so that they are in the correct order
|
||||||
in the table. */
|
in the table. */
|
||||||
@ -758,8 +751,12 @@ err_exit:
|
|||||||
|
|
||||||
ut_d(dict_table_check_for_dup_indexes(innodb_table,
|
ut_d(dict_table_check_for_dup_indexes(innodb_table,
|
||||||
FALSE));
|
FALSE));
|
||||||
|
mem_heap_free(heap);
|
||||||
|
trx_general_rollback_for_mysql(trx, NULL);
|
||||||
row_mysql_unlock_data_dictionary(trx);
|
row_mysql_unlock_data_dictionary(trx);
|
||||||
goto err_exit;
|
trx_free_for_mysql(trx);
|
||||||
|
trx_commit_for_mysql(prebuilt->trx);
|
||||||
|
DBUG_RETURN(error);
|
||||||
}
|
}
|
||||||
|
|
||||||
trx->table_id = indexed_table->id;
|
trx->table_id = indexed_table->id;
|
||||||
|
@ -44,6 +44,9 @@ extern sess_t* trx_dummy_sess;
|
|||||||
/** Number of transactions currently allocated for MySQL: protected by
|
/** Number of transactions currently allocated for MySQL: protected by
|
||||||
the kernel mutex */
|
the kernel mutex */
|
||||||
extern ulint trx_n_mysql_transactions;
|
extern ulint trx_n_mysql_transactions;
|
||||||
|
/** Number of transactions currently in the XA PREPARED state: protected by
|
||||||
|
the kernel mutex */
|
||||||
|
extern ulint trx_n_prepared;
|
||||||
|
|
||||||
/********************************************************************//**
|
/********************************************************************//**
|
||||||
Releases the search latch if trx has reserved it. */
|
Releases the search latch if trx has reserved it. */
|
||||||
@ -108,6 +111,14 @@ trx_free(
|
|||||||
/*=====*/
|
/*=====*/
|
||||||
trx_t* trx); /*!< in, own: trx object */
|
trx_t* trx); /*!< in, own: trx object */
|
||||||
/********************************************************************//**
|
/********************************************************************//**
|
||||||
|
At shutdown, frees a transaction object that is in the PREPARED state. */
|
||||||
|
UNIV_INTERN
|
||||||
|
void
|
||||||
|
trx_free_prepared(
|
||||||
|
/*==============*/
|
||||||
|
trx_t* trx) /*!< in, own: trx object */
|
||||||
|
__attribute__((nonnull));
|
||||||
|
/********************************************************************//**
|
||||||
Frees a transaction object for MySQL. */
|
Frees a transaction object for MySQL. */
|
||||||
UNIV_INTERN
|
UNIV_INTERN
|
||||||
void
|
void
|
||||||
|
@ -298,6 +298,15 @@ void
|
|||||||
trx_undo_insert_cleanup(
|
trx_undo_insert_cleanup(
|
||||||
/*====================*/
|
/*====================*/
|
||||||
trx_t* trx); /*!< in: transaction handle */
|
trx_t* trx); /*!< in: transaction handle */
|
||||||
|
|
||||||
|
/********************************************************************//**
|
||||||
|
At shutdown, frees the undo logs of a PREPARED transaction. */
|
||||||
|
UNIV_INTERN
|
||||||
|
void
|
||||||
|
trx_undo_free_prepared(
|
||||||
|
/*===================*/
|
||||||
|
trx_t* trx) /*!< in/out: PREPARED transaction */
|
||||||
|
__attribute__((nonnull));
|
||||||
#endif /* !UNIV_HOTBACKUP */
|
#endif /* !UNIV_HOTBACKUP */
|
||||||
/***********************************************************//**
|
/***********************************************************//**
|
||||||
Parses the redo log entry of an undo log page initialization.
|
Parses the redo log entry of an undo log page initialization.
|
||||||
|
@ -3085,12 +3085,13 @@ loop:
|
|||||||
goto loop;
|
goto loop;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Check that there are no longer transactions. We need this wait even
|
/* Check that there are no longer transactions, except for
|
||||||
for the 'very fast' shutdown, because the InnoDB layer may have
|
PREPARED ones. We need this wait even for the 'very fast'
|
||||||
committed or prepared transactions and we don't want to lose them. */
|
shutdown, because the InnoDB layer may have committed or
|
||||||
|
prepared transactions and we don't want to lose them. */
|
||||||
|
|
||||||
if (trx_n_mysql_transactions > 0
|
if (trx_n_mysql_transactions > 0
|
||||||
|| UT_LIST_GET_LEN(trx_sys->trx_list) > 0) {
|
|| UT_LIST_GET_LEN(trx_sys->trx_list) > trx_n_prepared) {
|
||||||
|
|
||||||
mutex_exit(&kernel_mutex);
|
mutex_exit(&kernel_mutex);
|
||||||
|
|
||||||
|
@ -37,6 +37,7 @@ Created 3/26/1996 Heikki Tuuri
|
|||||||
#include "trx0rseg.h"
|
#include "trx0rseg.h"
|
||||||
#include "trx0undo.h"
|
#include "trx0undo.h"
|
||||||
#include "srv0srv.h"
|
#include "srv0srv.h"
|
||||||
|
#include "srv0start.h"
|
||||||
#include "trx0purge.h"
|
#include "trx0purge.h"
|
||||||
#include "log0log.h"
|
#include "log0log.h"
|
||||||
#include "os0file.h"
|
#include "os0file.h"
|
||||||
@ -1548,10 +1549,12 @@ void
|
|||||||
trx_sys_close(void)
|
trx_sys_close(void)
|
||||||
/*===============*/
|
/*===============*/
|
||||||
{
|
{
|
||||||
|
trx_t* trx;
|
||||||
trx_rseg_t* rseg;
|
trx_rseg_t* rseg;
|
||||||
read_view_t* view;
|
read_view_t* view;
|
||||||
|
|
||||||
ut_ad(trx_sys != NULL);
|
ut_ad(trx_sys != NULL);
|
||||||
|
ut_ad(srv_shutdown_state == SRV_SHUTDOWN_EXIT_THREADS);
|
||||||
|
|
||||||
/* Check that all read views are closed except read view owned
|
/* Check that all read views are closed except read view owned
|
||||||
by a purge. */
|
by a purge. */
|
||||||
@ -1583,6 +1586,13 @@ trx_sys_close(void)
|
|||||||
mem_free(trx_doublewrite);
|
mem_free(trx_doublewrite);
|
||||||
trx_doublewrite = NULL;
|
trx_doublewrite = NULL;
|
||||||
|
|
||||||
|
/* Only prepared transactions may be left in the system. Free them. */
|
||||||
|
ut_a(UT_LIST_GET_LEN(trx_sys->trx_list) == trx_n_prepared);
|
||||||
|
|
||||||
|
while ((trx = UT_LIST_GET_FIRST(trx_sys->trx_list)) != NULL) {
|
||||||
|
trx_free_prepared(trx);
|
||||||
|
}
|
||||||
|
|
||||||
/* There can't be any active transactions. */
|
/* There can't be any active transactions. */
|
||||||
rseg = UT_LIST_GET_FIRST(trx_sys->rseg_list);
|
rseg = UT_LIST_GET_FIRST(trx_sys->rseg_list);
|
||||||
|
|
||||||
|
@ -50,6 +50,9 @@ UNIV_INTERN sess_t* trx_dummy_sess = NULL;
|
|||||||
/** Number of transactions currently allocated for MySQL: protected by
|
/** Number of transactions currently allocated for MySQL: protected by
|
||||||
the kernel mutex */
|
the kernel mutex */
|
||||||
UNIV_INTERN ulint trx_n_mysql_transactions = 0;
|
UNIV_INTERN ulint trx_n_mysql_transactions = 0;
|
||||||
|
/* Number of transactions currently in the XA PREPARED state: protected by
|
||||||
|
the kernel mutex */
|
||||||
|
UNIV_INTERN ulint trx_n_prepared = 0;
|
||||||
|
|
||||||
/*************************************************************//**
|
/*************************************************************//**
|
||||||
Set detailed error message for the transaction. */
|
Set detailed error message for the transaction. */
|
||||||
@ -333,6 +336,60 @@ trx_free(
|
|||||||
mem_free(trx);
|
mem_free(trx);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/********************************************************************//**
|
||||||
|
At shutdown, frees a transaction object that is in the PREPARED state. */
|
||||||
|
UNIV_INTERN
|
||||||
|
void
|
||||||
|
trx_free_prepared(
|
||||||
|
/*==============*/
|
||||||
|
trx_t* trx) /*!< in, own: trx object */
|
||||||
|
{
|
||||||
|
ut_ad(mutex_own(&kernel_mutex));
|
||||||
|
ut_a(trx->conc_state == TRX_PREPARED);
|
||||||
|
ut_a(trx->magic_n == TRX_MAGIC_N);
|
||||||
|
|
||||||
|
/* Prepared transactions are sort of active; they allow
|
||||||
|
ROLLBACK and COMMIT operations. Because the system does not
|
||||||
|
contain any other transactions than prepared transactions at
|
||||||
|
the shutdown stage and because a transaction cannot become
|
||||||
|
PREPARED while holding locks, it is safe to release the locks
|
||||||
|
held by PREPARED transactions here at shutdown.*/
|
||||||
|
lock_release_off_kernel(trx);
|
||||||
|
|
||||||
|
trx_undo_free_prepared(trx);
|
||||||
|
|
||||||
|
mutex_free(&trx->undo_mutex);
|
||||||
|
|
||||||
|
if (trx->undo_no_arr) {
|
||||||
|
trx_undo_arr_free(trx->undo_no_arr);
|
||||||
|
}
|
||||||
|
|
||||||
|
ut_a(UT_LIST_GET_LEN(trx->signals) == 0);
|
||||||
|
ut_a(UT_LIST_GET_LEN(trx->reply_signals) == 0);
|
||||||
|
|
||||||
|
ut_a(trx->wait_lock == NULL);
|
||||||
|
ut_a(UT_LIST_GET_LEN(trx->wait_thrs) == 0);
|
||||||
|
|
||||||
|
ut_a(!trx->has_search_latch);
|
||||||
|
|
||||||
|
ut_a(trx->dict_operation_lock_mode == 0);
|
||||||
|
|
||||||
|
if (trx->lock_heap) {
|
||||||
|
mem_heap_free(trx->lock_heap);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (trx->global_read_view_heap) {
|
||||||
|
mem_heap_free(trx->global_read_view_heap);
|
||||||
|
}
|
||||||
|
|
||||||
|
ut_a(ib_vector_is_empty(trx->autoinc_locks));
|
||||||
|
ib_vector_free(trx->autoinc_locks);
|
||||||
|
|
||||||
|
UT_LIST_REMOVE(trx_list, trx_sys->trx_list, trx);
|
||||||
|
|
||||||
|
mem_free(trx);
|
||||||
|
}
|
||||||
|
|
||||||
/********************************************************************//**
|
/********************************************************************//**
|
||||||
Frees a transaction object for MySQL. */
|
Frees a transaction object for MySQL. */
|
||||||
UNIV_INTERN
|
UNIV_INTERN
|
||||||
@ -463,6 +520,7 @@ trx_lists_init_at_db_start(void)
|
|||||||
if (srv_force_recovery == 0) {
|
if (srv_force_recovery == 0) {
|
||||||
|
|
||||||
trx->conc_state = TRX_PREPARED;
|
trx->conc_state = TRX_PREPARED;
|
||||||
|
trx_n_prepared++;
|
||||||
} else {
|
} else {
|
||||||
fprintf(stderr,
|
fprintf(stderr,
|
||||||
"InnoDB: Since"
|
"InnoDB: Since"
|
||||||
@ -541,6 +599,7 @@ trx_lists_init_at_db_start(void)
|
|||||||
|
|
||||||
trx->conc_state
|
trx->conc_state
|
||||||
= TRX_PREPARED;
|
= TRX_PREPARED;
|
||||||
|
trx_n_prepared++;
|
||||||
} else {
|
} else {
|
||||||
fprintf(stderr,
|
fprintf(stderr,
|
||||||
"InnoDB: Since"
|
"InnoDB: Since"
|
||||||
@ -820,6 +879,11 @@ trx_commit_off_kernel(
|
|||||||
|| trx->conc_state == TRX_PREPARED);
|
|| trx->conc_state == TRX_PREPARED);
|
||||||
ut_ad(mutex_own(&kernel_mutex));
|
ut_ad(mutex_own(&kernel_mutex));
|
||||||
|
|
||||||
|
if (UNIV_UNLIKELY(trx->conc_state == TRX_PREPARED)) {
|
||||||
|
ut_a(trx_n_prepared > 0);
|
||||||
|
trx_n_prepared--;
|
||||||
|
}
|
||||||
|
|
||||||
/* The following assignment makes the transaction committed in memory
|
/* The following assignment makes the transaction committed in memory
|
||||||
and makes its changes to data visible to other transactions.
|
and makes its changes to data visible to other transactions.
|
||||||
NOTE that there is a small discrepancy from the strict formal
|
NOTE that there is a small discrepancy from the strict formal
|
||||||
@ -1857,6 +1921,7 @@ trx_prepare_off_kernel(
|
|||||||
|
|
||||||
/*--------------------------------------*/
|
/*--------------------------------------*/
|
||||||
trx->conc_state = TRX_PREPARED;
|
trx->conc_state = TRX_PREPARED;
|
||||||
|
trx_n_prepared++;
|
||||||
/*--------------------------------------*/
|
/*--------------------------------------*/
|
||||||
|
|
||||||
if (lsn) {
|
if (lsn) {
|
||||||
@ -2031,10 +2096,11 @@ trx_get_trx_by_xid(
|
|||||||
while (trx) {
|
while (trx) {
|
||||||
/* Compare two X/Open XA transaction id's: their
|
/* Compare two X/Open XA transaction id's: their
|
||||||
length should be the same and binary comparison
|
length should be the same and binary comparison
|
||||||
of gtrid_lenght+bqual_length bytes should be
|
of gtrid_length+bqual_length bytes should be
|
||||||
the same */
|
the same */
|
||||||
|
|
||||||
if (trx->conc_state == TRX_PREPARED
|
if (trx->is_recovered
|
||||||
|
&& trx->conc_state == TRX_PREPARED
|
||||||
&& xid->gtrid_length == trx->xid.gtrid_length
|
&& xid->gtrid_length == trx->xid.gtrid_length
|
||||||
&& xid->bqual_length == trx->xid.bqual_length
|
&& xid->bqual_length == trx->xid.bqual_length
|
||||||
&& memcmp(xid->data, trx->xid.data,
|
&& memcmp(xid->data, trx->xid.data,
|
||||||
|
@ -36,6 +36,7 @@ Created 3/26/1996 Heikki Tuuri
|
|||||||
#include "trx0rseg.h"
|
#include "trx0rseg.h"
|
||||||
#include "trx0trx.h"
|
#include "trx0trx.h"
|
||||||
#include "srv0srv.h"
|
#include "srv0srv.h"
|
||||||
|
#include "srv0start.h"
|
||||||
#include "trx0rec.h"
|
#include "trx0rec.h"
|
||||||
#include "trx0purge.h"
|
#include "trx0purge.h"
|
||||||
|
|
||||||
@ -1976,4 +1977,31 @@ trx_undo_insert_cleanup(
|
|||||||
|
|
||||||
mutex_exit(&(rseg->mutex));
|
mutex_exit(&(rseg->mutex));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/********************************************************************//**
|
||||||
|
At shutdown, frees the undo logs of a PREPARED transaction. */
|
||||||
|
UNIV_INTERN
|
||||||
|
void
|
||||||
|
trx_undo_free_prepared(
|
||||||
|
/*===================*/
|
||||||
|
trx_t* trx) /*!< in/out: PREPARED transaction */
|
||||||
|
{
|
||||||
|
mutex_enter(&trx->rseg->mutex);
|
||||||
|
|
||||||
|
ut_ad(srv_shutdown_state == SRV_SHUTDOWN_EXIT_THREADS);
|
||||||
|
|
||||||
|
if (trx->update_undo) {
|
||||||
|
ut_a(trx->update_undo->state == TRX_UNDO_PREPARED);
|
||||||
|
UT_LIST_REMOVE(undo_list, trx->rseg->update_undo_list,
|
||||||
|
trx->update_undo);
|
||||||
|
trx_undo_mem_free(trx->update_undo);
|
||||||
|
}
|
||||||
|
if (trx->insert_undo) {
|
||||||
|
ut_a(trx->insert_undo->state == TRX_UNDO_PREPARED);
|
||||||
|
UT_LIST_REMOVE(undo_list, trx->rseg->insert_undo_list,
|
||||||
|
trx->insert_undo);
|
||||||
|
trx_undo_mem_free(trx->insert_undo);
|
||||||
|
}
|
||||||
|
mutex_exit(&trx->rseg->mutex);
|
||||||
|
}
|
||||||
#endif /* !UNIV_HOTBACKUP */
|
#endif /* !UNIV_HOTBACKUP */
|
||||||
|
Loading…
x
Reference in New Issue
Block a user