List:Commits« Previous MessageNext Message »
From:marko.makela Date:May 25 2012 8:41pm
Subject:bzr push into mysql-trunk-wl6255 branch (marko.makela:3867 to 3869) WL#6255
View as plain text  
 3869 Marko Mäkelä	2012-05-25
      WL#6255 preparation: Relax some assertions and adjust functions
      for online table rebuild.
      
      For indicating that an online table rebuild is in progress, we will
      flag the online_status of the clustered index in the old table, and
      allocate index->online_log on the clustered index of the old table.
      This is different from the modification logging on secondary index
      creation. In secondary index creation, if the index is being built
      online, we will write all changes only to the log. In online table
      rebuild, we will log the changes in addition to changing the original
      table directly.
      
      Relax many assertions on dict_index_is_online_ddl().
      
      dict_index_set_online_status(): Remove the qualifier "secondary" index.
      
      dict_index_is_online_ddl(): Adjust the function comment.
      
      index->to_be_dropped, index->online_status: Refine the latching rules.
      
      online_index_status: Update the comment of ONLINE_INDEX_ABORTED.
      
      row_merge_is_index_usable(): Do not deny access to the clustered index
      of a table that is being rebuilt.

    modified:
      storage/innobase/btr/btr0cur.cc
      storage/innobase/include/dict0dict.h
      storage/innobase/include/dict0dict.ic
      storage/innobase/include/dict0mem.h
      storage/innobase/lock/lock0lock.cc
      storage/innobase/row/row0merge.cc
 3868 Marko Mäkelä	2012-05-25
      WL#6255 preparation: Allow BTR_ALREADY_S_LATCHED
      to be specified with BTR_MODIFY_LEAF, not only with BTR_SEARCH_LEAF.

    modified:
      storage/innobase/btr/btr0cur.cc
      storage/innobase/include/btr0btr.h
 3867 Marko Mäkelä	2012-05-25
      prepare_inplace_alter_table_dict(): Do not acquire lock on the new table.
      We skip all record locking when populating the indexes.
      The table locking on the target (rebuilt) table is unnecessary too.

    modified:
      storage/innobase/handler/handler0alter.cc
=== modified file 'storage/innobase/btr/btr0cur.cc'
--- a/storage/innobase/btr/btr0cur.cc	revid:marko.makela@stripped02
+++ b/storage/innobase/btr/btr0cur.cc	revid:marko.makela@stripped
@@ -470,7 +470,9 @@ btr_cur_search_to_nth_level(
 	/* Turn the flags unrelated to the latch mode off. */
 	latch_mode = BTR_LATCH_MODE_WITHOUT_FLAGS(latch_mode);
 
-	ut_ad(!s_latch_by_caller || latch_mode == BTR_SEARCH_LEAF);
+	ut_ad(!s_latch_by_caller
+	      || latch_mode == BTR_SEARCH_LEAF
+	      || latch_mode == BTR_MODIFY_LEAF);
 
 	cursor->flag = BTR_CUR_BINARY;
 	cursor->index = index;
@@ -1129,7 +1131,9 @@ btr_cur_ins_lock_and_undo(
 	rec = btr_cur_get_rec(cursor);
 	index = cursor->index;
 
-	ut_ad(!dict_index_is_online_ddl(index) || (flags & BTR_CREATE_FLAG));
+	ut_ad(!dict_index_is_online_ddl(index)
+	      || dict_index_is_clust(index)
+	      || (flags & BTR_CREATE_FLAG));
 
 	err = lock_rec_insert_check_and_lock(flags, rec,
 					     btr_cur_get_block(cursor),
@@ -1230,7 +1234,9 @@ btr_cur_optimistic_insert(
 	block = btr_cur_get_block(cursor);
 	page = buf_block_get_frame(block);
 	index = cursor->index;
-	ut_ad(!dict_index_is_online_ddl(index) || (flags & BTR_CREATE_FLAG));
+	ut_ad(!dict_index_is_online_ddl(index)
+	      || dict_index_is_clust(index)
+	      || (flags & BTR_CREATE_FLAG));
 	zip_size = buf_block_get_zip_size(block);
 #ifdef UNIV_DEBUG_VALGRIND
 	if (zip_size) {
@@ -1494,7 +1500,9 @@ btr_cur_pessimistic_insert(
 				MTR_MEMO_X_LOCK));
 	ut_ad(mtr_memo_contains(mtr, btr_cur_get_block(cursor),
 				MTR_MEMO_PAGE_X_FIX));
-	ut_ad(!dict_index_is_online_ddl(index) || (flags & BTR_CREATE_FLAG));
+	ut_ad(!dict_index_is_online_ddl(index)
+	      || dict_index_is_clust(index)
+	      || (flags & BTR_CREATE_FLAG));
 
 	/* Try first an optimistic insert; reset the cursor flag: we do not
 	assume anything of how it was positioned */
@@ -1619,10 +1627,12 @@ btr_cur_upd_lock_and_undo(
 	rec = btr_cur_get_rec(cursor);
 	index = cursor->index;
 
-	ut_ad(dict_index_is_online_ddl(index) == !!(flags & BTR_CREATE_FLAG));
 	ut_ad(rec_offs_validate(rec, index, offsets));
 
 	if (!dict_index_is_clust(index)) {
+		ut_ad(dict_index_is_online_ddl(index)
+		      == !!(flags & BTR_CREATE_FLAG));
+
 		/* We do undo logging only when we update a clustered index
 		record */
 		return(lock_sec_rec_modify_check_and_lock(
@@ -1875,7 +1885,8 @@ btr_cur_update_in_place(
 	ut_ad(!!page_rec_is_comp(rec) == dict_table_is_comp(index->table));
 	/* The insert buffer tree should never be updated in place. */
 	ut_ad(!dict_index_is_ibuf(index));
-	ut_ad(dict_index_is_online_ddl(index) == !!(flags & BTR_CREATE_FLAG));
+	ut_ad(dict_index_is_online_ddl(index) == !!(flags & BTR_CREATE_FLAG)
+	      || dict_index_is_clust(index));
 	ut_ad(!thr || thr_get_trx(thr)->id == trx_id);
 	ut_ad(thr || flags == (BTR_NO_UNDO_LOG_FLAG | BTR_NO_LOCKING_FLAG
 			       | BTR_CREATE_FLAG | BTR_KEEP_SYS_FLAG));
@@ -2016,7 +2027,8 @@ btr_cur_optimistic_update(
 	ut_ad(mtr_memo_contains(mtr, block, MTR_MEMO_PAGE_X_FIX));
 	/* The insert buffer tree should never be updated in place. */
 	ut_ad(!dict_index_is_ibuf(index));
-	ut_ad(dict_index_is_online_ddl(index) == !!(flags & BTR_CREATE_FLAG));
+	ut_ad(dict_index_is_online_ddl(index) == !!(flags & BTR_CREATE_FLAG)
+	      || dict_index_is_clust(index));
 	ut_ad(!thr || thr_get_trx(thr)->id == trx_id);
 	ut_ad(thr || flags == (BTR_NO_UNDO_LOG_FLAG | BTR_NO_LOCKING_FLAG
 			       | BTR_CREATE_FLAG | BTR_KEEP_SYS_FLAG));
@@ -2283,7 +2295,8 @@ btr_cur_pessimistic_update(
 #endif /* UNIV_ZIP_DEBUG */
 	/* The insert buffer tree should never be updated in place. */
 	ut_ad(!dict_index_is_ibuf(index));
-	ut_ad(dict_index_is_online_ddl(index) == !!(flags & BTR_CREATE_FLAG));
+	ut_ad(dict_index_is_online_ddl(index) == !!(flags & BTR_CREATE_FLAG)
+	      || dict_index_is_clust(index));
 	ut_ad(!thr || thr_get_trx(thr)->id == trx_id);
 	ut_ad(thr || flags == (BTR_NO_UNDO_LOG_FLAG | BTR_NO_LOCKING_FLAG
 			       | BTR_CREATE_FLAG | BTR_KEEP_SYS_FLAG));
@@ -2972,6 +2985,7 @@ btr_cur_optimistic_delete_func(
 
 	ut_ad(page_is_leaf(buf_block_get_frame(block)));
 	ut_ad(!dict_index_is_online_ddl(cursor->index)
+	      || dict_index_is_clust(cursor->index)
 	      || (flags & BTR_CREATE_FLAG));
 
 	rec = btr_cur_get_rec(cursor);
@@ -3073,7 +3087,9 @@ btr_cur_pessimistic_delete(
 	index = btr_cur_get_index(cursor);
 
 	ut_ad(flags == 0 || flags == BTR_CREATE_FLAG);
-	ut_ad(!dict_index_is_online_ddl(index) || (flags & BTR_CREATE_FLAG));
+	ut_ad(!dict_index_is_online_ddl(index)
+	      || dict_index_is_clust(index)
+	      || (flags & BTR_CREATE_FLAG));
 	ut_ad(mtr_memo_contains(mtr, dict_index_get_lock(index),
 				MTR_MEMO_X_LOCK));
 	ut_ad(mtr_memo_contains(mtr, block, MTR_MEMO_PAGE_X_FIX));

=== modified file 'storage/innobase/include/btr0btr.h'
--- a/storage/innobase/include/btr0btr.h	revid:marko.makela@stripped
+++ b/storage/innobase/include/btr0btr.h	revid:marko.makela@oracle.com-20120525204032-kqdn46ajwkuh5y6w
@@ -92,8 +92,8 @@ insert/delete buffer when the record is
 buffer when the record is not in the buffer pool. */
 #define BTR_DELETE		8192
 
-/** In the case of BTR_SEARCH_LEAF, the caller is already holding an S latch
-on the index tree */
+/** In the case of BTR_SEARCH_LEAF or BTR_MODIFY_LEAF, the caller is
+already holding an S latch on the index tree */
 #define BTR_ALREADY_S_LATCHED	16384
 
 #define BTR_LATCH_MODE_WITHOUT_FLAGS(latch_mode)	\

=== modified file 'storage/innobase/include/dict0dict.h'
--- a/storage/innobase/include/dict0dict.h	revid:marko.makela@stripped120525200045-mv7uq4h5gytikr02
+++ b/storage/innobase/include/dict0dict.h	revid:marko.makela@stripped032-kqdn46ajwkuh5y6w
@@ -1315,16 +1315,18 @@ UNIV_INLINE
 void
 dict_index_set_online_status(
 /*=========================*/
-	dict_index_t*			index,	/*!< in/out: secondary index */
+	dict_index_t*			index,	/*!< in/out: index */
 	enum online_index_status	status)	/*!< in: status */
 	__attribute__((nonnull));
 /********************************************************************//**
 Determines if a secondary index is being or has been created online,
-allowing concurrent modifications to the table.
-@retval TRUE if the index is being or has been built online
-@retval FALSE if the index has been created completely */
+or if the table is being rebuilt online, allowing concurrent modifications
+to the table.
+@retval true if the index is being or has been built online, or
+if this is a clustered index and the table is or was being rebuilt online
+@retval false if the index has been created completely */
 UNIV_INLINE
-ibool
+bool
 dict_index_is_online_ddl(
 /*=====================*/
 	const dict_index_t*	index)	/*!< in: index */

=== modified file 'storage/innobase/include/dict0dict.ic'
--- a/storage/innobase/include/dict0dict.ic	revid:marko.makela@stripped5gytikr02
+++ b/storage/innobase/include/dict0dict.ic	revid:marko.makela@strippedw
@@ -1148,10 +1148,9 @@ UNIV_INLINE
 void
 dict_index_set_online_status(
 /*=========================*/
-	dict_index_t*			index,	/*!< in/out: secondary index */
+	dict_index_t*			index,	/*!< in/out: index */
 	enum online_index_status	status)	/*!< in: status */
 {
-	ut_ad(!dict_index_is_clust(index));
 	ut_ad(!(index->type & DICT_FTS));
 #ifdef UNIV_SYNC_DEBUG
 	ut_ad(rw_lock_own(dict_index_get_lock(index), RW_LOCK_EX));
@@ -1175,11 +1174,13 @@ dict_index_set_online_status(
 
 /********************************************************************//**
 Determines if a secondary index is being or has been created online,
-allowing concurrent modifications to the table.
-@retval TRUE if the index is being or has been built online
-@retval FALSE if the index has been created completely */
+or if the table is being rebuilt online, allowing concurrent modifications
+to the table.
+@retval true if the index is being or has been built online, or
+if this is a clustered index and the table is or was being rebuilt online
+@retval false if the index has been created completely */
 UNIV_INLINE
-ibool
+bool
 dict_index_is_online_ddl(
 /*=====================*/
 	const dict_index_t*	index)	/*!< in: index */

=== modified file 'storage/innobase/include/dict0mem.h'
--- a/storage/innobase/include/dict0mem.h	revid:marko.makela@strippedikr02
+++ b/storage/innobase/include/dict0mem.h	revid:marko.makela@stripped
@@ -484,9 +484,19 @@ struct dict_index_struct{
 	unsigned	cached:1;/*!< TRUE if the index object is in the
 				dictionary cache */
 	unsigned	to_be_dropped:1;
-				/*!< TRUE if the index is to be dropped */
+				/*!< TRUE if the index is to be dropped;
+				protected by dict_operation_lock */
 	unsigned	online_status:2;
-				/*!< enum online_index_status */
+				/*!< enum online_index_status.
+				Transitions from ONLINE_INDEX_COMPLETE (to
+				ONLINE_INDEX_CREATION) are protected
+				by dict_operation_lock and
+				dict_sys->mutex. Transitions of the
+				clustered index from ONLINE_INDEX_CREATION
+				to ONLINE_INDEX_ABORTED (modification log
+				overflow or other error) are protected
+				by index->online_log->mutex. Other
+				changes are protected by index->lock. */
 	dict_field_t*	fields;	/*!< array of field descriptions */
 #ifndef UNIV_HOTBACKUP
 	UT_LIST_NODE_T(dict_index_t)
@@ -553,8 +563,11 @@ enum online_index_status {
 	/** the index is being created, online
 	(allowing concurrent modifications) */
 	ONLINE_INDEX_CREATION,
-	/** the online index creation was aborted and the index
-	should be dropped as soon as index->table->n_ref_count reaches 0 */
+	/** secondary index creation was aborted and the index
+	should be dropped as soon as index->table->n_ref_count reaches 0,
+	or online table rebuild was aborted and the clustered index
+	of the original table should soon be restored to
+	ONLINE_INDEX_COMPLETE */
 	ONLINE_INDEX_ABORTED,
 	/** the online index creation was aborted, the index was
 	dropped from the data dictionary and the tablespace, and it

=== modified file 'storage/innobase/lock/lock0lock.cc'
--- a/storage/innobase/lock/lock0lock.cc	revid:marko.makela@oracle.com-20120525200045-mv7uq4h5gytikr02
+++ b/storage/innobase/lock/lock0lock.cc	revid:marko.makela@stripped525204032-kqdn46ajwkuh5y6w
@@ -531,7 +531,6 @@ lock_clust_rec_cons_read_sees(
 	trx_id_t	trx_id;
 
 	ut_ad(dict_index_is_clust(index));
-	ut_ad(!dict_index_is_online_ddl(index));
 	ut_ad(page_rec_is_user_rec(rec));
 	ut_ad(rec_offs_validate(rec, index, offsets));
 
@@ -1747,7 +1746,7 @@ lock_rec_create(
 
 	ut_ad(lock_mutex_own());
 	ut_ad(caller_owns_trx_mutex == trx_mutex_own(trx));
-	ut_ad(!dict_index_is_online_ddl(index));
+	ut_ad(dict_index_is_clust(index) || !dict_index_is_online_ddl(index));
 
 	/* Non-locking autocommit read-only transactions should not set
 	any locks. */
@@ -1853,7 +1852,7 @@ lock_rec_enqueue_waiting(
 	trx_id_t		victim_trx_id;
 
 	ut_ad(lock_mutex_own());
-	ut_ad(!dict_index_is_online_ddl(index));
+	ut_ad(dict_index_is_clust(index) || !dict_index_is_online_ddl(index));
 
 	trx = thr_get_trx(thr);
 
@@ -1972,7 +1971,7 @@ lock_rec_add_to_queue(
 
 	ut_ad(lock_mutex_own());
 	ut_ad(caller_owns_trx_mutex == trx_mutex_own(trx));
-	ut_ad(!dict_index_is_online_ddl(index));
+	ut_ad(dict_index_is_clust(index) || !dict_index_is_online_ddl(index));
 #ifdef UNIV_DEBUG
 	switch (type_mode & LOCK_MODE_MASK) {
 	case LOCK_X:
@@ -2094,7 +2093,7 @@ lock_rec_lock_fast(
 	ut_ad(mode - (LOCK_MODE_MASK & mode) == LOCK_GAP
 	      || mode - (LOCK_MODE_MASK & mode) == 0
 	      || mode - (LOCK_MODE_MASK & mode) == LOCK_REC_NOT_GAP);
-	ut_ad(!dict_index_is_online_ddl(index));
+	ut_ad(dict_index_is_clust(index) || !dict_index_is_online_ddl(index));
 
 	lock = lock_rec_get_first_on_page(block);
 
@@ -2170,7 +2169,7 @@ lock_rec_lock_slow(
 	ut_ad(mode - (LOCK_MODE_MASK & mode) == LOCK_GAP
 	      || mode - (LOCK_MODE_MASK & mode) == 0
 	      || mode - (LOCK_MODE_MASK & mode) == LOCK_REC_NOT_GAP);
-	ut_ad(!dict_index_is_online_ddl(index));
+	ut_ad(dict_index_is_clust(index) || !dict_index_is_online_ddl(index));
 
 	trx = thr_get_trx(thr);
 
@@ -2242,7 +2241,7 @@ lock_rec_lock(
 	ut_ad(mode - (LOCK_MODE_MASK & mode) == LOCK_GAP
 	      || mode - (LOCK_MODE_MASK & mode) == LOCK_REC_NOT_GAP
 	      || mode - (LOCK_MODE_MASK & mode) == 0);
-	ut_ad(!dict_index_is_online_ddl(index));
+	ut_ad(dict_index_is_clust(index) || !dict_index_is_online_ddl(index));
 
 	/* We try a simplified and faster subroutine for the most
 	common cases */
@@ -5419,7 +5418,8 @@ lock_rec_queue_validate(
 	ut_ad(rec_offs_validate(rec, index, offsets));
 	ut_ad(!page_rec_is_comp(rec) == !rec_offs_comp(offsets));
 	ut_ad(lock_mutex_own() == locked_lock_trx_sys);
-	ut_ad(!index || !dict_index_is_online_ddl(index));
+	ut_ad(!index || dict_index_is_clust(index)
+	      || !dict_index_is_online_ddl(index));
 
 	heap_no = page_rec_get_heap_no(rec);
 
@@ -5795,7 +5795,9 @@ lock_rec_insert_check_and_lock(
 	ulint		next_rec_heap_no;
 
 	ut_ad(block->frame == page_align(rec));
-	ut_ad(!dict_index_is_online_ddl(index) || (flags & BTR_CREATE_FLAG));
+	ut_ad(!dict_index_is_online_ddl(index)
+	      || dict_index_is_clust(index)
+	      || (flags & BTR_CREATE_FLAG));
 
 	if (flags & BTR_NO_LOCKING_FLAG) {
 
@@ -5923,7 +5925,6 @@ lock_rec_convert_impl_to_expl(
 	ut_ad(page_rec_is_user_rec(rec));
 	ut_ad(rec_offs_validate(rec, index, offsets));
 	ut_ad(!page_rec_is_comp(rec) == !rec_offs_comp(offsets));
-	ut_ad(!dict_index_is_online_ddl(index));
 
 	if (dict_index_is_clust(index)) {
 		trx_id = lock_clust_rec_some_has_impl(rec, index, offsets);
@@ -5931,6 +5932,7 @@ lock_rec_convert_impl_to_expl(
 		this transaction. The transaction may have been
 		committed a long time ago. */
 	} else {
+		ut_ad(!dict_index_is_online_ddl(index));
 		trx_id = lock_sec_rec_some_has_impl(rec, index, offsets);
 		/* The transaction can be committed before the
 		trx_is_active(trx_id, NULL) check below, because we are not
@@ -5990,7 +5992,6 @@ lock_clust_rec_modify_check_and_lock(
 
 	ut_ad(rec_offs_validate(rec, index, offsets));
 	ut_ad(dict_index_is_clust(index));
-	ut_ad(!dict_index_is_online_ddl(index));
 	ut_ad(block->frame == page_align(rec));
 
 	if (flags & BTR_NO_LOCKING_FLAG) {
@@ -6220,7 +6221,6 @@ lock_clust_rec_read_check_and_lock(
 	ulint	heap_no;
 
 	ut_ad(dict_index_is_clust(index));
-	ut_ad(!dict_index_is_online_ddl(index));
 	ut_ad(block->frame == page_align(rec));
 	ut_ad(page_rec_is_user_rec(rec) || page_rec_is_supremum(rec));
 	ut_ad(gap_mode == LOCK_ORDINARY || gap_mode == LOCK_GAP
@@ -6485,7 +6485,8 @@ lock_get_table(
 {
 	switch (lock_get_type_low(lock)) {
 	case LOCK_REC:
-		ut_ad(!dict_index_is_online_ddl(lock->index));
+		ut_ad(dict_index_is_clust(lock->index)
+		      || !dict_index_is_online_ddl(lock->index));
 		return(lock->index->table);
 	case LOCK_TABLE:
 		return(lock->un_member.tab_lock.table);
@@ -6538,7 +6539,8 @@ lock_rec_get_index(
 	const lock_t*	lock)	/*!< in: lock */
 {
 	ut_a(lock_get_type_low(lock) == LOCK_REC);
-	ut_ad(!dict_index_is_online_ddl(lock->index));
+	ut_ad(dict_index_is_clust(lock->index)
+	      || !dict_index_is_online_ddl(lock->index));
 
 	return(lock->index);
 }
@@ -6554,7 +6556,8 @@ lock_rec_get_index_name(
 	const lock_t*	lock)	/*!< in: lock */
 {
 	ut_a(lock_get_type_low(lock) == LOCK_REC);
-	ut_ad(!dict_index_is_online_ddl(lock->index));
+	ut_ad(dict_index_is_clust(lock->index)
+	      || !dict_index_is_online_ddl(lock->index));
 
 	return(lock->index->name);
 }
@@ -6819,7 +6822,8 @@ lock_table_locks_lookup(
 			ut_a(lock->trx == trx);
 
 			if (lock_get_type_low(lock) == LOCK_REC) {
-				ut_ad(!dict_index_is_online_ddl(lock->index));
+				ut_ad(!dict_index_is_online_ddl(lock->index)
+				      || dict_index_is_clust(lock->index));
 				if (lock->index->table == table) {
 					return(lock);
 				}

=== modified file 'storage/innobase/row/row0merge.cc'
--- a/storage/innobase/row/row0merge.cc	revid:marko.makela@strippedr02
+++ b/storage/innobase/row/row0merge.cc	revid:marko.makela@stripped
@@ -3092,7 +3092,8 @@ row_merge_is_index_usable(
 	const trx_t*		trx,	/*!< in: transaction */
 	const dict_index_t*	index)	/*!< in: index to check */
 {
-	if (dict_index_is_online_ddl(index)) {
+	if (!dict_index_is_clust(index)
+	    && dict_index_is_online_ddl(index)) {
 		/* Indexes that are being created are not useable. */
 		return(FALSE);
 	}

No bundle (reason: useless for push emails).
Thread
bzr push into mysql-trunk-wl6255 branch (marko.makela:3867 to 3869) WL#6255marko.makela27 May