This patch adds for "--ps-protocol" second execution
of queries "SELECT".
Also in this patch it is added ability to disable/enable
(--disable_ps2_protocol/--enable_ps2_protocol) second
execution for "--ps-prototocol" in testcases.
btr_lift_page_up(): If the leaf page only contains a hidden metadata
record for MDEV-11369 instant ADD COLUMN, convert the table to the
canonical format like we are supposed to do whenever the table
becomes empty.
prepare_inplace_add_virtual(): Over-estimate the size of the arrays
by not subtracting table->s->virtual_fields (which may refer to
stored, not virtual generated columns). InnoDB only distinguishes
virtual columns.
- InnoDB fails to skip newly created column while checking for
change column when table is in redundant row format. This issue
is caused the MDEV-18035 (ccb1acbd3c)
instant_alter_column_possible(): Relax a too strict debug assertion.
The existence of an index stub or a corrupted index on virtual columns
does not imply that virtual columns exist.
In commit 7eda556196 we removed a
valid debug assertion.
AddressSanitizer would trip when writing undo log for an INSERT
operation that follows the problematic ALTER TABLE because the
v_indexes would refer to an index object that was freed during
the execution of ALTER TABLE.
The operation to remove NOT NULL attribute from a column should
lead into any affected indexes to be dropped and re-created.
But, the SQL layer set the ha_alter_info->handler_flags to
HA_INPLACE_ADD_UNIQUE_INDEX_NO_WRITE|ALTER_COLUMN_NULLABLE
(that is, InnoDB was asked to add an index and change the column,
but not to drop the index that depended on the column).
Let us restore the debug assertion that catches this problem
outside AddressSanitizer, and 'defuse' the offending ALTER TABLE
statement in the test until something has been fixed in the SQL layer.
dict_v_idx_t node was shared between two dict_v_col_t objects because
of wrong object copy. Replace memory plain copy with copy constructor.
Tha patch also removes n_v_indexes property and improves "page full"
judgements for trx_undo_log_v_idx().
dict_col_t::same_encoding(), dict_col_t::same_format(): Allow
an instantaneous change of a column to a compatible encoding,
just like ha_innobase::can_convert_string() and similar functions do.
In commit 0e5a4ac253 (MDEV-15562)
we introduced a bogus debug assertion, demanding that dict_col_t::len
never exceed some maximum value. The intention was to match what
dict_index_add_col() is doing. But, the assignment field->fixed_len = 0
applies to dict_field_t::fixed_len, not dict_col_t::len!
- Instant alter should change the metadata alone when table is
discarded. It shouldn't try to add metadata record in clustered index.
Also make the clustered index to non-instant format.
ha_innobase::commit_inplace_alter_table(): After
ALTER_STORED_COLUMN_ORDER, ensure that the virtual column metadata
will be reloaded also when the table is not being rebuilt.
We must relax too strict debug assertions. For latin1_swedish_ci,
mtype=DATA_CHAR or mtype=DATA_VARCHAR will be used instead of
mtype=DATA_MYSQL or mtype=DATA_VARMYSQL. Likewise, some changes of
dtype_get_charset_coll() do not affect the data type encoding,
but only any indexes that are defined on the column.
Charset::same_encoding(): Check whether two charset-collations have
the same character set encoding.
dict_col_t::same_encoding(): Check whether two character columns
have the same character set encoding.
dict_col_t::same_type(): Check whether two columns have a compatible
data type encoding.
dict_col_t::same_format(), dict_table_t::instant_column(): Do not
compare mtype or the charset-collation of prtype directly.
Rely on dict_col_t::same_type() instead.
dtype_get_charset_coll(): Narrow the return type to uint16_t.
This is a refined version of a fix that was developed by
Thirunarayanan Balathandayuthapani.
innobase_drop_foreign_try(): Don't evict and reload the dict_foreign_t
during instant ALTER TABLE if the FOREIGN KEY constraint is being
dropped.
The MDEV-19630 fix (commit 07b1a26c33)
was incomplete, because it did not cover a case where the
FOREIGN KEY constraint is being dropped.
Thanks to Eugene Kosov for noting that the fix is incomplete.
It turns out that on instant DROP/reorder column (MDEV-15562),
we must always write the metadata record, even though the table
was empty. Alternatively, we should guarantee that all undo
log records for the table have been purged. (Attempting to do
that by updating table_id leads to other problems; see
commit 1b31d8852c00b4bab6e6fe179b97db45ccb8d535.)
It would be tempting to remove dict_index_t::clear_instant_alter()
altogether, but it turns that we need that when the instant ALTER TABLE
operation of a first-time DROP COLUMN is being rolled back.
innobase_instant_try(): Clarify a comment. Purge never calls
dict_index_t::clear_instant_alter(), but it may invoke
dict_index_t::clear_instant_add(). On first-time instant DROP/reorder,
always write a metadata record, even if the table is empty.
The crash scenario is as follows:
(1) A non-empty table exists.
(2) MDEV-15562 instant ADD/DROP/reorder has been invoked.
(3) Some purgeable undo log exists for the table.
(4) The table becomes empty, containing not even any delete-marked records,
only containing the hidden metadata record that was added in (2).
(5) An instant ADD/DROP/reorder column is executed, and the table
is emptied and the (2) metadata removed.
(6) Purge processes an undo log record from (3), which will refer to
a non-existent clustered index field, because the metadata that
was created in (2) was remoeved in (5).
We fix this by adjusting step (5) so that we will never remove the
MDEV-15562-style metadata record. Removing the MDEV-11369 metadata
record (instant ADD COLUMN to the end of the table) is completely
fine at any time when the table becomes empty, because
dict_index_t::n_fields will remain unchanged.
innobase_instant_try(): Never remove the MDEV-15562 metadata record.
page_cur_delete_rec(): Do not reset FIL_PAGE_TYPE when the
MDEV-15562 metadata record is being removed as part of
btr_cur_pessimistic_update() invoked by innobase_instant_try().
get_col_list_to_be_dropped() incorrectly returned uninteresting instantly
dropped column which was missing in a new dict_index_t
get_col_list_to_be_dropped(): rename to collect_columns_from_dropped_indexes
and stop return dropped columns
btr_push_update_extern_fields(): Add a parameter for the original number
of fields in the record before btr_cur_trim(). Assume that this function
will only be called for the clustered index, which is the only index
that can contain off-page columns.
trx_undo_prev_version_build(), btr_cur_pessimistic_update():
Only invoke btr_push_update_extern_fields() for the clustered index.
which are pointed to the table being altered
Problem:
========
InnoDB failed to change the column name present in foreign key cache
for instant add column. So it leads to column mismatch for the consecutive
rename of column.
Solution:
=========
Evict the foreign key information from cache and load the foreign
key information again for instant operation.
instant_alter_column_possible(): Do not support instantaneous removal
of NOT NULL if the table needs to be rebuilt for removing the hidden
FTS_DOC_ID column. This is not ideal and should ultimately be fixed
properly in MDEV-17459.
This basically is a duplicate of MDEV-18219, proving that the
assertion was not relaxed correctly.
dict_index_t::in_instant_init: A debug flag that will only be set in
btr_cur_instant_init_low() in order to suppress the assertion failure
in rec_init_offsets() for that code path only.
MDEV-11369 (instant ADD COLUMN) introduced a regression in the case the
leftmost leaf page of the clustered index is empty except for the
hidden metadata record.
btr_pcur_store_position(): If the only record in the leftmost leaf page
is the metadata record, store the position before the first user record
in the tree.