Skip to content

perf: stream the slow query log during import to fix the 10GB memory footprint - #47

Merged
TheWitness merged 4 commits into
mainfrom
perf/stream-import-memory
Oct 1, 2026
Merged

TheWitness merged 4 commits into
mainfrom
perf/stream-import-memory

Conversation

@TheWitness

Copy link
Copy Markdown
Member

Summary

Addresses the import memory blow-up (problem #1): a ~1.6GB slow query log (~1M queries) pushed the importer past 10GB RSS.

Root cause

import_logfile() read the entire log into a PHP array up front with file($logfile). For a multi-gigabyte log that costs many times the file's own size in PHP array/string overhead — hence >10GB for a 1.6GB log.

Fix

Stream the log a line at a time with fgets() instead. This is a clean fit because the detail rows are already flushed to plugin_slowlog_details in SLOWLOG_IMPORT_BATCH_SIZE (1000-row) batches as parsing proceeds — so once the whole-file slurp is removed, nothing accumulates in memory and RSS stays flat regardless of log size. (This is the "insert as you go" item.)

  • file($logfile) → fopen() + while (($l = fgets($fh)) !== false), with fclose() after the loop.
  • No change to parsing, batching, or the generated SQL.

Validation

  • php -l clean.
  • tests/Integration/ImportLogfileParsingTest.php drives import_logfile() against a real temp-file log and asserts the generated INSERT SQL; streaming produces byte-identical output, so it stays green.
  • CHANGELOG updated under the unreleased 2.6 section; no version bump (per request).

Not in this PR (proposed follow-up)

Your other points — de-normalizing plugin_slowlog_details_methods from methodid to a method varchar (and dropping the plugin_slowlog_methods/plugin_slowlog_tables dictionary-table usage), and restructuring the SELECT DISTINCT sld.* details query — are a larger schema + query change that rewrites ~6 Pest tests under the 100%-patch-coverage gate and needs a clean install to drop the old tables. I kept this PR to the memory fix (the most severe, blocking issue) so it lands cleanly; happy to do the de-normalization as a focused follow-up PR next.

…ll into memory

import_logfile() read the entire log into a PHP array with file(), so a multi-gigabyte slow query log cost many times its own size in array overhead (a ~1.6GB log pushed the importer past 10GB RSS). Stream it a line at a time with fgets() instead; detail rows are already flushed to plugin_slowlog_details in SLOWLOG_IMPORT_BATCH_SIZE batches as parsing proceeds, so nothing accumulates in memory.
Copilot AI balanced review requested due to automatic review settings October 1, 2026 18:30

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Copilot review overview

🟡 Changes recommended

Stream read errors can silently produce partial imports marked as successful.

Review effort: Balanced
Findings: 1 High severity

Open (1)
What changed in this PR

Streams slow-query logs during import to avoid whole-file memory usage.

Changes:

  • Replaces file() with fopen()/fgets() streaming.
  • Documents the performance improvement.
File Description
includes/​slowlog_functions.php Streams log parsing line by line.
CHANGELOG.md Records the memory optimization.

💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.

Comment thread includes/slowlog_functions.php
fgets() returns false for both EOF and a read error, so a mid-file I/O failure was treated as a clean end-of-log: the partial import was finalized and post-processing started on a truncated log. Check feof() before closing the handle and route a failed read through the import-failure path (status 3) instead of finalizing the parent record.
browniebraun
browniebraun previously approved these changes Oct 1, 2026
xmacan
xmacan previously approved these changes Oct 1, 2026
@TheWitness
TheWitness merged commit 8c95dc3 into main Oct 1, 2026
5 checks passed
@TheWitness
TheWitness deleted the perf/stream-import-memory branch October 1, 2026 21:25
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

5 participants