diff options
author | Marko Mäkelä <marko.makela@mariadb.com> | 2021-03-10 19:33:09 +0200 |
---|---|---|
committer | Marko Mäkelä <marko.makela@mariadb.com> | 2021-03-15 20:22:40 +0200 |
commit | 066ac9cc5a192b616a50fe88b8a4e94847bf476a (patch) | |
tree | 75ca565d7ccc9f453b6619185b80c61d4cdf8eec | |
parent | 30d040efe1cab3362433c6603f082f0cd07295ca (diff) | |
download | mariadb-git-10.5.9-recoveryfix.tar.gz |
MDEV-25110 [FATAL] InnoDB: Trying to write ... outside the bounds10.5.9-recoveryfix
In commit 118e258aaac5da75a2ac4556201aaea3688fac67 (part of MDEV-23855)
we inadvertently broke crash recovery, reintroducing MDEV-11556.
fil_system_t::extend_to_recv_size(): Extend all open tablespace files
to the recovered size.
recv_sys_t::apply(): Invoke fil_system.extend_to_recv_size() at the
start of each batch. In this way, any fil_space_t::recv_size
changes that were parsed after the file was opened will be applied.
-rw-r--r-- | storage/innobase/fil/fil0fil.cc | 27 | ||||
-rw-r--r-- | storage/innobase/include/fil0fil.h | 5 | ||||
-rw-r--r-- | storage/innobase/log/log0recv.cc | 2 |
3 files changed, 33 insertions, 1 deletions
diff --git a/storage/innobase/fil/fil0fil.cc b/storage/innobase/fil/fil0fil.cc index d000bc471d9..e245076a822 100644 --- a/storage/innobase/fil/fil0fil.cc +++ b/storage/innobase/fil/fil0fil.cc @@ -1305,6 +1305,33 @@ void fil_system_t::close() #endif /* UNIV_LINUX */ } +/** Extend all open data files to the recovered size */ +ATTRIBUTE_COLD void fil_system_t::extend_to_recv_size() +{ + ut_ad(is_initialised()); + mutex_enter(&mutex); + for (fil_space_t *space= UT_LIST_GET_FIRST(fil_system.space_list); space; + space= UT_LIST_GET_NEXT(space_list, space)) + { + const uint32_t size= space->recv_size; + + if (size > space->size) + { + if (space->is_closing()) + continue; + space->reacquire(); + bool success; + while (fil_space_extend_must_retry(space, UT_LIST_GET_LAST(space->chain), + size, &success)) + mutex_enter(&mutex); + /* Crash recovery requires the file extension to succeed. */ + ut_a(success); + space->release(); + } + } + mutex_exit(&mutex); +} + /** Close all tablespace files at shutdown */ void fil_space_t::close_all() { diff --git a/storage/innobase/include/fil0fil.h b/storage/innobase/include/fil0fil.h index f011eb6af69..f4ca4e9a73e 100644 --- a/storage/innobase/include/fil0fil.h +++ b/storage/innobase/include/fil0fil.h @@ -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, 2021, MariaDB Corporation. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software @@ -1422,6 +1422,9 @@ public: @retval NULL if this was the last */ inline fil_space_t* keyrotate_next(fil_space_t *space, bool recheck, bool encrypt); + + /** Extend all open data files to the recovered size */ + ATTRIBUTE_COLD void extend_to_recv_size(); }; /** The tablespace memory cache. */ diff --git a/storage/innobase/log/log0recv.cc b/storage/innobase/log/log0recv.cc index 6317444f326..c2aed5bb62b 100644 --- a/storage/innobase/log/log0recv.cc +++ b/storage/innobase/log/log0recv.cc @@ -2663,6 +2663,8 @@ void recv_sys_t::apply(bool last_batch) trim(page_id_t(id + srv_undo_space_id_start, t.pages), t.lsn); } + fil_system.extend_to_recv_size(); + buf_block_t *free_block= buf_LRU_get_free_block(false); for (map::iterator p= pages.begin(); p != pages.end(); ) |