Commit graph

3,639 commits

Author SHA1 Message Date
Sergei Golubchik
56abcc4087 Merge branch '11.8' into 12.0 2025-07-29 19:45:23 +02:00
Sergei Golubchik
b565b3e7e0 Merge branch '11.4' into 11.8 2025-07-28 21:29:29 +02:00
Sergei Golubchik
c4ed889b74 Merge branch '10.11' into 11.4 2025-07-28 19:40:10 +02:00
Sergei Golubchik
053f9bcb5b Merge branch '10.6' into 10.11 2025-07-28 18:06:31 +02:00
Marko Mäkelä
55e0c34f4f MDEV-37263 Hang or crash when shrinking innodb_buffer_pool_size
buf_pool_t::shrink(): If we run out of pages to evict from buf_pool.LRU,
abort the operation. Also, do not leak the spare block that we may have
allocated.
2025-07-18 10:06:33 +03:00
Marko Mäkelä
cedfe8eca4 MDEV-37250 buf_pool_t::shrink() assertion failure
buf_pool_t::shrink(): When relocating a dirty page of the temporary
tablespace, reset the oldest_modification() on the discarded block,
like we do for persistent pages in buf_flush_relocate_on_flush_list().

buf_pool_t::resize(): Add debug assertions to catch this error earlier.

This bug does not seem to affect non-debug builds.

Reviewed by: Thirunarayanan Balathandayuthapani
2025-07-17 12:24:25 +03:00
Aleksey Midenkov
9a51709dba MDEV-29001 DROP DEFAULT makes SHOW CREATE non-idempotent
DROP DEFAULT adds DEFAULT NULL in case of nullable column. In case of
NOT NULL column it drops default expression if any exists.
2025-07-17 09:18:18 +02:00
Marko Mäkelä
b7b2e009b3 MDEV-37215 SELECT FOR UPDATE crash in SERIALIZABLE
ha_innobase::store_lock(): Set also trx->will_lock when starting
a transaction at SERIALIZABLE isolation level. This fixes up
commit 7fbbbc983f (MDEV-36330).
2025-07-14 10:31:56 +03:00
Marko Mäkelä
7fbbbc983f MDEV-36330: SERIALIZABLE read inconsistency
At TRANSACTION ISOLATION LEVEL SERIALIZABLE, InnoDB would fail to flag
a write/read conflict, which would be a violation already at the more
relaxed REPEATABLE READ level when innodb_snapshot_isolation=ON.

Fix: Create a read view and start the transaction at the same time.
Thus, lock checks will be able to consult the correct read view
to flag ER_CHECKREAD if we are about to lock a record that was committed
after the start of our transaction.

innobase_start_trx_and_assign_read_view(): At any other isolation level
than READ UNCOMMITTED, do create a read view. This is needed for the
correct operation of START TRANSACTION WITH CONSISTENT SNAPSHOT.

ha_innobase::store_lock(): At SERIALIZABLE isolation level, if the
transaction was not started yet, start it and open a read view.
An alternative way to achieve this would be to make trans_begin()
treat START TRANSACTION (or BEGIN) in the same way as
START TRANSACTION WITH CONSISTENT SNAPSHOT when the isolation level
is SERIALIZABLE.

innodb_isolation_level(const THD*): A simpler version of
innobase_map_isolation_level(). Compared to earlier, we will return
READ UNCOMMITTED also if the :newraw option is set for the
InnoDB system tablespace.

Reviewed by: Vladislav Lesin
2025-07-11 16:07:08 +03:00
Marko Mäkelä
f73ffd1150 MDEV-37183 Scrubbing empty record breaks recovery
page_delete_rec_list_end(): Do not attempt to scrub the data of
an empty record.

The test case would reproduce a debug assertion failure in branches
where commit 358921ce32 (MDEV-26938)
is present. MariaDB Server 10.6 only supports ascending indexes,
and in those, the empty string would always be sorted first, never
last in a page.

Nevertheless, we fix the bug also in 10.6, in case it would be
reproducible in a slightly different scenario.

Reviewed by: Thirunarayanan Balathandayuthapani
2025-07-11 15:20:06 +03:00
Thirunarayanan Balathandayuthapani
0dd6566ee4 MDEV-37123 dict_table_open_on_id() fails to release dict_sys.latch
While updating the persistent defragmentation statistics
for the table, InnoDB opens the table only if it is in cache.
If dict_table_open_on_id() fails to find the table in cache
then it fails to unfreeze dict_sys.latch. This lead to crash
2025-07-02 14:25:38 +05:30
Marko Mäkelä
311b4445c5 MDEV-35049: Improve test coverage
innodb.lock_memory: Allow the test to run with
./mtr --mysqld=--loose-innodb-adaptive-hash-index.

main.row_filter_innodb,ahi: A new combination for
innodb_adaptive_hash_index=ON.
2025-06-26 11:45:33 +03:00
Thirunarayanan Balathandayuthapani
e706324205 MDEV-35863 innodb.doublewrite_debug test case fails to start the server
Problem:
=======
- There are two failures occurs for this test case:

(1) set global innodb_buf_flush_list_now=1 doesn't make sure that pages
are being flushed.

(2) InnoDB page cleaner thread aborts while writing the checkpoint information.
Problem is that When InnoDB startup aborts, InnoDB changes the shutdown
state to SRV_SHUTDOWN_EXIT_THREADS. By changing the shutdown state, InnoDB
doesn't advance the log_sys.lsn (avoids fil_names_clear()).
After InnoDB shutdown(innodb_shutdown()) is being initiated, shutdown state
again changed to SRV_SHUTDOWN_INITIATED. This leads the page cleaner thread
to fail with assertion ut_ad(srv_shutdown_state > SRV_SHUTDOWN_INITIATED)
in log_write_checkpoint_info()

Solution:
=========
(1)  In order to avoid (1) failure, InnoDB can make the
variable innodb_max_dirty_pages_pct_lwm, innodb_max_dirty_pages_pct to 0.
Also make sure that InnoDB doesn't have any dirty pages in buffer pool
by adding wait_condition.

(2) Avoid changing the srv_shutdown_state to SRV_SHUTDOWN_EXIT_THREADS
when the InnoDB startup aborts
2025-06-23 15:48:43 +05:30
mariadb-DebarunBanerjee
7f77041b0a MDEV-37141 DML committed within XA transaction block after deadlock error and implicit rollback
Issue: When XA transaction is implicitly rolled back, we keep XA state
XA_ACTIVE and set rm_error to ER_LOCK_DEADLOCK. Other than XA command
we don't check for rm_error and DML and query are executed with a new
transaction.

Fix: One way to fix this issue is to set the XA state to XA_ROLLBACK_ONLY
which is checked while opening table open_tables() and ER_XAER_RMFAIL is
returned for any DML or Query.
2025-07-10 13:37:03 +05:30
mariadb-DebarunBanerjee
0680e31737 MDEV-36959 Deadlock does not rollback transaction fully
A deadlock forces the on going transaction to rollback implicitly.
Within a transaction block, started with START TRANSACTION / BEGIN,
implicit rollback doesn't reset OPTION_BEGIN flag. It results in a
new implicit transaction to start when the next statement is executed.
This behaviour is unexpected and should be fixed. However, we should
note that there is no issue with rollback.

We fix the issue to keep the behaviour of implicit rollback (deadlock)
similar to explicit COMMIT and ROLLBACK i.e. the next statement after
deadlock error is not going to start a transaction block implicitly
unless autocommit is set to zero.
2025-06-24 13:34:27 +05:30
Oleksandr Byelkin
dfcb5c91e0 Merge branch '11.8' into 12.0 2025-06-18 07:50:39 +02:00
Oleksandr Byelkin
a65f7dc71d Merge branch '11.4' into 11.8 2025-06-18 07:43:24 +02:00
Oleksandr Byelkin
89c7e2b9c7 Merge branch '10.11' into 11.4
Some checks failed
Build on Windows ARM64 / build (push) Has been cancelled
2025-06-17 09:50:22 +02:00
Oleksandr Byelkin
7dcdb2c876 Merge branch '11.8' into 11.8 release 2025-05-30 13:28:41 +02:00
Marko Mäkelä
d953f2c810 MDEV-36868: Inconsistency when shrinking innodb_buffer_pool_size
buf_pool_t::resize(): After successfully shrinking the buffer pool,
announce the success. The size had already been updated in shrunk().
After failing to shrink the buffer pool, re-enable the adaptive
hash index if it had been enabled.

Reviewed by: Debarun Banerjee
2025-05-28 14:33:20 +03:00
Marko Mäkelä
7b4b759f13 MDEV-36868: Inconsistency when shrinking innodb_buffer_pool_size
buf_pool_t::resize(): After successfully shrinking the buffer pool,
announce the success. The size had already been updated in shrunk().
After failing to shrink the buffer pool, re-enable the adaptive
hash index if it had been enabled.

Reviewed by: Debarun Banerjee
2025-05-28 13:33:06 +03:00
Thirunarayanan Balathandayuthapani
db188083c3 MDEV-36771 Assertion 'bulk_insert == TRX_NO_BULK' failed in trx_t::assert_freed
- InnoDB fails to reset bulk_insert of a transaction while freeing
the transaction during shutting down of a server.
2025-05-26 12:13:01 +05:30
Marko Mäkelä
3da36fa130 Merge 10.6 into 10.11 2025-05-26 08:10:47 +03:00
Thirunarayanan Balathandayuthapani
d8962d138f MDEV-36017 Alter table aborts when temporary directory is full
Problem:
=======
- In 10.11, During Copy algorithm, InnoDB does use bulk insert
for row by row insert operation. When temporary directory
ran out of memory, row_mysql_handle_errors() fails to handle
DB_TEMP_FILE_WRITE_FAIL.

- During inplace algorithm, concurrent DML fails to write
the log operation into the temporary file. InnoDB fail to
mark the error for the online log.

- ddl_log_write() releases the global ddl lock prematurely before
release the log memory entry

Fix:
===
row_mysql_handle_errors(): Rollback the transaction when
InnoDB encounters DB_TEMP_FILE_WRITE_FAIL

convert_error_code_to_mysql(): Report an aborted transaction
when InnoDB encounters DB_TEMP_FILE_WRITE_FAIL during
alter table algorithm=copy or innodb bulk insert operation

row_log_online_op(): Mark the error in online log when
InnoDB ran out of temporary space

fil_space_extend_must_retry(): Mark the os_has_said_disk_full
as true if os_file_set_size() fails

btr_cur_pessimistic_update(): Return error code when
btr_cur_pessimistic_insert() fails

ddl_log_write(): Release the global ddl lock after releasing
the log memory entry when error was encountered

btr_cur_optimistic_update(): Relax the assertion that
blob pointer can be null during rollback because InnoDB can
ran out of space while allocating the external page

ha_innobase::extra(): Rollback the transaction during DDL before
calling convert_error_code_to_mysql().

row_undo_mod_upd_exist_sec(): Remove the assertion which says
that InnoDB should fail to build index entry when rollbacking
an incomplete transaction after crash recovery. This scenario
can happen when InnoDB ran out of space.

row_upd_changes_ord_field_binary_func(): Relax the assertion to
make that externally stored field can be null when InnoDB ran out
of space.
2025-05-26 10:12:14 +05:30
Thirunarayanan Balathandayuthapani
8a4d3a044f MDEV-36017 Alter table aborts when temporary directory is full
Problem:
=======
- During inplace algorithm, concurrent DML fails to write
the log operation into the temporary file. InnoDB fail to
mark the error for the online log.

- ddl_log_write() releases the global ddl lock prematurely before
release the log memory entry

Fix:
===
row_log_online_op(): Mark the error in online log when
InnoDB ran out of temporary space

fil_space_extend_must_retry(): Mark the os_has_said_disk_full
as true if os_file_set_size() fails

btr_cur_pessimistic_update(): Return error code when
btr_cur_pessimistic_insert() fails

ddl_log_write(): Release the global ddl lock after releasing the
log memory entry when error was encountered

btr_cur_optimistic_update(): Relax the assertion that
blob pointer can be null during rollback because InnoDB can
ran out of space while allocating the external page

row_undo_mod_upd_exist_sec(): Remove the assertion which says
that InnoDB should fail to build index entry when rollbacking
an incomplete transaction after crash recovery. This scenario
can happen when InnoDB ran out of space.

row_upd_changes_ord_field_binary_func(): Relax the assertion to
make that externally stored field can be null when InnoDB ran out
of space.
2025-05-25 09:11:41 +05:30
Oleksandr Byelkin
f1102da37a Merge branch '11.8' into 12.0 2025-05-22 09:22:55 +02:00
Oleksandr Byelkin
8d36cafe4f Merge branch '11.4' into 11.8 2025-05-21 15:57:16 +02:00
Oleksandr Byelkin
b8d3257243 Merge branch '10.11' into 10.11 2025-05-21 14:43:57 +02:00
Marko Mäkelä
1c7209e828 Merge 10.6 into 10.11 2025-05-21 07:36:35 +03:00
Marko Mäkelä
82d7419e06 MDEV-34388: Stack overflow on Alpine Linux
page_is_corrupted(): Do not allocate the buffers from stack,
but from the heap, in xb_fil_cur_open().

row_quiesce_write_cfg(): Issue one type of message when we
fail to create the .cfg file.

update_statistics_for_table(), read_statistics_for_table(),
delete_statistics_for_table(), rename_table_in_stat_tables():
Use a common stack buffer for Index_stat, Column_stat, Table_stat.

ha_connect::FileExists(): Invoke push_warning_printf() so that
we can avoid allocating a buffer for snprintf().

translog_init_with_table(): Do not duplicate TRANSLOG_PAGE_SIZE_BUFF.

Let us also globally enable the GCC 4.4 and clang 3.0 option
-Wframe-larger-than=16384 to reduce the possibility of introducing
such stack overflow in the future.  For RocksDB and Mroonga we relax
these limits.

Reviewed by: Vladislav Lesin
2025-05-20 17:27:05 +03:00
Marko Mäkelä
118cfcf821 Merge 10.11 into 11.4 2025-05-13 13:44:58 +03:00
Marko Mäkelä
bb48d7bc81 MDEV-36781: Assertion i < BUF_BUDDY_SIZES failed in buf_buddy_shrink()
buf_buddy_shrink(): Properly cover the case when KEY_BLOCK_SIZE
corresponds to the innodb_page_size, that is, the ROW_FORMAT=COMPRESSED
page frame is directly allocated from the buffer pool, not via the
binary buddy allocator.

buf_LRU_check_size_of_non_data_objects(): Avoid a crash when the
buffer pool is being shrunk.

buf_pool_t::shrink(): Abort if over 95% of the shrunk buffer pool
would be occupied by the adaptive hash index or record locks.
2025-05-13 12:27:46 +03:00
Sergei Golubchik
11f6b9d12a remove features that were deprecated in 10.5
--big-tables
--large-page-size
--storage-engine

performance_schema.setup_timers (WL#10986)
2025-04-29 16:53:02 +02:00
Vasilii Lakhin
1b95e46524 Fix typos in mysql-test/ 2025-04-29 13:53:16 +10:00
Sergei Golubchik
237e24497b Merge remote-tracking branch 'github/bb-11.4-release' into bb-11.8-serg 2025-04-27 19:40:00 +02:00
Oleksandr Byelkin
a8d4642375 Merge branch '10.11' into 11.4 2025-04-26 10:53:02 +02:00
Marko Mäkelä
75ad1e9f00 Merge 10.6 into 10.11 2025-04-23 08:53:53 +03:00
Vlad Lesin
47e687b109 MDEV-36639 innodb_snapshot_isolation=1 gives error for not committed row changes
Set solution is to check if transaction, which modified a record, is
still active in lock_clust_rec_read_check_and_lock(). if yes, then just
request a lock. If no, then, depending on if the current transaction read
view can see the changes, return eighter DB_RECORD_CHANGED or request a
lock.

We can do the check in lock_clust_rec_read_check_and_lock() because
transaction tries to set a lock on the record which cursor points to after
transaction resuming and cursor position restoring. If the lock already
exists, then we don't request the lock again. But for the current commit
it's important that lock_clust_rec_read_check_and_lock() will be invoked
again for the same record, so we can do the check again after
transaction, which modified a record, was committed or rolled back.

MDEV-33802(4aa9291) is partially reverted. If some transaction holds
implicit lock on some record and transaction with snapshot isolation level
requests conflicting lock on the same record, it should be blocked instead
of returning DB_RECORD_CHANGED to have ability to continue execution when
implicit lock owner is rolled back.

The construction
--------------------------------------------------------------------------
let $wait_condition=
  select count(*) = 1 from information_schema.processlist
  where state = 'Updating' and info = 'UPDATE t SET b = 2 WHERE a';
--source include/wait_condition.inc
--------------------------------------------------------------------------

is not reliable enought to make sure transaction is blocked in test
case, the test failed sporadically with
--------------------------------------------------------------------------
./mtr --max-test-fail=1 --parallel=96 lock_isolation{,,,,,,,}{,,,}{,,} \
--repeat=500
--------------------------------------------------------------------------

command. That's why it was replaced with debug sync-points.

Reviewed by: Marko Mäkelä
2025-04-22 20:41:43 +03:00
Thirunarayanan Balathandayuthapani
dac3d702f7 MDEV-36649 dict_acquire_mdl_shared() aborts when table mode is DICT_TABLE_OP_OPEN_ONLY_IF_CACHED
- InnoDB fails to check the table is being dropped or evicted
while acquiring the MDL for the table when table open operation
mode is DICT_TABLE_OP_OPEN_ONLY_IF_CACHED. This is caused by
the commit 337bf8ac4b (MDEV-36122)

Fix:
===
dict_acquire_mdl_shared(): If the table is evicted or dropped when
table operation mode is DICT_TABLE_OP_OPEN_IF_CACHED then return
nullptr
2025-04-22 15:17:29 +05:30
Sergei Golubchik
1a85ae444a MDEV-36050 DATA/INDEX DIRECTORY handling is inconsistent
consistently issue a

Note 1618 DATA DIRECTORY option ignored
Note 1618 INDEX DIRECTORY option ignored

in archive/csv/innodb/rocksdb whenever an option is ignored.

Note that csv doesn't say "INDEX DIRECTORY option ignored"
because it does not create index files at all anywhere.

Other engines don't say "INDEX DIRECTORY option ignored"
if the table has no indexes.

additionally InnoDB doesn't say that if INDEX DIRECTORY is
the same as DATA DIRECTORY, because in that case indexes are
technically stored in INDEX DIRECTORY.

collateral fix: use strmake to zero-terminate the string
2025-04-18 09:41:23 +02:00
Sergei Golubchik
606edaa6cd consistent error messages, no <angle quoting>
only WARN_OPTION_IGNORED was angle-quotting its parameter, no
other error message did it. Remove angle quoting for consistency.
2025-04-18 09:41:23 +02:00
Thirunarayanan Balathandayuthapani
f388222d49 MDEV-36504 Memory leak after CREATE TABLE..SELECT
Problem:
========
- After commit cc8eefb0dc (MDEV-33087),
InnoDB does use bulk insert operation for ALTER TABLE.. ALGORITHM=COPY
and CREATE TABLE..SELECT as well. InnoDB fails to clear the bulk
buffer when it encounters error during CREATE..SELECT. Problem
is that while transaction cleanup, InnoDB fails to identify
the bulk insert for DDL operation.

Fix:
====
- Represent bulk_insert in trx by 2 bits. By doing that, InnoDB
can distinguish between TRX_DML_BULK, TRX_DDL_BULK. During DDL,
set bulk insert value for transaction to TRX_DDL_BULK.

- Introduce a parameter HA_EXTRA_ABORT_ALTER_COPY which rollbacks
only TRX_DDL_BULK transaction.

- bulk_insert_apply() happens for TRX_DDL_BULK transaction happens
only during HA_EXTRA_END_ALTER_COPY extra() call.
2025-04-17 12:04:09 +05:30
Julius Goryavsky
1a013cea95 Merge branch '10.6' into '10.11' 2025-04-16 03:34:40 +02:00
Thirunarayanan Balathandayuthapani
c6de1267dd MDEV-35689 InnoDB system tables cannot be optimized or defragmented
- With the help of MDEV-14795, InnoDB implemented a way to shrink
the InnoDB system tablespace after undo tablespaces have been moved
to separate files (MDEV-29986). There is no way to defragment any
pages of InnoDB system tables. By doing that, shrinking of
system tablespace can be more effective. This patch deals with
defragment of system tables inside ibdata1.

Following steps are done to do the defragmentation of system
tablespace:
1) Make sure that there is no user tables exist in ibdata1

2) Iterate through all extent descriptor pages in system tablespace
and note their states.

3) Find the free earlier extent to replace the lastly used
extents in the system tablespace.

4) Iterate through all indexes of system tablespace and defragment
the tree level by level.

5) Iterate the level from left page to right page and find out
the page comes under the extent to be replaced. If it is then
do step (6) else step(4)

6) Prepare the allocation of new extent by latching necessary
pages. If any error happens then there is no modification of
page happened till step (5).

7) Allocate the new page from the new extent

8) Prepare the associated pages for the block to be modified

9) Prepare the step of freeing of page

10) If any error happens during preparing of associated pages,
freeing of page then restore the page which was modified
during new page allocation

11) Copy the old page content to new page

12) Change the associative pages like left, right and parent page

13) Complete the freeing of old page

Allocation of page from new extent, changing of relative pages,
freeing of page are done by 2 steps. one is prepare which
latches the to be modified pages and checks their validation.
Other is complete(), Do the operation

fseg_validate(): Validate the list exist in inode segment

Defragmentation is enabled only when :autoextend exist in
innodb_data_file_path variable.
2025-04-10 17:13:34 +05:30
Marko Mäkelä
db4763a0d1 Fix a slow test
When we expect a lock wait timeout, let us override
the default innodb_lock_wait_timeout=50
with the minimum timeout of 1 second.
2025-04-07 10:25:34 +03:00
Thirunarayanan Balathandayuthapani
b11772d9a5 MDEV-33167 ASAN errors in dict_sys_t::load_table / get_foreign_key_info after failing to load a table
Problem:
=======
- While loading the foreign key constraints for the parent table,
if child table wasn't open then InnoDB uses the parent table heap
to store the child table name in fk_tables list. If the consecutive
foreign key relation for the parent table fails with error,
InnoDB evicts the parent table from memory. But InnoDB accesses the
evicted table memory again in dict_sys.load_table()

Solution:
========
dict_load_table_one(): In case of error, remove the child table
names which was added during dict_load_foreigns()
2025-04-03 17:39:40 +05:30
Thirunarayanan Balathandayuthapani
0d7ef4f478 MDEV-36236 Instant alter aborts when InnoDB fails to rollback instant operation
Problem:
========
- InnoDB does consecutive instant alter operation, first instant DDL
fails, it fails to reset the old instant information in table during
rollback. This lead to consecutive instant alter to have wrong
assumption about the exisitng instant column information.

Fix:
====
dict_table_t::instant_column(): Duplicate the instant information
field of the table. By doing this, InnoDB alter retains the old
instant information and reset it during rollback operation
2025-04-03 13:09:08 +05:30
Marko Mäkelä
bb1d88b6dc Merge 11.4 into 11.8 2025-04-02 14:07:01 +03:00
Marko Mäkelä
3ae8f114e2 Merge 10.11 into 11.4 2025-04-02 10:15:08 +03:00
Marko Mäkelä
aaec841865 Merge 10.6 into 10.11 2025-04-02 09:33:20 +03:00