summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMarko Mäkelä <marko.makela@mariadb.com>2021-03-10 19:33:09 +0200
committerMarko Mäkelä <marko.makela@mariadb.com>2021-03-15 20:22:40 +0200
commit066ac9cc5a192b616a50fe88b8a4e94847bf476a (patch)
tree75ca565d7ccc9f453b6619185b80c61d4cdf8eec
parent30d040efe1cab3362433c6603f082f0cd07295ca (diff)
downloadmariadb-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.cc27
-rw-r--r--storage/innobase/include/fil0fil.h5
-rw-r--r--storage/innobase/log/log0recv.cc2
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(); )