diff options
author | Marko Mäkelä <marko.makela@mariadb.com> | 2020-07-17 15:55:45 +0300 |
---|---|---|
committer | Marko Mäkelä <marko.makela@mariadb.com> | 2020-07-17 15:55:45 +0300 |
commit | 7364d70c3ef5eceedea3aad96ea6040749baeac8 (patch) | |
tree | e283dabda801c711dab692da71b6eaacc71808ba /storage/xtradb/srv/srv0start.cc | |
parent | 84c590cada648a25e7ec9f61357656e914923738 (diff) | |
download | mariadb-git-bb-10.1-marko.tar.gz |
MDEV-23190 InnoDB data file extension is not crash-safebb-10.1-marko
When InnoDB is extending a data file, it is updating the FSP_SIZE
field in the first page of the data file.
In commit 8451e09073e8b1a300f177d74a9e3a530776640a (MDEV-11556)
we removed a work-around for this bug and made recovery stricter,
by making it track changes to FSP_SIZE via redo log records, and
extend the data files before any changes are being applied to them.
It turns out that the function fsp_fill_free_list() is not crash-safe
with respect to this when it is initializing the change buffer bitmap
page (page 1, or generally, N*innodb_page_size+1). It uses a separate
mini-transaction that is committed (and will be written to the redo
log file) before the mini-transaction that actually extended the data
file. Hence, recovery can observe a reference to a page that is
beyond the current end of the data file.
fsp_fill_free_list(): Initialize the change buffer bitmap page in
the same mini-transaction.
The rest of the changes are fixing a bug that the use of the separate
mini-transaction was attempting to work around. Namely, we must ensure
that no other thread will access the change buffer bitmap page before
our mini-transaction has been committed and all page latches have been
released.
That is, for read-ahead as well as neighbour flushing, we must avoid
accessing pages that might not yet be durably part of the tablespace.
fil_space_t::committed_size: The size of the tablespace
as persisted by mtr_commit().
fil_space_t::max_page_number_for_io(): Limit the highest page
number for I/O batches to committed_size.
MTR_MEMO_SPACE_X_LOCK: Replaces MTR_MEMO_X_LOCK for fil_space_t::latch.
mtr_x_space_lock(): Replaces mtr_x_lock() for fil_space_t::latch.
mtr_memo_slot_release_func(): When releasing MTR_MEMO_SPACE_X_LOCK,
copy space->size to space->committed_size. In this way, read-ahead
or flushing will never be invoked on pages that do not yet exist
according to FSP_SIZE.
Diffstat (limited to 'storage/xtradb/srv/srv0start.cc')
-rw-r--r-- | storage/xtradb/srv/srv0start.cc | 10 |
1 files changed, 9 insertions, 1 deletions
diff --git a/storage/xtradb/srv/srv0start.cc b/storage/xtradb/srv/srv0start.cc index 153599391dc..b61a8349b07 100644 --- a/storage/xtradb/srv/srv0start.cc +++ b/storage/xtradb/srv/srv0start.cc @@ -3,7 +3,7 @@ Copyright (c) 1996, 2017, Oracle and/or its affiliates. All rights reserved. Copyright (c) 2008, Google Inc. Copyright (c) 2009, Percona Inc. -Copyright (c) 2013, 2019, MariaDB Corporation. +Copyright (c) 2013, 2020, MariaDB Corporation. Portions of this file contain modifications contributed and copyrighted by Google, Inc. Those modifications are gratefully acknowledged and are described @@ -1240,6 +1240,10 @@ check_first_page: } } + if (fil_space_t* s = fil_space_get(0)) { + s->committed_size = s->size; + } + return(DB_SUCCESS); } @@ -1408,6 +1412,10 @@ srv_undo_tablespace_open( if (fil_node_create(name, (ulint) n_pages, space, FALSE)) { err = DB_SUCCESS; } + + if (fil_space_t* s = fil_space_get(space)) { + s->committed_size = n_pages; + } } return(err); |