summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorunknown <marko@hundin.mysql.fi>2004-11-04 18:25:48 +0200
committerunknown <marko@hundin.mysql.fi>2004-11-04 18:25:48 +0200
commit60e90ca052400f1f8a95a732266a6e05f65562c3 (patch)
treeb3376d8f0d638212a626b4abc7eddd67a1c1ab7b
parent02af97cc3431075b1b81826e6933251cf61cfb8e (diff)
parentf2be61f5b708a72ea22d773e46d1d42f8b2884a9 (diff)
downloadmariadb-git-60e90ca052400f1f8a95a732266a6e05f65562c3.tar.gz
Merge marko@bk-internal.mysql.com:/home/bk/mysql-4.1
into hundin.mysql.fi:/home/marko/j/mysql-4.1 innobase/row/row0mysql.c: Auto merged
-rw-r--r--innobase/include/lock0lock.h8
-rw-r--r--innobase/include/row0mysql.h6
-rw-r--r--innobase/lock/lock0lock.c13
-rw-r--r--innobase/row/row0mysql.c14
-rw-r--r--sql/ha_innodb.cc30
-rw-r--r--sql/ha_innodb.h4
6 files changed, 69 insertions, 6 deletions
diff --git a/innobase/include/lock0lock.h b/innobase/include/lock0lock.h
index 9f525042dcc..f8435e14d97 100644
--- a/innobase/include/lock0lock.h
+++ b/innobase/include/lock0lock.h
@@ -463,6 +463,14 @@ lock_rec_hash(
ulint space, /* in: space */
ulint page_no);/* in: page number */
/*************************************************************************
+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 */
+/*************************************************************************
Checks that a transaction id is sensible, i.e., not in the future. */
ibool
diff --git a/innobase/include/row0mysql.h b/innobase/include/row0mysql.h
index 9437ed4b6ee..73f41dea0da 100644
--- a/innobase/include/row0mysql.h
+++ b/innobase/include/row0mysql.h
@@ -175,8 +175,12 @@ int
row_lock_table_for_mysql(
/*=====================*/
/* out: error code or DB_SUCCESS */
- row_prebuilt_t* prebuilt); /* in: prebuilt struct in the MySQL
+ row_prebuilt_t* prebuilt, /* in: prebuilt struct in the MySQL
table handle */
+ dict_table_t* table); /* in: table to LOCK_IX, or NULL
+ if prebuilt->table should be
+ locked as LOCK_TABLE_EXP |
+ prebuilt->select_lock_type */
/*************************************************************************
Does an insert for MySQL. */
diff --git a/innobase/lock/lock0lock.c b/innobase/lock/lock0lock.c
index 68073647248..6f2d58b72c3 100644
--- a/innobase/lock/lock0lock.c
+++ b/innobase/lock/lock0lock.c
@@ -395,6 +395,19 @@ 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)
diff --git a/innobase/row/row0mysql.c b/innobase/row/row0mysql.c
index f356ef8081e..17747ae2a8e 100644
--- a/innobase/row/row0mysql.c
+++ b/innobase/row/row0mysql.c
@@ -779,8 +779,12 @@ int
row_lock_table_for_mysql(
/*=====================*/
/* out: error code or DB_SUCCESS */
- row_prebuilt_t* prebuilt) /* in: prebuilt struct in the MySQL
+ row_prebuilt_t* prebuilt, /* in: prebuilt struct in the MySQL
table handle */
+ dict_table_t* table) /* in: table to LOCK_IX, or NULL
+ if prebuilt->table should be
+ locked as LOCK_TABLE_EXP |
+ prebuilt->select_lock_type */
{
trx_t* trx = prebuilt->trx;
que_thr_t* thr;
@@ -813,8 +817,12 @@ run_again:
trx_start_if_not_started(trx);
- err = lock_table(LOCK_TABLE_EXP, prebuilt->table,
- prebuilt->select_lock_type, thr);
+ if (table) {
+ err = lock_table(0, table, LOCK_IX, thr);
+ } else {
+ err = lock_table(LOCK_TABLE_EXP, prebuilt->table,
+ prebuilt->select_lock_type, thr);
+ }
trx->error_state = err;
diff --git a/sql/ha_innodb.cc b/sql/ha_innodb.cc
index 0bcb7062437..6e08fc680b2 100644
--- a/sql/ha_innodb.cc
+++ b/sql/ha_innodb.cc
@@ -2314,6 +2314,34 @@ ha_innobase::write_row(
if (table->timestamp_field_type & TIMESTAMP_AUTO_SET_ON_INSERT)
table->timestamp_field->set_time();
+ if (user_thd->lex->sql_command == SQLCOM_ALTER_TABLE
+ && num_write_row >= 10000) {
+ /* ALTER TABLE is COMMITted at every 10000 copied rows.
+ The IX table lock for the original table has to be re-issued.
+ As this method will be called on a temporary table where the
+ contents of the original table is being copied to, it is
+ a bit tricky to determine the source table. The cursor
+ 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));
+ 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;
+ }
+
+ num_write_row++;
+
if (last_query_id != user_thd->query_id) {
prebuilt->sql_stat_start = TRUE;
last_query_id = user_thd->query_id;
@@ -4986,7 +5014,7 @@ ha_innobase::external_lock(
if (thd->in_lock_tables &&
thd->variables.innodb_table_locks) {
ulint error;
- error = row_lock_table_for_mysql(prebuilt);
+ error = row_lock_table_for_mysql(prebuilt, 0);
if (error != DB_SUCCESS) {
error = convert_error_code_to_mysql(
diff --git a/sql/ha_innodb.h b/sql/ha_innodb.h
index c10beacac1b..e76a966c6b9 100644
--- a/sql/ha_innodb.h
+++ b/sql/ha_innodb.h
@@ -64,6 +64,7 @@ class ha_innobase: public handler
uint last_match_mode;/* match mode of the latest search:
ROW_SEL_EXACT, ROW_SEL_EXACT_PREFIX,
or undefined */
+ uint num_write_row; /* number of write_row() calls */
longlong auto_inc_counter_for_this_stat;
ulong max_supported_row_length(const byte *buf);
@@ -85,7 +86,8 @@ class ha_innobase: public handler
HA_PRIMARY_KEY_IN_READ_INDEX |
HA_TABLE_SCAN_ON_INDEX),
last_dup_key((uint) -1),
- start_of_scan(0)
+ start_of_scan(0),
+ num_write_row(0)
{
}
~ha_innobase() {}