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

avg_frequency overflow (decimal(12,4)) causes truncated/invalid JSON histogram in mysql.column_stats

    XMLWordPrintable

Details

    • Bug
    • Status: Confirmed (View Workflow)
    • Major
    • Resolution: Unresolved
    • 10.11, 11.4, 11.8, 12.3, 11.4.9
    • 10.11, 11.4, 11.8, 12.3
    • Optimizer
    • None

    Description

      SUMMARY

      ANALYZE TABLE ... PERSISTENT FOR ALL on a very large table (~4.46 billion
      rows) with a low-cardinality column produces a corrupted JSON histogram
      in mysql.column_stats.histogram. The server logs a JSON parse error when
      later reading it back, and re-running ANALYZE TABLE reproduces the same
      truncation every time.

      ENVIRONMENT

      • MariaDB version: 11.4.9-MariaDB
      • Table storage engine: InnoDB
      • Approx. row count: ~4.46 billion (exact count not measured due to table size)
      • Column: `type` (small integer/enum-like column, min_value=0, max_value=9)
      • histogram_type: JSON_HB (default)
      • histogram_size: 254 (default, per target_histogram_size in the output)

      STEPS TO REPRODUCE

      1. Create/have an InnoDB table with several billion rows and a low-
      cardinality integer column (few distinct values, e.g. 0-9).
      2. Run:
      ANALYZE TABLE db.tbl PERSISTENT FOR ALL;
      (takes ~4.5 hours on our hardware for this table size)
      3. Query the resulting row:
      SELECT * FROM mysql.column_stats
      WHERE db_name='db' AND table_name='tbl' AND column_name='type';
      4. Observe:
      a) avg_frequency is capped at 99999999.9999 (the max value
      representable by decimal(12,4)), even though the true value
      (rows / ndv) is approximately 446326524.8 — i.e. the true value
      overflows the column's precision and gets silently clamped.
      b) The `histogram` JSON field is truncated/malformed mid-object, e.g.:

            {
              "target_histogram_size": 254,
              "collected_at": "...",
              "collected_by": "11.4.9-MariaDB-log",
              "histogram_hb": [
                { "start": "0", "size": 0.478226398, "ndv": 1 },
                { "start": "1", "size": 0.003937008, "ndv": 3 },
                { "start": "3"
              ]
            }
      
      

      (Note the third bucket is missing "size"/"ndv" and the closing
      brackets are unbalanced/incorrect.)

      5. On next server startup / optimizer read, this produces:
      [ERROR] InnoDB: (or general) Failed to parse histogram for table
      db.tbl: JSON parse error at offset 313.

      6. Re-running ANALYZE TABLE ... PERSISTENT FOR ALL reproduces the exact
      same truncation deterministically — this is not a one-off storage
      corruption (confirmed via CHECK TABLE mysql.column_stats EXTENDED,
      which reports OK; the mysql.column_stats table itself, an Aria table,
      is not corrupted).

      EXPECTED BEHAVIOR

      • avg_frequency should either use a data type that can hold the true
        value for very large tables, or should not silently clamp/overflow
        without at least a warning.
      • The histogram JSON serialization should not produce truncated/invalid
        JSON under any circumstance — either it completes correctly, or
        ANALYZE TABLE should fail loudly/log a clear error rather than
        persisting a broken value.

      SUSPECTED ROOT CAUSE

      The avg_frequency overflow (decimal(12,4) max = 99999999.9999) for this
      table size suggests an internal counter or intermediate calculation
      related to row/frequency counts hits a numeric limit during histogram
      bucket generation for very large tables with low column cardinality,
      which appears to also corrupt the JSON serialization of the histogram
      itself (possibly a shared buffer/length calculation that also overflows
      or a partial write that isn't rolled back on error).

      CREATE TABLE `column_stats` (
        `db_name` varchar(64) NOT NULL,
        `table_name` varchar(64) NOT NULL,
        `column_name` varchar(64) NOT NULL,
        `min_value` varbinary(255) DEFAULT NULL,
        `max_value` varbinary(255) DEFAULT NULL,
        `nulls_ratio` decimal(12,4) DEFAULT NULL,
        `avg_length` decimal(12,4) DEFAULT NULL,
        `avg_frequency` decimal(12,4) DEFAULT NULL,
        `hist_size` tinyint(3) unsigned DEFAULT NULL,
        `hist_type` enum('SINGLE_PREC_HB','DOUBLE_PREC_HB','JSON_HB') DEFAULT NULL,
        `histogram` longblob DEFAULT NULL,
        PRIMARY KEY (`db_name`,`table_name`,`column_name`)
      ) ENGINE=Aria DEFAULT CHARSET=utf8mb3 COLLATE=utf8mb3_bin PAGE_CHECKSUM=1 TRANSACTIONAL=0 COMMENT='Statistics on Columns'

      Attachments

        Activity

          People

            psergei Sergei Petrunia
            andreasha Andreas H
            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.