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
Analytics
Analytics
Repository
Value Stream
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Create a new issue
Commits
Issue Boards
Open sidebar
Kirill Smelkov
mariadb
Commits
2e7cb4d0
Commit
2e7cb4d0
authored
Nov 27, 2004
by
marko@hundin.mysql.fi
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
InnoDB: Make intermediate COMMITs in ALTER TABLE more robust (Bug #6633)
parent
19dab118
Changes
5
Show whitespace changes
Inline
Side-by-side
Showing
5 changed files
with
102 additions
and
33 deletions
+102
-33
innobase/include/lock0lock.h
innobase/include/lock0lock.h
+9
-5
innobase/include/row0mysql.h
innobase/include/row0mysql.h
+3
-1
innobase/lock/lock0lock.c
innobase/lock/lock0lock.c
+39
-13
innobase/row/row0mysql.c
innobase/row/row0mysql.c
+3
-2
sql/ha_innodb.cc
sql/ha_innodb.cc
+48
-12
No files found.
innobase/include/lock0lock.h
View file @
2e7cb4d0
...
...
@@ -463,13 +463,17 @@ lock_rec_hash(
ulint
space
,
/* in: space */
ulint
page_no
);
/* in: page number */
/*************************************************************************
Gets the table covered by an IX table lock. */
Gets the table covered by an IX or IS table lock, if there are no
other locks on the table. */
dict_table_t
*
lock_get_ix_table
(
/*==============*/
/* out: the table covered by the lock */
lock_t
*
lock
);
/* in: table lock */
lock_get_table
(
/*===========*/
/* out: the table covered by the lock,
or NULL if it is not an IX or IS table lock,
or there are other locks on the table */
lock_t
*
lock
,
/* in: lock */
ulint
*
mode
);
/* out: lock mode of table */
/*************************************************************************
Checks that a transaction id is sensible, i.e., not in the future. */
...
...
innobase/include/row0mysql.h
View file @
2e7cb4d0
...
...
@@ -177,10 +177,12 @@ row_lock_table_for_mysql(
/* out: error code or DB_SUCCESS */
row_prebuilt_t
*
prebuilt
,
/* in: prebuilt struct in the MySQL
table handle */
dict_table_t
*
table
);
/* in: table to LOCK_IX
, or NULL
dict_table_t
*
table
,
/* in: table to lock
, or NULL
if prebuilt->table should be
locked as LOCK_TABLE_EXP |
prebuilt->select_lock_type */
ulint
mode
);
/* in: lock mode of table */
/*************************************************************************
Does an insert for MySQL. */
...
...
innobase/lock/lock0lock.c
View file @
2e7cb4d0
...
...
@@ -395,19 +395,6 @@ lock_rec_get_nth_bit(
return
(
ut_bit_get_nth
(
b
,
bit_index
));
}
/*************************************************************************
Gets the table covered by an IX table lock. */
dict_table_t
*
lock_get_ix_table
(
/*==============*/
/* out: the table covered by the lock */
lock_t
*
lock
)
/* in: table lock */
{
ut_a
(
lock
->
type_mode
==
(
LOCK_TABLE
|
LOCK_IX
));
return
(
lock
->
un_member
.
tab_lock
.
table
);
}
/*************************************************************************/
#define lock_mutex_enter_kernel() mutex_enter(&kernel_mutex)
...
...
@@ -614,6 +601,45 @@ lock_get_wait(
return
(
FALSE
);
}
/*************************************************************************
Gets the table covered by an IX or IS table lock, if there are no
other locks on the table. */
dict_table_t
*
lock_get_table
(
/*===========*/
/* out: the table covered by the lock,
or NULL if it is not an IX or IS table lock,
or there are other locks on the table */
lock_t
*
lock
,
/* in: lock */
ulint
*
mode
)
/* out: lock mode of table */
{
dict_table_t
*
table
;
ulint
lock_mode
;
table
=
NULL
;
*
mode
=
LOCK_NONE
;
if
(
lock_get_type
(
lock
)
!=
LOCK_TABLE
)
{
return
(
table
);
}
lock_mode
=
lock_get_mode
(
lock
);
switch
(
lock_mode
)
{
case
LOCK_IS
:
case
LOCK_IX
:
*
mode
=
lock_mode
;
table
=
lock
->
un_member
.
tab_lock
.
table
;
if
(
UT_LIST_GET_LEN
(
table
->
locks
)
!=
1
||
UT_LIST_GET_FIRST
(
table
->
locks
)
!=
lock
)
{
/* We only support the case when
there is only one lock on this table. */
table
=
NULL
;
}
}
return
(
table
);
}
/*************************************************************************
Sets the wait flag of a lock and the back pointer in trx to lock. */
UNIV_INLINE
...
...
innobase/row/row0mysql.c
View file @
2e7cb4d0
...
...
@@ -782,10 +782,11 @@ row_lock_table_for_mysql(
/* out: error code or DB_SUCCESS */
row_prebuilt_t
*
prebuilt
,
/* in: prebuilt struct in the MySQL
table handle */
dict_table_t
*
table
)
/* in: table to LOCK_IX
, or NULL
dict_table_t
*
table
,
/* in: table to lock
, or NULL
if prebuilt->table should be
locked as LOCK_TABLE_EXP |
prebuilt->select_lock_type */
ulint
mode
)
/* in: lock mode of table */
{
trx_t
*
trx
=
prebuilt
->
trx
;
que_thr_t
*
thr
;
...
...
@@ -819,7 +820,7 @@ run_again:
trx_start_if_not_started
(
trx
);
if
(
table
)
{
err
=
lock_table
(
0
,
table
,
LOCK_IX
,
thr
);
err
=
lock_table
(
0
,
table
,
mode
,
thr
);
}
else
{
err
=
lock_table
(
LOCK_TABLE_EXP
,
prebuilt
->
table
,
prebuilt
->
select_lock_type
,
thr
);
...
...
sql/ha_innodb.cc
View file @
2e7cb4d0
...
...
@@ -2324,20 +2324,55 @@ ha_innobase::write_row(
position in the source table need not be adjusted after the
intermediate COMMIT, since writes by other transactions are
being blocked by a MySQL table lock TL_WRITE_ALLOW_READ. */
ut_a
(
prebuilt
->
trx
->
mysql_n_tables_locked
==
2
);
ut_a
(
UT_LIST_GET_LEN
(
prebuilt
->
trx
->
trx_locks
)
>=
2
)
;
dict_table_t
*
table
=
lock_get_ix_table
(
UT_LIST_GET_FIRST
(
prebuilt
->
trx
->
trx_locks
));
dict_table_t
*
table
;
ibool
mode
;
num_write_row
=
0
;
/* Commit the transaction. This will release the table
locks, so they have to be acquired again. */
switch
(
prebuilt
->
trx
->
mysql_n_tables_locked
)
{
case
1
:
/* Altering to InnoDB format */
innobase_commit
(
user_thd
,
prebuilt
->
trx
);
/* Note that this transaction is still active. */
user_thd
->
transaction
.
all
.
innodb_active_trans
=
1
;
/* We will need an IX lock on the destination table. */
prebuilt
->
sql_stat_start
=
TRUE
;
break
;
case
2
:
/* Altering an InnoDB table */
ut_a
(
UT_LIST_GET_LEN
(
prebuilt
->
trx
->
trx_locks
)
>=
2
);
table
=
lock_get_table
(
UT_LIST_GET_FIRST
(
prebuilt
->
trx
->
trx_locks
),
&
mode
);
if
(
!
table
)
{
goto
no_commit
;
}
/* Commit the transaction. This will release the table
locks, so they have to be acquired again. */
innobase_commit
(
user_thd
,
prebuilt
->
trx
);
/* Note that this transaction is still active. */
user_thd
->
transaction
.
all
.
innodb_active_trans
=
1
;
/* Re-acquire the IX
table lock on the source table. */
row_lock_table_for_mysql
(
prebuilt
,
tabl
e
);
/* Re-acquire the
table lock on the source table. */
row_lock_table_for_mysql
(
prebuilt
,
table
,
mod
e
);
/* We will need an IX lock on the destination table. */
prebuilt
->
sql_stat_start
=
TRUE
;
break
;
default:
no_commit:
/* Unknown situation: do nothing (no commit) */
/*
ut_print_timestamp(stderr);
fprintf(stderr,
" InnoDB error: ALTER TABLE is holding lock"
" on %lu tables!\n",
prebuilt->trx->mysql_n_tables_locked);
*/
break
;
}
}
num_write_row
++
;
...
...
@@ -5015,7 +5050,8 @@ ha_innobase::external_lock(
if
(
thd
->
in_lock_tables
&&
thd
->
variables
.
innodb_table_locks
)
{
ulint
error
;
error
=
row_lock_table_for_mysql
(
prebuilt
,
0
);
error
=
row_lock_table_for_mysql
(
prebuilt
,
NULL
,
LOCK_TABLE_EXP
);
if
(
error
!=
DB_SUCCESS
)
{
error
=
convert_error_code_to_mysql
(
...
...
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