MDEV-26951 gcol.innodb_virtual_basic fails
In this commit, the ultimate solution is given: no more error-prone retries
in the depths of purge!
All the mdl acquisitions now happen in row_purge_parse_undo_rec().
Rationale:
* innodb_acquire_mdl also reopens table data dictionary.
* It reacquires it and never releases
* It can open to a different table pointer. Therefore, data dictionary
should be updated at the caller side.
* Either we should release the data dictionary opened in innodb_acquire_mdl
and reopen in row_purge_parse_undo_rec, or keep it, but propogate the
changed pointer. If not, then SEGFAULT, data corruption, or unreleased
table instance are possible.
This commit chooses the first way -- keep the data dictionary opened.
It is technically hard to propogate table changes from any
innobase_allocate_row_for_vcol call, so it is decided to make the table
properly opened to the moment of allocation. Besides, this can also stand
as a crude port of 10.5 behavior.
innodb_find_table_for_vc: innodb_acquire_mdl call is removed. THDVAR check
is now only reasonable for an assertion
row_purge_parse_undo_rec: acquire mdl (and open a mariadb table) for any
table that has vcol indexes. For the rest of the tables, dict_sys.latch
is acquired.
dict_table_t::vc_templ: the allocations are supposed to be done under
dict_sys.mutex protection. NULL check should be also atomic with the
allocation (see switch (type) in row_purge_parse_undo_rec for example)
innobase_create_v_templ: is introduced as a shortcut for an allocation.
innodb_acquire_mdl: table_name_parse is now protected by dict_sys.latch
table->release() is also made under MDL or latch. Rationale:
failing assertion `ctx0->old_table->get_ref_count() == 1` in
ha_innobase::commit_inplace_alter_table.
After maria_table open, dict_sys.latch is acquired.
This is also to protect table_name_parse after table open.
We can't open it only when mariadb_table is failed to open,
because the tables could've been renamed in any combinations while
lathces are released, and therefore MDL wouldn't protect this table
data dictionary (because it can be different table now).
purge_vcol_info_t: everything is removed except table.