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
a35a93aa
Commit
a35a93aa
authored
Nov 30, 2004
by
marko@hundin.mysql.fi
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
InnoDB: Allow ALTER TABLE to do intermediate COMMIT also when the table
contains auto_increment columns. (Bug #6633)
parent
2e7cb4d0
Changes
3
Show whitespace changes
Inline
Side-by-side
Showing
3 changed files
with
162 additions
and
61 deletions
+162
-61
innobase/include/lock0lock.h
innobase/include/lock0lock.h
+24
-9
innobase/lock/lock0lock.c
innobase/lock/lock0lock.c
+111
-28
sql/ha_innodb.cc
sql/ha_innodb.cc
+27
-24
No files found.
innobase/include/lock0lock.h
View file @
a35a93aa
...
@@ -463,17 +463,32 @@ lock_rec_hash(
...
@@ -463,17 +463,32 @@ lock_rec_hash(
ulint
space
,
/* in: space */
ulint
space
,
/* in: space */
ulint
page_no
);
/* in: page number */
ulint
page_no
);
/* in: page number */
/*************************************************************************
/*************************************************************************
Gets the
table covered by an IX or IS table lock, if there are no
Gets the
source table of an ALTER TABLE transaction. The table must be
other locks on the table
. */
covered by an IX or IS table lock
. */
dict_table_t
*
dict_table_t
*
lock_get_table
(
lock_get_src_table
(
/*===========*/
/*===============*/
/* out: the table covered by the lock,
/* out: the source table of transaction,
or NULL if it is not an IX or IS table lock,
if it is covered by an IX or IS table lock;
or there are other locks on the table */
dest if there is no source table, and
lock_t
*
lock
,
/* in: lock */
NULL if the transaction is locking more than
ulint
*
mode
);
/* out: lock mode of table */
two tables or an inconsistency is found */
trx_t
*
trx
,
/* in: transaction */
dict_table_t
*
dest
,
/* in: destination of ALTER TABLE */
ulint
*
mode
);
/* out: lock mode of the source table */
/*************************************************************************
Determine if the given table is exclusively "owned" by the given
transaction, i.e., transaction holds LOCK_IX and possibly LOCK_AUTO_INC
on the table. */
ibool
lock_table_exclusive
(
/*=================*/
/* out: TRUE if table is only locked by trx,
with LOCK_IX, and possibly LOCK_AUTO_INC */
dict_table_t
*
table
,
/* in: table */
trx_t
*
trx
);
/* in: transaction */
/*************************************************************************
/*************************************************************************
Checks that a transaction id is sensible, i.e., not in the future. */
Checks that a transaction id is sensible, i.e., not in the future. */
...
...
innobase/lock/lock0lock.c
View file @
a35a93aa
...
@@ -602,42 +602,125 @@ lock_get_wait(
...
@@ -602,42 +602,125 @@ lock_get_wait(
}
}
/*************************************************************************
/*************************************************************************
Gets the
table covered by an IX or IS table lock, if there are no
Gets the
source table of an ALTER TABLE transaction. The table must be
other locks on the table
. */
covered by an IX or IS table lock
. */
dict_table_t
*
dict_table_t
*
lock_get_table
(
lock_get_src_table
(
/*===========*/
/*===============*/
/* out: the table covered by the lock,
/* out: the source table of transaction,
or NULL if it is not an IX or IS table lock,
if it is covered by an IX or IS table lock;
or there are other locks on the table */
dest if there is no source table, and
lock_t
*
lock
,
/* in: lock */
NULL if the transaction is locking more than
ulint
*
mode
)
/* out: lock mode of table */
two tables or an inconsistency is found */
trx_t
*
trx
,
/* in: transaction */
dict_table_t
*
dest
,
/* in: destination of ALTER TABLE */
ulint
*
mode
)
/* out: lock mode of the source table */
{
{
dict_table_t
*
table
;
dict_table_t
*
src
;
ulint
lock_mode
;
lock_t
*
lock
;
table
=
NULL
;
src
=
NULL
;
*
mode
=
LOCK_NONE
;
*
mode
=
LOCK_NONE
;
if
(
lock_get_type
(
lock
)
!=
LOCK_TABLE
)
{
for
(
lock
=
UT_LIST_GET_FIRST
(
trx
->
trx_locks
);
return
(
table
);
lock
;
lock
=
UT_LIST_GET_NEXT
(
trx_locks
,
lock
))
{
lock_table_t
*
tab_lock
;
ulint
lock_mode
;
if
(
!
(
lock_get_type
(
lock
)
&
LOCK_TABLE
))
{
/* We are only interested in table locks. */
continue
;
}
tab_lock
=
&
lock
->
un_member
.
tab_lock
;
if
(
dest
==
tab_lock
->
table
)
{
/* We are not interested in the destination table. */
continue
;
}
else
if
(
!
src
)
{
/* This presumably is the source table. */
src
=
tab_lock
->
table
;
if
(
UT_LIST_GET_LEN
(
src
->
locks
)
!=
1
||
UT_LIST_GET_FIRST
(
src
->
locks
)
!=
lock
)
{
/* We only support the case when
there is only one lock on this table. */
return
(
NULL
);
}
}
else
if
(
src
!=
tab_lock
->
table
)
{
/* The transaction is locking more than
two tables (src and dest): abort */
return
(
NULL
);
}
}
/* Check that the source table is locked by
LOCK_IX or LOCK_IS. */
lock_mode
=
lock_get_mode
(
lock
);
lock_mode
=
lock_get_mode
(
lock
);
switch
(
lock_mode
)
{
switch
(
lock_mode
)
{
case
LOCK_IS
:
case
LOCK_IX
:
case
LOCK_IX
:
case
LOCK_IS
:
if
(
*
mode
!=
LOCK_NONE
&&
*
mode
!=
lock_mode
)
{
/* There are multiple locks on src. */
return
(
NULL
);
}
*
mode
=
lock_mode
;
*
mode
=
lock_mode
;
table
=
lock
->
un_member
.
tab_lock
.
table
;
break
;
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
);
if
(
!
src
)
{
/* No source table lock found: flag the situation to caller */
src
=
dest
;
}
return
(
src
);
}
/*************************************************************************
Determine if the given table is exclusively "owned" by the given
transaction, i.e., transaction holds LOCK_IX and possibly LOCK_AUTO_INC
on the table. */
ibool
lock_is_table_exclusive
(
/*====================*/
/* out: TRUE if table is only locked by trx,
with LOCK_IX, and possibly LOCK_AUTO_INC */
dict_table_t
*
table
,
/* in: table */
trx_t
*
trx
)
/* in: transaction */
{
lock_t
*
lock
;
bool
ok
=
FALSE
;
ut_ad
(
table
&&
trx
);
for
(
lock
=
UT_LIST_GET_FIRST
(
table
->
locks
);
lock
;
lock
=
UT_LIST_GET_NEXT
(
locks
,
&
lock
->
un_member
.
tab_lock
))
{
if
(
lock
->
trx
!=
trx
)
{
/* A lock on the table is held
by some other transaction. */
return
(
FALSE
);
}
if
(
!
(
lock_get_type
(
lock
)
&
LOCK_TABLE
))
{
/* We are interested in table locks only. */
continue
;
}
switch
(
lock_get_mode
(
lock
))
{
case
LOCK_IX
:
ok
=
TRUE
;
break
;
case
LOCK_AUTO_INC
:
/* It is allowed for trx to hold an
auto_increment lock. */
break
;
default:
/* Other table locks than LOCK_IX are not allowed. */
return
(
FALSE
);
}
}
return
(
ok
);
}
}
/*************************************************************************
/*************************************************************************
...
...
sql/ha_innodb.cc
View file @
a35a93aa
...
@@ -2325,29 +2325,44 @@ ha_innobase::write_row(
...
@@ -2325,29 +2325,44 @@ ha_innobase::write_row(
intermediate COMMIT, since writes by other transactions are
intermediate COMMIT, since writes by other transactions are
being blocked by a MySQL table lock TL_WRITE_ALLOW_READ. */
being blocked by a MySQL table lock TL_WRITE_ALLOW_READ. */
dict_table_t
*
table
;
dict_table_t
*
src_
table
;
ibool
mode
;
ibool
mode
;
num_write_row
=
0
;
num_write_row
=
0
;
/* Commit the transaction. This will release the table
/* Commit the transaction. This will release the table
locks, so they have to be acquired again. */
locks, so they have to be acquired again. */
switch
(
prebuilt
->
trx
->
mysql_n_tables_locked
)
{
case
1
:
/* Altering an InnoDB table */
/* Get the source table. */
src_table
=
lock_get_src_table
(
prebuilt
->
trx
,
prebuilt
->
table
,
&
mode
);
if
(
!
src_table
)
{
no_commit:
/* Unknown situation: do not commit */
/*
ut_print_timestamp(stderr);
fprintf(stderr,
" InnoDB error: ALTER TABLE is holding lock"
" on %lu tables!\n",
prebuilt->trx->mysql_n_tables_locked);
*/
;
}
else
if
(
src_table
==
prebuilt
->
table
)
{
/* Source table is not in InnoDB format:
no need to re-acquire locks on it. */
/* Altering to InnoDB format */
/* Altering to InnoDB format */
innobase_commit
(
user_thd
,
prebuilt
->
trx
);
innobase_commit
(
user_thd
,
prebuilt
->
trx
);
/* Note that this transaction is still active. */
/* Note that this transaction is still active. */
user_thd
->
transaction
.
all
.
innodb_active_trans
=
1
;
user_thd
->
transaction
.
all
.
innodb_active_trans
=
1
;
/* We will need an IX lock on the destination table. */
/* We will need an IX lock on the destination table. */
prebuilt
->
sql_stat_start
=
TRUE
;
prebuilt
->
sql_stat_start
=
TRUE
;
break
;
}
else
{
case
2
:
/* Ensure that there are no other table locks than
/* Altering an InnoDB table */
LOCK_IX and LOCK_AUTO_INC on the destination table. */
ut_a
(
UT_LIST_GET_LEN
(
prebuilt
->
trx
->
trx_locks
)
>=
2
);
if
(
!
lock_is_table_exclusive
(
prebuilt
->
table
,
table
=
lock_get_table
(
prebuilt
->
trx
))
{
UT_LIST_GET_FIRST
(
prebuilt
->
trx
->
trx_locks
),
&
mode
);
if
(
!
table
)
{
goto
no_commit
;
goto
no_commit
;
}
}
...
@@ -2357,21 +2372,9 @@ ha_innobase::write_row(
...
@@ -2357,21 +2372,9 @@ ha_innobase::write_row(
/* Note that this transaction is still active. */
/* Note that this transaction is still active. */
user_thd
->
transaction
.
all
.
innodb_active_trans
=
1
;
user_thd
->
transaction
.
all
.
innodb_active_trans
=
1
;
/* Re-acquire the table lock on the source table. */
/* Re-acquire the table lock on the source table. */
row_lock_table_for_mysql
(
prebuilt
,
table
,
mode
);
row_lock_table_for_mysql
(
prebuilt
,
src_
table
,
mode
);
/* We will need an IX lock on the destination table. */
/* We will need an IX lock on the destination table. */
prebuilt
->
sql_stat_start
=
TRUE
;
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
;
}
}
}
}
...
...
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