MDEV-15250 UPSERT during ALTER-TABLE results in 'Duplicate entry' er
ror for alter
- To prevent the fake duplicates, InnoDB can write online log entries
during transaction commit. By doing this, InnoDB can avoid logging
the rollbacked DML transaction.
- Store clust_index->online_log value as table pointer when
secondary indexes are being built. This is a quick way to
indicate whether the table has active DDL
- DML thread will apply the log using alter table transaction
when online log ran out of memory and index is completed.
- DML thread can set the log->error if it encounters any error
during row_log_apply(). In that case, DML thread will clear
all other online indexes log and mark the indexes as corrupted.
It preserves failed online log to indicate the error happened
in commit phase.
- ha_innobase::commit_inplace_alter_table does row_log_apply()
for the last batch of online index. It does frees the online log
for the completed index.
- Remove the old online log code in row_ins_clust_index_entry_low(),
row_ins_scan_sec_index_for_duplicate(), btr_cur_del_mark_set_clust_rec(),row_purge_*(), row_undo_*()
row_log_insert_handle(): Handles the insert undo log entries and
apply it to the online indexes log.
row_log_update_handle(): Handles the update, delete undo log entries
and apply it on the online indexes log.
row_log_undo_vers_record(): Get the clustered index record version
which was modified by the given undo log record.
row_log_vers_undo_match(): Get the correct version of clustered
index record which matches with undo log record offset and page number
trx_t::apply_online_log: Set to true in trx_undo_report_row_operation
when modified table has active DDL
trx_t::apply_log(): Apply the DML changes to online DDL tables.
dict_table_t::is_active_ddl(): Returns true whether the table has
any active DDL
trx_undo_rec_apply_log(): Parse the undo log and apply to the online
log tables if there is any active DDL exist.
trx_undo_rec_apply_insert(): Apply the TRX_UNDO_INSERT_REC undo log
record
trx_undo_rec_apply_update(): Apply the TRX_UNDO_UPD & TRX_UNDO_DEL
undo log record
trx_undo_rec_is_equal(): Check whether the given roll pointer's
page number and offset matches with the undo log record.
row_log_table_apply_convert_mrec(): Instead of returning DATA_TRUNCATED
error, InnoDB should throw DB_INVALID_NULL when InnoDB DDL encounters
NULL value for NOT NULL column
trx_undo_rec_info: Information about undo log record like
trx id, block, offset, type, cmpl_info, updated_extern,
undo_no, undo_rec, update vector
ha_innobase_inplace_ctx::log_handle_failure(): Handle the apply
log failure for online DDL operation
ha_innobase::column_bitmaps_signal(): Remove table->F_WRLCK
to make sure that indexed virtual column is computed when
table has active ddl
row_log_mark_other_online_index_abort(): Clear out all other
online index log after encountering the error during
row_log_apply() in DML thread
row_log_get_error(): Get the error happened during row_log_apply()
row_log_online_op(): Does apply the online log if index is completed
and ran out of memory. It returns false only if row_log_apply() fails
- Many test case were changed to suit the new behaviour.
Thanks to Marko Mäkelä for providing the initial prototype.