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
460a7197
Commit
460a7197
authored
Apr 11, 2011
by
Marko Mäkelä
Browse files
Options
Browse Files
Download
Plain Diff
Merge mysql-5.1-innodb to mysql-5.5-innodb.
parents
3dc70ced
12fbe05c
Changes
13
Hide whitespace changes
Inline
Side-by-side
Showing
13 changed files
with
330 additions
and
83 deletions
+330
-83
client/mysqltest.cc
client/mysqltest.cc
+7
-5
mysql-test/suite/innodb/r/innodb_bug59641.result
mysql-test/suite/innodb/r/innodb_bug59641.result
+57
-0
mysql-test/suite/innodb/t/innodb_bug59641.test
mysql-test/suite/innodb/t/innodb_bug59641.test
+66
-0
sql/sql_class.cc
sql/sql_class.cc
+1
-0
storage/innobase/handler/ha_innodb.cc
storage/innobase/handler/ha_innodb.cc
+44
-44
storage/innobase/handler/ha_innodb.h
storage/innobase/handler/ha_innodb.h
+5
-6
storage/innobase/handler/handler0alter.cc
storage/innobase/handler/handler0alter.cc
+20
-23
storage/innobase/include/trx0trx.h
storage/innobase/include/trx0trx.h
+11
-0
storage/innobase/include/trx0undo.h
storage/innobase/include/trx0undo.h
+9
-0
storage/innobase/log/log0log.c
storage/innobase/log/log0log.c
+5
-4
storage/innobase/trx/trx0sys.c
storage/innobase/trx/trx0sys.c
+10
-0
storage/innobase/trx/trx0trx.c
storage/innobase/trx/trx0trx.c
+67
-1
storage/innobase/trx/trx0undo.c
storage/innobase/trx/trx0undo.c
+28
-0
No files found.
client/mysqltest.cc
View file @
460a7197
...
@@ -4598,13 +4598,14 @@ static int my_kill(int pid, int sig)
...
@@ -4598,13 +4598,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
;
...
@@ -4619,8 +4620,9 @@ void do_shutdown_server(struct st_command *command)
...
@@ -4619,8 +4620,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
);
...
@@ -4662,7 +4664,7 @@ void do_shutdown_server(struct st_command *command)
...
@@ -4662,7 +4664,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: %
l
d"
,
timeout
));
my_sleep
(
1000000L
);
my_sleep
(
1000000L
);
}
}
...
...
mysql-test/suite/innodb/r/innodb_bug59641.result
0 → 100644
View file @
460a7197
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_bug59641.test
0 → 100644
View file @
460a7197
# 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
;
sql/sql_class.cc
View file @
460a7197
...
@@ -3675,6 +3675,7 @@ bool xid_cache_insert(XID *xid, enum xa_states xa_state)
...
@@ -3675,6 +3675,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
);
}
}
mysql_mutex_unlock
(
&
LOCK_xid_cache
);
mysql_mutex_unlock
(
&
LOCK_xid_cache
);
...
...
storage/innobase/handler/ha_innodb.cc
View file @
460a7197
...
@@ -6244,10 +6244,6 @@ create_table_def(
...
@@ -6244,10 +6244,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 */
...
@@ -6368,6 +6364,8 @@ create_table_def(
...
@@ -6368,6 +6364,8 @@ create_table_def(
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
)
{
...
@@ -6784,38 +6782,17 @@ ha_innobase::create(
...
@@ -6784,38 +6782,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
);
srv_lower_case_table_names
=
lower_case_table_names
;
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
)
{
...
@@ -6957,16 +6934,37 @@ ha_innobase::create(
...
@@ -6957,16 +6934,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
(
t
rx
,
form
->
key_info
,
if
(
innobase_index_name_is_reserved
(
t
hd
,
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
);
...
@@ -7221,14 +7219,14 @@ ha_innobase::delete_table(
...
@@ -7221,14 +7219,14 @@ ha_innobase::delete_table(
trx
=
innobase_trx_allocate
(
thd
);
trx
=
innobase_trx_allocate
(
thd
);
srv_lower_case_table_names
=
lower_case_table_names
;
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
);
...
@@ -7344,8 +7342,6 @@ innobase_rename_table(
...
@@ -7344,8 +7342,6 @@ innobase_rename_table(
char
*
norm_to
;
char
*
norm_to
;
char
*
norm_from
;
char
*
norm_from
;
srv_lower_case_table_names
=
lower_case_table_names
;
// 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
));
...
@@ -7360,6 +7356,8 @@ innobase_rename_table(
...
@@ -7360,6 +7356,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
);
...
@@ -10265,7 +10263,7 @@ innobase_commit_by_xid(
...
@@ -10265,7 +10263,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
);
...
@@ -10291,7 +10289,9 @@ innobase_rollback_by_xid(
...
@@ -10291,7 +10289,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
);
}
}
...
@@ -10924,19 +10924,19 @@ static int show_innodb_vars(THD *thd, SHOW_VAR *var, char *buff)
...
@@ -10924,19 +10924,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
;
...
@@ -10948,7 +10948,7 @@ innobase_index_name_is_reserved(
...
@@ -10948,7 +10948,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 "
...
...
storage/innobase/handler/ha_innodb.h
View file @
460a7197
...
@@ -321,15 +321,14 @@ innobase_trx_allocate(
...
@@ -321,15 +321,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. */
storage/innobase/handler/handler0alter.cc
View file @
460a7197
...
@@ -653,44 +653,37 @@ ha_innobase::add_index(
...
@@ -653,44 +653,37 @@ 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
);
trx_start_if_not_started
(
prebuilt
->
trx
);
/* C
reate a background transaction for the operations on
/* C
heck if the index name is reserved. */
the data dictionary tables. */
if
(
innobase_index_name_is_reserved
(
user_thd
,
key_info
,
num_of_keys
))
{
trx
=
innobase_trx_allocate
(
user_thd
);
DBUG_RETURN
(
-
1
);
trx_start_if_not_started
(
trx
);
}
innodb_table
=
indexed_table
innodb_table
=
indexed_table
=
dict_table_get
(
prebuilt
->
table
->
name
,
FALSE
);
=
dict_table_get
(
prebuilt
->
table
->
name
,
FALSE
);
if
(
UNIV_UNLIKELY
(
!
innodb_table
))
{
if
(
UNIV_UNLIKELY
(
!
innodb_table
))
{
error
=
HA_ERR_NO_SUCH_TABLE
;
DBUG_RETURN
(
HA_ERR_NO_SUCH_TABLE
);
goto
err_exit
;
}
}
/* Check if the index name is reserved. */
/* Check that index keys are sensible */
if
(
innobase_index_name_is_reserved
(
trx
,
key_info
,
num_of_keys
))
{
error
=
innobase_check_index_keys
(
key_info
,
num_of_keys
,
innodb_table
);
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
))
{
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
);
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
/* 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. */
...
@@ -762,8 +755,12 @@ ha_innobase::add_index(
...
@@ -762,8 +755,12 @@ ha_innobase::add_index(
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
;
...
...
storage/innobase/include/trx0trx.h
View file @
460a7197
...
@@ -44,6 +44,9 @@ extern sess_t* trx_dummy_sess;
...
@@ -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(
...
@@ -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 */
UNIV_COLD
__attribute__
((
nonnull
));
/********************************************************************//**
Frees a transaction object for MySQL. */
Frees a transaction object for MySQL. */
UNIV_INTERN
UNIV_INTERN
void
void
...
...
storage/innobase/include/trx0undo.h
View file @
460a7197
...
@@ -296,6 +296,15 @@ void
...
@@ -296,6 +296,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 */
UNIV_COLD
__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.
...
...
storage/innobase/log/log0log.c
View file @
460a7197
...
@@ -3109,12 +3109,13 @@ logs_empty_and_mark_files_at_shutdown(void)
...
@@ -3109,12 +3109,13 @@ logs_empty_and_mark_files_at_shutdown(void)
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. */
server_busy
=
trx_n_mysql_transactions
>
0
server_busy
=
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
);
if
(
server_busy
||
srv_is_any_background_thread_active
())
{
if
(
server_busy
||
srv_is_any_background_thread_active
())
{
...
...
storage/innobase/trx/trx0sys.c
View file @
460a7197
...
@@ -37,6 +37,7 @@ Created 3/26/1996 Heikki Tuuri
...
@@ -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 "log0recv.h"
#include "log0recv.h"
...
@@ -1617,10 +1618,12 @@ void
...
@@ -1617,10 +1618,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. */
...
@@ -1652,6 +1655,13 @@ trx_sys_close(void)
...
@@ -1652,6 +1655,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
);
...
...
storage/innobase/trx/trx0trx.c
View file @
460a7197
...
@@ -50,6 +50,9 @@ UNIV_INTERN sess_t* trx_dummy_sess = NULL;
...
@@ -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
;
#ifdef UNIV_PFS_MUTEX
#ifdef UNIV_PFS_MUTEX
/* Key to register the mutex with performance schema */
/* Key to register the mutex with performance schema */
...
@@ -337,6 +340,60 @@ trx_free(
...
@@ -337,6 +340,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
...
@@ -467,6 +524,7 @@ trx_lists_init_at_db_start(void)
...
@@ -467,6 +524,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"
...
@@ -543,6 +601,7 @@ trx_lists_init_at_db_start(void)
...
@@ -543,6 +601,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"
...
@@ -877,6 +936,11 @@ trx_commit_off_kernel(
...
@@ -877,6 +936,11 @@ trx_commit_off_kernel(
ut_ad
(
trx
->
conc_state
==
TRX_ACTIVE
||
trx
->
conc_state
==
TRX_PREPARED
);
ut_ad
(
trx
->
conc_state
==
TRX_ACTIVE
||
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
...
@@ -1901,6 +1965,7 @@ trx_prepare_off_kernel(
...
@@ -1901,6 +1965,7 @@ trx_prepare_off_kernel(
/*--------------------------------------*/
/*--------------------------------------*/
trx
->
conc_state
=
TRX_PREPARED
;
trx
->
conc_state
=
TRX_PREPARED
;
trx_n_prepared
++
;
/*--------------------------------------*/
/*--------------------------------------*/
if
(
lsn
)
{
if
(
lsn
)
{
...
@@ -2077,7 +2142,8 @@ trx_get_trx_by_xid(
...
@@ -2077,7 +2142,8 @@ trx_get_trx_by_xid(
of gtrid_length+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
,
...
...
storage/innobase/trx/trx0undo.c
View file @
460a7197
...
@@ -36,6 +36,7 @@ Created 3/26/1996 Heikki Tuuri
...
@@ -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"
...
@@ -1975,4 +1976,31 @@ trx_undo_insert_cleanup(
...
@@ -1975,4 +1976,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 */
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