Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
75 commits
Select commit Hold shift + click to select a range
cba62d6
Add a regression test for global RIGHT JOIN on Distributed tables
ianton-ru Sep 4, 2026
3ec16e4
Rewrite global RIGHT JOIN of Distributed tables as LEFT JOIN
ianton-ru Sep 4, 2026
5ca17e5
Skip wrapping IStorageCluster on GLOBAL INNER/LEFT joins
ianton-ru Sep 4, 2026
3df7433
Widen the global RIGHT JOIN rewrite of Distributed tables
ianton-ru Sep 8, 2026
be7d6ed
Look through wrapper storages when rewriting a global RIGHT JOIN of D…
ianton-ru Sep 9, 2026
449a143
Merge branch 'antalya-26.6' into bugfix/antalya-26.6/distributed-glob…
ianton-ru Sep 10, 2026
4a73d6d
add cas disk to existing backup tests
k-morozov Sep 25, 2026
3300f85
update test
k-morozov Sep 25, 2026
db9e668
Merge branch 'antalya-26.6' into bugfix/antalya-26.6/distributed-glob…
ianton-ru Oct 1, 2026
46c5fb6
Move PREWHERE onto the broadcast side of a global RIGHT JOIN
ianton-ru Oct 1, 2026
ba2bac0
CAS GC: batch the namespace janitor's deletes under a soft time budget
filimonov Oct 5, 2026
aba7e09
CAS GC janitor: a refused delete job leaks instead of dropping the page
filimonov Oct 5, 2026
2644a44
CAS GC janitor test: make the quiet-pool round a decided one
filimonov Oct 5, 2026
b7b813d
CAS GC janitor: test `writeOnceStreamKey`, name the janitor in the ba…
filimonov Oct 5, 2026
2c757e5
CAS GC janitor: keep the cursor on a later LIST failure, count requests
filimonov Oct 5, 2026
a39bccb
CAS GC janitor: check `delete_requests` in the drain integration test
filimonov Oct 5, 2026
e997a95
Merge branch 'antalya-26.6' into cas/update-existing-backup-tests
k-morozov Oct 6, 2026
804c619
Fix GROUP BY hostName() over s3Cluster and object_storage_cluster
ianton-ru Oct 6, 2026
ea70a1f
Keep server-constant GROUP BY keys without raising distributed_depth
ianton-ru Oct 6, 2026
b84beb3
Fix CAS backup test coverage
k-morozov Oct 6, 2026
498cec1
test for diffrent endpoint
k-morozov Oct 6, 2026
12460ed
Drop __getScalar GROUP BY keys in the old analyzer
ianton-ru Oct 6, 2026
f050971
add test
k-morozov Oct 7, 2026
b10c823
Merge remote-tracking branch 'altinity/antalya-26.6' into fix/antalya…
filimonov Oct 7, 2026
bbdbb2c
CAS GC janitor: cut delete jobs by the storage's batch limit, count l…
filimonov Oct 7, 2026
7012666
backport
arthurpassos Oct 7, 2026
8c18d72
Merge pull request #2503 from Altinity/backport/antalya-26.6/115686
arthurpassos Oct 8, 2026
f33cc32
Merge branch 'antalya-26.6' into bugfix/antalya-26.6/distributed-glob…
ianton-ru Oct 8, 2026
1535184
Document where a distributed JOIN runs and which table is sent
ianton-ru Oct 8, 2026
7265c4b
Mark 02354_vector_search_rescoring_distance_in_select_list as broken …
CarlosFelipeOR Oct 8, 2026
ec8d362
Add missing __init__.py to two Iceberg integration test dirs
CarlosFelipeOR Oct 8, 2026
29f01ea
Merge pull request #2483 from Altinity/fix/antalya-26.6/cas-gc-janito…
filimonov Oct 8, 2026
c72ea99
Added nullcheck for type before calling unknown type check
subkanthi Oct 8, 2026
0758ad1
Merge pull request #2521 from Altinity/fix_iceberg_unknown_type_test_…
MyroTk Oct 8, 2026
9af7dce
Merge pull request #2520 from Altinity/ci/test-fixes-antalya-26.6.8.2001
MyroTk Oct 9, 2026
f4cdab0
Revert leftover changes in `test_backup_restore_on_cluster/test_cance…
k-morozov Oct 9, 2026
cee3950
Remove unused `parts/` prefix from CAS pool check
k-morozov Oct 9, 2026
c410f4b
Revert accidental `contrib` submodule changes
k-morozov Oct 9, 2026
a97c462
Do not treat missing Iceberg column metrics as NULL
ianton-ru Oct 9, 2026
e8fc642
upgrade all packages when building alpine images
strtgbb Oct 9, 2026
92a9e65
Log how many Iceberg columns in a file have no metrics
ianton-ru Oct 9, 2026
26d3a68
Drop local server-constant GROUP BY keys in the old analyzer
ianton-ru Oct 9, 2026
c2ef6ad
Add workflow to switch active bucket
MyroTk Oct 9, 2026
b367648
Merge pull request #2529 from Altinity/alpine-upgrade-all-26.6
strtgbb Oct 9, 2026
0f732b6
Merge pull request #2315 from Altinity/bugfix/antalya-26.6/distribute…
zvonand Oct 9, 2026
9aad315
Fix cluster reads of Iceberg tables reached through Alias.
ianton-ru Oct 12, 2026
6b711b2
Cover catalog wrappers that re-read Iceberg tables with object_storag…
ianton-ru Oct 12, 2026
7b72040
Round distances in 02354 so bf16 quantization differences don't fail it
CarlosFelipeOR Oct 12, 2026
3e85333
Move the alias Iceberg catalog scan into the integration tests.
ianton-ru Oct 12, 2026
15eceeb
Format ClickHouse names in the Iceberg alias test docstrings.
ianton-ru Oct 12, 2026
2a09ee3
Format `Buffer` and `WithMergeableState` in the wrapper test comment.
ianton-ru Oct 12, 2026
580aa46
safe cast
arthurpassos Oct 12, 2026
8204033
Merge pull request #2527 from Altinity/bugfix/antalya-26.6/iceberg-pa…
mkmkme Oct 13, 2026
abc516e
Keep the catalog storage alive for an `Alias` snapshot.
ianton-ru Oct 13, 2026
bd359eb
Revert "Keep the catalog storage alive for an `Alias` snapshot."
ianton-ru Oct 13, 2026
619d64a
Backport the `Alias` snapshot holder from master.
ianton-ru Oct 13, 2026
fc5874e
Merge branch 'antalya-26.6' into bugfix/antalya-26.6/alias-snapshot-s…
mkmkme Oct 13, 2026
dd25f85
Cover both `Alias` snapshot accessors and cloned snapshot data.
ianton-ru Oct 13, 2026
fc346d8
Give the MergeTree snapshot clone a real `mutations_snapshot`.
ianton-ru Oct 13, 2026
d9c9701
Merge pull request #2557 from Altinity/bugfix/antalya-26.6/alias-snap…
mkmkme Oct 13, 2026
bb444f1
Merge branch 'antalya-26.6' into bugfix/antalya-26.6/alias-iceberg-cl…
mkmkme Oct 13, 2026
a1e2fab
Merge pull request #2549 from Altinity/ci/round-02354-vector-search-test
strtgbb Oct 13, 2026
675e755
Merge branch 'antalya-26.6' into cas/update-existing-backup-tests
k-morozov Oct 13, 2026
a58cb45
Remove CAS from generic native copy test
k-morozov Oct 13, 2026
c55a6e7
Merge branch 'antalya-26.6' into bugfix/antalya-26.6/alias-iceberg-cl…
ianton-ru Oct 14, 2026
fd6d02f
Exclude CAS logs from backup all test
k-morozov Oct 14, 2026
43952da
Keep the unwrapped storage alive in `parallelReplicasEnabledForStorage`.
ianton-ru Oct 14, 2026
8b0499c
Merge pull request #2437 from Altinity/cas/update-existing-backup-tests
filimonov Oct 14, 2026
264203c
Merge pull request #2490 from Altinity/bugfix/antalya-26.6/2139-hostn…
zvonand Oct 14, 2026
9b6bc31
Merge pull request #2550 from Altinity/bugfix/antalya-26.6/alias-iceb…
mkmkme Oct 14, 2026
20d68b0
Bump version to 26.6.8.20002.altinityantalya
MyroTk Oct 14, 2026
b302425
add integ tests
arthurpassos Oct 15, 2026
2ab7fce
Merge pull request #2559 from Altinity/fix/antalya-26.6/safe-cast-uns…
zvonand Oct 16, 2026
47ef4b9
Nightly runs skip in-progress runs
MyroTk Oct 16, 2026
18cb495
Merge antalya-26.6 into antalya-26.6-20261008
filimonov Oct 19, 2026
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
26 changes: 13 additions & 13 deletions .github/workflows/deploy-static.yml
Original file line number Diff line number Diff line change
Expand Up @@ -7,14 +7,11 @@ on:
description: 'The environment to deploy to. "staging" or "production"'
required: true
default: 'staging'
keep_current_bucket:
push_to_active:
description: >-
Deploy onto whichever Blue/Green bucket is currently live, instead of
the normal release toggle. This workflow never touches packages, so
the other bucket is likely several releases stale - toggling to it
would make those stale packages live again. Leave this true unless
you specifically want to stage static changes on the inactive side
first.
If true, deploy static assets onto the currently live Blue/Green
prefix and do not rotate CloudFront. If false, deploy static assets
onto the inactive prefix and rotate CloudFront to it.
required: true
type: boolean
default: true
Expand All @@ -24,7 +21,10 @@ env:

jobs:
deploy-static:
runs-on: [altinity-style-checker-aarch64, altinity-on-demand]
runs-on: ${{
inputs.release_environment == 'staging' && 'arc-runners-clickhouse-signer' ||
inputs.release_environment == 'production' && 'arc-runners-clickhouse-signer-prod'
}}
env:
AWS_ACCESS_KEY_ID: ${{ secrets.AWS_ACCESS_KEY_ID }}
AWS_SECRET_ACCESS_KEY: ${{ secrets.AWS_SECRET_ACCESS_KEY }}
Expand Down Expand Up @@ -55,15 +55,15 @@ jobs:

- name: Run static deploy playbook
run: |
echo "Deploying static site assets (installer.sh, landing page, CloudFront routing) to ${{ inputs.release_environment }}..."
echo "Keep current bucket (skip Blue/Green toggle): ${{ inputs.keep_current_bucket }}"
if ! ansible-playbook -i release/packaging/ansible/inventory/localhost.yml \
echo "Deploying static site assets to ${{ inputs.release_environment }}..."
echo "push_to_active=${{ inputs.push_to_active }} (true=stay on live prefix, false=rotate Blue/Green)"
if ! ansible-playbook -i tests/ci/release/packaging/ansible/inventory/localhost.yml \
-e aws_region="$AWS_REGION" \
-e repo_dns_name="$REPO_DNS_NAME" \
-e repo_name="$REPO_NAME" \
-e repo_subtitle="$REPO_SUBTITLE" \
-e push_to_active=${{ inputs.keep_current_bucket }} \
release/packaging/ansible/deploy-static.yml; then
-e push_to_active=${{ inputs.push_to_active }} \
tests/ci/release/packaging/ansible/deploy-static.yml; then
echo "Ansible playbook failed"
exit 1
fi
28 changes: 22 additions & 6 deletions .github/workflows/scheduled_runs.yml
Original file line number Diff line number Diff line change
Expand Up @@ -68,26 +68,42 @@ jobs:
--jq '.[0].sha')
echo "Tip of ${BRANCH}: ${tip}"

unfinished=0
unfinished_ids=""
for status in in_progress queued waiting requested pending; do
payload=$(gh api -X GET \
-H "Accept: application/vnd.github+json" \
-H "X-GitHub-Api-Version: 2022-11-28" \
-f branch="$BRANCH" \
-f status="$status" \
-F per_page=5 \
"/repos/Altinity/ClickHouse/actions/workflows/${WORKFLOW}/runs")
count=$(jq '.total_count // 0' <<<"$payload")
ids=$(jq -r '[.workflow_runs // [] | .[].id | tostring] | join(" ")' <<<"$payload")
echo "Unfinished ${WORKFLOW} on ${BRANCH} (${status}): ${count}"
unfinished=$((unfinished + count))
if [ -n "$ids" ]; then
unfinished_ids="${unfinished_ids} ${ids}"
fi
done

runs=$(gh api -X GET \
-H "Accept: application/vnd.github+json" \
-H "X-GitHub-Api-Version: 2022-11-28" \
-f branch="$BRANCH" \
-f status=completed \
-F per_page=10 \
"/repos/Altinity/ClickHouse/actions/workflows/${WORKFLOW}/runs")

active=$(jq '
[.workflow_runs[]
| select(.status == "queued" or .status == "in_progress" or .status == "waiting" or .status == "requested" or .status == "pending")]
| length' <<<"$runs")
latest_sha=$(jq -r '.workflow_runs[0].head_sha // empty' <<<"$runs")
latest_id=$(jq -r '.workflow_runs[0].id // empty' <<<"$runs")
latest_status=$(jq -r '.workflow_runs[0].status // empty' <<<"$runs")
latest_conclusion=$(jq -r '.workflow_runs[0].conclusion // empty' <<<"$runs")

dispatch=false
previous_run_id=""
if [ "$active" -gt 0 ]; then
echo "${WORKFLOW} already has an unfinished run on ${BRANCH}"
if [ "$unfinished" -gt 0 ]; then
echo "${WORKFLOW} already has an unfinished run on ${BRANCH}:${unfinished_ids}"
elif [ -z "$latest_sha" ]; then
echo "No previous ${WORKFLOW} run on ${BRANCH}"
dispatch=true
Expand Down
6 changes: 3 additions & 3 deletions cmake/autogenerated_versions.txt
Original file line number Diff line number Diff line change
Expand Up @@ -7,10 +7,10 @@ SET(VERSION_MAJOR 26)
SET(VERSION_MINOR 6)
SET(VERSION_PATCH 8)
SET(VERSION_GITHASH bc7f520bc366fac69d3ff7323fecc35197a9b2c6)
SET(VERSION_DESCRIBE v26.6.8.20001.altinityantalya)
SET(VERSION_STRING 26.6.8.20001.altinityantalya)
SET(VERSION_DESCRIBE v26.6.8.20002.altinityantalya)
SET(VERSION_STRING 26.6.8.20002.altinityantalya)
# end of autochange

SET(VERSION_TWEAK 20001)
SET(VERSION_TWEAK 20002)
SET(VERSION_FLAVOUR altinityantalya)

4 changes: 3 additions & 1 deletion docker/keeper/Dockerfile
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ RUN arch=${TARGETARCH:-amd64} \
esac


FROM alpine:3.21
FROM alpine

ENV LANG=en_US.UTF-8 \
LANGUAGE=en_US:en \
Expand Down Expand Up @@ -89,6 +89,8 @@ RUN clickhouse-keeper --version \
&& chown root:clickhouse "${DEFAULT_LOG_DIR}" \
&& chmod ugo+Xrw -R "${DEFAULT_DATA_DIR}" "${DEFAULT_LOG_DIR}" "${DEFAULT_CONFIG_DIR}"

RUN apk update && apk upgrade --no-cache

# /var/lib/clickhouse is necessary due to the current default configuration for Keeper
VOLUME "${DEFAULT_DATA_DIR}" /var/lib/clickhouse
EXPOSE 2181 10181 44444 9181
Expand Down
3 changes: 1 addition & 2 deletions docker/server/Dockerfile.alpine
Original file line number Diff line number Diff line change
Expand Up @@ -107,8 +107,7 @@ RUN mkdir -p \
&& chown root:clickhouse "${DEFAULT_LOG_DIR}" \
&& chmod ugo+Xrw -R "${DEFAULT_DATA_DIR}" "${DEFAULT_LOG_DIR}" "${DEFAULT_CLIENT_CONFIG_DIR}" "${DEFAULT_SERVER_CONFIG_DIR}"

RUN apk update
RUN apk add --upgrade libssl3 libcrypto3
RUN apk update && apk upgrade --no-cache

VOLUME "${DEFAULT_DATA_DIR}"
EXPOSE 9000 8123 9009
Expand Down
45 changes: 31 additions & 14 deletions docs/en/antalya/cas/architecture/garbage-collection.md
Original file line number Diff line number Diff line change
Expand Up @@ -57,7 +57,7 @@ follower or a deferred round execution returns before that commit.
| 13 | `round_commit` | fold | Retention-prune old generations, then publish the single `gc/state` `CAS` that adopts the whole round |
| 14 | `handoff_reclaim` | post-`CAS` | Reclaim a generation a ref moved off during this round, which the ordinary retention prune already skipped and will not revisit |
| 15 | `manifest_deletes` | post-`CAS` | Delete manifest bodies whose owner-removal minus-one edge the `CAS` in phase 13 just adopted |
| 16 | `namespace_cleanup` | leader; suppressed on `DEFER` | One bounded page of the perpetual namespace janitor, reclaiming dead-life debris |
| 16 | `namespace_cleanup` | leader; suppressed on `DEFER` | Pages of the perpetual namespace janitor under a 20 s soft budget, reclaiming dead-life debris |
| 17 | `ref_object_cleanup` | post-`CAS` | Prune ref logs and snapshots once both fold coverage and a live snapshot make them safe to delete |
| 18 | `orphan_sweep` | post-`CAS` | Exact-token deletion for the [orphan-manifest sweep](/antalya/cas/architecture/manifests-and-refs#orphan-sweep), after phase 13 adopted each candidate's blob-source retirements and the cursor |

Expand Down Expand Up @@ -519,23 +519,36 @@ then picked up by the orphan-manifest sweep (phase 18).

## Phase 16 — namespace cleanup {#phase-16-namespace-cleanup}

One bounded page of the perpetual namespace janitor: deletes the physical objects of namespace lives
no longer in the catalog (dead-life debris).
Pages of the perpetual namespace janitor: deletes the physical objects of namespace lives
no longer in the catalog (dead-life debris). The phase takes the next page while the previous one
deleted something and published its cursor, until a 20 s soft budget: no page starts after it, the
page in progress finishes. After the last page of `cas/ns/` the next one starts from its beginning, so
a pass that began mid-stream also reaches the debris before its cursor; the first page that deletes
nothing ends the pass. A pool without debris costs one `LIST` per round.

- **Runs on:** fold path here; also on the deferred path right after phase 4 with
`suppress_destructive` forced on
- **Reads:** the durable `janitor_cursor`; one `LIST` page (≤ 1000 keys) of `cas/ns/`; a fresh
ref-catalog snapshot; `gc/state` per fence re-check
- **Writes / deletes:** exact-token `DELETE` per dead-life `_log` / `_snap` / `_ckpt` / `_files`
object; one `CAS` on the maintenance state when the page is decided
- **Safety:** each delete is under a GC fence re-check (`lease.owner` / `lease.seq`) before it and
once at the end; the incarnation segment in every key makes an old life's objects structurally
- **Reads:** per page: the durable `janitor_cursor`; one `LIST` page (≤ 1000 keys) of `cas/ns/`; a
fresh ref-catalog snapshot; `gc/state` for the fence re-check
- **Writes / deletes:** per page: batch `DELETE`s of the dead-life `_log` / `_snap` objects, which
are write-once and need no token; one request per `cas_gc_bulk_delete_chunk_keys` keys, capped by
the storage's batch-delete limit (`objects_chunk_size_to_delete` on S3; one key on a storage
without a batch delete), run as jobs on the GC I/O pool (`cas_gc_io_concurrency`); exact-token `DELETE` per
dead-life `_ckpt` / `_files` object; one `CAS` on the maintenance state when the page is decided
- **Safety:** each request is under a GC fence re-check (`lease.owner` / `lease.seq`), read once per
page and checked again before the cursor is published; the incarnation segment in every key makes an old life's objects structurally
unreachable from a reborn same-name namespace, so a missed key can only leak storage, never expose
it
- **Fails the round if:** nothing — the whole page is wrapped in a catch-all ("namespace janitor
skipped this round")
- **Fails the round if:** nothing — the whole phase is wrapped in a catch-all ("namespace janitor
stopped this round"). A failed batch `DELETE` leaks its keys and the cursor still advances. A failed
`LIST` resets the cursor to the stream start only on the first page of the phase; on a later page
the cursor the previous page published stays
- **Observability:** phase row `namespace_cleanup`; metrics `janitor_pages`, `janitor_keys`,
`janitor_deleted`, `leaked`
`janitor_deleted` (keys of successful batch requests, absent ones included, plus exact removals),
`leaked` (failed keys of published pages; an unpublished page is listed again), `delete_requests`
(delete calls: one per exact-token delete and per batch, including a batch the storage refused
before its keys went one by one), `budget_exhausted`. Batch deletes run on the GC I/O pool, so the
row's `ProfileEvents` do not include their requests

The cursor advances only when the whole page was decided under a held fence and an unambiguous
catalog; under suppression it lists and classifies but deletes nothing and does not advance.
Expand Down Expand Up @@ -942,13 +955,17 @@ backend without batch delete: the refused bulk call plus one `DELETE` per key).

### Phase 16 — namespace cleanup {#cost-phase-16}

Per page; the phase takes one page in a round without debris and more under its 20 s budget while
pages delete.

| Key | Operation | Requests |
|---|---|---:|
| `<pool_prefix>/gc/maintenance_state` | `GET` | 1 (durable `janitor_cursor`) |
| `<pool_prefix>/cas/ns/` | `LIST` | one page |
| `<pool_prefix>/cas/ref_catalog` | `GET` | 1 |
| `<pool_prefix>/gc/state` | `GET` | one per fence check |
| dead-life object | `DELETE` | one per object (plus one `HEAD` per object whose `LIST` entry carried no token) |
| `<pool_prefix>/gc/state` | `GET` | 1 (fence check) |
| dead-life `_log` / `_snap` objects | batch `DELETE` | one per `cas_gc_bulk_delete_chunk_keys` keys, capped by the storage's batch-delete limit; one per key on a storage without a batch delete |
| dead-life `_ckpt` / `_files` object | `DELETE` | one per object (plus one `HEAD` per object whose `LIST` entry carried no token) |
| `<pool_prefix>/gc/maintenance_state` | `CAS` | 1 when the page is decided |

### Phase 17 — ref object cleanup {#cost-phase-17}
Expand Down
2 changes: 1 addition & 1 deletion docs/en/antalya/cas/architecture/namespaces.md
Original file line number Diff line number Diff line change
Expand Up @@ -151,7 +151,7 @@ proven its ref history is fully drained.
| Catalog row (`cas/ref_catalog` entry) | `GC` phase 2, `pre_fold_ref_drain` | The round after the fold that sealed cleanup evidence for this life |
| Part manifest bodies | Ordinary owner-removal ([phase 15](/antalya/cas/architecture/garbage-collection#the-round)) for anything that had a committed or precommit binding, the [orphan-manifest sweep](/antalya/cas/architecture/manifests-and-refs#orphan-sweep) for anything that never got that far | As each owning ref is dropped by the removal transaction itself, independent of the catalog row |
| Blob bodies | The ordinary condemn/graduate/delete pipeline | Whenever the manifests that named them stop being live, same as any other blob |
| Ref stream/state objects (`_log`, `_snap`, `_ckpt`, `_files`) under the dead `life_id` | The perpetual namespace janitor ([phase 16](/antalya/cas/architecture/garbage-collection#the-round)) | Best-effort, one bounded `LIST` page at a time, whenever it next lists a key whose `life_id` a fresh catalog cut no longer names — independent of, and not gated on, catalog-row deletion |
| Ref stream/state objects (`_log`, `_snap`, `_ckpt`, `_files`) under the dead `life_id` | The perpetual namespace janitor ([phase 16](/antalya/cas/architecture/garbage-collection#the-round)) | Best-effort, in bounded `LIST` pages under a per-round time budget, whenever it next lists a key whose `life_id` a fresh catalog cut no longer names — independent of, and not gated on, catalog-row deletion |

The janitor is leak-only: it never fails a round, never blocks progress on an unreadable key, and a
crash mid-page simply leaves debris for its next page.
Expand Down
4 changes: 2 additions & 2 deletions docs/en/antalya/cas/configuration.md
Original file line number Diff line number Diff line change
Expand Up @@ -106,7 +106,7 @@ entirely before release. Treat this table as a snapshot of the current build, no
| `cas_part_folder_cache_max_entry_bytes` | 16 MiB | Oversized part-folder views bypass retention above this size |
| `cas_manifest_decode_cache_bytes` | 128 MiB | Manifest decode cache byte budget (`0` disables) |
| `cas_gc_meta_pool_size` | `16` | Bounded pool size for GC per-hash freshness-meta writes |
| `cas_gc_io_concurrency` | `16` | Bounded pool size for GC object-storage requests that run in parallel: the fold's read-ahead (checkpoints, ref logs, manifests, zero-candidate HEADs), the orphan-manifest sweep planning reads, the `SYSTEM CAS GC REBUILD` read-ahead, and the `pending_deletes` blob `HEAD` + conditional `DELETE` fan-out. Not covered: meta writes (`cas_gc_meta_pool_size`) and all other GC requests, which run on the round thread. `1` runs the covered requests sequentially. `cas_gc_read_concurrency` is rejected without an alias; use `cas_gc_io_concurrency` instead |
| `cas_gc_io_concurrency` | `16` | Bounded pool size for GC object-storage requests that run in parallel: the fold's read-ahead (checkpoints, ref logs, manifests, zero-candidate HEADs), the orphan-manifest sweep planning reads, the `SYSTEM CAS GC REBUILD` read-ahead, the `pending_deletes` blob `HEAD` + conditional `DELETE` fan-out, and the namespace janitor's batch deletes of dead ref logs and snapshots. Not covered: meta writes (`cas_gc_meta_pool_size`) and all other GC requests, which run on the round thread. `1` runs the covered requests sequentially. `cas_gc_read_concurrency` is rejected without an alias; use `cas_gc_io_concurrency` instead |
| `cas_attempt_timeout_ms` | `5000` | Budget for one HTTP attempt of a writable Native mount's control-plane requests (read, head, list, remove, conditional write), at least 1. Together with the connect cap it forms the attempt envelope (`cas_attempt_timeout_ms + 2 × cap`; the cap is `cas_attempt_timeout_ms` itself when the disk's `connect_timeout_ms` is `0`, else `min(connect_timeout_ms, cas_attempt_timeout_ms)`) that the lease arithmetic reserves: one TCP connect and one TLS handshake under the cap each, send/receive bounded per socket operation by `cas_attempt_timeout_ms`. With background renewal the cadence check requires `cas_mount_renew_period_ms + 2 × envelope + cas_lease_safety_margin_ms < cas_mount_lease_ttl_ms`, which puts an effective ceiling on the frozen connect cap: under the defaults (TTL 30000, period 10000, margin 2000) the envelope must stay under 9000, so a disk `connect_timeout_ms` of 2000 ms or more refuses to open writable — lower the connect timeout or raise the TTL if you hit this. Blob body publication does not use this budget: its object-creating request is sent once under the disk's `request_timeout_ms`, with the connect timeout under the same cap |
| `cas_lease_safety_margin_ms` | `2000` | Startup-only margin validated against the mount lease TTL: the attempt envelope + `cas_lease_safety_margin_ms` must be strictly less than the mount lease TTL, and `cas_mount_renew_period_ms` + 2 × envelope + `cas_lease_safety_margin_ms` too, or the disk refuses to open writable |
| `cas_unsafe_remount_no_delay` | `0` | Reclaim a mount slot that carries this server's own uuid at once after a hard restart, without observing the slot's token for the lease TTL. Unsafe whenever two processes can hold the same `server_uuid` (a copied uuid file, a stalled predecessor). After such a reclaim the predecessor can still start conditional writes until its own cutoff (`confirmed deadline − cas_lease_safety_margin_ms − 2 × envelope`) or until its next renewal meets the token guard, and a request it already sent may still materialize later. That is not a data hazard: ref-log keys carry `(writer_epoch, sequence)` and creates are conditional, so two writers can never commit different bodies to one key, and recovery's epoch seal settles any straggler (recovery fails closed after 64 successive seal-create attempts displaced by newly materializing old-epoch transactions). The exposure is availability, not data. Intended for test stands and deployments that guarantee one process per uuid |
Expand Down Expand Up @@ -177,7 +177,7 @@ for the remaining caps, `0` means unbounded.
|---|---|---|---|
| `cas_manifest_sweep_list_budget_keys` | `1000` | `UInt64` | Orphan-manifest sweep `LIST` budget per round |
| `cas_manifest_sweep_delete_budget_keys` | `100` | `UInt64` | Orphan-manifest sweep `DELETE` budget per round |
| `cas_gc_bulk_delete_chunk_keys` | `1000` | `1`–`1000` | Keys per batch delete request in GC's write-once families (owner-removed manifest bodies, covered ref logs and snapshots), capped by the storage's batch-delete limit |
| `cas_gc_bulk_delete_chunk_keys` | `1000` | `1`–`1000` | Most keys per batch delete request in GC's write-once families (owner-removed manifest bodies, covered ref logs and snapshots, the namespace janitor's dead ref logs and snapshots), capped by the storage's batch-delete limit |
| `cas_gc_round_graduation_budget` | `5000` | `0` = unbounded | Blob-graduation (`condemned` → `delete_pending`) cohort cap per round |
| `cas_gc_round_redelete_budget` | `5000` | `0` = unbounded | Exact-token re-delete cohort cap for prior `delete_pending` rows per round |
| `cas_gc_round_sweep_namespace_budget` | `20` | `0` = unbounded | Distinct namespaces per orphan-manifest sweep page whose protection view may be built |
Expand Down
Loading
Loading