From c0c003beb48b099b5e6516e9d36adf096cd2d09c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marko=20M=C3=A4kel=C3=A4?= Date: Fri, 11 Oct 2019 15:32:04 +0300 Subject: [PATCH] MDEV-20805 follow-up: Catch writes of bogus pages buf_flush_init_for_writing(): Assert that FIL_PAGE_TYPE is set except when creating a new data file with a dummy first page. buf_dblwr_create(): Ensure that FIL_PAGE_TYPE on all pages will be initialized. Reset buf_dblwr_being_created at the end. --- storage/innobase/buf/buf0dblwr.cc | 10 +++++++++- storage/innobase/buf/buf0flu.cc | 3 ++- storage/xtradb/buf/buf0dblwr.cc | 10 +++++++++- storage/xtradb/buf/buf0flu.cc | 3 ++- 4 files changed, 22 insertions(+), 4 deletions(-) diff --git a/storage/innobase/buf/buf0dblwr.cc b/storage/innobase/buf/buf0dblwr.cc index 99582685d04..36054dbf9fe 100644 --- a/storage/innobase/buf/buf0dblwr.cc +++ b/storage/innobase/buf/buf0dblwr.cc @@ -1,7 +1,7 @@ /***************************************************************************** Copyright (c) 1995, 2017, Oracle and/or its affiliates. All Rights Reserved. -Copyright (c) 2013, 2018, MariaDB Corporation. +Copyright (c) 2013, 2019, 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 @@ -291,6 +291,13 @@ too_small: ut_ad(rw_lock_get_x_lock_count(&new_block->lock) == 1); page_no = buf_block_get_page_no(new_block); + /* We only do this in the debug build, to ensure that + both the check in buf_flush_init_for_writing() and + recv_parse_or_apply_log_rec_body() will see a valid + page type. The flushes of new_block are actually + unnecessary here. */ + ut_d(mlog_write_ulint(FIL_PAGE_TYPE + new_block->frame, + FIL_PAGE_TYPE_SYS, MLOG_2BYTES, &mtr)); if (i == FSP_EXTENT_SIZE / 2) { ut_a(page_no == FSP_EXTENT_SIZE); @@ -353,6 +360,7 @@ too_small: /* Flush the modified pages to disk and make a checkpoint */ log_make_checkpoint_at(LSN_MAX, TRUE); + buf_dblwr_being_created = FALSE; /* Remove doublewrite pages from LRU */ buf_pool_invalidate(); diff --git a/storage/innobase/buf/buf0flu.cc b/storage/innobase/buf/buf0flu.cc index 2e352c3de72..f918b88a5ea 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, 2017, MariaDB Corporation. +Copyright (c) 2013, 2019, MariaDB Corporation. Copyright (c) 2013, 2014, Fusion-io This program is free software; you can redistribute it and/or modify it under @@ -745,6 +745,7 @@ buf_flush_init_for_writing( ib_uint32_t checksum = 0 /* silence bogus gcc warning */; ut_ad(page); + ut_ad(!newest_lsn || fil_page_get_type(page)); if (page_zip_) { page_zip_des_t* page_zip; diff --git a/storage/xtradb/buf/buf0dblwr.cc b/storage/xtradb/buf/buf0dblwr.cc index 6e0c6fb612e..c3a169d45ef 100644 --- a/storage/xtradb/buf/buf0dblwr.cc +++ b/storage/xtradb/buf/buf0dblwr.cc @@ -1,7 +1,7 @@ /***************************************************************************** Copyright (c) 1995, 2017, Oracle and/or its affiliates. All Rights Reserved. -Copyright (c) 2013, 2018, MariaDB Corporation. +Copyright (c) 2013, 2019, 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 @@ -291,6 +291,13 @@ too_small: ut_ad(rw_lock_get_x_lock_count(&new_block->lock) == 1); page_no = buf_block_get_page_no(new_block); + /* We only do this in the debug build, to ensure that + both the check in buf_flush_init_for_writing() and + recv_parse_or_apply_log_rec_body() will see a valid + page type. The flushes of new_block are actually + unnecessary here. */ + ut_d(mlog_write_ulint(FIL_PAGE_TYPE + new_block->frame, + FIL_PAGE_TYPE_SYS, MLOG_2BYTES, &mtr)); if (i == FSP_EXTENT_SIZE / 2) { ut_a(page_no == FSP_EXTENT_SIZE); @@ -353,6 +360,7 @@ too_small: /* Flush the modified pages to disk and make a checkpoint */ log_make_checkpoint_at(LSN_MAX, TRUE); + buf_dblwr_being_created = FALSE; /* Remove doublewrite pages from LRU */ buf_pool_invalidate(); diff --git a/storage/xtradb/buf/buf0flu.cc b/storage/xtradb/buf/buf0flu.cc index 96ab72a2636..e4512cacff8 100644 --- a/storage/xtradb/buf/buf0flu.cc +++ b/storage/xtradb/buf/buf0flu.cc @@ -1,7 +1,7 @@ /***************************************************************************** Copyright (c) 1995, 2017, Oracle and/or its affiliates. All Rights Reserved. -Copyright (c) 2013, 2017, MariaDB Corporation. +Copyright (c) 2013, 2019, MariaDB Corporation. Copyright (c) 2013, 2014, Fusion-io This program is free software; you can redistribute it and/or modify it under @@ -787,6 +787,7 @@ buf_flush_init_for_writing( ib_uint32_t checksum = 0 /* silence bogus gcc warning */; ut_ad(page); + ut_ad(!newest_lsn || fil_page_get_type(page)); if (page_zip_) { page_zip_des_t* page_zip;