Skip to content

perf(getlogs): reduce partition reads and disabled log conversion - #430

Merged
wanliqun merged 5 commits into
mainfrom
codex/getlogs-performance
Oct 27, 2026
Merged

wanliqun merged 5 commits into
mainfrom
codex/getlogs-performance

Conversation

@wanliqun

@wanliqun wanliqun commented Oct 27, 2026 •

Copy link
Copy Markdown
Contributor

An ordered getLogs query spanning partitions could load almost another 10,000 payload rows just to discover the 10,001st result. Disabled Geth logs also converted fields before Logrus discarded them. This change limits each ordered partition read to the remaining result allowance and checks the live Logrus level before conversion.

Both Core and eSpace retain existing result limits, suggested ranges, error logging, and complete reads when bound checks are disabled. Suggestion retry configuration remains supported. Main already provides indexed-query contexts and shared retry budgets through #428; this PR adds regression coverage for those behaviors and preserves its single-unit complete-read policy.

Commit breakdown

  1. Add reproducible query and logging benchmark fixtures.
  2. Cover cancellation of address/topic indexed queries, including connection-pool waits.
  3. Verify shared suggestion/reorg deadlines and cancellation in both handlers.
  4. Filter disabled Geth log levels before conversion using the adapter's existing Level interface.
  5. Bound universal, dedicated-contract, and dedicated-topic partition payload reads.

Compatibility

  • The early logging threshold only decides whether to convert fields. The existing output mapping remains unchanged: both Geth Info and Warn map to Logrus Info. At a Logrus Info threshold both are emitted; at Warn/Error thresholds both are filtered. Regression tests exercise the actual Geth logger and restore the test's global Warn mapping override.
  • Bounded partition reads use 10001 - len(result), retaining one row to detect overflow. With bound checks disabled, the supplied limit is ignored and all keyset pages are read, including more than 10,000 rows.
  • Bounded requests share the earlier of the caller deadline and the existing 3-second retry budget, including fullnode work. Original single-unit requests keep the caller context for their first complete read; consistency conflicts start the retry budget. Some auxiliary metadata queries do not accept the bounded context, and conversion is not forcibly interrupted, so this is not a hard deadline for every operation inside an RPC.
  • No schema or RPC interface changes. Suggestion retries remain supported with a default of 0. No log sampling or rate limiting is introduced. Different addresses/topics do not share the partition payload budget.

Local measurements

Measured on macOS/arm64, Apple M3 Pro, Go 1.23.10, with SQLite in memory. Each payload is 256 bytes. Each benchmark used 20 iterations; timings are illustrative, not production MySQL throughput or P95/P99 measurements.

Benchmark Before ns/op After ns/op Before / after payload rows Before / after SQL queries
Small (32 logs) 174,715 213,375 32 / 32 4 / 4
At limit (10,000 logs) 23,200,390 23,031,373 10,000 / 10,000 4 / 4
Oversized single partition 765,427 713,469 0 / 0 4 / 4
Cross partition (9,999 + 10,000 logs) 46,652,194 23,605,073 19,999 / 10,001 7 / 7
With topic (10,000 logs) 25,015,221 23,366,535 10,000 / 10,000 4 / 4

For the cross-partition case, allocated bytes decreased from 18,922,097 to 9,402,821 per operation, and allocations from 409,335 to 200,045. Disabled Geth Debug logs at Info level decreased from 2,944 bytes and 40 allocations per call to zero bytes and zero allocations (3,994 to 29.15 ns/op in this short sample). Small-query time increased in this sample despite unchanged reads and allocations; these short runs do not establish a latency regression or meet the production rollout criterion below.

The single-partition oversized benchmark still rejects through the existing lightweight precheck, so its payload count is zero before and after. This PR does not eliminate OFFSET 10000 validation scans or reduce SQL statement counts. Dense filtered queries can still be expensive; evaluate MySQL execution plans and scanned rows using representative production filters before changing indexes or query structure.

Reproduce the benchmarks on the baseline-fixture commit and on the completed branch with:

go test ./store/mysql ./config -run '^$' \
  -bench 'Benchmark(GetLogsPartitions|GethDisabledDebug)$' \
  -benchmem -benchtime=20x -count=1

Validation and rollout

Regression tests cover 0/9,999/10,000/10,001 results, empty partitions, overflow suggestions, topic filters, all three ordered routes, complete reads with bound checks disabled, cancellation during precheck/payload/connection-pool wait, suggestion retry counts of 0/1/3, and shared reorg deadlines. Main's existing integration/context tests also cover fullnode calls and request-local client copies. Logging tests cover live levels, skipped conversion, and grouped/connection fields.

Validation passed:

go test ./...
go test -race ./store/mysql ./rpc/handler ./config
go build -o /tmp/confura-getlogs-performance .

Deploy to one instance first. Compare the same request distribution and offered load with the old version: normal-request P95/P99 (target no more than 5% regression), RPC failures/timeouts, database connection-pool wait, CPU/GC, and MySQL execution counts/scanned rows. Confirm that overload subsides after traffic drops. Local SQLite benchmarks do not establish these production acceptance criteria.

Keep suggestion retries at 0 during overload where operationally acceptable. Confirm that the effective rate strategy contains cfx_getLogs_qps/eth_getLogs_qps; these changes do not modify production rate rules. Revert the PR to roll back; no database migration is required.


This change is Reviewable

@chatgpt-codex-connector

chatgpt-codex-connector Bot commented Oct 27, 2026 •

Copy link
Copy Markdown

Codex Review Summary

This comment shows the latest Codex review activity on this pull request.

Review Status Commit Review trigger
📝 Code Review ✅ Completed 2026-10-27T08:23:35.699295Z be32bbd PR opened
ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review" or "@codex security review".

Codex reacts with 👀 while any review is running, comments if it has suggestions, and reacts with 👍 once all reviews finish with no findings.

@wanliqun
wanliqun force-pushed the codex/getlogs-performance branch from be32bbd to f64678f Compare October 27, 2026 09:14
@wanliqun
wanliqun merged commit ea859fd into main Oct 27, 2026
1 check passed
@wanliqun
wanliqun deleted the codex/getlogs-performance branch October 27, 2026 09:47
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.

1 participant