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#6255 | marko.makela | 27 May |