summaryrefslogtreecommitdiff
path: root/innobase
diff options
context:
space:
mode:
authorunknown <brian@avenger.(none)>2004-11-30 10:10:40 -0800
committerunknown <brian@avenger.(none)>2004-11-30 10:10:40 -0800
commit9ada34b3162d4650e8cbe11c705fd30a98981bd2 (patch)
tree1f0afa7d9329a51b6fd4a5de7db6fbe43b47d328 /innobase
parent409debfa14baf9a493edc9dd45364a7334d492f6 (diff)
parentbe733ad13f5f6c196e9cd465cd32baf3e2faa75b (diff)
downloadmariadb-git-9ada34b3162d4650e8cbe11c705fd30a98981bd2.tar.gz
Merge for Matt for Innodb bug.
client/mysqldump.c: Auto merged innobase/include/row0mysql.h: Auto merged innobase/lock/lock0lock.c: Auto merged innobase/row/row0mysql.c: Auto merged innobase/row/row0sel.c: Auto merged mysql-test/r/mysqldump.result: Auto merged mysql-test/r/ndb_index_unique.result: Auto merged mysql-test/r/rpl_start_stop_slave.result: Auto merged mysql-test/t/mysqldump.test: Auto merged mysql-test/t/ndb_grant.later: Auto merged mysql-test/t/ndb_index_unique.test: Auto merged ndb/include/ndbapi/NdbScanOperation.hpp: Auto merged ndb/src/ndbapi/NdbScanOperation.cpp: Auto merged ndb/test/ndbapi/testScanPerf.cpp: Auto merged netware/comp_err.def: Auto merged netware/isamchk.def: Auto merged netware/isamlog.def: Auto merged netware/libmysql.def: Auto merged netware/my_print_defaults.def: Auto merged netware/myisam_ftdump.def: Auto merged netware/myisamchk.def: Auto merged netware/myisamlog.def: Auto merged netware/myisampack.def: Auto merged netware/mysql.def: Auto merged netware/mysql_install.def: Auto merged netware/mysql_install_db.def: Auto merged netware/mysql_test_run.def: Auto merged netware/mysql_waitpid.def: Auto merged netware/mysqladmin.def: Auto merged netware/mysqlbinlog.def: Auto merged netware/mysqlcheck.def: Auto merged netware/mysqld.def: Auto merged netware/mysqld_safe.def: Auto merged netware/mysqldump.def: Auto merged netware/mysqlimport.def: Auto merged netware/mysqlshow.def: Auto merged netware/mysqltest.def: Auto merged netware/pack_isam.def: Auto merged netware/perror.def: Auto merged netware/replace.def: Auto merged netware/resolve_stack_dump.def: Auto merged netware/resolveip.def: Auto merged sql/ha_innodb.cc: Auto merged sql/ha_ndbcluster.cc: Auto merged client/mysqladmin.cc: Merge for Netware changes. Indention fixes. sql/field.cc: Merge fixes, warnings added from 4.1 to 5.0 sql/mysqld.cc: Merge fixes, just indention fixes.
Diffstat (limited to 'innobase')
-rw-r--r--innobase/include/lock0lock.h29
-rw-r--r--innobase/include/row0mysql.h4
-rw-r--r--innobase/lock/lock0lock.c164
-rw-r--r--innobase/row/row0mysql.c5
-rw-r--r--innobase/row/row0sel.c1
5 files changed, 168 insertions, 35 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 d4634482752..ea6d26b46fa 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 479952235f0..32a6bcadecc 100644
--- a/innobase/lock/lock0lock.c
+++ b/innobase/lock/lock0lock.c
@@ -365,6 +365,21 @@ lock_deadlock_recursive(
ulint* cost); /* in/out: number of calculation steps thus
far: if this exceeds LOCK_MAX_N_STEPS_...
we return TRUE */
+
+/*************************************************************************
+Gets the type of a lock. */
+UNIV_INLINE
+ulint
+lock_get_type(
+/*==========*/
+ /* out: LOCK_TABLE or LOCK_REC */
+ lock_t* lock) /* in: lock */
+{
+ ut_ad(lock);
+
+ return(lock->type_mode & LOCK_TYPE_MASK);
+}
+
/*************************************************************************
Gets the nth bit of a record lock. */
UNIV_INLINE
@@ -395,19 +410,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)
@@ -582,20 +584,6 @@ lock_get_mode(
}
/*************************************************************************
-Gets the type of a lock. */
-UNIV_INLINE
-ulint
-lock_get_type(
-/*==========*/
- /* out: LOCK_TABLE or LOCK_REC */
- lock_t* lock) /* in: lock */
-{
- ut_ad(lock);
-
- return(lock->type_mode & LOCK_TYPE_MASK);
-}
-
-/*************************************************************************
Gets the wait flag of a lock. */
UNIV_INLINE
ibool
@@ -615,6 +603,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 0de4b189493..adf9d6695bc 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);
diff --git a/innobase/row/row0sel.c b/innobase/row/row0sel.c
index 27470df81c5..d3b834dd866 100644
--- a/innobase/row/row0sel.c
+++ b/innobase/row/row0sel.c
@@ -31,6 +31,7 @@ Created 12/19/1997 Heikki Tuuri
#include "pars0pars.h"
#include "row0mysql.h"
#include "read0read.h"
+#include "buf0lru.h"
/* Maximum number of rows to prefetch; MySQL interface has another parameter */
#define SEL_MAX_N_PREFETCH 16