Uploaded image for project: 'MariaDB ColumnStore'
  1. MariaDB ColumnStore
  2. MCOL-6671

KILL doesn't stop a disk-based aggregation in RowAggStorage::finalize; PrimProc keeps rewriting spill files

    XMLWordPrintable

Details

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

    Description

      After KILL of a query that is in a disk-based aggregation, mysqld drops the query but PrimProc keeps working on it. It keeps merging and rewriting the spill files, using CPU and disk, until PrimProc is restarted.

      What we saw (23.02.24, Rocky 8, 3-node cluster, columnstore_um_mem_limit=64, local SystemTempFileDir)

      • Query: select a, count, max(b) from t group by a order by 2 desc limit 3 with a where a < 1000000 filter on a large table, so the aggregation spills. After 10 minutes it had about 219k spill files (16 GB). We killed it with KILL <id>.
      • mysqld dropped the query right away. On the node running it, 8 PrimProc threads stayed in RowAggStorage::finalize -> RowGroupStorage::dumpFinalizedInfo at about 60% CPU. 15+ minutes later they were still rewriting the spill files.
      • Only a full cluster stop/start cleared it. The spill files and the work belonged to a query nobody was waiting for.
      • An earlier KILL of the same query without the filter (about 1.1M spill files at the time) did clean up within about a minute. So it depends on which phase the aggregation is in: we think the cancel is only noticed between phases, and finalize is one long phase.

      Where it happens
      RowAggStorage::finalize (utils/rowgroup/rowstorage.cpp:2040) merges the spilled generations in nested loops (from about line 2059: while (--curGen > 0), then per previous generation, then per row). Each pass reads and rewrites spill files (dumpFinalizedInfo, dumpAll). None of these loops checks whether the query was cancelled, so a KILL that arrives during finalize only takes effect when it returns, which for a large spill can take hours.

      Impact

      • A killed query keeps a PrimProc busy (CPU, disk I/O and the spill space in SystemTempFileDir) and slows every other query on that node.
      • Users see the query as gone and may rerun it, which starts a second spill next to the first.
      • The only way out is restarting PrimProc, which kills every other running query.

      Suggested fix
      Check the step's cancel/abort flag inside the finalize loops (once per generation and every N rows) and throw the usual "query cancelled" error. The spill files are then removed by the existing cleanup when the aggregation object is destroyed. The same check likely belongs in the other long spill loops (RowGroupStorage merge/dump, disk-based join).

      Related
      MCOL-6614 (no read timeouts between services; KILL can't free a query waiting on a dead connection). It's a different cause, but the same symptom of a query that outlives its KILL. MCOL-563 (disk-based aggregation).

      Stack dumps of the stuck threads can be shared as needed.

      Attachments

        Issue Links

          Activity

            People

              Unassigned Unassigned
              kyle.hutchinson Kyle Hutchinson
              Votes:
              0 Vote for this issue
              Watchers:
              1 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.