diff options
author | Marko Mäkelä <marko.makela@mariadb.com> | 2022-04-27 07:57:04 +0300 |
---|---|---|
committer | Marko Mäkelä <marko.makela@mariadb.com> | 2022-04-27 07:57:04 +0300 |
commit | f21a87560091a8149752b13e097d382ba30786d2 (patch) | |
tree | f89aafc789286afedc813c58c84f0ef9262ba593 /storage | |
parent | 39990135e57e7377fd2f9a156973a59eb07bc739 (diff) | |
download | mariadb-git-f21a87560091a8149752b13e097d382ba30786d2.tar.gz |
MDEV-28415 ALTER TABLE on a large table hangs InnoDB
buf_flush_page(): Never wait for a page latch, even in checkpoint
flushing (flush_type == BUF_FLUSH_LIST), to prevent a hang of the
page cleaner threads when a large number of pages is latched.
In mysql/mysql-server@9542f3015b00330ef537f6223565b28b82a5b325
it was claimed that such a hang only affects CREATE FULLTEXT INDEX.
Their fix was to retain buffer-fix but release exclusive latch
on non-leaf pages, and subsequently write to those pages while
they are not associated with the mini-transaction, which would
trip a debug assertion in the MariaDB version of
mtr_t::memo_modify_page() and cause potential corruption
when using the default MariaDB setting innodb_log_optimize_ddl=OFF.
This change essentially backports a small part of
commit 7cffb5f6e8a231a041152447be8980ce35d2c9b8 (MDEV-23399)
from MariaDB Server 10.5.7.
Diffstat (limited to 'storage')
-rw-r--r-- | storage/innobase/buf/buf0flu.cc | 27 |
1 files changed, 3 insertions, 24 deletions
diff --git a/storage/innobase/buf/buf0flu.cc b/storage/innobase/buf/buf0flu.cc index 2beddf4b243..e029948be55 100644 --- a/storage/innobase/buf/buf0flu.cc +++ b/storage/innobase/buf/buf0flu.cc @@ -1,7 +1,7 @@ /***************************************************************************** Copyright (c) 1995, 2017, Oracle and/or its affiliates. All Rights Reserved. -Copyright (c) 2013, 2020, MariaDB Corporation. +Copyright (c) 2013, 2022, MariaDB Corporation. Copyright (c) 2013, 2014, Fusion-io This program is free software; you can redistribute it and/or modify it under @@ -1160,15 +1160,10 @@ buf_flush_page( /* For table residing in temporary tablespace sync is done using IO_FIX and so before scheduling for flush ensure that page is not fixed. */ - flush = FALSE; + return FALSE; } else { rw_lock = &reinterpret_cast<buf_block_t*>(bpage)->lock; - if (flush_type != BUF_FLUSH_LIST) { - flush = rw_lock_sx_lock_nowait(rw_lock, BUF_IO_WRITE); - } else { - /* Will SX lock later */ - flush = TRUE; - } + flush = rw_lock_sx_lock_nowait(rw_lock, BUF_IO_WRITE); } if (flush) { @@ -1190,22 +1185,6 @@ buf_flush_page( buf_pool_mutex_exit(buf_pool); - if (flush_type == BUF_FLUSH_LIST - && is_uncompressed - && !rw_lock_sx_lock_nowait(rw_lock, BUF_IO_WRITE)) { - - if (!fsp_is_system_temporary(bpage->id.space())) { - /* avoiding deadlock possibility involves - doublewrite buffer, should flush it, because - it might hold the another block->lock. */ - buf_dblwr_flush_buffered_writes(); - } else { - buf_dblwr_sync_datafiles(); - } - - rw_lock_sx_lock_gen(rw_lock, BUF_IO_WRITE); - } - /* If there is an observer that want to know if the asynchronous flushing was sent then notify it. Note: we set flush observer to a page with x-latch, so we can |