Commit fd069e2b authored by marko@hundin.mysql.fi's avatar marko@hundin.mysql.fi

InnoDB: commit after every 10000 rows in ALTER TABLE

parent 97ecfced
...@@ -463,6 +463,14 @@ lock_rec_hash( ...@@ -463,6 +463,14 @@ lock_rec_hash(
ulint space, /* in: space */ ulint space, /* in: space */
ulint page_no);/* in: page number */ 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. */ Checks that a transaction id is sensible, i.e., not in the future. */
ibool ibool
......
...@@ -175,8 +175,12 @@ int ...@@ -175,8 +175,12 @@ int
row_lock_table_for_mysql( row_lock_table_for_mysql(
/*=====================*/ /*=====================*/
/* out: error code or DB_SUCCESS */ /* 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 */ 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. */ Does an insert for MySQL. */
......
...@@ -395,6 +395,19 @@ lock_rec_get_nth_bit( ...@@ -395,6 +395,19 @@ lock_rec_get_nth_bit(
return(ut_bit_get_nth(b, bit_index)); 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) #define lock_mutex_enter_kernel() mutex_enter(&kernel_mutex)
......
...@@ -779,8 +779,12 @@ int ...@@ -779,8 +779,12 @@ int
row_lock_table_for_mysql( row_lock_table_for_mysql(
/*=====================*/ /*=====================*/
/* out: error code or DB_SUCCESS */ /* 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 */ 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; trx_t* trx = prebuilt->trx;
que_thr_t* thr; que_thr_t* thr;
...@@ -813,8 +817,12 @@ run_again: ...@@ -813,8 +817,12 @@ run_again:
trx_start_if_not_started(trx); trx_start_if_not_started(trx);
err = lock_table(LOCK_TABLE_EXP, prebuilt->table, if (table) {
prebuilt->select_lock_type, thr); 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; trx->error_state = err;
......
...@@ -2314,7 +2314,31 @@ ha_innobase::write_row( ...@@ -2314,7 +2314,31 @@ ha_innobase::write_row(
if (table->timestamp_field_type & TIMESTAMP_AUTO_SET_ON_INSERT) if (table->timestamp_field_type & TIMESTAMP_AUTO_SET_ON_INSERT)
table->timestamp_field->set_time(); table->timestamp_field->set_time();
num_write_row++;
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;
innobase_commit(user_thd, prebuilt->trx);
user_thd->transaction.all.innodb_active_trans = 1;
row_lock_table_for_mysql(prebuilt, table);
goto new_trx;
}
if (last_query_id != user_thd->query_id) { if (last_query_id != user_thd->query_id) {
new_trx:
prebuilt->sql_stat_start = TRUE; prebuilt->sql_stat_start = TRUE;
last_query_id = user_thd->query_id; last_query_id = user_thd->query_id;
...@@ -4986,7 +5010,7 @@ ha_innobase::external_lock( ...@@ -4986,7 +5010,7 @@ ha_innobase::external_lock(
if (thd->in_lock_tables && if (thd->in_lock_tables &&
thd->variables.innodb_table_locks) { thd->variables.innodb_table_locks) {
ulint error; ulint error;
error = row_lock_table_for_mysql(prebuilt); error = row_lock_table_for_mysql(prebuilt, 0);
if (error != DB_SUCCESS) { if (error != DB_SUCCESS) {
error = convert_error_code_to_mysql( error = convert_error_code_to_mysql(
......
...@@ -64,6 +64,7 @@ class ha_innobase: public handler ...@@ -64,6 +64,7 @@ class ha_innobase: public handler
uint last_match_mode;/* match mode of the latest search: uint last_match_mode;/* match mode of the latest search:
ROW_SEL_EXACT, ROW_SEL_EXACT_PREFIX, ROW_SEL_EXACT, ROW_SEL_EXACT_PREFIX,
or undefined */ or undefined */
uint num_write_row; /* number of write_row() calls */
longlong auto_inc_counter_for_this_stat; longlong auto_inc_counter_for_this_stat;
ulong max_supported_row_length(const byte *buf); ulong max_supported_row_length(const byte *buf);
...@@ -85,7 +86,8 @@ class ha_innobase: public handler ...@@ -85,7 +86,8 @@ class ha_innobase: public handler
HA_PRIMARY_KEY_IN_READ_INDEX | HA_PRIMARY_KEY_IN_READ_INDEX |
HA_TABLE_SCAN_ON_INDEX), HA_TABLE_SCAN_ON_INDEX),
last_dup_key((uint) -1), last_dup_key((uint) -1),
start_of_scan(0) start_of_scan(0),
num_write_row(0)
{ {
} }
~ha_innobase() {} ~ha_innobase() {}
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment