misc.python.materialize.mzcompose

The implementation of the mzcompose system for Docker compositions.

For an overview of what mzcompose is and why it exists, see the user-facing documentation.

   1# Copyright Materialize, Inc. and contributors. All rights reserved.
   2#
   3# Use of this software is governed by the Business Source License
   4# included in the LICENSE file at the root of this repository.
   5#
   6# As of the Change Date specified in that file, in accordance with
   7# the Business Source License, use of this software will be governed
   8# by the Apache License, Version 2.0.
   9
  10"""The implementation of the mzcompose system for Docker compositions.
  11
  12For an overview of what mzcompose is and why it exists, see the [user-facing
  13documentation][user-docs].
  14
  15[user-docs]: https://github.com/MaterializeInc/materialize/blob/main/doc/developer/mzbuild.md
  16"""
  17
  18import os
  19import random
  20import subprocess
  21import sys
  22from collections.abc import Iterable
  23from dataclasses import dataclass
  24from typing import Any, Literal, TypeVar
  25
  26import psycopg
  27
  28from materialize import spawn, ui
  29from materialize.mz_version import MzVersion
  30from materialize.rustc_flags import Sanitizer
  31from materialize.ui import UIError
  32
  33T = TypeVar("T")
  34say = ui.speaker("C> ")
  35
  36
  37DEFAULT_CONFLUENT_PLATFORM_VERSION = "8.2.0"
  38
  39DEFAULT_MZ_VOLUMES = [
  40    "mzdata:/mzdata",
  41    "mydata:/var/lib/mysql-files",
  42    "tmp:/share/tmp",
  43    "scratch:/scratch",
  44]
  45
  46
  47# Parameters which disable systems that periodically/unpredictably impact performance
  48# We try to keep this empty, so that we benchmark Materialize as we ship it. If
  49# a new feature causes benchmarks to become flaky, consider that this can also
  50# impact customers' experience and try to find a solution other than disabling
  51# the feature here!
  52ADDITIONAL_BENCHMARKING_SYSTEM_PARAMETERS = {
  53    # Benchmarks measure the intended production configuration. For hedged
  54    # blob gets that is the planned enablement state (on, at production
  55    # tuning), not the CI-wide coverage tuning below, whose short delay
  56    # would add duplicate fetches to any measured get slower than it.
  57    "persist_blob_hedged_get_enabled": "true",
  58    "persist_blob_hedged_get_delay": "2s",
  59    "persist_blob_hedged_get_budget_ratio": "0.01",
  60    # Curated metric sinks are causing a regression in performance thresholds.
  61    # Currently, the flag defaults off in production, so benchmarking without it
  62    # measures the configuration we ship. Correctness coverage is unaffected:
  63    # the rest of CI # still gets "true" from get_minimal_system_parameters().
  64    # TODO: remove once the regression is fixed
  65    "enable_metric_sink": "false",
  66}
  67
  68
  69def sanitizer_enabled() -> bool:
  70    """Whether the binaries under test were built with a sanitizer.
  71
  72    Sanitizer builds run several times slower and use several times as much
  73    memory as ordinary ones, so tests that assert on timing, or that need
  74    jemalloc (which sanitizer builds drop, as it clashes with the sanitizer
  75    runtimes), have to account for them.
  76    """
  77    return Sanitizer[os.getenv("CI_SANITIZER", "none")] != Sanitizer.none
  78
  79
  80def get_minimal_system_parameters(
  81    version: MzVersion,
  82) -> dict[str, str]:
  83    """Settings we need in order to have tests run at all, but otherwise stay
  84    with the defaults: not changing performance or increasing coverage."""
  85
  86    config = {
  87        # -----
  88        # Unsafe functions
  89        "unsafe_enable_unsafe_functions": "true",
  90        # -----
  91        # Others (ordered by name)
  92        "allow_real_time_recency": "true",
  93        "constraint_based_timestamp_selection": "verify",  # removed from main, keeping it here for old versions
  94        "enable_compute_peek_response_stash": "true",
  95        "enable_0dt_deployment_panic_after_timeout": "true",
  96        "enable_0dt_deployment_sources": (
  97            "true" if version >= MzVersion.parse_mz("v0.132.0-dev") else "false"
  98        ),
  99        "enable_alter_swap": "true",
 100        "enable_arrangement_dictionary_compression_alpha": "false",
 101        "enable_case_literal_transform": "true",
 102        "enable_cast_elimination": "true",
 103        "enable_coalesce_case_transform": "true",
 104        "enable_columnation_lgalloc": "false",
 105        "enable_compute_correction_v2": "true",
 106        "enable_compute_logical_backpressure": "true",
 107        "enable_connection_validation_syntax": "true",
 108        "enable_create_table_from_source": "true",
 109        "enable_eager_delta_joins": "true",
 110        "enable_envelope_debezium_in_subscribe": "true",
 111        "enable_exclude_constraints_option": "true",
 112        "enable_expressions_in_limit_syntax": "true",
 113        "enable_fixed_correlated_cte_lowering": "true",
 114        "enable_introspection_subscribes": "true",
 115        "enable_lgalloc": "false",
 116        "enable_load_generator_counter": "true",
 117        "enable_logical_compaction_window": "true",
 118        "enable_metric_sink": "true",
 119        "enable_multi_worker_storage_persist_sink": "true",
 120        "enable_rbac_checks": "true",
 121        "enable_reduce_mfp_fusion": "true",
 122        "enable_refresh_every_mvs": "true",
 123        "enable_replacement_materialized_views": "true",
 124        "enable_cluster_schedule_refresh": "true",
 125        # Pinned explicitly so runs against older versions (which predate the
 126        # flag or defaulted it off) behave like current ones, where it defaults
 127        # on.
 128        "enable_background_alter_cluster": (
 129            "true" if version >= MzVersion.parse_mz("v26.29.0-dev") else "false"
 130        ),
 131        "enable_s3_tables_region_check": "false",
 132        "enable_statement_lifecycle_logging": "true",
 133        "enable_storage_introspection_logs": "true",
 134        "enable_compute_error_distinct": "true",
 135        "enable_compute_temporal_bucketing": "true",
 136        "enable_union_cancellation_after_relation_cse": "true",
 137        "enable_variadic_left_join_lowering": "true",
 138        "enable_worker_core_affinity": "true",
 139        "grpc_client_http2_keep_alive_timeout": "5s",
 140        "ore_overflowing_behavior": "panic",
 141        "unsafe_enable_table_keys": "true",
 142        # Keep the 0dt stability soak out of the critical path for tests. The
 143        # production default is much higher. Dedicated workflows override this.
 144        "with_0dt_caught_up_check_stability_period": "0s",
 145        "with_0dt_deployment_max_wait": "1800s",
 146        # End of list (ordered by name)
 147    }
 148
 149    if version >= MzVersion.parse_mz("v26.40.0-dev"):
 150        # Exercise the row-limit check without constraining normal test queries.
 151        config["compute_peek_row_iteration_limit"] = "1000000000"
 152        config["enable_compute_peek_row_iteration_limit"] = "true"
 153
 154        # Exercise the peek offload path in tests while it defaults off in
 155        # production. The budgets stay at their code defaults so tests make the
 156        # same placement decisions production makes.
 157        config["enable_compute_index_peek_offload"] = "true"
 158
 159    if version < MzVersion.parse_mz("v0.163.0-dev"):
 160        config["enable_compute_active_dataflow_cancelation"] = "true"
 161
 162    if version < MzVersion.parse_mz("v26.24.0-dev"):
 163        config["enable_columnar_lgalloc"] = "false"
 164    if version < MzVersion.parse_mz("v26.25.0-dev"):
 165        config["enable_multi_replica_sources"] = "true"
 166
 167    if version >= MzVersion.parse_mz("v26.40.0-dev"):
 168        config["hydration_history_collection_interval"] = "60s"
 169
 170    if sanitizer_enabled():
 171        config["with_0dt_deployment_max_wait"] = "18000s"
 172
 173    # The cluster controller's break-glass gate. Removed in v26.38, where the
 174    # controller runs unconditionally. Older binaries still read it, and
 175    # defaulted it off before v26.29, so pin it on for them to keep mixed-version
 176    # runs exercising the same path as current versions.
 177    if version < MzVersion.parse_mz("v26.38.0-dev"):
 178        config["enable_cluster_controller"] = (
 179            "true" if version >= MzVersion.parse_mz("v26.29.0-dev") else "false"
 180        )
 181
 182    # The `WITH (WAIT ...)` graceful-reconfiguration surface. Always accepted
 183    # from v26.41 on. Older binaries still gate it behind this feature flag, so
 184    # pin it on for them: the tests that use the surface no longer enable it
 185    # themselves, and in a mixed-version run some of their phases execute
 186    # against the old binary.
 187    if version < MzVersion.parse_mz("v26.41.0-dev"):
 188        config["enable_zero_downtime_cluster_reconfiguration"] = "true"
 189
 190    return config
 191
 192
 193@dataclass
 194class VariableSystemParameter:
 195    key: str
 196    default: str
 197    values: list[str]
 198
 199
 200# TODO: The linter should check this too
 201def get_variable_system_parameters(
 202    version: MzVersion,
 203    force_source_table_syntax: bool,
 204    metadata_store: str,
 205) -> list[VariableSystemParameter]:
 206    """Note: Only the default is tested unless we explicitly select "System Parameters: Random" in trigger-ci.
 207    These defaults are applied _after_ applying the settings from `get_minimal_system_parameters`.
 208    """
 209
 210    # `persist_pg_consensus_read_committed` must stay off on CockroachDB, where
 211    # the lockless CRDB_* consensus queries are only linearizable under
 212    # SERIALIZABLE and persist asserts on the connection's isolation level. On
 213    # Postgres-backed consensus the query family is linearizable under READ
 214    # COMMITTED, so default it on and let it vary.
 215    read_committed_safe = metadata_store in ("postgres-metadata", "alloydb")
 216    persist_pg_consensus_read_committed = VariableSystemParameter(
 217        "persist_pg_consensus_read_committed",
 218        "true" if read_committed_safe else "false",
 219        ["true", "false"] if read_committed_safe else ["false"],
 220    )
 221
 222    params = [
 223        # -----
 224        # To reduce CRDB load as we are struggling with it in CI (values based on load test environment):
 225        VariableSystemParameter(
 226            "persist_next_listen_batch_retryer_clamp",
 227            "16s",
 228            ["100ms", "1s", "10s", "100s"],
 229        ),
 230        VariableSystemParameter(
 231            "persist_next_listen_batch_retryer_initial_backoff",
 232            "100ms",
 233            ["10ms", "100ms", "1s", "10s"],
 234        ),
 235        VariableSystemParameter(
 236            "persist_next_listen_batch_retryer_fixed_sleep",
 237            "1200ms",
 238            ["100ms", "1s", "10s"],
 239        ),
 240        # -----
 241        # Persist internals changes, advance coverage
 242        VariableSystemParameter(
 243            "persist_source_fetch_concurrency", "1", ["1", "2", "8", "16"]
 244        ),
 245        VariableSystemParameter(
 246            "persist_blob_hedged_get_enabled", "true", ["true", "false"]
 247        ),
 248        # 10ms (vs the 2s production default) makes hedges actually fire in
 249        # every CI run; 0s makes every blob get hedge under randomized seeds.
 250        VariableSystemParameter(
 251            "persist_blob_hedged_get_delay", "10ms", ["0s", "10ms", "2s"]
 252        ),
 253        # The production ratio: with the 10ms delay above, a full refill
 254        # would hedge nearly every get and double CI blob traffic. The 1.0
 255        # variant lets randomized runs pair a full budget with delay=0s.
 256        VariableSystemParameter(
 257            "persist_blob_hedged_get_budget_ratio", "0.01", ["1.0", "0.01"]
 258        ),
 259        # -----
 260        # Others (ordered by name),
 261        VariableSystemParameter(
 262            "aws_prefetch_sts_connect_timeout",
 263            "3100ms",
 264            ["3100ms", "30s", "60s"],
 265        ),
 266        VariableSystemParameter(
 267            "compute_correction_v2_chain_proportionality",
 268            "3",
 269            ["2", "3"],
 270        ),
 271        VariableSystemParameter(
 272            "compute_correction_v2_chunk_size",
 273            "8192",
 274            ["8192", "65536", "1048576"],
 275        ),
 276        VariableSystemParameter(
 277            "compute_dataflow_max_inflight_bytes",
 278            "134217728",
 279            ["1048576", "4194304", "16777216", "67108864"],
 280        ),  # 128 MiB
 281        VariableSystemParameter("compute_hydration_concurrency", "2", ["1", "2", "4"]),
 282        VariableSystemParameter(
 283            "compute_replica_expiration_offset", "3d", ["3d", "10d"]
 284        ),
 285        VariableSystemParameter(
 286            "compute_apply_column_demands", "true", ["true", "false"]
 287        ),
 288        # On by default so CI exercises the columnar merge batcher, which is
 289        # off in production while it earns trust.
 290        VariableSystemParameter(
 291            "enable_columnar_merge_batcher", "true", ["true", "false"]
 292        ),
 293        # On by default so CI exercises the columnar accumulable diff layout, which
 294        # is off in production while it earns trust.
 295        VariableSystemParameter(
 296            "enable_columnar_accumulable_diff", "true", ["true", "false"]
 297        ),
 298        VariableSystemParameter(
 299            "compute_peek_response_stash_threshold_bytes",
 300            # 1 MiB, an in-between value
 301            "1048576",
 302            # force-enabled, the in-between, and the production value
 303            ["0", "1048576", "314572800", "67108864"],
 304        ),
 305        VariableSystemParameter(
 306            "compute_subscribe_snapshot_optimization",
 307            "true",
 308            ["true", "false"],
 309        ),
 310        VariableSystemParameter(
 311            "enable_case_literal_transform",
 312            "false",
 313            ["true", "false"],
 314        ),
 315        VariableSystemParameter(
 316            "enable_coalesce_case_transform",
 317            "true",
 318            ["true", "false"],
 319        ),
 320        VariableSystemParameter(
 321            "enable_adapter_frontend_occ_read_then_write",
 322            "true" if version >= MzVersion.parse_mz("v26.36.0-dev") else "false",
 323            ["true", "false"],
 324        ),
 325        VariableSystemParameter(
 326            "enable_cast_elimination",
 327            "true",
 328            ["true", "false"],
 329        ),
 330        VariableSystemParameter(
 331            "enable_fixed_correlated_cte_lowering",
 332            "true",
 333            ["true", "false"],
 334        ),
 335        VariableSystemParameter(
 336            "enable_compute_sync_mv_sink",
 337            "true",
 338            ["true", "false"],
 339        ),
 340        VariableSystemParameter(
 341            "enable_password_auth",
 342            "true",
 343            ["true", "false"],
 344        ),
 345        VariableSystemParameter(
 346            "enable_frontend_peek_sequencing",
 347            "true" if version >= MzVersion.parse_mz("v26.9.0-dev") else "false",
 348            ["true", "false"],
 349        ),
 350        VariableSystemParameter(
 351            "enable_frontend_subscribes",
 352            "true" if version >= MzVersion.parse_mz("v26.18.0-dev") else "false",
 353            ["true", "false"],
 354        ),
 355        VariableSystemParameter(
 356            "enable_simplify_from_less_existence",
 357            "true",
 358            ["true", "false"],
 359        ),
 360        VariableSystemParameter(
 361            "enable_union_cancellation_after_relation_cse",
 362            "true",
 363            ["true", "false"],
 364        ),
 365        VariableSystemParameter(
 366            "enable_upsert_paged_spill",
 367            "true",
 368            ["true", "false"],
 369        ),
 370        # On by default so CI exercises the chunked stash flavor, which is
 371        # off in production while it earns trust. Only meaningful when
 372        # enable_upsert_v2 is true.
 373        VariableSystemParameter(
 374            "enable_upsert_chunked_stash",
 375            "true",
 376            ["true", "false"],
 377        ),
 378        VariableSystemParameter(
 379            "enable_upsert_v2",
 380            "false",
 381            ["true", "false"],
 382        ),
 383        VariableSystemParameter(
 384            "default_timestamp_interval",
 385            "1s",
 386            ["100ms", "1s"],
 387        ),
 388        VariableSystemParameter(
 389            "force_source_table_syntax",
 390            "true" if force_source_table_syntax else "false",
 391            ["true", "false"] if force_source_table_syntax else ["false"],
 392        ),
 393        VariableSystemParameter(
 394            "mysql_source_snapshot_parallelism", "true", ["true", "false"]
 395        ),
 396        # Low default so small tables exercise partitioning.
 397        VariableSystemParameter(
 398            "mysql_source_snapshot_partition_min_rows", "2", ["2", "50000"]
 399        ),
 400        VariableSystemParameter(
 401            "persist_batch_delete_enabled", "true", ["true", "false"]
 402        ),
 403        VariableSystemParameter(
 404            "persist_batch_structured_key_lower_len",
 405            "256",
 406            ["0", "1", "512", "1000"],
 407        ),
 408        VariableSystemParameter(
 409            "persist_batch_max_run_len", "4", ["2", "3", "4", "16"]
 410        ),
 411        VariableSystemParameter(
 412            "persist_catalog_force_compaction_fuel",
 413            "1024",
 414            ["256", "1024", "4096"],
 415        ),
 416        VariableSystemParameter(
 417            "persist_catalog_force_compaction_wait",
 418            "1s",
 419            ["100ms", "1s", "10s"],
 420        ),
 421        VariableSystemParameter(
 422            "persist_stats_audit_percent",
 423            "100",
 424            [
 425                "0",
 426                "1",
 427                "2",
 428                "10",
 429                "100",
 430            ],
 431        ),
 432        VariableSystemParameter("persist_stats_audit_panic", "true", ["true", "false"]),
 433        VariableSystemParameter(
 434            "persist_encoding_enable_dictionary", "true", ["true", "false"]
 435        ),
 436        VariableSystemParameter(
 437            "persist_fast_path_limit",
 438            "1000",
 439            ["100", "1000", "10000"],
 440        ),
 441        VariableSystemParameter("persist_fast_path_order", "true", ["true", "false"]),
 442        VariableSystemParameter(
 443            "persist_gc_use_active_gc",
 444            ("true" if version > MzVersion.parse_mz("v0.143.0-dev") else "false"),
 445            (
 446                ["true", "false"]
 447                if version > MzVersion.parse_mz("v0.127.0-dev")
 448                else ["false"]
 449            ),
 450        ),
 451        VariableSystemParameter(
 452            "persist_gc_min_versions",
 453            "16",
 454            ["16", "256", "1024"],
 455        ),
 456        VariableSystemParameter(
 457            "persist_gc_max_versions",
 458            "128000",
 459            ["256", "128000"],
 460        ),
 461        VariableSystemParameter(
 462            "persist_inline_writes_single_max_bytes",
 463            "4096",
 464            ["256", "1024", "4096", "16384"],
 465        ),
 466        VariableSystemParameter(
 467            "persist_inline_writes_total_max_bytes",
 468            "1048576",
 469            ["65536", "262144", "1048576", "4194304"],
 470        ),
 471        VariableSystemParameter(
 472            "persist_pubsub_client_enabled", "true", ["true", "false"]
 473        ),
 474        VariableSystemParameter(
 475            "persist_pubsub_push_diff_enabled", "true", ["true", "false"]
 476        ),
 477        VariableSystemParameter(
 478            "persist_rollup_use_active_rollup",
 479            ("true" if version > MzVersion.parse_mz("v0.143.0-dev") else "false"),
 480            (
 481                ["true", "false"]
 482                if version > MzVersion.parse_mz("v0.127.0-dev")
 483                else ["false"]
 484            ),
 485        ),
 486        # 16 MiB - large enough to avoid a big perf hit, small enough to get more coverage...
 487        VariableSystemParameter(
 488            "persist_blob_target_size",
 489            "16777216",
 490            ["4096", "1048576", "16777216", "134217728"],
 491        ),
 492        # 5 times the default part size - 4 is the bare minimum.
 493        VariableSystemParameter(
 494            "persist_compaction_memory_bound_bytes",
 495            "83886080",
 496            ["67108864", "134217728", "536870912", "1073741824"],
 497        ),
 498        VariableSystemParameter(
 499            "persist_enable_incremental_compaction",
 500            ("true" if version >= MzVersion.parse_mz("v0.161.0-dev") else "false"),
 501            (
 502                ["true", "false"]
 503                if version >= MzVersion.parse_mz("v0.161.0-dev")
 504                else ["false"]
 505            ),
 506        ),
 507        VariableSystemParameter(
 508            "persist_use_critical_since_catalog", "true", ["true", "false"]
 509        ),
 510        VariableSystemParameter(
 511            "persist_use_critical_since_snapshot",
 512            "false",  # always false, because we always have zero-downtime enabled
 513            ["false"],
 514        ),
 515        VariableSystemParameter(
 516            "persist_use_critical_since_source",
 517            "false",  # always false, because we always have zero-downtime enabled
 518            ["false"],
 519        ),
 520        # 0 disables; otherwise coalesce hydration frontier downgrades until
 521        # this many encoded bytes have been emitted (1 MiB, 16 MiB, 128 MiB).
 522        VariableSystemParameter(
 523            "persist_source_hydration_frontier_coalesce_bytes",
 524            "0",
 525            ["0", "1048576", "16777216", "134217728"],
 526        ),
 527        VariableSystemParameter(
 528            "persist_part_decode_format", "arrow", ["arrow", "row_with_validate"]
 529        ),
 530        VariableSystemParameter(
 531            "persist_blob_cache_scale_with_threads", "true", ["true", "false"]
 532        ),
 533        persist_pg_consensus_read_committed,
 534        VariableSystemParameter(
 535            "persist_state_update_lease_timeout", "1s", ["0s", "1s", "10s"]
 536        ),
 537        VariableSystemParameter(
 538            "arrangement_size_history_collection_interval", "1h", ["1s", "10s", "1h"]
 539        ),
 540        VariableSystemParameter(
 541            "arrangement_size_history_retention_period", "7d", ["1min", "1h", "7d"]
 542        ),
 543        *(
 544            [
 545                VariableSystemParameter(
 546                    "hydration_history_retention_period",
 547                    "30d",
 548                    ["1min", "1h", "30d"],
 549                )
 550            ]
 551            if version >= MzVersion.parse_mz("v26.40.0-dev")
 552            else []
 553        ),
 554        VariableSystemParameter(
 555            "persist_validate_part_bounds_on_read", "false", ["true", "false"]
 556        ),
 557        VariableSystemParameter(
 558            "persist_validate_part_bounds_on_write", "false", ["true", "false"]
 559        ),
 560        VariableSystemParameter(
 561            "statement_logging_default_sample_rate",
 562            "1.0",
 563            ["0", "0.01", "0.5", "0.99", "1.0"],
 564        ),
 565        VariableSystemParameter(
 566            "statement_logging_max_data_credit",
 567            "",
 568            ["", "0", "1024", "1048576", "1073741824"],
 569        ),
 570        VariableSystemParameter(
 571            "statement_logging_max_sample_rate",
 572            "1.0",
 573            ["0", "0.01", "0.5", "0.99", "1.0"],
 574        ),
 575        VariableSystemParameter(
 576            "statement_logging_target_data_rate",
 577            "",
 578            ["", "0", "1", "1000", "2071", "1000000"],
 579        ),
 580        VariableSystemParameter(
 581            "storage_source_decode_fuel",
 582            "100000",
 583            ["10000", "100000", "1000000"],
 584        ),
 585        VariableSystemParameter(
 586            "storage_statistics_collection_interval",
 587            "1000",
 588            ["100", "1000", "10000"],
 589        ),
 590        VariableSystemParameter(
 591            "storage_statistics_interval", "2000", ["100", "1000", "10000"]
 592        ),
 593        VariableSystemParameter(
 594            "storage_use_continual_feedback_upsert", "true", ["true", "false"]
 595        ),
 596        # End of list (ordered by name)
 597    ]
 598
 599    if version < MzVersion.parse_mz("v26.14.0-dev"):
 600        params.append(
 601            VariableSystemParameter(
 602                "storage_reclock_to_latest", "true", ["true", "false"]
 603            )
 604        )
 605    if version < MzVersion.parse_mz("v26.23.0-dev"):
 606        params.append(
 607            VariableSystemParameter(
 608                "persist_enable_arrow_lgalloc_noncc_sizes", "true", ["true", "false"]
 609            )
 610        )
 611        params.append(
 612            VariableSystemParameter(
 613                "persist_enable_s3_lgalloc_noncc_sizes", "true", ["true", "false"]
 614            )
 615        )
 616
 617    return params
 618
 619
 620def get_default_system_parameters(
 621    version: MzVersion | None = None,
 622    force_source_table_syntax: bool = False,
 623    metadata_store: str | None = None,
 624) -> dict[str, str]:
 625    """For upgrade tests we only want parameters set when all environmentd /
 626    clusterd processes have reached a specific version (or higher)
 627
 628    `metadata_store` selects backend-specific defaults. It defaults to the
 629    globally configured metadata store, but callers that target a different
 630    backend than the global (e.g. a local CockroachDB) must pass their own.
 631    """
 632
 633    if not version:
 634        version = MzVersion.parse_cargo()
 635
 636    if metadata_store is None:
 637        from materialize.mzcompose.services.metadata_store import METADATA_STORE
 638
 639        metadata_store = METADATA_STORE
 640
 641    params = get_minimal_system_parameters(version)
 642
 643    system_param_setting = os.getenv("CI_SYSTEM_PARAMETERS", "")
 644    variable_params = get_variable_system_parameters(
 645        version, force_source_table_syntax, metadata_store
 646    )
 647
 648    if system_param_setting == "":
 649        for param in variable_params:
 650            params[param.key] = param.default
 651    elif system_param_setting == "random":
 652        seed = os.getenv("CI_SYSTEM_PARAMETERS_SEED", os.getenv("BUILDKITE_JOB_ID", 1))
 653        rng = random.Random(seed)
 654        for param in variable_params:
 655            params[param.key] = rng.choice(param.values)
 656        print(
 657            f"System parameters with seed CI_SYSTEM_PARAMETERS_SEED={seed}: {params}",
 658            file=sys.stderr,
 659        )
 660    elif system_param_setting == "minimal":
 661        pass
 662    else:
 663        raise ValueError(
 664            f"Unknown value for CI_SYSTEM_PARAMETERS: {system_param_setting}"
 665        )
 666
 667    return params
 668
 669
 670# If you are adding a new config flag in Materialize, consider setting values
 671# for it in get_variable_system_parameters if it can be varied in tests. Set it
 672# in get_minimal_system_parameters if it's required for tests to succeed at
 673# all. Only add it in UNINTERESTING_SYSTEM_PARAMETERS if none of the above
 674# apply.
 675UNINTERESTING_SYSTEM_PARAMETERS = [
 676    "enable_compute_half_join2",
 677    "enable_mz_join_core",
 678    "linear_join_yielding",
 679    "enable_column_paged_batcher",
 680    "enable_column_paged_batcher_spill",
 681    "column_chunk_compress_min_depth",
 682    "column_paged_batcher_budget_fraction",
 683    "column_paged_batcher_lz4",
 684    "column_paged_batcher_swap_pageout",
 685    "column_paged_batcher_spill_worker_count",
 686    "column_paged_batcher_eager_backing",
 687    "column_paged_batcher_pool_rss_target_fraction",
 688    "enable_lgalloc_eager_reclamation",
 689    "lgalloc_background_interval",
 690    "lgalloc_file_growth_dampener",
 691    "lgalloc_local_buffer_bytes",
 692    "lgalloc_slow_clear_bytes",
 693    "memory_limiter_interval",
 694    "memory_limiter_usage_bias",
 695    "memory_limiter_burst_factor",
 696    "catalog_info_metrics_reconcile_interval",
 697    "compute_server_maintenance_interval",
 698    "compute_dataflow_max_inflight_bytes_cc",
 699    "compute_flat_map_fuel",
 700    "compute_temporal_bucketing_summary",
 701    "consolidating_vec_growth_dampener",
 702    "copy_to_s3_parquet_row_group_file_ratio",
 703    "copy_to_s3_arrow_builder_buffer_ratio",
 704    "copy_to_s3_multipart_part_size_bytes",
 705    "enable_replica_targeted_materialized_views",
 706    "compute_mv_sink_advance_persist_frontiers",
 707    "compute_prometheus_introspection_scrape_interval",
 708    "enable_compute_replica_expiration",
 709    "compute_logical_backpressure_max_retained_capabilities",
 710    "compute_logical_backpressure_inflight_slack",
 711    "persist_fetch_semaphore_cost_adjustment",
 712    "persist_fetch_semaphore_permit_adjustment",
 713    "persist_optimize_ignored_data_fetch",
 714    "persist_pubsub_same_process_delegate_enabled",
 715    "persist_pubsub_connect_attempt_timeout",
 716    "persist_pubsub_request_timeout",
 717    "persist_pubsub_connect_max_backoff",
 718    "persist_pubsub_client_sender_channel_size",
 719    "persist_pubsub_client_receiver_channel_size",
 720    "persist_pubsub_server_connection_channel_size",
 721    "persist_pubsub_state_cache_shard_ref_channel_size",
 722    "persist_pubsub_reconnect_backoff",
 723    "persist_encoding_compression_format",
 724    "persist_batch_max_runs",
 725    "persist_write_combine_inline_writes",
 726    "persist_reader_lease_duration",
 727    "persist_consensus_connection_pool_max_size",
 728    "persist_consensus_connection_pool_max_wait",
 729    "persist_consensus_connection_pool_ttl",
 730    "persist_consensus_connection_pool_ttl_stagger",
 731    "persist_use_postgres_tuned_queries",
 732    "crdb_connect_timeout",
 733    "crdb_tcp_user_timeout",
 734    "crdb_keepalives_idle",
 735    "crdb_keepalives_interval",
 736    "crdb_keepalives_retries",
 737    "pg_timestamp_oracle_statement_timeout",
 738    "persist_use_critical_since_txn",
 739    "use_global_txn_cache_source",
 740    "persist_batch_builder_max_outstanding_parts",
 741    "persist_compaction_heuristic_min_inputs",
 742    "persist_compaction_heuristic_min_parts",
 743    "persist_compaction_heuristic_min_updates",
 744    "persist_gc_blob_delete_concurrency_limit",
 745    "persist_state_versions_recent_live_diffs_limit",
 746    "persist_usage_state_fetch_concurrency_limit",
 747    "persist_blob_operation_timeout",
 748    "persist_blob_operation_attempt_timeout",
 749    "persist_blob_connect_timeout",
 750    "persist_blob_read_timeout",
 751    "persist_blob_hedged_get_max_concurrent",
 752    "persist_blob_hedged_get_warm_interval",
 753    "persist_stats_collection_enabled",
 754    "persist_stats_filter_enabled",
 755    "persist_stats_budget_bytes",
 756    "persist_stats_untrimmable_columns_equals",
 757    "persist_stats_untrimmable_columns_prefix",
 758    "persist_stats_untrimmable_columns_suffix",
 759    "persist_expression_cache_force_compaction_fuel",
 760    "persist_expression_cache_force_compaction_wait",
 761    "persist_blob_cache_mem_limit_bytes",
 762    "persist_blob_cache_scale_factor_bytes",
 763    "persist_claim_unclaimed_compactions",
 764    "persist_claim_compaction_percent",
 765    "persist_claim_compaction_min_version",
 766    "persist_next_listen_batch_retryer_multiplier",
 767    "persist_rollup_threshold",
 768    "persist_rollup_fallback_threshold_ms",
 769    "persist_gc_fallback_threshold_ms",
 770    "persist_compaction_minimum_timeout",
 771    "persist_compaction_check_process_flag",
 772    "balancerd_sigterm_connection_wait",
 773    "balancerd_sigterm_listen_wait",
 774    "balancerd_inject_proxy_protocol_header_http",
 775    "balancerd_max_connections",
 776    "balancerd_log_filter",
 777    "balancerd_opentelemetry_filter",
 778    "balancerd_log_filter_defaults",
 779    "balancerd_opentelemetry_filter_defaults",
 780    "balancerd_sentry_filters",
 781    "persist_enable_s3_lgalloc_cc_sizes",
 782    "persist_enable_arrow_lgalloc_cc_sizes",
 783    "controller_past_generation_replica_cleanup_retry_interval",
 784    "wallclock_lag_recording_interval",
 785    "wallclock_lag_histogram_period_interval",
 786    "enable_timely_zero_copy",
 787    "enable_timely_zero_copy_lgalloc",
 788    "timely_zero_copy_limit",
 789    "arrangement_exert_proportionality",
 790    "txn_wal_apply_ensure_schema_match",
 791    "persist_txns_data_shard_retryer_initial_backoff",
 792    "persist_txns_data_shard_retryer_multiplier",
 793    "persist_txns_data_shard_retryer_clamp",
 794    "storage_cluster_shutdown_grace_period",
 795    "storage_dataflow_delay_sources_past_rehydration",
 796    "storage_dataflow_suspendable_sources",
 797    "storage_downgrade_since_during_finalization",
 798    "replica_metrics_history_retention_interval",
 799    "wallclock_lag_history_retention_interval",
 800    "wallclock_global_lag_histogram_retention_interval",
 801    "kafka_client_id_enrichment_rules",
 802    "kafka_poll_max_wait",
 803    "kafka_default_aws_privatelink_endpoint_identification_algorithm",
 804    "kafka_buffered_event_resize_threshold_elements",
 805    "kafka_low_watermark_check",
 806    "mysql_replication_heartbeat_interval",
 807    # Not varied here because statistics tests assert exact
 808    # snapshot_records_known values, which only hold on the exact-count path.
 809    # The estimated path is covered explicitly in mysql-cdc/statistics.td and
 810    # by parallel-workload.
 811    "mysql_source_snapshot_exact_count_max_rows",
 812    "mysql_source_snapshot_partition_probed_prefixes_per_billion_rows",
 813    "postgres_fetch_slot_resume_lsn_interval",
 814    "pg_schema_validation_interval",
 815    "pg_source_validate_timeline",
 816    "sql_server_source_validate_restore_history",
 817    "storage_enforce_external_addresses",
 818    "storage_upsert_prevent_snapshot_buffering",
 819    "storage_rocksdb_use_merge_operator",
 820    "storage_upsert_max_snapshot_batch_buffering",
 821    "storage_rocksdb_cleanup_tries",
 822    "storage_suspend_and_restart_delay",
 823    "storage_server_maintenance_interval",
 824    "storage_sink_progress_search",
 825    "storage_sink_ensure_topic_config",
 826    "sql_server_max_lsn_wait",
 827    "sql_server_snapshot_progress_report_interval",
 828    "sql_server_cdc_cleanup_change_table",
 829    "sql_server_cdc_cleanup_change_table_max_deletes",
 830    "allow_user_sessions",
 831    "group_commit_max_attempts",
 832    "with_0dt_deployment_ddl_check_interval",
 833    "enable_0dt_caught_up_check",
 834    "with_0dt_caught_up_check_allowed_lag",
 835    "with_0dt_caught_up_check_cutoff",
 836    "enable_0dt_caught_up_replica_status_check",
 837    "enable_0dt_caught_up_stability_check",
 838    "enable_0dt_hydrate_migrated_builtin_mvs",
 839    "plan_insights_notice_fast_path_clusters_optimize_duration",
 840    "enable_expression_cache",
 841    "mz_metrics_lgalloc_map_refresh_interval",
 842    "mz_metrics_lgalloc_refresh_interval",
 843    "mz_metrics_rusage_refresh_interval",
 844    "mz_metrics_usage_refresh_interval",
 845    "compute_peek_response_stash_batch_max_runs",
 846    # The offload's budgets, left at their code defaults so tests exercise the
 847    # placement decisions production makes. parallel-workload varies them.
 848    "compute_index_peek_inline_budget",
 849    "compute_index_peek_activation_budget",
 850    "compute_index_peek_yield_granularity",
 851    "compute_index_peek_permit_fraction",
 852    "compute_peek_response_stash_batch_bytes",
 853    "compute_peek_response_stash_read_batch_size_bytes",
 854    "compute_peek_response_stash_read_memory_budget_bytes",
 855    "storage_statistics_retention_duration",
 856    "enable_paused_cluster_readhold_downgrade",
 857    "kafka_retry_backoff",
 858    "kafka_retry_backoff_max",
 859    "kafka_reconnect_backoff",
 860    "kafka_reconnect_backoff_max",
 861    "kafka_sink_message_max_bytes",
 862    "kafka_sink_batch_size",
 863    "kafka_sink_batch_num_messages",
 864    "oidc_issuer",
 865    "oidc_audience",
 866    "oidc_authentication_claim",
 867    "oidc_group_role_sync_enabled",
 868    "oidc_group_claim",
 869    "oidc_group_role_sync_strict",
 870    "console_oidc_client_id",
 871    "console_oidc_scopes",
 872    "enable_public_metrics_endpoint",
 873    "enable_mcp_agent",
 874    "enable_mcp_agent_query_tool",
 875    "enable_mcp_agent_read_data_product_tool",
 876    "enable_mcp_developer",
 877    "enable_mcp_developer_query_tool",
 878    "mcp_max_response_size",
 879    "mcp_request_timeout",
 880    "user_id_pool_batch_size",
 881    "webhook_max_request_size_bytes",
 882    "webhook_validation_memory_budget_bytes",
 883    "subscribe_max_buffered_bytes",
 884    "cluster_controller_tick_interval",
 885    "default_cluster_reconfiguration_timeout",
 886    "read_then_write_max_dependencies",
 887    "enable_hydration_burst",
 888    "default_hydration_burst_linger",
 889]
 890
 891
 892DEFAULT_CRDB_ENVIRONMENT = [
 893    "COCKROACH_ENGINE_MAX_SYNC_DURATION_DEFAULT=120s",
 894    "COCKROACH_LOG_MAX_SYNC_DURATION=120s",
 895]
 896
 897
 898# TODO(benesch): change to `docker-mzcompose` once v0.39 ships.
 899DEFAULT_CLOUD_PROVIDER = "mzcompose"
 900DEFAULT_CLOUD_REGION = "us-east-1"
 901DEFAULT_ORG_ID = "00000000-0000-0000-0000-000000000000"
 902DEFAULT_ORDINAL = "0"
 903DEFAULT_MZ_ENVIRONMENT_ID = f"{DEFAULT_CLOUD_PROVIDER}-{DEFAULT_CLOUD_REGION}-{DEFAULT_ORG_ID}-{DEFAULT_ORDINAL}"
 904
 905
 906# TODO(benesch): replace with Docker health checks.
 907def _check_tcp(
 908    cmd: list[str], host: str, port: int, timeout_secs: int, kind: str = ""
 909) -> list[str]:
 910    cmd.extend(
 911        [
 912            "timeout",
 913            str(timeout_secs),
 914            "bash",
 915            "-c",
 916            f"until [ cat < /dev/null > /dev/tcp/{host}/{port} ] ; do sleep 0.1 ; done",
 917        ]
 918    )
 919    try:
 920        spawn.capture(cmd, stderr=subprocess.STDOUT)
 921    except subprocess.CalledProcessError as e:
 922        ui.log_in_automation(
 923            "wait-for-tcp ({}{}:{}): error running {}: {}, stdout:\n{}\nstderr:\n{}".format(
 924                kind, host, port, ui.shell_quote(cmd), e, e.stdout, e.stderr
 925            )
 926        )
 927        raise
 928    return cmd
 929
 930
 931# TODO(benesch): replace with Docker health checks.
 932def _wait_for_pg(
 933    timeout_secs: int,
 934    query: str,
 935    dbname: str,
 936    port: int,
 937    host: str,
 938    user: str,
 939    password: str | None,
 940    expected: Iterable[Any] | Literal["any"],
 941    print_result: bool = False,
 942    sslmode: str = "disable",
 943) -> None:
 944    """Wait for a pg-compatible database (includes materialized)"""
 945    obfuscated_password = password[0:1] if password is not None else ""
 946    args = f"dbname={dbname} host={host} port={port} user={user} password='{obfuscated_password}...'"
 947    ui.progress(f"waiting for {args} to handle {query!r}", "C")
 948    error = None
 949    for remaining in ui.timeout_loop(timeout_secs, tick=0.5):
 950        try:
 951            conn = psycopg.connect(
 952                dbname=dbname,
 953                host=host,
 954                port=port,
 955                user=user,
 956                password=password,
 957                connect_timeout=1,
 958                sslmode=sslmode,
 959            )
 960            # The default (autocommit = false) wraps everything in a transaction.
 961            conn.autocommit = True
 962            with conn.cursor() as cur:
 963                cur.execute(query.encode())
 964                if expected == "any" and cur.rowcount == -1:
 965                    ui.progress(" success!", finish=True)
 966                    return
 967                result = list(cur.fetchall())
 968                if expected == "any" or result == expected:
 969                    if print_result:
 970                        say(f"query result: {result}")
 971                    else:
 972                        ui.progress(" success!", finish=True)
 973                    return
 974                else:
 975                    say(
 976                        f"host={host} port={port} did not return rows matching {expected} got: {result}"
 977                    )
 978        except Exception as e:
 979            ui.progress(f"{e if print_result else ''} {int(remaining)}")
 980            error = e
 981    ui.progress(finish=True)
 982    raise UIError(f"never got correct result for {args}: {error}")
 983
 984
 985def bootstrap_cluster_replica_size() -> str:
 986    return "bootstrap"
 987
 988
 989def cluster_replica_size_map() -> dict[str, dict[str, Any]]:
 990    """scale=<n>,workers=<n>[,mem=<n>GiB][,legacy]"""
 991
 992    def replica_size(
 993        scale: int,
 994        workers: int,
 995        disabled: bool = False,
 996        is_cc: bool = True,
 997        memory_limit: str = "4 GiB",
 998    ) -> dict[str, Any]:
 999        return {
1000            "cpu_exclusive": False,
1001            "cpu_limit": None,
1002            "credits_per_hour": f"{workers * scale}",
1003            "disabled": disabled,
1004            "disk_limit": None,
1005            "is_cc": is_cc,
1006            "memory_limit": memory_limit,
1007            "scale": scale,
1008            "workers": workers,
1009            # "selectors": {},
1010        }
1011
1012    replica_sizes = {
1013        bootstrap_cluster_replica_size(): replica_size(1, 1),
1014        "scale=2,workers=4": replica_size(2, 4),
1015        "scale=1,workers=1,legacy": replica_size(1, 1, is_cc=False),
1016        "scale=1,workers=2,legacy": replica_size(1, 2, is_cc=False),
1017        # Intentionally not following the naming scheme
1018        "free": replica_size(1, 1, disabled=True),
1019    }
1020
1021    for i in range(0, 6):
1022        workers = 1 << i
1023        replica_sizes[f"scale=1,workers={workers}"] = replica_size(1, workers)
1024        for mem in [4, 8, 16, 32]:
1025            replica_sizes[f"scale=1,workers={workers},mem={mem}GiB"] = replica_size(
1026                1, workers, memory_limit=f"{mem} GiB"
1027            )
1028
1029        replica_sizes[f"scale={workers},workers=1"] = replica_size(workers, 1)
1030        replica_sizes[f"scale={workers},workers={workers}"] = replica_size(
1031            workers, workers
1032        )
1033        replica_sizes[f"scale=1,workers={workers},mem={workers}GiB"] = replica_size(
1034            1, workers, memory_limit=f"{workers} GiB"
1035        )
1036
1037    return replica_sizes
def say(msg: str) -> None:
55    def say(msg: str) -> None:
56        if not Verbosity.quiet:
57            print(f"{prefix}{msg}", file=sys.stderr)

The type of the None singleton.

DEFAULT_CONFLUENT_PLATFORM_VERSION = '8.2.0'
DEFAULT_MZ_VOLUMES = ['mzdata:/mzdata', 'mydata:/var/lib/mysql-files', 'tmp:/share/tmp', 'scratch:/scratch']
ADDITIONAL_BENCHMARKING_SYSTEM_PARAMETERS = {'persist_blob_hedged_get_enabled': 'true', 'persist_blob_hedged_get_delay': '2s', 'persist_blob_hedged_get_budget_ratio': '0.01', 'enable_metric_sink': 'false'}
def sanitizer_enabled() -> bool:
70def sanitizer_enabled() -> bool:
71    """Whether the binaries under test were built with a sanitizer.
72
73    Sanitizer builds run several times slower and use several times as much
74    memory as ordinary ones, so tests that assert on timing, or that need
75    jemalloc (which sanitizer builds drop, as it clashes with the sanitizer
76    runtimes), have to account for them.
77    """
78    return Sanitizer[os.getenv("CI_SANITIZER", "none")] != Sanitizer.none

Whether the binaries under test were built with a sanitizer.

Sanitizer builds run several times slower and use several times as much memory as ordinary ones, so tests that assert on timing, or that need jemalloc (which sanitizer builds drop, as it clashes with the sanitizer runtimes), have to account for them.

def get_minimal_system_parameters(version: materialize.mz_version.MzVersion) -> dict[str, str]:
 81def get_minimal_system_parameters(
 82    version: MzVersion,
 83) -> dict[str, str]:
 84    """Settings we need in order to have tests run at all, but otherwise stay
 85    with the defaults: not changing performance or increasing coverage."""
 86
 87    config = {
 88        # -----
 89        # Unsafe functions
 90        "unsafe_enable_unsafe_functions": "true",
 91        # -----
 92        # Others (ordered by name)
 93        "allow_real_time_recency": "true",
 94        "constraint_based_timestamp_selection": "verify",  # removed from main, keeping it here for old versions
 95        "enable_compute_peek_response_stash": "true",
 96        "enable_0dt_deployment_panic_after_timeout": "true",
 97        "enable_0dt_deployment_sources": (
 98            "true" if version >= MzVersion.parse_mz("v0.132.0-dev") else "false"
 99        ),
100        "enable_alter_swap": "true",
101        "enable_arrangement_dictionary_compression_alpha": "false",
102        "enable_case_literal_transform": "true",
103        "enable_cast_elimination": "true",
104        "enable_coalesce_case_transform": "true",
105        "enable_columnation_lgalloc": "false",
106        "enable_compute_correction_v2": "true",
107        "enable_compute_logical_backpressure": "true",
108        "enable_connection_validation_syntax": "true",
109        "enable_create_table_from_source": "true",
110        "enable_eager_delta_joins": "true",
111        "enable_envelope_debezium_in_subscribe": "true",
112        "enable_exclude_constraints_option": "true",
113        "enable_expressions_in_limit_syntax": "true",
114        "enable_fixed_correlated_cte_lowering": "true",
115        "enable_introspection_subscribes": "true",
116        "enable_lgalloc": "false",
117        "enable_load_generator_counter": "true",
118        "enable_logical_compaction_window": "true",
119        "enable_metric_sink": "true",
120        "enable_multi_worker_storage_persist_sink": "true",
121        "enable_rbac_checks": "true",
122        "enable_reduce_mfp_fusion": "true",
123        "enable_refresh_every_mvs": "true",
124        "enable_replacement_materialized_views": "true",
125        "enable_cluster_schedule_refresh": "true",
126        # Pinned explicitly so runs against older versions (which predate the
127        # flag or defaulted it off) behave like current ones, where it defaults
128        # on.
129        "enable_background_alter_cluster": (
130            "true" if version >= MzVersion.parse_mz("v26.29.0-dev") else "false"
131        ),
132        "enable_s3_tables_region_check": "false",
133        "enable_statement_lifecycle_logging": "true",
134        "enable_storage_introspection_logs": "true",
135        "enable_compute_error_distinct": "true",
136        "enable_compute_temporal_bucketing": "true",
137        "enable_union_cancellation_after_relation_cse": "true",
138        "enable_variadic_left_join_lowering": "true",
139        "enable_worker_core_affinity": "true",
140        "grpc_client_http2_keep_alive_timeout": "5s",
141        "ore_overflowing_behavior": "panic",
142        "unsafe_enable_table_keys": "true",
143        # Keep the 0dt stability soak out of the critical path for tests. The
144        # production default is much higher. Dedicated workflows override this.
145        "with_0dt_caught_up_check_stability_period": "0s",
146        "with_0dt_deployment_max_wait": "1800s",
147        # End of list (ordered by name)
148    }
149
150    if version >= MzVersion.parse_mz("v26.40.0-dev"):
151        # Exercise the row-limit check without constraining normal test queries.
152        config["compute_peek_row_iteration_limit"] = "1000000000"
153        config["enable_compute_peek_row_iteration_limit"] = "true"
154
155        # Exercise the peek offload path in tests while it defaults off in
156        # production. The budgets stay at their code defaults so tests make the
157        # same placement decisions production makes.
158        config["enable_compute_index_peek_offload"] = "true"
159
160    if version < MzVersion.parse_mz("v0.163.0-dev"):
161        config["enable_compute_active_dataflow_cancelation"] = "true"
162
163    if version < MzVersion.parse_mz("v26.24.0-dev"):
164        config["enable_columnar_lgalloc"] = "false"
165    if version < MzVersion.parse_mz("v26.25.0-dev"):
166        config["enable_multi_replica_sources"] = "true"
167
168    if version >= MzVersion.parse_mz("v26.40.0-dev"):
169        config["hydration_history_collection_interval"] = "60s"
170
171    if sanitizer_enabled():
172        config["with_0dt_deployment_max_wait"] = "18000s"
173
174    # The cluster controller's break-glass gate. Removed in v26.38, where the
175    # controller runs unconditionally. Older binaries still read it, and
176    # defaulted it off before v26.29, so pin it on for them to keep mixed-version
177    # runs exercising the same path as current versions.
178    if version < MzVersion.parse_mz("v26.38.0-dev"):
179        config["enable_cluster_controller"] = (
180            "true" if version >= MzVersion.parse_mz("v26.29.0-dev") else "false"
181        )
182
183    # The `WITH (WAIT ...)` graceful-reconfiguration surface. Always accepted
184    # from v26.41 on. Older binaries still gate it behind this feature flag, so
185    # pin it on for them: the tests that use the surface no longer enable it
186    # themselves, and in a mixed-version run some of their phases execute
187    # against the old binary.
188    if version < MzVersion.parse_mz("v26.41.0-dev"):
189        config["enable_zero_downtime_cluster_reconfiguration"] = "true"
190
191    return config

Settings we need in order to have tests run at all, but otherwise stay with the defaults: not changing performance or increasing coverage.

@dataclass
class VariableSystemParameter:
194@dataclass
195class VariableSystemParameter:
196    key: str
197    default: str
198    values: list[str]
VariableSystemParameter(key: str, default: str, values: list[str])
key: str
default: str
values: list[str]
def get_variable_system_parameters( version: materialize.mz_version.MzVersion, force_source_table_syntax: bool, metadata_store: str) -> list[VariableSystemParameter]:
202def get_variable_system_parameters(
203    version: MzVersion,
204    force_source_table_syntax: bool,
205    metadata_store: str,
206) -> list[VariableSystemParameter]:
207    """Note: Only the default is tested unless we explicitly select "System Parameters: Random" in trigger-ci.
208    These defaults are applied _after_ applying the settings from `get_minimal_system_parameters`.
209    """
210
211    # `persist_pg_consensus_read_committed` must stay off on CockroachDB, where
212    # the lockless CRDB_* consensus queries are only linearizable under
213    # SERIALIZABLE and persist asserts on the connection's isolation level. On
214    # Postgres-backed consensus the query family is linearizable under READ
215    # COMMITTED, so default it on and let it vary.
216    read_committed_safe = metadata_store in ("postgres-metadata", "alloydb")
217    persist_pg_consensus_read_committed = VariableSystemParameter(
218        "persist_pg_consensus_read_committed",
219        "true" if read_committed_safe else "false",
220        ["true", "false"] if read_committed_safe else ["false"],
221    )
222
223    params = [
224        # -----
225        # To reduce CRDB load as we are struggling with it in CI (values based on load test environment):
226        VariableSystemParameter(
227            "persist_next_listen_batch_retryer_clamp",
228            "16s",
229            ["100ms", "1s", "10s", "100s"],
230        ),
231        VariableSystemParameter(
232            "persist_next_listen_batch_retryer_initial_backoff",
233            "100ms",
234            ["10ms", "100ms", "1s", "10s"],
235        ),
236        VariableSystemParameter(
237            "persist_next_listen_batch_retryer_fixed_sleep",
238            "1200ms",
239            ["100ms", "1s", "10s"],
240        ),
241        # -----
242        # Persist internals changes, advance coverage
243        VariableSystemParameter(
244            "persist_source_fetch_concurrency", "1", ["1", "2", "8", "16"]
245        ),
246        VariableSystemParameter(
247            "persist_blob_hedged_get_enabled", "true", ["true", "false"]
248        ),
249        # 10ms (vs the 2s production default) makes hedges actually fire in
250        # every CI run; 0s makes every blob get hedge under randomized seeds.
251        VariableSystemParameter(
252            "persist_blob_hedged_get_delay", "10ms", ["0s", "10ms", "2s"]
253        ),
254        # The production ratio: with the 10ms delay above, a full refill
255        # would hedge nearly every get and double CI blob traffic. The 1.0
256        # variant lets randomized runs pair a full budget with delay=0s.
257        VariableSystemParameter(
258            "persist_blob_hedged_get_budget_ratio", "0.01", ["1.0", "0.01"]
259        ),
260        # -----
261        # Others (ordered by name),
262        VariableSystemParameter(
263            "aws_prefetch_sts_connect_timeout",
264            "3100ms",
265            ["3100ms", "30s", "60s"],
266        ),
267        VariableSystemParameter(
268            "compute_correction_v2_chain_proportionality",
269            "3",
270            ["2", "3"],
271        ),
272        VariableSystemParameter(
273            "compute_correction_v2_chunk_size",
274            "8192",
275            ["8192", "65536", "1048576"],
276        ),
277        VariableSystemParameter(
278            "compute_dataflow_max_inflight_bytes",
279            "134217728",
280            ["1048576", "4194304", "16777216", "67108864"],
281        ),  # 128 MiB
282        VariableSystemParameter("compute_hydration_concurrency", "2", ["1", "2", "4"]),
283        VariableSystemParameter(
284            "compute_replica_expiration_offset", "3d", ["3d", "10d"]
285        ),
286        VariableSystemParameter(
287            "compute_apply_column_demands", "true", ["true", "false"]
288        ),
289        # On by default so CI exercises the columnar merge batcher, which is
290        # off in production while it earns trust.
291        VariableSystemParameter(
292            "enable_columnar_merge_batcher", "true", ["true", "false"]
293        ),
294        # On by default so CI exercises the columnar accumulable diff layout, which
295        # is off in production while it earns trust.
296        VariableSystemParameter(
297            "enable_columnar_accumulable_diff", "true", ["true", "false"]
298        ),
299        VariableSystemParameter(
300            "compute_peek_response_stash_threshold_bytes",
301            # 1 MiB, an in-between value
302            "1048576",
303            # force-enabled, the in-between, and the production value
304            ["0", "1048576", "314572800", "67108864"],
305        ),
306        VariableSystemParameter(
307            "compute_subscribe_snapshot_optimization",
308            "true",
309            ["true", "false"],
310        ),
311        VariableSystemParameter(
312            "enable_case_literal_transform",
313            "false",
314            ["true", "false"],
315        ),
316        VariableSystemParameter(
317            "enable_coalesce_case_transform",
318            "true",
319            ["true", "false"],
320        ),
321        VariableSystemParameter(
322            "enable_adapter_frontend_occ_read_then_write",
323            "true" if version >= MzVersion.parse_mz("v26.36.0-dev") else "false",
324            ["true", "false"],
325        ),
326        VariableSystemParameter(
327            "enable_cast_elimination",
328            "true",
329            ["true", "false"],
330        ),
331        VariableSystemParameter(
332            "enable_fixed_correlated_cte_lowering",
333            "true",
334            ["true", "false"],
335        ),
336        VariableSystemParameter(
337            "enable_compute_sync_mv_sink",
338            "true",
339            ["true", "false"],
340        ),
341        VariableSystemParameter(
342            "enable_password_auth",
343            "true",
344            ["true", "false"],
345        ),
346        VariableSystemParameter(
347            "enable_frontend_peek_sequencing",
348            "true" if version >= MzVersion.parse_mz("v26.9.0-dev") else "false",
349            ["true", "false"],
350        ),
351        VariableSystemParameter(
352            "enable_frontend_subscribes",
353            "true" if version >= MzVersion.parse_mz("v26.18.0-dev") else "false",
354            ["true", "false"],
355        ),
356        VariableSystemParameter(
357            "enable_simplify_from_less_existence",
358            "true",
359            ["true", "false"],
360        ),
361        VariableSystemParameter(
362            "enable_union_cancellation_after_relation_cse",
363            "true",
364            ["true", "false"],
365        ),
366        VariableSystemParameter(
367            "enable_upsert_paged_spill",
368            "true",
369            ["true", "false"],
370        ),
371        # On by default so CI exercises the chunked stash flavor, which is
372        # off in production while it earns trust. Only meaningful when
373        # enable_upsert_v2 is true.
374        VariableSystemParameter(
375            "enable_upsert_chunked_stash",
376            "true",
377            ["true", "false"],
378        ),
379        VariableSystemParameter(
380            "enable_upsert_v2",
381            "false",
382            ["true", "false"],
383        ),
384        VariableSystemParameter(
385            "default_timestamp_interval",
386            "1s",
387            ["100ms", "1s"],
388        ),
389        VariableSystemParameter(
390            "force_source_table_syntax",
391            "true" if force_source_table_syntax else "false",
392            ["true", "false"] if force_source_table_syntax else ["false"],
393        ),
394        VariableSystemParameter(
395            "mysql_source_snapshot_parallelism", "true", ["true", "false"]
396        ),
397        # Low default so small tables exercise partitioning.
398        VariableSystemParameter(
399            "mysql_source_snapshot_partition_min_rows", "2", ["2", "50000"]
400        ),
401        VariableSystemParameter(
402            "persist_batch_delete_enabled", "true", ["true", "false"]
403        ),
404        VariableSystemParameter(
405            "persist_batch_structured_key_lower_len",
406            "256",
407            ["0", "1", "512", "1000"],
408        ),
409        VariableSystemParameter(
410            "persist_batch_max_run_len", "4", ["2", "3", "4", "16"]
411        ),
412        VariableSystemParameter(
413            "persist_catalog_force_compaction_fuel",
414            "1024",
415            ["256", "1024", "4096"],
416        ),
417        VariableSystemParameter(
418            "persist_catalog_force_compaction_wait",
419            "1s",
420            ["100ms", "1s", "10s"],
421        ),
422        VariableSystemParameter(
423            "persist_stats_audit_percent",
424            "100",
425            [
426                "0",
427                "1",
428                "2",
429                "10",
430                "100",
431            ],
432        ),
433        VariableSystemParameter("persist_stats_audit_panic", "true", ["true", "false"]),
434        VariableSystemParameter(
435            "persist_encoding_enable_dictionary", "true", ["true", "false"]
436        ),
437        VariableSystemParameter(
438            "persist_fast_path_limit",
439            "1000",
440            ["100", "1000", "10000"],
441        ),
442        VariableSystemParameter("persist_fast_path_order", "true", ["true", "false"]),
443        VariableSystemParameter(
444            "persist_gc_use_active_gc",
445            ("true" if version > MzVersion.parse_mz("v0.143.0-dev") else "false"),
446            (
447                ["true", "false"]
448                if version > MzVersion.parse_mz("v0.127.0-dev")
449                else ["false"]
450            ),
451        ),
452        VariableSystemParameter(
453            "persist_gc_min_versions",
454            "16",
455            ["16", "256", "1024"],
456        ),
457        VariableSystemParameter(
458            "persist_gc_max_versions",
459            "128000",
460            ["256", "128000"],
461        ),
462        VariableSystemParameter(
463            "persist_inline_writes_single_max_bytes",
464            "4096",
465            ["256", "1024", "4096", "16384"],
466        ),
467        VariableSystemParameter(
468            "persist_inline_writes_total_max_bytes",
469            "1048576",
470            ["65536", "262144", "1048576", "4194304"],
471        ),
472        VariableSystemParameter(
473            "persist_pubsub_client_enabled", "true", ["true", "false"]
474        ),
475        VariableSystemParameter(
476            "persist_pubsub_push_diff_enabled", "true", ["true", "false"]
477        ),
478        VariableSystemParameter(
479            "persist_rollup_use_active_rollup",
480            ("true" if version > MzVersion.parse_mz("v0.143.0-dev") else "false"),
481            (
482                ["true", "false"]
483                if version > MzVersion.parse_mz("v0.127.0-dev")
484                else ["false"]
485            ),
486        ),
487        # 16 MiB - large enough to avoid a big perf hit, small enough to get more coverage...
488        VariableSystemParameter(
489            "persist_blob_target_size",
490            "16777216",
491            ["4096", "1048576", "16777216", "134217728"],
492        ),
493        # 5 times the default part size - 4 is the bare minimum.
494        VariableSystemParameter(
495            "persist_compaction_memory_bound_bytes",
496            "83886080",
497            ["67108864", "134217728", "536870912", "1073741824"],
498        ),
499        VariableSystemParameter(
500            "persist_enable_incremental_compaction",
501            ("true" if version >= MzVersion.parse_mz("v0.161.0-dev") else "false"),
502            (
503                ["true", "false"]
504                if version >= MzVersion.parse_mz("v0.161.0-dev")
505                else ["false"]
506            ),
507        ),
508        VariableSystemParameter(
509            "persist_use_critical_since_catalog", "true", ["true", "false"]
510        ),
511        VariableSystemParameter(
512            "persist_use_critical_since_snapshot",
513            "false",  # always false, because we always have zero-downtime enabled
514            ["false"],
515        ),
516        VariableSystemParameter(
517            "persist_use_critical_since_source",
518            "false",  # always false, because we always have zero-downtime enabled
519            ["false"],
520        ),
521        # 0 disables; otherwise coalesce hydration frontier downgrades until
522        # this many encoded bytes have been emitted (1 MiB, 16 MiB, 128 MiB).
523        VariableSystemParameter(
524            "persist_source_hydration_frontier_coalesce_bytes",
525            "0",
526            ["0", "1048576", "16777216", "134217728"],
527        ),
528        VariableSystemParameter(
529            "persist_part_decode_format", "arrow", ["arrow", "row_with_validate"]
530        ),
531        VariableSystemParameter(
532            "persist_blob_cache_scale_with_threads", "true", ["true", "false"]
533        ),
534        persist_pg_consensus_read_committed,
535        VariableSystemParameter(
536            "persist_state_update_lease_timeout", "1s", ["0s", "1s", "10s"]
537        ),
538        VariableSystemParameter(
539            "arrangement_size_history_collection_interval", "1h", ["1s", "10s", "1h"]
540        ),
541        VariableSystemParameter(
542            "arrangement_size_history_retention_period", "7d", ["1min", "1h", "7d"]
543        ),
544        *(
545            [
546                VariableSystemParameter(
547                    "hydration_history_retention_period",
548                    "30d",
549                    ["1min", "1h", "30d"],
550                )
551            ]
552            if version >= MzVersion.parse_mz("v26.40.0-dev")
553            else []
554        ),
555        VariableSystemParameter(
556            "persist_validate_part_bounds_on_read", "false", ["true", "false"]
557        ),
558        VariableSystemParameter(
559            "persist_validate_part_bounds_on_write", "false", ["true", "false"]
560        ),
561        VariableSystemParameter(
562            "statement_logging_default_sample_rate",
563            "1.0",
564            ["0", "0.01", "0.5", "0.99", "1.0"],
565        ),
566        VariableSystemParameter(
567            "statement_logging_max_data_credit",
568            "",
569            ["", "0", "1024", "1048576", "1073741824"],
570        ),
571        VariableSystemParameter(
572            "statement_logging_max_sample_rate",
573            "1.0",
574            ["0", "0.01", "0.5", "0.99", "1.0"],
575        ),
576        VariableSystemParameter(
577            "statement_logging_target_data_rate",
578            "",
579            ["", "0", "1", "1000", "2071", "1000000"],
580        ),
581        VariableSystemParameter(
582            "storage_source_decode_fuel",
583            "100000",
584            ["10000", "100000", "1000000"],
585        ),
586        VariableSystemParameter(
587            "storage_statistics_collection_interval",
588            "1000",
589            ["100", "1000", "10000"],
590        ),
591        VariableSystemParameter(
592            "storage_statistics_interval", "2000", ["100", "1000", "10000"]
593        ),
594        VariableSystemParameter(
595            "storage_use_continual_feedback_upsert", "true", ["true", "false"]
596        ),
597        # End of list (ordered by name)
598    ]
599
600    if version < MzVersion.parse_mz("v26.14.0-dev"):
601        params.append(
602            VariableSystemParameter(
603                "storage_reclock_to_latest", "true", ["true", "false"]
604            )
605        )
606    if version < MzVersion.parse_mz("v26.23.0-dev"):
607        params.append(
608            VariableSystemParameter(
609                "persist_enable_arrow_lgalloc_noncc_sizes", "true", ["true", "false"]
610            )
611        )
612        params.append(
613            VariableSystemParameter(
614                "persist_enable_s3_lgalloc_noncc_sizes", "true", ["true", "false"]
615            )
616        )
617
618    return params

Note: Only the default is tested unless we explicitly select "System Parameters: Random" in trigger-ci. These defaults are applied _after_ applying the settings from get_minimal_system_parameters.

def get_default_system_parameters( version: materialize.mz_version.MzVersion | None = None, force_source_table_syntax: bool = False, metadata_store: str | None = None) -> dict[str, str]:
621def get_default_system_parameters(
622    version: MzVersion | None = None,
623    force_source_table_syntax: bool = False,
624    metadata_store: str | None = None,
625) -> dict[str, str]:
626    """For upgrade tests we only want parameters set when all environmentd /
627    clusterd processes have reached a specific version (or higher)
628
629    `metadata_store` selects backend-specific defaults. It defaults to the
630    globally configured metadata store, but callers that target a different
631    backend than the global (e.g. a local CockroachDB) must pass their own.
632    """
633
634    if not version:
635        version = MzVersion.parse_cargo()
636
637    if metadata_store is None:
638        from materialize.mzcompose.services.metadata_store import METADATA_STORE
639
640        metadata_store = METADATA_STORE
641
642    params = get_minimal_system_parameters(version)
643
644    system_param_setting = os.getenv("CI_SYSTEM_PARAMETERS", "")
645    variable_params = get_variable_system_parameters(
646        version, force_source_table_syntax, metadata_store
647    )
648
649    if system_param_setting == "":
650        for param in variable_params:
651            params[param.key] = param.default
652    elif system_param_setting == "random":
653        seed = os.getenv("CI_SYSTEM_PARAMETERS_SEED", os.getenv("BUILDKITE_JOB_ID", 1))
654        rng = random.Random(seed)
655        for param in variable_params:
656            params[param.key] = rng.choice(param.values)
657        print(
658            f"System parameters with seed CI_SYSTEM_PARAMETERS_SEED={seed}: {params}",
659            file=sys.stderr,
660        )
661    elif system_param_setting == "minimal":
662        pass
663    else:
664        raise ValueError(
665            f"Unknown value for CI_SYSTEM_PARAMETERS: {system_param_setting}"
666        )
667
668    return params

For upgrade tests we only want parameters set when all environmentd / clusterd processes have reached a specific version (or higher)

metadata_store selects backend-specific defaults. It defaults to the globally configured metadata store, but callers that target a different backend than the global (e.g. a local CockroachDB) must pass their own.

UNINTERESTING_SYSTEM_PARAMETERS = ['enable_compute_half_join2', 'enable_mz_join_core', 'linear_join_yielding', 'enable_column_paged_batcher', 'enable_column_paged_batcher_spill', 'column_chunk_compress_min_depth', 'column_paged_batcher_budget_fraction', 'column_paged_batcher_lz4', 'column_paged_batcher_swap_pageout', 'column_paged_batcher_spill_worker_count', 'column_paged_batcher_eager_backing', 'column_paged_batcher_pool_rss_target_fraction', 'enable_lgalloc_eager_reclamation', 'lgalloc_background_interval', 'lgalloc_file_growth_dampener', 'lgalloc_local_buffer_bytes', 'lgalloc_slow_clear_bytes', 'memory_limiter_interval', 'memory_limiter_usage_bias', 'memory_limiter_burst_factor', 'catalog_info_metrics_reconcile_interval', 'compute_server_maintenance_interval', 'compute_dataflow_max_inflight_bytes_cc', 'compute_flat_map_fuel', 'compute_temporal_bucketing_summary', 'consolidating_vec_growth_dampener', 'copy_to_s3_parquet_row_group_file_ratio', 'copy_to_s3_arrow_builder_buffer_ratio', 'copy_to_s3_multipart_part_size_bytes', 'enable_replica_targeted_materialized_views', 'compute_mv_sink_advance_persist_frontiers', 'compute_prometheus_introspection_scrape_interval', 'enable_compute_replica_expiration', 'compute_logical_backpressure_max_retained_capabilities', 'compute_logical_backpressure_inflight_slack', 'persist_fetch_semaphore_cost_adjustment', 'persist_fetch_semaphore_permit_adjustment', 'persist_optimize_ignored_data_fetch', 'persist_pubsub_same_process_delegate_enabled', 'persist_pubsub_connect_attempt_timeout', 'persist_pubsub_request_timeout', 'persist_pubsub_connect_max_backoff', 'persist_pubsub_client_sender_channel_size', 'persist_pubsub_client_receiver_channel_size', 'persist_pubsub_server_connection_channel_size', 'persist_pubsub_state_cache_shard_ref_channel_size', 'persist_pubsub_reconnect_backoff', 'persist_encoding_compression_format', 'persist_batch_max_runs', 'persist_write_combine_inline_writes', 'persist_reader_lease_duration', 'persist_consensus_connection_pool_max_size', 'persist_consensus_connection_pool_max_wait', 'persist_consensus_connection_pool_ttl', 'persist_consensus_connection_pool_ttl_stagger', 'persist_use_postgres_tuned_queries', 'crdb_connect_timeout', 'crdb_tcp_user_timeout', 'crdb_keepalives_idle', 'crdb_keepalives_interval', 'crdb_keepalives_retries', 'pg_timestamp_oracle_statement_timeout', 'persist_use_critical_since_txn', 'use_global_txn_cache_source', 'persist_batch_builder_max_outstanding_parts', 'persist_compaction_heuristic_min_inputs', 'persist_compaction_heuristic_min_parts', 'persist_compaction_heuristic_min_updates', 'persist_gc_blob_delete_concurrency_limit', 'persist_state_versions_recent_live_diffs_limit', 'persist_usage_state_fetch_concurrency_limit', 'persist_blob_operation_timeout', 'persist_blob_operation_attempt_timeout', 'persist_blob_connect_timeout', 'persist_blob_read_timeout', 'persist_blob_hedged_get_max_concurrent', 'persist_blob_hedged_get_warm_interval', 'persist_stats_collection_enabled', 'persist_stats_filter_enabled', 'persist_stats_budget_bytes', 'persist_stats_untrimmable_columns_equals', 'persist_stats_untrimmable_columns_prefix', 'persist_stats_untrimmable_columns_suffix', 'persist_expression_cache_force_compaction_fuel', 'persist_expression_cache_force_compaction_wait', 'persist_blob_cache_mem_limit_bytes', 'persist_blob_cache_scale_factor_bytes', 'persist_claim_unclaimed_compactions', 'persist_claim_compaction_percent', 'persist_claim_compaction_min_version', 'persist_next_listen_batch_retryer_multiplier', 'persist_rollup_threshold', 'persist_rollup_fallback_threshold_ms', 'persist_gc_fallback_threshold_ms', 'persist_compaction_minimum_timeout', 'persist_compaction_check_process_flag', 'balancerd_sigterm_connection_wait', 'balancerd_sigterm_listen_wait', 'balancerd_inject_proxy_protocol_header_http', 'balancerd_max_connections', 'balancerd_log_filter', 'balancerd_opentelemetry_filter', 'balancerd_log_filter_defaults', 'balancerd_opentelemetry_filter_defaults', 'balancerd_sentry_filters', 'persist_enable_s3_lgalloc_cc_sizes', 'persist_enable_arrow_lgalloc_cc_sizes', 'controller_past_generation_replica_cleanup_retry_interval', 'wallclock_lag_recording_interval', 'wallclock_lag_histogram_period_interval', 'enable_timely_zero_copy', 'enable_timely_zero_copy_lgalloc', 'timely_zero_copy_limit', 'arrangement_exert_proportionality', 'txn_wal_apply_ensure_schema_match', 'persist_txns_data_shard_retryer_initial_backoff', 'persist_txns_data_shard_retryer_multiplier', 'persist_txns_data_shard_retryer_clamp', 'storage_cluster_shutdown_grace_period', 'storage_dataflow_delay_sources_past_rehydration', 'storage_dataflow_suspendable_sources', 'storage_downgrade_since_during_finalization', 'replica_metrics_history_retention_interval', 'wallclock_lag_history_retention_interval', 'wallclock_global_lag_histogram_retention_interval', 'kafka_client_id_enrichment_rules', 'kafka_poll_max_wait', 'kafka_default_aws_privatelink_endpoint_identification_algorithm', 'kafka_buffered_event_resize_threshold_elements', 'kafka_low_watermark_check', 'mysql_replication_heartbeat_interval', 'mysql_source_snapshot_exact_count_max_rows', 'mysql_source_snapshot_partition_probed_prefixes_per_billion_rows', 'postgres_fetch_slot_resume_lsn_interval', 'pg_schema_validation_interval', 'pg_source_validate_timeline', 'sql_server_source_validate_restore_history', 'storage_enforce_external_addresses', 'storage_upsert_prevent_snapshot_buffering', 'storage_rocksdb_use_merge_operator', 'storage_upsert_max_snapshot_batch_buffering', 'storage_rocksdb_cleanup_tries', 'storage_suspend_and_restart_delay', 'storage_server_maintenance_interval', 'storage_sink_progress_search', 'storage_sink_ensure_topic_config', 'sql_server_max_lsn_wait', 'sql_server_snapshot_progress_report_interval', 'sql_server_cdc_cleanup_change_table', 'sql_server_cdc_cleanup_change_table_max_deletes', 'allow_user_sessions', 'group_commit_max_attempts', 'with_0dt_deployment_ddl_check_interval', 'enable_0dt_caught_up_check', 'with_0dt_caught_up_check_allowed_lag', 'with_0dt_caught_up_check_cutoff', 'enable_0dt_caught_up_replica_status_check', 'enable_0dt_caught_up_stability_check', 'enable_0dt_hydrate_migrated_builtin_mvs', 'plan_insights_notice_fast_path_clusters_optimize_duration', 'enable_expression_cache', 'mz_metrics_lgalloc_map_refresh_interval', 'mz_metrics_lgalloc_refresh_interval', 'mz_metrics_rusage_refresh_interval', 'mz_metrics_usage_refresh_interval', 'compute_peek_response_stash_batch_max_runs', 'compute_index_peek_inline_budget', 'compute_index_peek_activation_budget', 'compute_index_peek_yield_granularity', 'compute_index_peek_permit_fraction', 'compute_peek_response_stash_batch_bytes', 'compute_peek_response_stash_read_batch_size_bytes', 'compute_peek_response_stash_read_memory_budget_bytes', 'storage_statistics_retention_duration', 'enable_paused_cluster_readhold_downgrade', 'kafka_retry_backoff', 'kafka_retry_backoff_max', 'kafka_reconnect_backoff', 'kafka_reconnect_backoff_max', 'kafka_sink_message_max_bytes', 'kafka_sink_batch_size', 'kafka_sink_batch_num_messages', 'oidc_issuer', 'oidc_audience', 'oidc_authentication_claim', 'oidc_group_role_sync_enabled', 'oidc_group_claim', 'oidc_group_role_sync_strict', 'console_oidc_client_id', 'console_oidc_scopes', 'enable_public_metrics_endpoint', 'enable_mcp_agent', 'enable_mcp_agent_query_tool', 'enable_mcp_agent_read_data_product_tool', 'enable_mcp_developer', 'enable_mcp_developer_query_tool', 'mcp_max_response_size', 'mcp_request_timeout', 'user_id_pool_batch_size', 'webhook_max_request_size_bytes', 'webhook_validation_memory_budget_bytes', 'subscribe_max_buffered_bytes', 'cluster_controller_tick_interval', 'default_cluster_reconfiguration_timeout', 'read_then_write_max_dependencies', 'enable_hydration_burst', 'default_hydration_burst_linger']
DEFAULT_CRDB_ENVIRONMENT = ['COCKROACH_ENGINE_MAX_SYNC_DURATION_DEFAULT=120s', 'COCKROACH_LOG_MAX_SYNC_DURATION=120s']
DEFAULT_CLOUD_PROVIDER = 'mzcompose'
DEFAULT_CLOUD_REGION = 'us-east-1'
DEFAULT_ORG_ID = '00000000-0000-0000-0000-000000000000'
DEFAULT_ORDINAL = '0'
DEFAULT_MZ_ENVIRONMENT_ID = 'mzcompose-us-east-1-00000000-0000-0000-0000-000000000000-0'
def bootstrap_cluster_replica_size() -> str:
986def bootstrap_cluster_replica_size() -> str:
987    return "bootstrap"
def cluster_replica_size_map() -> dict[str, dict[str, typing.Any]]:
 990def cluster_replica_size_map() -> dict[str, dict[str, Any]]:
 991    """scale=<n>,workers=<n>[,mem=<n>GiB][,legacy]"""
 992
 993    def replica_size(
 994        scale: int,
 995        workers: int,
 996        disabled: bool = False,
 997        is_cc: bool = True,
 998        memory_limit: str = "4 GiB",
 999    ) -> dict[str, Any]:
1000        return {
1001            "cpu_exclusive": False,
1002            "cpu_limit": None,
1003            "credits_per_hour": f"{workers * scale}",
1004            "disabled": disabled,
1005            "disk_limit": None,
1006            "is_cc": is_cc,
1007            "memory_limit": memory_limit,
1008            "scale": scale,
1009            "workers": workers,
1010            # "selectors": {},
1011        }
1012
1013    replica_sizes = {
1014        bootstrap_cluster_replica_size(): replica_size(1, 1),
1015        "scale=2,workers=4": replica_size(2, 4),
1016        "scale=1,workers=1,legacy": replica_size(1, 1, is_cc=False),
1017        "scale=1,workers=2,legacy": replica_size(1, 2, is_cc=False),
1018        # Intentionally not following the naming scheme
1019        "free": replica_size(1, 1, disabled=True),
1020    }
1021
1022    for i in range(0, 6):
1023        workers = 1 << i
1024        replica_sizes[f"scale=1,workers={workers}"] = replica_size(1, workers)
1025        for mem in [4, 8, 16, 32]:
1026            replica_sizes[f"scale=1,workers={workers},mem={mem}GiB"] = replica_size(
1027                1, workers, memory_limit=f"{mem} GiB"
1028            )
1029
1030        replica_sizes[f"scale={workers},workers=1"] = replica_size(workers, 1)
1031        replica_sizes[f"scale={workers},workers={workers}"] = replica_size(
1032            workers, workers
1033        )
1034        replica_sizes[f"scale=1,workers={workers},mem={workers}GiB"] = replica_size(
1035            1, workers, memory_limit=f"{workers} GiB"
1036        )
1037
1038    return replica_sizes

scale=,workers=[,mem=GiB][,legacy]