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

Rejected compound SET silently changes the InnoDB FTS auxiliary-table target

    XMLWordPrintable

Details

    • Bug
    • Status: Open (View Workflow)
    • Major
    • Resolution: Unresolved
    • 12.3.3
    • None
    • Admin statements, Server
    • None
    • Can result in unexpected behaviour

    Description

      The validator for `innodb_ft_aux_table` publishes the selected table ID while
      MariaDB is still checking a compound `SET`. If a later assignment is invalid,
      the statement returns an error and the visible string variable is unchanged,
      but the hidden table ID remains changed.

      After the failed statement below, `@@innodb_ft_aux_table` still reports table
      `a`, while `INFORMATION_SCHEMA.INNODB_FT_INDEX_TABLE` returns words belonging
      to table `b`.

      Steps to reproduce

      set -eu
      IMAGE='mariadb@sha256:dd9b303aed4f4890ed09f766d8ca9ddfd176c0c6f6267feff53b3192ec65a979'
      C='mdev-ft-aux-partial-set'
      OWNER="edbf-report-mcfg08-$$"
      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
      }
      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"
      $SQL -e "
        CREATE DATABASE edbf_cfg;
        CREATE TABLE edbf_cfg.a(
          id INT PRIMARY KEY AUTO_INCREMENT, body TEXT, FULLTEXT(body)
        ) ENGINE=InnoDB;
        CREATE TABLE edbf_cfg.b(
          id INT PRIMARY KEY AUTO_INCREMENT, body TEXT, FULLTEXT(body)
        ) ENGINE=InnoDB;
        INSERT INTO edbf_cfg.a(body) VALUES('alphaonly alphaonly');
        INSERT INTO edbf_cfg.b(body) VALUES('betaonly betaonly');
        SET GLOBAL innodb_ft_aux_table='edbf_cfg/a';"
       
      echo 'before_variable:'
      $SQL -e 'SELECT @@GLOBAL.innodb_ft_aux_table'
      echo 'before_words:'
      $SQL -e "SELECT GROUP_CONCAT(DISTINCT WORD ORDER BY WORD)
        FROM (SELECT WORD FROM INFORMATION_SCHEMA.INNODB_FT_INDEX_TABLE
              UNION ALL
              SELECT WORD FROM INFORMATION_SCHEMA.INNODB_FT_INDEX_CACHE) AS w"
       
      set +e
      $SQL -e "SET GLOBAL innodb_ft_aux_table='edbf_cfg/b', binlog_format='INVALID'"
      RC=$?
      set -e
      echo "failed_compound_set_rc=$RC"
      test "$RC" -ne 0
       
      echo 'after_variable:'
      $SQL -e 'SELECT @@GLOBAL.innodb_ft_aux_table'
      echo 'after_words:'
      $SQL -e "SELECT GROUP_CONCAT(DISTINCT WORD ORDER BY WORD)
        FROM (SELECT WORD FROM INFORMATION_SCHEMA.INNODB_FT_INDEX_TABLE
              UNION ALL
              SELECT WORD FROM INFORMATION_SCHEMA.INNODB_FT_INDEX_CACHE) AS w"
      

      Actual result

      The control initially points to table `a` and returns its word. The compound
      statement is rejected, but only the displayed variable is rolled back:

      before_variable:
      edbf_cfg/a
      before_words:
      alphaonly
      ERROR 1231 (42000): Variable 'binlog_format' can't be set to the value of 'INVALID'
      failed_compound_set_rc=1
      after_variable:
      edbf_cfg/a
      after_words:
      betaonly
      

      Expected result

      If any assignment in a compound `SET` fails validation, no assignment or
      validator side effect should become visible. Both the string value and the
      internal FTS table ID should remain on table `a`.

      Attachments

        Issue Links

          Activity

            People

              Unassigned Unassigned
              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.