Uploaded image for project: 'MariaDB Server'
  1. MariaDB Server
  2. MDEV-30106

InnoDB fails to validate the change buffer on startup

    XMLWordPrintable

Details

    Description

      The function ibuf_init_at_db_start() fails to validate the contents of the root page of the change buffer tree, beyond checking that the page checksum is valid.

      Should the page exist but be in a different format (such as a dummy page created after MDEV-29694 removed the change buffer), InnoDB would crash on some DDL operations or on slow shutdown when trying to access the change buffer tree.

      Here is how the change buffer creation can be disabled on startup:

      diff --git a/storage/innobase/srv/srv0start.cc b/storage/innobase/srv/srv0start.cc
      index 8e291352d55..3f81f33cee1 100644
      --- a/storage/innobase/srv/srv0start.cc
      +++ b/storage/innobase/srv/srv0start.cc
      @@ -1401,17 +1401,48 @@ dberr_t srv_start(bool create_new_db)
       				     uint32_t(sum_of_new_sizes), &mtr)
       		     == DB_SUCCESS);
       
      +#if 1
       		ulint ibuf_root = btr_create(
       			DICT_CLUSTERED | DICT_IBUF, fil_system.sys_space,
       			DICT_IBUF_ID_MIN, nullptr, &mtr, &err);
      +#else
      +		/* Allocate dummy change buffer pages for backward
      +		compatibility and to prevent a downgrade. */
      +		if (err != DB_SUCCESS) {
      +		} else if (buf_block_t *b =
      +			   fseg_create(fil_system.sys_space, PAGE_DATA, &mtr,
      +				       &err)) {
      +			ut_ad(b->page.id()
      +			      == page_id_t(0, FSP_IBUF_HEADER_PAGE_NO));
      +			b = fseg_alloc_free_page_general(
      +				b->page.frame + PAGE_DATA,
      +				FSP_IBUF_TREE_ROOT_PAGE_NO, FSP_UP, false,
      +				&mtr, &mtr, &err);
      +			if (b) {
      +				ut_ad(b->page.id() == page_id_t
      +				      (0, FSP_IBUF_TREE_ROOT_PAGE_NO));
      +				mtr.set_modified(*b);
      +				fsp_init_file_page(fil_system.sys_space, b,
      +						   &mtr);
      +			} else {
      +				ut_ad(err != DB_SUCCESS);
      +			}
      +		}
      +#endif
       
       		mtr_commit(&mtr);
       
      +#if 1
       		if (ibuf_root == FIL_NULL) {
       			return srv_init_abort(err);
       		}
       
       		ut_ad(ibuf_root == IBUF_TREE_ROOT_PAGE_NO);
      +#else
      +		if (err != DB_SUCCESS) {
      +			return srv_init_abort(err);
      +		}
      +#endif
       
       		/* To maintain backward compatibility we create only
       		the first rollback segment before the double write buffer.
      

      A proper validation of the change buffer on startup is necessary so that attempts to downgrade from newer major releases that include MDEV-29694 can be prevented.

      Attachments

        Issue Links

          Activity

            People

              marko Marko Mäkelä
              marko Marko Mäkelä
              Votes:
              0 Vote for this issue
              Watchers:
              1 Start watching this issue

              Dates

                Created:
                Updated:
                Resolved:

                Git Integration

                  Error rendering 'com.xiplink.jira.git.jira_git_plugin:git-issue-webpanel'. Please contact your Jira administrators.