Skip to content

Add article: exporting query and session logs to files, S3, or HTTP - #189

Merged
BorisTyshkevich merged 1 commit into
mainfrom
kb/export-system-logs
Aug 25, 2026
Merged

Add article: exporting query and session logs to files, S3, or HTTP#189
BorisTyshkevich merged 1 commit into
mainfrom
kb/export-system-logs

Conversation

@BorisTyshkevich

Copy link
Copy Markdown
Contributor

What this adds

A new article at content/en/altinity-kb-setup-and-maintenance/altinity-kb-export-system-logs.md covering how to get system.query_log and system.session_log out of the server and into S3, an HTTP collector, or a file.

Gap it fills. Swept all of content/en: session_log appears exactly once in the KB, as <session_log remove="1"/> in altinity-kb-system-tables-eat-my-disk.md. logging.md and ch-logs-2-json-vectordev.md cover only the server text log files, not the system.*_log tables. Every article under altinity-kb-s3-object-storage/ treats S3 as MergeTree storage, never as an export sink. There is no article on the URL engine or on an MV writing to an external target.

Testing

Per AGENTS.md ("every recipe must be copy-pasteable and tested"), every DDL block, object name, file path, and error message in the article was produced by running it. Lab: clickhouse-server in Docker against MinIO and a stdlib HTTP collector.

Versions: 26.7.5.10 (latest stable), 26.4.5.143, 26.3.21.7 (LTS), 25.8.32.4, 24.10.1.2812 (pre-#75679).

The three recipes were re-run verbatim on a clean 26.7.5.10 server as a final check.

Findings worth a reviewer's attention

1. An MV with an S3 target can permanently destroy local system.query_log rows.

materialized_views_ignore_errors=true (set unconditionally since 23.3) only guards exceptions thrown while pushing rows. The S3 sink's object-existence probe throws during sink construction:

DB::checkAndGetNewFileOnInsertIfNeeded(...)
DB::StorageObjectStorage::write(...)
DB::InsertDependenciesBuilder::createSink(...)
DB::InsertDependenciesBuilder::createPostSink(...)
DB::InterpreterInsertQuery::execute()

That escapes the guard and fails the whole flush, and there is no retry path — SystemLogQueue::pop() detaches the batch before the insert runs.

MV target state Markers surviving locally
No MV (control) 20 / 20
Working S3 target (control) 20 / 20
S3, setting not effective 1 / 20
S3, endpoint unreachable 0 / 10

Same on 26.3.21.7 and 25.8.32.4. URL targets are unaffected (10/10 preserved on both HTTP 503 and connection-refused), so the usual "export failures are harmless" framing is true for HTTP and false for S3.

2. The obvious way to set s3_create_new_file_on_insert doesn't work. On a CREATE TABLE with an S3 engine the SETTINGS clause is silently dropped — it never appears in SHOW CREATE TABLE. On the MV it is preserved in SHOW CREATE but has no effect on the target write. Only a users.d profile default works. The article documents all three, since the two that fail are the two anyone would try first.

3. Upgrades silently break the export. After 25.8.32.4 → 26.7.5.10, system.query_log is renamed to query_log_0 and the MV follows the renamed table — 0 rows exported, no error, SystemLogErrorOnFlush never increments, and SHOW CREATE TABLE still reads FROM system.query_log. The article includes a system.tables detection query and the fix.

4. Issue #112419 reproduced. Two servers on one S3 key sequence: 300 inserts, all acknowledged, zero errors, only 267 objects afterwards.

5. SystemLogErrorOnFlush was added in 25.2 (PR #75466; the changelog lists it under 25.3). Its own description string in system.events says "Attempts to flush are repeated." — which is false for this path, and would lead an operator to the opposite of the right conclusion.

Also corrected along the way: the File engine does accept a stable path under user_files and appends across flushes (an arbitrary absolute path gives code 291), and the ifNull() casts on session_log are needed — not for the DDL, which accepts implicit conversion, but because a real NULL raises code 349 at push time, which is silently swallowed during a flush.

Second file in this PR

The 2-line note in altinity-kb-system-tables-eat-my-disk.md is attached to its existing Note 2 about renamed _N log tables — exactly the hazard finding 3 describes. It is in this PR rather than a separate one because it links to the new page and would 404 on its own.

Verification

Built with the CI-pinned Hugo (0.128.2, per .github/workflows/gh-pages.yml): 328 pages, page renders, all 6 {{% alert %}} shortcodes resolve with no leakage, both internal links resolve to existing pages, and the page appears in the Setup & maintenance nav in the expected alphabetical position for weight: 100.

Note for maintainers: the site does not build on any Hugo newer than 0.128.2 — unknown output format "md" for kind "home", then .Site.DisqusShortname removal. That is pre-existing on main and unrelated to this PR.

Reviewer notes

  • The profile-wide s3_create_new_file_on_insert default has a blast radius beyond the audit export; the article flags this rather than hiding it. If there's a narrower placement I missed, I'd like to know — I tested table-level and MV-level and both fail.
  • The reconciliation / Distributed-sender section is design prose, not a recipe, and makes no tested claim.
  • Issue #112419's mechanism (check-then-act on the free-suffix probe) is attributed to the issue; I reproduced the symptom, not the code path.

🤖 Generated with Claude Code

https://claude.ai/code/session_01AsB1E5eSBXpaZT4jGzY57L

The KB had no coverage of getting system.query_log / system.session_log
out of the server for auditing. session_log appeared exactly once across
content/en (as <session_log remove="1"/>); logging.md and
ch-logs-2-json-vectordev.md cover only the server text log files; the
S3 articles treat S3 as MergeTree storage, never as an export sink.

Every recipe and error message in the article was executed against
clickhouse-server in Docker (26.7.5.10, 26.4.5.143, 26.3.21.7 LTS,
25.8.32.4, 24.10.1.2812) with MinIO and a local HTTP collector.

Findings that shaped the article:

- A materialized view with an S3 target can permanently destroy rows in
  the local system.query_log. materialized_views_ignore_errors only
  guards row-push errors; the S3 sink's object-existence probe throws
  during createSink(), outside the guard, which fails the whole flush.
  Measured: 20/20 markers survive with no MV and with a working target,
  1/20 with a misconfigured S3 target, 0/10 with an unreachable one.
  Reproduced on 26.7, 26.3 and 25.8. URL targets are unaffected.

- SETTINGS s3_create_new_file_on_insert = 1 on a CREATE TABLE with an
  S3 engine is silently dropped (absent from SHOW CREATE TABLE). The
  same setting on the MV is kept but has no effect on the target write.
  Only a users.d profile default works.

- After an upgrade that renames system.query_log to query_log_0, the MV
  follows the renamed table and the export stops silently, with no error
  and no SystemLogErrorOnFlush increment. Includes a detection query
  against system.tables and the fix.

- Issue #112419 reproduced: two servers on one S3 key sequence made 300
  acknowledged inserts with zero errors and left only 267 objects.

- File engine does accept a stable path under user_files and appends
  across flushes; an arbitrary absolute path is rejected with code 291.

- SystemLogErrorOnFlush was added in 25.2 (PR #75466). Its description
  string claims failed flushes are repeated; they are not.

The one-line note in altinity-kb-system-tables-eat-my-disk.md is
included here because it links to the new page.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01AsB1E5eSBXpaZT4jGzY57L
@github-actions

Copy link
Copy Markdown
Contributor


Thank you for your submission, we really appreciate it. Like many open-source projects, we ask that you sign our Contributor License Agreement before we can accept your contribution. You can sign the CLA by just posting a Pull Request Comment same as the below format.


I have read the CLA Document and I hereby sign the CLA


You can retrigger this bot by commenting recheck in this Pull Request. Posted by the CLA Assistant Lite bot.

@BorisTyshkevich
BorisTyshkevich merged commit af28030 into main Aug 25, 2026
1 of 2 checks passed
@github-actions github-actions Bot locked and limited conversation to collaborators Aug 25, 2026
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant