Commit graph

2922 commits

Author SHA1 Message Date
Marko Mäkelä
0dab74ff3f MDEV-28539 Some InnoDB counters are duplicating generic SHOW STATUS
The InnoDB srv_stats counters
n_rows_updated, n_rows_deleted, n_rows_inserted, and n_rows_read
are duplicating
Handler_update, Handler_delete, Handler_write, and Handler_read_ counters.

Updating those counters is not free, especially because some counters
are furthermore split to distinguish a rare case of modifying tables
in the system schema.
2022-06-03 12:20:20 +03:00
Marko Mäkelä
12aeb9fa15 MDEV-28542 Useless output in SHOW ENGINE INNODB STATUS
srv_printf_innodb_monitor(): Only display an ADAPTIVE HASH INDEX
section if the adaptive hash index is enabled.

ibuf_print(): Only display an INSERT BUFFER section if the
change buffer is not empty.
2022-06-03 12:20:19 +03:00
Sergei Golubchik
bf2bdd1a1a Merge branch '10.8' into 10.9 2022-05-19 14:07:55 +02:00
Sergei Golubchik
443c2a715d Merge branch '10.7' into 10.8 2022-05-11 12:21:36 +02:00
Sergei Golubchik
fd132be117 Merge branch '10.6' into 10.7 2022-05-11 11:25:33 +02:00
Sergei Golubchik
3bc98a4ec4 Merge branch '10.5' into 10.6 2022-05-10 14:01:23 +02:00
Sergei Golubchik
ef781162ff Merge branch '10.4' into 10.5 2022-05-09 22:04:06 +02:00
Sergei Golubchik
a70a1cf3f4 Merge branch '10.3' into 10.4 2022-05-08 23:03:08 +02:00
Oleksandr Byelkin
9614fde1aa Merge branch '10.2' into 10.3 2022-05-03 10:59:54 +02:00
Thirunarayanan Balathandayuthapani
fc391df546 MDEV-28399 Assertion failure in dict_table_check_for_dup_indexes upon concurrent DML/DDL
Problem:
========
 InnoDB DDL fails to remove the newly added table or index from
dictionary and index stub from the table cache if the alter
transaction encounters DEADLOCK error in commit phase.

Solution:
========
Restart the alter table transaction if it encounters DEADLOCK
in commit phase. So that index stubs and index, table removal from
dictionary can be done in rollback_inplace_alter_table()

- Added one assert in rollback_inplace_alter_table() to indicate that
the online log for the old table shouldn't exist.
2022-05-02 12:52:16 +05:30
Marko Mäkelä
8c1c61309d MDEV-27274: DROP TABLE does not delete detached InnoDB files
In commit 1bd681c8b3 (MDEV-25506 part 3)
the way how DDL transactions delete files was rewritten.
Only files that are actually attached to InnoDB tablespaces would be
deleted, and only after the DDL transaction was durably committed.

After a failed ALTER TABLE...IMPORT TABLESPACE, any data files that
the user might have moved to the data directory will not be attached
to the InnoDB data dictionary. Therefore, DROP TABLE would not
attempt to delete those files, and a subsequent CREATE TABLE would
fail. The logic was that the user who created the files outside the
DBMS is still the owner of those files, and InnoDB should not delete
those files because an "ownership transfer" (IMPORT TABLESPACE) was
not successfully completed.

However, not deleting those detached files could surprise users.

ha_innobase::delete_table(): Even if no tablespace exists, try to
delete any files that might match the table name.

Reviewed by: Thirunarayanan Balathandayuthapani
2022-04-29 12:32:44 +03:00
Marko Mäkelä
504a3b32f6 Merge 10.8 into 10.9 2022-04-28 15:54:03 +03:00
Marko Mäkelä
0806592ac8 MDEV-28422 Page split breaks a gap lock
btr_insert_into_right_sibling(): Inherit any gap lock from the
left sibling to the right sibling before inserting the record
to the right sibling and updating the node pointer(s).

lock_update_node_pointer(): Update locks in case a node pointer
will move.

Based on mysql/mysql-server@c7d93c274f
2022-04-27 13:38:08 +03:00
Marko Mäkelä
133c2129cd Merge 10.7 into 10.8 2022-04-27 10:43:00 +03:00
Marko Mäkelä
44a27a26e9 MDEV-28416 Incorrect AUTO_INCREMENT may be issued when close to UINT64_MAX
ha_innobase::get_auto_increment(): In the overflow check, account
for 64-bit unsigned integer wrap-around.

Based on mysql/mysql-server@25ecfe7f49
2022-04-27 08:08:06 +03:00
Marko Mäkelä
638afc4acf Merge 10.6 into 10.7 2022-04-26 18:59:40 +03:00
Marko Mäkelä
2c005261cb MDEV-26753 Assertion state == TRX_STATE_PREPARED ||... failed
dict_stats_save(): Do not attempt to commit an already committed
transaction.
2022-04-26 18:09:14 +03:00
Marko Mäkelä
2ca1123464 MDEV-26217 Failing assertion: list.count > 0 in ut_list_remove or Assertion `lock->trx == this' failed in dberr_t trx_t::drop_table
This follows up the previous fix in
commit c3c53926c4 (MDEV-26554).

ha_innobase::delete_table(): Work around the insufficient
metadata locking (MDL) during DML operations by acquiring exclusive
InnoDB table locks on all child tables. Previously, this was only
done on TRUNCATE and ALTER.

ibuf_delete_rec(), btr_cur_optimistic_delete(): Do not invoke
lock_update_delete() during change buffer operations.
The revised trx_t::commit(std::vector<pfs_os_file_t>&) will
hold exclusive lock_sys.latch while invoking fil_delete_tablespace(),
which in turn may invoke ibuf_delete_rec().

dict_index_t::has_locking(): A new predicate, replacing the dummy
!dict_table_is_locking_disabled(index->table). Used for skipping lock
operations during ibuf_delete_rec().

trx_t::commit(std::vector<pfs_os_file_t>&): Release the locks
and remove the table from the cache while holding exclusive
lock_sys.latch.

trx_t::commit_in_memory(): Skip release_locks() if dict_operation holds.

trx_t::commit(): Reset dict_operation before invoking commit_in_memory()
via commit_persist().

lock_release_on_drop(): Release locks while lock_sys.latch is
exclusively locked.

lock_table(): Add a parameter for a pointer to the table.
We must not dereference the table before a lock_sys.latch has
been acquired. If the pointer to the table does not match the table
at that point, the table is invalid and DB_DEADLOCK will be returned.

row_ins_foreign_check_on_constraint(): Improve the checks.
Remove a bogus DB_LOCK_WAIT_TIMEOUT return that was needed
before commit c5fd9aa562 (MDEV-25919).

row_upd_check_references_constraints(),
wsrep_row_upd_check_foreign_constraints(): Simplify checks.
2022-04-26 18:09:03 +03:00
Marko Mäkelä
e135edec3a Merge 10.5 into 10.6 2022-04-26 15:21:20 +03:00
Thirunarayanan Balathandayuthapani
7c0b9c6020 MDEV-15250 UPSERT during ALTER TABLE results in 'Duplicate entry' error for alter
- InnoDB should avoid bulk insert operation when table has active
DDL. Because bulk insert writes only one undo log as TRX_UNDO_EMPTY
and logging of concurrent DML happens at commit time uses undo log
record to parse and get the value and operation.

- Removed ROW_T_EMPTY, ROW_OP_EMPTY and their associated functions
and also the test case which tries to log the ROW_OP_EMPTY
when table has active DDL.
2022-04-26 16:22:56 +05:30
Thirunarayanan Balathandayuthapani
4b80c11f52 MDEV-15250 UPSERT during ALTER TABLE results in 'Duplicate entry' error for alter
- InnoDB DDL results in `Duplicate entry' if concurrent DML throws
duplicate key error. The following scenario explains the problem

connection con1:
  ALTER TABLE t1 FORCE;

connection con2:
  INSERT INTO t1(pk, uk) VALUES (2, 2), (3, 2);

In connection con2, InnoDB throws the 'DUPLICATE KEY' error because
of unique index. Alter operation will throw the error when applying
the concurrent DML log.

- Inserting the duplicate key for unique index logs the insert
operation for online ALTER TABLE. When insertion fails,
transaction does rollback and it leads to logging of
delete operation for online ALTER TABLE.
While applying the insert log entries, alter operation
encounters 'DUPLICATE KEY' error.

- To avoid the above fake duplicate scenario, InnoDB should
not write any log for online ALTER TABLE before DML transaction
commit.

- User thread which does DML can apply the online log if
InnoDB ran out of online log and index is marked as completed.
Set online log error if apply phase encountered any error.
It can also clear all other indexes log, marks the newly
added indexes as corrupted.

- Removed the old online code which was a part of DML operations

commit_inplace_alter_table() : Does apply the online log
for the last batch of secondary index log and does frees
the log for the completed index.

trx_t::apply_online_log: Set to true while writing the undo
log if the 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 if the table
has an active DDL

dict_index_t::online_log_make_dummy(): Assign dummy value
for clustered index online log to indicate the secondary
indexes are being rebuild.

dict_index_t::online_log_is_dummy(): Check whether the online
log has dummy value

ha_innobase_inplace_ctx::log_failure(): Handle the apply log
failure for online DDL transaction

row_log_mark_other_online_index_abort(): Clear out all other
online index log after encountering the error during
row_log_apply()

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. Returns false if apply log fails

UndorecApplier: Introduced a class to maintain the undo log
record, latched undo buffer page, parse the undo log record,
maintain the undo record type, info bits and update vector

UndorecApplier::get_old_rec(): Get the correct version of the
clustered index record that was modified by the current undo
log record

UndorecApplier::clear_undo_rec(): Clear the undo log related
information after applying the undo log record

UndorecApplier::log_update(): Handle the update, delete undo
log and apply it on online indexes

UndorecApplier::log_insert(): Handle the insert undo log
and apply it on online indexes

UndorecApplier::is_same(): Check whether the given roll pointer
is generated by the current undo log record information

trx_t::rollback_low(): Set apply_online_log for the transaction
after partially rollbacked transaction has any active DDL

prepare_inplace_alter_table_dict(): After allocating the online
log, InnoDB does create fulltext common tables. Fulltext index
doesn't allow the index to be online. So removed the dead
code of online log removal

Thanks to Marko Mäkelä for providing the initial prototype and
Matthias Leich for testing the issue patiently.
2022-04-25 18:52:19 +05:30
Marko Mäkelä
cba13079da Remove redundant innodb-page_compression_ tests
These were replaced with innodb.innodb_page_compressed
in commit 35095c458b
2022-04-25 10:42:57 +03:00
Marko Mäkelä
35095c458b Clean up the page_compressed tests
It suffices to test compression with one record. Restarting the
server is not really needed; we are exercising the log based recovery
in other tests, such as mariabackup.page_compression_level.
2022-04-25 10:19:12 +03:00
Marko Mäkelä
c009ce7dd0 MDEV-27094 Debug builds include useless InnoDB "disabled" options
This is a backport of commit 4489a89c71
in order to remove the test innodb.redo_log_during_checkpoint
that would cause trouble in the DBUG subsystem invoked by
safe_mutex_lock() via log_checkpoint(). Before
commit 7cffb5f6e8
these mutexes were of different type.

The following options were introduced in
commit 2e814d4702 (mariadb-10.2.2)
and have little use:

innodb_disable_resize_buffer_pool_debug had no effect even in
MariaDB 10.2.2 or MySQL 5.7.9. It was introduced in
mysql/mysql-server@5c4094cf49
to work around a problem that was fixed in
mysql/mysql-server@2957ae4f99
(but the parameter was not removed).

innodb_page_cleaner_disabled_debug and innodb_master_thread_disabled_debug
are only used by the test innodb.redo_log_during_checkpoint
that will be removed as part of this commit.

innodb_dict_stats_disabled_debug is only used by that test,
and it is redundant because one could simply use
innodb_stats_persistent=OFF or the STATS_PERSISTENT=0 attribute
of the table in the test to achieve the same effect.
2022-04-22 12:48:40 +03:00
Marko Mäkelä
6948abb94c Cleanup: Remove fil_names_write_bogus
Ever since commit 685d958e38
some Perl code in the test mariabackup.huge_lsn is writing names of
non-existing files to the InnoDB redo log and testing the recovery.
We do not need any debug instrumentation to duplicate that test.
2022-04-22 12:22:28 +03:00
Marko Mäkelä
fae0ccad6e Merge 10.5 into 10.6 2022-04-21 17:46:40 +03:00
Marko Mäkelä
620c55e708 Merge 10.4 into 10.5 2022-04-21 15:33:50 +03:00
Vlad Lesin
188aae65e4 MDEV-26224 InnoDB fails to remove AUTO_INCREMENT attribute
Reset dict_table_t::persistent_autoinc when inplace alter table is
committed successfully.
2022-04-21 15:23:21 +03:00
Marko Mäkelä
394784095e Merge 10.3 into 10.4 2022-04-21 11:33:59 +03:00
Sergei Golubchik
6f6c74b0d1 Merge branch '10.2' into 10.3 2022-04-21 10:05:50 +02:00
Thirunarayanan Balathandayuthapani
372b0e6355 MDEV-20194 Warnings inconsistently issued upon CHECK on table from older versions
The following condition has to added:
1) InnoDB fails to include the offset of the node pointer field
in non-leaf record for redundant row format.

2) If the Fixed length field does have only prefix length then
calculate the field maximum size as prefix length.

- Added the test case to test (2) and to check maximum number of
fields can exist in the index.
2022-04-20 19:55:17 +05:30
Marko Mäkelä
5aef0123a7 MDEV-28317 Assertion failures in row_undo_mod on recovery
Starting with 10.3, an assertion would fail on the rollback of
a recovered incomplete transaction if a table definition violates
a FOREIGN KEY constraint.

DICT_ERR_IGNORE_RECOVER_LOCK: Include also DICT_ERR_IGNORE_FK_NOKEY
so that trx_resurrect_table_locks() will be able to load
table definitions and resurrect IX locks. Previously, if the
FOREIGN KEY constraints of a table were incomplete, the table
would fail to load until rollback, and in 10.3 or later an assertion
would fail that the rollback was not protected by a table IX lock.

Thanks to commit 9de2e60d74 there
will be no problems to enforce subsequent FOREIGN KEY operations
even though a table with invalid REFERENCES clause was loaded.
2022-04-19 12:40:05 +03:00
Marko Mäkelä
e98013cb5c Merge 10.8 into 10.9 2022-04-13 13:39:00 +03:00
Nayuta Yanagisawa
cbf9d8a8d5 Merge 10.7 into 10.8 2022-04-13 17:52:27 +09:00
Marko Mäkelä
aa3a9d1ef5 Merge 10.6 into 10.7 2022-04-12 16:11:29 +03:00
Thirunarayanan Balathandayuthapani
011b332d81 MDEV-28037 Assertion `trx->bulk_insert' failed in innodb_prepare_commit_versioned
- Trigger statement initiate update statement after bulk insert
operation and leads to disable of bulk operation. During commit,
InnoDB expects transaction to be in bulk insert mode before
applying the bulk insert operation. InnoDB transaction should
apply all bulk insert operation before disabling bulk insert
operation.
2022-04-12 14:41:11 +05:30
Marko Mäkelä
7bccf3dd74 MDEV-28274 Assertion s <= READ_FIX failed in buf_page_t::set_state
buf_page_t::set_state(): Relax a debug assertion. It is fine to update
a read-fixed block descriptor to be both read-fixed and buffer-fixed.

buf_pool_t::watch_unset(): Fix some incorrect logic that was implemented
in commit e9e6db9355.

Thanks to Elena Stepanova for the test case.
2022-04-11 10:22:40 +03:00
Daniel Black
7ae46ced37 Merge branch 10.8 into 10.9
Closes #2084
2022-04-06 14:33:27 +10:00
Daniel Black
7b06bc9a94 Merge branch 10.7 into 10.8
Closes #2083
2022-04-06 14:23:20 +10:00
Thirunarayanan Balathandayuthapani
db655e1310 MDEV-28237 Assertion `0' failed in row_upd_sec_index_entry on DELETE
- InnoDB bulk insert operation fails to rollback when it detect
DB_DUPLICATE_KEY error. It leads to orphaned records in primary
indexes. Consecutive update/delete operation assumes that record
should exist in secondary index and it leads to failure.
2022-04-04 19:34:59 +05:30
Thirunarayanan Balathandayuthapani
b678f8811b MDEV-28138 MariaDB Assertion Failed in mtr_buf_t::has_space
- After MDEV-24621, InnoDB does buffer the insert bulk operation
for all indexes expect spatial one. But it leads to search the
primary key lookup and it leads to failure. So InnoDB should avoid
bulk insert when table has spatial index involved.
2022-04-04 19:34:36 +05:30
Marko Mäkelä
8680eedb26 Merge 10.8 into 10.9 2022-03-30 09:41:14 +03:00
Marko Mäkelä
5c69e93630 Merge 10.7 into 10.8 2022-03-30 09:34:07 +03:00
Marko Mäkelä
a4d753758f Merge 10.6 into 10.7 2022-03-30 08:52:05 +03:00
Marko Mäkelä
8f8ba75855 MDEV-27234: Data dictionary recovery was not READ COMMITTED
This also fixes MDEV-20198: Instant ALTER TABLE is not crash safe

InnoDB dictionary recovery wrongly used the READ UNCOMMITTED isolation
level, causing some mismatch. For example, if a table was renamed or
replaced in a transaction, according to READ UNCOMMITTED the table might
not exist at all.

We implement READ COMMITTED isolation level for accessing the dictionary
tables SYS_TABLES, SYS_COLUMNS, SYS_INDEXES, SYS_FIELDS, SYS_VIRTUAL,
SYS_FOREIGN, SYS_FOREIGN_COLS. For most of these tables, no secondary
index exists. For the secondary indexes (on SYS_TABLES.ID,
SYS_FOREIGN.FOR_NAME, SYS_FOREIGN.REF_NAME), we will always look up
the primary key in the clustered index and check if the record actually
is a committed version.

dict_check_sys_tables(): Recover tablespaces also from delete-marked
committed records, so that if a matching .ibd file exists, it will
be removed by fil_delete_tablespace() when the committed delete-marked
SYS_INDEXES record of the clustered index is purged
in row_purge_remove_clust_if_poss_low().

fil_ibd_open(): Change the Boolean parameter "validate" to a ternary
one, to suppress error messages when the file might not exist.
It is possible that a .ibd file was deleted and the server shut down
before the SYS_INDEXES and SYS_TABLES records were purged. Hence, if
dict_check_sys_tables() finds a committed delete-marked record,
we must not complain if the tablespace file is not found.
On Windows, we msut treat ERROR_PATH_NOT_FOUND (directory not found)
in the same way as ERROR_FILE_NOT_FOUND. This fixes a few failures where
a previous test successfully executed DROP DATABASE (and deleted all
files and the directory), but a committed delete-marked SYS_TABLES
record had not been purged before server restart.

dict_getnext_system_low(): Do not filter out delete-marked records.

dict_startscan_system(), dict_getnext_system(): Do filter out
delete-marked records, for accessing the INFORMATION_SCHEMA tables.

dict_sys_tables_rec_read(): Return the DB_TRX_ID of the committed
version of the record. This is needed in dict_load_table_low().

dict_load_foreign_cols(), dict_load_foreign(): Add a parameter for
the current transaction identifier. In some DDL operations, the
FOREIGN KEY constraints are being loaded from the data dictionary
before the DDL transaction has been committed. For SYS_FOREIGN
and SYS_FOREIGN_COLS, we must implement the special case of
READ COMMITTED that the changes of the uncommitted current transaction
are visible.

dict_load_foreign(): Validate the table name. We could find a
SYS_FOREIGN.ID via a committed delete-marked secondary index record
that does not match the REF_NAME or FOR_NAME of the secondary index record.

dict_load_index_low(): Optionally take the table as a parameter,
so that table->def_trx_id can be updated in case of a
committed delete-marked SYS_INDEXES record corresponding
to DROP INDEX, but not corresponding to an index stub of ADD INDEX.

dict_load_indexes(): Do not update table->def_trx_id
in case of delete-marked records.

rec_is_metadata(), rec_offs_make_valid(), rec_get_offsets_func(),
row_build_low(): Relax some assertions. We may now have
!index->is_instant() even if a metadata record is present in the index.
Previously, the recovery of instant ADD/DROP COLUMN assumed
that READ UNCOMMITTED of the data dictionary will be performed.
Now, we will have a READ COMMITTED copy of the data dictionary
cache, and a READ UNCOMMITTED copy of the metadata record.

btr_page_reorganize_low(): Correctly update the FIL_PAGE_TYPE
when rolling back an instant ADD/DROP COLUMN operation.

row_rec_to_index_entry_impl(): Relax some assertions,
and disallow accessing "extra" fields. This fixes the recovery
of a crash during an instant ADD COLUMN after a successful
instant DROP COLUMN, in the test innodb.instant_alter_crash.

Tested by: Matthias Leich
2022-03-28 08:37:51 +03:00
Daniel Black
88ce8a3d8b Merge 10.7 into 10.8 2022-03-25 15:06:56 +11:00
Daniel Black
8b92e346b1 Merge 10.6 into 10.7 2022-03-25 14:31:59 +11:00
Daniel Black
ec62f46a61 Merge 10.5 to 10.6 2022-03-25 11:31:49 +11:00
Marko Mäkelä
75b7cd680b MDEV-23974 Tests fail due to [Warning] InnoDB: Trying to delete tablespace
A few regression tests invoke heavy flushing of the buffer pool
and may trigger warnings that tablespaces could not be deleted
because of pending writes. Those warnings are to be expected
during the execution of such tests.

The warnings are also frequently seen with Valgrind or MemorySanitizer.
For those, the global suppression in have_innodb.inc does the trick.
2022-03-23 16:42:43 +02:00
Thirunarayanan Balathandayuthapani
c3ca729ba8 MDEV-27858 Assertion `page_dir_get_n_heap(new_page) == 2U' failed in PageBulk::init
- InnoDB should check whether bulk transaction id set to its own
transaction id before start bulk insert operation.

- When bulk insert failure happens, InnoDB should set the error info
of the transaction.
2022-03-23 10:15:52 +05:30