mirror of
https://github.com/MariaDB/server.git
synced 2025-07-29 05:21:33 +03:00
InnoDB: commit after every 10000 rows in ALTER TABLE
innobase/include/lock0lock.h: Added function lock_get_ix_table() innobase/include/row0mysql.h: Added parameter "table" to row_lock_table_for_mysql() innobase/lock/lock0lock.c: Added function lock_get_ix_table() innobase/row/row0mysql.c: Added parameter "table" to row_lock_table_for_mysql() sql/ha_innodb.cc: write_row(): commit every 10000 rows in ALTER TABLE sql/ha_innodb.h: Added member variable num_write_row
This commit is contained in:
@ -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
|
||||
|
@ -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. */
|
||||
|
||||
|
@ -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)
|
||||
|
@ -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);
|
||||
|
||||
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;
|
||||
|
||||
|
@ -2314,7 +2314,31 @@ ha_innobase::write_row(
|
||||
if (table->timestamp_field_type & TIMESTAMP_AUTO_SET_ON_INSERT)
|
||||
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) {
|
||||
new_trx:
|
||||
prebuilt->sql_stat_start = TRUE;
|
||||
last_query_id = user_thd->query_id;
|
||||
|
||||
@ -4986,7 +5010,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(
|
||||
|
@ -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() {}
|
||||
|
Reference in New Issue
Block a user