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

Change buffer entries for secondary indexes are lost on InnoDB restart

Details

    Description

      The bug fix MDEV-21069 aimed to avoid a server crash when executing DROP TABLE of a corrupted table. Unfortunately, that fix introduced corruption in the function buf_read_ibuf_merge_pages() and caused wrongful deletion of records from the change buffer for tablespaces whose first page had not been read yet. The following should fix it:

      diff --git a/storage/innobase/buf/buf0rea.cc b/storage/innobase/buf/buf0rea.cc
      --- a/storage/innobase/buf/buf0rea.cc
      +++ b/storage/innobase/buf/buf0rea.cc
      @@ -772,13 +772,18 @@ buf_read_ibuf_merge_pages(
       			continue;
       		}
       
      -		if (UNIV_UNLIKELY(page_nos[i] >= space->size)) {
      +		ulint size = space->size;
      +		if (!size) {
      +			size = fil_space_get_size(space->id);
      +		}
      +
      +		if (UNIV_UNLIKELY(page_nos[i] >= size)) {
       			do {
       				ibuf_delete_recs(page_id_t(space_ids[i],
       							   page_nos[i]));
       			} while (++i < n_stored
       				 && space_ids[i - 1] == space_ids[i]
      -				 && page_nos[i] >= space->size);
      +				 && page_nos[i] >= size);
       			i--;
       next:
       			space->release();
      

      MariaDB Server 10.5 is not affected by this, because this code was removed in MDEV-19514. (However, 10.5 is affected by MDEV-25783 without even involving a server restart.)

      Also if crash recovery is needed, those tablespaces for which no redo log was applied could be affected by this bug.

      I believe that this kind of corruption can be detected by CHECK TABLE, and it can be fixed by dropping and re-creating the secondary indexes:

      CHECK TABLE t QUICK;
      ALTER TABLE t DROP INDEX idx1, DROP INDEX idx2;
      ALTER TABLE t ADD INDEX idx1(a), ADD INDEX idx2(b);
      

      A work-around would be to ensure that the change buffer is empty during shutdown (set innodb_fast_shutdown=0) or to always run with innodb_change_buffering=none.

      This bug was originally reported and analyzed in MDEV-22373, but because MDEV-22373 is partly explained by MDEV-24449 and MDEV-25783, it is clearer to file a separate ticket for this specific case.

      Attachments

        Issue Links

          Activity

            We have been using the combination of
            innodb_change_buffering=none + rebuilding the tables that got reported by check tables after upgrading to 10.4 and so far it seems ok.

            marostegui Manuel Arostegui added a comment - We have been using the combination of innodb_change_buffering=none + rebuilding the tables that got reported by check tables after upgrading to 10.4 and so far it seems ok.

            Pushed to 10.2 and merged to 10.3 and 10.4.

            marko Marko Mäkelä added a comment - Pushed to 10.2 and merged to 10.3 and 10.4.

            People

              marko Marko Mäkelä
              marko Marko Mäkelä
              Votes:
              0 Vote for this issue
              Watchers:
              4 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.