diff options
author | unknown <marko@hundin.mysql.fi> | 2004-11-04 18:25:48 +0200 |
---|---|---|
committer | unknown <marko@hundin.mysql.fi> | 2004-11-04 18:25:48 +0200 |
commit | 60e90ca052400f1f8a95a732266a6e05f65562c3 (patch) | |
tree | b3376d8f0d638212a626b4abc7eddd67a1c1ab7b | |
parent | 02af97cc3431075b1b81826e6933251cf61cfb8e (diff) | |
parent | f2be61f5b708a72ea22d773e46d1d42f8b2884a9 (diff) | |
download | mariadb-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.h | 8 | ||||
-rw-r--r-- | innobase/include/row0mysql.h | 6 | ||||
-rw-r--r-- | innobase/lock/lock0lock.c | 13 | ||||
-rw-r--r-- | innobase/row/row0mysql.c | 14 | ||||
-rw-r--r-- | sql/ha_innodb.cc | 30 | ||||
-rw-r--r-- | sql/ha_innodb.h | 4 |
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() {} |