Commit d07f96cf authored by unknown's avatar unknown
Browse files

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
parent 37e92c9b
Loading
Loading
Loading
Loading
+8 −0
Original line number Diff line number Diff line
@@ -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
+5 −1
Original line number Diff line number Diff line
@@ -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. */

+13 −0
Original line number Diff line number Diff line
@@ -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)
+11 −3
Original line number Diff line number Diff line
@@ -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 @@ row_lock_table_for_mysql(

	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;

+25 −1
Original line number Diff line number Diff line
@@ -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(
Loading