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
892cec85
Commit
892cec85
authored
Nov 30, 2004
by
unknown
Browse files
Options
Browse Files
Download
Plain Diff
Merge marko@bk-internal.mysql.com:/home/bk/mysql-4.1
into hundin.mysql.fi:/home/marko/k/mysql-4.1
parents
668d61b9
795045d9
Changes
5
Hide whitespace changes
Inline
Side-by-side
Showing
5 changed files
with
203 additions
and
33 deletions
+203
-33
innobase/include/lock0lock.h
innobase/include/lock0lock.h
+24
-5
innobase/include/row0mysql.h
innobase/include/row0mysql.h
+3
-1
innobase/lock/lock0lock.c
innobase/lock/lock0lock.c
+122
-13
innobase/row/row0mysql.c
innobase/row/row0mysql.c
+3
-2
sql/ha_innodb.cc
sql/ha_innodb.cc
+51
-12
No files found.
innobase/include/lock0lock.h
View file @
892cec85
...
...
@@ -463,13 +463,32 @@ lock_rec_hash(
ulint
space
,
/* in: space */
ulint
page_no
);
/* in: page number */
/*************************************************************************
Gets the table covered by an IX table lock. */
Gets the source table of an ALTER TABLE transaction. The table must be
covered by an IX or IS table lock. */
dict_table_t
*
lock_get_ix_table
(
/*==============*/
/* out: the table covered by the lock */
lock_t
*
lock
);
/* in: table lock */
lock_get_src_table
(
/*===============*/
/* out: the source table of transaction,
if it is covered by an IX or IS table lock;
dest if there is no source table, and
NULL if the transaction is locking more than
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. */
...
...
innobase/include/row0mysql.h
View file @
892cec85
...
...
@@ -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 @
892cec85
...
...
@@ -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,128 @@ lock_get_wait(
return
(
FALSE
);
}
/*************************************************************************
Gets the source table of an ALTER TABLE transaction. The table must be
covered by an IX or IS table lock. */
dict_table_t
*
lock_get_src_table
(
/*===============*/
/* out: the source table of transaction,
if it is covered by an IX or IS table lock;
dest if there is no source table, and
NULL if the transaction is locking more than
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
*
src
;
lock_t
*
lock
;
src
=
NULL
;
*
mode
=
LOCK_NONE
;
for
(
lock
=
UT_LIST_GET_FIRST
(
trx
->
trx_locks
);
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
);
switch
(
lock_mode
)
{
case
LOCK_IX
:
case
LOCK_IS
:
if
(
*
mode
!=
LOCK_NONE
&&
*
mode
!=
lock_mode
)
{
/* There are multiple locks on src. */
return
(
NULL
);
}
*
mode
=
lock_mode
;
break
;
}
}
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
);
}
/*************************************************************************
Sets the wait flag of a lock and the back pointer in trx to lock. */
UNIV_INLINE
...
...
innobase/row/row0mysql.c
View file @
892cec85
...
...
@@ -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 @@ row_lock_table_for_mysql(
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 @
892cec85
...
...
@@ -2324,20 +2324,58 @@ 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
*
src_table
;
ibool
mode
;
num_write_row
=
0
;
/* 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
,
table
);
/* We will need an IX lock on the destination table. */
prebuilt
->
sql_stat_start
=
TRUE
;
/* 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 */
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
;
}
else
{
/* Ensure that there are no other table locks than
LOCK_IX and LOCK_AUTO_INC on the destination table. */
if
(
!
lock_is_table_exclusive
(
prebuilt
->
table
,
prebuilt
->
trx
))
{
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 table lock on the source table. */
row_lock_table_for_mysql
(
prebuilt
,
src_table
,
mode
);
/* We will need an IX lock on the destination table. */
prebuilt
->
sql_stat_start
=
TRUE
;
}
}
num_write_row
++
;
...
...
@@ -5015,7 +5053,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