Commit graph

1861 commits

Author SHA1 Message Date
Nikita Malyavin
a8a925dd22 Merge branch bb-10.2-release into bb-10.3-release 2021-05-04 14:49:31 +03:00
Nikita Malyavin
300253acf1 revive innodb_debug_sync
innodb_debug_sync was introduced in commit
b393e2cb0c and reverted in
commit fc58c17216 due to memory leak reported
by valgrind, see MDEV-21336.

The leak is now fixed by adding `rw_lock_free(&slot->debug_sync_lock)`
after background thread working loop is finished, and the patch is
reapplied, with respect to c++98 fixes by Marko.

The missing DEBUG_SYNC for MDEV-18546 in row0vers.cc is also reapplied.
2021-04-27 11:51:17 +03:00
Marko Mäkelä
29b2f3dbb5 MDEV-24545 Sequence created by one connection remains invisible to another
row_merge_is_index_usable(): Allow access to any SEQUENCE, even if it was
created after the read view. SQL sequences are no-rollback tables with no
history at all.
2021-04-27 08:44:28 +03:00
Marko Mäkelä
c425d93b92 Merge 10.2 into 10.3
except commit 1288dfffe7
2021-04-24 10:37:21 +03:00
Marko Mäkelä
25ed665a20 MDEV-25459 MVCC read from index on CHAR or VARCHAR wrongly omits rows
row_sel_sec_rec_is_for_clust_rec(): If the field in the
clustered index record stored off page, always fetch it,
also when the secondary index field has been built on the
entire column. This was broken ever since the InnoDB Plugin
for MySQL Server 5.1 introduced ROW_FORMAT=DYNAMIC and
ROW_FORMAT=COMPRESSED for InnoDB tables. That code was first
introduced in this tree in
commit 3945d5e554.

For the original ROW_FORMAT=REDUNDANT and the MySQL 5.0.3
ROW_FORMAT=COMPRESSED, there was no problem, because for
those tables we always stored at least a 768-byte prefix of
each column in the clustered index record.

row_sel_sec_rec_is_for_blob(): Allow prefix_len==0 for matching
the full column.
2021-04-24 09:26:49 +03:00
Eugene Kosov
64eeb250eb MDEV-25457 Server crashes in row_undo_mod_clust_low upon rollback of read-only transaction
node->index was NULL.
But it's possible to get dict_table_t* from another source.
2021-04-21 17:42:16 +03:00
Marko Mäkelä
75c01f39b1 Merge 10.2 into 10.3 2021-04-21 07:25:48 +03:00
Eugene Kosov
a3871cd283 MDEV-22255 SIGABRT: Assertion id' failed in trx_write_trx_id on INSERT | Assertion id > 0' failed in trx_write_trx_id | Assertion val > 0' failed in row_upd_index_entry_sys_field | Assertion thr_get_trx(thr)->id || index->table->no_rollback()' failed. 2021-04-15 17:53:33 +03:00
Marko Mäkelä
b8c8692fd9 MDEV-24620 ASAN heap-buffer-overflow in btr_pcur_restore_position()
Between btr_pcur_store_position() and btr_pcur_restore_position()
it is possible that purge empties a table and enlarges
index->n_core_fields and index->n_core_null_bytes.
Therefore, we must cache index->n_core_fields in
btr_pcur_t::old_n_core_fields so that btr_pcur_t::old_rec can be
parsed correctly.

Unfortunately, this is a huge change, because we will replace
"bool leaf" parameters with "ulint n_core"
(passing index->n_core_fields, or 0 for non-leaf pages).
For special cases where we know that index->is_instant() cannot hold,
we may also pass index->n_fields.
2021-04-13 10:28:13 +03:00
Marko Mäkelä
6e6318b29b Merge 10.2 into 10.3 2021-04-13 10:26:01 +03:00
Thirunarayanan Balathandayuthapani
cf2c6b7f8d MDEV-24971 InnoDB access freed virtual column after rollback of secondary index
Problem:
========
 InnoDB fails to clean the index stub if it fails to add the
virtual index which contains new virtual column. But it clears
the newly virtual column from index in clear_added_indexes()
during inplace_alter_table. On commit, InnoDB evicts and
reload the table. In case of rollback, it doesn't happen.
InnoDB clears the ABORTED index while opening the table
or doing the DDL. In the mean time, InnoDB can access
the dropped virtual index columns while creating prebuilt
or rollback of concurrent DML.

Solution:
==========
(1) InnoDB should maintain newly added virtual column while
rollbacking the newly added virtual index.
(2) InnoDB must not defer the index removal
if the alter table is executed with LOCK=EXCLUSIVE.
(3) For LOCK=SHARED, InnoDB should check whether the table
has any other transaction lock other than alter transaction
before deferring the index stub.

Replaced has_new_v_col with dict_add_vcol_info in dict_index_t to
indicate whether the index has any new virtual column.

dict_index_t::has_new_v_col(): Returns whether the index has
newly added virtual column, it doesn't say which columns are
newly added virtual column

ha_innobase_inplace_ctx::is_new_vcol(): Return whether the
given column is added as a part of the current alter.

ha_innobase_inplace_ctx::clean_new_vcol_index(): Copy the newly
added virtual column to new_vcol_info in dict_index_t. Replace
the column in the index fields with virtual column stored
in new_vcol_info.

dict_index_t::assign_new_v_col(): Store the number of virtual
column added in index as a part of alter table.

dict_index_t::get_n_new_vcol(): Get the number of newly added
virtual column

dict_index_t::assign_drop_v_col(): Allocate the memory for
adding new virtual column in new_vcol_info.

dict_index_t::add_drop_v_col(): Add the newly added virtual
column in new_vcol_info.

dict_table_t::has_lock_for_other_trx(): Whether the table has
any other transaction lock than given transaction.

row_merge_drop_indexes(): Add parameter alter_trx and check
whether the table has any other lock than alter transaction.
2021-04-12 16:06:06 +05:30
Thirunarayanan Balathandayuthapani
1ac4d0c168 BtrBulk::table_name(): Return the table name while displaying
table name for fts diagnostics
2021-04-09 17:38:21 +05:30
Marko Mäkelä
450c017c2d Merge 10.2 into 10.3 2021-04-09 14:32:06 +03:00
Thirunarayanan Balathandayuthapani
5a3151bcda Improve diagnostics in order to catch MDEV-18868 and similar bugs 2021-04-09 12:01:42 +05:30
Marko Mäkelä
d6d3d9ae2f Merge 10.2 into 10.3 2021-03-31 08:01:03 +03:00
Thirunarayanan Balathandayuthapani
b771ab242b MDEV-25200 Index count mismatch due to aborted FULLTEXT INDEX
- Aborting of fulltext index creation fails to remove the
index from sys indexes table. When we try to reload the
table definition, InnoDB fails with index count mismatch
error. InnoDB should remove the index from sys indexes while
rollbacking the secondary index creation.
2021-03-30 20:40:14 +05:30
Thirunarayanan Balathandayuthapani
108ba4c380 MDEV-15527 page_compressed compressed page partially during import tablespace
- Post push to address 32-bit build failure.
2021-03-30 20:34:39 +05:30
Thirunarayanan Balathandayuthapani
c468d5cb50 MDEV-15527 page_compressed compressed page partially during import tablespace
- Importing table operation fails to punch the hole in
the filesystem when page compressed table is involved.
To achieve that, InnoDB firstly punches the hole for
the IOBuffer size(1MB). After that, InnoDB should write
page by page when page compression is involved.
2021-03-30 15:18:06 +05:30
Marko Mäkelä
3157fa182a Merge 10.2 into 10.3 2021-03-27 16:11:26 +02:00
Marko Mäkelä
a6d66fe75e MDEV-24786: row_upd_clust_step() skips mtr_t::commit() on virtual column error
The function row_upd_clust_step() is invoking several static functions,
some of which used to commit the mini-transaction in some cases.
If innobase_get_computed_value() would fail due to some reason,
we would fail to invoke mtr_t::commit() and release buffer pool
page latches. This would likely lead to a hanging server later.

This regression was introduced in
commit 97db6c15ea (MDEV-20618).

row_upd_index_is_referenced(), row_upd_sec_index_entry(),
row_upd_sec_index_entry(): Cleanup: Replace some ibool with bool.

row_upd_clust_rec_by_insert(), row_upd_clust_rec(): Guarantee that
the mini-transaction will always remain in active state.

row_upd_del_mark_clust_rec(): Guarantee that
the mini-transaction will always remain in active state.
This fixes one "leak" of mini-transaction on DB_COMPUTE_VALUE_FAILED.

row_upd_clust_step(): Use only one return path, which will always
invoke mtr.commit(). After a failed row_upd_store_row() call, we
will no longer "leak" the mini-transaction.

This fix was verified by RQG on 10.6 (depending on MDEV-371 that
was introduced in 10.4). Unfortunately, it is challenging to
create a regression test for this, and a test case could soon become
invalid as more bugs in virtual column evaluation are fixed.
2021-03-26 14:12:39 +02:00
Marko Mäkelä
96dd4b53c1 MDEV-8708 fixup: Remove dead code 2021-03-19 18:18:45 +02:00
Thirunarayanan Balathandayuthapani
eb7c5530ec MDEV-24730 Insert log operation fails after purge resets n_core_fields
Online log for insert operation of redundant table fails with
index->is_instant() assert. Purge can reset the n_core_fields when
alter is waiting to upgrade MDL for commit phase of DDL. In the
meantime, any insert DML tries to log the operation fails with
index is not being instant.

row_log_get_n_core_fields(): Get the n_core_fields of online log
for the given index.

rec_get_converted_size_comp_prefix_low(): Use n_core_fields of online
log when InnoDB calculates the size of data tuple during redundant
row format table rebuild.

rec_convert_dtuple_to_rec_comp(): Use n_core_fields of online log
when InnoDB does the conversion of data tuple to record during
redudant row format table rebuild.

- Adding the test case which has more than 129 instant columns.
2021-03-12 16:56:47 +05:30
Marko Mäkelä
bcd160753c Merge 10.2 into 10.3 2021-03-05 10:06:42 +02:00
Marko Mäkelä
7759991a06 fixup 58b56f14a0: Remove dead code
row_prebuilt_t::m_no_prefetch: Remove (it was always false).
row_prebuilt_t::m_read_virtual_key: Remove (it was always false).

Only ha_innopart ever set these fields.
2021-03-04 18:11:25 +02:00
Sergei Golubchik
60ea09eae6 Merge branch '10.2' into 10.3 2021-02-01 13:49:33 +01:00
Thirunarayanan Balathandayuthapani
479b4214fa MDEV-24547 Update fails when online alter does rollback due to MDL time out
When online alter rollbacks due to MDL time out, it doesn't mark the
index online status as ONLINE_INDEX_ABORTED. Concurrent update fails
to update the secondary index while building the entry.
InnoDB should check the online status of the secondary index before
building the secondary index entry.

Reviewed-by: Marko Mäkelä
2021-01-19 16:18:37 +05:30
Nikita Malyavin
f0baa86484 ut_ad(err != DB_DUPLICATE_KEY) in row_rename_table_for_mysql 2021-01-05 19:19:27 +10:00
Oleksandr Byelkin
25561435e0 Merge branch '10.2' into 10.3 2020-12-23 19:28:02 +01:00
Aleksey Midenkov
932ec586aa MDEV-23644 Assertion on evaluating foreign referential action for self-reference in system versioned table
First part of the fix (row0mysql.cc) addresses external columns when adding history
row on referential action. The full data must be retrieved before the
row is inserted.

Second part of the fix (the rest) avoids duplicate primary key error between
the history row generated on referential action and the history row
generated by SQL command. Both command and referential action can
happen on same table since foreign key can be self-reference (parent
and child tables are same). Moreover, the self-reference can refer
multiple rows when the key is non-unique. In such case history is
generated by referential action occured on first row but processed all
rows by a matched key. The second round is when the next row is
processed by a command but history already exists. In such case we
check TRX_ID of existing history row and if it is the same we assume
the above situation and skip adding one more history row or failing
the command.
2020-12-22 03:33:53 +03:00
Aleksey Midenkov
7410ff436e MDEV-21138 Assertion col->ord_part' or f.col->ord_part' failed in row_build_index_entry_low
First part (row0mysql.cc) fixes ins_node_set_new_row() usage workflow
as it is designed to operate on empty row (see row_get_prebuilt_insert_row()
for example).

Second part (row0ins.cc) fixes duplicate key error in FTS_DOC_ID_INDEX
since history rows must not generate entries in that index. We detect
FTS_DOC_ID_INDEX by a number of attributes and skip it if the row is
historical.

Misc fixes:

row_build_index_entry_low() does not accept non-NULL tuple
for FTS index (subject assertion fails), assertion (index->type !=
DICT_FTS) adds code understanding.

Now as historical_row is copied in row_update_vers_insert() there is
no need to copy the row twice: ROW_COPY_POINTERS is used to build
historical_row initially.

dbug_print_rec() debug functions.
2020-12-22 03:33:53 +03:00
Nikita Malyavin
83d2e0841e MDEV-24041 Generated column DELETE with FOREIGN KEY crash InnoDB
row_upd_clust_step() calls row_upd_del_mark_clust_rec() which would
allocate some memory in row_ins_foreign_fill_virtual(). Then,
row_upd_store_row() would access the allocated memory, but only after
potentially freeing that memory by invoking mem_heap_empty(),
leading to ASAN heap-use-after-free diagnostics.

row_ins_foreign_fill_virtual(): Use a more appropriate memory heap with a
longer lifetime.
2020-12-18 20:17:45 +10:00
Marko Mäkelä
73f34336e3 MDEV-24323 Crash on recovery after kill during instant ADD COLUMN
row_undo_ins_parse_undo_rec(): Do not try to read non-existing
virtual column information for the metadata record.
2020-12-01 15:24:49 +02:00
Marko Mäkelä
81ab9ea63f Merge 10.2 into 10.3 2020-12-01 14:55:46 +02:00
Marko Mäkelä
1c9833c511 Cleanup: row_log_free()
The nonnull attribute is not applicable to parameters that are
passed by reference, at least not in the Intel compiler.
Let us remove the reference indirection, which was only there
so that the pointer could be assigned to NULL, and let the
callers perform that task.

row_log_allocate(): Fix a bug in out-of-memory error handling
that would leave a pointer to freed memory.
2020-11-25 10:54:38 +02:00
Marko Mäkelä
2b6f804490 Merge 10.2 into 10.3 2020-10-28 10:44:40 +02:00
Eugene Kosov
afc9d00c66 MDEV-23991 dict_table_stats_lock() has unnecessarily long scope
Patch removes dict_index_t::stats_latch. Table/index statistics now
protected with dict_sys->mutex. That way statistics computation can
happen in parallel in several threads and dict_sys->mutex will be locked
only for a short period of time.

This patch is a joint work with Marko Mäkelä

dict_index_t:🔒 make mutable which allows to pass const pointer
when only lock is touched in an object

btr_height_get()
btr_get_size(): make index argument const for better type safety

btr_estimate_number_of_different_key_vals(): now returns computed values
instead of setting fields in dict_index_t directly

remove everything related to dict_index_t::stats_latch

dict_stats_index_set_n_diff(): now returns computed values instead
of setting fields in dict_index_t directly

dict_stats_analyze_index():  now returns computed values instead
of setting fields in dict_index_t directly

Reviewed by: Marko Mäkelä
2020-10-27 19:09:20 +03:00
Marko Mäkelä
e3d692aa09 Merge 10.2 into 10.3 2020-10-22 08:26:28 +03:00
Marko Mäkelä
620ea816ad Merge 10.1 into 10.2 2020-10-21 14:02:04 +03:00
Marko Mäkelä
0049d5b515 Revert MDEV-23484 Rollback unnecessarily acquires dict_operation_lock
In row_undo_ins_remove_clust_rec() and similar places,
an assertion !node->trx->dict_operation_lock_mode could fail,
because an online ALTER is not allowed to run at the same time
while DDL operations on the table are being rolled back.

This race condition would be fixed by always acquiring an InnoDB
table lock in ha_innobase::prepare_inplace_alter_table() or
prepare_inplace_alter_table_dict(), or by ensuring that recovered
transactions are protected by MDL that would block concurrent DDL
until the rollback has been completed.

This reverts commit 1509363970
and commit 22c4a7512f.
2020-10-20 19:55:16 +03:00
Sergei Petrunia
3e807d255e MDEV-23938: innodb row_search_idx_cond_check handle ICP_ABORTED_BY_USER
- row_search_mvcc() should return DB_INTERRUPTED when it got killed.
- Add a syncpoint for the ICP check.
- Add test coverage for killed-during-ICP-check scenario

Backport of MDEV-22761 fixes for ICP from 10.4 commits:
* a6f956488c
* c03885cd9c

XtraDB was fixed in deb3b9a174

Reviewer: Daniel Black
2020-10-16 09:44:03 +11:00
Thirunarayanan Balathandayuthapani
6504d3d229 MDEV-23722 InnoDB: Assertion: result != FTS_INVALID in fts_trx_row_get_new_state
Marking of deletion of row in fts index happens twice in
self-referential foreign key relation. So while performing
referential checks of foreign key, InnoDB can avoid updating
of fts index if the foreign key has self-referential relationship.

Reviewed-by: Marko Mäkelä
2020-10-08 19:41:03 +05:30
Marko Mäkelä
cbcb4ecabb Merge 10.2 into 10.3 2020-09-21 11:04:04 +03:00
Nikita Malyavin
ae8ff3a067 MDEV-20396 Server crashes after DELETE with SEL NULL Foreign key and a
virtual column in index

Problem:
row_ins_foreign_fill_virtual was unconditionally set virtual fields to NULL
even though the field is not a part of a foreign key
(but a part of an index)

Solution:
The new virtual value should be computed with regard to cascade updates.
2020-09-14 18:08:56 +10:00
Thirunarayanan Balathandayuthapani
75e82f71f1 MDEV-18867 Long Time to Stop and Start
fts_drop_orphaned_tables() takes long time to remove the orphaned
FTS tables. In order to reduce the time, do the following:

- Traverse fil_system.space_list and construct a set of
table_id,index_id of all FTS_*.ibd tablespaces.
- Traverse the sys_indexes table and ignore the entry
from the above collection if it exist.
- Existing elements in the collection can be considered as
orphaned fts tables. construct the table name from
(table_id,index_id) and invoke fts_drop_tables().
- Removed DICT_TF2_FTS_AUX_HEX_NAME flag usage from upgrade.
- is_aux_table() in dict_table_t to check whether the given name
is fts auxiliary table
fts_space_set_t is a structure to store set of parent table id
and index id
- Remove unused FTS function in fts0fts.cc
- Remove the fulltext index in row_format_redundant test case.
Because it deals with the condition that SYS_TABLES does have
corrupted entry and valid entry exist in SYS_INDEXES.
2020-09-10 14:10:26 +05:30
Marko Mäkelä
7e07e38cf6 Merge 10.2 into 10.3 2020-09-09 13:06:46 +03:00
Marko Mäkelä
040ae4c59b MDEV-22924 fixup: Replace C++11 auto 2020-09-09 13:02:25 +03:00
Marko Mäkelä
d44c0f46c5 MDEV-22924 fixup: Replace C++11 nullptr
Only starting with MariaDB Server 10.4 we may depend on C++11.
2020-09-09 12:26:51 +03:00
Marko Mäkelä
f99cace77f MDEV-22924 Corruption in MVCC read via secondary index
An unsafe optimization was introduced by
commit 2347ffd843 (MDEV-20301)
which is based on
mysql/mysql-server@3f3136188f or
mysql/mysql-server@647a3814a9
in MySQL 8.0.12 or MySQL 8.0.13
(which in turn is based on the contribution in MySQL Bug #84958).

Row_sel_get_clust_rec_for_mysql::operator(): In addition to checking
that the pointer to the record matches, also check the latest
modification of the page (FIL_PAGE_LSN) as well as the page identifier.
Only if all three match, it is safe to reuse cached_old_vers.

Row_sel_get_clust_rec_for_mysql::check_eq(): Assert that the PRIMARY KEY
of the cached old version of the record corresponds to the latest version.

We got a test case where CHECK TABLE, UPDATE and purge would be
hammering on the same table (with only 6 rows) and a pointer that
was originally pointing to a record pk=2 would match a cached_clust_rec
that was pointing to a record pk=1. In the diagnosed `rr replay` trace,
we would wrongly return an old cached version of the pk=1 record,
instead of retrieving the correct version of the pk=2 record. Because
of this, CHECK TABLE would fail to count one of the records in a
secondary index, and report failure.

This bug appears to affect MVCC reads via secondary indexes only.
The purge of history in secondary indexes uses a different code path,
and so do checks for implicit record locks.
2020-09-07 15:31:54 +03:00
Marko Mäkelä
c3752cef3c Merge 10.2 into 10.3 2020-09-03 09:26:54 +03:00
Thirunarayanan Balathandayuthapani
837bbbafc5 MDEV-23470 InnoDB: Failing assertion: cmp < 0 in row_ins_check_foreign_constraint
During insertion of clustered index, InnoDB does the check for foreign key
constraints. Problem is that it uses the clustered index entry to search
indexes of referenced tables and it could lead to unexpected result
when there is no foreign index.

Solution:
========
  Rebuild the tuple based on foreign column names before searching it
on reference index when there is no foreign index.
2020-09-02 16:16:45 +05:30