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

SET innodb_log_file_write_through succeeds but is silently ignored during redo resize

    XMLWordPrintable

Details

    • Bug
    • Status: Open (View Workflow)
    • Major
    • Resolution: Unresolved
    • 12.3.3
    • None
    • None

    Description

      While an InnoDB redo-log resize is in progress,
      `SET GLOBAL innodb_log_file_write_through=ON` returns success even though the
      requested value is not applied. Reading the variable immediately after the
      successful statement still returns `0`.

      The internal setter declines to change the value while resize state is active,
      but its `void` result is not propagated to the SQL system-variable framework.

      Steps to reproduce

      The resize window is short, so the script tries a bounded sequence of 64 MiB / 96
      MiB resizes and stops on the first observed silent failure.

      set -eu
      IMAGE='mariadb@sha256:dd9b303aed4f4890ed09f766d8ca9ddfd176c0c6f6267feff53b3192ec65a979'
      C='mdev-redo-write-through-resize'
      OWNER="edbf-report-mcfg02-$$"
      D=$(mktemp -d)
      cleanup() {
        if docker inspect --format '{{ index .Config.Labels "io.encryptiondbfuzz.owner" }}' \
             "$C" 2>/dev/null | grep -Fqx "$OWNER"; then
          docker rm -f "$C" >/dev/null 2>&1 || true
        fi
        rm -r "$D" >/dev/null 2>&1 || true
      }
      trap cleanup EXIT
       
      docker run --detach --name "$C" \
        --label "io.encryptiondbfuzz.owner=$OWNER" \
        --network none --read-only --cap-drop ALL \
        --security-opt no-new-privileges=true --pids-limit 160 \
        --memory 1g --cpus 1 --user 999:999 \
        --tmpfs /var/lib/mysql:rw,nosuid,nodev,size=512m,uid=999,gid=999 \
        --tmpfs /run/mysqld:rw,nosuid,nodev,size=16m,uid=999,gid=999 \
        --tmpfs /tmp:rw,nosuid,nodev,size=64m,uid=999,gid=999 \
        --env MARIADB_ALLOW_EMPTY_ROOT_PASSWORD=1 "$IMAGE"
       
      READY=0
      for I in $(seq 1 90); do
        if docker exec --user 999:999 "$C" mariadb --protocol=socket \
             --socket=/run/mysqld/mysqld.sock -uroot -NBe 'SELECT @@port' \
             2>/dev/null | grep -qx 3306; then
          READY=1
          break
        fi
        sleep 1
      done
      test "$READY" -eq 1
       
      sql() {
        docker exec --user 999:999 "$C" mariadb --protocol=socket \
          --socket=/run/mysqld/mysqld.sock -uroot --batch --skip-column-names \
          --execute "$1"
      }
       
      sql 'SET GLOBAL innodb_log_file_write_through=OFF;
           SELECT @@innodb_log_file_size,@@innodb_log_file_write_through'
       
      FOUND=0
      for ATTEMPT in $(seq 1 16); do
        sql 'SET GLOBAL innodb_log_file_write_through=OFF'
        if test $((ATTEMPT % 2)) -eq 1; then TARGET=67108864; else TARGET=100663296; fi
       
        sql "SET GLOBAL innodb_log_file_size=$TARGET" \
          >"$D/resize-$ATTEMPT.out" 2>"$D/resize-$ATTEMPT.err" &
        RESIZE_PID=$!
        RUNNING_BEFORE=0
        if kill -0 "$RESIZE_PID" 2>/dev/null; then RUNNING_BEFORE=1; fi
       
        VALUE=$(sql 'SET GLOBAL innodb_log_file_write_through=ON;
                     SELECT @@innodb_log_file_write_through')
        RUNNING_AFTER=0
        if kill -0 "$RESIZE_PID" 2>/dev/null; then RUNNING_AFTER=1; fi
        wait "$RESIZE_PID" || true
       
        printf 'attempt=%s resize_running_before=%s resize_running_after=%s value_after_successful_set=%s\n' \
          "$ATTEMPT" "$RUNNING_BEFORE" "$RUNNING_AFTER" "$VALUE"
        if test "$VALUE" = 0 && \
           { test "$RUNNING_BEFORE" -eq 1 || test "$RUNNING_AFTER" -eq 1; }; then
          FOUND=1
          break
        fi
      done
      test "$FOUND" -eq 1
      sql 'SELECT 1,@@innodb_log_file_write_through'
      

      Actual result

      The first attempt reproduced the issue in the tested image. The resize process
      was still active on both observations; the `SET ...=ON` command returned exit
      code 0, but its own readback returned 0:

      100663296    0
      attempt=1 resize_running_before=1 resize_running_after=1 value_after_successful_set=0
      1    0
      

      There was no SQL error or warning indicating that the requested configuration
      change had been declined.

      Expected result

      MariaDB should either apply the requested value after coordinating with the
      resize, wait until it can safely apply it, or return a clear SQL error. A
      successful `SET GLOBAL` must not silently leave the old value in effect.

      Impact and boundary

      An administrator can receive a false success response for a durability/I/O
      configuration change. The server remained healthy and no crash or data loss
      was demonstrated. The trigger requires an overlapping redo resize and
      administrative access. Only MariaDB 12.3.3 was tested. This report is
      researcher-reproduced and not yet maintainer-confirmed.

      Attachments

        Issue Links

          Activity

            People

              tafzeel Mohammad Tafzeel Shams
              csfuzz csfuzz
              Votes:
              0 Vote for this issue
              Watchers:
              2 Start watching this issue

              Dates

                Created:
                Updated:

                Git Integration

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