Commit Graph

3443 Commits

Author SHA1 Message Date
安正超 c76e4dc6bc refactor: clean Swift ECStore boundaries (#3570) 2026-06-18 15:18:55 +08:00
安正超 0e7e2660bb refactor: clean remaining storage DTO imports (#3568) 2026-06-18 14:44:46 +08:00
安正超 acdf439371 refactor: clean external DTO consumers (#3566)
* refactor: clean external DTO consumers

* fix: handle empty erasure shard recovery
2026-06-18 14:22:44 +08:00
安正超 99941f7e7c refactor: clean external operation consumers (#3565) 2026-06-18 12:39:41 +08:00
houseme d2a135b397 fix(admin): require admin auth for metrics (#3562)
fix: require admin auth for metrics
2026-06-18 12:39:16 +08:00
GatewayJ a30cafa73f fix(filemeta): detect physical data dirs for overwrite cleanup (#3510) 2026-06-18 11:58:12 +08:00
安正超 24443c829d refactor: clean shared list operation consumers (#3563) 2026-06-18 11:57:46 +08:00
Henry Guo 46e200c22b feat(scanner): prioritize dirty usage refresh work (#3538) 2026-06-18 11:03:23 +08:00
houseme 32aca6d835 feat(fuzz): scaffold cargo-fuzz harness for smoke targets (#3537) 2026-06-18 11:02:56 +08:00
Henry Guo ea70d5697a test(table-catalog): harden smoke catalog probes (#3535) 2026-06-18 11:01:09 +08:00
安正超 57403525ee refactor: move heal and namespace contracts (#3560) 2026-06-18 11:00:21 +08:00
安正超 e5cad7ed20 refactor: move object operation contracts (#3559) 2026-06-18 09:48:13 +08:00
安正超 3fb4cb3d65 refactor: move list operations contract (#3550) 2026-06-18 08:48:18 +08:00
安正超 36f7ad6936 refactor: move walk options contract (#3549) 2026-06-18 08:18:26 +08:00
Henry Guo 604379d62f feat(table-catalog): harden table row-level commit conflicts (#3517)
* feat(table-catalog): harden snapshot conflict validation

* feat: harden table row-level commit conflicts

* fix: accept additional row-level snapshot shapes

* test(table-catalog): expand smoke catalog probes

* fix(table-catalog): satisfy row-level clippy checks

---------

Co-authored-by: Henry Guo <marshawcoco@users.noreply.github.com>
Co-authored-by: houseme <housemecn@gmail.com>
2026-06-18 07:32:20 +08:00
安正超 24fa03e04b refactor: move object list response contracts (#3548) 2026-06-18 07:19:07 +08:00
安正超 80ed63484b refactor: move object precondition contracts (#3547) 2026-06-18 06:34:30 +08:00
安正超 54bbd05b25 refactor: move object list helper contracts (#3546) 2026-06-18 06:09:33 +08:00
houseme 87a3d107d6 test(property): add path validator invariants (#3541)
test(property): add path validator invariants for #3525
2026-06-18 02:14:24 +08:00
houseme bc769948ab test(property): add erasure recoverability invariants (#3540) 2026-06-18 01:34:07 +08:00
安正超 53337a6f71 refactor: move HTTP range helper contracts (#3533) 2026-06-18 00:47:23 +08:00
houseme cc84d9065e test(property): add filemeta invariants (#3536)
* test(property): add filemeta invariants for #3523

* docs: relocate issue-3518 property testing plan

* docs: keep issue-3518 property plan local only
2026-06-18 00:36:55 +08:00
houseme 841f86fe90 test(property): expand parser invariants (#3534)
* test(property): harden parser invariants for #3522

* test(property): satisfy clippy for #3522
2026-06-17 23:52:30 +08:00
安正超 919deeb816 refactor: move object option helper contracts (#3521) 2026-06-17 22:56:10 +08:00
Henry Guo a97122ab80 fix(heal): retry recoverable bucket heal failures (#3509)
* fix(heal): retry recoverable bucket heal failures

* fix(heal): keep merged heal tokens cancellable

* fix(heal): group queue processing context

---------

Co-authored-by: Henry Guo <marshawcoco@users.noreply.github.com>
Co-authored-by: houseme <housemecn@gmail.com>
2026-06-17 22:45:29 +08:00
Henry Guo a9aba323c6 fix(scanner): restore prompt bucket usage scans (#3516)
Co-authored-by: Henry Guo <marshawcoco@users.noreply.github.com>
Co-authored-by: houseme <housemecn@gmail.com>
2026-06-17 21:49:56 +08:00
houseme 8d24d9133b perf(put): comprehensive PUT performance optimization (#3514)
* perf(put): add eager path metrics and isolation tooling

* fix(decommission): persist progress adaptively (#3497)

Persist decommission progress after either the existing time interval or a migrated-item threshold, and flush progress baselines after bucket and terminal-state saves.

Also stabilize the OIDC discovery mock used by the pre-commit gate.

* refactor: move bucket operations contract (#3507)

* fix(s3): handle multipart flexible checksums (#3508)

* fix(io-core): avoid blocking on pooled buffer return

* perf(put): add slow inflight diagnostics

* perf(put): fix 16KiB regression with threshold and pool bypass

- Lower SMALL_EAGER_PUT_MAX_SIZE from 256KB to 8KB so objects >8KiB
  use the streaming BufReader path (matches baseline behavior)
- Add POOL_BYPASE_MAX_SIZE (16KiB) to bypass BytesPool for very small
  objects, avoiding Small-tier Mutex contention under high concurrency
- Add read_small_put_body_exact_direct() for direct Vec<u8> allocation
- Fix stale test assertions to match new 8KB threshold

Root cause analysis: the 16KiB regression was primarily caused by
instrumentation overhead in set_disk.rs (4x Instant::now() + metrics
per PUT), not BytesPool contention. Lowering the threshold eliminates
the eager-path overhead for 16KiB+ objects.

* perf(put): gate stage metrics behind observability flag

Add put_stage_metrics_enabled() AtomicBool switch in io-metrics crate.
When disabled (default), record_put_object_path() and
record_put_object_stage_duration() are no-ops, avoiding unnecessary
histogram/counter macro overhead in the PUT hot path.

The flag is set to true during startup when OTEL metric export is
enabled (rustfs_obs::observability_metric_enabled() == true).

This eliminates the per-request metrics overhead that contributed
to the 16KiB PUT regression when metrics collection is not active.

* perf(put): comprehensive optimization - restore eager path, cache env, remove UUID

Change 1: Restore SMALL_EAGER_PUT_MAX_SIZE from 8KB to 1MB
- The try_lock() fix (d13a189e3) eliminates the blocking that caused
  service health timeouts under 512KiB c64 load
- Eager path with BytesPool is now safe for objects up to 1MB
- Recovers the eager path benefit for 32KiB-256KiB objects

Change 2: Adjust POOL_BYPASE_MAX_SIZE from 16KB to 4KB
- With eager path restored to 1MB, objects 4KB-1MB benefit from pool reuse
- Only ≤4KB objects bypass the pool (allocation cost negligible)

Change 3: Cache RUSTFS_ERASURE_ENCODE_MAX_INFLIGHT_BYTES via OnceLock
- Eliminates per-encode std::env::var() syscall
- Env var still works (read once at first use)

Change 4: Replace Uuid::new_v4() with Uuid::nil() in Erasure construction
- _id field is unused in hot paths (documented in code)
- Eliminates CSPRNG syscall per PUT request

Change 5: Add concurrency-aware buffer sizing to PUT path
- Reuses get_concurrency_aware_buffer_size() from GET path
- Reduces buffer size under high concurrency (0.4x at >8 concurrent)
- Lowers memory pressure for >1MB streaming PUTs

* chore: add pyroscope feature flag and clean up imports

- Add pyroscope feature flag forwarding to rustfs-obs
- Remove unused allow(non_upper_case_globals) in globals.rs
- Sort imports and fix Cargo.toml formatting consistency

* style: fix import ordering and code formatting

- Sort imports alphabetically in globals.rs, encode.rs
- Fix indentation in erasure_coding encode/erasure
- Clean up HashReader formatting in object_usecase.rs

* fix(test): use tokio::test for request_logging_layer tests

The tests call tokio::spawn via RequestContextLayer, which requires a
Tokio runtime. Changed from #[test] + futures::executor::block_on to
#[tokio::test] + .await, and replaced tracing::subscriber::with_default
with tracing::subscriber::set_default to support async.

* fix(bench): normalize no-space throughput/latency parsing in to_bps/to_ms

When a benchmark tool prints throughput without a separator (e.g. 123MiB/s),
awk '{print $2}' returns empty because the whole string is one field,
causing to_bps to return N/A and losing valid measurements in CSV output.

Insert a space between number and unit via sed before awk field splitting.
Same fix applied to to_ms for latency values like '50ms'.

Also add TODO comment on PUT path noting that get_concurrency_aware_buffer_size
reads ACTIVE_GET_REQUESTS instead of PUT concurrency (PR #3514 review).

Refs: PR #3514 review comments by chatgpt-codex-connector

* fix(metrics): correct POOL_BYPASS comments and separate PUT vs generic stage metrics

- Fix 3 comment-code mismatches: POOL_BYPASS_MAX_SIZE is 4KiB, not 16KiB
- Add generic record_stage_duration() with separate histogram
  (rustfs_internal_stage_duration_ms) for non-PUT paths
- Replace record_put_object_stage_duration with record_stage_duration in
  metacache_set, store_list_objects, and bucket_lifecycle_ops to avoid
  polluting PUT-specific dashboards with listing/lifecycle timings
- Fix flaky test: serialize tests mutating PUT_STAGE_METRICS_ENABLED with
  METRICS_FLAG_LOCK mutex and explicitly set desired state at test start

Refs: PR #3514 review comments by chatgpt-codex-connector

* style: apply cargo fmt to metacache_set.rs

---------

Co-authored-by: cxymds <cxymds@gmail.com>
Co-authored-by: 安正超 <anzhengchao@gmail.com>
2026-06-17 21:19:11 +08:00
majinghe a58692f550 fix(heal): bind service account to sts and deployment (#3513) 2026-06-17 18:36:24 +08:00
安正超 38bbba4c5c fix(s3): handle multipart flexible checksums (#3508) 2026-06-17 11:54:58 +08:00
安正超 ed55857bca refactor: move bucket operations contract (#3507) 2026-06-17 09:10:38 +08:00
cxymds 5b36ef5556 fix(decommission): persist progress adaptively (#3497)
Persist decommission progress after either the existing time interval or a migrated-item threshold, and flush progress baselines after bucket and terminal-state saves.

Also stabilize the OIDC discovery mock used by the pre-commit gate.
2026-06-17 08:17:59 +08:00
安正超 1830911973 fix(s3): return content disposition on get object (#3504) 2026-06-17 02:23:13 +08:00
安正超 0c259547d1 refactor: move multipart DTO contracts (#3505) 2026-06-17 00:33:06 +08:00
安正超 2ff69ae21c refactor: remove ecstore bucket DTO aliases (#3503) 2026-06-16 22:10:07 +08:00
cxymds d094d91925 fix(site-replication): harden service account sync (#3500) 2026-06-16 21:20:13 +08:00
Henry Guo cd96491b39 feat(table-catalog): add refs and views semantics (#3502)
Co-authored-by: Henry Guo <marshawcoco@users.noreply.github.com>
2026-06-16 21:19:27 +08:00
安正超 966756d788 test: guard storage contract cleanup (#3501) 2026-06-16 21:18:52 +08:00
cxymds c405470f73 test(decommission): cover tier lifecycle recovery flows (#3494)
Co-authored-by: houseme <housemecn@gmail.com>
2026-06-16 16:48:24 +08:00
cxymds 0f37c5675e fix(ecstore): bound decommission bucket concurrency (#3498) 2026-06-16 15:11:54 +08:00
cxymds ba0ba0d35e fix(lifecycle): persist remote tier delete journal tasks (#3493)
fix: persist remote tier delete journal tasks
2026-06-16 10:38:41 +08:00
Henry Guo b5d19e6595 test(scanner): close parity validation harness (#3486) 2026-06-16 08:46:22 +08:00
Adnan Hussain Turki 401e876209 fix(admin): reject access keys and names containing any whitespace (#3488) 2026-06-16 08:46:05 +08:00
cxymds 156e21c90e fix(lifecycle): make tier cleanup recoverable (#3491) 2026-06-16 08:45:49 +08:00
Henry Guo d23ed02b3f feat(table-catalog): add parquet compaction commit (#3487)
Co-authored-by: Henry Guo <marshawcoco@users.noreply.github.com>
2026-06-16 08:02:18 +08:00
安正超 0baf90ee88 refactor: remove storage api facade (#3490) 2026-06-16 07:46:32 +08:00
安正超 c26593fa7a refactor: clean config storage boundaries (#3489) 2026-06-16 06:35:32 +08:00
安正超 fbab160c2b refactor: narrow replication storage consumers (#3485) 2026-06-15 22:29:38 +08:00
Henry Guo 65c724c786 feat(table-catalog): add manifest reachability cleanup (#3484)
Co-authored-by: Henry Guo <marshawcoco@users.noreply.github.com>
2026-06-15 22:29:23 +08:00
Henry Guo b387689f26 feat(heal): expose scanner-aware operations status (#3483)
Co-authored-by: Henry Guo <marshawcoco@users.noreply.github.com>
2026-06-15 22:28:53 +08:00
Ramakrishna Chilaka 956bd19417 perf(ecstore): reuse erasure-decode shard buffers across stripes (#3482)
* perf(ecstore): reuse erasure-decode shard buffers across stripes

ParallelReader::read allocated and zero-filled a fresh
`vec![0u8; shard_size]` per shard on every erasure stripe. Erasure::decode
builds one ParallelReader and loops stripes, so those buffers can be
reused: BitrotReader::read overwrites buf[..n] and the caller truncates to
n, so leftover bytes from the prior stripe are never observed. The decode
loop now hands each stripe's shard buffers back to the reader, which
reuses them (resized to shard_size) on the next stripe. The heal path,
which consumes its buffers into Bytes, never hands them back and is
unchanged.

This path runs on every object GET. Streaming-decode benchmark
(Erasure::decode end-to-end, median):

  4+2 16MiB 1MiB-block:  -9.6% verify-on,  -23.8% verify-off
  6+3 24MiB 1MiB-block:  -9.7% verify-on,  -22.5% verify-off
  4+2  4MiB 64KiB-block: -5.5% verify-on,  -16.3% verify-off

Adds a streaming-decode benchmark covering the ParallelReader path and a
regression test that decodes a multi-stripe object with missing data
shards (so reconstructed buffers are recycled) with bitrot verification
both on and off, asserting byte-exact output.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>

* perf(ecstore): tighten decode buffer reuse and bench harness

Address PR review feedback on the erasure-decode buffer-reuse change:

- Only claim a recycled shard buffer inside the `Some(reader)` branch of
  `ParallelReader::read`, so the take is co-located with the read that
  uses it and missing shards no longer touch the recycle slot.
- Move per-shard `BitrotReader` construction into Criterion `iter_batched`
  setup so reader/UUID construction stays out of the timed decode path,
  and assert decode success plus full output length each iteration.

Re-measured with the cleaner harness (median, before -> after, all
p < 0.05): verify-on -5.3%..-11.7%, verify-off -15.8%..-25.3%.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>

* perf(ecstore): drop dead recycle slots and tidy decode bench

Address the second PR review pass:

- In `Erasure::decode`, clear recycled slots for missing-shard (None-reader)
  indices before handing buffers back. `ParallelReader::read` only reuses
  slots with an active reader, and `decode_data` always re-allocates the
  reconstructed shard, so retaining those buffers only held memory that could
  never be reused in degraded reads.
- Move the output sink into the benchmark's `iter_batched` setup and validate
  decode success/output length once per config instead of inside the timed
  loop, so neither sink construction nor assertions touch the measurement.

Re-measured with the final harness (median, before -> after, all p < 0.05):
verify-on -5.2%..-9.8%, verify-off -19.4%..-25.8%.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>

---------

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
2026-06-15 22:28:39 +08:00