Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Support
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
M
MariaDB
Project overview
Project overview
Details
Activity
Releases
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Issues
0
Issues
0
List
Boards
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Analytics
Analytics
CI / CD
Repository
Value Stream
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
nexedi
MariaDB
Commits
1607f4aa
Commit
1607f4aa
authored
May 02, 2011
by
Vasil Dimov
Browse files
Options
Browse Files
Download
Plain Diff
Merge mysql-5.1-innodb -> mysql-5.1
parents
8843aea7
6f7d0f18
Changes
25
Hide whitespace changes
Inline
Side-by-side
Showing
25 changed files
with
616 additions
and
158 deletions
+616
-158
client/mysqltest.cc
client/mysqltest.cc
+7
-5
mysql-test/include/wait_until_disconnected.inc
mysql-test/include/wait_until_disconnected.inc
+1
-1
mysql-test/suite/innodb/r/innodb_bug59410.result
mysql-test/suite/innodb/r/innodb_bug59410.result
+17
-0
mysql-test/suite/innodb/r/innodb_bug59641.result
mysql-test/suite/innodb/r/innodb_bug59641.result
+57
-0
mysql-test/suite/innodb/t/innodb_bug59410.test
mysql-test/suite/innodb/t/innodb_bug59410.test
+24
-0
mysql-test/suite/innodb/t/innodb_bug59641.test
mysql-test/suite/innodb/t/innodb_bug59641.test
+66
-0
mysql-test/suite/innodb_plugin/r/innodb_bug59410.result
mysql-test/suite/innodb_plugin/r/innodb_bug59410.result
+17
-0
mysql-test/suite/innodb_plugin/r/innodb_bug59641.result
mysql-test/suite/innodb_plugin/r/innodb_bug59641.result
+57
-0
mysql-test/suite/innodb_plugin/t/innodb_bug59410.test
mysql-test/suite/innodb_plugin/t/innodb_bug59410.test
+24
-0
mysql-test/suite/innodb_plugin/t/innodb_bug59641.test
mysql-test/suite/innodb_plugin/t/innodb_bug59641.test
+70
-0
sql/sql_class.cc
sql/sql_class.cc
+1
-0
storage/innobase/handler/ha_innodb.cc
storage/innobase/handler/ha_innodb.cc
+42
-57
storage/innobase/include/trx0trx.h
storage/innobase/include/trx0trx.h
+5
-0
storage/innobase/log/log0log.c
storage/innobase/log/log0log.c
+5
-4
storage/innobase/trx/trx0trx.c
storage/innobase/trx/trx0trx.c
+11
-0
storage/innodb_plugin/ChangeLog
storage/innodb_plugin/ChangeLog
+12
-0
storage/innodb_plugin/handler/ha_innodb.cc
storage/innodb_plugin/handler/ha_innodb.cc
+44
-56
storage/innodb_plugin/handler/ha_innodb.h
storage/innodb_plugin/handler/ha_innodb.h
+5
-6
storage/innodb_plugin/handler/handler0alter.cc
storage/innodb_plugin/handler/handler0alter.cc
+20
-23
storage/innodb_plugin/include/trx0trx.h
storage/innodb_plugin/include/trx0trx.h
+11
-0
storage/innodb_plugin/include/trx0undo.h
storage/innodb_plugin/include/trx0undo.h
+9
-0
storage/innodb_plugin/log/log0log.c
storage/innodb_plugin/log/log0log.c
+5
-4
storage/innodb_plugin/trx/trx0sys.c
storage/innodb_plugin/trx/trx0sys.c
+10
-0
storage/innodb_plugin/trx/trx0trx.c
storage/innodb_plugin/trx/trx0trx.c
+68
-2
storage/innodb_plugin/trx/trx0undo.c
storage/innodb_plugin/trx/trx0undo.c
+28
-0
No files found.
client/mysqltest.cc
View file @
1607f4aa
...
...
@@ -4461,13 +4461,14 @@ static int my_kill(int pid, int sig)
command called command
DESCRIPTION
shutdown [<timeout>]
shutdown
_server
[<timeout>]
*/
void
do_shutdown_server
(
struct
st_command
*
command
)
{
int
timeout
=
60
,
pid
;
long
timeout
=
60
;
int
pid
;
DYNAMIC_STRING
ds_pidfile_name
;
MYSQL
*
mysql
=
&
cur_con
->
mysql
;
static
DYNAMIC_STRING
ds_timeout
;
...
...
@@ -4482,8 +4483,9 @@ void do_shutdown_server(struct st_command *command)
if
(
ds_timeout
.
length
)
{
timeout
=
atoi
(
ds_timeout
.
str
);
if
(
timeout
==
0
)
char
*
endptr
;
timeout
=
strtol
(
ds_timeout
.
str
,
&
endptr
,
10
);
if
(
*
endptr
!=
'\0'
)
die
(
"Illegal argument for timeout: '%s'"
,
ds_timeout
.
str
);
}
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_VOID_RETURN
;
}
DBUG_PRINT
(
"info"
,
(
"Sleeping, timeout: %d"
,
timeout
));
DBUG_PRINT
(
"info"
,
(
"Sleeping, timeout: %
l
d"
,
timeout
));
my_sleep
(
1000000L
);
}
...
...
mysql-test/include/wait_until_disconnected.inc
View file @
1607f4aa
...
...
@@ -7,7 +7,7 @@ let $counter= 500;
let
$mysql_errno
=
0
;
while
(
!
$mysql_errno
)
{
--
error
0
,
10
53
,
2002
,
2006
,
2013
--
error
0
,
10
40
,
1053
,
2002
,
2003
,
2006
,
2013
show
status
;
dec
$counter
;
...
...
mysql-test/suite/innodb/r/innodb_bug59410.result
0 → 100644
View file @
1607f4aa
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;
mysql-test/suite/innodb/r/innodb_bug59641.result
0 → 100644
View file @
1607f4aa
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;
mysql-test/suite/innodb/t/innodb_bug59410.test
0 → 100644
View file @
1607f4aa
#
# 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
;
mysql-test/suite/innodb/t/innodb_bug59641.test
0 → 100644
View file @
1607f4aa
# 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
;
mysql-test/suite/innodb_plugin/r/innodb_bug59410.result
0 → 100644
View file @
1607f4aa
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;
mysql-test/suite/innodb_plugin/r/innodb_bug59641.result
0 → 100644
View file @
1607f4aa
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;
mysql-test/suite/innodb_plugin/t/innodb_bug59410.test
0 → 100644
View file @
1607f4aa
#
# 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
;
mysql-test/suite/innodb_plugin/t/innodb_bug59641.test
0 → 100644
View file @
1607f4aa
# 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
;
sql/sql_class.cc
View file @
1607f4aa
...
...
@@ -3383,6 +3383,7 @@ bool xid_cache_insert(XID *xid, enum xa_states xa_state)
xs
->
xa_state
=
xa_state
;
xs
->
xid
.
set
(
xid
);
xs
->
in_thd
=
0
;
xs
->
rm_error
=
0
;
res
=
my_hash_insert
(
&
xid_cache
,
(
uchar
*
)
xs
);
}
pthread_mutex_unlock
(
&
LOCK_xid_cache
);
...
...
storage/innobase/handler/ha_innodb.cc
View file @
1607f4aa
...
...
@@ -189,7 +189,7 @@ innobase_index_name_is_reserved(
/*============================*/
/* out: true if index name matches a
reserved name */
const
trx_t
*
trx
,
/* in: InnoDB transaction handle
*/
THD
*
thd
,
/* in/out: MySQL connection
*/
const
TABLE
*
form
,
/* in: information on table
columns and indexes */
const
char
*
norm_name
);
/* in: table name */
...
...
@@ -5285,10 +5285,6 @@ create_table_def(
DBUG_PRINT
(
"enter"
,
(
"table_name: %s"
,
table_name
));
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
;
...
...
@@ -5397,6 +5393,8 @@ create_table_def(
col_len
);
}
srv_lower_case_table_names
=
lower_case_table_names
;
error
=
row_create_table_for_mysql
(
table
,
trx
);
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
);
}
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
if not yet created */
...
...
@@ -5665,48 +5692,12 @@ ha_innobase::create(
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
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 */
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
,
create_info
->
options
&
HA_LEX_CREATE_TMP_TABLE
?
name2
:
NULL
,
flags
);
...
...
@@ -5936,12 +5927,6 @@ ha_innobase::delete_table(
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
->
mysql_thd
=
thd
;
...
...
@@ -5961,6 +5946,8 @@ ha_innobase::delete_table(
/* Drop the table in InnoDB */
srv_lower_case_table_names
=
lower_case_table_names
;
error
=
row_drop_table_for_mysql
(
norm_name
,
trx
,
thd_sql_command
(
thd
)
==
SQLCOM_DROP_DB
);
...
...
@@ -6089,12 +6076,6 @@ ha_innobase::rename_table(
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
->
mysql_thd
=
thd
;
INNOBASE_COPY_STMT
(
thd
,
trx
);
...
...
@@ -6114,6 +6095,8 @@ ha_innobase::rename_table(
/* 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
);
/* Flush the log to reduce probability that the .frm files and
...
...
@@ -8565,7 +8548,7 @@ innobase_commit_by_xid(
if
(
trx
)
{
innobase_commit_low
(
trx
);
trx_free_for_background
(
trx
);
return
(
XA_OK
);
}
else
{
return
(
XAER_NOTA
);
...
...
@@ -8588,7 +8571,9 @@ innobase_rollback_by_xid(
trx
=
trx_get_trx_by_xid
(
xid
);
if
(
trx
)
{
return
(
innobase_rollback_trx
(
trx
));
int
ret
=
innobase_rollback_trx
(
trx
);
trx_free_for_background
(
trx
);
return
(
ret
);
}
else
{
return
(
XAER_NOTA
);
}
...
...
@@ -8824,7 +8809,7 @@ innobase_index_name_is_reserved(
/*============================*/
/* out: true if an index 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
columns and indexes */
const
char
*
norm_name
)
/* in: table name */
...
...
@@ -8838,7 +8823,7 @@ innobase_index_name_is_reserved(
if
(
innobase_strcasecmp
(
key
->
name
,
innobase_index_reserve_name
)
==
0
)
{
/* Push warning to mysql */
push_warning_printf
(
(
THD
*
)
trx
->
mysql_
thd
,
push_warning_printf
(
thd
,
MYSQL_ERROR
::
WARN_LEVEL_WARN
,
ER_CANT_CREATE_TABLE
,
"Cannot Create Index with name "
...
...
storage/innobase/include/trx0trx.h
View file @
1607f4aa
...
...
@@ -19,7 +19,12 @@ Created 3/26/1996 Heikki Tuuri
#include "dict0types.h"
#include "trx0xa.h"
/* Number of transactions currently allocated for MySQL: protected by
the kernel mutex */
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. */
...
...
storage/innobase/log/log0log.c
View file @
1607f4aa
...
...
@@ -3052,12 +3052,13 @@ logs_empty_and_mark_files_at_shutdown(void)
goto
loop
;
}
/* Check that there are no longer transactions. We need this wait even
for the 'very fast' shutdown, because the InnoDB layer may have
committed or prepared transactions and we don't want to lose them. */
/* Check that there are no longer transactions, except for
PREPARED ones. We need this wait even for the 'very fast'
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
||
UT_LIST_GET_LEN
(
trx_sys
->
trx_list
)
>
0
)
{
||
UT_LIST_GET_LEN
(
trx_sys
->
trx_list
)
>
trx_n_prepared
)
{
mutex_exit
(
&
kernel_mutex
);
...
...
storage/innobase/trx/trx0trx.c
View file @
1607f4aa
...
...
@@ -41,6 +41,9 @@ sess_t* trx_dummy_sess = NULL;
/* Number of transactions currently allocated for MySQL: protected by
the kernel mutex */
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. */
...
...
@@ -480,6 +483,7 @@ trx_lists_init_at_db_start(void)
if
(
srv_force_recovery
==
0
)
{
trx
->
conc_state
=
TRX_PREPARED
;
trx_n_prepared
++
;
}
else
{
fprintf
(
stderr
,
"InnoDB: Since"
...
...
@@ -558,6 +562,7 @@ trx_lists_init_at_db_start(void)
trx
->
conc_state
=
TRX_PREPARED
;
trx_n_prepared
++
;
}
else
{
fprintf
(
stderr
,
"InnoDB: Since"
...
...
@@ -832,6 +837,11 @@ trx_commit_off_kernel(
||
trx
->
conc_state
==
TRX_PREPARED
);
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
and makes its changes to data visible to other transactions.
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_n_prepared
++
;
/*--------------------------------------*/
if
(
must_flush_log
)
{
...
...
storage/innodb_plugin/ChangeLog
View file @
1607f4aa
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
* srv/srv0srv.c, sync/sync0arr.h, sync/sync0arr.c:
...
...
storage/innodb_plugin/handler/ha_innodb.cc
View file @
1607f4aa
...
...
@@ -6023,10 +6023,6 @@ create_table_def(
DBUG_PRINT
(
"enter"
,
(
"table_name: %s"
,
table_name
));
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
on the name length here */
...
...
@@ -6146,6 +6142,8 @@ create_table_def(
col_len
);
}
srv_lower_case_table_names
=
lower_case_table_names
;
error
=
row_create_table_for_mysql
(
table
,
trx
);
if
(
error
==
DB_DUPLICATE_KEY
)
{
...
...
@@ -6562,42 +6560,17 @@ ha_innobase::create(
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
);
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 */
flags
=
0
;
/* Validate create options if innodb_strict_mode is set. */
if
(
!
create_options_are_valid
(
thd
,
form
,
create_info
))
{
error
=
ER_ILLEGAL_HA_CREATE_OPTION
;
goto
cleanup
;
DBUG_RETURN
(
ER_ILLEGAL_HA_CREATE_OPTION
);
}
if
(
create_info
->
key_block_size
)
{
...
...
@@ -6739,16 +6712,37 @@ ha_innobase::create(
/* Check for name conflicts (with reserved name) for
any user indices to be created. */
if
(
innobase_index_name_is_reserved
(
t
rx
,
form
->
key_info
,
if
(
innobase_index_name_is_reserved
(
t
hd
,
form
->
key_info
,
form
->
s
->
keys
))
{
error
=
-
1
;
goto
cleanup
;
DBUG_RETURN
(
-
1
);
}
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
)
{
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
,
create_info
->
options
&
HA_LEX_CREATE_TMP_TABLE
?
name2
:
NULL
,
flags
);
...
...
@@ -6992,18 +6986,14 @@ ha_innobase::delete_table(
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
);
ut_a
(
name_len
<
1000
);
/* Drop the table in InnoDB */
srv_lower_case_table_names
=
lower_case_table_names
;
error
=
row_drop_table_for_mysql
(
norm_name
,
trx
,
thd_sql_command
(
thd
)
==
SQLCOM_DROP_DB
);
...
...
@@ -7119,12 +7109,6 @@ innobase_rename_table(
char
*
norm_to
;
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
norm_to
=
(
char
*
)
my_malloc
(
strlen
(
to
)
+
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
);
}
srv_lower_case_table_names
=
lower_case_table_names
;
error
=
row_rename_table_for_mysql
(
norm_from
,
norm_to
,
trx
,
lock_and_commit
);
...
...
@@ -9998,7 +9984,7 @@ innobase_commit_by_xid(
if
(
trx
)
{
innobase_commit_low
(
trx
);
trx_free_for_background
(
trx
);
return
(
XA_OK
);
}
else
{
return
(
XAER_NOTA
);
...
...
@@ -10024,7 +10010,9 @@ innobase_rollback_by_xid(
trx
=
trx_get_trx_by_xid
(
xid
);
if
(
trx
)
{
return
(
innobase_rollback_trx
(
trx
));
int
ret
=
innobase_rollback_trx
(
trx
);
trx_free_for_background
(
trx
);
return
(
ret
);
}
else
{
return
(
XAER_NOTA
);
}
...
...
@@ -10698,19 +10686,19 @@ static int show_innodb_vars(THD *thd, SHOW_VAR *var, char *buff)
return
0
;
}
/***********************************************************************
/*********************************************************************
//
**
This function checks each index name for a table against reserved
system default primary index name 'GEN_CLUST_INDEX'. If a name matches,
this function pushes an warning message to the client, and returns true. */
system default primary index name 'GEN_CLUST_INDEX'. If a name
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
bool
innobase_index_name_is_reserved
(
/*============================*/
/* out: true if an index name
matches the reserved name */
const
trx_t
*
trx
,
/* in: InnoDB transaction handle */
const
KEY
*
key_info
,
/* in: Indexes to be created */
ulint
num_of_keys
)
/* in: Number of indexes to
THD
*
thd
,
/*!< in/out: MySQL connection */
const
KEY
*
key_info
,
/*!< in: Indexes to be created */
ulint
num_of_keys
)
/*!< in: Number of indexes to
be created. */
{
const
KEY
*
key
;
...
...
@@ -10722,7 +10710,7 @@ innobase_index_name_is_reserved(
if
(
innobase_strcasecmp
(
key
->
name
,
innobase_index_reserve_name
)
==
0
)
{
/* Push warning to mysql */
push_warning_printf
(
(
THD
*
)
trx
->
mysql_
thd
,
push_warning_printf
(
thd
,
MYSQL_ERROR
::
WARN_LEVEL_WARN
,
ER_WRONG_NAME_FOR_INDEX
,
"Cannot Create Index with name "
...
...
storage/innodb_plugin/handler/ha_innodb.h
View file @
1607f4aa
...
...
@@ -317,15 +317,14 @@ innobase_trx_allocate(
This function checks each index name for a table against reserved
system default primary index name 'GEN_CLUST_INDEX'. If a name
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"
bool
innobase_index_name_is_reserved
(
/*============================*/
/* out: true if the index name
matches the reserved name */
const
trx_t
*
trx
,
/* in: InnoDB transaction handle */
const
KEY
*
key_info
,
/* in: Indexes to be created */
ulint
num_of_keys
);
/* in: Number of indexes to
THD
*
thd
,
/*!< in/out: MySQL connection */
const
KEY
*
key_info
,
/*!< in: Indexes to be created */
ulint
num_of_keys
);
/*!< in: Number of indexes to
be created. */
storage/innodb_plugin/handler/handler0alter.cc
View file @
1607f4aa
...
...
@@ -649,44 +649,37 @@ ha_innobase::add_index(
update_thd
();
heap
=
mem_heap_create
(
1024
);
/* 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
(
prebuilt
->
trx
);
trx_start_if_not_started
(
prebuilt
->
trx
);
/* C
reate a background transaction for the operations on
the data dictionary tables. */
trx
=
innobase_trx_allocate
(
user_thd
);
trx_start_if_not_started
(
trx
);
/* C
heck 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
))
{
error
=
HA_ERR_NO_SUCH_TABLE
;
goto
err_exit
;
DBUG_RETURN
(
HA_ERR_NO_SUCH_TABLE
);
}
/* 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
);
}
/* 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
);
}
heap
=
mem_heap_create
(
1024
);
trx_start_if_not_started
(
prebuilt
->
trx
);
/* Create a background transaction for the operations on
the data dictionary tables. */
trx
=
innobase_trx_allocate
(
user_thd
);
trx_start_if_not_started
(
trx
);
/* Create table containing all indexes to be built in this
alter table add index so that they are in the correct order
in the table. */
...
...
@@ -758,8 +751,12 @@ ha_innobase::add_index(
ut_d
(
dict_table_check_for_dup_indexes
(
innodb_table
,
FALSE
));
mem_heap_free
(
heap
);
trx_general_rollback_for_mysql
(
trx
,
NULL
);
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
;
...
...
storage/innodb_plugin/include/trx0trx.h
View file @
1607f4aa
...
...
@@ -44,6 +44,9 @@ extern sess_t* trx_dummy_sess;
/** Number of transactions currently allocated for MySQL: protected by
the kernel mutex */
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. */
...
...
@@ -108,6 +111,14 @@ trx_free(
/*=====*/
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. */
UNIV_INTERN
void
...
...
storage/innodb_plugin/include/trx0undo.h
View file @
1607f4aa
...
...
@@ -298,6 +298,15 @@ void
trx_undo_insert_cleanup
(
/*====================*/
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 */
/***********************************************************//**
Parses the redo log entry of an undo log page initialization.
...
...
storage/innodb_plugin/log/log0log.c
View file @
1607f4aa
...
...
@@ -3085,12 +3085,13 @@ logs_empty_and_mark_files_at_shutdown(void)
goto
loop
;
}
/* Check that there are no longer transactions. We need this wait even
for the 'very fast' shutdown, because the InnoDB layer may have
committed or prepared transactions and we don't want to lose them. */
/* Check that there are no longer transactions, except for
PREPARED ones. We need this wait even for the 'very fast'
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
||
UT_LIST_GET_LEN
(
trx_sys
->
trx_list
)
>
0
)
{
||
UT_LIST_GET_LEN
(
trx_sys
->
trx_list
)
>
trx_n_prepared
)
{
mutex_exit
(
&
kernel_mutex
);
...
...
storage/innodb_plugin/trx/trx0sys.c
View file @
1607f4aa
...
...
@@ -37,6 +37,7 @@ Created 3/26/1996 Heikki Tuuri
#include "trx0rseg.h"
#include "trx0undo.h"
#include "srv0srv.h"
#include "srv0start.h"
#include "trx0purge.h"
#include "log0log.h"
#include "os0file.h"
...
...
@@ -1548,10 +1549,12 @@ void
trx_sys_close
(
void
)
/*===============*/
{
trx_t
*
trx
;
trx_rseg_t
*
rseg
;
read_view_t
*
view
;
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
by a purge. */
...
...
@@ -1583,6 +1586,13 @@ trx_sys_close(void)
mem_free
(
trx_doublewrite
);
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. */
rseg
=
UT_LIST_GET_FIRST
(
trx_sys
->
rseg_list
);
...
...
storage/innodb_plugin/trx/trx0trx.c
View file @
1607f4aa
...
...
@@ -50,6 +50,9 @@ UNIV_INTERN sess_t* trx_dummy_sess = NULL;
/** Number of transactions currently allocated for MySQL: protected by
the kernel mutex */
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. */
...
...
@@ -333,6 +336,60 @@ trx_free(
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. */
UNIV_INTERN
...
...
@@ -463,6 +520,7 @@ trx_lists_init_at_db_start(void)
if
(
srv_force_recovery
==
0
)
{
trx
->
conc_state
=
TRX_PREPARED
;
trx_n_prepared
++
;
}
else
{
fprintf
(
stderr
,
"InnoDB: Since"
...
...
@@ -541,6 +599,7 @@ trx_lists_init_at_db_start(void)
trx
->
conc_state
=
TRX_PREPARED
;
trx_n_prepared
++
;
}
else
{
fprintf
(
stderr
,
"InnoDB: Since"
...
...
@@ -820,6 +879,11 @@ trx_commit_off_kernel(
||
trx
->
conc_state
==
TRX_PREPARED
);
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
and makes its changes to data visible to other transactions.
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_n_prepared
++
;
/*--------------------------------------*/
if
(
lsn
)
{
...
...
@@ -2031,10 +2096,11 @@ trx_get_trx_by_xid(
while
(
trx
)
{
/* Compare two X/Open XA transaction id's: their
length should be the same and binary comparison
of gtrid_leng
ht
+bqual_length bytes should be
of gtrid_leng
th
+bqual_length bytes should be
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
->
bqual_length
==
trx
->
xid
.
bqual_length
&&
memcmp
(
xid
->
data
,
trx
->
xid
.
data
,
...
...
storage/innodb_plugin/trx/trx0undo.c
View file @
1607f4aa
...
...
@@ -36,6 +36,7 @@ Created 3/26/1996 Heikki Tuuri
#include "trx0rseg.h"
#include "trx0trx.h"
#include "srv0srv.h"
#include "srv0start.h"
#include "trx0rec.h"
#include "trx0purge.h"
...
...
@@ -1976,4 +1977,31 @@ trx_undo_insert_cleanup(
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 */
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment