diff options
author | unknown <marko@hundin.mysql.fi> | 2004-11-30 17:50:56 +0200 |
---|---|---|
committer | unknown <marko@hundin.mysql.fi> | 2004-11-30 17:50:56 +0200 |
commit | 892cec855512e271fbffc66439fc3b3b06140e2a (patch) | |
tree | 11ac976879496b8b599ebaa8f1a4927c5fe26b29 /innobase | |
parent | 668d61b946d6487829c28a2860ecff7df7637d09 (diff) | |
parent | 795045d9a01ac816360c1477625713beaad429cc (diff) | |
download | mariadb-git-892cec855512e271fbffc66439fc3b3b06140e2a.tar.gz |
Merge marko@bk-internal.mysql.com:/home/bk/mysql-4.1
into hundin.mysql.fi:/home/marko/k/mysql-4.1
Diffstat (limited to 'innobase')
-rw-r--r-- | innobase/include/lock0lock.h | 29 | ||||
-rw-r--r-- | innobase/include/row0mysql.h | 4 | ||||
-rw-r--r-- | innobase/lock/lock0lock.c | 135 | ||||
-rw-r--r-- | innobase/row/row0mysql.c | 5 |
4 files changed, 152 insertions, 21 deletions
diff --git a/innobase/include/lock0lock.h b/innobase/include/lock0lock.h index f8435e14d97..ff5b6aae02e 100644 --- a/innobase/include/lock0lock.h +++ b/innobase/include/lock0lock.h @@ -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. */ diff --git a/innobase/include/row0mysql.h b/innobase/include/row0mysql.h index 73f41dea0da..f47ce74ce37 100644 --- a/innobase/include/row0mysql.h +++ b/innobase/include/row0mysql.h @@ -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. */ diff --git a/innobase/lock/lock0lock.c b/innobase/lock/lock0lock.c index 78a78c9dd95..16c4ddfd96d 100644 --- a/innobase/lock/lock0lock.c +++ b/innobase/lock/lock0lock.c @@ -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) @@ -615,6 +602,128 @@ lock_get_wait( } /************************************************************************* +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 void diff --git a/innobase/row/row0mysql.c b/innobase/row/row0mysql.c index 9613da2e286..dec2b19559c 100644 --- a/innobase/row/row0mysql.c +++ b/innobase/row/row0mysql.c @@ -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); |