Skip to content

Commit

Permalink
Terminology: 'metadata record' instead of 'default row'
Browse files Browse the repository at this point in the history
For instant ALTER TABLE, we store a hidden metadata record at the
start of the clustered index, to indicate how the format of the
records differs from the latest table definition.

The term 'default row' is too specific, because it applies to
instant ADD COLUMN only, and we will be supporting more classes
of instant ALTER TABLE later on. For instant ADD COLUMN, we
store the initial default values in the metadata record.
  • Loading branch information
dr-m committed Sep 19, 2018
1 parent 043639f commit 755187c
Show file tree
Hide file tree
Showing 24 changed files with 134 additions and 137 deletions.
77 changes: 38 additions & 39 deletions storage/innobase/btr/btr0cur.cc
Original file line number Diff line number Diff line change
Expand Up @@ -431,7 +431,7 @@ btr_cur_instant_init_low(dict_index_t* index, mtr_t* mtr)

const rec_t* rec = cur.page_cur.rec;

if (page_rec_is_supremum(rec) || !rec_is_default_row(rec, index)) {
if (page_rec_is_supremum(rec) || !rec_is_metadata(rec, index)) {
ib::error() << "Table " << index->table->name
<< " is missing instant ALTER metadata";
index->table->corrupted = true;
Expand All @@ -452,7 +452,7 @@ btr_cur_instant_init_low(dict_index_t* index, mtr_t* mtr)
goto incompatible;
}

/* Read the 'default row'. We can get here on server restart
/* Read the metadata. We can get here on server restart
or when the table was evicted from the data dictionary cache
and is now being accessed again.
Expand All @@ -471,8 +471,8 @@ btr_cur_instant_init_low(dict_index_t* index, mtr_t* mtr)
goto incompatible;
}

/* In fact, because we only ever append fields to the 'default
value' record, it is also OK to perform READ UNCOMMITTED and
/* In fact, because we only ever append fields to the metadata
record, it is also OK to perform READ UNCOMMITTED and
then ignore any extra fields, provided that
trx_sys.is_registered(DB_TRX_ID). */
if (rec_offs_n_fields(offsets) > index->n_fields
Expand Down Expand Up @@ -2270,10 +2270,9 @@ btr_cur_search_to_nth_level_func(
ut_ad(index->is_instant());
/* This may be a search tuple for
btr_pcur_restore_position(). */
ut_ad(tuple->info_bits == REC_INFO_DEFAULT_ROW
ut_ad(tuple->info_bits == REC_INFO_METADATA
|| tuple->info_bits == REC_INFO_MIN_REC_FLAG);
} else if (rec_is_default_row(btr_cur_get_rec(cursor),
index)) {
} else if (rec_is_metadata(btr_cur_get_rec(cursor), index)) {
/* Only user records belong in the adaptive
hash index. */
} else {
Expand Down Expand Up @@ -3412,7 +3411,7 @@ btr_cur_optimistic_insert(
} else if (index->disable_ahi) {
# endif
} else if (entry->info_bits & REC_INFO_MIN_REC_FLAG) {
ut_ad(entry->info_bits == REC_INFO_DEFAULT_ROW);
ut_ad(entry->info_bits == REC_INFO_METADATA);
ut_ad(index->is_instant());
ut_ad(flags == BTR_NO_LOCKING_FLAG);
} else {
Expand Down Expand Up @@ -3620,7 +3619,7 @@ btr_cur_pessimistic_insert(
if (index->disable_ahi); else
# endif
if (entry->info_bits & REC_INFO_MIN_REC_FLAG) {
ut_ad(entry->info_bits == REC_INFO_DEFAULT_ROW);
ut_ad(entry->info_bits == REC_INFO_METADATA);
ut_ad(index->is_instant());
ut_ad((flags & ulint(~BTR_KEEP_IBUF_BITMAP))
== BTR_NO_LOCKING_FLAG);
Expand Down Expand Up @@ -4100,9 +4099,9 @@ btr_cur_update_in_place(

/** Trim an update tuple due to instant ADD COLUMN, if needed.
For normal records, the trailing instantly added fields that match
the 'default row' are omitted.
the initial default values are omitted.
For the special 'default row' record on a table on which instant
For the special metadata record on a table on which instant
ADD COLUMN has already been executed, both ADD COLUMN and the
rollback of ADD COLUMN need to be handled specially.
Expand All @@ -4119,8 +4118,8 @@ btr_cur_trim(
const que_thr_t* thr)
{
if (!index->is_instant()) {
} else if (UNIV_UNLIKELY(update->info_bits == REC_INFO_DEFAULT_ROW)) {
/* We are either updating a 'default row'
} else if (UNIV_UNLIKELY(update->info_bits == REC_INFO_METADATA)) {
/* We are either updating a metadata record
(instantly adding columns to a table where instant ADD was
already executed) or rolling back such an operation. */
ut_ad(!upd_get_nth_field(update, 0)->orig_len);
Expand Down Expand Up @@ -4227,9 +4226,9 @@ btr_cur_optimistic_update(
|| trx_is_recv(thr_get_trx(thr)));
#endif /* UNIV_DEBUG || UNIV_BLOB_LIGHT_DEBUG */

const bool is_default_row = update->info_bits == REC_INFO_DEFAULT_ROW;
const bool is_metadata = update->info_bits == REC_INFO_METADATA;

if (UNIV_LIKELY(!is_default_row)
if (UNIV_LIKELY(!is_metadata)
&& !row_upd_changes_field_size_or_external(index, *offsets,
update)) {

Expand Down Expand Up @@ -4389,8 +4388,8 @@ btr_cur_optimistic_update(
lock_rec_store_on_page_infimum(block, rec);
}

if (UNIV_UNLIKELY(is_default_row)) {
ut_ad(new_entry->info_bits == REC_INFO_DEFAULT_ROW);
if (UNIV_UNLIKELY(is_metadata)) {
ut_ad(new_entry->info_bits == REC_INFO_METADATA);
ut_ad(index->is_instant());
/* This can be innobase_add_instant_try() performing a
subsequent instant ADD COLUMN, or its rollback by
Expand All @@ -4416,9 +4415,9 @@ btr_cur_optimistic_update(
cursor, new_entry, offsets, heap, 0/*n_ext*/, mtr);
ut_a(rec); /* <- We calculated above the insert would fit */

if (UNIV_UNLIKELY(is_default_row)) {
if (UNIV_UNLIKELY(is_metadata)) {
/* We must empty the PAGE_FREE list, because if this
was a rollback, the shortened 'default row' record
was a rollback, the shortened metadata record
would have too many fields, and we would be unable to
know the size of the freed record. */
btr_page_reorganize(page_cursor, index, mtr);
Expand Down Expand Up @@ -4623,7 +4622,7 @@ btr_cur_pessimistic_update(
entry_heap);
btr_cur_trim(new_entry, index, update, thr);

const bool is_default_row = new_entry->info_bits
const bool is_metadata = new_entry->info_bits
& REC_INFO_MIN_REC_FLAG;

/* We have to set appropriate extern storage bits in the new
Expand Down Expand Up @@ -4717,8 +4716,8 @@ btr_cur_pessimistic_update(
page, 1);
}

if (UNIV_UNLIKELY(is_default_row)) {
ut_ad(new_entry->info_bits == REC_INFO_DEFAULT_ROW);
if (UNIV_UNLIKELY(is_metadata)) {
ut_ad(new_entry->info_bits == REC_INFO_METADATA);
ut_ad(index->is_instant());
/* This can be innobase_add_instant_try() performing a
subsequent instant ADD COLUMN, or its rollback by
Expand Down Expand Up @@ -4757,9 +4756,9 @@ btr_cur_pessimistic_update(
if (rec) {
page_cursor->rec = rec;

if (UNIV_UNLIKELY(is_default_row)) {
if (UNIV_UNLIKELY(is_metadata)) {
/* We must empty the PAGE_FREE list, because if this
was a rollback, the shortened 'default row' record
was a rollback, the shortened metadata record
would have too many fields, and we would be unable to
know the size of the freed record. */
btr_page_reorganize(page_cursor, index, mtr);
Expand Down Expand Up @@ -4913,9 +4912,9 @@ btr_cur_pessimistic_update(
ut_ad(row_get_rec_trx_id(rec, index, *offsets));
}

if (UNIV_UNLIKELY(is_default_row)) {
if (UNIV_UNLIKELY(is_metadata)) {
/* We must empty the PAGE_FREE list, because if this
was a rollback, the shortened 'default row' record
was a rollback, the shortened metadata record
would have too many fields, and we would be unable to
know the size of the freed record. */
btr_page_reorganize(page_cursor, index, mtr);
Expand Down Expand Up @@ -5413,16 +5412,16 @@ btr_cur_optimistic_delete_func(
if (UNIV_UNLIKELY(page_is_root(block->frame)
&& page_get_n_recs(block->frame) == 1
+ (cursor->index->is_instant()
&& !rec_is_default_row(rec, cursor->index)))) {
&& !rec_is_metadata(rec, cursor->index)))) {
/* The whole index (and table) becomes logically empty.
Empty the whole page. That is, if we are deleting the
only user record, also delete the 'default row' record
only user record, also delete the metadata record
if one exists (it exists if and only if is_instant()).
If we are deleting the 'default row' record and the
If we are deleting the metadata record and the
table becomes empty, clean up the whole page. */
dict_index_t* index = cursor->index;
ut_ad(!index->is_instant()
|| rec_is_default_row(
|| rec_is_metadata(
page_rec_get_next_const(
page_get_infimum_rec(block->frame)),
index));
Expand Down Expand Up @@ -5475,7 +5474,7 @@ btr_cur_optimistic_delete_func(
page_cur_delete_rec(btr_cur_get_page_cur(cursor),
cursor->index, offsets, mtr);
/* We must empty the PAGE_FREE list, because
after rollback, this deleted 'default row' record
after rollback, this deleted metadata record
would have too many fields, and we would be
unable to know the size of the freed record. */
btr_page_reorganize(btr_cur_get_page_cur(cursor),
Expand Down Expand Up @@ -5628,9 +5627,9 @@ btr_cur_pessimistic_delete(
}

if (page_is_leaf(page)) {
const bool is_default_row = rec_get_info_bits(
const bool is_metadata = rec_get_info_bits(
rec, page_rec_is_comp(rec)) & REC_INFO_MIN_REC_FLAG;
if (UNIV_UNLIKELY(is_default_row)) {
if (UNIV_UNLIKELY(is_metadata)) {
/* This should be rolling back instant ADD COLUMN.
If this is a recovered transaction, then
index->is_instant() will hold until the
Expand All @@ -5648,15 +5647,15 @@ btr_cur_pessimistic_delete(
}
} else if (page_get_n_recs(page) == 1
+ (index->is_instant()
&& !rec_is_default_row(rec, index))) {
&& !rec_is_metadata(rec, index))) {
/* The whole index (and table) becomes logically empty.
Empty the whole page. That is, if we are deleting the
only user record, also delete the 'default row' record
only user record, also delete the metadata record
if one exists (it exists if and only if is_instant()).
If we are deleting the 'default row' record and the
If we are deleting the metadata record and the
table becomes empty, clean up the whole page. */
ut_ad(!index->is_instant()
|| rec_is_default_row(
|| rec_is_metadata(
page_rec_get_next_const(
page_get_infimum_rec(page)),
index));
Expand All @@ -5673,13 +5672,13 @@ btr_cur_pessimistic_delete(
goto return_after_reservations;
}

if (UNIV_LIKELY(!is_default_row)) {
if (UNIV_LIKELY(!is_metadata)) {
btr_search_update_hash_on_delete(cursor);
} else {
page_cur_delete_rec(btr_cur_get_page_cur(cursor),
index, offsets, mtr);
/* We must empty the PAGE_FREE list, because
after rollback, this deleted 'default row' record
after rollback, this deleted metadata record
would carry too many fields, and we would be
unable to know the size of the freed record. */
btr_page_reorganize(btr_cur_get_page_cur(cursor),
Expand Down
4 changes: 2 additions & 2 deletions storage/innobase/btr/btr0pcur.cc
Original file line number Diff line number Diff line change
Expand Up @@ -151,13 +151,13 @@ btr_pcur_store_position(
rec = page_rec_get_prev(rec);

ut_ad(!page_rec_is_infimum(rec));
ut_ad(!rec_is_default_row(rec, index));
ut_ad(!rec_is_metadata(rec, index));

cursor->rel_pos = BTR_PCUR_AFTER;
} else if (page_rec_is_infimum_low(offs)) {
rec = page_rec_get_next(rec);

if (rec_is_default_row(rec, index)) {
if (rec_is_metadata(rec, index)) {
rec = page_rec_get_next(rec);
ut_ad(!page_rec_is_supremum(rec));
}
Expand Down
8 changes: 4 additions & 4 deletions storage/innobase/btr/btr0sea.cc
Original file line number Diff line number Diff line change
Expand Up @@ -111,7 +111,7 @@ rec_fold(
ut_ad(rec_offs_validate(rec, NULL, offsets));
ut_ad(rec_validate(rec, offsets));
ut_ad(page_rec_is_leaf(rec));
ut_ad(!page_rec_is_default_row(rec));
ut_ad(!page_rec_is_metadata(rec));
ut_ad(n_fields > 0 || n_bytes > 0);

n_fields_rec = rec_offs_n_fields(offsets);
Expand Down Expand Up @@ -1190,7 +1190,7 @@ void btr_search_drop_page_hash_index(buf_block_t* block)

rec = page_get_infimum_rec(page);
rec = page_rec_get_next_low(rec, page_is_comp(page));
if (rec_is_default_row(rec, index)) {
if (rec_is_metadata(rec, index)) {
rec = page_rec_get_next_low(rec, page_is_comp(page));
}

Expand Down Expand Up @@ -1398,7 +1398,7 @@ btr_search_build_page_hash_index(

rec = page_rec_get_next_const(page_get_infimum_rec(page));

if (rec_is_default_row(rec, index)) {
if (rec_is_metadata(rec, index)) {
rec = page_rec_get_next_const(rec);
if (!--n_recs) return;
}
Expand Down Expand Up @@ -1862,7 +1862,7 @@ btr_search_update_hash_on_insert(btr_cur_t* cursor, rw_lock_t* ahi_latch)
n_bytes, index->id);
}

if (!page_rec_is_infimum(rec) && !rec_is_default_row(rec, index)) {
if (!page_rec_is_infimum(rec) && !rec_is_metadata(rec, index)) {
offsets = rec_get_offsets(
rec, index, offsets, true,
btr_search_get_n_fields(n_fields, n_bytes), &heap);
Expand Down
3 changes: 2 additions & 1 deletion storage/innobase/data/data0data.cc
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,8 @@ byte data_error;

/** Trim the tail of an index tuple before insert or update.
After instant ADD COLUMN, if the last fields of a clustered index tuple
match the 'default row', there will be no need to store them.
match the default values that were explicitly specified or implied during
ADD COLUMN, there will be no need to store them.
NOTE: A page latch in the index must be held, so that the index
may not lose 'instantness' before the trimmed tuple has been
inserted or updated.
Expand Down
2 changes: 1 addition & 1 deletion storage/innobase/dict/dict0stats.cc
Original file line number Diff line number Diff line change
Expand Up @@ -1084,7 +1084,7 @@ dict_stats_analyze_index_level(
btr_pcur_get_rec(&pcur), page_is_comp(page))) {
ut_ad(btr_pcur_is_on_user_rec(&pcur));
if (level == 0) {
/* Skip the 'default row' pseudo-record */
/* Skip the metadata pseudo-record */
ut_ad(index->is_instant());
btr_pcur_move_to_next_user_rec(&pcur, mtr);
}
Expand Down
2 changes: 1 addition & 1 deletion storage/innobase/fts/fts0fts.cc
Original file line number Diff line number Diff line change
Expand Up @@ -3733,7 +3733,7 @@ fts_get_max_doc_id(
goto func_exit;
}

ut_ad(!rec_is_default_row(rec, index));
ut_ad(!rec_is_metadata(rec, index));
offsets = rec_get_offsets(
rec, index, offsets, true, ULINT_UNDEFINED, &heap);

Expand Down
10 changes: 5 additions & 5 deletions storage/innobase/handler/handler0alter.cc
Original file line number Diff line number Diff line change
Expand Up @@ -4236,7 +4236,7 @@ innobase_add_virtual_try(
return innodb_update_n_cols(user_table, new_n, trx);
}

/** Insert into SYS_COLUMNS and insert/update the 'default row'
/** Insert into SYS_COLUMNS and insert/update the hidden metadata record
for instant ADD COLUMN.
@param[in,out] ctx ALTER TABLE context for the current partition
@param[in] altered_table MySQL table that is being altered
Expand Down Expand Up @@ -4304,7 +4304,7 @@ innobase_add_instant_try(
/* For fixed-length NOT NULL 'core' columns,
get a dummy default value from SQL. Note that
we will preserve the old values of these
columns when updating the 'default row'
columns when updating the metadata
record, to avoid unnecessary updates. */
ulint len = (*af)->pack_length();
DBUG_ASSERT(d->type.mtype != DATA_INT
Expand Down Expand Up @@ -4371,7 +4371,7 @@ innobase_add_instant_try(
memset(roll_ptr, 0, sizeof roll_ptr);

dtuple_t* entry = row_build_index_entry(row, NULL, index, ctx->heap);
entry->info_bits = REC_INFO_DEFAULT_ROW;
entry->info_bits = REC_INFO_METADATA;

mtr_t mtr;
mtr.start();
Expand All @@ -4391,7 +4391,7 @@ innobase_add_instant_try(
NULL, trx, ctx->heap, NULL);

dberr_t err;
if (rec_is_default_row(rec, index)) {
if (rec_is_metadata(rec, index)) {
ut_ad(page_rec_is_user_rec(rec));
if (!page_has_next(block->frame)
&& page_rec_is_last(rec, block->frame)) {
Expand All @@ -4404,7 +4404,7 @@ innobase_add_instant_try(
page as a result of the update. */
upd_t* update = upd_create(index->n_fields, ctx->heap);
update->n_fields = n;
update->info_bits = REC_INFO_DEFAULT_ROW;
update->info_bits = REC_INFO_METADATA;
/* Add the default values for instantly added columns */
for (unsigned i = 0; i < n; i++) {
upd_field_t* uf = upd_get_nth_field(update, i);
Expand Down
3 changes: 2 additions & 1 deletion storage/innobase/include/data0data.h
Original file line number Diff line number Diff line change
Expand Up @@ -638,7 +638,8 @@ struct dtuple_t {

/** Trim the tail of an index tuple before insert or update.
After instant ADD COLUMN, if the last fields of a clustered index tuple
match the 'default row', there will be no need to store them.
match the default values that were explicitly specified or implied
during ADD COLUMN, there will be no need to store them.
NOTE: A page latch in the index must be held, so that the index
may not lose 'instantness' before the trimmed tuple has been
inserted or updated.
Expand Down
Loading

0 comments on commit 755187c

Please sign in to comment.