From e97de9608d7f27f1445aa787ef25c8c046ae6425 Mon Sep 17 00:00:00 2001
From: Arthur Schreiber
Date: Tue, 13 Oct 2026 22:58:48 +0200
Subject: [PATCH 01/31] [release-23.0] Bump to `v23.0.9-SNAPSHOT` after the
`v23.0.8` release (#21564)
Signed-off-by: Arthur Schreiber
---
go/vt/servenv/version.go | 2 +-
java/client/pom.xml | 2 +-
java/example/pom.xml | 2 +-
java/grpc-client/pom.xml | 2 +-
java/jdbc/pom.xml | 2 +-
java/pom.xml | 2 +-
6 files changed, 6 insertions(+), 6 deletions(-)
diff --git a/go/vt/servenv/version.go b/go/vt/servenv/version.go
index 968147e8c92..e9ebf78d81e 100644
--- a/go/vt/servenv/version.go
+++ b/go/vt/servenv/version.go
@@ -19,4 +19,4 @@ package servenv
// DO NOT EDIT
// THIS FILE IS AUTO-GENERATED DURING NEW RELEASES BY THE VITESS-RELEASER
-const versionName = "23.0.8"
+const versionName = "23.0.9-SNAPSHOT"
diff --git a/java/client/pom.xml b/java/client/pom.xml
index 600efaea585..c16882174fe 100644
--- a/java/client/pom.xml
+++ b/java/client/pom.xml
@@ -5,7 +5,7 @@
io.vitess
vitess-parent
- 23.0.8
+ 23.0.9-SNAPSHOT
vitess-client
Vitess Java Client
diff --git a/java/example/pom.xml b/java/example/pom.xml
index 9dd76034c65..9919b59f3e0 100644
--- a/java/example/pom.xml
+++ b/java/example/pom.xml
@@ -5,7 +5,7 @@
io.vitess
vitess-parent
- 23.0.8
+ 23.0.9-SNAPSHOT
vitess-example
Vitess Java Client Example
diff --git a/java/grpc-client/pom.xml b/java/grpc-client/pom.xml
index d8fe7b45045..161ecd069ad 100644
--- a/java/grpc-client/pom.xml
+++ b/java/grpc-client/pom.xml
@@ -5,7 +5,7 @@
io.vitess
vitess-parent
- 23.0.8
+ 23.0.9-SNAPSHOT
vitess-grpc-client
Vitess gRPC Client
diff --git a/java/jdbc/pom.xml b/java/jdbc/pom.xml
index bfe5d2a0f97..e7e596ed903 100644
--- a/java/jdbc/pom.xml
+++ b/java/jdbc/pom.xml
@@ -5,7 +5,7 @@
io.vitess
vitess-parent
- 23.0.8
+ 23.0.9-SNAPSHOT
vitess-jdbc
Vitess JDBC Driver
diff --git a/java/pom.xml b/java/pom.xml
index 65fb73e2d97..e1136d92723 100644
--- a/java/pom.xml
+++ b/java/pom.xml
@@ -11,7 +11,7 @@
io.vitess
vitess-parent
- 23.0.8
+ 23.0.9-SNAPSHOT
pom
Vitess Java Client libraries [Parent]
From a637a511e54f678e9280f83fcc7927eb9608b1c6 Mon Sep 17 00:00:00 2001
From: "vitess-bot[bot]" <108069721+vitess-bot[bot]@users.noreply.github.com>
Date: Wed, 14 Oct 2026 12:33:42 +0200
Subject: [PATCH 02/31] [release-23.0] ci: export the bootstrap BuildKit cache
from one job on main and release branches only (#21009) (#21582)
Signed-off-by: Arthur Schreiber
Co-authored-by: vitess-bot[bot] <108069721+vitess-bot[bot]@users.noreply.github.com>
Co-authored-by: Claude Fable 5.1
---
.github/actions/build-bootstrap/action.yml | 6 +++++-
.github/workflows/docker_ci.yml | 1 +
2 files changed, 6 insertions(+), 1 deletion(-)
diff --git a/.github/actions/build-bootstrap/action.yml b/.github/actions/build-bootstrap/action.yml
index 826063ff570..ca4a2193093 100644
--- a/.github/actions/build-bootstrap/action.yml
+++ b/.github/actions/build-bootstrap/action.yml
@@ -10,6 +10,10 @@ inputs:
description: "Bootstrap image flavor (e.g. mysql84)"
required: false
default: "mysql84"
+ cache-export:
+ description: "Export the build cache to the GitHub Actions cache. Only one job per push should do this, and only on branches whose cache other builds can read (main and release branches)."
+ required: false
+ default: "false"
runs:
using: "composite"
@@ -24,7 +28,7 @@ runs:
load: true
set: |
*.cache-from=type=gha,scope=bootstrap
- *.cache-to=type=gha,scope=bootstrap,mode=max
+ ${{ inputs.cache-export == 'true' && '*.cache-to=type=gha,scope=bootstrap,mode=max' || '' }}
env:
BOOTSTRAP_VERSION: ${{ inputs.bootstrap-version }}
BOOTSTRAP_FLAVOR: ${{ inputs.bootstrap-flavor }}
diff --git a/.github/workflows/docker_ci.yml b/.github/workflows/docker_ci.yml
index d2c07c7ef4b..456c16e1648 100644
--- a/.github/workflows/docker_ci.yml
+++ b/.github/workflows/docker_ci.yml
@@ -77,6 +77,7 @@ jobs:
with:
bootstrap-version: ${{ env.BOOTSTRAP_VERSION }}
bootstrap-flavor: ${{ env.BOOTSTRAP_FLAVOR }}
+ cache-export: ${{ matrix.shard == 'java' && (github.ref == 'refs/heads/main' || startsWith(github.ref, 'refs/heads/release-')) }}
- name: Set up Go
if: steps.changes.outputs.end_to_end == 'true'
From 1a1ab7565a0f3c9878518cd5e2672d03c1bc8558 Mon Sep 17 00:00:00 2001
From: Arthur Schreiber
Date: Wed, 14 Oct 2026 12:37:17 +0200
Subject: [PATCH 03/31] [release-23.0] Bump Go dependencies with known
vulnerabilities (#21571)
Signed-off-by: Arthur Schreiber
Co-authored-by: Claude Opus 5.5
---
go.mod | 190 +++----
go.sum | 484 +++++++++---------
go/vt/proto/binlogdata/binlogdata.pb.go | 2 +-
go/vt/proto/binlogservice/binlogservice.pb.go | 2 +-
go/vt/proto/logutil/logutil.pb.go | 2 +-
go/vt/proto/mysqlctl/mysqlctl.pb.go | 2 +-
go/vt/proto/query/query.pb.go | 2 +-
go/vt/proto/queryservice/queryservice.pb.go | 2 +-
.../replicationdata/replicationdata.pb.go | 2 +-
go/vt/proto/tableacl/tableacl.pb.go | 2 +-
.../tabletmanagerdata/tabletmanagerdata.pb.go | 2 +-
.../tabletmanagerservice.pb.go | 2 +-
go/vt/proto/throttlerdata/throttlerdata.pb.go | 2 +-
.../throttlerservice/throttlerservice.pb.go | 2 +-
go/vt/proto/topodata/topodata.pb.go | 2 +-
go/vt/proto/vschema/vschema.pb.go | 2 +-
go/vt/proto/vtadmin/vtadmin.pb.go | 2 +-
go/vt/proto/vtctldata/vtctldata.pb.go | 2 +-
go/vt/proto/vtctlservice/vtctlservice.pb.go | 2 +-
go/vt/proto/vtgate/vtgate.pb.go | 2 +-
go/vt/proto/vtgateservice/vtgateservice.pb.go | 2 +-
go/vt/proto/vtorcdata/vtorcdata.pb.go | 2 +-
go/vt/proto/vtrpc/vtrpc.pb.go | 2 +-
go/vt/proto/vttest/vttest.pb.go | 2 +-
go/vt/proto/vttime/vttime.pb.go | 2 +-
25 files changed, 371 insertions(+), 349 deletions(-)
diff --git a/go.mod b/go.mod
index 86319b68bc9..5d2ff47dcd7 100644
--- a/go.mod
+++ b/go.mod
@@ -23,7 +23,7 @@ require (
github.com/evanphx/json-patch v5.9.11+incompatible
github.com/fsnotify/fsnotify v1.9.0
github.com/go-sql-driver/mysql v1.7.1
- github.com/go-viper/mapstructure/v2 v2.4.0
+ github.com/go-viper/mapstructure/v2 v2.5.0
github.com/golang/glog v1.2.5
github.com/golang/protobuf v1.5.4 // indirect
github.com/golang/snappy v1.0.0
@@ -38,7 +38,7 @@ require (
github.com/hashicorp/go-immutable-radix v1.3.1 // indirect
github.com/hashicorp/serf v0.10.2 // indirect
github.com/icrowley/fake v0.0.0-20180203215853-4178557ae428
- github.com/klauspost/compress v1.18.0
+ github.com/klauspost/compress v1.18.4
github.com/klauspost/pgzip v1.2.6
github.com/krishicks/yaml-patch v0.0.10
github.com/minio/minio-go v0.0.0-20190131015406-c8a261de75c1
@@ -53,16 +53,16 @@ require (
github.com/planetscale/pargzip v0.0.0-20201116224723-90c7fc03ea8a
github.com/planetscale/vtprotobuf v0.6.1-0.20250313105119-ba97887b0a25
github.com/prometheus/client_golang v1.23.2
- github.com/prometheus/common v0.66.1
+ github.com/prometheus/common v0.67.5
github.com/sjmudd/stopwatch v0.1.1
github.com/soheilhy/cmux v0.1.5
- github.com/spf13/cobra v1.10.1
+ github.com/spf13/cobra v1.10.2
github.com/spf13/pflag v1.0.10
github.com/spf13/viper v1.21.0
github.com/stretchr/testify v1.11.1
github.com/tchap/go-patricia v2.3.0+incompatible
github.com/tidwall/gjson v1.18.0
- github.com/tinylib/msgp v1.4.0 // indirect
+ github.com/tinylib/msgp v1.6.3 // indirect
github.com/uber/jaeger-client-go v2.30.0+incompatible
github.com/uber/jaeger-lib v2.4.1+incompatible // indirect
github.com/yudai/golcs v0.0.0-20170316035057-ecda9a501e82
@@ -70,67 +70,72 @@ require (
go.etcd.io/etcd/api/v3 v3.5.25
go.etcd.io/etcd/client/pkg/v3 v3.5.25
go.etcd.io/etcd/client/v3 v3.5.25
- go.uber.org/mock v0.5.0
- golang.org/x/crypto v0.45.0 // indirect
- golang.org/x/mod v0.30.0 // indirect
- golang.org/x/net v0.47.0
- golang.org/x/oauth2 v0.33.0
- golang.org/x/sys v0.38.0
- golang.org/x/term v0.37.0
- golang.org/x/text v0.31.0 // indirect
- golang.org/x/time v0.13.0
- golang.org/x/tools v0.39.0
- google.golang.org/api v0.251.0
- google.golang.org/genproto v0.0.0-20250929231259-57b25ae835d4 // indirect
- google.golang.org/grpc v1.75.1
+ go.uber.org/mock v0.6.0
+ golang.org/x/crypto v0.55.0 // indirect
+ golang.org/x/mod v0.38.0 // indirect
+ golang.org/x/net v0.58.0
+ golang.org/x/oauth2 v0.36.0
+ golang.org/x/sys v0.47.0
+ golang.org/x/term v0.45.0
+ golang.org/x/text v0.41.0 // indirect
+ golang.org/x/time v0.15.0
+ golang.org/x/tools v0.48.0
+ google.golang.org/api v0.264.0
+ google.golang.org/genproto v0.0.0-20260128011058-8636f8732409 // indirect
+ google.golang.org/grpc v1.83.2
google.golang.org/grpc/examples v0.0.0-20250407062114-b368379ef8f6
- google.golang.org/protobuf v1.36.9
- gopkg.in/DataDog/dd-trace-go.v1 v1.74.6
+ google.golang.org/protobuf v1.36.11
+ gopkg.in/DataDog/dd-trace-go.v1 v1.74.8
gopkg.in/asn1-ber.v1 v1.0.0-20181015200546-f715ec2f112d // indirect
gopkg.in/ldap.v2 v2.5.1
sigs.k8s.io/yaml v1.6.0
)
require (
- github.com/DataDog/datadog-go/v5 v5.8.0
+ github.com/DataDog/datadog-go/v5 v5.8.3
github.com/Shopify/toxiproxy/v2 v2.12.0
- github.com/aws/aws-sdk-go-v2 v1.39.2
+ github.com/aws/aws-sdk-go-v2 v1.41.5
github.com/aws/aws-sdk-go-v2/config v1.31.12
github.com/aws/aws-sdk-go-v2/feature/s3/manager v1.19.10
- github.com/aws/aws-sdk-go-v2/service/s3 v1.88.3
- github.com/aws/smithy-go v1.23.0
+ github.com/aws/aws-sdk-go-v2/service/s3 v1.97.3
+ github.com/aws/smithy-go v1.24.2
github.com/bndr/gotabulate v1.1.2
github.com/dustin/go-humanize v1.0.1
github.com/gammazero/deque v1.1.0
github.com/google/go-containerregistry v0.20.6
github.com/google/safehtml v0.1.0
- github.com/hashicorp/go-version v1.7.0
+ github.com/hashicorp/go-version v1.8.0
github.com/kr/pretty v0.3.1
github.com/kr/text v0.2.0
github.com/nsf/jsondiff v0.0.0-20210926074059-1e845ec5d249
- github.com/shirou/gopsutil/v4 v4.25.8
+ github.com/shirou/gopsutil/v4 v4.26.2
github.com/spf13/afero v1.15.0
github.com/spf13/jwalterweatherman v1.1.0
github.com/xlab/treeprint v1.2.0
go.uber.org/goleak v1.3.0
- golang.org/x/exp v0.0.0-20250911091902-df9299821621
- golang.org/x/sync v0.18.0
- gonum.org/v1/gonum v0.16.0
+ golang.org/x/exp v0.0.0-20260209203927-2842357ff358
+ golang.org/x/sync v0.22.0
+ gonum.org/v1/gonum v0.17.0
modernc.org/sqlite v1.39.0
)
require (
- github.com/DataDog/datadog-agent/comp/core/tagger/origindetection v0.70.2 // indirect
- github.com/DataDog/datadog-agent/pkg/proto v0.70.2 // indirect
- github.com/DataDog/datadog-agent/pkg/trace v0.70.2 // indirect
- github.com/DataDog/datadog-agent/pkg/util/log v0.70.2 // indirect
- github.com/DataDog/datadog-agent/pkg/util/scrubber v0.70.2 // indirect
- github.com/DataDog/datadog-agent/pkg/version v0.70.2 // indirect
- github.com/DataDog/dd-trace-go/v2 v2.2.3 // indirect
- github.com/DataDog/go-libddwaf/v4 v4.5.0 // indirect
- github.com/DataDog/go-runtime-metrics-internal v0.0.4-0.20250721125240-fdf1ef85b633 // indirect
- github.com/DataDog/opentelemetry-mapping-go/pkg/otlp/attributes v0.29.1 // indirect
- github.com/Masterminds/semver/v3 v3.4.0 // indirect
+ github.com/DataDog/datadog-agent/comp/core/tagger/origindetection v0.77.0 // indirect
+ github.com/DataDog/datadog-agent/pkg/opentelemetry-mapping-go/otlp/attributes v0.77.0 // indirect
+ github.com/DataDog/datadog-agent/pkg/proto v0.77.0 // indirect
+ github.com/DataDog/datadog-agent/pkg/template v0.77.0 // indirect
+ github.com/DataDog/datadog-agent/pkg/trace v0.77.0 // indirect
+ github.com/DataDog/datadog-agent/pkg/trace/log v0.77.0 // indirect
+ github.com/DataDog/datadog-agent/pkg/trace/otel v0.77.0 // indirect
+ github.com/DataDog/datadog-agent/pkg/trace/stats v0.77.0 // indirect
+ github.com/DataDog/datadog-agent/pkg/trace/traceutil v0.77.0 // indirect
+ github.com/DataDog/datadog-agent/pkg/util/log v0.77.0 // indirect
+ github.com/DataDog/datadog-agent/pkg/util/scrubber v0.77.0 // indirect
+ github.com/DataDog/datadog-agent/pkg/version v0.77.0 // indirect
+ github.com/DataDog/dd-trace-go/v2 v2.8.2 // indirect
+ github.com/DataDog/go-libddwaf/v4 v4.9.0 // indirect
+ github.com/DataDog/go-runtime-metrics-internal v0.0.4-0.20260217080614-b0f4edc38a6d // indirect
+ github.com/cenkalti/backoff/v5 v5.0.3 // indirect
github.com/cihub/seelog v0.0.0-20170130134532-f561c5e57575 // indirect
github.com/cilium/ebpf v0.19.0 // indirect
github.com/clipperhouse/uax29/v2 v2.2.0 // indirect
@@ -144,6 +149,9 @@ require (
github.com/google/btree v1.1.3 // indirect
github.com/google/pprof v0.0.0-20250820193118-f64d9cf942d6 // indirect
github.com/json-iterator/go v1.1.12 // indirect
+ github.com/klauspost/cpuid/v2 v2.3.0 // indirect
+ github.com/linkdata/deadlock v0.5.5 // indirect
+ github.com/minio/simdjson-go v0.4.5 // indirect
github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd // indirect
github.com/modern-go/reflect2 v1.0.3-0.20250322232337-35a7c28c31ee // indirect
github.com/olekukonko/cat v0.0.0-20250911104152-50322a0618f6 // indirect
@@ -152,75 +160,73 @@ require (
github.com/opencontainers/go-digest v1.0.0 // indirect
github.com/opencontainers/image-spec v1.1.1 // indirect
github.com/opencontainers/runtime-spec v1.2.1 // indirect
+ github.com/petermattis/goid v0.0.0-20260226131333-17d1149c6ac6 // indirect
github.com/puzpuzpuz/xsync/v3 v3.5.1 // indirect
github.com/sirupsen/logrus v1.9.3 // indirect
+ github.com/trailofbits/go-mutexasserts v0.0.0-20250514102930-c1f3d2e37561 // indirect
github.com/vbatts/tar-split v0.12.2 // indirect
- go.opentelemetry.io/collector/component v1.42.0 // indirect
- go.opentelemetry.io/collector/featuregate v1.42.0 // indirect
- go.opentelemetry.io/collector/internal/telemetry v0.136.0 // indirect
- go.opentelemetry.io/collector/pdata v1.42.0 // indirect
- go.opentelemetry.io/contrib/bridges/otelzap v0.13.0 // indirect
- go.opentelemetry.io/otel/log v0.14.0 // indirect
+ go.opentelemetry.io/collector/component v1.51.1-0.20260205185216-81bc641f26c0 // indirect
+ go.opentelemetry.io/collector/featuregate v1.51.1-0.20260205185216-81bc641f26c0 // indirect
+ go.opentelemetry.io/collector/pdata v1.51.1-0.20260205185216-81bc641f26c0 // indirect
+ go.opentelemetry.io/collector/pdata/pprofile v0.145.1-0.20260205185216-81bc641f26c0 // indirect
+ go.opentelemetry.io/proto/otlp v1.9.0 // indirect
go.yaml.in/yaml/v2 v2.4.3 // indirect
go.yaml.in/yaml/v3 v3.0.4 // indirect
google.golang.org/grpc/cmd/protoc-gen-go-grpc v1.2.0 // indirect
- k8s.io/apimachinery v0.33.4 // indirect
)
require (
- cel.dev/expr v0.24.0 // indirect
+ cel.dev/expr v0.25.2 // indirect
cloud.google.com/go v0.123.0 // indirect
- cloud.google.com/go/auth v0.16.5 // indirect
+ cloud.google.com/go/auth v0.18.2 // indirect
cloud.google.com/go/auth/oauth2adapt v0.2.8 // indirect
cloud.google.com/go/compute/metadata v0.9.0 // indirect
- cloud.google.com/go/iam v1.5.2 // indirect
- cloud.google.com/go/monitoring v1.24.2 // indirect
- github.com/DataDog/appsec-internal-go v1.14.0 // indirect
- github.com/DataDog/datadog-agent/pkg/obfuscate v0.70.2 // indirect
- github.com/DataDog/datadog-agent/pkg/remoteconfig/state v0.70.2 // indirect
- github.com/DataDog/go-sqllexer v0.1.8 // indirect
+ cloud.google.com/go/iam v1.5.3 // indirect
+ cloud.google.com/go/monitoring v1.24.3 // indirect
+ github.com/DataDog/datadog-agent/pkg/obfuscate v0.77.0 // indirect
+ github.com/DataDog/datadog-agent/pkg/remoteconfig/state v0.77.0 // indirect
+ github.com/DataDog/go-sqllexer v0.1.13 // indirect
github.com/DataDog/go-tuf v1.1.1-0.5.2 // indirect
- github.com/DataDog/sketches-go v1.4.7 // indirect
- github.com/GoogleCloudPlatform/opentelemetry-operations-go/detectors/gcp v1.30.0 // indirect
+ github.com/DataDog/sketches-go v1.4.8 // indirect
+ github.com/GoogleCloudPlatform/opentelemetry-operations-go/detectors/gcp v1.33.0 // indirect
github.com/GoogleCloudPlatform/opentelemetry-operations-go/exporter/metric v0.54.0 // indirect
github.com/GoogleCloudPlatform/opentelemetry-operations-go/internal/resourcemapping v0.54.0 // indirect
github.com/Microsoft/go-winio v0.6.2 // indirect
- github.com/aws/aws-sdk-go-v2/aws/protocol/eventstream v1.7.1 // indirect
+ github.com/aws/aws-sdk-go-v2/aws/protocol/eventstream v1.7.8 // indirect
github.com/aws/aws-sdk-go-v2/credentials v1.18.16 // indirect
github.com/aws/aws-sdk-go-v2/feature/ec2/imds v1.18.9 // indirect
- github.com/aws/aws-sdk-go-v2/internal/configsources v1.4.9 // indirect
- github.com/aws/aws-sdk-go-v2/internal/endpoints/v2 v2.7.9 // indirect
+ github.com/aws/aws-sdk-go-v2/internal/configsources v1.4.21 // indirect
+ github.com/aws/aws-sdk-go-v2/internal/endpoints/v2 v2.7.21 // indirect
github.com/aws/aws-sdk-go-v2/internal/ini v1.8.3 // indirect
- github.com/aws/aws-sdk-go-v2/internal/v4a v1.4.9 // indirect
- github.com/aws/aws-sdk-go-v2/service/internal/accept-encoding v1.13.1 // indirect
- github.com/aws/aws-sdk-go-v2/service/internal/checksum v1.8.9 // indirect
- github.com/aws/aws-sdk-go-v2/service/internal/presigned-url v1.13.9 // indirect
- github.com/aws/aws-sdk-go-v2/service/internal/s3shared v1.19.9 // indirect
+ github.com/aws/aws-sdk-go-v2/internal/v4a v1.4.22 // indirect
+ github.com/aws/aws-sdk-go-v2/service/internal/accept-encoding v1.13.7 // indirect
+ github.com/aws/aws-sdk-go-v2/service/internal/checksum v1.9.13 // indirect
+ github.com/aws/aws-sdk-go-v2/service/internal/presigned-url v1.13.21 // indirect
+ github.com/aws/aws-sdk-go-v2/service/internal/s3shared v1.19.21 // indirect
github.com/aws/aws-sdk-go-v2/service/sso v1.29.6 // indirect
github.com/aws/aws-sdk-go-v2/service/ssooidc v1.35.1 // indirect
github.com/aws/aws-sdk-go-v2/service/sts v1.38.6 // indirect
github.com/beorn7/perks v1.0.1 // indirect
- github.com/cncf/xds/go v0.0.0-20250501225837-2ac532fd4443 // indirect
+ github.com/cncf/xds/go v0.0.0-20260202195803-dba9d589def2 // indirect
github.com/containerd/cgroups v1.1.0
github.com/containerd/cgroups/v3 v3.0.5
github.com/coreos/go-semver v0.3.1 // indirect
github.com/coreos/go-systemd/v22 v22.6.0 // indirect
github.com/cpuguy83/go-md2man/v2 v2.0.7 // indirect
github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc // indirect
- github.com/eapache/queue/v2 v2.0.0-20230407133247-75960ed334e4 // indirect
- github.com/ebitengine/purego v0.9.0 // indirect
- github.com/envoyproxy/go-control-plane/envoy v1.35.0 // indirect
- github.com/envoyproxy/protoc-gen-validate v1.2.1 // indirect
+ github.com/ebitengine/purego v0.10.0 // indirect
+ github.com/envoyproxy/go-control-plane/envoy v1.37.0 // indirect
+ github.com/envoyproxy/protoc-gen-validate v1.3.3 // indirect
github.com/fatih/color v1.18.0 // indirect
github.com/felixge/httpsnoop v1.0.4 // indirect
- github.com/go-jose/go-jose/v4 v4.1.2 // indirect
- github.com/go-logr/logr v1.4.3 // indirect
+ github.com/go-jose/go-jose/v4 v4.1.5 // indirect
+ github.com/go-logr/logr v1.4.4 // indirect
github.com/go-logr/stdr v1.2.2 // indirect
github.com/go-ole/go-ole v1.3.0 // indirect
github.com/gogo/protobuf v1.3.2 // indirect
github.com/google/s2a-go v0.1.9 // indirect
- github.com/googleapis/enterprise-certificate-proxy v0.3.6 // indirect
- github.com/googleapis/gax-go/v2 v2.15.0 // indirect
+ github.com/googleapis/enterprise-certificate-proxy v0.3.11 // indirect
+ github.com/googleapis/gax-go/v2 v2.17.0 // indirect
github.com/hashicorp/errwrap v1.1.0 // indirect
github.com/hashicorp/go-cleanhttp v0.5.2 // indirect
github.com/hashicorp/go-hclog v1.6.3 // indirect
@@ -229,7 +235,7 @@ require (
github.com/hashicorp/go-rootcerts v1.0.2 // indirect
github.com/hashicorp/golang-lru v1.0.2 // indirect
github.com/inconshreveable/mousetrap v1.1.0 // indirect
- github.com/lufia/plan9stats v0.0.0-20250827001030-24949be3fa54 // indirect
+ github.com/lufia/plan9stats v0.0.0-20260216142805-b3301c5f2a88 // indirect
github.com/mattn/go-colorable v0.1.14 // indirect
github.com/mattn/go-ieproxy v0.0.12 // indirect
github.com/mattn/go-isatty v0.0.20 // indirect
@@ -238,43 +244,43 @@ require (
github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822 // indirect
github.com/ncruces/go-strftime v0.1.9 // indirect
github.com/onsi/ginkgo v1.16.5 // indirect
- github.com/onsi/gomega v1.36.2 // indirect
+ github.com/onsi/gomega v1.38.2 // indirect
github.com/outcaste-io/ristretto v0.2.3 // indirect
github.com/pelletier/go-toml/v2 v2.2.4 // indirect
github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2 // indirect
github.com/power-devops/perfstat v0.0.0-20240221224432-82ca36839d55 // indirect
github.com/prometheus/client_model v0.6.2 // indirect
- github.com/prometheus/procfs v0.17.0 // indirect
+ github.com/prometheus/procfs v0.19.2 // indirect
github.com/remyoudompheng/bigfft v0.0.0-20230129092748-24d4a6f8daec // indirect
github.com/rivo/uniseg v0.4.7 // indirect
github.com/rogpeppe/go-internal v1.14.1 // indirect
github.com/russross/blackfriday/v2 v2.1.0 // indirect
github.com/sagikazarmark/locafero v0.12.0 // indirect
- github.com/secure-systems-lab/go-securesystemslib v0.9.1 // indirect
+ github.com/secure-systems-lab/go-securesystemslib v0.10.0 // indirect
github.com/spf13/cast v1.10.0 // indirect
- github.com/spiffe/go-spiffe/v2 v2.6.0 // indirect
+ github.com/spiffe/go-spiffe/v2 v2.7.0 // indirect
github.com/subosito/gotenv v1.6.0 // indirect
github.com/tidwall/match v1.2.0 // indirect
github.com/tidwall/pretty v1.2.1 // indirect
- github.com/tklauser/go-sysconf v0.3.15 // indirect
- github.com/tklauser/numcpus v0.10.0 // indirect
+ github.com/tklauser/go-sysconf v0.3.16 // indirect
+ github.com/tklauser/numcpus v0.11.0 // indirect
github.com/yusufpapurcu/wmi v1.2.4 // indirect
go.opentelemetry.io/auto/sdk v1.2.1 // indirect
- go.opentelemetry.io/contrib/detectors/gcp v1.38.0 // indirect
+ go.opentelemetry.io/contrib/detectors/gcp v1.44.0 // indirect
go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc v0.63.0 // indirect
- go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.63.0 // indirect
- go.opentelemetry.io/otel v1.38.0 // indirect
- go.opentelemetry.io/otel/metric v1.38.0 // indirect
- go.opentelemetry.io/otel/sdk v1.38.0 // indirect
- go.opentelemetry.io/otel/sdk/metric v1.38.0 // indirect
- go.opentelemetry.io/otel/trace v1.38.0 // indirect
+ go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.64.0 // indirect
+ go.opentelemetry.io/otel v1.45.0 // indirect
+ go.opentelemetry.io/otel/metric v1.45.0 // indirect
+ go.opentelemetry.io/otel/sdk v1.45.0 // indirect
+ go.opentelemetry.io/otel/sdk/metric v1.45.0 // indirect
+ go.opentelemetry.io/otel/trace v1.45.0 // indirect
go.uber.org/atomic v1.11.0 // indirect
go.uber.org/multierr v1.11.0 // indirect
- go.uber.org/zap v1.27.0 // indirect
+ go.uber.org/zap v1.27.1 // indirect
golang.org/x/xerrors v0.0.0-20240903120638-7835f813f4da // indirect
- google.golang.org/genproto/googleapis/api v0.0.0-20250929231259-57b25ae835d4 // indirect
- google.golang.org/genproto/googleapis/rpc v0.0.0-20250929231259-57b25ae835d4 // indirect
- gopkg.in/ini.v1 v1.67.0 // indirect
+ google.golang.org/genproto/googleapis/api v0.0.0-20260526163538-3dc84a4a5aaa // indirect
+ google.golang.org/genproto/googleapis/rpc v0.0.0-20260526163538-3dc84a4a5aaa // indirect
+ gopkg.in/ini.v1 v1.67.1 // indirect
gopkg.in/yaml.v2 v2.4.0 // indirect
gopkg.in/yaml.v3 v3.0.1 // indirect
modernc.org/libc v1.66.10 // indirect
diff --git a/go.sum b/go.sum
index 0f00ce02eee..2688fd598b9 100644
--- a/go.sum
+++ b/go.sum
@@ -1,27 +1,27 @@
-cel.dev/expr v0.24.0 h1:56OvJKSH3hDGL0ml5uSxZmz3/3Pq4tJ+fb1unVLAFcY=
-cel.dev/expr v0.24.0/go.mod h1:hLPLo1W4QUmuYdA72RBX06QTs6MXw941piREPl3Yfiw=
+cel.dev/expr v0.25.2 h1:K6j46C81hXtZQfuX60cVWQFBJahKSE2gfRbNuvr5bFs=
+cel.dev/expr v0.25.2/go.mod h1:hrXvqGP6G6gyx8UAHSHJ5RGk//1Oj5nXQ2NI02Nrsg4=
cloud.google.com/go v0.26.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw=
cloud.google.com/go v0.34.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw=
cloud.google.com/go v0.123.0 h1:2NAUJwPR47q+E35uaJeYoNhuNEM9kM8SjgRgdeOJUSE=
cloud.google.com/go v0.123.0/go.mod h1:xBoMV08QcqUGuPW65Qfm1o9Y4zKZBpGS+7bImXLTAZU=
-cloud.google.com/go/auth v0.16.5 h1:mFWNQ2FEVWAliEQWpAdH80omXFokmrnbDhUS9cBywsI=
-cloud.google.com/go/auth v0.16.5/go.mod h1:utzRfHMP+Vv0mpOkTRQoWD2q3BatTOoWbA7gCc2dUhQ=
+cloud.google.com/go/auth v0.18.2 h1:+Nbt5Ev0xEqxlNjd6c+yYUeosQ5TtEUaNcN/3FozlaM=
+cloud.google.com/go/auth v0.18.2/go.mod h1:xD+oY7gcahcu7G2SG2DsBerfFxgPAJz17zz2joOFF3M=
cloud.google.com/go/auth/oauth2adapt v0.2.8 h1:keo8NaayQZ6wimpNSmW5OPc283g65QNIiLpZnkHRbnc=
cloud.google.com/go/auth/oauth2adapt v0.2.8/go.mod h1:XQ9y31RkqZCcwJWNSx2Xvric3RrU88hAYYbjDWYDL+c=
cloud.google.com/go/compute/metadata v0.9.0 h1:pDUj4QMoPejqq20dK0Pg2N4yG9zIkYGdBtwLoEkH9Zs=
cloud.google.com/go/compute/metadata v0.9.0/go.mod h1:E0bWwX5wTnLPedCKqk3pJmVgCBSM6qQI1yTBdEb3C10=
-cloud.google.com/go/iam v1.5.2 h1:qgFRAGEmd8z6dJ/qyEchAuL9jpswyODjA2lS+w234g8=
-cloud.google.com/go/iam v1.5.2/go.mod h1:SE1vg0N81zQqLzQEwxL2WI6yhetBdbNQuTvIKCSkUHE=
-cloud.google.com/go/logging v1.13.0 h1:7j0HgAp0B94o1YRDqiqm26w4q1rDMH7XNRU34lJXHYc=
-cloud.google.com/go/logging v1.13.0/go.mod h1:36CoKh6KA/M0PbhPKMq6/qety2DCAErbhXT62TuXALA=
-cloud.google.com/go/longrunning v0.6.7 h1:IGtfDWHhQCgCjwQjV9iiLnUta9LBCo8R9QmAFsS/PrE=
-cloud.google.com/go/longrunning v0.6.7/go.mod h1:EAFV3IZAKmM56TyiE6VAP3VoTzhZzySwI/YI1s/nRsY=
-cloud.google.com/go/monitoring v1.24.2 h1:5OTsoJ1dXYIiMiuL+sYscLc9BumrL3CarVLL7dd7lHM=
-cloud.google.com/go/monitoring v1.24.2/go.mod h1:x7yzPWcgDRnPEv3sI+jJGBkwl5qINf+6qY4eq0I9B4U=
+cloud.google.com/go/iam v1.5.3 h1:+vMINPiDF2ognBJ97ABAYYwRgsaqxPbQDlMnbHMjolc=
+cloud.google.com/go/iam v1.5.3/go.mod h1:MR3v9oLkZCTlaqljW6Eb2d3HGDGK5/bDv93jhfISFvU=
+cloud.google.com/go/logging v1.13.1 h1:O7LvmO0kGLaHY/gq8cV7T0dyp6zJhYAOtZPX4TF3QtY=
+cloud.google.com/go/logging v1.13.1/go.mod h1:XAQkfkMBxQRjQek96WLPNze7vsOmay9H5PqfsNYDqvw=
+cloud.google.com/go/longrunning v0.8.0 h1:LiKK77J3bx5gDLi4SMViHixjD2ohlkwBi+mKA7EhfW8=
+cloud.google.com/go/longrunning v0.8.0/go.mod h1:UmErU2Onzi+fKDg2gR7dusz11Pe26aknR4kHmJJqIfk=
+cloud.google.com/go/monitoring v1.24.3 h1:dde+gMNc0UhPZD1Azu6at2e79bfdztVDS5lvhOdsgaE=
+cloud.google.com/go/monitoring v1.24.3/go.mod h1:nYP6W0tm3N9H/bOw8am7t62YTzZY+zUeQ+Bi6+2eonI=
cloud.google.com/go/storage v1.57.0 h1:4g7NB7Ta7KetVbOMpCqy89C+Vg5VE8scqlSHUPm7Rds=
cloud.google.com/go/storage v1.57.0/go.mod h1:329cwlpzALLgJuu8beyJ/uvQznDHpa2U5lGjWednkzg=
-cloud.google.com/go/trace v1.11.6 h1:2O2zjPzqPYAHrn3OKl029qlqG6W8ZdYaOWRyr8NgMT4=
-cloud.google.com/go/trace v1.11.6/go.mod h1:GA855OeDEBiBMzcckLPE2kDunIpC72N+Pq8WFieFjnI=
+cloud.google.com/go/trace v1.11.7 h1:kDNDX8JkaAG3R2nq1lIdkb7FCSi1rCmsEtKVsty7p+U=
+cloud.google.com/go/trace v1.11.7/go.mod h1:TNn9d5V3fQVf6s4SCveVMIBS2LJUqo73GACmq/Tky0s=
github.com/AdaLogics/go-fuzz-headers v0.0.0-20240806141605-e8a1dd7889d6 h1:He8afgbRMd7mFxO99hRNu+6tazq8nFF9lIwo9JFroBk=
github.com/AdaLogics/go-fuzz-headers v0.0.0-20240806141605-e8a1dd7889d6/go.mod h1:8o94RPi1/7XTJvwPpRSzSUedZrtlirdB3r9Z20bi2f8=
github.com/Azure/azure-pipeline-go v0.2.3 h1:7U9HBg1JFK3jHl5qmo4CTZKFTVgMwdFHMVtCdfBE21U=
@@ -40,45 +40,51 @@ github.com/Azure/go-autorest/logger v0.2.1/go.mod h1:T9E3cAhj2VqvPOtCYAvby9aBXkZ
github.com/Azure/go-autorest/tracing v0.6.0 h1:TYi4+3m5t6K48TGI9AUdb+IzbnSxvnvUMfuitfgcfuo=
github.com/Azure/go-autorest/tracing v0.6.0/go.mod h1:+vhtPC754Xsa23ID7GlGsrdKBpUA79WCAKPPZVC2DeU=
github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU=
-github.com/DataDog/appsec-internal-go v1.14.0 h1:MIEZ015kdpeSZSFYBQteSmg8f7zkQTWbMDHbSL9zBx8=
-github.com/DataDog/appsec-internal-go v1.14.0/go.mod h1:9YppRCpElfGX+emXOKruShFYsdPq7WEPq/Fen4tYYpk=
-github.com/DataDog/datadog-agent/comp/core/tagger/origindetection v0.70.2 h1:kUc5YY7AIvhWyW2m/7Mmr4TfQrrG7L4kXpDFiS0kcAc=
-github.com/DataDog/datadog-agent/comp/core/tagger/origindetection v0.70.2/go.mod h1:C32ImT3ZcOaEG8xARqPF5uVBTUd4Q9XSZ8qZUDKn+V8=
-github.com/DataDog/datadog-agent/pkg/obfuscate v0.70.2 h1:Xrmg13fi5wOm7+fhKRsMQGAKcZJIv/k1R/3czUnBL08=
-github.com/DataDog/datadog-agent/pkg/obfuscate v0.70.2/go.mod h1:lpp+8NC8/ggIah/F89kN4A7zzEWsIpDy0L9v8jsTpwg=
-github.com/DataDog/datadog-agent/pkg/proto v0.70.2 h1:1/DbqEqvyhDe9j/V5RHDZndhKLa6GF2zHnwSHCYuWbo=
-github.com/DataDog/datadog-agent/pkg/proto v0.70.2/go.mod h1:04uBfKTbFuA9muKbgBE6yC/+955fGjnpwkTPV2LjREY=
-github.com/DataDog/datadog-agent/pkg/remoteconfig/state v0.70.2 h1:8WERtPbezb94idOvUmEyzB7pznpSn3/bEoOcGRyEi4w=
-github.com/DataDog/datadog-agent/pkg/remoteconfig/state v0.70.2/go.mod h1:RaAja1FpZs9KoDQsqGKkq3VQ9phpFXqkjFf/ZxRmr3A=
-github.com/DataDog/datadog-agent/pkg/trace v0.70.2 h1:T3qzpw1dgD7LsmQMGhToljFhW6rgH2ueOefvAFSM5/s=
-github.com/DataDog/datadog-agent/pkg/trace v0.70.2/go.mod h1:b/wPDq+xdftLlgy5re3KbND+lZEnul641O5O8amsDIU=
-github.com/DataDog/datadog-agent/pkg/util/log v0.70.2 h1:4Abe5dyhdyv9cwA2tAFWCyX5pEjk2fQ89q6Q8NLtQ5Y=
-github.com/DataDog/datadog-agent/pkg/util/log v0.70.2/go.mod h1:tO7knmYyZGGoFPC8huxl4vtwgLYdVRQS0PoLdpZI8Lg=
-github.com/DataDog/datadog-agent/pkg/util/scrubber v0.70.2 h1:dM8yjDH0e1DLzh8sDiquRftGdFO87XLaTZ6t+KC9bpE=
-github.com/DataDog/datadog-agent/pkg/util/scrubber v0.70.2/go.mod h1:3b9n1n6Cs8RGjvvnn4xc4pE4JwtPb2SjMKwUgZ65XPw=
-github.com/DataDog/datadog-agent/pkg/version v0.70.2 h1:31BJbziYgvaJrUjhv33otDFi2O+Co+E8sWzFMYdE5fU=
-github.com/DataDog/datadog-agent/pkg/version v0.70.2/go.mod h1:XPERomJsscI4LZk5xVZ8O3fjmIg9gmEq08ixSi5wI3I=
+github.com/DataDog/datadog-agent/comp/core/tagger/origindetection v0.77.0 h1:Lu/HEo5svx/UwE7XWh8vOrEHCrVRsein9X1N0jGK5bo=
+github.com/DataDog/datadog-agent/comp/core/tagger/origindetection v0.77.0/go.mod h1:+Ty3r23MjcmMSkr8JbFeqA3utgtc1wxsZ0KaQ9CzoWA=
+github.com/DataDog/datadog-agent/pkg/obfuscate v0.77.0 h1:mrHaNnDAIOFAVYhCqDpkenUtbadswHN68ZlG5krv40o=
+github.com/DataDog/datadog-agent/pkg/obfuscate v0.77.0/go.mod h1:E6RGAcEOr/d8wsV5/khYHvaHkijWex6dfNEvsBIgR7A=
+github.com/DataDog/datadog-agent/pkg/opentelemetry-mapping-go/otlp/attributes v0.77.0 h1:g1d9d1CfG54WjXgvkysTFL9yjXexWeDbYssQaf1PG6c=
+github.com/DataDog/datadog-agent/pkg/opentelemetry-mapping-go/otlp/attributes v0.77.0/go.mod h1:N/AB9VGpVwHxCcyX+7GLNYMfnTZvn65vp5cHb5Ed0ow=
+github.com/DataDog/datadog-agent/pkg/proto v0.77.0 h1:21nDAKD+LdxZz2pMsLAQTZ+w9Z4JqecjKpt8xY1b7Ig=
+github.com/DataDog/datadog-agent/pkg/proto v0.77.0/go.mod h1:g2QYJe1CheZdssiDQpSYWra9hORkh+S3WO8aOqDNLkg=
+github.com/DataDog/datadog-agent/pkg/remoteconfig/state v0.77.0 h1:SxFGFN/Dd/uREaUTxuVTi0R7fRABzvUtu32YOXcjf6c=
+github.com/DataDog/datadog-agent/pkg/remoteconfig/state v0.77.0/go.mod h1:TpW5ZwsQTrlRBPjtZH5/OFwpmOqxV/v2i9BiF4Xfcac=
+github.com/DataDog/datadog-agent/pkg/template v0.77.0 h1:sUbTCoQyU9kXMc6/aDd4YTP2pe9PlNkgySM11ydMEbE=
+github.com/DataDog/datadog-agent/pkg/template v0.77.0/go.mod h1:ZUjICHSlN0of0cmWrYk9Pof0DV0eqHSpTUK1NTnN26Y=
+github.com/DataDog/datadog-agent/pkg/trace v0.77.0 h1:B7M6IW0sd60XnLfeP6HEneeR4lRnaNtI9bboU4R1cV0=
+github.com/DataDog/datadog-agent/pkg/trace v0.77.0/go.mod h1:+7zMNPjHTDidiphECirrpq5jLK09S9kmLtGRv7di29Q=
+github.com/DataDog/datadog-agent/pkg/trace/log v0.77.0 h1:2VY1byEA2XnYVg7+eLQSTgX2f76ZCf/AwpCBJDXCiDc=
+github.com/DataDog/datadog-agent/pkg/trace/log v0.77.0/go.mod h1:thnxBOGfMU9uRlFUClXud6J7DdI8qWtElELSds5jqts=
+github.com/DataDog/datadog-agent/pkg/trace/otel v0.77.0 h1:9zSto72E+wSETaKs47Yiq5D9du9H71IqWgbDJzGpzSs=
+github.com/DataDog/datadog-agent/pkg/trace/otel v0.77.0/go.mod h1:IxBidgqUt8aBrKYq4VKynBHWYZYNoflk+0+m7w+lfbI=
+github.com/DataDog/datadog-agent/pkg/trace/stats v0.77.0 h1:InA6JO5R8TFAUcKRxsdmIF1hJpVZqVO5Aqux+Iw/2V0=
+github.com/DataDog/datadog-agent/pkg/trace/stats v0.77.0/go.mod h1:iZVotmInV8qaU6Q5h+tsKk4CBYupDcOgTzonzLlMi0k=
+github.com/DataDog/datadog-agent/pkg/trace/traceutil v0.77.0 h1:b/2+uA/cG2xEV0LzgwnxloMFWe5sdJa3xtaQhSGN0+s=
+github.com/DataDog/datadog-agent/pkg/trace/traceutil v0.77.0/go.mod h1:csT+8o3GOUjhKPs/GqWMb5Zh4iQpuZ/HZQ4Z5ls8Sak=
+github.com/DataDog/datadog-agent/pkg/util/log v0.77.0 h1:YFa+8kIg2qQZca9zvowtwCPdHDhGMcTIF+PMIQsLSRs=
+github.com/DataDog/datadog-agent/pkg/util/log v0.77.0/go.mod h1:DFK2U5RcB8/BcObgmVEZ4VxqXUi2t7y2svLTtJwQqeo=
+github.com/DataDog/datadog-agent/pkg/util/scrubber v0.77.0 h1:dd0W9e39rv0R3DSgnaurVnQ43/jX/juqQPwLpGAJgFs=
+github.com/DataDog/datadog-agent/pkg/util/scrubber v0.77.0/go.mod h1:nkhevws2pJvoXSGhjc8wuTbptNQ9ECRBjwVr4hSvoq0=
+github.com/DataDog/datadog-agent/pkg/version v0.77.0 h1:fxpMWuoaRHS5vHzCNHftvJ6wdQrGhEmuozjjl8wZG5k=
+github.com/DataDog/datadog-agent/pkg/version v0.77.0/go.mod h1:h9eJjfeTHlYYv+kzq6n3rQ07qXGirdCCacn1Ryu4TFQ=
github.com/DataDog/datadog-go v3.2.0+incompatible/go.mod h1:LButxg5PwREeZtORoXG3tL4fMGNddJ+vMq1mwgfaqoQ=
-github.com/DataDog/datadog-go/v5 v5.8.0 h1:pKZtux5CfqkqGYGvKCM3wV5i8sYAzcddK7nkrChUtxo=
-github.com/DataDog/datadog-go/v5 v5.8.0/go.mod h1:K9kcYBlxkcPP8tvvjZZKs/m1edNAUFzBbdpTUKfCsuw=
-github.com/DataDog/dd-trace-go/v2 v2.2.3 h1:6RvVdY9suR/rYYYZHjx4txrtSYcRZ5u5Cs2sXMsIBf4=
-github.com/DataDog/dd-trace-go/v2 v2.2.3/go.mod h1:1LcqWELgQwgk6x7sO0MXUgsvxcAVjxSA423cUjvUqR0=
-github.com/DataDog/go-libddwaf/v4 v4.5.0 h1:dXD9xL9T02Mqu9AH7imXpGThKAYqO3BmT2QoXbMFxow=
-github.com/DataDog/go-libddwaf/v4 v4.5.0/go.mod h1:/AZqP6zw3qGJK5mLrA0PkfK3UQDk1zCI2fUNCt4xftE=
-github.com/DataDog/go-runtime-metrics-internal v0.0.4-0.20250721125240-fdf1ef85b633 h1:ZRLR9Lbym748e8RznWzmSoK+OfV+8qW6SdNYA4/IqdA=
-github.com/DataDog/go-runtime-metrics-internal v0.0.4-0.20250721125240-fdf1ef85b633/go.mod h1:YFoTl1xsMzdSRFIu33oCSPS/3+HZAPGpO3oOM96wXCM=
-github.com/DataDog/go-sqllexer v0.1.8 h1:ku9DpghFHeyyviR28W/3R4cCJwzpsuC08YIoltnx5ds=
-github.com/DataDog/go-sqllexer v0.1.8/go.mod h1:GGpo1h9/BVSN+6NJKaEcJ9Jn44Hqc63Rakeb+24Mjgo=
+github.com/DataDog/datadog-go/v5 v5.8.3 h1:s58CUJ9s8lezjhTNJO/SxkPBv2qZjS3ktpRSqGF5n0s=
+github.com/DataDog/datadog-go/v5 v5.8.3/go.mod h1:K9kcYBlxkcPP8tvvjZZKs/m1edNAUFzBbdpTUKfCsuw=
+github.com/DataDog/dd-trace-go/v2 v2.8.2 h1:ZqF2M7j5DPG7PxkJpLIjF4L62LU/QnI86oOSAZjQC/U=
+github.com/DataDog/dd-trace-go/v2 v2.8.2/go.mod h1:o+fhXzd1mPT4Ji5YYcqIjORnNKWcS6m2eW4xqdJplRA=
+github.com/DataDog/go-libddwaf/v4 v4.9.0 h1:a788e37iuH7sR9uIYHkulvTnp2FkXTiZ3yY/kuaHgZE=
+github.com/DataDog/go-libddwaf/v4 v4.9.0/go.mod h1:/AZqP6zw3qGJK5mLrA0PkfK3UQDk1zCI2fUNCt4xftE=
+github.com/DataDog/go-runtime-metrics-internal v0.0.4-0.20260217080614-b0f4edc38a6d h1:cH9Bm0tJ8FEQbA4FRi0iRm7Zr/5Lata/Or31c+Dth0E=
+github.com/DataDog/go-runtime-metrics-internal v0.0.4-0.20260217080614-b0f4edc38a6d/go.mod h1:yDuvU+Ak1TKwgd4K8DNcpJmUrrK8ONLkBMGNAppmBRk=
+github.com/DataDog/go-sqllexer v0.1.13 h1:HhT2G21y7SDZYQx9i1b+3Sy/CHhESHet/YKMSm06XcE=
+github.com/DataDog/go-sqllexer v0.1.13/go.mod h1:vOw7Ia7z+z6nl3zGZlLIZe0vQlPtCPR906WIPBJadxc=
github.com/DataDog/go-tuf v1.1.1-0.5.2 h1:YWvghV4ZvrQsPcUw8IOUMSDpqc3W5ruOIC+KJxPknv0=
github.com/DataDog/go-tuf v1.1.1-0.5.2/go.mod h1:zBcq6f654iVqmkk8n2Cx81E1JnNTMOAx1UEO/wZR+P0=
-github.com/DataDog/gostackparse v0.7.0 h1:i7dLkXHvYzHV308hnkvVGDL3BR4FWl7IsXNPz/IGQh4=
-github.com/DataDog/gostackparse v0.7.0/go.mod h1:lTfqcJKqS9KnXQGnyQMCugq3u1FP6UZMfWR0aitKFMM=
-github.com/DataDog/opentelemetry-mapping-go/pkg/otlp/attributes v0.29.1 h1:RoHver8/fv4qKZtmb11TJ/zcOMd0SqOKT8H9ZQIjjPA=
-github.com/DataDog/opentelemetry-mapping-go/pkg/otlp/attributes v0.29.1/go.mod h1:yN8VBQrExGN/nbIpn8E2jrMJn94e69mnq8a5PDCKY/g=
-github.com/DataDog/sketches-go v1.4.7 h1:eHs5/0i2Sdf20Zkj0udVFWuCrXGRFig2Dcfm5rtcTxc=
-github.com/DataDog/sketches-go v1.4.7/go.mod h1:eAmQ/EBmtSO+nQp7IZMZVRPT4BQTmIc5RZQ+deGlTPM=
-github.com/GoogleCloudPlatform/opentelemetry-operations-go/detectors/gcp v1.30.0 h1:sBEjpZlNHzK1voKq9695PJSX2o5NEXl7/OL3coiIY0c=
-github.com/GoogleCloudPlatform/opentelemetry-operations-go/detectors/gcp v1.30.0/go.mod h1:P4WPRUkOhJC13W//jWpyfJNDAIpvRbAUIYLX/4jtlE0=
+github.com/DataDog/sketches-go v1.4.8 h1:pFk9BNn+Rzv8IMIoPUttoOpOr3bJOqU3P6EP5wK+Lv8=
+github.com/DataDog/sketches-go v1.4.8/go.mod h1:a/wjRUqzqtGS8qRHRPDCs4EAQfmvPDZGDlMIF5mxXOE=
+github.com/GoogleCloudPlatform/opentelemetry-operations-go/detectors/gcp v1.33.0 h1:l7+6kwRMJNwdCvYdDl7Eax+wzEYHSnNY7zrrfbhDdTA=
+github.com/GoogleCloudPlatform/opentelemetry-operations-go/detectors/gcp v1.33.0/go.mod h1:pJTkW8hEUIIi3Pf65lPZOnn4Y81yCllX6IWk2jNXdkM=
github.com/GoogleCloudPlatform/opentelemetry-operations-go/exporter/metric v0.54.0 h1:lhhYARPUu3LmHysQ/igznQphfzynnqI3D75oUyw1HXk=
github.com/GoogleCloudPlatform/opentelemetry-operations-go/exporter/metric v0.54.0/go.mod h1:l9rva3ApbBpEJxSNYnwT9N4CDLrWgtq3u8736C5hyJw=
github.com/GoogleCloudPlatform/opentelemetry-operations-go/internal/cloudmock v0.54.0 h1:xfK3bbi6F2RDtaZFtUdKO3osOBIhNb+xTs8lFW6yx9o=
@@ -89,8 +95,6 @@ github.com/HdrHistogram/hdrhistogram-go v0.9.0 h1:dpujRju0R4M/QZzcnR1LH1qm+TVG3U
github.com/HdrHistogram/hdrhistogram-go v0.9.0/go.mod h1:nxrse8/Tzg2tg3DZcZjm6qEclQKK70g0KxO61gFFZD4=
github.com/Masterminds/glide v0.13.2/go.mod h1:STyF5vcenH/rUqTEv+/hBXlSTo7KYwg2oc2f4tzPWic=
github.com/Masterminds/semver v1.4.2/go.mod h1:MB6lktGJrhw8PrUyiEoblNEGEQ+RzHPF078ddwwvV3Y=
-github.com/Masterminds/semver/v3 v3.4.0 h1:Zog+i5UMtVoCU8oKka5P7i9q9HgrJeGzI9SA1Xbatp0=
-github.com/Masterminds/semver/v3 v3.4.0/go.mod h1:4V+yj/TJE1HU9XfppCwVMZq3I84lprf4nC11bSS5beM=
github.com/Masterminds/vcs v1.13.0/go.mod h1:N09YCmOQr6RLxC6UNHzuVwAdodYbbnycGHSmwVJjcKA=
github.com/Microsoft/go-winio v0.5.0/go.mod h1:JPGBdM1cNvN/6ISo+n8V5iA4v8pBzdOpzfwIujj1a84=
github.com/Microsoft/go-winio v0.6.2 h1:F2VQgta7ecxGYO8k3ZZz3RS8fVIXVxONVUPlNERoyfY=
@@ -106,10 +110,10 @@ github.com/aquarapid/vaultlib v0.5.1 h1:vuLWR6bZzLHybjJBSUYPgZlIp6KZ+SXeHLRRYTuk
github.com/aquarapid/vaultlib v0.5.1/go.mod h1:yT7AlEXtuabkxylOc/+Ulyp18tff1+QjgNLTnFWTlOs=
github.com/armon/go-metrics v0.4.1 h1:hR91U9KYmb6bLBYLQjyM+3j+rcd/UhE+G78SFnF8gJA=
github.com/armon/go-metrics v0.4.1/go.mod h1:E6amYzXo6aW1tqzoZGT755KkbgrJsSdpwZ+3JqfkOG4=
-github.com/aws/aws-sdk-go-v2 v1.39.2 h1:EJLg8IdbzgeD7xgvZ+I8M1e0fL0ptn/M47lianzth0I=
-github.com/aws/aws-sdk-go-v2 v1.39.2/go.mod h1:sDioUELIUO9Znk23YVmIk86/9DOpkbyyVb1i/gUNFXY=
-github.com/aws/aws-sdk-go-v2/aws/protocol/eventstream v1.7.1 h1:i8p8P4diljCr60PpJp6qZXNlgX4m2yQFpYk+9ZT+J4E=
-github.com/aws/aws-sdk-go-v2/aws/protocol/eventstream v1.7.1/go.mod h1:ddqbooRZYNoJ2dsTwOty16rM+/Aqmk/GOXrK8cg7V00=
+github.com/aws/aws-sdk-go-v2 v1.41.5 h1:dj5kopbwUsVUVFgO4Fi5BIT3t4WyqIDjGKCangnV/yY=
+github.com/aws/aws-sdk-go-v2 v1.41.5/go.mod h1:mwsPRE8ceUUpiTgF7QmQIJ7lgsKUPQOUl3o72QBrE1o=
+github.com/aws/aws-sdk-go-v2/aws/protocol/eventstream v1.7.8 h1:eBMB84YGghSocM7PsjmmPffTa+1FBUeNvGvFou6V/4o=
+github.com/aws/aws-sdk-go-v2/aws/protocol/eventstream v1.7.8/go.mod h1:lyw7GFp3qENLh7kwzf7iMzAxDn+NzjXEAGjKS2UOKqI=
github.com/aws/aws-sdk-go-v2/config v1.31.12 h1:pYM1Qgy0dKZLHX2cXslNacbcEFMkDMl+Bcj5ROuS6p8=
github.com/aws/aws-sdk-go-v2/config v1.31.12/go.mod h1:/MM0dyD7KSDPR+39p9ZNVKaHDLb9qnfDurvVS2KAhN8=
github.com/aws/aws-sdk-go-v2/credentials v1.18.16 h1:4JHirI4zp958zC026Sm+V4pSDwW4pwLefKrc0bF2lwI=
@@ -118,32 +122,32 @@ github.com/aws/aws-sdk-go-v2/feature/ec2/imds v1.18.9 h1:Mv4Bc0mWmv6oDuSWTKnk+wg
github.com/aws/aws-sdk-go-v2/feature/ec2/imds v1.18.9/go.mod h1:IKlKfRppK2a1y0gy1yH6zD+yX5uplJ6UuPlgd48dJiQ=
github.com/aws/aws-sdk-go-v2/feature/s3/manager v1.19.10 h1:i9EmUTyCWtUp1KsBwKGTtZUxaRym4LmiFiBcb//i8Kw=
github.com/aws/aws-sdk-go-v2/feature/s3/manager v1.19.10/go.mod h1:IPS1CSYQ8lfLYGytpMEPW4erZmVFUdxLpC0RCI/RCn8=
-github.com/aws/aws-sdk-go-v2/internal/configsources v1.4.9 h1:se2vOWGD3dWQUtfn4wEjRQJb1HK1XsNIt825gskZ970=
-github.com/aws/aws-sdk-go-v2/internal/configsources v1.4.9/go.mod h1:hijCGH2VfbZQxqCDN7bwz/4dzxV+hkyhjawAtdPWKZA=
-github.com/aws/aws-sdk-go-v2/internal/endpoints/v2 v2.7.9 h1:6RBnKZLkJM4hQ+kN6E7yWFveOTg8NLPHAkqrs4ZPlTU=
-github.com/aws/aws-sdk-go-v2/internal/endpoints/v2 v2.7.9/go.mod h1:V9rQKRmK7AWuEsOMnHzKj8WyrIir1yUJbZxDuZLFvXI=
+github.com/aws/aws-sdk-go-v2/internal/configsources v1.4.21 h1:Rgg6wvjjtX8bNHcvi9OnXWwcE0a2vGpbwmtICOsvcf4=
+github.com/aws/aws-sdk-go-v2/internal/configsources v1.4.21/go.mod h1:A/kJFst/nm//cyqonihbdpQZwiUhhzpqTsdbhDdRF9c=
+github.com/aws/aws-sdk-go-v2/internal/endpoints/v2 v2.7.21 h1:PEgGVtPoB6NTpPrBgqSE5hE/o47Ij9qk/SEZFbUOe9A=
+github.com/aws/aws-sdk-go-v2/internal/endpoints/v2 v2.7.21/go.mod h1:p+hz+PRAYlY3zcpJhPwXlLC4C+kqn70WIHwnzAfs6ps=
github.com/aws/aws-sdk-go-v2/internal/ini v1.8.3 h1:bIqFDwgGXXN1Kpp99pDOdKMTTb5d2KyU5X/BZxjOkRo=
github.com/aws/aws-sdk-go-v2/internal/ini v1.8.3/go.mod h1:H5O/EsxDWyU+LP/V8i5sm8cxoZgc2fdNR9bxlOFrQTo=
-github.com/aws/aws-sdk-go-v2/internal/v4a v1.4.9 h1:w9LnHqTq8MEdlnyhV4Bwfizd65lfNCNgdlNC6mM5paE=
-github.com/aws/aws-sdk-go-v2/internal/v4a v1.4.9/go.mod h1:LGEP6EK4nj+bwWNdrvX/FnDTFowdBNwcSPuZu/ouFys=
-github.com/aws/aws-sdk-go-v2/service/internal/accept-encoding v1.13.1 h1:oegbebPEMA/1Jny7kvwejowCaHz1FWZAQ94WXFNCyTM=
-github.com/aws/aws-sdk-go-v2/service/internal/accept-encoding v1.13.1/go.mod h1:kemo5Myr9ac0U9JfSjMo9yHLtw+pECEHsFtJ9tqCEI8=
-github.com/aws/aws-sdk-go-v2/service/internal/checksum v1.8.9 h1:by3nYZLR9l8bUH7kgaMU4dJgYFjyRdFEfORlDpPILB4=
-github.com/aws/aws-sdk-go-v2/service/internal/checksum v1.8.9/go.mod h1:IWjQYlqw4EX9jw2g3qnEPPWvCE6bS8fKzhMed1OK7c8=
-github.com/aws/aws-sdk-go-v2/service/internal/presigned-url v1.13.9 h1:5r34CgVOD4WZudeEKZ9/iKpiT6cM1JyEROpXjOcdWv8=
-github.com/aws/aws-sdk-go-v2/service/internal/presigned-url v1.13.9/go.mod h1:dB12CEbNWPbzO2uC6QSWHteqOg4JfBVJOojbAoAUb5I=
-github.com/aws/aws-sdk-go-v2/service/internal/s3shared v1.19.9 h1:wuZ5uW2uhJR63zwNlqWH2W4aL4ZjeJP3o92/W+odDY4=
-github.com/aws/aws-sdk-go-v2/service/internal/s3shared v1.19.9/go.mod h1:/G58M2fGszCrOzvJUkDdY8O9kycodunH4VdT5oBAqls=
-github.com/aws/aws-sdk-go-v2/service/s3 v1.88.3 h1:P18I4ipbk+b/3dZNq5YYh+Hq6XC0vp5RWkLp1tJldDA=
-github.com/aws/aws-sdk-go-v2/service/s3 v1.88.3/go.mod h1:Rm3gw2Jov6e6kDuamDvyIlZJDMYk97VeCZ82wz/mVZ0=
+github.com/aws/aws-sdk-go-v2/internal/v4a v1.4.22 h1:rWyie/PxDRIdhNf4DzRk0lvjVOqFJuNnO8WwaIRVxzQ=
+github.com/aws/aws-sdk-go-v2/internal/v4a v1.4.22/go.mod h1:zd/JsJ4P7oGfUhXn1VyLqaRZwPmZwg44Jf2dS84Dm3Y=
+github.com/aws/aws-sdk-go-v2/service/internal/accept-encoding v1.13.7 h1:5EniKhLZe4xzL7a+fU3C2tfUN4nWIqlLesfrjkuPFTY=
+github.com/aws/aws-sdk-go-v2/service/internal/accept-encoding v1.13.7/go.mod h1:x0nZssQ3qZSnIcePWLvcoFisRXJzcTVvYpAAdYX8+GI=
+github.com/aws/aws-sdk-go-v2/service/internal/checksum v1.9.13 h1:JRaIgADQS/U6uXDqlPiefP32yXTda7Kqfx+LgspooZM=
+github.com/aws/aws-sdk-go-v2/service/internal/checksum v1.9.13/go.mod h1:CEuVn5WqOMilYl+tbccq8+N2ieCy0gVn3OtRb0vBNNM=
+github.com/aws/aws-sdk-go-v2/service/internal/presigned-url v1.13.21 h1:c31//R3xgIJMSC8S6hEVq+38DcvUlgFY0FM6mSI5oto=
+github.com/aws/aws-sdk-go-v2/service/internal/presigned-url v1.13.21/go.mod h1:r6+pf23ouCB718FUxaqzZdbpYFyDtehyZcmP5KL9FkA=
+github.com/aws/aws-sdk-go-v2/service/internal/s3shared v1.19.21 h1:ZlvrNcHSFFWURB8avufQq9gFsheUgjVD9536obIknfM=
+github.com/aws/aws-sdk-go-v2/service/internal/s3shared v1.19.21/go.mod h1:cv3TNhVrssKR0O/xxLJVRfd2oazSnZnkUeTf6ctUwfQ=
+github.com/aws/aws-sdk-go-v2/service/s3 v1.97.3 h1:HwxWTbTrIHm5qY+CAEur0s/figc3qwvLWsNkF4RPToo=
+github.com/aws/aws-sdk-go-v2/service/s3 v1.97.3/go.mod h1:uoA43SdFwacedBfSgfFSjjCvYe8aYBS7EnU5GZ/YKMM=
github.com/aws/aws-sdk-go-v2/service/sso v1.29.6 h1:A1oRkiSQOWstGh61y4Wc/yQ04sqrQZr1Si/oAXj20/s=
github.com/aws/aws-sdk-go-v2/service/sso v1.29.6/go.mod h1:5PfYspyCU5Vw1wNPsxi15LZovOnULudOQuVxphSflQA=
github.com/aws/aws-sdk-go-v2/service/ssooidc v1.35.1 h1:5fm5RTONng73/QA73LhCNR7UT9RpFH3hR6HWL6bIgVY=
github.com/aws/aws-sdk-go-v2/service/ssooidc v1.35.1/go.mod h1:xBEjWD13h+6nq+z4AkqSfSvqRKFgDIQeaMguAJndOWo=
github.com/aws/aws-sdk-go-v2/service/sts v1.38.6 h1:p3jIvqYwUZgu/XYeI48bJxOhvm47hZb5HUQ0tn6Q9kA=
github.com/aws/aws-sdk-go-v2/service/sts v1.38.6/go.mod h1:WtKK+ppze5yKPkZ0XwqIVWD4beCwv056ZbPQNoeHqM8=
-github.com/aws/smithy-go v1.23.0 h1:8n6I3gXzWJB2DxBDnfxgBaSX6oe0d/t10qGz7OKqMCE=
-github.com/aws/smithy-go v1.23.0/go.mod h1:t1ufH5HMublsJYulve2RKmHDC15xu1f26kHCp/HgceI=
+github.com/aws/smithy-go v1.24.2 h1:FzA3bu/nt/vDvmnkg+R8Xl46gmzEDam6mZ1hzmwXFng=
+github.com/aws/smithy-go v1.24.2/go.mod h1:YE2RhdIuDbA5E5bTdciG9KrW3+TiEONeUWCqxX9i1Fc=
github.com/benbjohnson/clock v1.1.0/go.mod h1:J11/hYXuz8f4ySSvYwY0FKfm+ezbsZBKZxNJlLklBHA=
github.com/beorn7/perks v0.0.0-20180321164747-3a771d992973/go.mod h1:Dwedo/Wpr24TaqPxmxbtue+5NUziq4I4S80YR8gNf3Q=
github.com/beorn7/perks v1.0.0/go.mod h1:KWe93zE9D1o94FZ5RNwFwVgaQK1VOXiVxmqh+CedLV8=
@@ -153,6 +157,8 @@ github.com/bndr/gotabulate v1.1.2 h1:yC9izuZEphojb9r+KYL4W9IJKO/ceIO8HDwxMA24U4c
github.com/bndr/gotabulate v1.1.2/go.mod h1:0+8yUgaPTtLRTjf49E8oju7ojpU11YmXyvq1LbPAb3U=
github.com/buger/jsonparser v1.1.1 h1:2PnMjfWD7wBILjqQbt530v576A/cAbQvEW9gGIpYMUs=
github.com/buger/jsonparser v1.1.1/go.mod h1:6RYKKt7H4d4+iWqouImQ9R2FZql3VbhNgx27UK13J/0=
+github.com/cenkalti/backoff/v5 v5.0.3 h1:ZN+IMa753KfX5hd8vVaMixjnqRZ3y8CuJKRKj1xcsSM=
+github.com/cenkalti/backoff/v5 v5.0.3/go.mod h1:rkhZdG3JZukswDf7f0cwqPNk4K0sa+F97BxZthm/crw=
github.com/census-instrumentation/opencensus-proto v0.2.1/go.mod h1:f6KPmirojxKA12rnyqOA5BBL4O983OfeGPqjHWSTneU=
github.com/cespare/xxhash/v2 v2.1.1/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs=
github.com/cespare/xxhash/v2 v2.3.0 h1:UL815xU9SqsFlibzuggzjXhog7bL6oX9BbNZnL2UFvs=
@@ -167,8 +173,8 @@ github.com/client9/misspell v0.3.4/go.mod h1:qj6jICC3Q7zFZvVWo7KLAzC3yx5G7kyvSDk
github.com/clipperhouse/uax29/v2 v2.2.0 h1:ChwIKnQN3kcZteTXMgb1wztSgaU+ZemkgWdohwgs8tY=
github.com/clipperhouse/uax29/v2 v2.2.0/go.mod h1:EFJ2TJMRUaplDxHKj1qAEhCtQPW2tJSwu5BF98AuoVM=
github.com/cncf/udpa/go v0.0.0-20191209042840-269d4d468f6f/go.mod h1:M8M6+tZqaGXZJjfX53e64911xZQV5JYwmTeXPW+k8Sc=
-github.com/cncf/xds/go v0.0.0-20250501225837-2ac532fd4443 h1:aQ3y1lwWyqYPiWZThqv1aFbZMiM9vblcSArJRf2Irls=
-github.com/cncf/xds/go v0.0.0-20250501225837-2ac532fd4443/go.mod h1:W+zGtBO5Y1IgJhy4+A9GOqVhqLpfZi+vwmdNXUehLA8=
+github.com/cncf/xds/go v0.0.0-20260202195803-dba9d589def2 h1:aBangftG7EVZoUb69Os8IaYg++6uMOdKK83QtkkvJik=
+github.com/cncf/xds/go v0.0.0-20260202195803-dba9d589def2/go.mod h1:qwXFYgsP6T7XnJtbKlf1HP8AjxZZyzxMmc+Lq5GjlU4=
github.com/codegangsta/cli v1.20.0/go.mod h1:/qJNoX69yVSKu5o4jLyXAENLRyk1uhi7zkbQ3slBdOA=
github.com/containerd/cgroups v1.1.0 h1:v8rEWFl6EoqHB+swVNjVoCJE8o3jX7e8nqBGPLaDFBM=
github.com/containerd/cgroups v1.1.0/go.mod h1:6ppBcbh/NOOUU+dMKrykgaBnK9lCIBxHqJDGwsa1mIw=
@@ -208,22 +214,20 @@ github.com/docker/go-units v0.5.0/go.mod h1:fgPhTUdO+D/Jk86RDLlptpiXQzgHJF7gydDD
github.com/dustin/go-humanize v1.0.0/go.mod h1:HtrtbFcZ19U5GC7JDqmcUSB87Iq5E25KnS6fMYU6eOk=
github.com/dustin/go-humanize v1.0.1 h1:GzkhY7T5VNhEkwH0PVJgjz+fX1rhBrR7pRT3mDkpeCY=
github.com/dustin/go-humanize v1.0.1/go.mod h1:Mu1zIs6XwVuF/gI1OepvI0qD18qycQx+mFykh5fBlto=
-github.com/eapache/queue/v2 v2.0.0-20230407133247-75960ed334e4 h1:8EXxF+tCLqaVk8AOC29zl2mnhQjwyLxxOTuhUazWRsg=
-github.com/eapache/queue/v2 v2.0.0-20230407133247-75960ed334e4/go.mod h1:I5sHm0Y0T1u5YjlyqC5GVArM7aNZRUYtTjmJ8mPJFds=
-github.com/ebitengine/purego v0.9.0 h1:mh0zpKBIXDceC63hpvPuGLiJ8ZAa3DfrFTudmfi8A4k=
-github.com/ebitengine/purego v0.9.0/go.mod h1:iIjxzd6CiRiOG0UyXP+V1+jWqUXVjPKLAI0mRfJZTmQ=
+github.com/ebitengine/purego v0.10.0 h1:QIw4xfpWT6GWTzaW5XEKy3HXoqrJGx1ijYHzTF0/ISU=
+github.com/ebitengine/purego v0.10.0/go.mod h1:iIjxzd6CiRiOG0UyXP+V1+jWqUXVjPKLAI0mRfJZTmQ=
github.com/envoyproxy/go-control-plane v0.9.0/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymFceY/DCBVvsKhRF0iEA4=
github.com/envoyproxy/go-control-plane v0.9.1-0.20191026205805-5f8ba28d4473/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymFceY/DCBVvsKhRF0iEA4=
github.com/envoyproxy/go-control-plane v0.9.4/go.mod h1:6rpuAdCZL397s3pYoYcLgu1mIlRU8Am5FuJP05cCM98=
-github.com/envoyproxy/go-control-plane v0.13.4 h1:zEqyPVyku6IvWCFwux4x9RxkLOMUL+1vC9xUFv5l2/M=
-github.com/envoyproxy/go-control-plane v0.13.4/go.mod h1:kDfuBlDVsSj2MjrLEtRWtHlsWIFcGyB2RMO44Dc5GZA=
-github.com/envoyproxy/go-control-plane/envoy v1.35.0 h1:ixjkELDE+ru6idPxcHLj8LBVc2bFP7iBytj353BoHUo=
-github.com/envoyproxy/go-control-plane/envoy v1.35.0/go.mod h1:09qwbGVuSWWAyN5t/b3iyVfz5+z8QWGrzkoqm/8SbEs=
+github.com/envoyproxy/go-control-plane v0.14.0 h1:hbG2kr4RuFj222B6+7T83thSPqLjwBIfQawTkC++2HA=
+github.com/envoyproxy/go-control-plane v0.14.0/go.mod h1:NcS5X47pLl/hfqxU70yPwL9ZMkUlwlKxtAohpi2wBEU=
+github.com/envoyproxy/go-control-plane/envoy v1.37.0 h1:u3riX6BoYRfF4Dr7dwSOroNfdSbEPe9Yyl09/B6wBrQ=
+github.com/envoyproxy/go-control-plane/envoy v1.37.0/go.mod h1:DReE9MMrmecPy+YvQOAOHNYMALuowAnbjjEMkkWOi6A=
github.com/envoyproxy/go-control-plane/ratelimit v0.1.0 h1:/G9QYbddjL25KvtKTv3an9lx6VBE2cnb8wp1vEGNYGI=
github.com/envoyproxy/go-control-plane/ratelimit v0.1.0/go.mod h1:Wk+tMFAFbCXaJPzVVHnPgRKdUdwW/KdbRt94AzgRee4=
github.com/envoyproxy/protoc-gen-validate v0.1.0/go.mod h1:iSmxcyjqTsJpI2R4NaDN7+kN2VEUnK/pcBlmesArF7c=
-github.com/envoyproxy/protoc-gen-validate v1.2.1 h1:DEo3O99U8j4hBFwbJfrz9VtgcDfUKS7KJ7spH3d86P8=
-github.com/envoyproxy/protoc-gen-validate v1.2.1/go.mod h1:d/C80l/jxXLdfEIhX1W2TmLfsJ31lvEjwamM4DxlWXU=
+github.com/envoyproxy/protoc-gen-validate v1.3.3 h1:MVQghNeW+LZcmXe7SY1V36Z+WFMDjpqGAGacLe2T0ds=
+github.com/envoyproxy/protoc-gen-validate v1.3.3/go.mod h1:TsndJ/ngyIdQRhMcVVGDDHINPLWB7C82oDArY51KfB0=
github.com/evanphx/json-patch v5.9.11+incompatible h1:ixHHqfcGvxhWkniF1tWxBHA0yb4Z+d1UQi45df52xW8=
github.com/evanphx/json-patch v5.9.11+incompatible/go.mod h1:50XU6AFN0ol/bzJsmQLiYLvXMP4fmwYFNcr97nuDLSk=
github.com/fatih/color v1.13.0/go.mod h1:kLAiJbzzSOZDVNGyDpeOxJ47H46qBXwg5ILebYFFOfk=
@@ -241,8 +245,8 @@ github.com/fsnotify/fsnotify v1.9.0 h1:2Ml+OJNzbYCTzsxtv8vKSFD9PbJjmhYF14k/jKC7S
github.com/fsnotify/fsnotify v1.9.0/go.mod h1:8jBTzvmWwFyi3Pb8djgCCO5IBqzKJ/Jwo8TRcHyHii0=
github.com/gammazero/deque v1.1.0 h1:OyiyReBbnEG2PP0Bnv1AASLIYvyKqIFN5xfl1t8oGLo=
github.com/gammazero/deque v1.1.0/go.mod h1:JVrR+Bj1NMQbPnYclvDlvSX0nVGReLrQZ0aUMuWLctg=
-github.com/go-jose/go-jose/v4 v4.1.2 h1:TK/7NqRQZfgAh+Td8AlsrvtPoUyiHh0LqVvokh+1vHI=
-github.com/go-jose/go-jose/v4 v4.1.2/go.mod h1:22cg9HWM1pOlnRiY+9cQYJ9XHmya1bYW8OeDM6Ku6Oo=
+github.com/go-jose/go-jose/v4 v4.1.5 h1:RjgjO2LOtWOJKUC5wpwY9LR3B3vwVAz6JS2YHfYU6eA=
+github.com/go-jose/go-jose/v4 v4.1.5/go.mod h1:x4oUasVrzR7071A4TnHLGSPpNOm2a21K9Kf04k1rs08=
github.com/go-kit/kit v0.8.0/go.mod h1:xBxKIO96dXMWWy0MnWVtmwkA9/13aqxPnvrjFYMA2as=
github.com/go-kit/kit v0.9.0/go.mod h1:xBxKIO96dXMWWy0MnWVtmwkA9/13aqxPnvrjFYMA2as=
github.com/go-kit/log v0.1.0/go.mod h1:zbhenjAZHb184qTLMA9ZjW7ThYL0H2mk7Q6pNt4vbaY=
@@ -250,8 +254,8 @@ github.com/go-logfmt/logfmt v0.3.0/go.mod h1:Qt1PoO58o5twSAckw1HlFXLmHsOX5/0LbT9
github.com/go-logfmt/logfmt v0.4.0/go.mod h1:3RMwSq7FuexP4Kalkev3ejPJsZTpXXBr9+V4qmtdjCk=
github.com/go-logfmt/logfmt v0.5.0/go.mod h1:wCYkCAKZfumFQihp8CzCvQ3paCTfi41vtzG1KdI/P7A=
github.com/go-logr/logr v1.2.2/go.mod h1:jdQByPbusPIv2/zmleS9BjJVeZ6kBagPoEUsqbVz/1A=
-github.com/go-logr/logr v1.4.3 h1:CjnDlHq8ikf6E492q6eKboGOC0T8CDaOvkHCIg8idEI=
-github.com/go-logr/logr v1.4.3/go.mod h1:9T104GzyrTigFIr8wt5mBrctHMim0Nb2HLGrmQ40KvY=
+github.com/go-logr/logr v1.4.4 h1:tG4xh9yMsRCAiodLVTxyrkzSZ9+o0L1Kg/+cPVcbP/8=
+github.com/go-logr/logr v1.4.4/go.mod h1:9T104GzyrTigFIr8wt5mBrctHMim0Nb2HLGrmQ40KvY=
github.com/go-logr/stdr v1.2.2 h1:hSWxHoqTgW2S2qGc0LTAI563KZ5YKYRhT3MFKZMbjag=
github.com/go-logr/stdr v1.2.2/go.mod h1:mMo/vtBO5dYbehREoey6XUKy/eSumjCCveDpRre4VKE=
github.com/go-ole/go-ole v1.2.6/go.mod h1:pprOEPIfldk/42T2oK7lQ4v4JSDwmV0As9GaiUsvbm0=
@@ -263,8 +267,8 @@ github.com/go-sql-driver/mysql v1.7.1 h1:lUIinVbN1DY0xBg0eMOzmmtGoHwWBbvnWubQUrt
github.com/go-sql-driver/mysql v1.7.1/go.mod h1:OXbVy3sEdcQ2Doequ6Z5BW6fXNQTmx+9S1MCJN5yJMI=
github.com/go-stack/stack v1.8.0/go.mod h1:v0f6uXyyMGvRgIKkXu+yp6POWl0qKG85gN/melR3HDY=
github.com/go-task/slim-sprig v0.0.0-20210107165309-348f09dbbbc0/go.mod h1:fyg7847qk6SyHyPtNmDHnmrv/HOrqktSC+C9fM+CJOE=
-github.com/go-viper/mapstructure/v2 v2.4.0 h1:EBsztssimR/CONLSZZ04E8qAkxNYq4Qp9LvH92wZUgs=
-github.com/go-viper/mapstructure/v2 v2.4.0/go.mod h1:oJDH3BJKyqBA2TXFhDsKDGDTlndYOZ6rGS0BRZIxGhM=
+github.com/go-viper/mapstructure/v2 v2.5.0 h1:vM5IJoUAy3d7zRSVtIwQgBj7BiWtMPfmPEgAXnvj1Ro=
+github.com/go-viper/mapstructure/v2 v2.5.0/go.mod h1:oJDH3BJKyqBA2TXFhDsKDGDTlndYOZ6rGS0BRZIxGhM=
github.com/godbus/dbus/v5 v5.1.0 h1:4KLkAxT3aOY8Li4FRJe/KvhoNFFxo0m6fNuFUO8QJUk=
github.com/godbus/dbus/v5 v5.1.0/go.mod h1:xhWf0FNVPg57R7Z0UbKHbJfkEywrmjJnf7w5xrFpKfA=
github.com/gogo/protobuf v1.1.1/go.mod h1:r8qH/GZQm5c6nD/R0oafs1akxWv10x8SbQlK7atdtwQ=
@@ -321,10 +325,10 @@ github.com/google/shlex v0.0.0-20191202100458-e7afc7fbc510/go.mod h1:pupxD2MaaD3
github.com/google/uuid v1.2.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
github.com/google/uuid v1.6.0 h1:NIvaJDMOsjHA8n1jAhLSgzrAzy1Hgr+hNrb57e+94F0=
github.com/google/uuid v1.6.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
-github.com/googleapis/enterprise-certificate-proxy v0.3.6 h1:GW/XbdyBFQ8Qe+YAmFU9uHLo7OnF5tL52HFAgMmyrf4=
-github.com/googleapis/enterprise-certificate-proxy v0.3.6/go.mod h1:MkHOF77EYAE7qfSuSS9PU6g4Nt4e11cnsDUowfwewLA=
-github.com/googleapis/gax-go/v2 v2.15.0 h1:SyjDc1mGgZU5LncH8gimWo9lW1DtIfPibOG81vgd/bo=
-github.com/googleapis/gax-go/v2 v2.15.0/go.mod h1:zVVkkxAQHa1RQpg9z2AUCMnKhi0Qld9rcmyfL1OZhoc=
+github.com/googleapis/enterprise-certificate-proxy v0.3.11 h1:vAe81Msw+8tKUxi2Dqh/NZMz7475yUvmRIkXr4oN2ao=
+github.com/googleapis/enterprise-certificate-proxy v0.3.11/go.mod h1:RFV7MUdlb7AgEq2v7FmMCfeSMCllAzWxFgRdusoGks8=
+github.com/googleapis/gax-go/v2 v2.17.0 h1:RksgfBpxqff0EZkDWYuz9q/uWsTVz+kf43LsZ1J6SMc=
+github.com/googleapis/gax-go/v2 v2.17.0/go.mod h1:mzaqghpQp4JDh3HvADwrat+6M3MOIDp5YKHhb9PAgDY=
github.com/gopherjs/gopherjs v0.0.0-20181103185306-d547d1d9531e/go.mod h1:wJfORRmW1u3UXTncJ5qlYoELFm8eSnnEO6hX4iZ3EWY=
github.com/gorilla/handlers v1.5.2 h1:cLTUSsNkgcwhgRqvCNmdbRWG0A3N4F+M2nWKdScwyEE=
github.com/gorilla/handlers v1.5.2/go.mod h1:dX+xVpaxdSw+q0Qek8SSsl3dfMk3jNddUkMzo0GtH0w=
@@ -364,8 +368,8 @@ github.com/hashicorp/go-sockaddr v1.0.7/go.mod h1:FZQbEYa1pxkQ7WLpyXJ6cbjpT8q0Yg
github.com/hashicorp/go-uuid v1.0.0/go.mod h1:6SBZvOh/SIDV7/2o3Jml5SYk/TvGqwFJ/bN7x4byOro=
github.com/hashicorp/go-uuid v1.0.3 h1:2gKiV6YVmrJ1i2CKKa9obLvRieoRGviZFL26PcT/Co8=
github.com/hashicorp/go-uuid v1.0.3/go.mod h1:6SBZvOh/SIDV7/2o3Jml5SYk/TvGqwFJ/bN7x4byOro=
-github.com/hashicorp/go-version v1.7.0 h1:5tqGy27NaOTB8yJKUZELlFAS/LTKJkrmONwQKeRZfjY=
-github.com/hashicorp/go-version v1.7.0/go.mod h1:fltr4n8CU8Ke44wwGCBoEymUuxUHl09ZGVZPK5anwXA=
+github.com/hashicorp/go-version v1.8.0 h1:KAkNb1HAiZd1ukkxDFGmokVZe1Xy9HG6NUp+bPle2i4=
+github.com/hashicorp/go-version v1.8.0/go.mod h1:fltr4n8CU8Ke44wwGCBoEymUuxUHl09ZGVZPK5anwXA=
github.com/hashicorp/golang-lru v0.5.0/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8=
github.com/hashicorp/golang-lru v1.0.2 h1:dV3g9Z/unq5DpblPpw+Oqcv4dU/1omnb4Ok8iPY6p1c=
github.com/hashicorp/golang-lru v1.0.2/go.mod h1:iADmTwqILo4mZ8BN3D2Q6+9jd8WM5uGBxy+E8yxSoD4=
@@ -394,8 +398,10 @@ github.com/julienschmidt/httprouter v1.2.0/go.mod h1:SYymIcj16QtmaHHD7aYtjjsJG7V
github.com/julienschmidt/httprouter v1.3.0/go.mod h1:JR6WtHb+2LUe8TCKY3cZOxFyyO8IZAc4RVcycCCAKdM=
github.com/kisielk/errcheck v1.5.0/go.mod h1:pFxgyoBC7bSaBwPgfKdkLd5X25qrDl4LWUI2bnpBCr8=
github.com/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+oQHNcck=
-github.com/klauspost/compress v1.18.0 h1:c/Cqfb0r+Yi+JtIEq73FWXVkRonBlf0CRNYc8Zttxdo=
-github.com/klauspost/compress v1.18.0/go.mod h1:2Pp+KzxcywXVXMr50+X0Q/Lsb43OQHYWRCY2AiWywWQ=
+github.com/klauspost/compress v1.18.4 h1:RPhnKRAQ4Fh8zU2FY/6ZFDwTVTxgJ/EMydqSTzE9a2c=
+github.com/klauspost/compress v1.18.4/go.mod h1:R0h/fSBs8DE4ENlcrlib3PsXS61voFxhIs2DeRhCvJ4=
+github.com/klauspost/cpuid/v2 v2.3.0 h1:S4CRMLnYUhGeDFDqkGriYKdfoFlDnMtqTiI/sFzhA9Y=
+github.com/klauspost/cpuid/v2 v2.3.0/go.mod h1:hqwkgyIinND0mEev00jJYCxPNVRVXFQeu1XKlok6oO0=
github.com/klauspost/pgzip v1.2.6 h1:8RXeL5crjEUFnR2/Sn6GJNWtSQ3Dk8pq4CL3jvdDyjU=
github.com/klauspost/pgzip v1.2.6/go.mod h1:Ch1tH69qFZu15pkjo5kYi6mth2Zzwzt50oCQKQE9RUs=
github.com/konsorten/go-windows-terminal-sequences v1.0.1/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ=
@@ -413,8 +419,10 @@ github.com/krishicks/yaml-patch v0.0.10 h1:H4FcHpnNwVmw8u0MjPRjWyIXtco6zM2F78t+5
github.com/krishicks/yaml-patch v0.0.10/go.mod h1:Sm5TchwZS6sm7RJoyg87tzxm2ZcKzdRE4Q7TjNhPrME=
github.com/kylelemons/godebug v1.1.0 h1:RPNrshWIDI6G2gRW9EHilWtl7Z6Sb1BR0xunSBf0SNc=
github.com/kylelemons/godebug v1.1.0/go.mod h1:9/0rRGxNHcop5bhtWyNeEfOS8JIWk580+fNqagV/RAw=
-github.com/lufia/plan9stats v0.0.0-20250827001030-24949be3fa54 h1:mFWunSatvkQQDhpdyuFAYwyAan3hzCuma+Pz8sqvOfg=
-github.com/lufia/plan9stats v0.0.0-20250827001030-24949be3fa54/go.mod h1:autxFIvghDt3jPTLoqZ9OZ7s9qTGNAWmYCjVFWPX/zg=
+github.com/linkdata/deadlock v0.5.5 h1:d6O+rzEqasSfamGDA8u7bjtaq7hOX8Ha4Zn36Wxrkvo=
+github.com/linkdata/deadlock v0.5.5/go.mod h1:tXb28stzAD3trzEEK0UJWC+rZKuobCoPktPYzebb1u0=
+github.com/lufia/plan9stats v0.0.0-20260216142805-b3301c5f2a88 h1:PTw+yKnXcOFCR6+8hHTyWBeQ/P4Nb7dd4/0ohEcWQuM=
+github.com/lufia/plan9stats v0.0.0-20260216142805-b3301c5f2a88/go.mod h1:autxFIvghDt3jPTLoqZ9OZ7s9qTGNAWmYCjVFWPX/zg=
github.com/mattn/go-colorable v0.1.9/go.mod h1:u6P/XSegPjTcexA+o6vUJrdnUu04hMope9wVRipJSqc=
github.com/mattn/go-colorable v0.1.12/go.mod h1:u5H1YNBxpqRaxsYJYSkiCWKzEfiAb1Gb520KVy5xxl4=
github.com/mattn/go-colorable v0.1.14 h1:9A9LHSqF/7dyVVX6g0U9cwm9pG3kP9gSzcuIPHPsaIE=
@@ -431,12 +439,14 @@ github.com/mattn/go-runewidth v0.0.19/go.mod h1:XBkDxAl56ILZc9knddidhrOlY5R/pDhg
github.com/matttproud/golang_protobuf_extensions v1.0.1/go.mod h1:D8He9yQNgCq6Z5Ld7szi9bcBfOoFv/3dc6xSMkL2PC0=
github.com/mdlayher/netlink v1.7.2 h1:/UtM3ofJap7Vl4QWCPDGXY8d3GIY2UGSDbK+QWmY8/g=
github.com/mdlayher/netlink v1.7.2/go.mod h1:xraEF7uJbxLhc5fpHL4cPe221LI2bdttWlU+ZGLfQSw=
-github.com/mdlayher/socket v0.4.1 h1:eM9y2/jlbs1M615oshPQOHZzj6R6wMT7bX5NPiQvn2U=
-github.com/mdlayher/socket v0.4.1/go.mod h1:cAqeGjoufqdxWkD7DkpyS+wcefOtmu5OQ8KuoJGIReA=
+github.com/mdlayher/socket v0.5.1 h1:VZaqt6RkGkt2OE9l3GcC6nZkqD3xKeQLyfleW/uBcos=
+github.com/mdlayher/socket v0.5.1/go.mod h1:TjPLHI1UgwEv5J1B5q0zTZq12A/6H7nKmtTanQE37IQ=
github.com/miekg/dns v1.1.56 h1:5imZaSeoRNvpM9SzWNhEcP9QliKiz20/dA2QabIGVnE=
github.com/miekg/dns v1.1.56/go.mod h1:cRm6Oo2C8TY9ZS/TqsSrseAcncm74lfK5G+ikN2SWWY=
github.com/minio/minio-go v0.0.0-20190131015406-c8a261de75c1 h1:jw16EimP5oAEM/2wt+SiEUov/YDyTCTDuPtIKgQIvk0=
github.com/minio/minio-go v0.0.0-20190131015406-c8a261de75c1/go.mod h1:vuvdOZLJuf5HmJAJrKV64MmozrSsk+or0PB5dzdfspg=
+github.com/minio/simdjson-go v0.4.5 h1:r4IQwjRGmWCQ2VeMc7fGiilu1z5du0gJ/I/FsKwgo5A=
+github.com/minio/simdjson-go v0.4.5/go.mod h1:eoNz0DcLQRyEDeaPr4Ru6JpjlZPzbA0IodxVJk8lO8E=
github.com/mitchellh/go-homedir v1.1.0 h1:lukF9ziXFxDFPkA1vsr5zpc1XuPDn/wFntq5mG+4E0Y=
github.com/mitchellh/go-homedir v1.1.0/go.mod h1:SfyaCUpYCn1Vlf4IUYiD9fPX4A5wJrkLzIz1N1q0pr0=
github.com/modern-go/concurrent v0.0.0-20180228061459-e0a39a4cb421/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q=
@@ -473,12 +483,12 @@ github.com/onsi/ginkgo v1.16.5 h1:8xi0RTUf59SOSfEtZMvwTvXYMzG4gV23XVHOZiXNtnE=
github.com/onsi/ginkgo v1.16.5/go.mod h1:+E8gABHa3K6zRBolWtd+ROzc/U5bkGt0FwiG042wbpU=
github.com/onsi/gomega v1.7.1/go.mod h1:XdKZgCCFLUoM/7CFJVPcG8C1xQ1AJ0vpAezJrB7JYyY=
github.com/onsi/gomega v1.10.1/go.mod h1:iN09h71vgCQne3DLsj+A5owkum+a2tYe+TOCB1ybHNo=
-github.com/onsi/gomega v1.36.2 h1:koNYke6TVk6ZmnyHrCXba/T/MoLBXFjeC1PtvYgw0A8=
-github.com/onsi/gomega v1.36.2/go.mod h1:DdwyADRjrc825LhMEkD76cHR5+pUnjhUN8GlHlRPHzY=
-github.com/open-telemetry/opentelemetry-collector-contrib/pkg/sampling v0.131.0 h1:5sPZErUo231/wBoKp/HiEieW8uhiQXHIHnII3HXIcYM=
-github.com/open-telemetry/opentelemetry-collector-contrib/pkg/sampling v0.131.0/go.mod h1:0eTDOk4+HDSo+3oA2N+2Q41ypGZDTvZpzODQsOHQ4cw=
-github.com/open-telemetry/opentelemetry-collector-contrib/processor/probabilisticsamplerprocessor v0.131.0 h1:6afPSMz1XbtFYGhT/BCsbgP5dIx/lbmKrndW8WuOBV8=
-github.com/open-telemetry/opentelemetry-collector-contrib/processor/probabilisticsamplerprocessor v0.131.0/go.mod h1:hM44pzNNfE4qpj9bNdaxSs6EMSvMUl/W6N8YcJIo3LU=
+github.com/onsi/gomega v1.38.2 h1:eZCjf2xjZAqe+LeWvKb5weQ+NcPwX84kqJ0cZNxok2A=
+github.com/onsi/gomega v1.38.2/go.mod h1:W2MJcYxRGV63b418Ai34Ud0hEdTVXq9NW9+Sx6uXf3k=
+github.com/open-telemetry/opentelemetry-collector-contrib/pkg/sampling v0.145.0 h1:7rdLY2Ewa1WVnjMfJTEKwQ5uPDHYeA1tqNPNROi957U=
+github.com/open-telemetry/opentelemetry-collector-contrib/pkg/sampling v0.145.0/go.mod h1:jYlQAaJO4ZyJAW2jcKAbjN+nt5BRCyu49mlZv4Rui7U=
+github.com/open-telemetry/opentelemetry-collector-contrib/processor/probabilisticsamplerprocessor v0.145.0 h1:12mxn+8YLeAjMZ1kLGulBcvHrdhRNUmxLVIDnaLkJbQ=
+github.com/open-telemetry/opentelemetry-collector-contrib/processor/probabilisticsamplerprocessor v0.145.0/go.mod h1:V87HYJpfmvCeQ6Cjy3Q4xylxfCn2wVSS80wvv5ECc0s=
github.com/opencontainers/go-digest v1.0.0 h1:apOUWs51W5PlhuyGyz9FCeeBIOUDA/6nW8Oi/yOhh5U=
github.com/opencontainers/go-digest v1.0.0/go.mod h1:0JzlMkj0TRzQZfJkVvzbP0HBR3IKzErnv2BNG4W4MAM=
github.com/opencontainers/image-spec v1.1.1 h1:y0fUlFfIZhPF1W537XOLg0/fcx6zcHCJwooC2xJA040=
@@ -498,6 +508,9 @@ github.com/patrickmn/go-cache v2.1.0+incompatible h1:HRMgzkcYKYpi3C8ajMPV8OFXaaR
github.com/patrickmn/go-cache v2.1.0+incompatible/go.mod h1:3Qf8kWWT7OJRJbdiICTKqZju1ZixQ/KpMGzzAfe6+WQ=
github.com/pelletier/go-toml/v2 v2.2.4 h1:mye9XuhQ6gvn5h28+VilKrrPoQVanw5PMw/TB0t5Ec4=
github.com/pelletier/go-toml/v2 v2.2.4/go.mod h1:2gIqNv+qfxSVS7cM2xJQKtLSTLUE9V8t9Stt+h56mCY=
+github.com/petermattis/goid v0.0.0-20250813065127-a731cc31b4fe/go.mod h1:pxMtw7cyUw6B2bRH0ZBANSPg+AoSud1I1iyJHI69jH4=
+github.com/petermattis/goid v0.0.0-20260226131333-17d1149c6ac6 h1:rh2lKw/P/EqHa724vYH2+VVQ1YnW4u6EOXl0PMAovZE=
+github.com/petermattis/goid v0.0.0-20260226131333-17d1149c6ac6/go.mod h1:pxMtw7cyUw6B2bRH0ZBANSPg+AoSud1I1iyJHI69jH4=
github.com/philhofer/fwd v1.2.0 h1:e6DnBTl7vGY+Gz322/ASL4Gyp1FspeMvx1RNDoToZuM=
github.com/philhofer/fwd v1.2.0/go.mod h1:RqIHx9QI14HlwKwm98g9Re5prTQ6LdeRQn+gXJFxsJM=
github.com/pierrec/lz4/v4 v4.1.27 h1:+PhzhWDrjRj89TH2sw43nE3+4+W8lSxIuQadEHZyjUk=
@@ -535,15 +548,15 @@ github.com/prometheus/common v0.4.1/go.mod h1:TNfzLD0ON7rHzMJeJkieUDPYmFC7Snx/y8
github.com/prometheus/common v0.9.1/go.mod h1:yhUN8i9wzaXS3w1O07YhxHEBxD+W35wd8bs7vj7HSQ4=
github.com/prometheus/common v0.10.0/go.mod h1:Tlit/dnDKsSWFlCLTWaA1cyBgKHSMdTB80sz/V91rCo=
github.com/prometheus/common v0.26.0/go.mod h1:M7rCNAaPfAosfx8veZJCuw84e35h3Cfd9VFqTh1DIvc=
-github.com/prometheus/common v0.66.1 h1:h5E0h5/Y8niHc5DlaLlWLArTQI7tMrsfQjHV+d9ZoGs=
-github.com/prometheus/common v0.66.1/go.mod h1:gcaUsgf3KfRSwHY4dIMXLPV0K/Wg1oZ8+SbZk/HH/dA=
+github.com/prometheus/common v0.67.5 h1:pIgK94WWlQt1WLwAC5j2ynLaBRDiinoAb86HZHTUGI4=
+github.com/prometheus/common v0.67.5/go.mod h1:SjE/0MzDEEAyrdr5Gqc6G+sXI67maCxzaT3A2+HqjUw=
github.com/prometheus/procfs v0.0.0-20181005140218-185b4288413d/go.mod h1:c3At6R/oaqEKCNdg8wHV1ftS6bRYblBhIjjI8uT2IGk=
github.com/prometheus/procfs v0.0.2/go.mod h1:TjEm7ze935MbeOT/UhFTIMYKhuLP4wbCsTZCD3I8kEA=
github.com/prometheus/procfs v0.0.8/go.mod h1:7Qr8sr6344vo1JqZ6HhLceV9o3AJ1Ff+GxbHq6oeK9A=
github.com/prometheus/procfs v0.1.3/go.mod h1:lV6e/gmhEcM9IjHGsFOCxxuZ+z1YqCvr4OA4YeYWdaU=
github.com/prometheus/procfs v0.6.0/go.mod h1:cz+aTbrPOrUb4q7XlbU9ygM+/jj0fzG6c1xBZuNvfVA=
-github.com/prometheus/procfs v0.17.0 h1:FuLQ+05u4ZI+SS/w9+BWEM2TXiHKsUQ9TADiRH7DuK0=
-github.com/prometheus/procfs v0.17.0/go.mod h1:oPQLaDAMRbA+u8H5Pbfq+dl3VDAvHxMUOVhe0wYB2zw=
+github.com/prometheus/procfs v0.19.2 h1:zUMhqEW66Ex7OXIiDkll3tl9a1ZdilUOd/F6ZXw4Vws=
+github.com/prometheus/procfs v0.19.2/go.mod h1:M0aotyiemPhBCM0z5w87kL22CxfcH05ZpYlu+b4J7mw=
github.com/puzpuzpuz/xsync/v3 v3.5.1 h1:GJYJZwO6IdxN/IKbneznS6yPkVC+c3zyY/j19c++5Fg=
github.com/puzpuzpuz/xsync/v3 v3.5.1/go.mod h1:VjzYrABPabuM4KyBh1Ftq6u8nhwY5tBPKP9jpmh0nnA=
github.com/remyoudompheng/bigfft v0.0.0-20230129092748-24d4a6f8daec h1:W09IVJc94icq4NjY3clb7Lk8O1qJ8BdBEF8z0ibU0rE=
@@ -561,10 +574,10 @@ github.com/sagikazarmark/locafero v0.12.0 h1:/NQhBAkUb4+fH1jivKHWusDYFjMOOKU88ee
github.com/sagikazarmark/locafero v0.12.0/go.mod h1:sZh36u/YSZ918v0Io+U9ogLYQJ9tLLBmM4eneO6WwsI=
github.com/sean-/seed v0.0.0-20170313163322-e2103e2c3529 h1:nn5Wsu0esKSJiIVhscUtVbo7ada43DJhG55ua/hjS5I=
github.com/sean-/seed v0.0.0-20170313163322-e2103e2c3529/go.mod h1:DxrIzT+xaE7yg65j358z/aeFdxmN0P9QXhEzd20vsDc=
-github.com/secure-systems-lab/go-securesystemslib v0.9.1 h1:nZZaNz4DiERIQguNy0cL5qTdn9lR8XKHf4RUyG1Sx3g=
-github.com/secure-systems-lab/go-securesystemslib v0.9.1/go.mod h1:np53YzT0zXGMv6x4iEWc9Z59uR+x+ndLwCLqPYpLXVU=
-github.com/shirou/gopsutil/v4 v4.25.8 h1:NnAsw9lN7587WHxjJA9ryDnqhJpFH6A+wagYWTOH970=
-github.com/shirou/gopsutil/v4 v4.25.8/go.mod h1:q9QdMmfAOVIw7a+eF86P7ISEU6ka+NLgkUxlopV4RwI=
+github.com/secure-systems-lab/go-securesystemslib v0.10.0 h1:l+H5ErcW0PAehBNrBxoGv1jjNpGYdZ9RcheFkB2WI14=
+github.com/secure-systems-lab/go-securesystemslib v0.10.0/go.mod h1:MRKONWmRoFzPNQ9USRF9i1mc7MvAVvF1LlW8X5VWDvk=
+github.com/shirou/gopsutil/v4 v4.26.2 h1:X8i6sicvUFih4BmYIGT1m2wwgw2VG9YgrDTi7cIRGUI=
+github.com/shirou/gopsutil/v4 v4.26.2/go.mod h1:LZ6ewCSkBqUpvSOf+LsTGnRinC6iaNUNMGBtDkJBaLQ=
github.com/sirupsen/logrus v1.2.0/go.mod h1:LxeOpSwHxABJmUn/MG1IvRgCAasNZTLOkJPxbbu5VWo=
github.com/sirupsen/logrus v1.4.2/go.mod h1:tLMulIdttU9McNUspp0xgXVQah82FyeX6MwdIuYE2rE=
github.com/sirupsen/logrus v1.6.0/go.mod h1:7uNnSEd1DgxDLC74fIahvMZmmYsHGZGEOFrfsX/uA88=
@@ -583,8 +596,8 @@ github.com/spf13/afero v1.15.0 h1:b/YBCLWAJdFWJTN9cLhiXXcD7mzKn9Dm86dNnfyQw1I=
github.com/spf13/afero v1.15.0/go.mod h1:NC2ByUVxtQs4b3sIUphxK0NioZnmxgyCrfzeuq8lxMg=
github.com/spf13/cast v1.10.0 h1:h2x0u2shc1QuLHfxi+cTJvs30+ZAHOGRic8uyGTDWxY=
github.com/spf13/cast v1.10.0/go.mod h1:jNfB8QC9IA6ZuY2ZjDp0KtFO2LZZlg4S/7bzP6qqeHo=
-github.com/spf13/cobra v1.10.1 h1:lJeBwCfmrnXthfAupyUTzJ/J4Nc1RsHC/mSRU2dll/s=
-github.com/spf13/cobra v1.10.1/go.mod h1:7SmJGaTHFVBY0jW4NXGluQoLvhqFQM+6XSKD+P4XaB0=
+github.com/spf13/cobra v1.10.2 h1:DMTTonx5m65Ic0GOoRY2c16WCbHxOOw6xxezuLaBpcU=
+github.com/spf13/cobra v1.10.2/go.mod h1:7C1pvHqHw5A4vrJfjNwvOdzYu0Gml16OCs2GRiTUUS4=
github.com/spf13/jwalterweatherman v1.1.0 h1:ue6voC5bR5F8YxI5S67j9i582FU4Qvo2bmqnqMYADFk=
github.com/spf13/jwalterweatherman v1.1.0/go.mod h1:aNWZUN0dPAAO/Ljvb5BEdw96iTZ0EXowPYD95IqWIGo=
github.com/spf13/pflag v1.0.9/go.mod h1:McXfInJRrz4CZXVZOBLb0bTZqETkiAhM9Iw0y3An2Bg=
@@ -592,8 +605,8 @@ github.com/spf13/pflag v1.0.10 h1:4EBh2KAYBwaONj6b2Ye1GiHfwjqyROoF4RwYO+vPwFk=
github.com/spf13/pflag v1.0.10/go.mod h1:McXfInJRrz4CZXVZOBLb0bTZqETkiAhM9Iw0y3An2Bg=
github.com/spf13/viper v1.21.0 h1:x5S+0EU27Lbphp4UKm1C+1oQO+rKx36vfCoaVebLFSU=
github.com/spf13/viper v1.21.0/go.mod h1:P0lhsswPGWD/1lZJ9ny3fYnVqxiegrlNrEmgLjbTCAY=
-github.com/spiffe/go-spiffe/v2 v2.6.0 h1:l+DolpxNWYgruGQVV0xsfeya3CsC7m8iBzDnMpsbLuo=
-github.com/spiffe/go-spiffe/v2 v2.6.0/go.mod h1:gm2SeUoMZEtpnzPNs2Csc0D/gX33k1xIx7lEzqblHEs=
+github.com/spiffe/go-spiffe/v2 v2.7.0 h1:uXe1MflJoHw58wAUvxVlcM7WpKtijWG7I1UidcGh6g4=
+github.com/spiffe/go-spiffe/v2 v2.7.0/go.mod h1:47Q0Q9/AqGha8QLHp+kxpH4Wca7X7EnOtlIJy3mxZ3U=
github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
github.com/stretchr/objx v0.1.1/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
github.com/stretchr/objx v0.4.0/go.mod h1:YvHI0jy2hoMjB+UWwv71VJQ9isScKT/TqJzVSSt89Yw=
@@ -609,6 +622,7 @@ github.com/stretchr/testify v1.7.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/
github.com/stretchr/testify v1.7.2/go.mod h1:R6va5+xMeoiuVRoj+gSkQ7d3FALtqAAGI1FQKckRals=
github.com/stretchr/testify v1.8.0/go.mod h1:yNjHg4UonilssWZ8iaSj1OCr/vHnekPRkoO+kdMU+MU=
github.com/stretchr/testify v1.8.1/go.mod h1:w2LPCIKwWwSfY2zedu0+kehJoqGctiVI29o6fzry7u4=
+github.com/stretchr/testify v1.8.4/go.mod h1:sz/lmYIOXD/1dqDmKjjqLyZ2RngseejIcXlSw2iwfAo=
github.com/stretchr/testify v1.11.1 h1:7s2iGBzp5EwR7/aIZr8ao5+dra3wiQyKjjFuvgVKu7U=
github.com/stretchr/testify v1.11.1/go.mod h1:wZwfW3scLgRK+23gO65QZefKpKQRnfz6sD981Nm4B6U=
github.com/subosito/gotenv v1.6.0 h1:9NlTDc1FTs4qu0DDq7AEtTPNw6SVm7uBMsUCUjABIf8=
@@ -623,12 +637,14 @@ github.com/tidwall/match v1.2.0/go.mod h1:eRSPERbgtNPcGhD8UCthc6PmLEQXEWd3PRB5JT
github.com/tidwall/pretty v1.2.0/go.mod h1:ITEVvHYasfjBbM0u2Pg8T2nJnzm8xPwvNhhsoaGGjNU=
github.com/tidwall/pretty v1.2.1 h1:qjsOFOWWQl+N3RsoF5/ssm1pHmJJwhjlSbZ51I6wMl4=
github.com/tidwall/pretty v1.2.1/go.mod h1:ITEVvHYasfjBbM0u2Pg8T2nJnzm8xPwvNhhsoaGGjNU=
-github.com/tinylib/msgp v1.4.0 h1:SYOeDRiydzOw9kSiwdYp9UcBgPFtLU2WDHaJXyHruf8=
-github.com/tinylib/msgp v1.4.0/go.mod h1:cvjFkb4RiC8qSBOPMGPSzSAx47nAsfhLVTCZZNuHv5o=
-github.com/tklauser/go-sysconf v0.3.15 h1:VE89k0criAymJ/Os65CSn1IXaol+1wrsFHEB8Ol49K4=
-github.com/tklauser/go-sysconf v0.3.15/go.mod h1:Dmjwr6tYFIseJw7a3dRLJfsHAMXZ3nEnL/aZY+0IuI4=
-github.com/tklauser/numcpus v0.10.0 h1:18njr6LDBk1zuna922MgdjQuJFjrdppsZG60sHGfjso=
-github.com/tklauser/numcpus v0.10.0/go.mod h1:BiTKazU708GQTYF4mB+cmlpT2Is1gLk7XVuEeem8LsQ=
+github.com/tinylib/msgp v1.6.3 h1:bCSxiTz386UTgyT1i0MSCvdbWjVW+8sG3PjkGsZQt4s=
+github.com/tinylib/msgp v1.6.3/go.mod h1:RSp0LW9oSxFut3KzESt5Voq4GVWyS+PSulT77roAqEA=
+github.com/tklauser/go-sysconf v0.3.16 h1:frioLaCQSsF5Cy1jgRBrzr6t502KIIwQ0MArYICU0nA=
+github.com/tklauser/go-sysconf v0.3.16/go.mod h1:/qNL9xxDhc7tx3HSRsLWNnuzbVfh3e7gh/BmM179nYI=
+github.com/tklauser/numcpus v0.11.0 h1:nSTwhKH5e1dMNsCdVBukSZrURJRoHbSEQjdEbY+9RXw=
+github.com/tklauser/numcpus v0.11.0/go.mod h1:z+LwcLq54uWZTX0u/bGobaV34u6V7KNlTZejzM6/3MQ=
+github.com/trailofbits/go-mutexasserts v0.0.0-20250514102930-c1f3d2e37561 h1:qqa3P9AtNn6RMe90l/lxd3eJWnIRxjI4eb5Rx8xqCLA=
+github.com/trailofbits/go-mutexasserts v0.0.0-20250514102930-c1f3d2e37561/go.mod h1:GA3+Mq3kt3tYAfM0WZCu7ofy+GW9PuGysHfhr+6JX7s=
github.com/tv42/httpunix v0.0.0-20150427012821-b75d8614f926/go.mod h1:9ESjWnEqriFuLhtthL60Sar/7RFoluCcXsuvEwTV5KM=
github.com/uber/jaeger-client-go v2.30.0+incompatible h1:D6wyKGCecFaSRUpo8lCVbaOOb6ThwMmTEbhRwtKR97o=
github.com/uber/jaeger-client-go v2.30.0+incompatible/go.mod h1:WVhlPFC8FDjOFMMWRy2pZqQJSXxYSwNYOkTr/Z6d3Kk=
@@ -659,68 +675,68 @@ go.etcd.io/etcd/client/v3 v3.5.25 h1:Secqbl/DeksaY8Tg+984FDdRR8XWnxgXksjPrSFm5Lc
go.etcd.io/etcd/client/v3 v3.5.25/go.mod h1:6QqI2Y9iqtIaUTS55285OyZqpF1QLCghATMEx1mhS0I=
go.opentelemetry.io/auto/sdk v1.2.1 h1:jXsnJ4Lmnqd11kwkBV2LgLoFMZKizbCi5fNZ/ipaZ64=
go.opentelemetry.io/auto/sdk v1.2.1/go.mod h1:KRTj+aOaElaLi+wW1kO/DZRXwkF4C5xPbEe3ZiIhN7Y=
-go.opentelemetry.io/collector/component v1.42.0 h1:on4XJ/NT1oPnuCVKDEtlpcr3GGPAS9taWBe8woHSTmY=
-go.opentelemetry.io/collector/component v1.42.0/go.mod h1:mehIbkABLhEEs3kmAqer2GRmLwcQLoeF7C48CR6lxP0=
-go.opentelemetry.io/collector/component/componentstatus v0.131.0 h1:IVsyN0melBQU3QAabLj3ey1QQ+K2e8PhIcPRXH+LfiI=
-go.opentelemetry.io/collector/component/componentstatus v0.131.0/go.mod h1:DotgEZNwPF9Ug2YKk2+zBlmGW4hRTJ7k7YBkZoM4xL4=
-go.opentelemetry.io/collector/component/componenttest v0.131.0 h1:pvBENFUdOSIikdIExUP2+2B4K3LbZIqdUI7Kh7jNGxI=
-go.opentelemetry.io/collector/component/componenttest v0.131.0/go.mod h1:5RdiTb/UaiCp1RvKH2+B6SyggGNvcY8Yd5799lJcEe4=
-go.opentelemetry.io/collector/consumer v1.37.0 h1:RqTqEcc95Fg7T3MRPPjUX2nxzn1X88yfFUQV+AjdMK0=
-go.opentelemetry.io/collector/consumer v1.37.0/go.mod h1:vDA1JDXeb7vnQ02PXIjjR6dI9LTaya+Qr89Nyt2Gl7Y=
-go.opentelemetry.io/collector/consumer/consumertest v0.131.0 h1:+lgAblWlItsaWhUW10mKCmt3vTrmwvAWRSTrvrPgN/Q=
-go.opentelemetry.io/collector/consumer/consumertest v0.131.0/go.mod h1:t7eH0dWqxAeIPtyvzT7mOJTKM9km2YEMjFCtaIeIl/w=
-go.opentelemetry.io/collector/consumer/xconsumer v0.131.0 h1:PgCoBVF5FN87Ef2wDqLpRU7QxxIDs8dNiy9jKNdpWzk=
-go.opentelemetry.io/collector/consumer/xconsumer v0.131.0/go.mod h1:xh1XRXcwk4Hxm3KSUCw/IOA0dyEoZr7Q/h0gzLnYaQo=
-go.opentelemetry.io/collector/featuregate v1.42.0 h1:uCVwumVBVex46DsG/fvgiTGuf9f53bALra7vGyKaqFI=
-go.opentelemetry.io/collector/featuregate v1.42.0/go.mod h1:d0tiRzVYrytB6LkcYgz2ESFTv7OktRPQe0QEQcPt1L4=
-go.opentelemetry.io/collector/internal/telemetry v0.136.0 h1:3TcnxyUFs6jJZeLo5ju3fMWS4lRmIApl9To2XWk922M=
-go.opentelemetry.io/collector/internal/telemetry v0.136.0/go.mod h1:dTykH9zv/zOnlyUvqfGIqpaQZhmayW7NssD7TPU4paE=
-go.opentelemetry.io/collector/pdata v1.42.0 h1:XEzisp/SNfKDcY4aRU6qrHeLzGypRUdYHjbBqkDFOO4=
-go.opentelemetry.io/collector/pdata v1.42.0/go.mod h1:nnOmgf+RI/D5xYWgFPZ5nKuhf2E0Qy9Nx/mxoTvIq3k=
-go.opentelemetry.io/collector/pdata/pprofile v0.131.0 h1:eQ2Yq1g6wOWHjRXum9Fm0dZax/klNmjtpL7UPsEXrPo=
-go.opentelemetry.io/collector/pdata/pprofile v0.131.0/go.mod h1:g4IuRFVGC89n/2bTdw0CuMJkkCY4zDb0Hu37wCKlx0c=
-go.opentelemetry.io/collector/pdata/testdata v0.131.0 h1:ARWgM7MMg5D4qwp1hLTfd8BS3H1tUWwQ9iVCMeAoJ+o=
-go.opentelemetry.io/collector/pdata/testdata v0.131.0/go.mod h1:cagnzOua8bdn2m4zz0DQSehR5vVe7M5JazkZs8J5nMo=
-go.opentelemetry.io/collector/pipeline v1.42.0 h1:jqn1lPwUdCn+lsyNubCtwzXZLEm+R3kRWxLpDkhlvvs=
-go.opentelemetry.io/collector/pipeline v1.42.0/go.mod h1:xUrAqiebzYbrgxyoXSkk6/Y3oi5Sy3im2iCA51LwUAI=
-go.opentelemetry.io/collector/processor v1.37.0 h1:yUQfHHZFs94BZNCamYx+WoN0VoN7MVEDwlU1H/pHISU=
-go.opentelemetry.io/collector/processor v1.37.0/go.mod h1:TdCjl4QiiQ/JIcvonAGbXB7/cU1Sb8O7KrkN0sBmW3s=
-go.opentelemetry.io/collector/processor/processorhelper v0.131.0 h1:4otHyECTsRsz9yd4d6diTKb11j4fYtjgz6+PbR0CF7A=
-go.opentelemetry.io/collector/processor/processorhelper v0.131.0/go.mod h1:KAkP+oNGkZxOmfafz8osEerOY/lHJm/R55TaVyncBUM=
-go.opentelemetry.io/collector/processor/processortest v0.131.0 h1:Yj5LHMHjpd795k6KR0iyRWOZ+/LT6un4IVh41xgFsr4=
-go.opentelemetry.io/collector/processor/processortest v0.131.0/go.mod h1:CNdxqDm+QOEpgovxOG2YrFZ5ldqe5R5lTOUMAByl5wI=
-go.opentelemetry.io/collector/processor/xprocessor v0.131.0 h1:l2BjdmCr+1H7dat42fhxq45Um5Tbq7BQqjCIVTD5nyU=
-go.opentelemetry.io/collector/processor/xprocessor v0.131.0/go.mod h1:uNo0JRtxJNepop+QB105ASX8MkvyusoIZYIUTm00epE=
-go.opentelemetry.io/contrib/bridges/otelzap v0.13.0 h1:aBKdhLVieqvwWe9A79UHI/0vgp2t/s2euY8X59pGRlw=
-go.opentelemetry.io/contrib/bridges/otelzap v0.13.0/go.mod h1:SYqtxLQE7iINgh6WFuVi2AI70148B8EI35DSk0Wr8m4=
-go.opentelemetry.io/contrib/detectors/gcp v1.38.0 h1:ZoYbqX7OaA/TAikspPl3ozPI6iY6LiIY9I8cUfm+pJs=
-go.opentelemetry.io/contrib/detectors/gcp v1.38.0/go.mod h1:SU+iU7nu5ud4oCb3LQOhIZ3nRLj6FNVrKgtflbaf2ts=
+go.opentelemetry.io/collector/component v1.51.1-0.20260205185216-81bc641f26c0 h1:ZSlXxE90IY0Cl53RTqzyEgRgRPLTeTNBdGhaTmvj9eY=
+go.opentelemetry.io/collector/component v1.51.1-0.20260205185216-81bc641f26c0/go.mod h1:944C7vEIdk13Pn1fBbyaU8C1qKf2XC0jRBlc69NAsRY=
+go.opentelemetry.io/collector/component/componentstatus v0.145.0 h1:EwUZfSaagdpRXnlrb0TqReJXXW2p9HWBU5YiIeXPCAE=
+go.opentelemetry.io/collector/component/componentstatus v0.145.0/go.mod h1:OiYb8rT4FtSJPFSGCKYvOaajdueDUTJZncixGrmy5aM=
+go.opentelemetry.io/collector/component/componenttest v0.145.1-0.20260205185216-81bc641f26c0 h1:+VCK6wX/WN170dcaWJweRAkxpmAEyVucfrUV13NwUlY=
+go.opentelemetry.io/collector/component/componenttest v0.145.1-0.20260205185216-81bc641f26c0/go.mod h1:U2wUjKMGwgqM49/q8ORkzzYzSWY2m6zpG/e606eK1wc=
+go.opentelemetry.io/collector/consumer v1.51.1-0.20260205185216-81bc641f26c0 h1:WNkJ1bKnRVAEJtBm1bwEkoLG2x7GyANc3/OnErZJ338=
+go.opentelemetry.io/collector/consumer v1.51.1-0.20260205185216-81bc641f26c0/go.mod h1:Erk6qdfVj+24QTrGCpurcrF+qdUlHkb4dgMy5wJxLvY=
+go.opentelemetry.io/collector/consumer/consumertest v0.145.1-0.20260205185216-81bc641f26c0 h1:FHyDIlTbqt0Y6tDI9EbI3hr9uWthwkeLY7uGF1jZYqQ=
+go.opentelemetry.io/collector/consumer/consumertest v0.145.1-0.20260205185216-81bc641f26c0/go.mod h1:IFc/FeaIHQClb8KK0aVn0tFDNMc+/MmfQ+aBT1cJNeo=
+go.opentelemetry.io/collector/consumer/xconsumer v0.145.1-0.20260205185216-81bc641f26c0 h1:zg2Jqfy7n7o/LEmLsXB4sFhxWtOEMFCKRyQUFLFUS9M=
+go.opentelemetry.io/collector/consumer/xconsumer v0.145.1-0.20260205185216-81bc641f26c0/go.mod h1:SryDCLP2ZaFeZJtA2CSksJ0XvjH8k3LmlfXvy/kC7Wc=
+go.opentelemetry.io/collector/featuregate v1.51.1-0.20260205185216-81bc641f26c0 h1:fOXhfT2xKqNhfalTXaT/Wic9EBRK8+9ZH0y8phReQS4=
+go.opentelemetry.io/collector/featuregate v1.51.1-0.20260205185216-81bc641f26c0/go.mod h1:/1bclXgP91pISaEeNulRxzzmzMTm4I5Xih2SnI4HRSo=
+go.opentelemetry.io/collector/internal/componentalias v0.145.1-0.20260205185216-81bc641f26c0 h1:s4/vCxeIxgQpuWmX1AK1DRbZmEdmNBq925EKES8ebiI=
+go.opentelemetry.io/collector/internal/componentalias v0.145.1-0.20260205185216-81bc641f26c0/go.mod h1:Z0TtMbzaMp2qhj1dw4toya8toyQzqoTF46/WhJXplVw=
+go.opentelemetry.io/collector/internal/testutil v0.145.0 h1:H/KL0GH3kGqSMKxZvnQ0B0CulfO9xdTg4DZf28uV7fY=
+go.opentelemetry.io/collector/internal/testutil v0.145.0/go.mod h1:YAD9EAkwh/l5asZNbEBEUCqEjoL1OKMjAMoPjPqH76c=
+go.opentelemetry.io/collector/pdata v1.51.1-0.20260205185216-81bc641f26c0 h1:8tgf9W3aW3vFabyVxPNHKsaoyUytudfVOQbqZI9xBHQ=
+go.opentelemetry.io/collector/pdata v1.51.1-0.20260205185216-81bc641f26c0/go.mod h1:GoX1bjKDR++mgFKdT7Hynv9+mdgQ1DDXbjs7/Ww209Q=
+go.opentelemetry.io/collector/pdata/pprofile v0.145.1-0.20260205185216-81bc641f26c0 h1:MJcnK8txYZlqHZyfZ1rVf66kt5/kEveIdR6KX//BY1Y=
+go.opentelemetry.io/collector/pdata/pprofile v0.145.1-0.20260205185216-81bc641f26c0/go.mod h1:a60GC7wQPhLAixWzKbbP51QLwwc+J0Cmp4SurOlhGUk=
+go.opentelemetry.io/collector/pdata/testdata v0.145.0 h1:iFsxsCMtE3lnAc/5kZbhZHpRv1OMmM+O5ry46xdQHbg=
+go.opentelemetry.io/collector/pdata/testdata v0.145.0/go.mod h1:0y2ERArdzqmYdJHdKLKue+AUubSEGlwK49F+23+Mbic=
+go.opentelemetry.io/collector/pipeline v1.51.1-0.20260205185216-81bc641f26c0 h1:1KP5gXGF9qN1mEzJupZDUQVIND35qe/0Hy6Cptvdk0s=
+go.opentelemetry.io/collector/pipeline v1.51.1-0.20260205185216-81bc641f26c0/go.mod h1:xUrAqiebzYbrgxyoXSkk6/Y3oi5Sy3im2iCA51LwUAI=
+go.opentelemetry.io/collector/processor v1.51.0 h1:PKpCzkLQmqaW08TOVh/zM0qx07Ihq+DR5J/OBkPiL9o=
+go.opentelemetry.io/collector/processor v1.51.0/go.mod h1:rtIPFS+EFRAkG+CSwtjxs2IsIkuZStObvALeueD02XI=
+go.opentelemetry.io/collector/processor/processorhelper v0.145.0 h1:vXdv6lHz20Tm3ZEsg0i6jPZJBQgy9kzk/PuqWhHWiiM=
+go.opentelemetry.io/collector/processor/processorhelper v0.145.0/go.mod h1:3Ecpe5jHRHGf24EvJHeJ/ekK/a1DLByyq0CSUxjjURg=
+go.opentelemetry.io/collector/processor/processortest v0.145.0 h1:RDGBmyZnHk7XVK/EdLt/8iPWj+QLStbbVi1nFTNR01s=
+go.opentelemetry.io/collector/processor/processortest v0.145.0/go.mod h1:WAvxAzSojkdoZB915Z1lsVHCPDJBb2fepjJBjenrzjg=
+go.opentelemetry.io/collector/processor/xprocessor v0.145.0 h1:DaIE7MxRlg0OL1o2P0GQZtmZeExAmVso3qWv8S0RLps=
+go.opentelemetry.io/collector/processor/xprocessor v0.145.0/go.mod h1:kUwRyKBU/kjCmXodd+0z7CpvcP0A9G9/QL+MaJt4U2o=
+go.opentelemetry.io/contrib/detectors/gcp v1.44.0 h1:NmLfL734pJhM0JKaYd2Y28+nY9dPRWYAAbxhRCrKXPw=
+go.opentelemetry.io/contrib/detectors/gcp v1.44.0/go.mod h1:tNAsgd8avTGke1+MndXlU5Cru4PQ9Ai/cCNWQv/ZJ/s=
go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc v0.63.0 h1:YH4g8lQroajqUwWbq/tr2QX1JFmEXaDLgG+ew9bLMWo=
go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc v0.63.0/go.mod h1:fvPi2qXDqFs8M4B4fmJhE92TyQs9Ydjlg3RvfUp+NbQ=
-go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.63.0 h1:RbKq8BG0FI8OiXhBfcRtqqHcZcka+gU3cskNuf05R18=
-go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.63.0/go.mod h1:h06DGIukJOevXaj/xrNjhi/2098RZzcLTbc0jDAUbsg=
-go.opentelemetry.io/otel v1.38.0 h1:RkfdswUDRimDg0m2Az18RKOsnI8UDzppJAtj01/Ymk8=
-go.opentelemetry.io/otel v1.38.0/go.mod h1:zcmtmQ1+YmQM9wrNsTGV/q/uyusom3P8RxwExxkZhjM=
-go.opentelemetry.io/otel/exporters/stdout/stdoutmetric v1.36.0 h1:rixTyDGXFxRy1xzhKrotaHy3/KXdPhlWARrCgK+eqUY=
-go.opentelemetry.io/otel/exporters/stdout/stdoutmetric v1.36.0/go.mod h1:dowW6UsM9MKbJq5JTz2AMVp3/5iW5I/TStsk8S+CfHw=
-go.opentelemetry.io/otel/log v0.14.0 h1:2rzJ+pOAZ8qmZ3DDHg73NEKzSZkhkGIua9gXtxNGgrM=
-go.opentelemetry.io/otel/log v0.14.0/go.mod h1:5jRG92fEAgx0SU/vFPxmJvhIuDU9E1SUnEQrMlJpOno=
-go.opentelemetry.io/otel/log/logtest v0.14.0 h1:BGTqNeluJDK2uIHAY8lRqxjVAYfqgcaTbVk1n3MWe5A=
-go.opentelemetry.io/otel/log/logtest v0.14.0/go.mod h1:IuguGt8XVP4XA4d2oEEDMVDBBCesMg8/tSGWDjuKfoA=
-go.opentelemetry.io/otel/metric v1.38.0 h1:Kl6lzIYGAh5M159u9NgiRkmoMKjvbsKtYRwgfrA6WpA=
-go.opentelemetry.io/otel/metric v1.38.0/go.mod h1:kB5n/QoRM8YwmUahxvI3bO34eVtQf2i4utNVLr9gEmI=
-go.opentelemetry.io/otel/sdk v1.38.0 h1:l48sr5YbNf2hpCUj/FoGhW9yDkl+Ma+LrVl8qaM5b+E=
-go.opentelemetry.io/otel/sdk v1.38.0/go.mod h1:ghmNdGlVemJI3+ZB5iDEuk4bWA3GkTpW+DOoZMYBVVg=
-go.opentelemetry.io/otel/sdk/metric v1.38.0 h1:aSH66iL0aZqo//xXzQLYozmWrXxyFkBJ6qT5wthqPoM=
-go.opentelemetry.io/otel/sdk/metric v1.38.0/go.mod h1:dg9PBnW9XdQ1Hd6ZnRz689CbtrUp0wMMs9iPcgT9EZA=
-go.opentelemetry.io/otel/trace v1.38.0 h1:Fxk5bKrDZJUH+AMyyIXGcFAPah0oRcT+LuNtJrmcNLE=
-go.opentelemetry.io/otel/trace v1.38.0/go.mod h1:j1P9ivuFsTceSWe1oY+EeW3sc+Pp42sO++GHkg4wwhs=
-go.opentelemetry.io/proto/slim/otlp v1.8.0 h1:afcLwp2XOeCbGrjufT1qWyruFt+6C9g5SOuymrSPUXQ=
-go.opentelemetry.io/proto/slim/otlp v1.8.0/go.mod h1:Yaa5fjYm1SMCq0hG0x/87wV1MP9H5xDuG/1+AhvBcsI=
-go.opentelemetry.io/proto/slim/otlp/collector/profiles/v1development v0.1.0 h1:Uc+elixz922LHx5colXGi1ORbsW8DTIGM+gg+D9V7HE=
-go.opentelemetry.io/proto/slim/otlp/collector/profiles/v1development v0.1.0/go.mod h1:VyU6dTWBWv6h9w/+DYgSZAPMabWbPTFTuxp25sM8+s0=
-go.opentelemetry.io/proto/slim/otlp/profiles/v1development v0.1.0 h1:i8YpvWGm/Uq1koL//bnbJ/26eV3OrKWm09+rDYo7keU=
-go.opentelemetry.io/proto/slim/otlp/profiles/v1development v0.1.0/go.mod h1:pQ70xHY/ZVxNUBPn+qUWPl8nwai87eWdqL3M37lNi9A=
+go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.64.0 h1:ssfIgGNANqpVFCndZvcuyKbl0g+UAVcbBcqGkG28H0Y=
+go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.64.0/go.mod h1:GQ/474YrbE4Jx8gZ4q5I4hrhUzM6UPzyrqJYV2AqPoQ=
+go.opentelemetry.io/otel v1.45.0 h1:pdrWmLHofpubmArBv1LgFSv1Z0Ie/ppdZzu+kUN5EeU=
+go.opentelemetry.io/otel v1.45.0/go.mod h1:XZxIqPapzEYnhNSScF5DIqXhm/rYi0FzCe2XddAwZfQ=
+go.opentelemetry.io/otel/exporters/stdout/stdoutmetric v1.39.0 h1:5gn2urDL/FBnK8OkCfD1j3/ER79rUuTYmCvlXBKeYL8=
+go.opentelemetry.io/otel/exporters/stdout/stdoutmetric v1.39.0/go.mod h1:0fBG6ZJxhqByfFZDwSwpZGzJU671HkwpWaNe2t4VUPI=
+go.opentelemetry.io/otel/metric v1.45.0 h1:7Eg1uH7CJ5cXv9is6tnBe1FI6rj1nwUdbFypRm3br/M=
+go.opentelemetry.io/otel/metric v1.45.0/go.mod h1:HAPbm1nd3p1PmFH7v2dR+6BjXxw+Lq4a2+pndMAm08s=
+go.opentelemetry.io/otel/metric/x v0.67.0 h1:PcicCNZFkZ4bXfSooXdo3WN7RBOVOtjVdo1wD358Uns=
+go.opentelemetry.io/otel/metric/x v0.67.0/go.mod h1:FBjCWZe6wgcqxcMtjdGiClDKXb2YxxXii0CXftE4QtI=
+go.opentelemetry.io/otel/sdk v1.45.0 h1:4VVSMgQ83dUgW2aoX5f6JgLvHwIvzcuLnF9lUdCSpCw=
+go.opentelemetry.io/otel/sdk v1.45.0/go.mod h1:Sr40LgXV7DsKMMJMKOhUWOgMWTfAaqvm2kF0g7ilwuA=
+go.opentelemetry.io/otel/sdk/metric v1.45.0 h1:oVFszMfyj1Am6s24Vtc7wBb8BKLcwepJjNEYILuiE3o=
+go.opentelemetry.io/otel/sdk/metric v1.45.0/go.mod h1:vUWUxDZvu1WVRj8JA8S0AdhsPrZoDpA2DdZauIh4mDA=
+go.opentelemetry.io/otel/trace v1.45.0 h1:l/mP6Uv7oNO7/TblbhpbgMidxhq1uO/rPsikOyVhxag=
+go.opentelemetry.io/otel/trace v1.45.0/go.mod h1:qoJJA2xNMnxRrdISU/kLtfUH2wNeQbiv+jhs/CxI8bc=
+go.opentelemetry.io/proto/otlp v1.9.0 h1:l706jCMITVouPOqEnii2fIAuO3IVGBRPV5ICjceRb/A=
+go.opentelemetry.io/proto/otlp v1.9.0/go.mod h1:xE+Cx5E/eEHw+ISFkwPLwCZefwVjY+pqKg1qcK03+/4=
+go.opentelemetry.io/proto/slim/otlp v1.9.0 h1:fPVMv8tP3TrsqlkH1HWYUpbCY9cAIemx184VGkS6vlE=
+go.opentelemetry.io/proto/slim/otlp v1.9.0/go.mod h1:xXdeJJ90Gqyll+orzUkY4bOd2HECo5JofeoLpymVqdI=
+go.opentelemetry.io/proto/slim/otlp/collector/profiles/v1development v0.2.0 h1:o13nadWDNkH/quoDomDUClnQBpdQQ2Qqv0lQBjIXjE8=
+go.opentelemetry.io/proto/slim/otlp/collector/profiles/v1development v0.2.0/go.mod h1:Gyb6Xe7FTi/6xBHwMmngGoHqL0w29Y4eW8TGFzpefGA=
+go.opentelemetry.io/proto/slim/otlp/profiles/v1development v0.2.0 h1:EiUYvtwu6PMrMHVjcPfnsG3v+ajPkbUeH+IL93+QYyk=
+go.opentelemetry.io/proto/slim/otlp/profiles/v1development v0.2.0/go.mod h1:mUUHKFiN2SST3AhJ8XhJxEoeVW12oqfXog0Bo8W3Ec4=
go.uber.org/atomic v1.7.0/go.mod h1:fEN4uk6kAWBTFdckzkM89CLk9XfWZrxpCo0nPH17wJc=
go.uber.org/atomic v1.9.0/go.mod h1:fEN4uk6kAWBTFdckzkM89CLk9XfWZrxpCo0nPH17wJc=
go.uber.org/atomic v1.11.0 h1:ZvwS0R+56ePWxUNi+Atn9dWONBPp/AUETXlHW0DxSjE=
@@ -728,14 +744,14 @@ go.uber.org/atomic v1.11.0/go.mod h1:LUxbIzbOniOlMKjJjyPfpl4v+PKK2cNJn91OQbhoJI0
go.uber.org/goleak v1.1.10/go.mod h1:8a7PlsEVH3e/a/GLqe5IIrQx6GzcnRmZEufDUTk4A7A=
go.uber.org/goleak v1.3.0 h1:2K3zAYmnTNqV73imy9J1T3WC+gmCePx2hEGkimedGto=
go.uber.org/goleak v1.3.0/go.mod h1:CoHD4mav9JJNrW/WLlf7HGZPjdw8EucARQHekz1X6bE=
-go.uber.org/mock v0.5.0 h1:KAMbZvZPyBPWgD14IrIQ38QCyjwpvVVV6K/bHl1IwQU=
-go.uber.org/mock v0.5.0/go.mod h1:ge71pBPLYDk7QIi1LupWxdAykm7KIEFchiOqd6z7qMM=
+go.uber.org/mock v0.6.0 h1:hyF9dfmbgIX5EfOdasqLsWD6xqpNZlXblLB/Dbnwv3Y=
+go.uber.org/mock v0.6.0/go.mod h1:KiVJ4BqZJaMj4svdfmHM0AUx4NJYO8ZNpPnZn1Z+BBU=
go.uber.org/multierr v1.6.0/go.mod h1:cdWPpRnG4AhwMwsgIHip0KRBQjJy5kYEpYjJxpXp9iU=
go.uber.org/multierr v1.11.0 h1:blXXJkSxSSfBVBlC76pxqeO+LN3aDfLQo+309xJstO0=
go.uber.org/multierr v1.11.0/go.mod h1:20+QtiLqy0Nd6FdQB9TLXag12DsQkrbs3htMFfDN80Y=
go.uber.org/zap v1.18.1/go.mod h1:xg/QME4nWcxGxrpdeYfq7UvYrLh66cuVKdrbD1XF/NI=
-go.uber.org/zap v1.27.0 h1:aJMhYGrd5QSmlpLMr2MftRKl7t8J8PTZPA732ud/XR8=
-go.uber.org/zap v1.27.0/go.mod h1:GB2qFLM7cTU87MWRP2mPIjqfIDnGu+VIO4V/SdhGo2E=
+go.uber.org/zap v1.27.1 h1:08RqriUEv8+ArZRYSTXy1LeBScaMpVSTBhCeaZYfMYc=
+go.uber.org/zap v1.27.1/go.mod h1:GB2qFLM7cTU87MWRP2mPIjqfIDnGu+VIO4V/SdhGo2E=
go.yaml.in/yaml/v2 v2.4.3 h1:6gvOSjQoTB3vt1l+CU+tSyi/HOjfOjRLJ4YwYZGwRO0=
go.yaml.in/yaml/v2 v2.4.3/go.mod h1:zSxWcmIDjOzPXpjlTTbAsKokqkDNAVtZO0WOMiT90s8=
go.yaml.in/yaml/v3 v3.0.4 h1:tfq32ie2Jv2UxXFdLJdh3jXuOzWiL1fo0bu/FbuKpbc=
@@ -747,11 +763,11 @@ golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8U
golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
golang.org/x/crypto v0.0.0-20201002170205-7f63de1d35b0/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
golang.org/x/crypto v0.0.0-20201016220609-9e8e0b390897/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
-golang.org/x/crypto v0.45.0 h1:jMBrvKuj23MTlT0bQEOBcAE0mjg8mK9RXFhRH6nyF3Q=
-golang.org/x/crypto v0.45.0/go.mod h1:XTGrrkGJve7CYK7J8PEww4aY7gM3qMCElcJQ8n8JdX4=
+golang.org/x/crypto v0.55.0 h1:+KWHjbgOaAQ66dh/YlkZKHlz9ZUlq61AFirAR9ntP8M=
+golang.org/x/crypto v0.55.0/go.mod h1:uq0V9dE/fzQuJtbnL+2EhWOE63vo164FY8xqEnV9xis=
golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA=
-golang.org/x/exp v0.0.0-20250911091902-df9299821621 h1:2id6c1/gto0kaHYyrixvknJ8tUK/Qs5IsmBtrc+FtgU=
-golang.org/x/exp v0.0.0-20250911091902-df9299821621/go.mod h1:TwQYMMnGpvZyc+JpB/UAuTNIsVJifOlSkrZkhcvpVUk=
+golang.org/x/exp v0.0.0-20260209203927-2842357ff358 h1:kpfSV7uLwKJbFSEgNhWzGSL47NDSF/5pYYQw1V0ub6c=
+golang.org/x/exp v0.0.0-20260209203927-2842357ff358/go.mod h1:R3t0oliuryB5eenPWl3rrQxwnNM3WTwnsRZZiXLAAW8=
golang.org/x/lint v0.0.0-20181026193005-c67002cb31c3/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE=
golang.org/x/lint v0.0.0-20190227174305-5b3e6a55c961/go.mod h1:wehouNa3lNwaWXcvxsM5YxQ5yQlVC4a0KAMCusXpPoU=
golang.org/x/lint v0.0.0-20190313153728-d0100b6bd8b3/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc=
@@ -759,8 +775,8 @@ golang.org/x/lint v0.0.0-20190930215403-16217165b5de/go.mod h1:6SW0HCj/g11FgYtHl
golang.org/x/mod v0.2.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
golang.org/x/mod v0.3.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
golang.org/x/mod v0.4.2/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
-golang.org/x/mod v0.30.0 h1:fDEXFVZ/fmCKProc/yAXXUijritrDzahmwwefnjoPFk=
-golang.org/x/mod v0.30.0/go.mod h1:lAsf5O2EvJeSFMiBxXDki7sCgAxEUcZHXoXMKT4GJKc=
+golang.org/x/mod v0.38.0 h1:MECBjubtXD7yj4HrhIUcywNaGeNVUdfVnxmPajOk4yk=
+golang.org/x/mod v0.38.0/go.mod h1:V6Xz0pq8TQ3dGqVQ1FVHuelZpAL0uNhSkk9ogYP3c40=
golang.org/x/net v0.0.0-20180724234803-3673e40ba225/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
golang.org/x/net v0.0.0-20180826012351-8a410e7b638d/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
golang.org/x/net v0.0.0-20180906233101-161cd47e91fd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
@@ -780,12 +796,12 @@ golang.org/x/net v0.0.0-20201021035429-f5854403a974/go.mod h1:sp8m0HH+o8qH0wwXwY
golang.org/x/net v0.0.0-20201202161906-c7110b5ffcbb/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU=
golang.org/x/net v0.0.0-20210405180319-a5a99cb37ef4/go.mod h1:p54w0d4576C0XHj96bSt6lcn1PtDYWL6XObtHCRCNQM=
golang.org/x/net v0.0.0-20210610132358-84b48f89b13b/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y=
-golang.org/x/net v0.47.0 h1:Mx+4dIFzqraBXUugkia1OOvlD6LemFo1ALMHjrXDOhY=
-golang.org/x/net v0.47.0/go.mod h1:/jNxtkgq5yWUGYkaZGqo27cfGZ1c5Nen03aYrrKpVRU=
+golang.org/x/net v0.58.0 h1:ynWG7rqYi4ccpTEuPZ2QGWHktVEM9DMCj9yzDE0Q7To=
+golang.org/x/net v0.58.0/go.mod h1:YwCddHnFlT7eLQqVprV19OnhLGtc5xOKgE0RyqgfWAU=
golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U=
golang.org/x/oauth2 v0.0.0-20190226205417-e64efc72b421/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw=
-golang.org/x/oauth2 v0.33.0 h1:4Q+qn+E5z8gPRJfmRy7C2gGG3T4jIprK6aSYgTXGRpo=
-golang.org/x/oauth2 v0.33.0/go.mod h1:lzm5WQJQwKZ3nwavOZ3IS5Aulzxi68dUSgRHujetwEA=
+golang.org/x/oauth2 v0.36.0 h1:peZ/1z27fi9hUOFCAZaHyrpWG5lwe0RJEEEeH0ThlIs=
+golang.org/x/oauth2 v0.36.0/go.mod h1:YDBUJMTkDnJS+A4BP4eZBjCqtokkg1hODuPjwiGPO7Q=
golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sync v0.0.0-20181108010431-42b317875d0f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sync v0.0.0-20181221193216-37e7f081c4d4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
@@ -794,8 +810,8 @@ golang.org/x/sync v0.0.0-20190911185100-cd5d95a43a6e/go.mod h1:RxMgew5VJxzue5/jJ
golang.org/x/sync v0.0.0-20201020160332-67f06af15bc9/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sync v0.0.0-20201207232520-09787c993a3a/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sync v0.0.0-20210220032951-036812b2e83c/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
-golang.org/x/sync v0.18.0 h1:kr88TuHDroi+UVf+0hZnirlk8o8T+4MrK6mr60WkH/I=
-golang.org/x/sync v0.18.0/go.mod h1:9KTHXmSnoGruLpwFjVSX0lNNA75CykiMECbovNTZqGI=
+golang.org/x/sync v0.22.0 h1:SZjpbeLmrCk4xhRSZFNZW5gFUeCeFgjekvI/+gfScek=
+golang.org/x/sync v0.22.0/go.mod h1:9xrNwdLfx4jkKbNva9FpL6vEN7evnE43NNNJQ2LF3+0=
golang.org/x/sys v0.0.0-20180830151530-49385e6e1522/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
golang.org/x/sys v0.0.0-20180905080454-ebe1bf3edb33/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
golang.org/x/sys v0.0.0-20180909124046-d0be0721c37e/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
@@ -834,19 +850,19 @@ golang.org/x/sys v0.0.0-20220627191245-f75cf1eec38b/go.mod h1:oPkhp1MJrh7nUepCBc
golang.org/x/sys v0.0.0-20220715151400-c0bba94af5f8/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.1.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
-golang.org/x/sys v0.38.0 h1:3yZWxaJjBmCWXqhN1qh02AkOnCQ1poK6oF+a7xWL6Gc=
-golang.org/x/sys v0.38.0/go.mod h1:OgkHotnGiDImocRcuBABYBEXf8A9a87e/uXjp9XT3ks=
+golang.org/x/sys v0.47.0 h1:o7XGOvZQCADBQQ4Y7VNq2dRWQR7JmOUW8Kxx4ZsNgWs=
+golang.org/x/sys v0.47.0/go.mod h1:4GL1E5IUh+htKOUEOaiffhrAeqysfVGipDYzABqnCmw=
golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo=
-golang.org/x/term v0.37.0 h1:8EGAD0qCmHYZg6J17DvsMy9/wJ7/D/4pV/wfnld5lTU=
-golang.org/x/term v0.37.0/go.mod h1:5pB4lxRNYYVZuTLmy8oR2BH8dflOR+IbTYFD8fi3254=
+golang.org/x/term v0.45.0 h1:NwWyBmoJCbfTHpxrWoZ9C6/VxOf7ic219I8xZZFdrf0=
+golang.org/x/term v0.45.0/go.mod h1:9aqxs0blBcrm/n0L9QW0aRVD+ktan8ssZromtqJC43w=
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
golang.org/x/text v0.3.2/go.mod h1:bEr9sfX3Q8Zfm5fL9x+3itogRgK3+ptLWKqgva+5dAk=
golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
golang.org/x/text v0.3.6/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
-golang.org/x/text v0.31.0 h1:aC8ghyu4JhP8VojJ2lEHBnochRno1sgL6nEi9WGFGMM=
-golang.org/x/text v0.31.0/go.mod h1:tKRAlv61yKIjGGHX/4tP1LTbc13YSec1pxVEWXzfoeM=
-golang.org/x/time v0.13.0 h1:eUlYslOIt32DgYD6utsuUeHs4d7AsEYLuIAdg7FlYgI=
-golang.org/x/time v0.13.0/go.mod h1:eL/Oa2bBBK0TkX57Fyni+NgnyQQN4LitPmob2Hjnqw4=
+golang.org/x/text v0.41.0 h1:vz/seA0lnX87Othu2f/0L24RcgrXD9/YFTSuGjj3rH8=
+golang.org/x/text v0.41.0/go.mod h1:jvf1O8ajNzZqhSrQBPbutR/EB83Cc0CFrezNQIwbb5M=
+golang.org/x/time v0.15.0 h1:bbrp8t3bGUeFOx08pvsMYRTCVSMk89u4tKbNOZbp88U=
+golang.org/x/time v0.15.0/go.mod h1:Y4YMaQmXwGQZoFaVFk4YpCt4FLQMYKZe9oeV/f4MSno=
golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
golang.org/x/tools v0.0.0-20190114222345-bf090417da8b/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
golang.org/x/tools v0.0.0-20190226205152-f727befe758c/go.mod h1:9Yl7xja0Znq3iFh3HoIrodX9oNMXvdceNzlUR8zjMvY=
@@ -858,18 +874,18 @@ golang.org/x/tools v0.0.0-20200619180055-7c47624df98f/go.mod h1:EkVYQZoAsY45+roY
golang.org/x/tools v0.0.0-20201224043029-2b0845dc783e/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA=
golang.org/x/tools v0.0.0-20210106214847-113979e3529a/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA=
golang.org/x/tools v0.1.1/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk=
-golang.org/x/tools v0.39.0 h1:ik4ho21kwuQln40uelmciQPp9SipgNDdrafrYA4TmQQ=
-golang.org/x/tools v0.39.0/go.mod h1:JnefbkDPyD8UU2kI5fuf8ZX4/yUeh9W877ZeBONxUqQ=
+golang.org/x/tools v0.48.0 h1:3+hClM1aLL5mjMKm5ovokw9epgRXPuu2tILgismM6RE=
+golang.org/x/tools v0.48.0/go.mod h1:08xX0orndb/F7jJxGDicx061tyd5pcMto75YMAXr6lk=
golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
golang.org/x/xerrors v0.0.0-20240903120638-7835f813f4da h1:noIWHXmPHxILtqtCOPIhSt0ABwskkZKjD3bXGnZGpNY=
golang.org/x/xerrors v0.0.0-20240903120638-7835f813f4da/go.mod h1:NDW/Ps6MPRej6fsCIbMTohpP40sJ/P/vI1MoTEGwX90=
-gonum.org/v1/gonum v0.16.0 h1:5+ul4Swaf3ESvrOnidPp4GZbzf0mxVQpDCYUQE7OJfk=
-gonum.org/v1/gonum v0.16.0/go.mod h1:fef3am4MQ93R2HHpKnLk4/Tbh/s0+wqD5nfa6Pnwy4E=
-google.golang.org/api v0.251.0 h1:6lea5nHRT8RUmpy9kkC2PJYnhnDAB13LqrLSVQlMIE8=
-google.golang.org/api v0.251.0/go.mod h1:Rwy0lPf/TD7+T2VhYcffCHhyyInyuxGjICxdfLqT7KI=
+gonum.org/v1/gonum v0.17.0 h1:VbpOemQlsSMrYmn7T2OUvQ4dqxQXU+ouZFQsZOx50z4=
+gonum.org/v1/gonum v0.17.0/go.mod h1:El3tOrEuMpv2UdMrbNlKEh9vd86bmQ6vqIcDwxEOc1E=
+google.golang.org/api v0.264.0 h1:+Fo3DQXBK8gLdf8rFZ3uLu39JpOnhvzJrLMQSoSYZJM=
+google.golang.org/api v0.264.0/go.mod h1:fAU1xtNNisHgOF5JooAs8rRaTkl2rT3uaoNGo9NS3R8=
google.golang.org/appengine v1.1.0/go.mod h1:EbEs0AVv82hx2wNQdGPgUI5lhzA/G0D9YwlJXL52JkM=
google.golang.org/appengine v1.4.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4=
google.golang.org/appengine v1.6.8 h1:IhEN5q69dyKagZPYMSdIjS2HqprW324FRQZJcGqPAsM=
@@ -877,19 +893,19 @@ google.golang.org/appengine v1.6.8/go.mod h1:1jJ3jBArFh5pcgW8gCtRJnepW8FzD1V44FJ
google.golang.org/genproto v0.0.0-20180817151627-c66870c02cf8/go.mod h1:JiN7NxoALGmiZfu7CAH4rXhgtRTLTxftemlI0sWmxmc=
google.golang.org/genproto v0.0.0-20190819201941-24fa4b261c55/go.mod h1:DMBHOl98Agz4BDEuKkezgsaosCRResVns1a3J2ZsMNc=
google.golang.org/genproto v0.0.0-20200423170343-7949de9c1215/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c=
-google.golang.org/genproto v0.0.0-20250929231259-57b25ae835d4 h1:HmI33/XNQ1jVwhb5ZUgot40oiwFHa2l5ZNkQpj8VaEg=
-google.golang.org/genproto v0.0.0-20250929231259-57b25ae835d4/go.mod h1:OqVwZqqGV3h7k+YCVWXoTtwC2cs55RnDEUVMMadhxrc=
-google.golang.org/genproto/googleapis/api v0.0.0-20250929231259-57b25ae835d4 h1:8XJ4pajGwOlasW+L13MnEGA8W4115jJySQtVfS2/IBU=
-google.golang.org/genproto/googleapis/api v0.0.0-20250929231259-57b25ae835d4/go.mod h1:NnuHhy+bxcg30o7FnVAZbXsPHUDQ9qKWAQKCD7VxFtk=
-google.golang.org/genproto/googleapis/rpc v0.0.0-20250929231259-57b25ae835d4 h1:i8QOKZfYg6AbGVZzUAY3LrNWCKF8O6zFisU9Wl9RER4=
-google.golang.org/genproto/googleapis/rpc v0.0.0-20250929231259-57b25ae835d4/go.mod h1:HSkG/KdJWusxU1F6CNrwNDjBMgisKxGnc5dAZfT0mjQ=
+google.golang.org/genproto v0.0.0-20260128011058-8636f8732409 h1:VQZ/yAbAtjkHgH80teYd2em3xtIkkHd7ZhqfH2N9CsM=
+google.golang.org/genproto v0.0.0-20260128011058-8636f8732409/go.mod h1:rxKD3IEILWEu3P44seeNOAwZN4SaoKaQ/2eTg4mM6EM=
+google.golang.org/genproto/googleapis/api v0.0.0-20260526163538-3dc84a4a5aaa h1:Kjn0N0tCrDgiAFW+lGO4JZ3ck44CehvJQMAwj9QF0G8=
+google.golang.org/genproto/googleapis/api v0.0.0-20260526163538-3dc84a4a5aaa/go.mod h1:q4lMZS6kskjT5HvCPrnnypcDPVJqT/f4nfxmkE7gryY=
+google.golang.org/genproto/googleapis/rpc v0.0.0-20260526163538-3dc84a4a5aaa h1:mZHHdPZl0dbGHCflZgAq/Q468DWVFcU2whhB2KAo8fk=
+google.golang.org/genproto/googleapis/rpc v0.0.0-20260526163538-3dc84a4a5aaa/go.mod h1:4Hqkh8ycfw05ld/3BWL7rJOSfebL2Q+DVDeRgYgxUU8=
google.golang.org/grpc v1.19.0/go.mod h1:mqu4LbDTu4XGKhr4mRzUsmM4RtVoemTSY81AxZiDr8c=
google.golang.org/grpc v1.23.0/go.mod h1:Y5yQAOtifL1yxbo5wqy6BxZv8vAUGQwXBOALyacEbxg=
google.golang.org/grpc v1.25.1/go.mod h1:c3i+UQWmh7LiEpx4sFZnkU36qjEYZ0imhYfXVyQciAY=
google.golang.org/grpc v1.27.0/go.mod h1:qbnxyOmOxrQa7FizSgH+ReBfzJrCY1pSN7KXBS8abTk=
google.golang.org/grpc v1.29.1/go.mod h1:itym6AZVZYACWQqET3MqgPpjcuV5QH3BxFS3IjizoKk=
-google.golang.org/grpc v1.75.1 h1:/ODCNEuf9VghjgO3rqLcfg8fiOP0nSluljWFlDxELLI=
-google.golang.org/grpc v1.75.1/go.mod h1:JtPAzKiq4v1xcAB2hydNlWI2RnF85XXcV0mhKXr2ecQ=
+google.golang.org/grpc v1.83.2 h1:EManeRomTObA0BU7I8vXgg/78uE5MJ9M8B39EX2WscU=
+google.golang.org/grpc v1.83.2/go.mod h1:YPI1hK3kDked6iHvgX3tR0y+nX/qpMFKhPgFsokw1S8=
google.golang.org/grpc/cmd/protoc-gen-go-grpc v1.2.0 h1:TLkBREm4nIsEcexnCjgQd5GQWaHcqMzwQV0TX9pq8S0=
google.golang.org/grpc/cmd/protoc-gen-go-grpc v1.2.0/go.mod h1:DNq5QpG7LJqD2AamLZ7zvKE0DEpVl2BSEVjFycAAjRY=
google.golang.org/grpc/examples v0.0.0-20250407062114-b368379ef8f6 h1:ExN12ndbJ608cboPYflpTny6mXSzPrDLh0iTaVrRrds=
@@ -902,10 +918,10 @@ google.golang.org/protobuf v1.21.0/go.mod h1:47Nbq4nVaFHyn7ilMalzfO3qCViNmqZ2kzi
google.golang.org/protobuf v1.23.0/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU=
google.golang.org/protobuf v1.26.0-rc.1/go.mod h1:jlhhOSvTdKEhbULTjvd4ARK9grFBp09yW+WbY/TyQbw=
google.golang.org/protobuf v1.27.1/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQnmE0givc=
-google.golang.org/protobuf v1.36.9 h1:w2gp2mA27hUeUzj9Ex9FBjsBm40zfaDtEWow293U7Iw=
-google.golang.org/protobuf v1.36.9/go.mod h1:fuxRtAxBytpl4zzqUh6/eyUujkJdNiuEkXntxiD/uRU=
-gopkg.in/DataDog/dd-trace-go.v1 v1.74.6 h1:VBxCK/WkaNjsM9Ygn57scwmiwMqF0gEbuE4C5c2TU5E=
-gopkg.in/DataDog/dd-trace-go.v1 v1.74.6/go.mod h1:jQL1vSDZhH+DJWUOYjkRQ+kU1HUXPvUK41gS1AvHOTE=
+google.golang.org/protobuf v1.36.11 h1:fV6ZwhNocDyBLK0dj+fg8ektcVegBBuEolpbTQyBNVE=
+google.golang.org/protobuf v1.36.11/go.mod h1:HTf+CrKn2C3g5S8VImy6tdcUvCska2kB7j23XfzDpco=
+gopkg.in/DataDog/dd-trace-go.v1 v1.74.8 h1:h96ji92t9eXbPvSWhJ+lrPWetHiQNYlt48JKRO09NFA=
+gopkg.in/DataDog/dd-trace-go.v1 v1.74.8/go.mod h1:LpHbtHsCZBlm1HWrlVOUQcEXwMWZnU6yMvmtd1GvSDI=
gopkg.in/alecthomas/kingpin.v2 v2.2.6/go.mod h1:FMv+mEhP44yOT+4EoQTLFTRgOQ1FBLkstjWtayDeSgw=
gopkg.in/asn1-ber.v1 v1.0.0-20181015200546-f715ec2f112d h1:TxyelI5cVkbREznMhfzycHdkp5cLA7DpE+GKjSslYhM=
gopkg.in/asn1-ber.v1 v1.0.0-20181015200546-f715ec2f112d/go.mod h1:cuepJuh7vyXfUyUwEgHQXw849cJrilpS5NeIjOWESAw=
@@ -916,8 +932,8 @@ gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c h1:Hei/4ADfdWqJk1ZMxUNpqntN
gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c/go.mod h1:JHkPIbrfpd72SG/EVd6muEfDQjcINNoR0C8j2r3qZ4Q=
gopkg.in/fsnotify.v1 v1.4.7/go.mod h1:Tz8NjZHkW78fSQdbUxIjBTcgA1z1m8ZHf0WmKUhAMys=
gopkg.in/ini.v1 v1.41.0/go.mod h1:pNLf8WUiyNEtQjuu5G5vTm06TEv9tsIgeAvK8hOrP4k=
-gopkg.in/ini.v1 v1.67.0 h1:Dgnx+6+nfE+IfzjUEISNeydPJh9AXNNsWbGP9KzCsOA=
-gopkg.in/ini.v1 v1.67.0/go.mod h1:pNLf8WUiyNEtQjuu5G5vTm06TEv9tsIgeAvK8hOrP4k=
+gopkg.in/ini.v1 v1.67.1 h1:tVBILHy0R6e4wkYOn3XmiITt/hEVH4TFMYvAX2Ytz6k=
+gopkg.in/ini.v1 v1.67.1/go.mod h1:x/cyOwCgZqOkJoDIJ3c1KNHMo10+nLGAhh+kn3Zizss=
gopkg.in/ldap.v2 v2.5.1 h1:wiu0okdNfjlBzg6UWvd1Hn8Y+Ux17/u/4nlk4CQr6tU=
gopkg.in/ldap.v2 v2.5.1/go.mod h1:oI0cpe/D7HRtBQl8aTg+ZmzFUAvu4lsv3eLXMLGFxWk=
gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7 h1:uRGJdciOHaEIrze2W8Q3AKkepLTh2hOroT7a+7czfdQ=
@@ -938,8 +954,8 @@ gotest.tools/v3 v3.5.2 h1:7koQfIKdy+I8UTetycgUqXWSDwpgv193Ka+qRsmBY8Q=
gotest.tools/v3 v3.5.2/go.mod h1:LtdLGcnqToBH83WByAAi/wiwSFCArdFIUV/xxN4pcjA=
honnef.co/go/tools v0.0.0-20190102054323-c2f93a96b099/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4=
honnef.co/go/tools v0.0.0-20190523083050-ea95bdfd59fc/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4=
-k8s.io/apimachinery v0.33.4 h1:SOf/JW33TP0eppJMkIgQ+L6atlDiP/090oaX0y9pd9s=
-k8s.io/apimachinery v0.33.4/go.mod h1:BHW0YOu7n22fFv/JkYOEfkUYNRN0fj0BlvMFWA7b+SM=
+k8s.io/apimachinery v0.35.1 h1:yxO6gV555P1YV0SANtnTjXYfiivaTPvCTKX6w6qdDsU=
+k8s.io/apimachinery v0.35.1/go.mod h1:jQCgFZFR1F4Ik7hvr2g84RTJSZegBc8yHgFWKn//hns=
modernc.org/cc/v4 v4.26.5 h1:xM3bX7Mve6G8K8b+T11ReenJOT+BmVqQj0FY5T4+5Y4=
modernc.org/cc/v4 v4.26.5/go.mod h1:uVtb5OGqUKpoLWhqwNQo/8LwvoiEBLvZXIQ/SmO6mL0=
modernc.org/ccgo/v4 v4.28.1 h1:wPKYn5EC/mYTqBO373jKjvX2n+3+aK7+sICCv4Fjy1A=
diff --git a/go/vt/proto/binlogdata/binlogdata.pb.go b/go/vt/proto/binlogdata/binlogdata.pb.go
index a35f5439698..4995f032824 100644
--- a/go/vt/proto/binlogdata/binlogdata.pb.go
+++ b/go/vt/proto/binlogdata/binlogdata.pb.go
@@ -19,7 +19,7 @@
// Code generated by protoc-gen-go. DO NOT EDIT.
// versions:
-// protoc-gen-go v1.36.9
+// protoc-gen-go v1.36.11
// protoc v3.21.3
// source: binlogdata.proto
diff --git a/go/vt/proto/binlogservice/binlogservice.pb.go b/go/vt/proto/binlogservice/binlogservice.pb.go
index 363f8123c0e..d9669eab454 100644
--- a/go/vt/proto/binlogservice/binlogservice.pb.go
+++ b/go/vt/proto/binlogservice/binlogservice.pb.go
@@ -19,7 +19,7 @@
// Code generated by protoc-gen-go. DO NOT EDIT.
// versions:
-// protoc-gen-go v1.36.9
+// protoc-gen-go v1.36.11
// protoc v3.21.3
// source: binlogservice.proto
diff --git a/go/vt/proto/logutil/logutil.pb.go b/go/vt/proto/logutil/logutil.pb.go
index 23c1f6472b7..d0ee4088017 100644
--- a/go/vt/proto/logutil/logutil.pb.go
+++ b/go/vt/proto/logutil/logutil.pb.go
@@ -17,7 +17,7 @@
// Code generated by protoc-gen-go. DO NOT EDIT.
// versions:
-// protoc-gen-go v1.36.9
+// protoc-gen-go v1.36.11
// protoc v3.21.3
// source: logutil.proto
diff --git a/go/vt/proto/mysqlctl/mysqlctl.pb.go b/go/vt/proto/mysqlctl/mysqlctl.pb.go
index ccbefc9af64..c97c75df867 100644
--- a/go/vt/proto/mysqlctl/mysqlctl.pb.go
+++ b/go/vt/proto/mysqlctl/mysqlctl.pb.go
@@ -18,7 +18,7 @@
// Code generated by protoc-gen-go. DO NOT EDIT.
// versions:
-// protoc-gen-go v1.36.9
+// protoc-gen-go v1.36.11
// protoc v3.21.3
// source: mysqlctl.proto
diff --git a/go/vt/proto/query/query.pb.go b/go/vt/proto/query/query.pb.go
index 6d225ffe225..9799f9f0776 100644
--- a/go/vt/proto/query/query.pb.go
+++ b/go/vt/proto/query/query.pb.go
@@ -18,7 +18,7 @@
// Code generated by protoc-gen-go. DO NOT EDIT.
// versions:
-// protoc-gen-go v1.36.9
+// protoc-gen-go v1.36.11
// protoc v3.21.3
// source: query.proto
diff --git a/go/vt/proto/queryservice/queryservice.pb.go b/go/vt/proto/queryservice/queryservice.pb.go
index fc19fd9e66b..af1c5bbec2e 100644
--- a/go/vt/proto/queryservice/queryservice.pb.go
+++ b/go/vt/proto/queryservice/queryservice.pb.go
@@ -17,7 +17,7 @@
// Code generated by protoc-gen-go. DO NOT EDIT.
// versions:
-// protoc-gen-go v1.36.9
+// protoc-gen-go v1.36.11
// protoc v3.21.3
// source: queryservice.proto
diff --git a/go/vt/proto/replicationdata/replicationdata.pb.go b/go/vt/proto/replicationdata/replicationdata.pb.go
index 5079a71b4eb..5e9055ee6a9 100644
--- a/go/vt/proto/replicationdata/replicationdata.pb.go
+++ b/go/vt/proto/replicationdata/replicationdata.pb.go
@@ -17,7 +17,7 @@
// Code generated by protoc-gen-go. DO NOT EDIT.
// versions:
-// protoc-gen-go v1.36.9
+// protoc-gen-go v1.36.11
// protoc v3.21.3
// source: replicationdata.proto
diff --git a/go/vt/proto/tableacl/tableacl.pb.go b/go/vt/proto/tableacl/tableacl.pb.go
index 2064a1baaf0..76d3ccb04ff 100644
--- a/go/vt/proto/tableacl/tableacl.pb.go
+++ b/go/vt/proto/tableacl/tableacl.pb.go
@@ -17,7 +17,7 @@
// Code generated by protoc-gen-go. DO NOT EDIT.
// versions:
-// protoc-gen-go v1.36.9
+// protoc-gen-go v1.36.11
// protoc v3.21.3
// source: tableacl.proto
diff --git a/go/vt/proto/tabletmanagerdata/tabletmanagerdata.pb.go b/go/vt/proto/tabletmanagerdata/tabletmanagerdata.pb.go
index 6cad59cd6fe..849e8c7aade 100644
--- a/go/vt/proto/tabletmanagerdata/tabletmanagerdata.pb.go
+++ b/go/vt/proto/tabletmanagerdata/tabletmanagerdata.pb.go
@@ -18,7 +18,7 @@
// Code generated by protoc-gen-go. DO NOT EDIT.
// versions:
-// protoc-gen-go v1.36.9
+// protoc-gen-go v1.36.11
// protoc v3.21.3
// source: tabletmanagerdata.proto
diff --git a/go/vt/proto/tabletmanagerservice/tabletmanagerservice.pb.go b/go/vt/proto/tabletmanagerservice/tabletmanagerservice.pb.go
index 17cb23c3761..c472dc673c5 100644
--- a/go/vt/proto/tabletmanagerservice/tabletmanagerservice.pb.go
+++ b/go/vt/proto/tabletmanagerservice/tabletmanagerservice.pb.go
@@ -18,7 +18,7 @@
// Code generated by protoc-gen-go. DO NOT EDIT.
// versions:
-// protoc-gen-go v1.36.9
+// protoc-gen-go v1.36.11
// protoc v3.21.3
// source: tabletmanagerservice.proto
diff --git a/go/vt/proto/throttlerdata/throttlerdata.pb.go b/go/vt/proto/throttlerdata/throttlerdata.pb.go
index 0e1065c95cd..d6efc282772 100644
--- a/go/vt/proto/throttlerdata/throttlerdata.pb.go
+++ b/go/vt/proto/throttlerdata/throttlerdata.pb.go
@@ -17,7 +17,7 @@
// Code generated by protoc-gen-go. DO NOT EDIT.
// versions:
-// protoc-gen-go v1.36.9
+// protoc-gen-go v1.36.11
// protoc v3.21.3
// source: throttlerdata.proto
diff --git a/go/vt/proto/throttlerservice/throttlerservice.pb.go b/go/vt/proto/throttlerservice/throttlerservice.pb.go
index f88e889c6b8..8d1fa04006e 100644
--- a/go/vt/proto/throttlerservice/throttlerservice.pb.go
+++ b/go/vt/proto/throttlerservice/throttlerservice.pb.go
@@ -18,7 +18,7 @@
// Code generated by protoc-gen-go. DO NOT EDIT.
// versions:
-// protoc-gen-go v1.36.9
+// protoc-gen-go v1.36.11
// protoc v3.21.3
// source: throttlerservice.proto
diff --git a/go/vt/proto/topodata/topodata.pb.go b/go/vt/proto/topodata/topodata.pb.go
index cdbc9c31e15..c0423ad6572 100644
--- a/go/vt/proto/topodata/topodata.pb.go
+++ b/go/vt/proto/topodata/topodata.pb.go
@@ -20,7 +20,7 @@
// Code generated by protoc-gen-go. DO NOT EDIT.
// versions:
-// protoc-gen-go v1.36.9
+// protoc-gen-go v1.36.11
// protoc v3.21.3
// source: topodata.proto
diff --git a/go/vt/proto/vschema/vschema.pb.go b/go/vt/proto/vschema/vschema.pb.go
index af63a3f8a12..3c90ad91132 100644
--- a/go/vt/proto/vschema/vschema.pb.go
+++ b/go/vt/proto/vschema/vschema.pb.go
@@ -17,7 +17,7 @@
// Code generated by protoc-gen-go. DO NOT EDIT.
// versions:
-// protoc-gen-go v1.36.9
+// protoc-gen-go v1.36.11
// protoc v3.21.3
// source: vschema.proto
diff --git a/go/vt/proto/vtadmin/vtadmin.pb.go b/go/vt/proto/vtadmin/vtadmin.pb.go
index cf94afba3f0..4232dc95256 100644
--- a/go/vt/proto/vtadmin/vtadmin.pb.go
+++ b/go/vt/proto/vtadmin/vtadmin.pb.go
@@ -17,7 +17,7 @@
// Code generated by protoc-gen-go. DO NOT EDIT.
// versions:
-// protoc-gen-go v1.36.9
+// protoc-gen-go v1.36.11
// protoc v3.21.3
// source: vtadmin.proto
diff --git a/go/vt/proto/vtctldata/vtctldata.pb.go b/go/vt/proto/vtctldata/vtctldata.pb.go
index 1508392963f..54b50947508 100644
--- a/go/vt/proto/vtctldata/vtctldata.pb.go
+++ b/go/vt/proto/vtctldata/vtctldata.pb.go
@@ -18,7 +18,7 @@
// Code generated by protoc-gen-go. DO NOT EDIT.
// versions:
-// protoc-gen-go v1.36.9
+// protoc-gen-go v1.36.11
// protoc v3.21.3
// source: vtctldata.proto
diff --git a/go/vt/proto/vtctlservice/vtctlservice.pb.go b/go/vt/proto/vtctlservice/vtctlservice.pb.go
index 778059ae294..0122b939cba 100644
--- a/go/vt/proto/vtctlservice/vtctlservice.pb.go
+++ b/go/vt/proto/vtctlservice/vtctlservice.pb.go
@@ -18,7 +18,7 @@
// Code generated by protoc-gen-go. DO NOT EDIT.
// versions:
-// protoc-gen-go v1.36.9
+// protoc-gen-go v1.36.11
// protoc v3.21.3
// source: vtctlservice.proto
diff --git a/go/vt/proto/vtgate/vtgate.pb.go b/go/vt/proto/vtgate/vtgate.pb.go
index b616d0aa6ad..fd6cdc301d9 100644
--- a/go/vt/proto/vtgate/vtgate.pb.go
+++ b/go/vt/proto/vtgate/vtgate.pb.go
@@ -17,7 +17,7 @@
// Code generated by protoc-gen-go. DO NOT EDIT.
// versions:
-// protoc-gen-go v1.36.9
+// protoc-gen-go v1.36.11
// protoc v3.21.3
// source: vtgate.proto
diff --git a/go/vt/proto/vtgateservice/vtgateservice.pb.go b/go/vt/proto/vtgateservice/vtgateservice.pb.go
index 8fc5de70c7d..c2db636e9ce 100644
--- a/go/vt/proto/vtgateservice/vtgateservice.pb.go
+++ b/go/vt/proto/vtgateservice/vtgateservice.pb.go
@@ -18,7 +18,7 @@
// Code generated by protoc-gen-go. DO NOT EDIT.
// versions:
-// protoc-gen-go v1.36.9
+// protoc-gen-go v1.36.11
// protoc v3.21.3
// source: vtgateservice.proto
diff --git a/go/vt/proto/vtorcdata/vtorcdata.pb.go b/go/vt/proto/vtorcdata/vtorcdata.pb.go
index e5cb87a455b..9707f2c7cf9 100644
--- a/go/vt/proto/vtorcdata/vtorcdata.pb.go
+++ b/go/vt/proto/vtorcdata/vtorcdata.pb.go
@@ -20,7 +20,7 @@
// Code generated by protoc-gen-go. DO NOT EDIT.
// versions:
-// protoc-gen-go v1.36.9
+// protoc-gen-go v1.36.11
// protoc v3.21.3
// source: vtorcdata.proto
diff --git a/go/vt/proto/vtrpc/vtrpc.pb.go b/go/vt/proto/vtrpc/vtrpc.pb.go
index ebc091ea4e8..a4a39ec3867 100644
--- a/go/vt/proto/vtrpc/vtrpc.pb.go
+++ b/go/vt/proto/vtrpc/vtrpc.pb.go
@@ -17,7 +17,7 @@
// Code generated by protoc-gen-go. DO NOT EDIT.
// versions:
-// protoc-gen-go v1.36.9
+// protoc-gen-go v1.36.11
// protoc v3.21.3
// source: vtrpc.proto
diff --git a/go/vt/proto/vttest/vttest.pb.go b/go/vt/proto/vttest/vttest.pb.go
index ffb7c519e9f..0bf3f6355e4 100644
--- a/go/vt/proto/vttest/vttest.pb.go
+++ b/go/vt/proto/vttest/vttest.pb.go
@@ -41,7 +41,7 @@
// Code generated by protoc-gen-go. DO NOT EDIT.
// versions:
-// protoc-gen-go v1.36.9
+// protoc-gen-go v1.36.11
// protoc v3.21.3
// source: vttest.proto
diff --git a/go/vt/proto/vttime/vttime.pb.go b/go/vt/proto/vttime/vttime.pb.go
index 3672062d102..048f1c61d62 100644
--- a/go/vt/proto/vttime/vttime.pb.go
+++ b/go/vt/proto/vttime/vttime.pb.go
@@ -17,7 +17,7 @@
// Code generated by protoc-gen-go. DO NOT EDIT.
// versions:
-// protoc-gen-go v1.36.9
+// protoc-gen-go v1.36.11
// protoc v3.21.3
// source: vttime.proto
From 1dc8e7c2913c046c5d640f89592e536d32e6098b Mon Sep 17 00:00:00 2001
From: "vitess-bot[bot]" <108069721+vitess-bot[bot]@users.noreply.github.com>
Date: Wed, 14 Oct 2026 12:47:48 +0200
Subject: [PATCH 04/31] [release-23.0] ci: upload release packages with the gh
CLI (#21565) (#21588)
Signed-off-by: Arthur Schreiber
Co-authored-by: vitess-bot[bot] <108069721+vitess-bot[bot]@users.noreply.github.com>
Co-authored-by: Claude Opus 5.5
---
.github/workflows/create_release.yml | 9 +++++----
1 file changed, 5 insertions(+), 4 deletions(-)
diff --git a/.github/workflows/create_release.yml b/.github/workflows/create_release.yml
index 90179299416..e86ff049c74 100644
--- a/.github/workflows/create_release.yml
+++ b/.github/workflows/create_release.yml
@@ -64,7 +64,8 @@ jobs:
./tools/make-release-packages.sh
- name: Upload Files
- uses: csexton/release-asset-action@3567794e918fa3068116688122a76cdeb57b5f09 # v3
- with:
- github-token: ${{ secrets.GITHUB_TOKEN }}
- pattern: "releases/*.{tar.gz,rpm,deb}"
+ env:
+ GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
+ TAG: ${{ github.event.release.tag_name }}
+ run: |
+ gh release upload "$TAG" releases/*.{tar.gz,rpm,deb} --repo "$GITHUB_REPOSITORY"
From b7848c1f2e773932a859ec1ef949876365949299 Mon Sep 17 00:00:00 2001
From: "vitess-bot[bot]" <108069721+vitess-bot[bot]@users.noreply.github.com>
Date: Wed, 14 Oct 2026 13:04:00 +0200
Subject: [PATCH 05/31] [release-23.0] docker: use `ENV key=value` in the
remaining Dockerfiles (#21569) (#21586)
Signed-off-by: Arthur Schreiber
Co-authored-by: vitess-bot[bot] <108069721+vitess-bot[bot]@users.noreply.github.com>
Co-authored-by: Claude Opus 5.5
---
docker/binaries/logtail/Dockerfile | 2 +-
docker/binaries/mysqlctl/Dockerfile | 4 ++--
docker/binaries/mysqlctld/Dockerfile | 4 ++--
docker/binaries/vtadmin/Dockerfile | 2 +-
docker/binaries/vtbackup/Dockerfile | 4 ++--
docker/binaries/vtctl/Dockerfile | 2 +-
docker/binaries/vtctld/Dockerfile | 2 +-
docker/binaries/vtexplain/Dockerfile | 2 +-
docker/binaries/vtgate/Dockerfile | 2 +-
docker/binaries/vtorc/Dockerfile | 2 +-
docker/binaries/vttablet/Dockerfile | 4 ++--
docker/mini/Dockerfile | 6 +++---
docker/vttestserver/Dockerfile.mysql80 | 6 +++---
docker/vttestserver/Dockerfile.mysql84 | 6 +++---
14 files changed, 24 insertions(+), 24 deletions(-)
diff --git a/docker/binaries/logtail/Dockerfile b/docker/binaries/logtail/Dockerfile
index b64fe5b3b6f..a488d294d80 100644
--- a/docker/binaries/logtail/Dockerfile
+++ b/docker/binaries/logtail/Dockerfile
@@ -16,7 +16,7 @@ ARG DEBIAN_VER=stable-slim
FROM debian:${DEBIAN_VER}
-ENV TAIL_FILEPATH /dev/null
+ENV TAIL_FILEPATH=/dev/null
COPY tail.sh /vt/tail.sh
diff --git a/docker/binaries/mysqlctl/Dockerfile b/docker/binaries/mysqlctl/Dockerfile
index 72c80c6363b..e56832e73c6 100644
--- a/docker/binaries/mysqlctl/Dockerfile
+++ b/docker/binaries/mysqlctl/Dockerfile
@@ -20,8 +20,8 @@ FROM vitess/lite:${VT_BASE_VER} AS lite
FROM debian:${DEBIAN_VER}
# Set up Vitess environment (just enough to run pre-built Go binaries)
-ENV VTROOT /vt
-ENV VTDATAROOT /vtdataroot
+ENV VTROOT=/vt
+ENV VTDATAROOT=/vtdataroot
# Prepare directory structure.
RUN mkdir -p /vt/bin && \
diff --git a/docker/binaries/mysqlctld/Dockerfile b/docker/binaries/mysqlctld/Dockerfile
index 81909b9f092..f1bb82c8fd9 100644
--- a/docker/binaries/mysqlctld/Dockerfile
+++ b/docker/binaries/mysqlctld/Dockerfile
@@ -27,8 +27,8 @@ RUN apt-get update && \
rm -rf /var/lib/apt/lists/*
# Set up Vitess environment (just enough to run pre-built Go binaries)
-ENV VTROOT /vt
-ENV VTDATAROOT /vtdataroot
+ENV VTROOT=/vt
+ENV VTDATAROOT=/vtdataroot
# Prepare directory structure.
RUN mkdir -p /vt/bin && \
diff --git a/docker/binaries/vtadmin/Dockerfile b/docker/binaries/vtadmin/Dockerfile
index c51527c1f39..0c79284650b 100644
--- a/docker/binaries/vtadmin/Dockerfile
+++ b/docker/binaries/vtadmin/Dockerfile
@@ -34,7 +34,7 @@ FROM nginxinc/nginx-unprivileged:1.22 AS nginx
ENV VTADMIN_WEB_PORT=14201
# Set up Vitess environment (just enough to run pre-built Go binaries)
-ENV VTROOT /vt
+ENV VTROOT=/vt
# Copy binaries
COPY --from=lite /vt/bin/vtadmin /vt/bin/
diff --git a/docker/binaries/vtbackup/Dockerfile b/docker/binaries/vtbackup/Dockerfile
index 3b429928cb4..5ed2f1a0898 100644
--- a/docker/binaries/vtbackup/Dockerfile
+++ b/docker/binaries/vtbackup/Dockerfile
@@ -21,8 +21,8 @@ FROM vitess/lite:${VT_BASE_VER} AS lite
FROM debian:${DEBIAN_VER}
# Set up Vitess environment (just enough to run pre-built Go binaries)
-ENV VTROOT /vt
-ENV VTDATAROOT /vtdataroot
+ENV VTROOT=/vt
+ENV VTDATAROOT=/vtdataroot
# Prepare directory structure.
RUN mkdir -p /vt/bin && mkdir -p /vtdataroot
diff --git a/docker/binaries/vtctl/Dockerfile b/docker/binaries/vtctl/Dockerfile
index 21ca6aaf77c..5e00b867932 100644
--- a/docker/binaries/vtctl/Dockerfile
+++ b/docker/binaries/vtctl/Dockerfile
@@ -20,7 +20,7 @@ FROM vitess/lite:${VT_BASE_VER} AS lite
FROM debian:${DEBIAN_VER}
# Set up Vitess environment (just enough to run pre-built Go binaries)
-ENV VTROOT /vt
+ENV VTROOT=/vt
# Prepare directory structure.
RUN mkdir -p /vt/bin && mkdir -p /vtdataroot
diff --git a/docker/binaries/vtctld/Dockerfile b/docker/binaries/vtctld/Dockerfile
index a33297fe0ff..9981960717e 100644
--- a/docker/binaries/vtctld/Dockerfile
+++ b/docker/binaries/vtctld/Dockerfile
@@ -20,7 +20,7 @@ FROM vitess/lite:${VT_BASE_VER} AS lite
FROM debian:${DEBIAN_VER}
# Set up Vitess environment (just enough to run pre-built Go binaries)
-ENV VTROOT /vt
+ENV VTROOT=/vt
# Prepare directory structure.
RUN mkdir -p /vt/bin && \
diff --git a/docker/binaries/vtexplain/Dockerfile b/docker/binaries/vtexplain/Dockerfile
index 58e2bd040db..a201e5a7830 100644
--- a/docker/binaries/vtexplain/Dockerfile
+++ b/docker/binaries/vtexplain/Dockerfile
@@ -20,7 +20,7 @@ FROM vitess/lite:${VT_BASE_VER} AS lite
FROM debian:${DEBIAN_VER}
# Set up Vitess environment (just enough to run pre-built Go binaries)
-ENV VTROOT /vt
+ENV VTROOT=/vt
# Prepare directory structure.
RUN mkdir -p /vt/bin && mkdir -p /vtdataroot
diff --git a/docker/binaries/vtgate/Dockerfile b/docker/binaries/vtgate/Dockerfile
index 761700c1673..1d2341b20b2 100644
--- a/docker/binaries/vtgate/Dockerfile
+++ b/docker/binaries/vtgate/Dockerfile
@@ -20,7 +20,7 @@ FROM vitess/lite:${VT_BASE_VER} AS lite
FROM debian:${DEBIAN_VER}
# Set up Vitess environment (just enough to run pre-built Go binaries)
-ENV VTROOT /vt
+ENV VTROOT=/vt
# Prepare directory structure.
RUN mkdir -p /vt/bin && mkdir -p /vtdataroot
diff --git a/docker/binaries/vtorc/Dockerfile b/docker/binaries/vtorc/Dockerfile
index b24588f8ee4..1e24f36ab15 100644
--- a/docker/binaries/vtorc/Dockerfile
+++ b/docker/binaries/vtorc/Dockerfile
@@ -20,7 +20,7 @@ FROM vitess/lite:${VT_BASE_VER} AS lite
FROM debian:${DEBIAN_VER}
# Set up Vitess environment (just enough to run pre-built Go binaries)
-ENV VTROOT /vt
+ENV VTROOT=/vt
# Prepare directory structure.
RUN mkdir -p /vt/bin && mkdir -p /vtdataroot
diff --git a/docker/binaries/vttablet/Dockerfile b/docker/binaries/vttablet/Dockerfile
index 1c6ff92a588..72b2647c8df 100644
--- a/docker/binaries/vttablet/Dockerfile
+++ b/docker/binaries/vttablet/Dockerfile
@@ -20,8 +20,8 @@ FROM vitess/lite:${VT_BASE_VER} AS lite
FROM debian:${DEBIAN_VER}
# Set up Vitess environment (just enough to run pre-built Go binaries)
-ENV VTROOT /vt
-ENV VTDATAROOT /vtdataroot
+ENV VTROOT=/vt
+ENV VTDATAROOT=/vtdataroot
# Prepare directory structure.
RUN mkdir -p /vt/bin && mkdir -p /vtdataroot
diff --git a/docker/mini/Dockerfile b/docker/mini/Dockerfile
index 0bb3aac7561..8e25d50a7a1 100644
--- a/docker/mini/Dockerfile
+++ b/docker/mini/Dockerfile
@@ -38,9 +38,9 @@ RUN echo "hostname=127.0.0.1" >> /vt/dist/scripts/env.sh
RUN cat /vt/dist/scripts/env.sh | egrep "^alias" >> /etc/bash.bashrc
# Set up Vitess environment (just enough to run pre-built Go binaries)
-ENV VTROOT /vt/src/vitess.io/vitess
-ENV VTDATAROOT /vt/vtdataroot
-ENV PATH $VTROOT/bin:$PATH
+ENV VTROOT=/vt/src/vitess.io/vitess
+ENV VTDATAROOT=/vt/vtdataroot
+ENV PATH=$VTROOT/bin:$PATH
ENV PATH="/vt/bin:${PATH}"
ENV PATH="/var/opt/etcd:${PATH}"
ENV TOPO="etcd"
diff --git a/docker/vttestserver/Dockerfile.mysql80 b/docker/vttestserver/Dockerfile.mysql80
index e970bdb89b0..0d64423da52 100644
--- a/docker/vttestserver/Dockerfile.mysql80
+++ b/docker/vttestserver/Dockerfile.mysql80
@@ -42,9 +42,9 @@ RUN groupadd -r vitess && useradd -r -g vitess vitess
RUN mkdir -p /vt/vtdataroot && chown -R vitess:vitess /vt
# Set up Vitess environment (just enough to run pre-built Go binaries)
-ENV VTROOT /vt
-ENV VTDATAROOT /vt/vtdataroot
-ENV PATH $VTROOT/bin:$PATH
+ENV VTROOT=/vt
+ENV VTDATAROOT=/vt/vtdataroot
+ENV PATH=$VTROOT/bin:$PATH
# Copy artifacts from builder layer.
COPY --from=builder --chown=vitess:vitess /vt/install /vt
diff --git a/docker/vttestserver/Dockerfile.mysql84 b/docker/vttestserver/Dockerfile.mysql84
index 6632d4a6469..32d4f7b057f 100644
--- a/docker/vttestserver/Dockerfile.mysql84
+++ b/docker/vttestserver/Dockerfile.mysql84
@@ -42,9 +42,9 @@ RUN groupadd -r vitess && useradd -r -g vitess vitess
RUN mkdir -p /vt/vtdataroot && chown -R vitess:vitess /vt
# Set up Vitess environment (just enough to run pre-built Go binaries)
-ENV VTROOT /vt
-ENV VTDATAROOT /vt/vtdataroot
-ENV PATH $VTROOT/bin:$PATH
+ENV VTROOT=/vt
+ENV VTDATAROOT=/vt/vtdataroot
+ENV PATH=$VTROOT/bin:$PATH
# Copy artifacts from builder layer.
COPY --from=builder --chown=vitess:vitess /vt/install /vt
From a20601872c55516b650be5e78f95bcdbfb728bac Mon Sep 17 00:00:00 2001
From: Arthur Schreiber
Date: Wed, 14 Oct 2026 13:37:29 +0200
Subject: [PATCH 06/31] [release-23.0] Bump GitHub Actions to the versions on
main (#21577)
Signed-off-by: Arthur Schreiber
Co-authored-by: Claude Opus 5.5
---
.github/actions/build-bootstrap/action.yml | 4 +--
.github/actions/setup-go/action.yml | 2 +-
.github/workflows/assign_milestone.yml | 2 +-
.github/workflows/auto_approve_pr.yml | 2 +-
.../check_make_vtadmin_authz_testgen.yml | 6 ++--
.../check_make_vtadmin_web_proto.yml | 8 ++---
.../workflows/close_stale_pull_requests.yml | 2 +-
.github/workflows/cluster_endtoend.yml | 14 ++++-----
.github/workflows/codecov.yml | 14 ++++-----
.github/workflows/codeql_analysis.yml | 10 +++----
.github/workflows/create_release.yml | 4 +--
.github/workflows/docker_build_images.yml | 30 +++++++++----------
.github/workflows/docker_ci.yml | 8 ++---
.github/workflows/docker_lite_build_check.yml | 8 ++---
.github/workflows/e2e_race.yml | 6 ++--
.github/workflows/endtoend.yml | 6 ++--
.github/workflows/local_example.yml | 8 ++---
.github/workflows/region_example.yml | 8 ++---
.github/workflows/scorecards.yml | 8 ++---
.github/workflows/static_checks_etc.yml | 16 +++++-----
.github/workflows/unit_test.yml | 14 ++++-----
.../workflows/update_golang_dependencies.yml | 6 ++--
.github/workflows/update_golang_version.yml | 6 ++--
.../upgrade_downgrade_test_backups_e2e.yml | 12 ++++----
...owngrade_test_backups_e2e_next_release.yml | 12 ++++----
.../upgrade_downgrade_test_backups_manual.yml | 12 ++++----
...grade_test_backups_manual_next_release.yml | 12 ++++----
.../upgrade_downgrade_test_onlineddl_flow.yml | 14 ++++-----
...e_downgrade_test_query_serving_queries.yml | 10 +++----
...downgrade_test_query_serving_queries_2.yml | 10 +++----
...t_query_serving_queries_2_next_release.yml | 12 ++++----
...est_query_serving_queries_next_release.yml | 12 ++++----
...de_downgrade_test_query_serving_schema.yml | 12 ++++----
...test_query_serving_schema_next_release.yml | 12 ++++----
...rade_downgrade_test_reparent_new_vtctl.yml | 12 ++++----
...e_downgrade_test_reparent_new_vttablet.yml | 12 ++++----
...rade_downgrade_test_reparent_old_vtctl.yml | 12 ++++----
...e_downgrade_test_reparent_old_vttablet.yml | 12 ++++----
.../upgrade_downgrade_test_semi_sync.yml | 14 ++++-----
.github/workflows/vitess_tester_vtgate.yml | 10 +++----
.github/workflows/vtadmin_web_build.yml | 4 +--
.github/workflows/vtadmin_web_lint.yml | 4 +--
.github/workflows/vtadmin_web_unit_tests.yml | 4 +--
.github/workflows/vtop_example.yml | 8 ++---
44 files changed, 208 insertions(+), 206 deletions(-)
diff --git a/.github/actions/build-bootstrap/action.yml b/.github/actions/build-bootstrap/action.yml
index ca4a2193093..05123e38dba 100644
--- a/.github/actions/build-bootstrap/action.yml
+++ b/.github/actions/build-bootstrap/action.yml
@@ -19,10 +19,10 @@ runs:
using: "composite"
steps:
- name: Set up Docker Buildx
- uses: docker/setup-buildx-action@8d2750c68a42422c14e847fe6c8ac0403b4cbd6f # v3.12.0
+ uses: docker/setup-buildx-action@594f3bf4285d9ea8dc53c9a0c9c4092420091003 # v4.4.0
- name: Build bootstrap images
- uses: docker/bake-action@5be5f02ff8819ecd3092ea6b2e6261c31774f2b4 # v6.10.0
+ uses: docker/bake-action@018cb6412ab401ebaa809aa5f85966b74628600f # v7.4.0
with:
files: docker/bootstrap/docker-bake.hcl
load: true
diff --git a/.github/actions/setup-go/action.yml b/.github/actions/setup-go/action.yml
index 5547a0e47cf..14e00e6dde5 100644
--- a/.github/actions/setup-go/action.yml
+++ b/.github/actions/setup-go/action.yml
@@ -18,7 +18,7 @@ runs:
- name: Cache Go modules
if: inputs.cache == 'true' && (github.base_ref == 'main' || (github.base_ref == '' && github.ref_name == 'main'))
- uses: actions/cache@5a3ec84eff668545956fd18022155c47e93e2684 # v4.2.3
+ uses: actions/cache@55cc8345863c7cc4c66a329aec7e433d2d1c52a9 # v6.1.0
with:
# Same paths cached by actions/setup-go internally.
path: |
diff --git a/.github/workflows/assign_milestone.yml b/.github/workflows/assign_milestone.yml
index 398e7ed44ae..ef4a11c9a11 100644
--- a/.github/workflows/assign_milestone.yml
+++ b/.github/workflows/assign_milestone.yml
@@ -19,7 +19,7 @@ jobs:
steps:
- name: Checkout code
- uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
+ uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
with:
# We must explicitly checkout the base's SHA to avoid executing any code coming from
# the PR's SHA - Which would be executed in the base branch's context.
diff --git a/.github/workflows/auto_approve_pr.yml b/.github/workflows/auto_approve_pr.yml
index d5b5cf50a89..cbfaaf88220 100644
--- a/.github/workflows/auto_approve_pr.yml
+++ b/.github/workflows/auto_approve_pr.yml
@@ -17,7 +17,7 @@ jobs:
steps:
- name: Checkout code
- uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
+ uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
with:
persist-credentials: 'false'
diff --git a/.github/workflows/check_make_vtadmin_authz_testgen.yml b/.github/workflows/check_make_vtadmin_authz_testgen.yml
index 49afae01796..7a16e038d5d 100644
--- a/.github/workflows/check_make_vtadmin_authz_testgen.yml
+++ b/.github/workflows/check_make_vtadmin_authz_testgen.yml
@@ -23,12 +23,12 @@ jobs:
fi
- name: Check out code
- uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
+ uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
with:
persist-credentials: 'false'
- name: Check for changes in relevant files
- uses: dorny/paths-filter@ebc4d7e9ebcb0b1eb21480bb8f43113e996ac77a # v3.0.1
+ uses: dorny/paths-filter@ceb8a2b8f2d89434be7ff52d3de7ec3738c5cc9d # v4.0.3
id: changes
with:
token: ''
@@ -49,7 +49,7 @@ jobs:
- name: Set up Go
# zizmor: ignore[cache-poisoning] this workflow publishes no artifacts
- uses: actions/setup-go@d35c59abb061a4a6fb18e82ac0862c26744d6ab5 # v5.5.0
+ uses: actions/setup-go@b7ad1dad31e06c5925ef5d2fc7ad053ef454303e # v7.0.0
if: steps.changes.outputs.vtadmin_changes == 'true'
with:
go-version-file: go.mod
diff --git a/.github/workflows/check_make_vtadmin_web_proto.yml b/.github/workflows/check_make_vtadmin_web_proto.yml
index 3556488b1f7..961db086c98 100644
--- a/.github/workflows/check_make_vtadmin_web_proto.yml
+++ b/.github/workflows/check_make_vtadmin_web_proto.yml
@@ -23,7 +23,7 @@ jobs:
fi
- name: Check out code
- uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
+ uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
with:
persist-credentials: 'false'
@@ -31,7 +31,7 @@ jobs:
uses: $/.github/actions/tune-os
- name: Check for changes in relevant files
- uses: dorny/paths-filter@ebc4d7e9ebcb0b1eb21480bb8f43113e996ac77a # v3.0.1
+ uses: dorny/paths-filter@ceb8a2b8f2d89434be7ff52d3de7ec3738c5cc9d # v4.0.3
id: changes
with:
token: ''
@@ -50,7 +50,7 @@ jobs:
- name: Set up Go
# zizmor: ignore[cache-poisoning] this workflow publishes no artifacts
- uses: actions/setup-go@d35c59abb061a4a6fb18e82ac0862c26744d6ab5 # v5.5.0
+ uses: actions/setup-go@b7ad1dad31e06c5925ef5d2fc7ad053ef454303e # v7.0.0
if: steps.changes.outputs.proto_changes == 'true'
with:
go-version-file: go.mod
@@ -59,7 +59,7 @@ jobs:
- name: Setup Node
if: steps.changes.outputs.proto_changes == 'true'
# zizmor: ignore[cache-poisoning] this workflow publishes no artifacts
- uses: actions/setup-node@1e60f620b9541d16bece96c5465dc8ee9832be0b # v4.0.3
+ uses: actions/setup-node@820762786026740c76f36085b0efc47a31fe5020 # v7.0.0
with:
# node-version should match package.json
node-version: '22.13.1'
diff --git a/.github/workflows/close_stale_pull_requests.yml b/.github/workflows/close_stale_pull_requests.yml
index 45b37babc76..8ffe22a956f 100644
--- a/.github/workflows/close_stale_pull_requests.yml
+++ b/.github/workflows/close_stale_pull_requests.yml
@@ -15,7 +15,7 @@ jobs:
pull-requests: write
steps:
- - uses: actions/stale@f7176fd3007623b69d27091f9b9d4ab7995f0a06 # v5.2.1
+ - uses: actions/stale@4391f3da665fdf50b6810c1a66712fb9ba21aa93 # v11.0.0
with:
days-before-stale: 30
# Do not handle issues at all. We only want to handle PRs.
diff --git a/.github/workflows/cluster_endtoend.yml b/.github/workflows/cluster_endtoend.yml
index 9d835982673..785529e01e1 100644
--- a/.github/workflows/cluster_endtoend.yml
+++ b/.github/workflows/cluster_endtoend.yml
@@ -34,7 +34,7 @@ jobs:
end_to_end: ${{ steps.changes.outputs.end_to_end }}
steps:
- name: Check out code
- uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
+ uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
with:
persist-credentials: "false"
@@ -74,7 +74,7 @@ jobs:
echo "shard_count=$(echo "$matrix" | jq length)" >> $GITHUB_OUTPUT
- name: Check for changes in relevant files
- uses: dorny/paths-filter@de90cc6fb38fc0963ad72b210f1f284cd68cea36 # v3.0.2
+ uses: dorny/paths-filter@ceb8a2b8f2d89434be7ff52d3de7ec3738c5cc9d # v4.0.3
id: changes
with:
token: ""
@@ -125,7 +125,7 @@ jobs:
steps:
- name: Harden the runner (Audit all outbound calls)
- uses: step-security/harden-runner@f808768d1510423e83855289c910610ca9b43176 # v2.17.0
+ uses: step-security/harden-runner@e14015d583714f6e62063499dc959a02595150a1 # v2.21.1
with:
egress-policy: audit
@@ -152,21 +152,21 @@ jobs:
- name: Check out code
if: needs.generate-matrix.outputs.end_to_end == 'true'
- uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
+ uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
with:
persist-credentials: "false"
- name: Set up Go
if: needs.generate-matrix.outputs.end_to_end == 'true'
# zizmor: ignore[cache-poisoning] this workflow publishes no artifacts
- uses: actions/setup-go@7a3fe6cf4cb3a834922a1244abfce67bcef6a0c5 # v6.2.0
+ uses: actions/setup-go@b7ad1dad31e06c5925ef5d2fc7ad053ef454303e # v7.0.0
with:
go-version-file: go.mod
cache: ${{ (github.base_ref == 'main' || (github.base_ref == '' && github.ref_name == 'main')) && 'true' || 'false' }}
- name: Set up python
if: needs.generate-matrix.outputs.end_to_end == 'true'
- uses: actions/setup-python@a309ff8b426b58ec0e2a45f0f869d46889d02405 # v6.2.0
+ uses: actions/setup-python@5fda3b95a4ea91299a34e894583c3862153e4b97 # v7.0.0
- name: Tune the OS
if: needs.generate-matrix.outputs.end_to_end == 'true'
@@ -291,7 +291,7 @@ jobs:
- name: Test Summary
if: needs.generate-matrix.outputs.end_to_end == 'true' && failure()
- uses: test-summary/action@31493c76ec9e7aa675f1585d3ed6f1da69269a86 # v2.4
+ uses: test-summary/action@37b508cfee6d4d080eedd00b5bb240a6a784a6a5 # v2.6
with:
paths: "_test/junit/*.xml"
show: "fail"
diff --git a/.github/workflows/codecov.yml b/.github/workflows/codecov.yml
index 9f8e1f4c83b..aaea4873f01 100644
--- a/.github/workflows/codecov.yml
+++ b/.github/workflows/codecov.yml
@@ -27,7 +27,7 @@ jobs:
packages: ${{ steps.packages.outputs.packages }}
steps:
- name: Check out code
- uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
+ uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
with:
# Full history is needed to diff the pull request's base and head.
fetch-depth: 0
@@ -44,7 +44,7 @@ jobs:
- name: Check for changes in files relevant to code coverage
if: steps.mode.outputs.is_full_run != 'true'
- uses: dorny/paths-filter@de90cc6fb38fc0963ad72b210f1f284cd68cea36 # v3.0.2
+ uses: dorny/paths-filter@ceb8a2b8f2d89434be7ff52d3de7ec3738c5cc9d # v4.0.3
id: changes
with:
token: ''
@@ -62,7 +62,7 @@ jobs:
- name: Set up Go
if: steps.mode.outputs.is_full_run != 'true' && steps.changes.outputs.changed_files == 'true'
# zizmor: ignore[cache-poisoning] this workflow publishes no artifacts
- uses: actions/setup-go@7a3fe6cf4cb3a834922a1244abfce67bcef6a0c5 # v6.2.0
+ uses: actions/setup-go@b7ad1dad31e06c5925ef5d2fc7ad053ef454303e # v7.0.0
with:
go-version-file: go.mod
cache: ${{ (github.base_ref == 'main' || (github.base_ref == '' && github.ref_name == 'main')) && 'true' || 'false' }}
@@ -114,12 +114,12 @@ jobs:
steps:
- name: Check out code
- uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
+ uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
with:
persist-credentials: 'false'
- name: Set up Go
- uses: actions/setup-go@7a3fe6cf4cb3a834922a1244abfce67bcef6a0c5 # v6.2.0
+ uses: actions/setup-go@b7ad1dad31e06c5925ef5d2fc7ad053ef454303e # v7.0.0
with:
go-version-file: go.mod
cache: ${{ (github.base_ref == 'main' || (github.base_ref == '' && github.ref_name == 'main')) && 'true' || 'false' }}
@@ -128,7 +128,7 @@ jobs:
tools/**/go.sum
- name: Set up python
- uses: actions/setup-python@a309ff8b426b58ec0e2a45f0f869d46889d02405 # v6.2.0
+ uses: actions/setup-python@5fda3b95a4ea91299a34e894583c3862153e4b97 # v7.0.0
- name: Tune the OS
uses: $/.github/actions/tune-os
@@ -171,7 +171,7 @@ jobs:
fi
- name: Upload coverage reports
- uses: codecov/codecov-action@0fb7174895f61a3b6b78fc075e0cd60383518dac # v5.5.5
+ uses: codecov/codecov-action@303a32d7a59b442fa8d48b6a1cc6825c09c847a5 # v7.1.1
with:
files: coverage.out
fail_ci_if_error: true
diff --git a/.github/workflows/codeql_analysis.yml b/.github/workflows/codeql_analysis.yml
index 71ecdbd763e..65ee653b1b1 100644
--- a/.github/workflows/codeql_analysis.yml
+++ b/.github/workflows/codeql_analysis.yml
@@ -27,13 +27,13 @@ jobs:
steps:
- name: Checkout repository
- uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
+ uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
with:
persist-credentials: 'false'
- name: Set up Go
# zizmor: ignore[cache-poisoning] this workflow publishes no artifacts
- uses: actions/setup-go@d35c59abb061a4a6fb18e82ac0862c26744d6ab5 # v5.5.0
+ uses: actions/setup-go@b7ad1dad31e06c5925ef5d2fc7ad053ef454303e # v7.0.0
with:
go-version-file: go.mod
cache: ${{ (github.base_ref == 'main' || (github.base_ref == '' && github.ref_name == 'main')) && 'true' || 'false' }}
@@ -43,7 +43,7 @@ jobs:
# Initializes the CodeQL tools for scanning.
- name: Initialize CodeQL
- uses: github/codeql-action/init@4bdb89f48054571735e3792627da6195c57459e2 # v3.31.10
+ uses: github/codeql-action/init@2892aa5e19bbd11bc0cff5427e3b750a04d9e3c2 # v4.38.2
with:
languages: ${{ matrix.language }}
# If you wish to specify cu stom queries, you can do so here or in a config file.
@@ -75,11 +75,11 @@ jobs:
make build
- name: Perform CodeQL Analysis
- uses: github/codeql-action/analyze@4bdb89f48054571735e3792627da6195c57459e2 # v3.31.10
+ uses: github/codeql-action/analyze@2892aa5e19bbd11bc0cff5427e3b750a04d9e3c2 # v4.38.2
- name: Slack Workflow Notification
if: ${{ failure() }}
- uses: Gamesight/slack-workflow-status@68bf00d0dbdbcb206c278399aa1ef6c14f74347a # v1.3.0
+ uses: Gamesight/slack-workflow-status@2e709ce51fd47f02b7221db8547e6e6f49f81f1d # v2.0.0
with:
repo_token: ${{secrets.GITHUB_TOKEN}}
slack_webhook_url: ${{secrets.SLACK_WEBHOOK_URL}}
diff --git a/.github/workflows/create_release.yml b/.github/workflows/create_release.yml
index e86ff049c74..464637e60cc 100644
--- a/.github/workflows/create_release.yml
+++ b/.github/workflows/create_release.yml
@@ -17,12 +17,12 @@ jobs:
runs-on: ubuntu-24.04
steps:
- name: Check out code
- uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
+ uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
with:
persist-credentials: 'false'
- name: Set up Go
- uses: actions/setup-go@d35c59abb061a4a6fb18e82ac0862c26744d6ab5 # v5.5.0
+ uses: actions/setup-go@b7ad1dad31e06c5925ef5d2fc7ad053ef454303e # v7.0.0
with:
go-version-file: go.mod
cache: 'false'
diff --git a/.github/workflows/docker_build_images.yml b/.github/workflows/docker_build_images.yml
index cf6891bf2a0..fe51d299a0d 100644
--- a/.github/workflows/docker_build_images.yml
+++ b/.github/workflows/docker_build_images.yml
@@ -27,12 +27,12 @@ jobs:
steps:
- name: Check out code
- uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
+ uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
with:
persist-credentials: 'false'
- name: Login to Docker Hub
- uses: docker/login-action@9780b0c442fbb1117ed29e0efdff1e18412f7567 # v3.3.0
+ uses: docker/login-action@dbcb813823bdd20940b903addbd779551569679f # v4.6.0
with:
username: ${{ secrets.DOCKERHUB_USERNAME }}
password: ${{ secrets.DOCKERHUB_TOKEN }}
@@ -43,7 +43,7 @@ jobs:
- name: Build and push on main
if: startsWith(github.ref, 'refs/tags/') == false
- uses: docker/build-push-action@b32b51a8eda65d6793cd0494a773d4f6bcef32dc # v6.11.0
+ uses: docker/build-push-action@c3c9e263c25d99ce0380d002d59b67737d91b0dc # v7.4.0
with:
context: .
file: ${{ env.DOCKERFILE }}
@@ -64,7 +64,7 @@ jobs:
- name: Build and push on tags
if: startsWith(github.ref, 'refs/tags/')
- uses: docker/build-push-action@b32b51a8eda65d6793cd0494a773d4f6bcef32dc # v6.11.0
+ uses: docker/build-push-action@c3c9e263c25d99ce0380d002d59b67737d91b0dc # v7.4.0
with:
context: .
file: ${{ env.DOCKERFILE }}
@@ -83,12 +83,12 @@ jobs:
steps:
- name: Check out code
- uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
+ uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
with:
persist-credentials: 'false'
- name: Login to Docker Hub
- uses: docker/login-action@9780b0c442fbb1117ed29e0efdff1e18412f7567 # v3.3.0
+ uses: docker/login-action@dbcb813823bdd20940b903addbd779551569679f # v4.6.0
with:
username: ${{ secrets.DOCKERHUB_USERNAME }}
password: ${{ secrets.DOCKERHUB_TOKEN }}
@@ -103,7 +103,7 @@ jobs:
- name: Build and push on main
if: startsWith(github.ref, 'refs/tags/') == false
- uses: docker/build-push-action@b32b51a8eda65d6793cd0494a773d4f6bcef32dc # v6.11.0
+ uses: docker/build-push-action@c3c9e263c25d99ce0380d002d59b67737d91b0dc # v7.4.0
with:
context: .
file: ${{ env.DOCKERFILE }}
@@ -128,7 +128,7 @@ jobs:
- name: Build and push on tags
if: startsWith(github.ref, 'refs/tags/')
- uses: docker/build-push-action@b32b51a8eda65d6793cd0494a773d4f6bcef32dc # v6.11.0
+ uses: docker/build-push-action@c3c9e263c25d99ce0380d002d59b67737d91b0dc # v7.4.0
with:
context: .
file: ${{ env.DOCKERFILE }}
@@ -150,12 +150,12 @@ jobs:
steps:
- name: Check out code
- uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
+ uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
with:
persist-credentials: 'false'
- name: Login to Docker Hub
- uses: docker/login-action@9780b0c442fbb1117ed29e0efdff1e18412f7567 # v3.3.0
+ uses: docker/login-action@dbcb813823bdd20940b903addbd779551569679f # v4.6.0
with:
username: ${{ secrets.DOCKERHUB_USERNAME }}
password: ${{ secrets.DOCKERHUB_TOKEN }}
@@ -166,7 +166,7 @@ jobs:
- name: Build and push on main latest tag
if: startsWith(github.ref, 'refs/tags/') == false && matrix.debian == 'bookworm'
- uses: docker/build-push-action@b32b51a8eda65d6793cd0494a773d4f6bcef32dc # v6.11.0
+ uses: docker/build-push-action@c3c9e263c25d99ce0380d002d59b67737d91b0dc # v7.4.0
with:
context: ${{ env.DOCKER_CTX }}
push: true
@@ -177,7 +177,7 @@ jobs:
- name: Build and push on main debian specific tag
if: startsWith(github.ref, 'refs/tags/') == false
- uses: docker/build-push-action@b32b51a8eda65d6793cd0494a773d4f6bcef32dc # v6.11.0
+ uses: docker/build-push-action@c3c9e263c25d99ce0380d002d59b67737d91b0dc # v7.4.0
with:
context: ${{ env.DOCKER_CTX }}
push: true
@@ -209,7 +209,7 @@ jobs:
# Build and Push component image to DOCKER_TAG, applies to both debian version
- name: Build and push on tags using Debian extension
if: startsWith(github.ref, 'refs/tags/')
- uses: docker/build-push-action@b32b51a8eda65d6793cd0494a773d4f6bcef32dc # v6.11.0
+ uses: docker/build-push-action@c3c9e263c25d99ce0380d002d59b67737d91b0dc # v7.4.0
with:
context: ${{ env.DOCKER_CTX }}
push: true
@@ -222,7 +222,7 @@ jobs:
# It is fine to build a second time here when "matrix.debian == 'bookworm'" as we have cached the first build already
- name: Build and push on tags without Debian extension
if: startsWith(github.ref, 'refs/tags/') && matrix.debian == 'bookworm'
- uses: docker/build-push-action@b32b51a8eda65d6793cd0494a773d4f6bcef32dc # v6.11.0
+ uses: docker/build-push-action@c3c9e263c25d99ce0380d002d59b67737d91b0dc # v7.4.0
with:
context: ${{ env.DOCKER_CTX }}
push: true
@@ -243,7 +243,7 @@ jobs:
if: ${{ failure() }}
steps:
- name: Slack Workflow Notification
- uses: Gamesight/slack-workflow-status@68bf00d0dbdbcb206c278399aa1ef6c14f74347a # v1.3.0
+ uses: Gamesight/slack-workflow-status@2e709ce51fd47f02b7221db8547e6e6f49f81f1d # v2.0.0
with:
repo_token: ${{secrets.GITHUB_TOKEN}}
slack_webhook_url: ${{secrets.SLACK_WEBHOOK_URL}}
diff --git a/.github/workflows/docker_ci.yml b/.github/workflows/docker_ci.yml
index 456c16e1648..1bfd859881c 100644
--- a/.github/workflows/docker_ci.yml
+++ b/.github/workflows/docker_ci.yml
@@ -33,7 +33,7 @@ jobs:
steps:
- name: Harden the runner (Audit all outbound calls)
- uses: step-security/harden-runner@f808768d1510423e83855289c910610ca9b43176 # v2.17.0
+ uses: step-security/harden-runner@e14015d583714f6e62063499dc959a02595150a1 # v2.21.1
with:
egress-policy: audit
@@ -45,12 +45,12 @@ jobs:
fi
- name: Check out code
- uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
+ uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
with:
persist-credentials: "false"
- name: Check for changes in relevant files
- uses: dorny/paths-filter@de90cc6fb38fc0963ad72b210f1f284cd68cea36 # v3.0.2
+ uses: dorny/paths-filter@ceb8a2b8f2d89434be7ff52d3de7ec3738c5cc9d # v4.0.3
id: changes
with:
token: ""
@@ -82,7 +82,7 @@ jobs:
- name: Set up Go
if: steps.changes.outputs.end_to_end == 'true'
# zizmor: ignore[cache-poisoning] this workflow publishes no artifacts
- uses: actions/setup-go@7a3fe6cf4cb3a834922a1244abfce67bcef6a0c5 # v6.2.0
+ uses: actions/setup-go@b7ad1dad31e06c5925ef5d2fc7ad053ef454303e # v7.0.0
with:
go-version-file: go.mod
cache: ${{ (github.base_ref == 'main' || (github.base_ref == '' && github.ref_name == 'main')) && 'true' || 'false' }}
diff --git a/.github/workflows/docker_lite_build_check.yml b/.github/workflows/docker_lite_build_check.yml
index 1e68f37b043..360a6bc5ff7 100644
--- a/.github/workflows/docker_lite_build_check.yml
+++ b/.github/workflows/docker_lite_build_check.yml
@@ -23,7 +23,7 @@ jobs:
dockerfiles: ${{ steps.generate-matrix.outputs.dockerfiles }}
steps:
- name: Check out code
- uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
+ uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
with:
persist-credentials: 'false'
@@ -45,7 +45,7 @@ jobs:
steps:
- name: Harden the runner (Audit all outbound calls)
- uses: step-security/harden-runner@f808768d1510423e83855289c910610ca9b43176 # v2.17.0
+ uses: step-security/harden-runner@e14015d583714f6e62063499dc959a02595150a1 # v2.21.1
with:
egress-policy: audit
@@ -57,12 +57,12 @@ jobs:
fi
- name: Check out code
- uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
+ uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
with:
persist-credentials: 'false'
- name: Build lite image
- uses: docker/build-push-action@263435318d21b8e681c14492fe198d362a7d2c83 # v6.18.0
+ uses: docker/build-push-action@c3c9e263c25d99ce0380d002d59b67737d91b0dc # v7.4.0
with:
context: .
file: ${{ matrix.dockerfile }}
diff --git a/.github/workflows/e2e_race.yml b/.github/workflows/e2e_race.yml
index a868924f742..bacc4b1def4 100644
--- a/.github/workflows/e2e_race.yml
+++ b/.github/workflows/e2e_race.yml
@@ -26,12 +26,12 @@ jobs:
fi
- name: Check out code
- uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
+ uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
with:
persist-credentials: 'false'
- name: Check for changes in relevant files
- uses: dorny/paths-filter@ebc4d7e9ebcb0b1eb21480bb8f43113e996ac77a # v3.0.1
+ uses: dorny/paths-filter@ceb8a2b8f2d89434be7ff52d3de7ec3738c5cc9d # v4.0.3
id: changes
with:
token: ''
@@ -54,7 +54,7 @@ jobs:
- name: Set up Go
if: steps.changes.outputs.end_to_end == 'true'
# zizmor: ignore[cache-poisoning] this workflow publishes no artifacts
- uses: actions/setup-go@d35c59abb061a4a6fb18e82ac0862c26744d6ab5 # v5.5.0
+ uses: actions/setup-go@b7ad1dad31e06c5925ef5d2fc7ad053ef454303e # v7.0.0
with:
go-version-file: go.mod
cache: ${{ (github.base_ref == 'main' || (github.base_ref == '' && github.ref_name == 'main')) && 'true' || 'false' }}
diff --git a/.github/workflows/endtoend.yml b/.github/workflows/endtoend.yml
index 71dfa0b8bd2..8f69d46d2c9 100644
--- a/.github/workflows/endtoend.yml
+++ b/.github/workflows/endtoend.yml
@@ -26,12 +26,12 @@ jobs:
fi
- name: Check out code
- uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
+ uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
with:
persist-credentials: 'false'
- name: Check for changes in relevant files
- uses: dorny/paths-filter@ebc4d7e9ebcb0b1eb21480bb8f43113e996ac77a # v3.0.1
+ uses: dorny/paths-filter@ceb8a2b8f2d89434be7ff52d3de7ec3738c5cc9d # v4.0.3
id: changes
with:
token: ''
@@ -54,7 +54,7 @@ jobs:
- name: Set up Go
if: steps.changes.outputs.end_to_end == 'true'
# zizmor: ignore[cache-poisoning] this workflow publishes no artifacts
- uses: actions/setup-go@d35c59abb061a4a6fb18e82ac0862c26744d6ab5 # v5.5.0
+ uses: actions/setup-go@b7ad1dad31e06c5925ef5d2fc7ad053ef454303e # v7.0.0
with:
go-version-file: go.mod
cache: ${{ (github.base_ref == 'main' || (github.base_ref == '' && github.ref_name == 'main')) && 'true' || 'false' }}
diff --git a/.github/workflows/local_example.yml b/.github/workflows/local_example.yml
index a8eea949006..aaae80f972f 100644
--- a/.github/workflows/local_example.yml
+++ b/.github/workflows/local_example.yml
@@ -30,12 +30,12 @@ jobs:
examples: ${{ steps.changes.outputs.examples }}
steps:
- name: Check out code
- uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
+ uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
with:
persist-credentials: 'false'
- name: Check for changes in relevant files
- uses: dorny/paths-filter@ebc4d7e9ebcb0b1eb21480bb8f43113e996ac77a # v3.0.1
+ uses: dorny/paths-filter@ceb8a2b8f2d89434be7ff52d3de7ec3738c5cc9d # v4.0.3
id: changes
with:
token: ''
@@ -85,7 +85,7 @@ jobs:
- name: Check out code
if: needs.changes.outputs.examples == 'true'
- uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
+ uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
with:
persist-credentials: 'false'
@@ -96,7 +96,7 @@ jobs:
- name: Set up Go
if: needs.changes.outputs.examples == 'true'
# zizmor: ignore[cache-poisoning] this workflow publishes no artifacts
- uses: actions/setup-go@d35c59abb061a4a6fb18e82ac0862c26744d6ab5 # v5.5.0
+ uses: actions/setup-go@b7ad1dad31e06c5925ef5d2fc7ad053ef454303e # v7.0.0
with:
go-version-file: go.mod
cache: ${{ (github.base_ref == 'main' || (github.base_ref == '' && github.ref_name == 'main')) && 'true' || 'false' }}
diff --git a/.github/workflows/region_example.yml b/.github/workflows/region_example.yml
index ae73dfe6b55..709ed2bce42 100644
--- a/.github/workflows/region_example.yml
+++ b/.github/workflows/region_example.yml
@@ -30,12 +30,12 @@ jobs:
examples: ${{ steps.changes.outputs.examples }}
steps:
- name: Check out code
- uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
+ uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
with:
persist-credentials: 'false'
- name: Check for changes in relevant files
- uses: dorny/paths-filter@ebc4d7e9ebcb0b1eb21480bb8f43113e996ac77a # v3.0.1
+ uses: dorny/paths-filter@ceb8a2b8f2d89434be7ff52d3de7ec3738c5cc9d # v4.0.3
id: changes
with:
token: ''
@@ -85,7 +85,7 @@ jobs:
- name: Check out code
if: needs.changes.outputs.examples == 'true'
- uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
+ uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
with:
persist-credentials: 'false'
@@ -96,7 +96,7 @@ jobs:
- name: Set up Go
if: needs.changes.outputs.examples == 'true'
# zizmor: ignore[cache-poisoning] this workflow publishes no artifacts
- uses: actions/setup-go@d35c59abb061a4a6fb18e82ac0862c26744d6ab5 # v5.5.0
+ uses: actions/setup-go@b7ad1dad31e06c5925ef5d2fc7ad053ef454303e # v7.0.0
with:
go-version-file: go.mod
cache: ${{ (github.base_ref == 'main' || (github.base_ref == '' && github.ref_name == 'main')) && 'true' || 'false' }}
diff --git a/.github/workflows/scorecards.yml b/.github/workflows/scorecards.yml
index d142f390af7..b5bc7b2ac96 100644
--- a/.github/workflows/scorecards.yml
+++ b/.github/workflows/scorecards.yml
@@ -27,12 +27,12 @@ jobs:
steps:
- name: "Checkout code"
- uses: actions/checkout@8e8c483db84b4bee98b60c0593521ed34d9990e8 # v6.0.1
+ uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
with:
persist-credentials: false
- name: "Run analysis"
- uses: ossf/scorecard-action@4eaacf0543bb3f2c246792bd56e8cdeffafb205a # v2.4.3
+ uses: ossf/scorecard-action@2d1146689b8cda280b9bc96326124645441f03bc # v2.4.4
with:
results_file: results.sarif
results_format: sarif
@@ -54,7 +54,7 @@ jobs:
# Upload the results as artifacts (optional). Commenting out will disable uploads of run results in SARIF
# format to the repository Actions tab.
- name: "Upload artifact"
- uses: actions/upload-artifact@b7c566a772e6b6bfb58ed0dc250532a479d7789f # v6.0.0
+ uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7.0.1
with:
name: SARIF file
path: results.sarif
@@ -63,6 +63,6 @@ jobs:
# Upload the results to GitHub's code scanning dashboard (optional).
# Commenting out will disable upload of results to your repo's Code Scanning dashboard
- name: "Upload to code-scanning"
- uses: github/codeql-action/upload-sarif@4bdb89f48054571735e3792627da6195c57459e2 # v3.31.10
+ uses: github/codeql-action/upload-sarif@2892aa5e19bbd11bc0cff5427e3b750a04d9e3c2 # v4.38.2
with:
sarif_file: results.sarif
diff --git a/.github/workflows/static_checks_etc.yml b/.github/workflows/static_checks_etc.yml
index 025d075e63e..f8b9e80dd9c 100644
--- a/.github/workflows/static_checks_etc.yml
+++ b/.github/workflows/static_checks_etc.yml
@@ -29,7 +29,7 @@ jobs:
fi
- name: Checkout code
- uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
+ uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
with:
persist-credentials: 'false'
@@ -38,14 +38,14 @@ jobs:
# Pushes keep main, the release branches and the tags scanned.
- name: Run FOSSA scan and upload build data
if: github.event_name == 'push'
- uses: fossa-contrib/fossa-action@3d2ef181b1820d6dcd1972f86a767d18167fa19b # v3.0.1
+ uses: fossa-contrib/fossa-action@d28f0c947e7406706981a62a91ecc009bcc39fd7 # v4.0.0
with:
# This is a push-only API token: https://github.com/fossa-contrib/fossa-action#push-only-api-token
fossa-api-key: f62c11ef0c249fef239947f01279aa0f
github-token: ${{ github.token }}
- name: Check for changes in Go files
- uses: dorny/paths-filter@ebc4d7e9ebcb0b1eb21480bb8f43113e996ac77a # v3.0.1
+ uses: dorny/paths-filter@ceb8a2b8f2d89434be7ff52d3de7ec3738c5cc9d # v4.0.3
id: changes
with:
token: ''
@@ -129,7 +129,7 @@ jobs:
- name: Set up Go
if: (steps.changes.outputs.go_files == 'true' || steps.changes.outputs.parser_changes == 'true' || steps.changes.outputs.proto_changes == 'true')
# zizmor: ignore[cache-poisoning] this workflow publishes no artifacts
- uses: actions/setup-go@d35c59abb061a4a6fb18e82ac0862c26744d6ab5 # v5.5.0
+ uses: actions/setup-go@b7ad1dad31e06c5925ef5d2fc7ad053ef454303e # v7.0.0
with:
go-version-file: go.mod
cache: ${{ (github.base_ref == 'main' || (github.base_ref == '' && github.ref_name == 'main')) && 'true' || 'false' }}
@@ -149,7 +149,9 @@ jobs:
- name: Install goimports
if: (steps.changes.outputs.go_files == 'true' || steps.changes.outputs.visitor == 'true')
run: |
- go install golang.org/x/tools/cmd/goimports@latest
+ # actions/setup-go sets GOTOOLCHAIN=local, so pin an x/tools release
+ # that builds with this branch's Go 1.25 (v0.50.0 and later need Go 1.26).
+ go install golang.org/x/tools/cmd/goimports@v0.49.0
- name: Run goimports
if: steps.changes.outputs.go_files == 'true'
@@ -243,7 +245,7 @@ jobs:
- name: Setup Node
if: steps.changes.outputs.proto_changes == 'true'
# zizmor: ignore[cache-poisoning] this workflow publishes no artifacts
- uses: actions/setup-node@6044e13b5dc448c55e2357c09f80417699197238 # v6.2.0
+ uses: actions/setup-node@820762786026740c76f36085b0efc47a31fe5020 # v7.0.0
with:
# make proto requires newer node than the pre-installed one
node-version: '22.13.1'
@@ -274,7 +276,7 @@ jobs:
exit 1
- name: Run zizmor 🌈
- uses: zizmorcore/zizmor-action@3dc1ecc9bcb9e94e9b2c709687979e1298497054 # v0.6.2
+ uses: zizmorcore/zizmor-action@cc914d7f3750a2d13d75c7f184a1060aa0e9d482 # v0.6.4
with:
advanced-security: false
annotations: true
diff --git a/.github/workflows/unit_test.yml b/.github/workflows/unit_test.yml
index 1a14e36dba0..2d9c56a8b21 100644
--- a/.github/workflows/unit_test.yml
+++ b/.github/workflows/unit_test.yml
@@ -32,12 +32,12 @@ jobs:
unit_tests: ${{ steps.changes.outputs.unit_tests }}
steps:
- name: Check out code
- uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
+ uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
with:
persist-credentials: "false"
- name: Check for changes in relevant files
- uses: dorny/paths-filter@de90cc6fb38fc0963ad72b210f1f284cd68cea36 # v3.0.2
+ uses: dorny/paths-filter@ceb8a2b8f2d89434be7ff52d3de7ec3738c5cc9d # v4.0.3
id: changes
with:
token: ""
@@ -115,7 +115,7 @@ jobs:
steps:
- name: Harden the runner (Audit all outbound calls)
- uses: step-security/harden-runner@f808768d1510423e83855289c910610ca9b43176 # v2.17.0
+ uses: step-security/harden-runner@e14015d583714f6e62063499dc959a02595150a1 # v2.21.1
with:
egress-policy: audit
@@ -133,14 +133,14 @@ jobs:
- name: Check out code
if: needs.changes.outputs.unit_tests == 'true'
- uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
+ uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
with:
persist-credentials: "false"
- name: Set up Go
if: needs.changes.outputs.unit_tests == 'true'
# zizmor: ignore[cache-poisoning] this workflow publishes no artifacts
- uses: actions/setup-go@7a3fe6cf4cb3a834922a1244abfce67bcef6a0c5 # v6.2.0
+ uses: actions/setup-go@b7ad1dad31e06c5925ef5d2fc7ad053ef454303e # v7.0.0
with:
go-version-file: go.mod
cache: ${{ (github.base_ref == 'main' || (github.base_ref == '' && github.ref_name == 'main')) && 'true' || 'false' }}
@@ -150,7 +150,7 @@ jobs:
- name: Set up python
if: needs.changes.outputs.unit_tests == 'true'
- uses: actions/setup-python@a309ff8b426b58ec0e2a45f0f869d46889d02405 # v6.2.0
+ uses: actions/setup-python@5fda3b95a4ea91299a34e894583c3862153e4b97 # v7.0.0
- name: Tune the OS
if: needs.changes.outputs.unit_tests == 'true'
@@ -215,7 +215,7 @@ jobs:
- name: Test Summary
if: needs.changes.outputs.unit_tests == 'true' && failure()
- uses: test-summary/action@31493c76ec9e7aa675f1585d3ed6f1da69269a86 # v2.4
+ uses: test-summary/action@37b508cfee6d4d080eedd00b5bb240a6a784a6a5 # v2.6
with:
paths: "report.xml"
show: "fail"
diff --git a/.github/workflows/update_golang_dependencies.yml b/.github/workflows/update_golang_dependencies.yml
index a469521e5dc..84bb89fb51a 100644
--- a/.github/workflows/update_golang_dependencies.yml
+++ b/.github/workflows/update_golang_dependencies.yml
@@ -18,13 +18,13 @@ jobs:
timeout-minutes: 15
steps:
- name: Check out code
- uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
+ uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
with:
ref: main
persist-credentials: 'false'
- name: Set up Go
- uses: actions/setup-go@d35c59abb061a4a6fb18e82ac0862c26744d6ab5 # v5.5.0
+ uses: actions/setup-go@b7ad1dad31e06c5925ef5d2fc7ad053ef454303e # v7.0.0
with:
go-version-file: go.mod
cache: ${{ (github.base_ref == 'main' || (github.base_ref == '' && github.ref_name == 'main')) && 'true' || 'false' }}
@@ -42,7 +42,7 @@ jobs:
go mod tidy
- name: Create Pull Request
- uses: peter-evans/create-pull-request@98357b18bf14b5342f975ff684046ec3b2a07725 # v8.0.0
+ uses: peter-evans/create-pull-request@5f6978faf089d4d20b00c7766989d076bb2fc7f1 # v8.1.1
with:
token: ${{ secrets.CREATE_PR_VITESS_BOT }}
branch: "upgrade-go-deps-on-main"
diff --git a/.github/workflows/update_golang_version.yml b/.github/workflows/update_golang_version.yml
index f3c0e4b8173..013fe8a0927 100644
--- a/.github/workflows/update_golang_version.yml
+++ b/.github/workflows/update_golang_version.yml
@@ -21,13 +21,13 @@ jobs:
timeout-minutes: 10
steps:
- name: Check out code
- uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
+ uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
with:
ref: ${{ matrix.branch }}
persist-credentials: 'false'
- name: Set up Go
- uses: actions/setup-go@d35c59abb061a4a6fb18e82ac0862c26744d6ab5 # v5.5.0
+ uses: actions/setup-go@b7ad1dad31e06c5925ef5d2fc7ad053ef454303e # v7.0.0
with:
go-version-file: go.mod
cache: ${{ (github.base_ref == 'main' || (github.base_ref == '' && github.ref_name == 'main')) && 'true' || 'false' }}
@@ -70,7 +70,7 @@ jobs:
- name: Create Pull Request
if: steps.detect-and-update.outputs.create-pr == 'true'
- uses: peter-evans/create-pull-request@98357b18bf14b5342f975ff684046ec3b2a07725 # v8.0.0
+ uses: peter-evans/create-pull-request@5f6978faf089d4d20b00c7766989d076bb2fc7f1 # v8.1.1
with:
token: ${{ secrets.CREATE_PR_VITESS_BOT }}
branch: "upgrade-go-to-${{steps.detect-and-update.outputs.go-version}}-on-${{ matrix.branch }}"
diff --git a/.github/workflows/upgrade_downgrade_test_backups_e2e.yml b/.github/workflows/upgrade_downgrade_test_backups_e2e.yml
index d07ba7a426f..e3624093e40 100644
--- a/.github/workflows/upgrade_downgrade_test_backups_e2e.yml
+++ b/.github/workflows/upgrade_downgrade_test_backups_e2e.yml
@@ -27,7 +27,7 @@ jobs:
previous_release_ref: ${{ steps.output-previous-release-ref.outputs.previous_release_ref }}
steps:
- name: Check out commit's code
- uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
+ uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
with:
# Full history is needed to list the release branches.
fetch-depth: 0
@@ -44,7 +44,7 @@ jobs:
echo "previous_release_ref=${previous_release_ref}" >> $GITHUB_OUTPUT
- name: Check for changes in relevant files
- uses: dorny/paths-filter@ebc4d7e9ebcb0b1eb21480bb8f43113e996ac77a # v3.0.1
+ uses: dorny/paths-filter@ceb8a2b8f2d89434be7ff52d3de7ec3738c5cc9d # v4.0.3
id: changes
with:
token: ''
@@ -92,7 +92,7 @@ jobs:
run: exit 1
- name: Check out commit's code
- uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
+ uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
with:
persist-credentials: 'false'
@@ -100,7 +100,7 @@ jobs:
uses: $/.github/actions/tune-os
- name: Set up python
- uses: actions/setup-python@39cd14951b08e74b54015e9e001cdefcf80e669f # v5.1.1
+ uses: actions/setup-python@5fda3b95a4ea91299a34e894583c3862153e4b97 # v7.0.0
- name: Setup MySQL
uses: $/.github/actions/setup-mysql
@@ -127,7 +127,7 @@ jobs:
# Checkout to the last release of Vitess
- name: Check out other version's code (${{ needs.changes.outputs.previous_release_ref }})
- uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
+ uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
with:
ref: ${{ needs.changes.outputs.previous_release_ref }}
persist-credentials: 'false'
@@ -149,7 +149,7 @@ jobs:
# Checkout to this build's commit
- name: Check out commit's code
- uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
+ uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
with:
persist-credentials: 'false'
diff --git a/.github/workflows/upgrade_downgrade_test_backups_e2e_next_release.yml b/.github/workflows/upgrade_downgrade_test_backups_e2e_next_release.yml
index 21519927d38..37d34c227e0 100644
--- a/.github/workflows/upgrade_downgrade_test_backups_e2e_next_release.yml
+++ b/.github/workflows/upgrade_downgrade_test_backups_e2e_next_release.yml
@@ -28,7 +28,7 @@ jobs:
next_release_ref: ${{ steps.output-next-release-ref.outputs.next_release_ref }}
steps:
- name: Check out commit's code
- uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
+ uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
with:
# Full history is needed to list the release branches.
fetch-depth: 0
@@ -45,7 +45,7 @@ jobs:
echo "next_release_ref=${next_release_ref}" >> $GITHUB_OUTPUT
- name: Check for changes in relevant files
- uses: dorny/paths-filter@ebc4d7e9ebcb0b1eb21480bb8f43113e996ac77a # v3.0.1
+ uses: dorny/paths-filter@ceb8a2b8f2d89434be7ff52d3de7ec3738c5cc9d # v4.0.3
id: changes
with:
token: ''
@@ -93,7 +93,7 @@ jobs:
run: exit 1
- name: Check out commit's code
- uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
+ uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
with:
persist-credentials: 'false'
@@ -101,7 +101,7 @@ jobs:
uses: $/.github/actions/tune-os
- name: Set up python
- uses: actions/setup-python@39cd14951b08e74b54015e9e001cdefcf80e669f # v5.1.1
+ uses: actions/setup-python@5fda3b95a4ea91299a34e894583c3862153e4b97 # v7.0.0
- name: Setup MySQL
uses: $/.github/actions/setup-mysql
@@ -128,7 +128,7 @@ jobs:
# Checkout to the next release of Vitess
- name: Check out other version's code (${{ needs.changes.outputs.next_release_ref }})
- uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
+ uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
with:
ref: ${{ needs.changes.outputs.next_release_ref }}
persist-credentials: 'false'
@@ -150,7 +150,7 @@ jobs:
# Checkout to this build's commit
- name: Check out commit's code
- uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
+ uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
with:
persist-credentials: 'false'
diff --git a/.github/workflows/upgrade_downgrade_test_backups_manual.yml b/.github/workflows/upgrade_downgrade_test_backups_manual.yml
index 4c4a64c5f08..f5f14f64f3f 100644
--- a/.github/workflows/upgrade_downgrade_test_backups_manual.yml
+++ b/.github/workflows/upgrade_downgrade_test_backups_manual.yml
@@ -28,7 +28,7 @@ jobs:
previous_release_ref: ${{ steps.output-previous-release-ref.outputs.previous_release_ref }}
steps:
- name: Check out commit's code
- uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
+ uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
with:
# Full history is needed to list the release branches.
fetch-depth: 0
@@ -45,7 +45,7 @@ jobs:
echo "previous_release_ref=${previous_release_ref}" >> $GITHUB_OUTPUT
- name: Check for changes in relevant files
- uses: dorny/paths-filter@ebc4d7e9ebcb0b1eb21480bb8f43113e996ac77a # v3.0.1
+ uses: dorny/paths-filter@ceb8a2b8f2d89434be7ff52d3de7ec3738c5cc9d # v4.0.3
id: changes
with:
token: ''
@@ -96,7 +96,7 @@ jobs:
# Checkout to this build's commit
- name: Checkout to commit's code
- uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
+ uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
with:
persist-credentials: 'false'
@@ -104,7 +104,7 @@ jobs:
uses: $/.github/actions/tune-os
- name: Set up python
- uses: actions/setup-python@39cd14951b08e74b54015e9e001cdefcf80e669f # v5.1.1
+ uses: actions/setup-python@5fda3b95a4ea91299a34e894583c3862153e4b97 # v7.0.0
- name: Setup MySQL
uses: $/.github/actions/setup-mysql
@@ -131,7 +131,7 @@ jobs:
# Checkout to the last release of Vitess
- name: Checkout to the other version's code (${{ needs.changes.outputs.previous_release_ref }})
- uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
+ uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
with:
ref: ${{ needs.changes.outputs.previous_release_ref }}
persist-credentials: 'false'
@@ -153,7 +153,7 @@ jobs:
# Checkout to this build's commit
- name: Checkout to commit's code
- uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
+ uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
with:
persist-credentials: 'false'
diff --git a/.github/workflows/upgrade_downgrade_test_backups_manual_next_release.yml b/.github/workflows/upgrade_downgrade_test_backups_manual_next_release.yml
index 39a9a0743b0..8cc4a9db20d 100644
--- a/.github/workflows/upgrade_downgrade_test_backups_manual_next_release.yml
+++ b/.github/workflows/upgrade_downgrade_test_backups_manual_next_release.yml
@@ -28,7 +28,7 @@ jobs:
next_release_ref: ${{ steps.output-next-release-ref.outputs.next_release_ref }}
steps:
- name: Check out commit's code
- uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
+ uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
with:
# Full history is needed to list the release branches.
fetch-depth: 0
@@ -45,7 +45,7 @@ jobs:
echo "next_release_ref=${next_release_ref}" >> $GITHUB_OUTPUT
- name: Check for changes in relevant files
- uses: dorny/paths-filter@ebc4d7e9ebcb0b1eb21480bb8f43113e996ac77a # v3.0.1
+ uses: dorny/paths-filter@ceb8a2b8f2d89434be7ff52d3de7ec3738c5cc9d # v4.0.3
id: changes
with:
token: ''
@@ -96,7 +96,7 @@ jobs:
# Checkout to this build's commit
- name: Checkout to commit's code
- uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
+ uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
with:
persist-credentials: 'false'
@@ -104,7 +104,7 @@ jobs:
uses: $/.github/actions/tune-os
- name: Set up python
- uses: actions/setup-python@39cd14951b08e74b54015e9e001cdefcf80e669f # v5.1.1
+ uses: actions/setup-python@5fda3b95a4ea91299a34e894583c3862153e4b97 # v7.0.0
- name: Setup MySQL
uses: $/.github/actions/setup-mysql
@@ -131,7 +131,7 @@ jobs:
# Checkout to the next release of Vitess
- name: Checkout to the other version's code (${{ needs.changes.outputs.next_release_ref }})
- uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
+ uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
with:
ref: ${{ needs.changes.outputs.next_release_ref }}
persist-credentials: 'false'
@@ -153,7 +153,7 @@ jobs:
# Checkout to this build's commit
- name: Checkout to commit's code
- uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
+ uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
with:
persist-credentials: 'false'
diff --git a/.github/workflows/upgrade_downgrade_test_onlineddl_flow.yml b/.github/workflows/upgrade_downgrade_test_onlineddl_flow.yml
index c4d979d83e0..6345b7409cb 100644
--- a/.github/workflows/upgrade_downgrade_test_onlineddl_flow.yml
+++ b/.github/workflows/upgrade_downgrade_test_onlineddl_flow.yml
@@ -32,7 +32,7 @@ jobs:
next_release_ref: ${{ steps.output-next-release-ref.outputs.next_release_ref }}
steps:
- name: Check out commit's code
- uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
+ uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
with:
# Full history is needed to list the release branches.
fetch-depth: 0
@@ -59,7 +59,7 @@ jobs:
echo "next_release_ref=${next_release_ref}" >> $GITHUB_OUTPUT
- name: Check for changes in relevant files
- uses: dorny/paths-filter@ebc4d7e9ebcb0b1eb21480bb8f43113e996ac77a # v3.0.1
+ uses: dorny/paths-filter@ceb8a2b8f2d89434be7ff52d3de7ec3738c5cc9d # v4.0.3
id: changes
with:
token: ''
@@ -107,7 +107,7 @@ jobs:
run: exit 1
- name: Check out commit's code
- uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
+ uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
with:
persist-credentials: 'false'
@@ -115,7 +115,7 @@ jobs:
uses: $/.github/actions/tune-os
- name: Set up python
- uses: actions/setup-python@39cd14951b08e74b54015e9e001cdefcf80e669f # v5.1.1
+ uses: actions/setup-python@5fda3b95a4ea91299a34e894583c3862153e4b97 # v7.0.0
- name: Setup MySQL
uses: $/.github/actions/setup-mysql
@@ -134,7 +134,7 @@ jobs:
# Checkout to the last release of Vitess
- name: Check out last version's code (${{ needs.changes.outputs.previous_release_ref }})
- uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
+ uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
with:
ref: ${{ needs.changes.outputs.previous_release_ref }}
persist-credentials: 'false'
@@ -157,7 +157,7 @@ jobs:
# Checkout to the next release of Vitess
- name: Check out next version's code (${{ needs.changes.outputs.next_release_ref }})
- uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
+ uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
with:
ref: ${{ needs.changes.outputs.next_release_ref }}
persist-credentials: 'false'
@@ -180,7 +180,7 @@ jobs:
# Checkout to this build's commit
- name: Check out commit's code
- uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
+ uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
with:
persist-credentials: 'false'
diff --git a/.github/workflows/upgrade_downgrade_test_query_serving_queries.yml b/.github/workflows/upgrade_downgrade_test_query_serving_queries.yml
index fbb1136315d..3c0f59c3f2e 100644
--- a/.github/workflows/upgrade_downgrade_test_query_serving_queries.yml
+++ b/.github/workflows/upgrade_downgrade_test_query_serving_queries.yml
@@ -31,7 +31,7 @@ jobs:
previous_release_ref: ${{ steps.output-previous-release-ref.outputs.previous_release_ref }}
steps:
- name: Check out commit's code
- uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
+ uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
with:
# Full history is needed to list the release branches.
fetch-depth: 0
@@ -48,7 +48,7 @@ jobs:
echo "previous_release_ref=${previous_release_ref}" >> $GITHUB_OUTPUT
- name: Check for changes in relevant files
- uses: dorny/paths-filter@ebc4d7e9ebcb0b1eb21480bb8f43113e996ac77a # v3.0.1
+ uses: dorny/paths-filter@ceb8a2b8f2d89434be7ff52d3de7ec3738c5cc9d # v4.0.3
id: changes
with:
token: ''
@@ -96,7 +96,7 @@ jobs:
run: exit 1
- name: Check out commit's code
- uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
+ uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
with:
persist-credentials: 'false'
@@ -111,7 +111,7 @@ jobs:
uses: $/.github/actions/tune-os
- name: Set up python
- uses: actions/setup-python@39cd14951b08e74b54015e9e001cdefcf80e669f # v5.1.1
+ uses: actions/setup-python@5fda3b95a4ea91299a34e894583c3862153e4b97 # v7.0.0
- name: Setup MySQL
uses: $/.github/actions/setup-mysql
@@ -140,7 +140,7 @@ jobs:
# Checkout to the last release of Vitess
- name: Check out other version's code (${{ needs.changes.outputs.previous_release_ref }})
- uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
+ uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
with:
ref: ${{ needs.changes.outputs.previous_release_ref }}
persist-credentials: 'false'
diff --git a/.github/workflows/upgrade_downgrade_test_query_serving_queries_2.yml b/.github/workflows/upgrade_downgrade_test_query_serving_queries_2.yml
index a0473165e57..dc57b577b71 100644
--- a/.github/workflows/upgrade_downgrade_test_query_serving_queries_2.yml
+++ b/.github/workflows/upgrade_downgrade_test_query_serving_queries_2.yml
@@ -30,7 +30,7 @@ jobs:
previous_release_ref: ${{ steps.output-previous-release-ref.outputs.previous_release_ref }}
steps:
- name: Check out commit's code
- uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
+ uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
with:
# Full history is needed to list the release branches.
fetch-depth: 0
@@ -47,7 +47,7 @@ jobs:
echo "previous_release_ref=${previous_release_ref}" >> $GITHUB_OUTPUT
- name: Check for changes in relevant files
- uses: dorny/paths-filter@ebc4d7e9ebcb0b1eb21480bb8f43113e996ac77a # v3.0.1
+ uses: dorny/paths-filter@ceb8a2b8f2d89434be7ff52d3de7ec3738c5cc9d # v4.0.3
id: changes
with:
token: ''
@@ -95,7 +95,7 @@ jobs:
run: exit 1
- name: Check out commit's code
- uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
+ uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
with:
persist-credentials: 'false'
@@ -110,7 +110,7 @@ jobs:
uses: $/.github/actions/tune-os
- name: Set up python
- uses: actions/setup-python@39cd14951b08e74b54015e9e001cdefcf80e669f # v5.1.1
+ uses: actions/setup-python@5fda3b95a4ea91299a34e894583c3862153e4b97 # v7.0.0
- name: Setup MySQL
uses: $/.github/actions/setup-mysql
@@ -139,7 +139,7 @@ jobs:
# Checkout to the last release of Vitess
- name: Check out other version's code (${{ needs.changes.outputs.previous_release_ref }})
- uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
+ uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
with:
ref: ${{ needs.changes.outputs.previous_release_ref }}
persist-credentials: 'false'
diff --git a/.github/workflows/upgrade_downgrade_test_query_serving_queries_2_next_release.yml b/.github/workflows/upgrade_downgrade_test_query_serving_queries_2_next_release.yml
index f56e4250258..baf2f3d4990 100644
--- a/.github/workflows/upgrade_downgrade_test_query_serving_queries_2_next_release.yml
+++ b/.github/workflows/upgrade_downgrade_test_query_serving_queries_2_next_release.yml
@@ -31,7 +31,7 @@ jobs:
next_release_ref: ${{ steps.output-next-release-ref.outputs.next_release_ref }}
steps:
- name: Check out commit's code
- uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
+ uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
with:
# Full history is needed to list the release branches.
fetch-depth: 0
@@ -48,7 +48,7 @@ jobs:
echo "next_release_ref=${next_release_ref}" >> $GITHUB_OUTPUT
- name: Check for changes in relevant files
- uses: dorny/paths-filter@ebc4d7e9ebcb0b1eb21480bb8f43113e996ac77a # v3.0.1
+ uses: dorny/paths-filter@ceb8a2b8f2d89434be7ff52d3de7ec3738c5cc9d # v4.0.3
id: changes
with:
token: ''
@@ -96,7 +96,7 @@ jobs:
run: exit 1
- name: Check out commit's code
- uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
+ uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
with:
persist-credentials: 'false'
@@ -104,7 +104,7 @@ jobs:
uses: $/.github/actions/tune-os
- name: Set up python
- uses: actions/setup-python@39cd14951b08e74b54015e9e001cdefcf80e669f # v5.1.1
+ uses: actions/setup-python@5fda3b95a4ea91299a34e894583c3862153e4b97 # v7.0.0
- name: Setup MySQL
uses: $/.github/actions/setup-mysql
@@ -123,7 +123,7 @@ jobs:
# Checkout to the next release of Vitess
- name: Check out other version's code (${{ needs.changes.outputs.next_release_ref }})
- uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
+ uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
with:
ref: ${{ needs.changes.outputs.next_release_ref }}
persist-credentials: 'false'
@@ -145,7 +145,7 @@ jobs:
# Checkout to this build's commit
- name: Check out commit's code
- uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
+ uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
with:
persist-credentials: 'false'
diff --git a/.github/workflows/upgrade_downgrade_test_query_serving_queries_next_release.yml b/.github/workflows/upgrade_downgrade_test_query_serving_queries_next_release.yml
index 2a2be95d882..41cab616751 100644
--- a/.github/workflows/upgrade_downgrade_test_query_serving_queries_next_release.yml
+++ b/.github/workflows/upgrade_downgrade_test_query_serving_queries_next_release.yml
@@ -31,7 +31,7 @@ jobs:
next_release_ref: ${{ steps.output-next-release-ref.outputs.next_release_ref }}
steps:
- name: Check out commit's code
- uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
+ uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
with:
# Full history is needed to list the release branches.
fetch-depth: 0
@@ -48,7 +48,7 @@ jobs:
echo "next_release_ref=${next_release_ref}" >> $GITHUB_OUTPUT
- name: Check for changes in relevant files
- uses: dorny/paths-filter@ebc4d7e9ebcb0b1eb21480bb8f43113e996ac77a # v3.0.1
+ uses: dorny/paths-filter@ceb8a2b8f2d89434be7ff52d3de7ec3738c5cc9d # v4.0.3
id: changes
with:
token: ''
@@ -96,7 +96,7 @@ jobs:
run: exit 1
- name: Check out commit's code
- uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
+ uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
with:
persist-credentials: 'false'
@@ -104,7 +104,7 @@ jobs:
uses: $/.github/actions/tune-os
- name: Set up python
- uses: actions/setup-python@39cd14951b08e74b54015e9e001cdefcf80e669f # v5.1.1
+ uses: actions/setup-python@5fda3b95a4ea91299a34e894583c3862153e4b97 # v7.0.0
- name: Setup MySQL
uses: $/.github/actions/setup-mysql
@@ -123,7 +123,7 @@ jobs:
# Checkout to the next release of Vitess
- name: Check out other version's code (${{ needs.changes.outputs.next_release_ref }})
- uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
+ uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
with:
ref: ${{ needs.changes.outputs.next_release_ref }}
persist-credentials: 'false'
@@ -145,7 +145,7 @@ jobs:
# Checkout to this build's commit
- name: Check out commit's code
- uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
+ uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
with:
persist-credentials: 'false'
diff --git a/.github/workflows/upgrade_downgrade_test_query_serving_schema.yml b/.github/workflows/upgrade_downgrade_test_query_serving_schema.yml
index 5827e817b4e..86a82a3771d 100644
--- a/.github/workflows/upgrade_downgrade_test_query_serving_schema.yml
+++ b/.github/workflows/upgrade_downgrade_test_query_serving_schema.yml
@@ -31,7 +31,7 @@ jobs:
previous_release_ref: ${{ steps.output-previous-release-ref.outputs.previous_release_ref }}
steps:
- name: Check out commit's code
- uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
+ uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
with:
# Full history is needed to list the release branches.
fetch-depth: 0
@@ -48,7 +48,7 @@ jobs:
echo "previous_release_ref=${previous_release_ref}" >> $GITHUB_OUTPUT
- name: Check for changes in relevant files
- uses: dorny/paths-filter@ebc4d7e9ebcb0b1eb21480bb8f43113e996ac77a # v3.0.1
+ uses: dorny/paths-filter@ceb8a2b8f2d89434be7ff52d3de7ec3738c5cc9d # v4.0.3
id: changes
with:
token: ''
@@ -96,7 +96,7 @@ jobs:
run: exit 1
- name: Check out commit's code
- uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
+ uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
with:
persist-credentials: 'false'
@@ -104,7 +104,7 @@ jobs:
uses: $/.github/actions/tune-os
- name: Set up python
- uses: actions/setup-python@39cd14951b08e74b54015e9e001cdefcf80e669f # v5.1.1
+ uses: actions/setup-python@5fda3b95a4ea91299a34e894583c3862153e4b97 # v7.0.0
- name: Setup MySQL
uses: $/.github/actions/setup-mysql
@@ -123,7 +123,7 @@ jobs:
# Checkout to the last release of Vitess
- name: Check out other version's code (${{ needs.changes.outputs.previous_release_ref }})
- uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
+ uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
with:
ref: ${{ needs.changes.outputs.previous_release_ref }}
persist-credentials: 'false'
@@ -145,7 +145,7 @@ jobs:
# Checkout to this build's commit
- name: Check out commit's code
- uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
+ uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
with:
persist-credentials: 'false'
diff --git a/.github/workflows/upgrade_downgrade_test_query_serving_schema_next_release.yml b/.github/workflows/upgrade_downgrade_test_query_serving_schema_next_release.yml
index 27a6761122b..54a31dd4081 100644
--- a/.github/workflows/upgrade_downgrade_test_query_serving_schema_next_release.yml
+++ b/.github/workflows/upgrade_downgrade_test_query_serving_schema_next_release.yml
@@ -31,7 +31,7 @@ jobs:
next_release_ref: ${{ steps.output-next-release-ref.outputs.next_release_ref }}
steps:
- name: Check out commit's code
- uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
+ uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
with:
# Full history is needed to list the release branches.
fetch-depth: 0
@@ -48,7 +48,7 @@ jobs:
echo "next_release_ref=${next_release_ref}" >> $GITHUB_OUTPUT
- name: Check for changes in relevant files
- uses: dorny/paths-filter@ebc4d7e9ebcb0b1eb21480bb8f43113e996ac77a # v3.0.1
+ uses: dorny/paths-filter@ceb8a2b8f2d89434be7ff52d3de7ec3738c5cc9d # v4.0.3
id: changes
with:
token: ''
@@ -96,7 +96,7 @@ jobs:
run: exit 1
- name: Check out commit's code
- uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
+ uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
with:
persist-credentials: 'false'
@@ -104,7 +104,7 @@ jobs:
uses: $/.github/actions/tune-os
- name: Set up python
- uses: actions/setup-python@39cd14951b08e74b54015e9e001cdefcf80e669f # v5.1.1
+ uses: actions/setup-python@5fda3b95a4ea91299a34e894583c3862153e4b97 # v7.0.0
- name: Setup MySQL
uses: $/.github/actions/setup-mysql
@@ -123,7 +123,7 @@ jobs:
# Checkout to the next release of Vitess
- name: Check out other version's code (${{ needs.changes.outputs.next_release_ref }})
- uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
+ uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
with:
ref: ${{ needs.changes.outputs.next_release_ref }}
persist-credentials: 'false'
@@ -145,7 +145,7 @@ jobs:
# Checkout to this build's commit
- name: Check out commit's code
- uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
+ uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
with:
persist-credentials: 'false'
diff --git a/.github/workflows/upgrade_downgrade_test_reparent_new_vtctl.yml b/.github/workflows/upgrade_downgrade_test_reparent_new_vtctl.yml
index f9d595887cc..2fbd5269fc4 100644
--- a/.github/workflows/upgrade_downgrade_test_reparent_new_vtctl.yml
+++ b/.github/workflows/upgrade_downgrade_test_reparent_new_vtctl.yml
@@ -31,7 +31,7 @@ jobs:
next_release_ref: ${{ steps.output-next-release-ref.outputs.next_release_ref }}
steps:
- name: Check out commit's code
- uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
+ uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
with:
# Full history is needed to list the release branches.
fetch-depth: 0
@@ -48,7 +48,7 @@ jobs:
echo "next_release_ref=${next_release_ref}" >> $GITHUB_OUTPUT
- name: Check for changes in relevant files
- uses: dorny/paths-filter@ebc4d7e9ebcb0b1eb21480bb8f43113e996ac77a # v3.0.1
+ uses: dorny/paths-filter@ceb8a2b8f2d89434be7ff52d3de7ec3738c5cc9d # v4.0.3
id: changes
with:
token: ''
@@ -96,7 +96,7 @@ jobs:
run: exit 1
- name: Check out commit's code
- uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
+ uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
with:
persist-credentials: 'false'
@@ -104,7 +104,7 @@ jobs:
uses: $/.github/actions/tune-os
- name: Set up python
- uses: actions/setup-python@39cd14951b08e74b54015e9e001cdefcf80e669f # v5.1.1
+ uses: actions/setup-python@5fda3b95a4ea91299a34e894583c3862153e4b97 # v7.0.0
- name: Setup MySQL
uses: $/.github/actions/setup-mysql
@@ -123,7 +123,7 @@ jobs:
# Checkout to the next release of Vitess
- name: Check out other version's code (${{ needs.changes.outputs.next_release_ref }})
- uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
+ uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
with:
ref: ${{ needs.changes.outputs.next_release_ref }}
persist-credentials: 'false'
@@ -145,7 +145,7 @@ jobs:
# Checkout to this build's commit
- name: Check out commit's code
- uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
+ uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
with:
persist-credentials: 'false'
diff --git a/.github/workflows/upgrade_downgrade_test_reparent_new_vttablet.yml b/.github/workflows/upgrade_downgrade_test_reparent_new_vttablet.yml
index f054403c94f..3016bc9414a 100644
--- a/.github/workflows/upgrade_downgrade_test_reparent_new_vttablet.yml
+++ b/.github/workflows/upgrade_downgrade_test_reparent_new_vttablet.yml
@@ -31,7 +31,7 @@ jobs:
next_release_ref: ${{ steps.output-next-release-ref.outputs.next_release_ref }}
steps:
- name: Check out commit's code
- uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
+ uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
with:
# Full history is needed to list the release branches.
fetch-depth: 0
@@ -48,7 +48,7 @@ jobs:
echo "next_release_ref=${next_release_ref}" >> $GITHUB_OUTPUT
- name: Check for changes in relevant files
- uses: dorny/paths-filter@ebc4d7e9ebcb0b1eb21480bb8f43113e996ac77a # v3.0.1
+ uses: dorny/paths-filter@ceb8a2b8f2d89434be7ff52d3de7ec3738c5cc9d # v4.0.3
id: changes
with:
token: ''
@@ -96,7 +96,7 @@ jobs:
run: exit 1
- name: Check out commit's code
- uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
+ uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
with:
persist-credentials: 'false'
@@ -104,7 +104,7 @@ jobs:
uses: $/.github/actions/tune-os
- name: Set up python
- uses: actions/setup-python@39cd14951b08e74b54015e9e001cdefcf80e669f # v5.1.1
+ uses: actions/setup-python@5fda3b95a4ea91299a34e894583c3862153e4b97 # v7.0.0
- name: Setup MySQL
uses: $/.github/actions/setup-mysql
@@ -131,7 +131,7 @@ jobs:
# Checkout to the next release of Vitess
- name: Check out other version's code (${{ needs.changes.outputs.next_release_ref }})
- uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
+ uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
with:
ref: ${{ needs.changes.outputs.next_release_ref }}
persist-credentials: 'false'
@@ -153,7 +153,7 @@ jobs:
# Checkout to this build's commit
- name: Check out commit's code
- uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
+ uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
with:
persist-credentials: 'false'
diff --git a/.github/workflows/upgrade_downgrade_test_reparent_old_vtctl.yml b/.github/workflows/upgrade_downgrade_test_reparent_old_vtctl.yml
index f36e5303bde..498f3c62741 100644
--- a/.github/workflows/upgrade_downgrade_test_reparent_old_vtctl.yml
+++ b/.github/workflows/upgrade_downgrade_test_reparent_old_vtctl.yml
@@ -31,7 +31,7 @@ jobs:
previous_release_ref: ${{ steps.output-previous-release-ref.outputs.previous_release_ref }}
steps:
- name: Check out commit's code
- uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
+ uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
with:
# Full history is needed to list the release branches.
fetch-depth: 0
@@ -48,7 +48,7 @@ jobs:
echo "previous_release_ref=${previous_release_ref}" >> $GITHUB_OUTPUT
- name: Check for changes in relevant files
- uses: dorny/paths-filter@ebc4d7e9ebcb0b1eb21480bb8f43113e996ac77a # v3.0.1
+ uses: dorny/paths-filter@ceb8a2b8f2d89434be7ff52d3de7ec3738c5cc9d # v4.0.3
id: changes
with:
token: ''
@@ -96,7 +96,7 @@ jobs:
run: exit 1
- name: Check out commit's code
- uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
+ uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
with:
persist-credentials: 'false'
@@ -104,7 +104,7 @@ jobs:
uses: $/.github/actions/tune-os
- name: Set up python
- uses: actions/setup-python@39cd14951b08e74b54015e9e001cdefcf80e669f # v5.1.1
+ uses: actions/setup-python@5fda3b95a4ea91299a34e894583c3862153e4b97 # v7.0.0
- name: Setup MySQL
uses: $/.github/actions/setup-mysql
@@ -123,7 +123,7 @@ jobs:
# Checkout to the last release of Vitess
- name: Check out other version's code (${{ needs.changes.outputs.previous_release_ref }})
- uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
+ uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
with:
ref: ${{ needs.changes.outputs.previous_release_ref }}
persist-credentials: 'false'
@@ -145,7 +145,7 @@ jobs:
# Checkout to this build's commit
- name: Check out commit's code
- uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
+ uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
with:
persist-credentials: 'false'
diff --git a/.github/workflows/upgrade_downgrade_test_reparent_old_vttablet.yml b/.github/workflows/upgrade_downgrade_test_reparent_old_vttablet.yml
index 04fb2cdaaca..441663c8d3c 100644
--- a/.github/workflows/upgrade_downgrade_test_reparent_old_vttablet.yml
+++ b/.github/workflows/upgrade_downgrade_test_reparent_old_vttablet.yml
@@ -31,7 +31,7 @@ jobs:
previous_release_ref: ${{ steps.output-previous-release-ref.outputs.previous_release_ref }}
steps:
- name: Check out commit's code
- uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
+ uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
with:
# Full history is needed to list the release branches.
fetch-depth: 0
@@ -48,7 +48,7 @@ jobs:
echo "previous_release_ref=${previous_release_ref}" >> $GITHUB_OUTPUT
- name: Check for changes in relevant files
- uses: dorny/paths-filter@ebc4d7e9ebcb0b1eb21480bb8f43113e996ac77a # v3.0.1
+ uses: dorny/paths-filter@ceb8a2b8f2d89434be7ff52d3de7ec3738c5cc9d # v4.0.3
id: changes
with:
token: ''
@@ -96,7 +96,7 @@ jobs:
run: exit 1
- name: Check out commit's code
- uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
+ uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
with:
persist-credentials: 'false'
@@ -104,7 +104,7 @@ jobs:
uses: $/.github/actions/tune-os
- name: Set up python
- uses: actions/setup-python@39cd14951b08e74b54015e9e001cdefcf80e669f # v5.1.1
+ uses: actions/setup-python@5fda3b95a4ea91299a34e894583c3862153e4b97 # v7.0.0
- name: Setup MySQL
uses: $/.github/actions/setup-mysql
@@ -123,7 +123,7 @@ jobs:
# Checkout to the last release of Vitess
- name: Check out other version's code (${{ needs.changes.outputs.previous_release_ref }})
- uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
+ uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
with:
ref: ${{ needs.changes.outputs.previous_release_ref }}
persist-credentials: 'false'
@@ -145,7 +145,7 @@ jobs:
# Checkout to this build's commit
- name: Check out commit's code
- uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
+ uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
with:
persist-credentials: 'false'
diff --git a/.github/workflows/upgrade_downgrade_test_semi_sync.yml b/.github/workflows/upgrade_downgrade_test_semi_sync.yml
index 0d906b58728..21b5c9f0e26 100644
--- a/.github/workflows/upgrade_downgrade_test_semi_sync.yml
+++ b/.github/workflows/upgrade_downgrade_test_semi_sync.yml
@@ -29,13 +29,13 @@ jobs:
fi
- name: Check out commit's code
- uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
+ uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
with:
fetch-depth: 0
persist-credentials: 'false'
- name: Check for changes in relevant files
- uses: dorny/paths-filter@ebc4d7e9ebcb0b1eb21480bb8f43113e996ac77a # v3.0.1
+ uses: dorny/paths-filter@ceb8a2b8f2d89434be7ff52d3de7ec3738c5cc9d # v4.0.3
id: changes
with:
token: ''
@@ -72,7 +72,7 @@ jobs:
- name: Set up python
if: steps.changes.outputs.end_to_end == 'true'
- uses: actions/setup-python@39cd14951b08e74b54015e9e001cdefcf80e669f # v5.1.1
+ uses: actions/setup-python@5fda3b95a4ea91299a34e894583c3862153e4b97 # v7.0.0
- name: Setup MySQL
if: steps.changes.outputs.end_to_end == 'true'
@@ -102,14 +102,14 @@ jobs:
# Checkout to the last release of Vitess
- name: Check out other version's code (${{ steps.output-previous-release-ref.outputs.previous_release_ref }})
if: steps.changes.outputs.end_to_end == 'true'
- uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
+ uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
with:
ref: ${{ steps.output-previous-release-ref.outputs.previous_release_ref }}
persist-credentials: 'false'
- name: Set up Go
if: steps.changes.outputs.end_to_end == 'true'
- uses: actions/setup-go@d35c59abb061a4a6fb18e82ac0862c26744d6ab5 # v5.5.0
+ uses: actions/setup-go@b7ad1dad31e06c5925ef5d2fc7ad053ef454303e # v7.0.0
with:
go-version-file: go.mod
cache: false
@@ -132,13 +132,13 @@ jobs:
# Checkout to this build's commit
- name: Check out commit's code
if: steps.changes.outputs.end_to_end == 'true'
- uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
+ uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
with:
persist-credentials: 'false'
- name: Set up Go
if: steps.changes.outputs.end_to_end == 'true'
- uses: actions/setup-go@d35c59abb061a4a6fb18e82ac0862c26744d6ab5 # v5.5.0
+ uses: actions/setup-go@b7ad1dad31e06c5925ef5d2fc7ad053ef454303e # v7.0.0
with:
go-version-file: go.mod
cache: false
diff --git a/.github/workflows/vitess_tester_vtgate.yml b/.github/workflows/vitess_tester_vtgate.yml
index 7428f5fed48..3ca9da870dd 100644
--- a/.github/workflows/vitess_tester_vtgate.yml
+++ b/.github/workflows/vitess_tester_vtgate.yml
@@ -32,12 +32,12 @@ jobs:
fi
- name: Check out code
- uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
+ uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
with:
persist-credentials: 'false'
- name: Check for changes in relevant files
- uses: dorny/paths-filter@ebc4d7e9ebcb0b1eb21480bb8f43113e996ac77a # v3.0.1
+ uses: dorny/paths-filter@ceb8a2b8f2d89434be7ff52d3de7ec3738c5cc9d # v4.0.3
id: changes
with:
token: ''
@@ -63,14 +63,14 @@ jobs:
- name: Set up Go
if: steps.changes.outputs.end_to_end == 'true'
# zizmor: ignore[cache-poisoning] this workflow publishes no artifacts
- uses: actions/setup-go@d35c59abb061a4a6fb18e82ac0862c26744d6ab5 # v5.5.0
+ uses: actions/setup-go@b7ad1dad31e06c5925ef5d2fc7ad053ef454303e # v7.0.0
with:
go-version-file: go.mod
cache: ${{ (github.base_ref == 'main' || (github.base_ref == '' && github.ref_name == 'main')) && 'true' || 'false' }}
- name: Set up python
if: steps.changes.outputs.end_to_end == 'true'
- uses: actions/setup-python@39cd14951b08e74b54015e9e001cdefcf80e669f # v5.1.1
+ uses: actions/setup-python@5fda3b95a4ea91299a34e894583c3862153e4b97 # v7.0.0
- name: Tune the OS
if: steps.changes.outputs.end_to_end == 'true'
@@ -151,7 +151,7 @@ jobs:
- name: Test Summary
if: steps.changes.outputs.end_to_end == 'true' && !cancelled()
- uses: test-summary/action@31493c76ec9e7aa675f1585d3ed6f1da69269a86 # v2.4
+ uses: test-summary/action@37b508cfee6d4d080eedd00b5bb240a6a784a6a5 # v2.6
with:
paths: "report*.xml"
show: "fail"
diff --git a/.github/workflows/vtadmin_web_build.yml b/.github/workflows/vtadmin_web_build.yml
index 095ae004573..a169e0f7719 100644
--- a/.github/workflows/vtadmin_web_build.yml
+++ b/.github/workflows/vtadmin_web_build.yml
@@ -30,7 +30,7 @@ jobs:
exit 1
fi
- - uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
+ - uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
with:
persist-credentials: 'false'
@@ -39,7 +39,7 @@ jobs:
- name: Setup Node
# zizmor: ignore[cache-poisoning] this workflow publishes no artifacts
- uses: actions/setup-node@6044e13b5dc448c55e2357c09f80417699197238 # v6.2.0
+ uses: actions/setup-node@820762786026740c76f36085b0efc47a31fe5020 # v7.0.0
with:
# node-version should match package.json
node-version: '22.13.1'
diff --git a/.github/workflows/vtadmin_web_lint.yml b/.github/workflows/vtadmin_web_lint.yml
index 29d32b42fd6..ae3493e53f7 100644
--- a/.github/workflows/vtadmin_web_lint.yml
+++ b/.github/workflows/vtadmin_web_lint.yml
@@ -30,7 +30,7 @@ jobs:
exit 1
fi
- - uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
+ - uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
with:
persist-credentials: 'false'
@@ -39,7 +39,7 @@ jobs:
- name: Setup Node
# zizmor: ignore[cache-poisoning] this workflow publishes no artifacts
- uses: actions/setup-node@6044e13b5dc448c55e2357c09f80417699197238 # v6.2.0
+ uses: actions/setup-node@820762786026740c76f36085b0efc47a31fe5020 # v7.0.0
with:
# node-version should match package.json
node-version: '22.13.1'
diff --git a/.github/workflows/vtadmin_web_unit_tests.yml b/.github/workflows/vtadmin_web_unit_tests.yml
index 9225f96f6d1..dd3f7fb10c0 100644
--- a/.github/workflows/vtadmin_web_unit_tests.yml
+++ b/.github/workflows/vtadmin_web_unit_tests.yml
@@ -30,7 +30,7 @@ jobs:
exit 1
fi
- - uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
+ - uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
with:
persist-credentials: 'false'
@@ -39,7 +39,7 @@ jobs:
- name: Setup Node
# zizmor: ignore[cache-poisoning] this workflow publishes no artifacts
- uses: actions/setup-node@6044e13b5dc448c55e2357c09f80417699197238 # v6.2.0
+ uses: actions/setup-node@820762786026740c76f36085b0efc47a31fe5020 # v7.0.0
with:
# node-version should match package.json
node-version: '22.13.1'
diff --git a/.github/workflows/vtop_example.yml b/.github/workflows/vtop_example.yml
index 20c42fbf55b..af82606d1f9 100644
--- a/.github/workflows/vtop_example.yml
+++ b/.github/workflows/vtop_example.yml
@@ -26,12 +26,12 @@ jobs:
end_to_end: ${{ steps.changes.outputs.end_to_end }}
steps:
- name: Check out code
- uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
+ uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
with:
persist-credentials: "false"
- name: Check for changes in relevant files
- uses: dorny/paths-filter@ebc4d7e9ebcb0b1eb21480bb8f43113e996ac77a # v3.0.1
+ uses: dorny/paths-filter@ceb8a2b8f2d89434be7ff52d3de7ec3738c5cc9d # v4.0.3
id: changes
with:
token: ""
@@ -78,13 +78,13 @@ jobs:
run: exit 1
- name: Check out code
- uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
+ uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
with:
persist-credentials: "false"
- name: Set up Go
# zizmor: ignore[cache-poisoning] this workflow publishes no artifacts
- uses: actions/setup-go@d35c59abb061a4a6fb18e82ac0862c26744d6ab5 # v5.5.0
+ uses: actions/setup-go@b7ad1dad31e06c5925ef5d2fc7ad053ef454303e # v7.0.0
with:
go-version-file: go.mod
cache: ${{ (github.base_ref == 'main' || (github.base_ref == '' && github.ref_name == 'main')) && 'true' || 'false' }}
From 73b9ad726fce1791ee9b6a3a0cd0de770cc6158d Mon Sep 17 00:00:00 2001
From: "vitess-bot[bot]" <108069721+vitess-bot[bot]@users.noreply.github.com>
Date: Wed, 14 Oct 2026 14:41:16 +0000
Subject: [PATCH 07/31] [release-23.0] java: fix Maven Central publishing with
Maven 3.10 (#21570) (#21575)
Signed-off-by: Matt Lord
Co-authored-by: vitess-bot[bot] <108069721+vitess-bot[bot]@users.noreply.github.com>
Co-authored-by: Matt Lord
---
doc/internal/release/how-to-release.md | 5 +--
doc/internal/release/java-packages.md | 51 ++++++++++++++++++++------
java/pom.xml | 2 +-
3 files changed, 43 insertions(+), 15 deletions(-)
diff --git a/doc/internal/release/how-to-release.md b/doc/internal/release/how-to-release.md
index 97e58a074d7..ea59018f23d 100644
--- a/doc/internal/release/how-to-release.md
+++ b/doc/internal/release/how-to-release.md
@@ -354,11 +354,10 @@ You will need administrator privileges on the vitess repository to be able to ma
3. Export following to avoid any version conflicts
```bash
- export MAVEN_OPTS="--add-opens=java.base/java.util=ALL-UNNAMED --add-opens=java.base/java.lang.reflect=ALL-UNNAMED --add-opens=java.base/java.text=ALL-UNNAMED
- --add-opens=java.desktop/java.awt.font=ALL-UNNAMED"
+ export MAVEN_OPTS="--add-opens=java.base/java.util=ALL-UNNAMED --add-opens=java.base/java.lang.reflect=ALL-UNNAMED --add-opens=java.base/java.text=ALL-UNNAMED --add-opens=java.desktop/java.awt.font=ALL-UNNAMED"
```
-4. Deploy (upload) the Java code to the oss.sonatype.org repository:
+4. Deploy (upload) the Java code to Maven Central through the [Central Portal](https://central.sonatype.com/):
> **Warning:** After the deployment, the Java packages will be automatically released. Once released, you cannot delete them. The only option is to upload a newer version (e.g. increment the patch level).
diff --git a/doc/internal/release/java-packages.md b/doc/internal/release/java-packages.md
index 3b3d2a38472..247a1d373e9 100644
--- a/doc/internal/release/java-packages.md
+++ b/doc/internal/release/java-packages.md
@@ -1,27 +1,56 @@
# Java Packages
-We publish binary packages for our [JDBC driver and Java client on Maven Central](https://search.maven.org/#search|ga|1|g:"io.vitess").
+We publish binary packages for our [JDBC driver and Java client on Maven Central](https://central.sonatype.com/namespace/io.vitess).
-To do so, we use the http://oss.sonatype.org/ repository.
-New packages must be uploaded there ("deployed") and will be automatically published ("released").
-Once they are released there, they will be automatically synchronized with Maven Central.
-The synchronization takes only several minutes, but the update on http://search.maven.org may take up to two hours.
+To do so, we use the [Central Portal](https://central.sonatype.com/).
+The `central-publishing-maven-plugin`, configured in the `release` profile of `java/pom.xml`, uploads ("deploys") the packages there as a single bundle.
+It must be version 0.12.0 or later to publish with Maven 3.10 ([#21566](https://github.com/vitessio/vitess/issues/21566)).
+After the Central Portal validates the bundle, it automatically publishes ("releases") the packages to Maven Central.
+Publishing usually takes several minutes, but the packages may take longer to show up in search results.
-## Access to oss.sonatype.org
+## Access to the Central Portal
-[Sign up here.](https://issues.sonatype.org/secure/Signup!default.jspa)
-Then you must be added as member to our `io.vitess` namespace.
-Therefore, file a JIRA ticket with Sonatype to get added ([example for a different namespace](https://issues.sonatype.org/browse/OSSRH-30604)).
+[Create a Central Portal account.](https://central.sonatype.org/register/central-portal/)
+Then you must be given access to our `io.vitess` namespace.
+Ask an administrator of the organization that owns `io.vitess` to [invite you and grant you access to the namespace](https://central.sonatype.org/publish/publish-portal-organizations/).
+If they don't see the Organizations tab, they can ask [Central Support](https://central.sonatype.org/faq/get-support/) to enable organization management.
## One-time setup
### Set up GPG
-Follow [Sonatype's GPG instructions](https://central.sonatype.org/pages/working-with-pgp-signatures.html).
+Follow [Sonatype's GPG instructions](https://central.sonatype.org/publish/requirements/gpg/).
Install `gpg-agent` (needed below) e.g. on Ubuntu via: `sudo apt-get install gnupg-agent`.
for Mac you need to install 'gnupg' via 'brew install gnupg'
### Login configuration
-Create the `settings.xml` in the `$HOME/.m2/` directory as described in their [instructions](https://central.sonatype.org/pages/apache-maven.html).
+[Generate a user token](https://central.sonatype.org/publish/generate-portal-token/) in the Central Portal.
+Then add it to the `settings.xml` in the `$HOME/.m2/` directory, using the server ID `central`:
+
+```xml
+
+
+
+ central
+
+
+
+
+
+```
+
+## Publishing a release
+
+> **Warning:** Once the packages are published, you cannot delete them. The only option is to publish a newer version (e.g. increment the patch level).
+
+1. Check out the release tag, e.g. `git checkout v24.0.5`.
+2. Start `gpg-agent`, so that Maven doesn't keep prompting for your private key's passphrase (see [How to Release](how-to-release.md#java-packages-deploy--release)).
+3. Go into the `java` directory, then build and publish the packages:
+
+ ```bash
+ cd java
+ export MAVEN_OPTS="--add-opens=java.base/java.util=ALL-UNNAMED --add-opens=java.base/java.lang.reflect=ALL-UNNAMED --add-opens=java.base/java.text=ALL-UNNAMED --add-opens=java.desktop/java.awt.font=ALL-UNNAMED"
+ mvn clean deploy -P release
+ ```
diff --git a/java/pom.xml b/java/pom.xml
index e1136d92723..14f23b87e47 100644
--- a/java/pom.xml
+++ b/java/pom.xml
@@ -293,7 +293,7 @@
org.sonatype.central
central-publishing-maven-plugin
- 0.6.0
+ 0.12.0
true
central
From 735314ef9dd6b8ef48adab6970b0e5cf640e3665 Mon Sep 17 00:00:00 2001
From: "vitess-bot[bot]" <108069721+vitess-bot[bot]@users.noreply.github.com>
Date: Wed, 14 Oct 2026 14:32:31 -0400
Subject: [PATCH 08/31] [release-23.0] VReplication: cancel the switch when
reading the source positions fails (#21531) (#21591)
Signed-off-by: Matt Lord
Co-authored-by: vitess-bot[bot] <108069721+vitess-bot[bot]@users.noreply.github.com>
---
go/vt/vtctl/workflow/framework_test.go | 13 +++++
go/vt/vtctl/workflow/server.go | 3 ++
go/vt/vtctl/workflow/server_test.go | 68 ++++++++++++++++++++++++--
3 files changed, 81 insertions(+), 3 deletions(-)
diff --git a/go/vt/vtctl/workflow/framework_test.go b/go/vt/vtctl/workflow/framework_test.go
index f6eea36cd3e..4e0d0e47173 100644
--- a/go/vt/vtctl/workflow/framework_test.go
+++ b/go/vt/vtctl/workflow/framework_test.go
@@ -280,6 +280,7 @@ type testTMClient struct {
updateVReplicationWorklowRequests map[uint32][]*updateVReplicationWorkflowRequestResponse
applySchemaRequests map[uint32][]*applySchemaRequestResponse
primaryPositions map[uint32]string
+ primaryPositionErrors map[uint32]error
vdiffRequests map[uint32]*vdiffRequestResponse
refreshStateErrors map[uint32]error
@@ -818,9 +819,21 @@ func (tmc *testTMClient) setPrimaryPosition(tablet *topodatapb.Tablet, position
tmc.primaryPositions[tablet.Alias.Uid] = position
}
+func (tmc *testTMClient) setPrimaryPositionError(tablet *topodatapb.Tablet, err error) {
+ tmc.mu.Lock()
+ defer tmc.mu.Unlock()
+ if tmc.primaryPositionErrors == nil {
+ tmc.primaryPositionErrors = make(map[uint32]error)
+ }
+ tmc.primaryPositionErrors[tablet.Alias.Uid] = err
+}
+
func (tmc *testTMClient) PrimaryPosition(ctx context.Context, tablet *topodatapb.Tablet) (string, error) {
tmc.mu.Lock()
defer tmc.mu.Unlock()
+ if err := tmc.primaryPositionErrors[tablet.Alias.Uid]; err != nil {
+ return "", err
+ }
if tmc.primaryPositions != nil && tmc.primaryPositions[tablet.Alias.Uid] != "" {
return tmc.primaryPositions[tablet.Alias.Uid], nil
}
diff --git a/go/vt/vtctl/workflow/server.go b/go/vt/vtctl/workflow/server.go
index 0a7f169b9b4..195de053a14 100644
--- a/go/vt/vtctl/workflow/server.go
+++ b/go/vt/vtctl/workflow/server.go
@@ -3218,6 +3218,9 @@ func (s *Server) switchWrites(ctx context.Context, req *vtctldatapb.WorkflowSwit
// intra-keyspace materializations that write on the source), and we know for certain
// that any in progress writes are done.
if err := ts.gatherSourcePositions(ctx); err != nil {
+ if cerr := sw.cancelMigration(ctx, sm); cerr != nil {
+ err = vterrors.Errorf(vtrpcpb.Code_CANCELED, "%v\n\n%v", err, cerr)
+ }
return handleError("failed to gather replication positions on migration sources", err)
}
diff --git a/go/vt/vtctl/workflow/server_test.go b/go/vt/vtctl/workflow/server_test.go
index c832bdb6a92..28912f42a7f 100644
--- a/go/vt/vtctl/workflow/server_test.go
+++ b/go/vt/vtctl/workflow/server_test.go
@@ -1254,6 +1254,12 @@ func TestMoveTablesTrafficSwitching(t *testing.T) {
query: fmt.Sprintf("update _vt.vreplication set message = 'FROZEN' where db_name='vt_%s' and workflow='%s'", sourceKeyspaceName, ReverseWorkflowName(workflowName)),
result: &querypb.QueryResult{},
}
+ // Canceling a forward switch restarts the workflow and deletes the
+ // reverse one.
+ restartWFQR := &queryResult{
+ query: fmt.Sprintf("update _vt.vreplication set state='Running', message='' where db_name='vt_%s' and workflow='%s'", targetKeyspaceName, workflowName),
+ result: &querypb.QueryResult{},
+ }
hasDeniedTableEntry := func(si *topo.ShardInfo) bool {
if si == nil || len(si.TabletControls) == 0 {
@@ -1271,8 +1277,13 @@ func TestMoveTablesTrafficSwitching(t *testing.T) {
req *vtctldatapb.WorkflowSwitchTrafficRequest
multiTenant bool
preFunc func(env *testEnv)
- want *vtctldatapb.WorkflowSwitchTrafficResponse
- wantErr bool
+ // expectQueries, when set, replaces the default expected queries.
+ expectQueries func(env *testEnv, source, target *testKeyspace)
+ want *vtctldatapb.WorkflowSwitchTrafficResponse
+ wantErr bool
+ // wantCanceled means that the failed switch must have been canceled,
+ // leaving writes on the source.
+ wantCanceled bool
}{
{
name: "basic forward",
@@ -1431,6 +1442,39 @@ func TestMoveTablesTrafficSwitching(t *testing.T) {
CurrentState: "All Reads Switched. Writes Switched",
},
},
+ {
+ name: "forward with an error reading the source positions",
+ sourceKeyspace: &testKeyspace{
+ KeyspaceName: sourceKeyspaceName,
+ ShardNames: []string{"0"},
+ },
+ targetKeyspace: &testKeyspace{
+ KeyspaceName: targetKeyspaceName,
+ ShardNames: []string{"-80", "80-"},
+ },
+ req: &vtctldatapb.WorkflowSwitchTrafficRequest{
+ Keyspace: targetKeyspaceName,
+ Workflow: workflowName,
+ Direction: int32(DirectionForward),
+ TabletTypes: allTabletTypes,
+ },
+ preFunc: func(env *testEnv) {
+ env.tmc.setPrimaryPositionError(env.tablets[sourceKeyspaceName][startingSourceTabletUID], errors.New("position read failed"))
+ },
+ expectQueries: func(env *testEnv, source, target *testKeyspace) {
+ env.tmc.expectVRQueryResultOnKeyspaceTablets(target.KeyspaceName, copyTableQR)
+ for i := 0; i < len(target.ShardNames); i++ { // Per stream
+ env.tmc.expectVRQueryResultOnKeyspaceTablets(source.KeyspaceName, journalQR)
+ }
+ for i := 0; i < len(target.ShardNames); i++ { // Per stream
+ env.tmc.expectVRQueryResultOnKeyspaceTablets(source.KeyspaceName, lockTableQR)
+ }
+ env.tmc.expectVRQueryResultOnKeyspaceTablets(target.KeyspaceName, restartWFQR)
+ env.tmc.expectVRQueryResultOnKeyspaceTablets(source.KeyspaceName, deleteReverseWFQR)
+ },
+ wantErr: true,
+ wantCanceled: true,
+ },
}
for _, tc := range testcases {
@@ -1442,7 +1486,9 @@ func TestMoveTablesTrafficSwitching(t *testing.T) {
defer env.close()
env.tmc.schema = schema
- if tc.req.Direction == int32(DirectionForward) {
+ if tc.expectQueries != nil {
+ tc.expectQueries(env, tc.sourceKeyspace, tc.targetKeyspace)
+ } else if tc.req.Direction == int32(DirectionForward) {
env.tmc.expectVRQueryResultOnKeyspaceTablets(tc.targetKeyspace.KeyspaceName, copyTableQR)
env.tmc.expectVRQueryResultOnKeyspaceTablets(tc.targetKeyspace.KeyspaceName, cutoverQR)
for i := 0; i < len(tc.targetKeyspace.ShardNames); i++ { // Per stream
@@ -1527,6 +1573,22 @@ func TestMoveTablesTrafficSwitching(t *testing.T) {
got, err := env.ws.WorkflowSwitchTraffic(ctx, tc.req)
if tc.wantErr {
require.Error(t, err)
+ if tc.wantCanceled {
+ require.ErrorContains(t, err, "failed to gather replication positions")
+ require.NotContains(t, err.Error(), "cancel migration failed")
+ // Writes are back on the source, and every expected
+ // query, including the cancel's, was run.
+ for _, keyspace := range []*testKeyspace{tc.sourceKeyspace, tc.targetKeyspace} {
+ for _, shardName := range keyspace.ShardNames {
+ si, err := env.ts.GetShard(ctx, keyspace.KeyspaceName, shardName)
+ require.NoError(t, err)
+ require.Equal(t, keyspace == tc.targetKeyspace, hasDeniedTableEntry(si), "denied tables in %s/%s", keyspace.KeyspaceName, shardName)
+ }
+ }
+ for tabletID, queries := range env.tmc.vrQueries {
+ require.Empty(t, queries, "queries not run on tablet %d", tabletID)
+ }
+ }
return
}
require.NoError(t, err)
From 039da855d39fdc7e35a3112e8371c0ef58f8bdad Mon Sep 17 00:00:00 2001
From: "vitess-bot[bot]" <108069721+vitess-bot[bot]@users.noreply.github.com>
Date: Mon, 19 Oct 2026 14:26:39 +0200
Subject: [PATCH 09/31] [release-23.0] ci: compile the e2e tests with the same
flags as make build (#21603) (#21608)
Signed-off-by: Arthur Schreiber
Co-authored-by: vitess-bot[bot] <108069721+vitess-bot[bot]@users.noreply.github.com>
Co-authored-by: Arthur Schreiber
Co-authored-by: Claude Opus 5.5
---
tools/e2e_go_test.sh | 7 ++++++-
1 file changed, 6 insertions(+), 1 deletion(-)
diff --git a/tools/e2e_go_test.sh b/tools/e2e_go_test.sh
index baa77b9ba98..2b35e7c928e 100755
--- a/tools/e2e_go_test.sh
+++ b/tools/e2e_go_test.sh
@@ -23,6 +23,11 @@ if [[ -n "$JUNIT_OUTPUT" ]]; then
GOTESTSUM_ARGS+=("--junitfile" "$JUNIT_OUTPUT")
fi
+# Compile the tests with the same CGO_ENABLED=0 and -trimpath that "make build"
+# uses for the binaries. Both are part of Go's build cache key, so the tests
+# then reuse the packages "make build" already compiled instead of compiling
+# the whole dependency graph a second time.
+#
# The test packages must come before "$@" on the go test command line: "$@"
# can contain test-binary flags such as --topo-flavor or -keep-data, which
# go test only forwards to the test binary when they appear after the package
@@ -33,4 +38,4 @@ fi
# this command; go test applies the -run flag (the last occurrence wins) and
# hands the trailing package string to the test binary, which ignores it.
# shellcheck disable=SC2086
-go tool -modfile=tools/gotestsum/go.mod gotestsum "${GOTESTSUM_ARGS[@]}" --raw-command -- go test -json -v -count=1 $PACKAGES "$@" -args -alsologtostderr
+CGO_ENABLED=0 go tool -modfile=tools/gotestsum/go.mod gotestsum "${GOTESTSUM_ARGS[@]}" --raw-command -- go test -trimpath -json -v -count=1 $PACKAGES "$@" -args -alsologtostderr
From 954855b160d53ad5929ca1ae3338bfb55d69915c Mon Sep 17 00:00:00 2001
From: "vitess-bot[bot]" <108069721+vitess-bot[bot]@users.noreply.github.com>
Date: Mon, 19 Oct 2026 15:11:51 +0200
Subject: [PATCH 10/31] [release-23.0] Refer to flags by their dashed names in
help and error text (#21339) (#21355)
Signed-off-by: Arthur Schreiber
Co-authored-by: vitess-bot[bot] <108069721+vitess-bot[bot]@users.noreply.github.com>
Co-authored-by: Arthur Schreiber
Co-authored-by: Claude Opus 5.5
---
go/cmd/vtbackup/cli/vtbackup.go | 8 ++++----
go/cmd/vtclient/cli/vtclient.go | 2 +-
go/cmd/vtcombo/cli/main.go | 2 +-
.../vtctldclient/command/vreplication/common/cancel.go | 2 +-
go/cmd/vttestserver/cli/main.go | 6 +++---
go/flags/endtoend/mysqlctld.txt | 2 +-
go/flags/endtoend/vtbackup.txt | 4 ++--
go/flags/endtoend/vtbench.txt | 2 +-
go/flags/endtoend/vtclient.txt | 4 ++--
go/flags/endtoend/vtcombo.txt | 6 +++---
go/flags/endtoend/vtctlclient.txt | 2 +-
go/flags/endtoend/vtctld.txt | 2 +-
go/flags/endtoend/vtctldclient.txt | 2 +-
go/flags/endtoend/vtgate.txt | 8 ++++----
go/flags/endtoend/vtgateclienttest.txt | 2 +-
go/flags/endtoend/vtorc.txt | 2 +-
go/flags/endtoend/vttablet.txt | 4 ++--
go/flags/endtoend/vttestserver.txt | 6 +++---
go/mysql/vault/auth_server_vault.go | 10 +++++-----
go/vt/discovery/replicationlag.go | 4 ++--
go/vt/grpcclient/client.go | 2 +-
go/vt/proto/tabletmanagerdata/tabletmanagerdata.pb.go | 2 +-
go/vt/vtgate/buffer/flags.go | 4 ++--
go/vt/vtgate/vstream_manager.go | 2 +-
go/vt/vtgate/vtgate.go | 2 +-
go/vt/vtorc/logic/tablet_discovery.go | 6 +++---
go/vt/vttablet/tabletmanager/rpc_vreplication.go | 4 ++--
go/vt/vttablet/tabletserver/tabletenv/config.go | 4 ++--
proto/tabletmanagerdata.proto | 2 +-
29 files changed, 54 insertions(+), 54 deletions(-)
diff --git a/go/cmd/vtbackup/cli/vtbackup.go b/go/cmd/vtbackup/cli/vtbackup.go
index 8c085e9a83b..3adfe4f52d4 100644
--- a/go/cmd/vtbackup/cli/vtbackup.go
+++ b/go/cmd/vtbackup/cli/vtbackup.go
@@ -203,7 +203,7 @@ func init() {
utils.SetFlagDurationVar(Main.Flags(), &minBackupInterval, "min-backup-interval", minBackupInterval, "Only take a new backup if it's been at least this long since the most recent backup.")
utils.SetFlagDurationVar(Main.Flags(), &minRetentionTime, "min-retention-time", minRetentionTime, "Keep each old backup for at least this long before removing it. Set to 0 to disable pruning of old backups.")
- utils.SetFlagIntVar(Main.Flags(), &minRetentionCount, "min-retention-count", minRetentionCount, "Always keep at least this many of the most recent backups in this backup storage location, even if some are older than the min_retention_time. This must be at least 1 since a backup must always exist to allow new backups to be made")
+ utils.SetFlagIntVar(Main.Flags(), &minRetentionCount, "min-retention-count", minRetentionCount, "Always keep at least this many of the most recent backups in this backup storage location, even if some are older than --min-retention-time. This must be at least 1 since a backup must always exist to allow new backups to be made")
utils.SetFlagBoolVar(Main.Flags(), &initialBackup, "initial-backup", initialBackup, "Instead of restoring from backup, initialize an empty database with the provided init-db-sql-file and upload a backup of that for the shard, if the shard has no backups yet. This can be used to seed a brand new shard with an initial, empty backup. If any backups already exist for the shard, this will be considered a successful no-op. This can only be done before the shard exists in topology (i.e. before any tablets are deployed).")
utils.SetFlagBoolVar(Main.Flags(), &allowFirstBackup, "allow-first-backup", allowFirstBackup, "Allow this job to take the first backup of an existing shard.")
utils.SetFlagBoolVar(Main.Flags(), &restartBeforeBackup, "restart-before-backup", restartBeforeBackup, "Perform a mysqld clean/full restart after applying binlogs, but before taking the backup. Only makes sense to work around xtrabackup bugs.")
@@ -467,7 +467,7 @@ func takeBackup(ctx, backgroundCtx context.Context, topoServer *topo.Server, bac
case mysqlctl.ErrNoBackup:
// There is no backup found, but we may be taking the initial backup of a shard
if !allowFirstBackup {
- return fmt.Errorf("no backup found; not starting up empty since --initial_backup flag was not enabled")
+ return fmt.Errorf("no backup found; not starting up empty since --allow-first-backup flag was not enabled")
}
restorePos = replication.Position{}
default:
@@ -854,14 +854,14 @@ func shouldBackup(ctx context.Context, topoServer *topo.Server, backupStorage ba
// We need at least one backup so we can restore first, unless the user explicitly says we don't
if len(backups) == 0 && !allowFirstBackup {
- return false, fmt.Errorf("no existing backups to restore from; backup is not possible since --initial_backup flag was not enabled")
+ return false, fmt.Errorf("no existing backups to restore from; backup is not possible since --allow-first-backup flag was not enabled")
}
if lastBackup == nil {
if allowFirstBackup {
// There's no complete backup, but we were told to take one from scratch anyway.
return true, nil
}
- return false, fmt.Errorf("no complete backups to restore from; backup is not possible since --initial_backup flag was not enabled")
+ return false, fmt.Errorf("no complete backups to restore from; backup is not possible since --allow-first-backup flag was not enabled")
}
// Has it been long enough since the last complete backup to need a new one?
diff --git a/go/cmd/vtclient/cli/vtclient.go b/go/cmd/vtclient/cli/vtclient.go
index 7f4590d127a..e2d80879675 100644
--- a/go/cmd/vtclient/cli/vtclient.go
+++ b/go/cmd/vtclient/cli/vtclient.go
@@ -73,7 +73,7 @@ For query bound variables, we assume place-holders in the query string
in the form of :v1, :v2, etc.`,
Example: `vtclient --server vtgate:15991 "SELECT * FROM messages"
-vtclient --server vtgate:15991 --target '@primary' --bind_variables '[ 12345, 1, "msg 12345" ]' "INSERT INTO messages (page,time_created_ns,message) VALUES (:v1, :v2, :v3)"`,
+vtclient --server vtgate:15991 --target '@primary' --bind-variables '[ 12345, 1, "msg 12345" ]' "INSERT INTO messages (page,time_created_ns,message) VALUES (:v1, :v2, :v3)"`,
Args: cobra.ExactArgs(1),
Version: servenv.AppVersion.String(),
RunE: run,
diff --git a/go/cmd/vtcombo/cli/main.go b/go/cmd/vtcombo/cli/main.go
index d2b2dd62df8..0425449c722 100644
--- a/go/cmd/vtcombo/cli/main.go
+++ b/go/cmd/vtcombo/cli/main.go
@@ -116,7 +116,7 @@ func init() {
Main.Flags().StringVar(&vschemaPersistenceDir, "vschema-persistence-dir", vschemaPersistenceDir, "If set, per-keyspace vschema will be persisted in this directory "+
"and reloaded into the in-memory topology server across restarts. Bookkeeping is performed using a simple watcher goroutine. "+
"This is useful when running vtcombo as an application development container (e.g. vttestserver) where you want to keep the same "+
- "vschema even if developer's machine reboots. This works in tandem with vttestserver's --persistent_mode flag. Needless to say, "+
+ "vschema even if developer's machine reboots. This works in tandem with vttestserver's --persistent-mode flag. Needless to say, "+
"this is neither a perfect nor a production solution for vschema persistence. Consider using the --external-topo-server flag if "+
"you require a more complete solution. This flag is ignored if --external-topo-server is set.")
diff --git a/go/cmd/vtctldclient/command/vreplication/common/cancel.go b/go/cmd/vtctldclient/command/vreplication/common/cancel.go
index 756aee968bc..245b2704955 100644
--- a/go/cmd/vtctldclient/command/vreplication/common/cancel.go
+++ b/go/cmd/vtctldclient/command/vreplication/common/cancel.go
@@ -70,7 +70,7 @@ func commandCancel(cmd *cobra.Command, args []string) error {
resp, err := GetClient().WorkflowDelete(GetCommandCtx(), req)
if err != nil {
if grpcerr, ok := status.FromError(err); ok && (grpcerr.Code() == codes.DeadlineExceeded) {
- return fmt.Errorf("Cancel action timed out. Please try again and the work will pick back up where it left off. Note that you can control the timeout using the --action_timeout flag and the delete batch size with --delete-batch-size.")
+ return fmt.Errorf("Cancel action timed out. Please try again and the work will pick back up where it left off. Note that you can control the timeout using the --action-timeout flag and the delete batch size with --delete-batch-size.")
}
return err
}
diff --git a/go/cmd/vttestserver/cli/main.go b/go/cmd/vttestserver/cli/main.go
index 7732cb5a011..0b68c6f48b7 100644
--- a/go/cmd/vttestserver/cli/main.go
+++ b/go/cmd/vttestserver/cli/main.go
@@ -150,12 +150,12 @@ func New() (cmd *cobra.Command) {
" random data (--initialize-with-random-data option) will only run during"+
" cluster startup if the data directory does not already exist. "+
" Changes to VSchema are persisted across cluster restarts using a simple"+
- " watcher if the --data_dir argument is specified.")
+ " watcher if the --data-dir argument is specified.")
utils.SetFlagBoolVar(cmd.Flags(), &doSeed, "initialize-with-random-data", false,
"If this flag is each table-shard will be initialized"+
- " with random data. See also the 'rng_seed' and 'min_shard_size'"+
- " and 'max_shard_size' flags.")
+ " with random data. See also the --rng-seed, --min-table-shard-size"+
+ " and --max-table-shard-size flags.")
utils.SetFlagIntVar(cmd.Flags(), &seed.RngSeed, "rng-seed", 123,
"The random number generator seed to use when initializing"+
diff --git a/go/flags/endtoend/mysqlctld.txt b/go/flags/endtoend/mysqlctld.txt
index 61a4e850b1f..90865dccc13 100644
--- a/go/flags/endtoend/mysqlctld.txt
+++ b/go/flags/endtoend/mysqlctld.txt
@@ -63,7 +63,7 @@ Flags:
--dba-pool-size int Size of the connection pool for dba connections (default 20)
--grpc-auth-mode string Which auth plugin implementation to use (eg: static)
--grpc-auth-mtls-allowed-substrings string List of substrings of at least one of the client certificate names (separated by colon).
- --grpc-auth-static-client-creds string When using grpc_static_auth in the server, this file provides the credentials to use to authenticate with server.
+ --grpc-auth-static-client-creds string When using --grpc-auth-mode=static in the server, this file provides the credentials to use to authenticate with server.
--grpc-auth-static-password-file string JSON File to read the users/passwords from.
--grpc-bind-address string Bind address for gRPC calls. If empty, listen on all addresses.
--grpc-ca string server CA to use for gRPC connections, requires TLS, and enforces client certificate check
diff --git a/go/flags/endtoend/vtbackup.txt b/go/flags/endtoend/vtbackup.txt
index 552bf059042..b7a477fdf05 100644
--- a/go/flags/endtoend/vtbackup.txt
+++ b/go/flags/endtoend/vtbackup.txt
@@ -135,7 +135,7 @@ Flags:
--file-backup-storage-root string Root directory for the file backup storage.
--gcs-backup-storage-bucket string Google Cloud Storage bucket to use for backups.
--gcs-backup-storage-root string Root prefix for all backup-related object names.
- --grpc-auth-static-client-creds string When using grpc_static_auth in the server, this file provides the credentials to use to authenticate with server.
+ --grpc-auth-static-client-creds string When using --grpc-auth-mode=static in the server, this file provides the credentials to use to authenticate with server.
--grpc-compression string Which protocol to use for compressing gRPC. Default: nothing. Supported: snappy
--grpc-dial-concurrency-limit int Maximum concurrency of grpc dial operations. This should be less than the golang max thread limit of 10000. (default 1024)
--grpc-enable-tracing Enable gRPC tracing.
@@ -163,7 +163,7 @@ Flags:
--logtostderr log to standard error instead of files
--manifest-external-decompressor string command with arguments to store in the backup manifest when compressing a backup with an external compression engine.
--min-backup-interval duration Only take a new backup if it's been at least this long since the most recent backup.
- --min-retention-count int Always keep at least this many of the most recent backups in this backup storage location, even if some are older than the min_retention_time. This must be at least 1 since a backup must always exist to allow new backups to be made (default 1)
+ --min-retention-count int Always keep at least this many of the most recent backups in this backup storage location, even if some are older than --min-retention-time. This must be at least 1 since a backup must always exist to allow new backups to be made (default 1)
--min-retention-time duration Keep each old backup for at least this long before removing it. Set to 0 to disable pruning of old backups.
--mycnf-bin-log-path string mysql binlog path
--mycnf-data-dir string data directory for mysql
diff --git a/go/flags/endtoend/vtbench.txt b/go/flags/endtoend/vtbench.txt
index f1449e468e1..c498da24024 100644
--- a/go/flags/endtoend/vtbench.txt
+++ b/go/flags/endtoend/vtbench.txt
@@ -62,7 +62,7 @@ Flags:
--db-credentials-vault-tokenfile string Path to file containing Vault auth token; token can also be passed using VAULT_TOKEN environment variable
--db-credentials-vault-ttl duration How long to cache DB credentials from the Vault server (default 30m0s)
--deadline duration Maximum duration for the test run (default 5 minutes) (default 5m0s)
- --grpc-auth-static-client-creds string When using grpc_static_auth in the server, this file provides the credentials to use to authenticate with server.
+ --grpc-auth-static-client-creds string When using --grpc-auth-mode=static in the server, this file provides the credentials to use to authenticate with server.
--grpc-compression string Which protocol to use for compressing gRPC. Default: nothing. Supported: snappy
--grpc-dial-concurrency-limit int Maximum concurrency of grpc dial operations. This should be less than the golang max thread limit of 10000. (default 1024)
--grpc-enable-tracing Enable gRPC tracing.
diff --git a/go/flags/endtoend/vtclient.txt b/go/flags/endtoend/vtclient.txt
index b79139b1aad..c696c58a76c 100644
--- a/go/flags/endtoend/vtclient.txt
+++ b/go/flags/endtoend/vtclient.txt
@@ -9,7 +9,7 @@ Usage:
Examples:
vtclient --server vtgate:15991 "SELECT * FROM messages"
-vtclient --server vtgate:15991 --target '@primary' --bind_variables '[ 12345, 1, "msg 12345" ]' "INSERT INTO messages (page,time_created_ns,message) VALUES (:v1, :v2, :v3)"
+vtclient --server vtgate:15991 --target '@primary' --bind-variables '[ 12345, 1, "msg 12345" ]' "INSERT INTO messages (page,time_created_ns,message) VALUES (:v1, :v2, :v3)"
Flags:
--alsologtostderr log to standard error as well as files
@@ -24,7 +24,7 @@ Flags:
--datadog-agent-host string host to send spans to. if empty, no tracing will be done
--datadog-agent-port string port to send spans to. if empty, no tracing will be done
--datadog-trace-debug-mode enable debug mode for datadog tracing
- --grpc-auth-static-client-creds string When using grpc_static_auth in the server, this file provides the credentials to use to authenticate with server.
+ --grpc-auth-static-client-creds string When using --grpc-auth-mode=static in the server, this file provides the credentials to use to authenticate with server.
--grpc-compression string Which protocol to use for compressing gRPC. Default: nothing. Supported: snappy
--grpc-dial-concurrency-limit int Maximum concurrency of grpc dial operations. This should be less than the golang max thread limit of 10000. (default 1024)
--grpc-enable-tracing Enable gRPC tracing.
diff --git a/go/flags/endtoend/vtcombo.txt b/go/flags/endtoend/vtcombo.txt
index 0b87393fd4f..80dad918a6f 100644
--- a/go/flags/endtoend/vtcombo.txt
+++ b/go/flags/endtoend/vtcombo.txt
@@ -23,7 +23,7 @@ Flags:
--binlog-in-memory-decompressor-max-size uint This value sets the uncompressed transaction payload size at which we switch from in-memory buffer based decompression to the slower streaming mode. (default 134217728)
--binlog-player-protocol string the protocol to download binlogs from a vttablet (default "grpc")
--buffer-drain-concurrency int Maximum number of requests retried simultaneously. More concurrency will increase the load on the PRIMARY vttablet when draining the buffer. (default 1)
- --buffer-keyspace-shards string If not empty, limit buffering to these entries (comma separated). Entry format: keyspace or keyspace/shard. Requires --enable_buffer=true.
+ --buffer-keyspace-shards string If not empty, limit buffering to these entries (comma separated). Entry format: keyspace or keyspace/shard. Requires --enable-buffer=true.
--buffer-max-failover-duration duration Stop buffering completely if a failover takes longer than this duration. (default 20s)
--buffer-min-time-between-failovers duration Minimum time between the end of a failover and the start of the next one (tracked per shard). Faster consecutive failovers will not trigger buffering. (default 1m0s)
--buffer-size int Maximum number of buffered requests in flight (across all ongoing failovers). (default 1000)
@@ -389,7 +389,7 @@ Flags:
--transaction-limit-by-principal Include CallerID.principal when considering who the user is for the purpose of transaction limit. (default true)
--transaction-limit-by-subcomponent Include CallerID.subcomponent when considering who the user is for the purpose of transaction limit.
--transaction-limit-by-username Include VTGateCallerID.username when considering who the user is for the purpose of transaction limit. (default true)
- --transaction-limit-per-user float Maximum number of transactions a single user is allowed to use at any time, represented as fraction of -transaction_cap. (default 0.4)
+ --transaction-limit-per-user float Maximum number of transactions a single user is allowed to use at any time, represented as fraction of --queryserver-config-transaction-cap. (default 0.4)
--transaction-log-stream-handler string URL handler for streaming transactions log (default "/debug/txlog")
--transaction-mode string SINGLE: disallow multi-db transactions, MULTI: allow multi-db transactions with best effort commit, TWOPC: allow multi-db transactions with 2pc commit (default "MULTI")
--truncate-error-len int truncate errors sent to client if they are longer than this value (0 means do not truncate)
@@ -418,7 +418,7 @@ Flags:
--vreplication-retry-delay duration delay before retrying a failed workflow event in the replication phase (default 5s)
--vreplication-store-compressed-gtid Store compressed gtids in the pos column of the sidecar database's vreplication table
--vschema-ddl-authorized-users string List of users authorized to execute vschema ddl operations, or '%' to allow all users.
- --vschema-persistence-dir string If set, per-keyspace vschema will be persisted in this directory and reloaded into the in-memory topology server across restarts. Bookkeeping is performed using a simple watcher goroutine. This is useful when running vtcombo as an application development container (e.g. vttestserver) where you want to keep the same vschema even if developer's machine reboots. This works in tandem with vttestserver's --persistent_mode flag. Needless to say, this is neither a perfect nor a production solution for vschema persistence. Consider using the --external-topo-server flag if you require a more complete solution. This flag is ignored if --external-topo-server is set.
+ --vschema-persistence-dir string If set, per-keyspace vschema will be persisted in this directory and reloaded into the in-memory topology server across restarts. Bookkeeping is performed using a simple watcher goroutine. This is useful when running vtcombo as an application development container (e.g. vttestserver) where you want to keep the same vschema even if developer's machine reboots. This works in tandem with vttestserver's --persistent-mode flag. Needless to say, this is neither a perfect nor a production solution for vschema persistence. Consider using the --external-topo-server flag if you require a more complete solution. This flag is ignored if --external-topo-server is set.
--vstream-binlog-rotation-threshold int Byte size at which a VStreamer will attempt to rotate the source's open binary log before starting a GTID snapshot based stream (e.g. a ResultStreamer or RowStreamer) (default 67108864)
--vstream-dynamic-packet-size Enable dynamic packet sizing for vstreamers. This will adjust the packet size in vreplication workflows to improve performance. (default true)
--vstream-packet-size int Suggested packet size for vstreamers. The actual packet size may be more or less than this amount. (default 250000)
diff --git a/go/flags/endtoend/vtctlclient.txt b/go/flags/endtoend/vtctlclient.txt
index ac6b76fcf42..eb78315b777 100644
--- a/go/flags/endtoend/vtctlclient.txt
+++ b/go/flags/endtoend/vtctlclient.txt
@@ -10,7 +10,7 @@ Usage of vtctlclient:
--datadog-agent-host string host to send spans to. if empty, no tracing will be done
--datadog-agent-port string port to send spans to. if empty, no tracing will be done
--datadog-trace-debug-mode enable debug mode for datadog tracing
- --grpc-auth-static-client-creds string When using grpc_static_auth in the server, this file provides the credentials to use to authenticate with server.
+ --grpc-auth-static-client-creds string When using --grpc-auth-mode=static in the server, this file provides the credentials to use to authenticate with server.
--grpc-compression string Which protocol to use for compressing gRPC. Default: nothing. Supported: snappy
--grpc-dial-concurrency-limit int Maximum concurrency of grpc dial operations. This should be less than the golang max thread limit of 10000. (default 1024)
--grpc-enable-tracing Enable gRPC tracing.
diff --git a/go/flags/endtoend/vtctld.txt b/go/flags/endtoend/vtctld.txt
index b591b78a79f..830f2e24a6c 100644
--- a/go/flags/endtoend/vtctld.txt
+++ b/go/flags/endtoend/vtctld.txt
@@ -58,7 +58,7 @@ Flags:
--gcs-backup-storage-root string Root prefix for all backup-related object names.
--grpc-auth-mode string Which auth plugin implementation to use (eg: static)
--grpc-auth-mtls-allowed-substrings string List of substrings of at least one of the client certificate names (separated by colon).
- --grpc-auth-static-client-creds string When using grpc_static_auth in the server, this file provides the credentials to use to authenticate with server.
+ --grpc-auth-static-client-creds string When using --grpc-auth-mode=static in the server, this file provides the credentials to use to authenticate with server.
--grpc-auth-static-password-file string JSON File to read the users/passwords from.
--grpc-bind-address string Bind address for gRPC calls. If empty, listen on all addresses.
--grpc-ca string server CA to use for gRPC connections, requires TLS, and enforces client certificate check
diff --git a/go/flags/endtoend/vtctldclient.txt b/go/flags/endtoend/vtctldclient.txt
index 97214868b41..f7cc1502f10 100644
--- a/go/flags/endtoend/vtctldclient.txt
+++ b/go/flags/endtoend/vtctldclient.txt
@@ -122,7 +122,7 @@ Flags:
--action-timeout duration timeout to use for the command (default 1h0m0s)
--alsologtostderr log to standard error as well as files
--compact use compact format for otherwise verbose outputs
- --grpc-auth-static-client-creds string When using grpc_static_auth in the server, this file provides the credentials to use to authenticate with server.
+ --grpc-auth-static-client-creds string When using --grpc-auth-mode=static in the server, this file provides the credentials to use to authenticate with server.
--grpc-compression string Which protocol to use for compressing gRPC. Default: nothing. Supported: snappy
--grpc-enable-tracing Enable gRPC tracing.
--grpc-initial-conn-window-size int gRPC initial connection window size
diff --git a/go/flags/endtoend/vtgate.txt b/go/flags/endtoend/vtgate.txt
index 56185cb6fad..581b3237c67 100644
--- a/go/flags/endtoend/vtgate.txt
+++ b/go/flags/endtoend/vtgate.txt
@@ -32,7 +32,7 @@ Flags:
--balancer-vtgate-cells strings When in balanced mode, a comma-separated list of cells that contain vtgates (required)
--bind-address string Bind address for the server. If empty, the server will listen on all available unicast and anycast IP addresses of the local system.
--buffer-drain-concurrency int Maximum number of requests retried simultaneously. More concurrency will increase the load on the PRIMARY vttablet when draining the buffer. (default 1)
- --buffer-keyspace-shards string If not empty, limit buffering to these entries (comma separated). Entry format: keyspace or keyspace/shard. Requires --enable_buffer=true.
+ --buffer-keyspace-shards string If not empty, limit buffering to these entries (comma separated). Entry format: keyspace or keyspace/shard. Requires --enable-buffer=true.
--buffer-max-failover-duration duration Stop buffering completely if a failover takes longer than this duration. (default 20s)
--buffer-min-time-between-failovers duration Minimum time between the end of a failover and the start of the next one (tracked per shard). Faster consecutive failovers will not trigger buffering. (default 1m0s)
--buffer-size int Maximum number of buffered requests in flight (across all ongoing failovers). (default 1000)
@@ -53,7 +53,7 @@ Flags:
--dbddl-plugin string controls how to handle CREATE/DROP DATABASE. use it if you are using your own database provisioning service (default "fail")
--ddl-strategy string Set default strategy for DDL statements. Override with @@ddl_strategy session variable (default "direct")
--default-tablet-type topodatapb.TabletType The default tablet type to set for queries, when one is not explicitly selected. (default PRIMARY)
- --discovery-high-replication-lag-minimum-serving duration Threshold above which replication lag is considered too high when applying the min_number_serving_vttablets flag. (default 2h0m0s)
+ --discovery-high-replication-lag-minimum-serving duration Threshold above which replication lag is considered too high when applying the --min-number-serving-vttablets flag. (default 2h0m0s)
--discovery-low-replication-lag duration Threshold below which replication lag is considered low enough to be healthy. (default 30s)
--emit-stats If set, emit stats to push-based monitoring and stats backends
--enable-balancer Enable the tablet balancer to evenly spread query load for a given tablet type
@@ -70,7 +70,7 @@ Flags:
--gateway-initial-tablet-timeout duration At startup, the tabletGateway will wait up to this duration to get at least one tablet per keyspace/shard/tablet type (default 30s)
--grpc-auth-mode string Which auth plugin implementation to use (eg: static)
--grpc-auth-mtls-allowed-substrings string List of substrings of at least one of the client certificate names (separated by colon).
- --grpc-auth-static-client-creds string When using grpc_static_auth in the server, this file provides the credentials to use to authenticate with server.
+ --grpc-auth-static-client-creds string When using --grpc-auth-mode=static in the server, this file provides the credentials to use to authenticate with server.
--grpc-auth-static-password-file string JSON File to read the users/passwords from.
--grpc-bind-address string Bind address for gRPC calls. If empty, listen on all addresses.
--grpc-ca string server CA to use for gRPC connections, requires TLS, and enforces client certificate check
@@ -122,7 +122,7 @@ Flags:
--max-payload-size int The threshold for query payloads in bytes. A payload greater than this threshold will result in a failure to handle the query.
--max-stack-size int configure the maximum stack size in bytes (default 67108864)
--message-stream-grace-period duration the amount of time to give for a vttablet to resume if it ends a message stream, usually because of a reparent. (default 30s)
- --min-number-serving-vttablets int The minimum number of vttablets for each replicating tablet_type (e.g. replica, rdonly) that will be continue to be used even with replication lag above discovery_low_replication_lag, but still below discovery_high_replication_lag_minimum_serving. (default 2)
+ --min-number-serving-vttablets int The minimum number of vttablets for each replicating tablet_type (e.g. replica, rdonly) that will be continue to be used even with replication lag above --discovery-low-replication-lag, but still below --discovery-high-replication-lag-minimum-serving. (default 2)
--mysql-allow-clear-text-without-tls If set, the server will allow the use of a clear text password over non-SSL connections.
--mysql-auth-server-impl string Which auth server implementation to use. Options: none, ldap, clientcert, static, vault. (default "static")
--mysql-auth-server-static-file string JSON File to read the users/passwords from.
diff --git a/go/flags/endtoend/vtgateclienttest.txt b/go/flags/endtoend/vtgateclienttest.txt
index ec9a2a3347a..0f56ab5e796 100644
--- a/go/flags/endtoend/vtgateclienttest.txt
+++ b/go/flags/endtoend/vtgateclienttest.txt
@@ -16,7 +16,7 @@ Flags:
--default-tablet-type topodatapb.TabletType The default tablet type to set for queries, when one is not explicitly selected. (default PRIMARY)
--grpc-auth-mode string Which auth plugin implementation to use (eg: static)
--grpc-auth-mtls-allowed-substrings string List of substrings of at least one of the client certificate names (separated by colon).
- --grpc-auth-static-client-creds string When using grpc_static_auth in the server, this file provides the credentials to use to authenticate with server.
+ --grpc-auth-static-client-creds string When using --grpc-auth-mode=static in the server, this file provides the credentials to use to authenticate with server.
--grpc-auth-static-password-file string JSON File to read the users/passwords from.
--grpc-bind-address string Bind address for gRPC calls. If empty, listen on all addresses.
--grpc-ca string server CA to use for gRPC connections, requires TLS, and enforces client certificate check
diff --git a/go/flags/endtoend/vtorc.txt b/go/flags/endtoend/vtorc.txt
index 18a1d89ec80..91c5ec4d22c 100644
--- a/go/flags/endtoend/vtorc.txt
+++ b/go/flags/endtoend/vtorc.txt
@@ -38,7 +38,7 @@ Flags:
--discovery-workers int Number of workers used for tablet discovery (default 300)
--emit-stats If set, emit stats to push-based monitoring and stats backends
--enable-primary-disk-stalled-recovery Whether VTOrc should detect a stalled disk on the primary and failover
- --grpc-auth-static-client-creds string When using grpc_static_auth in the server, this file provides the credentials to use to authenticate with server.
+ --grpc-auth-static-client-creds string When using --grpc-auth-mode=static in the server, this file provides the credentials to use to authenticate with server.
--grpc-compression string Which protocol to use for compressing gRPC. Default: nothing. Supported: snappy
--grpc-dial-concurrency-limit int Maximum concurrency of grpc dial operations. This should be less than the golang max thread limit of 10000. (default 1024)
--grpc-enable-tracing Enable gRPC tracing.
diff --git a/go/flags/endtoend/vttablet.txt b/go/flags/endtoend/vttablet.txt
index 0047c81eddc..35000362539 100644
--- a/go/flags/endtoend/vttablet.txt
+++ b/go/flags/endtoend/vttablet.txt
@@ -163,7 +163,7 @@ Flags:
--gcs-backup-storage-root string Root prefix for all backup-related object names.
--grpc-auth-mode string Which auth plugin implementation to use (eg: static)
--grpc-auth-mtls-allowed-substrings string List of substrings of at least one of the client certificate names (separated by colon).
- --grpc-auth-static-client-creds string When using grpc_static_auth in the server, this file provides the credentials to use to authenticate with server.
+ --grpc-auth-static-client-creds string When using --grpc-auth-mode=static in the server, this file provides the credentials to use to authenticate with server.
--grpc-auth-static-password-file string JSON File to read the users/passwords from.
--grpc-bind-address string Bind address for gRPC calls. If empty, listen on all addresses.
--grpc-ca string server CA to use for gRPC connections, requires TLS, and enforces client certificate check
@@ -397,7 +397,7 @@ Flags:
--transaction-limit-by-principal Include CallerID.principal when considering who the user is for the purpose of transaction limit. (default true)
--transaction-limit-by-subcomponent Include CallerID.subcomponent when considering who the user is for the purpose of transaction limit.
--transaction-limit-by-username Include VTGateCallerID.username when considering who the user is for the purpose of transaction limit. (default true)
- --transaction-limit-per-user float Maximum number of transactions a single user is allowed to use at any time, represented as fraction of -transaction_cap. (default 0.4)
+ --transaction-limit-per-user float Maximum number of transactions a single user is allowed to use at any time, represented as fraction of --queryserver-config-transaction-cap. (default 0.4)
--transaction-log-stream-handler string URL handler for streaming transactions log (default "/debug/txlog")
--twopc-abandon-age time.Duration Any unresolved transaction older than this time will be sent to the coordinator to be resolved. NOTE: Providing time as seconds (float64) is deprecated. Use time.Duration format (e.g., '1s', '2m', '1h'). (default 15m0s)
--tx-throttler-config string The configuration of the transaction throttler as a text-formatted throttlerdata.Configuration protocol buffer message. (default "target_replication_lag_sec:2 max_replication_lag_sec:10 initial_rate:100 max_increase:1 emergency_decrease:0.5 min_duration_between_increases_sec:40 max_duration_between_increases_sec:62 min_duration_between_decreases_sec:20 spread_backlog_across_sec:20 age_bad_rate_after_sec:180 bad_rate_increase:0.1 max_rate_approach_threshold:0.9")
diff --git a/go/flags/endtoend/vttestserver.txt b/go/flags/endtoend/vttestserver.txt
index 76907be34c0..e2e0303a558 100644
--- a/go/flags/endtoend/vttestserver.txt
+++ b/go/flags/endtoend/vttestserver.txt
@@ -46,7 +46,7 @@ Flags:
--foreign-key-mode string This is to provide how to handle foreign key constraint in create/alter table. Valid values are: allow, disallow (default "allow")
--grpc-auth-mode string Which auth plugin implementation to use (eg: static)
--grpc-auth-mtls-allowed-substrings string List of substrings of at least one of the client certificate names (separated by colon).
- --grpc-auth-static-client-creds string When using grpc_static_auth in the server, this file provides the credentials to use to authenticate with server.
+ --grpc-auth-static-client-creds string When using --grpc-auth-mode=static in the server, this file provides the credentials to use to authenticate with server.
--grpc-auth-static-password-file string JSON File to read the users/passwords from.
--grpc-bind-address string Bind address for gRPC calls. If empty, listen on all addresses.
--grpc-ca string server CA to use for gRPC connections, requires TLS, and enforces client certificate check
@@ -75,7 +75,7 @@ Flags:
--grpc-server-keepalive-time duration After a duration of this time, if the server doesn't see any activity, it pings the client to see if the transport is still alive. (default 10s)
--grpc-server-keepalive-timeout duration After having pinged for keepalive check, the server waits for a duration of Timeout and if no activity is seen even after that the connection is closed. (default 10s)
-h, --help help for vttestserver
- --initialize-with-random-data If this flag is each table-shard will be initialized with random data. See also the 'rng_seed' and 'min_shard_size' and 'max_shard_size' flags.
+ --initialize-with-random-data If this flag is each table-shard will be initialized with random data. See also the --rng-seed, --min-table-shard-size and --max-table-shard-size flags.
--initialize-with-vt-dba-tcp If this flag is enabled, MySQL will be initialized with an additional user named vt_dba_tcp, who will have access via TCP/IP connection.
--keep-logs duration keep logs for this long (using ctime) (zero to keep forever)
--keep-logs-by-mtime duration keep logs for this long (using mtime) (zero to keep forever)
@@ -106,7 +106,7 @@ Flags:
--num-shards strings Comma separated shard count (one per keyspace) (default [2])
--onclose-timeout duration wait no more than this for OnClose handlers before stopping (default 10s)
--onterm-timeout duration wait no more than this for OnTermSync handlers before stopping (default 10s)
- --persistent-mode If this flag is set, the MySQL data directory is not cleaned up when LocalCluster.TearDown() is called. This is useful for running vttestserver as a database container in local developer environments. Note that db migration files (--schema-dir option) and seeding of random data (--initialize-with-random-data option) will only run during cluster startup if the data directory does not already exist. Changes to VSchema are persisted across cluster restarts using a simple watcher if the --data_dir argument is specified.
+ --persistent-mode If this flag is set, the MySQL data directory is not cleaned up when LocalCluster.TearDown() is called. This is useful for running vttestserver as a database container in local developer environments. Note that db migration files (--schema-dir option) and seeding of random data (--initialize-with-random-data option) will only run during cluster startup if the data directory does not already exist. Changes to VSchema are persisted across cluster restarts using a simple watcher if the --data-dir argument is specified.
--pid-file string If set, the process will write its pid to the named file, and delete it on graceful shutdown.
--planner-version string Sets the default planner to use when the session has not changed it. Valid values are: Gen4, Gen4Greedy, Gen4Left2Right
--pool-hostname-resolve-interval duration if set force an update to all hostnames and reconnect if changed, defaults to 0 (disabled)
diff --git a/go/mysql/vault/auth_server_vault.go b/go/mysql/vault/auth_server_vault.go
index 3a6df3b6ca4..5f959a1764c 100644
--- a/go/mysql/vault/auth_server_vault.go
+++ b/go/mysql/vault/auth_server_vault.go
@@ -39,7 +39,7 @@ type AuthServerVault struct {
methods []mysql.AuthMethod
mu sync.Mutex
// users, passwords and user data
- // We use the same JSON format as for --mysql_auth_server_static
+ // We use the same JSON format as for --mysql-auth-server-static-file
// Acts as a cache for the in-Vault data
entries map[string][]*mysql.AuthServerStaticEntry
vaultCacheExpireTicker *time.Ticker
@@ -54,11 +54,11 @@ type AuthServerVault struct {
func InitAuthServerVault(vaultAddr string, vaultTimeout time.Duration, vaultCACert, vaultPath string, vaultCacheTTL time.Duration, vaultTokenFile, vaultRoleID, vaultRoleSecretIDFile, vaultRoleMountPoint string) {
// Check critical parameters.
if vaultAddr == "" {
- log.Infof("Not configuring AuthServerVault, as --mysql_auth_vault_addr is empty.")
+ log.Infof("Not configuring AuthServerVault, as --mysql-auth-vault-addr is empty.")
return
}
if vaultPath == "" {
- log.Exitf("If using Vault auth server, --mysql_auth_vault_path is required.")
+ log.Exitf("If using Vault auth server, --mysql-auth-vault-path is required.")
}
registerAuthServerVault(vaultAddr, vaultTimeout, vaultCACert, vaultPath, vaultCacheTTL, vaultTokenFile, vaultRoleID, vaultRoleSecretIDFile, vaultRoleMountPoint)
@@ -76,11 +76,11 @@ func newAuthServerVault(addr string, timeout time.Duration, caCertPath string, p
// Validate more parameters
token, err := readFromFile(tokenFilePath)
if err != nil {
- return nil, fmt.Errorf("No Vault token in provided filename for --mysql_auth_vault_tokenfile")
+ return nil, fmt.Errorf("No Vault token in provided filename for --mysql-auth-vault-tokenfile")
}
secretID, err := readFromFile(secretIDPath)
if err != nil {
- return nil, fmt.Errorf("No Vault secret_id in provided filename for --mysql_auth_vault_role_secretidfile")
+ return nil, fmt.Errorf("No Vault secret_id in provided filename for --mysql-auth-vault-role-secretidfile")
}
config := vaultapi.NewConfig()
diff --git a/go/vt/discovery/replicationlag.go b/go/vt/discovery/replicationlag.go
index f9475ccddfc..c0ce31d13c7 100644
--- a/go/vt/discovery/replicationlag.go
+++ b/go/vt/discovery/replicationlag.go
@@ -68,8 +68,8 @@ func init() {
func registerReplicationFlags(fs *pflag.FlagSet) {
fs.Duration("discovery-low-replication-lag", lowReplicationLag.Default(), "Threshold below which replication lag is considered low enough to be healthy.")
- fs.Duration("discovery-high-replication-lag-minimum-serving", highReplicationLagMinServing.Default(), "Threshold above which replication lag is considered too high when applying the min_number_serving_vttablets flag.")
- fs.Int("min-number-serving-vttablets", minNumTablets.Default(), "The minimum number of vttablets for each replicating tablet_type (e.g. replica, rdonly) that will be continue to be used even with replication lag above discovery_low_replication_lag, but still below discovery_high_replication_lag_minimum_serving.")
+ fs.Duration("discovery-high-replication-lag-minimum-serving", highReplicationLagMinServing.Default(), "Threshold above which replication lag is considered too high when applying the --min-number-serving-vttablets flag.")
+ fs.Int("min-number-serving-vttablets", minNumTablets.Default(), "The minimum number of vttablets for each replicating tablet_type (e.g. replica, rdonly) that will be continue to be used even with replication lag above --discovery-low-replication-lag, but still below --discovery-high-replication-lag-minimum-serving.")
fs.Bool("legacy-replication-lag-algorithm", legacyReplicationLagAlgorithm.Default(), "Use the legacy algorithm when selecting vttablets for serving.")
viperutil.BindFlags(fs,
diff --git a/go/vt/grpcclient/client.go b/go/vt/grpcclient/client.go
index ffab53a17a8..71b5d33a3b8 100644
--- a/go/vt/grpcclient/client.go
+++ b/go/vt/grpcclient/client.go
@@ -79,7 +79,7 @@ func RegisterFlags(fs *pflag.FlagSet) {
utils.SetFlagIntVar(fs, &initialWindowSize, "grpc-initial-window-size", initialWindowSize, "gRPC initial window size")
utils.SetFlagStringVar(fs, &compression, "grpc-compression", compression, "Which protocol to use for compressing gRPC. Default: nothing. Supported: snappy")
- utils.SetFlagStringVar(fs, &credsFile, "grpc-auth-static-client-creds", credsFile, "When using grpc_static_auth in the server, this file provides the credentials to use to authenticate with server.")
+ utils.SetFlagStringVar(fs, &credsFile, "grpc-auth-static-client-creds", credsFile, "When using --grpc-auth-mode=static in the server, this file provides the credentials to use to authenticate with server.")
}
func RegisterDialConcurrencyFlags(fs *pflag.FlagSet) {
diff --git a/go/vt/proto/tabletmanagerdata/tabletmanagerdata.pb.go b/go/vt/proto/tabletmanagerdata/tabletmanagerdata.pb.go
index 849e8c7aade..30e07f35e37 100644
--- a/go/vt/proto/tabletmanagerdata/tabletmanagerdata.pb.go
+++ b/go/vt/proto/tabletmanagerdata/tabletmanagerdata.pb.go
@@ -6267,7 +6267,7 @@ func (*ValidateVReplicationPermissionsRequest) Descriptor() ([]byte, []int) {
type ValidateVReplicationPermissionsResponse struct {
state protoimpl.MessageState `protogen:"open.v1"`
- // The --db_filtered_user on the tablet.
+ // The --db-filtered-user on the tablet.
User string `protobuf:"bytes,1,opt,name=user,proto3" json:"user,omitempty"`
// Does the user have the minimum privileges needed to manage
// vreplication metadata.
diff --git a/go/vt/vtgate/buffer/flags.go b/go/vt/vtgate/buffer/flags.go
index 9290132f411..d5dcafacd0c 100644
--- a/go/vt/vtgate/buffer/flags.go
+++ b/go/vt/vtgate/buffer/flags.go
@@ -53,7 +53,7 @@ func registerFlags(fs *pflag.FlagSet) {
utils.SetFlagDurationVar(fs, &bufferMinTimeBetweenFailovers, "buffer-min-time-between-failovers", 1*time.Minute, "Minimum time between the end of a failover and the start of the next one (tracked per shard). Faster consecutive failovers will not trigger buffering.")
utils.SetFlagIntVar(fs, &bufferDrainConcurrency, "buffer-drain-concurrency", 1, "Maximum number of requests retried simultaneously. More concurrency will increase the load on the PRIMARY vttablet when draining the buffer.")
- utils.SetFlagStringVar(fs, &bufferKeyspaceShards, "buffer-keyspace-shards", "", "If not empty, limit buffering to these entries (comma separated). Entry format: keyspace or keyspace/shard. Requires --enable_buffer=true.")
+ utils.SetFlagStringVar(fs, &bufferKeyspaceShards, "buffer-keyspace-shards", "", "If not empty, limit buffering to these entries (comma separated). Entry format: keyspace or keyspace/shard. Requires --enable-buffer=true.")
}
func init() {
@@ -80,7 +80,7 @@ func verifyFlags() error {
}
if bufferKeyspaceShards != "" && !bufferEnabled {
- return fmt.Errorf("--buffer-keyspace-shards=%v also requires that --enable_buffer is set", bufferKeyspaceShards)
+ return fmt.Errorf("--buffer-keyspace-shards=%v also requires that --enable-buffer is set", bufferKeyspaceShards)
}
if bufferEnabled && bufferEnabledDryRun && bufferKeyspaceShards == "" {
return errors.New("both the dry-run mode and actual buffering is enabled. To avoid ambiguity, keyspaces and shards for actual buffering must be explicitly listed in --buffer-keyspace-shards")
diff --git a/go/vt/vtgate/vstream_manager.go b/go/vt/vtgate/vstream_manager.go
index 2b9fc80a6aa..55e30900fd3 100644
--- a/go/vt/vtgate/vstream_manager.go
+++ b/go/vt/vtgate/vstream_manager.go
@@ -637,7 +637,7 @@ func (vs *vstream) streamFromTablet(ctx context.Context, sgtid *binlogdatapb.Sha
err = fmt.Errorf("tablet %s is no longer healthy: %s, restarting vstream",
topoproto.TabletAliasString(tablet.Alias), shr.RealtimeStats.HealthError)
case shr.RealtimeStats.ReplicationLagSeconds > uint32(discovery.GetLowReplicationLag().Seconds()):
- err = fmt.Errorf("tablet %s has a replication lag of %d seconds which is beyond the value provided in --discovery_low_replication_lag of %s so the tablet is no longer considered healthy, restarting vstream",
+ err = fmt.Errorf("tablet %s has a replication lag of %d seconds which is beyond the value provided in --discovery-low-replication-lag of %s so the tablet is no longer considered healthy, restarting vstream",
topoproto.TabletAliasString(tablet.Alias), shr.RealtimeStats.ReplicationLagSeconds, discovery.GetLowReplicationLag())
}
if err != nil {
diff --git a/go/vt/vtgate/vtgate.go b/go/vt/vtgate/vtgate.go
index c135375c510..8b179e6ee8e 100644
--- a/go/vt/vtgate/vtgate.go
+++ b/go/vt/vtgate/vtgate.go
@@ -138,7 +138,7 @@ var (
return vtgatepb.TransactionMode_TWOPC
default:
fmt.Printf("Invalid option: %v\n", txMode)
- fmt.Println("Usage: -transaction_mode {SINGLE | MULTI | TWOPC}")
+ fmt.Println("Usage: --transaction-mode {SINGLE | MULTI | TWOPC}")
os.Exit(1)
return -1
}
diff --git a/go/vt/vtorc/logic/tablet_discovery.go b/go/vt/vtorc/logic/tablet_discovery.go
index d381a4ea78d..b8a77cbe292 100644
--- a/go/vt/vtorc/logic/tablet_discovery.go
+++ b/go/vt/vtorc/logic/tablet_discovery.go
@@ -51,7 +51,7 @@ var (
shutdownWaitTime = 30 * time.Second
// shardsToWatch is a map storing the shards for a given keyspace that need to be watched.
// We store the key range for all the shards that we want to watch.
- // This is populated by parsing `--clusters_to_watch` flag.
+ // This is populated by parsing `--clusters-to-watch` flag.
shardsToWatch map[string][]*topodatapb.KeyRange
// ErrNoPrimaryTablet is a fixed error message.
@@ -122,7 +122,7 @@ func RegisterFlags(fs *pflag.FlagSet) {
utils.SetFlagDurationVar(fs, &shutdownWaitTime, "shutdown-wait-time", shutdownWaitTime, "Maximum time to wait for VTOrc to release all the locks that it is holding before shutting down on SIGTERM")
}
-// initializeShardsToWatch parses the --clusters_to_watch flag-value
+// initializeShardsToWatch parses the --clusters-to-watch flag-value
// into a map of keyspace/shards.
func initializeShardsToWatch() error {
shardsToWatch = make(map[string][]*topodatapb.KeyRange)
@@ -193,7 +193,7 @@ func OpenTabletDiscovery() <-chan time.Time {
if _, err := db.ExecVTOrc("DELETE FROM vitess_tablet"); err != nil {
log.Error(err)
}
- // Parse --clusters_to_watch into a filter.
+ // Parse --clusters-to-watch into a filter.
err := initializeShardsToWatch()
if err != nil {
log.Fatalf("Error parsing --clusters-to-watch: %v", err)
diff --git a/go/vt/vttablet/tabletmanager/rpc_vreplication.go b/go/vt/vttablet/tabletmanager/rpc_vreplication.go
index 35928602df7..40b1cb1bed5 100644
--- a/go/vt/vttablet/tabletmanager/rpc_vreplication.go
+++ b/go/vt/vttablet/tabletmanager/rpc_vreplication.go
@@ -874,7 +874,7 @@ func (tm *TabletManager) createSequenceTable(ctx context.Context, tableName stri
return err
}
-// ValidateVReplicationPermissionsOld validates that the --db_filtered_user has
+// ValidateVReplicationPermissionsOld validates that the --db-filtered-user has
// the minimum permissions required on the sidecardb vreplication table
// needed in order to manage vreplication metadata.
// Switching to use a functional test approach in ValidateVReplicationPermissions below
@@ -921,7 +921,7 @@ func (tm *TabletManager) ValidateVReplicationPermissionsOld(ctx context.Context,
}, nil
}
-// ValidateVReplicationPermissions validates that the --db_filtered_user has
+// ValidateVReplicationPermissions validates that the --db-filtered-user has
// the minimum permissions required on the sidecardb vreplication table
// using a functional testing approach that doesn't require access to mysql.user table.
func (tm *TabletManager) ValidateVReplicationPermissions(ctx context.Context, req *tabletmanagerdatapb.ValidateVReplicationPermissionsRequest) (*tabletmanagerdatapb.ValidateVReplicationPermissionsResponse, error) {
diff --git a/go/vt/vttablet/tabletserver/tabletenv/config.go b/go/vt/vttablet/tabletserver/tabletenv/config.go
index 91f43ad3b1b..5077edd8f1e 100644
--- a/go/vt/vttablet/tabletserver/tabletenv/config.go
+++ b/go/vt/vttablet/tabletserver/tabletenv/config.go
@@ -184,7 +184,7 @@ func registerTabletEnvFlags(fs *pflag.FlagSet) {
utils.SetFlagBoolVar(fs, ¤tConfig.EnableTransactionLimit, "enable-transaction-limit", defaultConfig.EnableTransactionLimit, "If true, limit on number of transactions open at the same time will be enforced for all users. User trying to open a new transaction after exhausting their limit will receive an error immediately, regardless of whether there are available slots or not.")
utils.SetFlagBoolVar(fs, ¤tConfig.EnableTransactionLimitDryRun, "enable-transaction-limit-dry-run", defaultConfig.EnableTransactionLimitDryRun, "If true, limit on number of transactions open at the same time will be tracked for all users, but not enforced.")
- utils.SetFlagFloat64Var(fs, ¤tConfig.TransactionLimitPerUser, "transaction-limit-per-user", defaultConfig.TransactionLimitPerUser, "Maximum number of transactions a single user is allowed to use at any time, represented as fraction of -transaction_cap.")
+ utils.SetFlagFloat64Var(fs, ¤tConfig.TransactionLimitPerUser, "transaction-limit-per-user", defaultConfig.TransactionLimitPerUser, "Maximum number of transactions a single user is allowed to use at any time, represented as fraction of --queryserver-config-transaction-cap.")
utils.SetFlagBoolVar(fs, ¤tConfig.TransactionLimitByUsername, "transaction-limit-by-username", defaultConfig.TransactionLimitByUsername, "Include VTGateCallerID.username when considering who the user is for the purpose of transaction limit.")
utils.SetFlagBoolVar(fs, ¤tConfig.TransactionLimitByPrincipal, "transaction-limit-by-principal", defaultConfig.TransactionLimitByPrincipal, "Include CallerID.principal when considering who the user is for the purpose of transaction limit.")
utils.SetFlagBoolVar(fs, ¤tConfig.TransactionLimitByComponent, "transaction-limit-by-component", defaultConfig.TransactionLimitByComponent, "Include CallerID.component when considering who the user is for the purpose of transaction limit.")
@@ -1001,7 +1001,7 @@ func (c *TabletConfig) verifyTransactionLimitConfig() error {
bySubcomp = c.TransactionLimitBySubcomponent
)
if byAny := byUser || byPrincipal || byComp || bySubcomp; !byAny {
- return errors.New("no user discriminating fields selected for transaction limiter, everyone would share single chunk of transaction pool. Override with at least one of --transaction_limit_by flags set to true")
+ return errors.New("no user discriminating fields selected for transaction limiter, everyone would share single chunk of transaction pool. Override with at least one of the --transaction-limit-by-* flags set to true")
}
if v := c.TransactionLimitPerUser; v <= 0 || v >= 1 {
return fmt.Errorf("--transaction-limit-per-user should be a fraction within range (0, 1) (specified value: %v)", v)
diff --git a/proto/tabletmanagerdata.proto b/proto/tabletmanagerdata.proto
index e46bc63dbd4..94eeceab516 100644
--- a/proto/tabletmanagerdata.proto
+++ b/proto/tabletmanagerdata.proto
@@ -714,7 +714,7 @@ message ValidateVReplicationPermissionsRequest {
}
message ValidateVReplicationPermissionsResponse {
- // The --db_filtered_user on the tablet.
+ // The --db-filtered-user on the tablet.
string user = 1;
// Does the user have the minimum privileges needed to manage
// vreplication metadata.
From 73b0b8ddd1bff9062de9bfc3e7b2b568f75eec76 Mon Sep 17 00:00:00 2001
From: "vitess-bot[bot]" <108069721+vitess-bot[bot]@users.noreply.github.com>
Date: Mon, 19 Oct 2026 17:23:55 +0000
Subject: [PATCH 11/31] [release-23.0] VReplication: refresh shards
concurrently before switching traffic (#21607) (#21644)
Signed-off-by: Matt Lord
Co-authored-by: vitess-bot[bot] <108069721+vitess-bot[bot]@users.noreply.github.com>
Co-authored-by: Matt Lord
---
go/vt/vtctl/workflow/framework_test.go | 9 +++++
go/vt/vtctl/workflow/server.go | 44 +++++++++++++-----------
go/vt/vtctl/workflow/server_test.go | 47 ++++++++++++++++++++++++++
3 files changed, 81 insertions(+), 19 deletions(-)
diff --git a/go/vt/vtctl/workflow/framework_test.go b/go/vt/vtctl/workflow/framework_test.go
index 4e0d0e47173..2533c9a0caf 100644
--- a/go/vt/vtctl/workflow/framework_test.go
+++ b/go/vt/vtctl/workflow/framework_test.go
@@ -283,6 +283,8 @@ type testTMClient struct {
primaryPositionErrors map[uint32]error
vdiffRequests map[uint32]*vdiffRequestResponse
refreshStateErrors map[uint32]error
+ // How long each RefreshState call takes. Set it before use.
+ refreshStateDelay time.Duration
// Stack of ReadVReplicationWorkflowsResponse to return, in order, for each shard
readVReplicationWorkflowsResponses map[string][]*tabletmanagerdatapb.ReadVReplicationWorkflowsResponse
@@ -859,6 +861,13 @@ func (tmc *testTMClient) SetRefreshStateError(tablet *topodatapb.Tablet, err err
}
func (tmc *testTMClient) RefreshState(ctx context.Context, tablet *topodatapb.Tablet) error {
+ if tmc.refreshStateDelay > 0 {
+ select {
+ case <-time.After(tmc.refreshStateDelay):
+ case <-ctx.Done():
+ return ctx.Err()
+ }
+ }
tmc.mu.Lock()
defer tmc.mu.Unlock()
diff --git a/go/vt/vtctl/workflow/server.go b/go/vt/vtctl/workflow/server.go
index 195de053a14..5935c9d6949 100644
--- a/go/vt/vtctl/workflow/server.go
+++ b/go/vt/vtctl/workflow/server.go
@@ -3378,32 +3378,38 @@ func (s *Server) canSwitch(ctx context.Context, ts *trafficSwitcher, maxAllowedR
}
// Ensure that the tablets on both sides are in good shape as we make this same call in the
- // process and an error will cause us to backout.
+ // process and an error will cause us to backout. All of the shards are refreshed
+ // concurrently, so the shared timeout only has to cover the slowest shard.
refreshErrors := strings.Builder{}
var m sync.Mutex
- var wg sync.WaitGroup
rtbsCtx, cancel := context.WithTimeout(ctx, shardTabletRefreshTimeout)
defer cancel()
- refreshTablets := func(shards []*topo.ShardInfo, stype string) {
- defer wg.Done()
- for _, si := range shards {
- if partial, partialDetails, err := topotools.RefreshTabletsByShard(rtbsCtx, s.ts, s.tmc, si, nil, ts.Logger()); err != nil || partial {
- msg := fmt.Sprintf("failed to successfully refresh all tablets in the %s/%s %s shard (%v):\n %v\n",
- si.Keyspace(), si.ShardName(), stype, err, partialDetails)
- if partial && ts.force {
- log.Warning(msg)
- } else {
- m.Lock()
- refreshErrors.WriteString(msg)
- m.Unlock()
- }
+ refreshTablets := func(si *topo.ShardInfo, stype string) {
+ if partial, partialDetails, err := topotools.RefreshTabletsByShard(rtbsCtx, s.ts, s.tmc, si, nil, ts.Logger()); err != nil || partial {
+ msg := fmt.Sprintf("failed to successfully refresh all tablets in the %s/%s %s shard (%v):\n %v\n",
+ si.Keyspace(), si.ShardName(), stype, err, partialDetails)
+ if partial && ts.force {
+ log.Warning(msg)
+ } else {
+ m.Lock()
+ refreshErrors.WriteString(msg)
+ m.Unlock()
}
}
}
- wg.Add(1)
- go refreshTablets(ts.SourceShards(), "source")
- wg.Add(1)
- go refreshTablets(ts.TargetShards(), "target")
+ var wg sync.WaitGroup
+ wg.Go(func() {
+ _ = ts.ForAllSources(func(source *MigrationSource) error {
+ refreshTablets(source.GetShard(), "source")
+ return nil
+ })
+ })
+ wg.Go(func() {
+ _ = ts.ForAllTargets(func(target *MigrationTarget) error {
+ refreshTablets(target.GetShard(), "target")
+ return nil
+ })
+ })
wg.Wait()
if refreshErrors.Len() > 0 {
return fmt.Sprintf(cannotSwitchFailedTabletRefresh, refreshErrors.String()), nil
diff --git a/go/vt/vtctl/workflow/server_test.go b/go/vt/vtctl/workflow/server_test.go
index 28912f42a7f..07f8fa0ff13 100644
--- a/go/vt/vtctl/workflow/server_test.go
+++ b/go/vt/vtctl/workflow/server_test.go
@@ -37,6 +37,7 @@ import (
"vitess.io/vitess/go/sqltypes"
"vitess.io/vitess/go/test/utils"
"vitess.io/vitess/go/textutil"
+ "vitess.io/vitess/go/vt/key"
"vitess.io/vitess/go/vt/logutil"
"vitess.io/vitess/go/vt/mysqlctl/tmutils"
"vitess.io/vitess/go/vt/topo"
@@ -1672,6 +1673,52 @@ func TestMoveTablesTrafficSwitching(t *testing.T) {
}
}
+// TestCanSwitchRefreshesShardsConcurrently confirms that the tablet refresh done before
+// switching traffic refreshes the shards concurrently, so it does not fail when refreshing
+// the shards one at a time would take longer than shardTabletRefreshTimeout.
+func TestCanSwitchRefreshesShardsConcurrently(t *testing.T) {
+ ctx, cancel := context.WithTimeout(t.Context(), 2*shardTabletRefreshTimeout)
+ defer cancel()
+
+ workflowName := "wf1"
+ tableName := "t1"
+ targetShards, err := key.GenerateShardRanges(16, 0)
+ require.NoError(t, err)
+ sourceKeyspace := &testKeyspace{
+ KeyspaceName: "sourceks",
+ ShardNames: []string{"0"},
+ }
+ targetKeyspace := &testKeyspace{
+ KeyspaceName: "targetks",
+ ShardNames: targetShards,
+ }
+
+ env := newTestEnv(t, ctx, defaultCellName, sourceKeyspace, targetKeyspace)
+ defer env.close()
+ env.tmc.schema = map[string]*tabletmanagerdatapb.SchemaDefinition{
+ tableName: {
+ TableDefinitions: []*tabletmanagerdatapb.TableDefinition{
+ {
+ Name: tableName,
+ Schema: fmt.Sprintf("CREATE TABLE %s (id BIGINT, name VARCHAR(64), PRIMARY KEY (id))", tableName),
+ },
+ },
+ },
+ }
+ env.tmc.expectVRQueryResultOnKeyspaceTablets(targetKeyspace.KeyspaceName, &queryResult{
+ query: "/select vrepl_id, table_name, lastpk from _vt.copy_state.*",
+ result: &querypb.QueryResult{},
+ })
+ // Refreshing the target shards one at a time takes 1.6 times the timeout.
+ env.tmc.refreshStateDelay = shardTabletRefreshTimeout / 10
+
+ ts, err := env.ws.buildTrafficSwitcher(ctx, targetKeyspace.KeyspaceName, workflowName)
+ require.NoError(t, err)
+ reason, err := env.ws.canSwitch(ctx, ts, 30, nil)
+ require.NoError(t, err)
+ require.Empty(t, reason)
+}
+
func TestMoveTablesSwitchWritesCompletesAfterCancelOnFreeze(t *testing.T) {
ctx, cancel := context.WithCancel(context.Background())
defer cancel()
From 598c238e6e23469a72de2094e0c5bbc2b878edb5 Mon Sep 17 00:00:00 2001
From: "vitess-bot[bot]" <108069721+vitess-bot[bot]@users.noreply.github.com>
Date: Tue, 20 Oct 2026 09:06:59 +0000
Subject: [PATCH 12/31] [release-23.0] vreplication: recheck WaitForPos after
100ms, backing off to 1s (#21630) (#21652)
Signed-off-by: Arthur Schreiber
Co-authored-by: vitess-bot[bot] <108069721+vitess-bot[bot]@users.noreply.github.com>
Co-authored-by: Claude Opus 5.5
---
.../tabletmanager/vreplication/engine.go | 15 ++++++--
.../tabletmanager/vreplication/engine_test.go | 34 +++++++++++++++++--
2 files changed, 44 insertions(+), 5 deletions(-)
diff --git a/go/vt/vttablet/tabletmanager/vreplication/engine.go b/go/vt/vttablet/tabletmanager/vreplication/engine.go
index 2607f1683a7..a1c31c25e77 100644
--- a/go/vt/vttablet/tabletmanager/vreplication/engine.go
+++ b/go/vt/vttablet/tabletmanager/vreplication/engine.go
@@ -71,6 +71,12 @@ const (
// stop replicating.
var waitRetryTime = 1 * time.Second
+// waitForPosRetryTime is how long WaitForPos waits before it first checks the
+// stream's position again. The wait doubles after each check, up to
+// waitRetryTime, so a short wait returns soon after the stream saves the
+// position, while a long one still checks only once per waitRetryTime.
+var waitForPosRetryTime = 100 * time.Millisecond
+
// How frequently vcopier will update _vt.vreplication rows_copied
var rowsCopiedUpdateInterval = 30 * time.Second
@@ -795,8 +801,9 @@ func (vre *Engine) WaitForPos(ctx context.Context, id int32, pos string) error {
}
defer dbClient.Close()
- tkr := time.NewTicker(waitRetryTime)
- defer tkr.Stop()
+ retryTime := waitForPosRetryTime
+ retry := time.NewTimer(retryTime)
+ defer retry.Stop()
for {
qr, err := dbClient.ExecuteFetch(binlogplayer.ReadVReplicationStatus(id), 10)
switch {
@@ -851,8 +858,10 @@ func (vre *Engine) WaitForPos(ctx context.Context, id int32, pos string) error {
return doneErr
case <-vre.ctx.Done():
return fmt.Errorf("vreplication is closing: %v", vre.ctx.Err())
- case <-tkr.C:
+ case <-retry.C:
}
+ retryTime = min(2*retryTime, max(waitRetryTime, waitForPosRetryTime))
+ retry.Reset(retryTime)
}
}
diff --git a/go/vt/vttablet/tabletmanager/vreplication/engine_test.go b/go/vt/vttablet/tabletmanager/vreplication/engine_test.go
index af054932c89..f9ee8d97e13 100644
--- a/go/vt/vttablet/tabletmanager/vreplication/engine_test.go
+++ b/go/vt/vttablet/tabletmanager/vreplication/engine_test.go
@@ -369,9 +369,10 @@ func TestEngineSelect(t *testing.T) {
}
func TestWaitForPos(t *testing.T) {
- savedRetryTime := waitRetryTime
- defer func() { waitRetryTime = savedRetryTime }()
+ savedRetryTime, savedWaitForPosRetryTime := waitRetryTime, waitForPosRetryTime
+ defer func() { waitRetryTime, waitForPosRetryTime = savedRetryTime, savedWaitForPosRetryTime }()
waitRetryTime = 10 * time.Millisecond
+ waitForPosRetryTime = 10 * time.Millisecond
dbClient := binlogplayer.NewMockDBClient(t)
mysqld := &mysqlctl.FakeMysqlDaemon{}
@@ -402,6 +403,35 @@ func TestWaitForPos(t *testing.T) {
}
}
+// TestWaitForPosRetriesQuickly checks that WaitForPos notices a position that
+// the stream saves just after the first check within its first, short retry
+// instead of a full waitRetryTime later.
+func TestWaitForPosRetriesQuickly(t *testing.T) {
+ dbClient := binlogplayer.NewMockDBClient(t)
+ mysqld := &mysqlctl.FakeMysqlDaemon{}
+ mysqld.MysqlPort.Store(3306)
+
+ dbClientFactory := func() binlogplayer.DBClient { return dbClient }
+ vre := NewTestEngine(env.TopoServ, env.Cells[0], mysqld, dbClientFactory, dbClientFactory, dbClient.DBName(), nil)
+
+ dbClient.ExpectRequest("select * from _vt.vreplication where db_name='db'", &sqltypes.Result{}, nil)
+ vre.Open(t.Context())
+
+ dbClient.ExpectRequest("select pos, state, message from _vt.vreplication where id=1", &sqltypes.Result{Rows: [][]sqltypes.Value{{
+ sqltypes.NewVarBinary("MariaDB/0-1-1083"),
+ sqltypes.NewVarBinary(binlogdatapb.VReplicationWorkflowState_Running.String()),
+ sqltypes.NewVarBinary(""),
+ }}}, nil)
+ dbClient.ExpectRequest("select pos, state, message from _vt.vreplication where id=1", &sqltypes.Result{Rows: [][]sqltypes.Value{{
+ sqltypes.NewVarBinary("MariaDB/0-1-1084"),
+ sqltypes.NewVarBinary(binlogdatapb.VReplicationWorkflowState_Running.String()),
+ sqltypes.NewVarBinary(""),
+ }}}, nil)
+ start := time.Now()
+ require.NoError(t, vre.WaitForPos(t.Context(), 1, "MariaDB/0-1-1084"))
+ assert.Less(t, time.Since(start), waitRetryTime/2)
+}
+
func TestWaitForPosError(t *testing.T) {
dbClient := binlogplayer.NewMockDBClient(t)
mysqld := &mysqlctl.FakeMysqlDaemon{}
From a005ce125729aa9e85e3a2936249d2aaeb8b596a Mon Sep 17 00:00:00 2001
From: "vitess-bot[bot]" <108069721+vitess-bot[bot]@users.noreply.github.com>
Date: Tue, 20 Oct 2026 09:22:09 -0400
Subject: [PATCH 13/31] [release-23.0] test: remove dead waits from the vstream
e2e tests (#21619) (#21621)
Signed-off-by: Arthur Schreiber
Co-authored-by: vitess-bot[bot] <108069721+vitess-bot[bot]@users.noreply.github.com>
Co-authored-by: Arthur Schreiber
Co-authored-by: Claude Opus 5.5
---
go/test/endtoend/vreplication/vstream_test.go | 431 ++++++++++++------
1 file changed, 299 insertions(+), 132 deletions(-)
diff --git a/go/test/endtoend/vreplication/vstream_test.go b/go/test/endtoend/vreplication/vstream_test.go
index 0a4205a722e..2d896651036 100644
--- a/go/test/endtoend/vreplication/vstream_test.go
+++ b/go/test/endtoend/vreplication/vstream_test.go
@@ -20,6 +20,8 @@ import (
"context"
"fmt"
"io"
+ "slices"
+ "strconv"
"strings"
"sync"
"sync/atomic"
@@ -29,6 +31,7 @@ import (
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"
+ "vitess.io/vitess/go/mysql"
"vitess.io/vitess/go/sets"
"vitess.io/vitess/go/vt/log"
"vitess.io/vitess/go/vt/utils"
@@ -36,6 +39,7 @@ import (
"vitess.io/vitess/go/vt/vtgate/vtgateconn"
binlogdatapb "vitess.io/vitess/go/vt/proto/binlogdata"
+ querypb "vitess.io/vitess/go/vt/proto/query"
topodatapb "vitess.io/vitess/go/vt/proto/topodata"
vtgatepb "vitess.io/vitess/go/vt/proto/vtgate"
)
@@ -98,7 +102,8 @@ func TestVStreamWithTablesToSkipCopyFlag(t *testing.T) {
// Stream events from the VStream API
reader, err := vstreamConn.VStream(ctx, topodatapb.TabletType_PRIMARY, vgtid, filter, flags)
require.NoError(t, err)
- var numRowEvents int64
+ var numRowEvents atomic.Int64
+ var sentinelSeen atomic.Bool
copyPhaseCompleted := atomic.Bool{}
copyPhaseCompleted.Store(false)
@@ -120,7 +125,10 @@ func TestVStreamWithTablesToSkipCopyFlag(t *testing.T) {
require.Len(t, escapedTableNameParts, 2)
copiedTables.Insert(escapedTableNameParts[1])
}
- numRowEvents++
+ numRowEvents.Add(1)
+ if isSentinelRow(ev.RowEvent) {
+ sentinelSeen.Store(true)
+ }
}
if ev.Type == binlogdatapb.VEventType_COPY_COMPLETED {
copyPhaseCompleted.Store(true)
@@ -150,7 +158,8 @@ func TestVStreamWithTablesToSkipCopyFlag(t *testing.T) {
stopInserting := atomic.Bool{}
stopInserting.Store(false)
var insertMu sync.Mutex
- go func() {
+ var inserts sync.WaitGroup
+ inserts.Go(func() {
for {
if stopInserting.Load() {
return
@@ -162,11 +171,12 @@ func TestVStreamWithTablesToSkipCopyFlag(t *testing.T) {
execVtgateQuery(t, vtgateConn, defaultSourceKs, fmt.Sprintf("insert into merchant (mname, category) values ('mname%d', 'category%d')", id+100, id))
insertMu.Unlock()
}
- }()
+ })
time.Sleep(100 * time.Millisecond)
stopInserting.Store(true)
- time.Sleep(10 * time.Second) // Give the vstream plenty of time to catchup
+ inserts.Wait()
+ waitForSentinelRow(t, vtgateConn, defaultSourceKs, &sentinelSeen)
done.Store(true)
qr1 := execVtgateQuery(t, vtgateConn, defaultSourceKs, "select count(*) from customer")
@@ -197,7 +207,7 @@ func TestVStreamWithTablesToSkipCopyFlag(t *testing.T) {
// Since we don't expect merchant table to be part of copy phase, we can
// subtract 10 from the total rows found in the 3 tables.
wantTotalRows := insertedRows1 + insertedRows2 + insertedRows3 - 10
- assert.Equal(t, wantTotalRows, numRowEvents)
+ assert.Equal(t, wantTotalRows, numRowEvents.Load())
}
// Validates that we have a working VStream API
@@ -253,7 +263,8 @@ func testVStreamWithFailover(t *testing.T, failover bool) {
defer vtgateConn.Close()
// first goroutine that keeps inserting rows into table being streamed until some time elapses after second PRS
- go func() {
+ var inserts sync.WaitGroup
+ inserts.Go(func() {
for {
if stopInserting.Load() {
return
@@ -263,12 +274,13 @@ func testVStreamWithFailover(t *testing.T, failover bool) {
execVtgateQuery(t, vtgateConn, defaultSourceKs, fmt.Sprintf("insert into customer (cid, name) values (%d, 'customer%d')", id+100, id))
insertMu.Unlock()
}
- }()
+ })
// stream events from the VStream API
reader, err := vstreamConn.VStream(ctx, topodatapb.TabletType_PRIMARY, vgtid, filter, flags)
require.NoError(t, err)
- var numRowEvents int64
+ var numRowEvents atomic.Int64
+ var sentinelSeen atomic.Bool
// second goroutine that continuously receives events via VStream API and should be resilient to the two PRS events
go func() {
for {
@@ -278,7 +290,10 @@ func testVStreamWithFailover(t *testing.T, failover bool) {
case nil:
for _, ev := range evs {
if ev.Type == binlogdatapb.VEventType_ROW {
- numRowEvents++
+ numRowEvents.Add(1)
+ if isSentinelRow(ev.RowEvent) {
+ sentinelSeen.Store(true)
+ }
}
}
case io.EOF:
@@ -297,7 +312,7 @@ func testVStreamWithFailover(t *testing.T, failover bool) {
ticker := time.NewTicker(1 * time.Second)
tickCount := 0
// this for loop implements a mini state machine that does the two PRSs, waits a bit after the second PRS,
- // stops the insertions, waits for a bit again for the vstream to catchup and signals the test to stop
+ // stops the insertions, waits for the vstream to catch up and signals the test to stop
for {
<-ticker.C
tickCount++
@@ -320,7 +335,8 @@ func testVStreamWithFailover(t *testing.T, failover bool) {
}
time.Sleep(100 * time.Millisecond)
stopInserting.Store(true)
- time.Sleep(10 * time.Second) // Give the vstream plenty of time to catchup
+ inserts.Wait()
+ waitForSentinelRow(t, vtgateConn, defaultSourceKs, &sentinelSeen)
done.Store(true)
}
@@ -334,7 +350,7 @@ func testVStreamWithFailover(t *testing.T, failover bool) {
// total number of row events found by the VStream API should match the rows inserted
insertedRows, err := qr.Rows[0][0].ToCastInt64()
require.NoError(t, err)
- require.Equal(t, insertedRows, numRowEvents)
+ require.Equal(t, insertedRows, numRowEvents.Load())
}
const schemaUnsharded = `
@@ -393,6 +409,47 @@ func insertRow(keyspace, table string, id int) {
vtgateConn.ExecuteFetch("commit", 1000, false)
}
+// sentinelCID is the cid of the customer row that a test inserts after its
+// other inserts. A single-shard stream delivers commits in order, so once it
+// delivers the sentinel row it has delivered every earlier insert. It is
+// negative so that it collides with neither explicit nor auto-increment ids.
+const sentinelCID = -1
+
+// rowValues returns the column values of row, with NULL as an empty string.
+func rowValues(row *querypb.Row) []string {
+ values := make([]string, 0, len(row.GetLengths()))
+ var offset int64
+ for _, length := range row.GetLengths() {
+ if length < 0 {
+ values = append(values, "")
+ continue
+ }
+ values = append(values, string(row.Values[offset:offset+length]))
+ offset += length
+ }
+ return values
+}
+
+// isSentinelRow reports whether ev inserts the customer row with cid sentinelCID.
+func isSentinelRow(ev *binlogdatapb.RowEvent) bool {
+ if !strings.HasSuffix(ev.GetTableName(), ".customer") {
+ return false
+ }
+ for _, rowChange := range ev.GetRowChanges() {
+ if values := rowValues(rowChange.GetAfter()); len(values) > 0 && values[0] == strconv.Itoa(sentinelCID) {
+ return true
+ }
+ }
+ return false
+}
+
+// waitForSentinelRow inserts the sentinel customer row into keyspace and waits
+// until the stream reports it in seen.
+func waitForSentinelRow(t *testing.T, vtgateConn *mysql.Conn, keyspace string, seen *atomic.Bool) {
+ execVtgateQuery(t, vtgateConn, keyspace, fmt.Sprintf("insert into customer (cid, name) values (%d, 'sentinel')", sentinelCID))
+ require.Eventually(t, seen.Load, 30*time.Second, 10*time.Millisecond, "the vstream did not deliver the sentinel row")
+}
+
type numEvents struct {
numRowEvents, numJournalEvents int64
numDash80Events, num80DashEvents int64
@@ -442,23 +499,26 @@ func testVStreamStopOnReshardFlag(t *testing.T, stopOnReshard bool, baseTabletID
}},
}
flags := &vtgatepb.VStreamFlags{HeartbeatInterval: 3600, StopOnReshard: stopOnReshard}
- done := false
+ var done, streamEnded, stopInserts atomic.Bool
- id := 1000
- // first goroutine that keeps inserting rows into table being streamed until a minute after reshard
+ // first goroutine that keeps inserting rows into table being streamed until the test has seen the reshard
// * if StopOnReshard is false we should keep getting events on the new shards
// * if StopOnReshard is true we should get a journal event and no events on the new shards
- go func() {
- for {
- if done {
- return
- }
- id++
- time.Sleep(1 * time.Second)
+ var inserts sync.WaitGroup
+ inserts.Go(func() {
+ for id := 1001; !stopInserts.Load(); id++ {
+ time.Sleep(250 * time.Millisecond)
insertRow("sharded", "customer", id)
}
- }()
+ })
+ stopInserting := func() {
+ stopInserts.Store(true)
+ inserts.Wait()
+ }
+ // Stop inserting before the deferred teardown, also when the test fails.
+ defer stopInserting()
// stream events from the VStream API
+ var mu sync.Mutex // protects ne
var ne numEvents
go func() {
var reader vtgateconn.VStreamReader
@@ -476,6 +536,7 @@ func testVStreamStopOnReshardFlag(t *testing.T, stopOnReshard bool, baseTabletID
switch err {
case nil:
+ mu.Lock()
for _, ev := range evs {
switch ev.Type {
case binlogdatapb.VEventType_VGTID:
@@ -497,13 +558,16 @@ func testVStreamStopOnReshardFlag(t *testing.T, stopOnReshard bool, baseTabletID
ne.numJournalEvents++
}
}
+ mu.Unlock()
case io.EOF:
log.Infof("Stream Ended")
- done = true
+ streamEnded.Store(true)
+ done.Store(true)
default:
log.Infof("%s:: remote error: %v", time.Now(), err)
numErrors++
if numErrors > 10 { // if vtgate is continuously unavailable error the test
+ done.Store(true)
return
}
if strings.Contains(strings.ToLower(err.Error()), "unavailable") {
@@ -513,32 +577,41 @@ func testVStreamStopOnReshardFlag(t *testing.T, stopOnReshard bool, baseTabletID
connect = true
} else {
// failure, stop test
- done = true
+ done.Store(true)
}
}
- if done {
+ if done.Load() {
return
}
}
}()
- ticker := time.NewTicker(1 * time.Second)
- tickCount := 0
- for {
- <-ticker.C
- tickCount++
- switch tickCount {
- case 1:
- reshard(t, "sharded", "customer", "vstreamStopOnReshard", "-80,80-",
- "-40,40-", baseTabletID+400, nil, nil, nil, nil, defaultCellName, 1)
- case 60:
- done = true
- }
- if done {
- break
+ reshard(t, "sharded", "customer", "vstreamStopOnReshard", "-80,80-",
+ "-40,40-", baseTabletID+400, nil, nil, nil, nil, defaultCellName, 1)
+
+ // With StopOnReshard the stream ends cleanly on the reshard journal.
+ // Without it, the stream must keep going: vtgate starts streaming the new
+ // shards only after every old shard has reached the journal, and it sends
+ // a journal to the client before that. Once rows from both new shards
+ // have arrived, a journal sent by mistake would already have arrived too.
+ require.EventuallyWithT(t, func(c *assert.CollectT) {
+ if stopOnReshard {
+ assert.True(c, streamEnded.Load(), "the vstream did not end with io.EOF after the reshard")
+ return
}
- }
- return &ne
+ assert.False(c, done.Load(), "the vstream ended")
+ mu.Lock()
+ defer mu.Unlock()
+ assert.Positive(c, ne.numDash40Events, "no row events from shard -40")
+ assert.Positive(c, ne.num40DashEvents, "no row events from shard 40-")
+ }, time.Minute, 100*time.Millisecond)
+ stopInserting()
+ done.Store(true)
+
+ mu.Lock()
+ defer mu.Unlock()
+ result := ne
+ return &result
}
// Validate that we can continue streaming from multiple keyspaces after first copying some tables and then resharding one of the keyspaces
@@ -582,40 +655,45 @@ func testVStreamCopyMultiKeyspaceReshard(t *testing.T, baseTabletID int) numEven
}},
}
flags := &vtgatepb.VStreamFlags{}
- done := false
+ var done, stopInserts, reshardDone atomic.Bool
- id := 1000
- // First goroutine that keeps inserting rows into the table being streamed until a minute after reshard
+ // First goroutine that keeps inserting rows into the table being streamed until the new shards have streamed rows
// We should keep getting events on the new shards
- go func() {
- for {
- if done {
- return
- }
- id++
- time.Sleep(1 * time.Second)
+ var inserts sync.WaitGroup
+ inserts.Go(func() {
+ for id := 1001; !stopInserts.Load(); id++ {
+ time.Sleep(250 * time.Millisecond)
insertRow("sharded", "customer", id)
}
- }()
+ })
+ stopInserting := func() {
+ stopInserts.Store(true)
+ inserts.Wait()
+ }
+ // Stop inserting before the deferred teardown, also when the test fails.
+ defer stopInserting()
// stream events from the VStream API
+ var mu sync.Mutex // protects ne and streamedNames
var ne numEvents
- reshardDone := false
+ streamedNames := make(map[string]bool) // names of the streamed rows of the sharded customer table
go func() {
- var reader vtgateconn.VStreamReader
- reader, err = vstreamConn.VStream(ctx, topodatapb.TabletType_PRIMARY, vgtid, filter, flags)
- require.NoError(t, err)
+ reader, err := vstreamConn.VStream(ctx, topodatapb.TabletType_PRIMARY, vgtid, filter, flags)
+ if !assert.NoError(t, err) {
+ return
+ }
for {
evs, err := reader.Recv()
switch err {
case nil:
+ mu.Lock()
for _, ev := range evs {
switch ev.Type {
case binlogdatapb.VEventType_ROW:
shard := ev.RowEvent.Shard
switch shard {
case "0":
- if reshardDone {
+ if reshardDone.Load() {
ne.numShard0AfterReshardEvents++
} else {
ne.numShard0BeforeReshardEvents++
@@ -629,41 +707,63 @@ func testVStreamCopyMultiKeyspaceReshard(t *testing.T, baseTabletID int) numEven
case "40-":
ne.num40DashEvents++
}
+ if shard != "0" {
+ for _, rowChange := range ev.RowEvent.RowChanges {
+ if values := rowValues(rowChange.GetAfter()); len(values) > 1 {
+ streamedNames[values[1]] = true
+ }
+ }
+ }
ne.numRowEvents++
case binlogdatapb.VEventType_JOURNAL:
ne.numJournalEvents++
}
}
+ mu.Unlock()
case io.EOF:
log.Infof("Stream Ended")
- done = true
+ done.Store(true)
default:
log.Errorf("Returned err %v", err)
- done = true
+ done.Store(true)
}
- if done {
+ if done.Load() {
return
}
}
}()
- ticker := time.NewTicker(1 * time.Second)
- tickCount := 0
- for {
- <-ticker.C
- tickCount++
- switch tickCount {
- case 1:
- reshard(t, "sharded", defaultTargetKs, "vstreamCopyMultiKeyspaceReshard", "-80,80-", "-40,40-", baseTabletID+400, nil, nil, nil, nil, defaultCellName, 1)
- reshardDone = true
- case 60:
- done = true
+ reshard(t, "sharded", defaultTargetKs, "vstreamCopyMultiKeyspaceReshard", "-80,80-", "-40,40-", baseTabletID+400, nil, nil, nil, nil, defaultCellName, 1)
+ reshardDone.Store(true)
+
+ // Once rows from both new shards have arrived, vtgate has finished the
+ // reshard transition, so a journal sent by mistake would already have
+ // arrived (see testVStreamStopOnReshardFlag).
+ require.EventuallyWithT(t, func(c *assert.CollectT) {
+ assert.False(c, done.Load(), "the vstream ended")
+ mu.Lock()
+ defer mu.Unlock()
+ assert.Positive(c, ne.numDash40Events, "no row events from shard -40")
+ assert.Positive(c, ne.num40DashEvents, "no row events from shard 40-")
+ assert.Positive(c, ne.numShard0AfterReshardEvents, "no row events from the unsharded keyspace after the reshard")
+ }, time.Minute, 100*time.Millisecond)
+ stopInserting()
+
+ // Wait until every inserted row has been streamed.
+ nameResult := execVtgateQuery(t, vtgateConn, "sharded", "select name from customer")
+ require.EventuallyWithT(t, func(c *assert.CollectT) {
+ mu.Lock()
+ defer mu.Unlock()
+ for _, row := range nameResult.Rows {
+ assert.Truef(c, streamedNames[row[0].ToString()], "row %s was not streamed", row[0].ToString())
}
- if done {
- break
- }
- }
- log.Infof("ne=%v", ne)
+ }, 30*time.Second, 10*time.Millisecond)
+ done.Store(true)
+
+ mu.Lock()
+ result := ne
+ mu.Unlock()
+ log.Infof("ne=%v", result)
// The number of row events streamed by the VStream API should match the number of rows inserted.
// This is important for sharded tables, where we need to ensure that no row events are missed during the resharding process.
@@ -675,8 +775,8 @@ func testVStreamCopyMultiKeyspaceReshard(t *testing.T, baseTabletID int) numEven
customerResult := execVtgateQuery(t, vtgateConn, "sharded", "select count(*) from customer")
insertedCustomerRows, err := customerResult.Rows[0][0].ToCastInt64()
require.NoError(t, err)
- require.Equal(t, insertedCustomerRows, ne.numDash80Events+ne.num80DashEvents+ne.numDash40Events+ne.num40DashEvents)
- return ne
+ require.Equal(t, insertedCustomerRows, result.numDash80Events+result.num80DashEvents+result.numDash40Events+result.num40DashEvents)
+ return result
}
// Validate that we can resume a VStream when the keyspace has been resharded
@@ -726,24 +826,22 @@ func TestMultiVStreamsKeyspaceReshard(t *testing.T) {
// Coordinate go-routines.
streamCtx, streamCancel := context.WithTimeout(ctx, 1*time.Minute)
defer streamCancel()
- done := make(chan struct{})
+ stopInserts := make(chan struct{})
+ insertsDone := make(chan struct{})
// First goroutine that keeps inserting rows into the table being streamed until the
- // stream context is cancelled.
+ // resumed stream has crossed the reshard, or the stream context is cancelled.
go func() {
- id := 1
- for {
+ defer close(insertsDone)
+ for id := 1; ; id++ {
select {
case <-streamCtx.Done():
- // Give the VStream a little catch-up time before telling it to stop
- // via the done channel.
- time.Sleep(10 * time.Second)
- close(done)
+ return
+ case <-stopInserts:
return
default:
insertRow(ks, "customer", id)
time.Sleep(250 * time.Millisecond)
- id++
}
}
}()
@@ -756,6 +854,15 @@ func TestMultiVStreamsKeyspaceReshard(t *testing.T) {
ShardGtids: []*binlogdatapb.ShardGtid{{
Keyspace: "/.*", // Match all keyspaces just to be more realistic.
}}}
+ // The names of the customer rows seen in either stream.
+ streamedNames := make(map[string]bool)
+ recordNames := func(ev *binlogdatapb.RowEvent) {
+ for _, rowChange := range ev.RowChanges {
+ if values := rowValues(rowChange.GetAfter()); len(values) > 1 {
+ streamedNames[values[1]] = true
+ }
+ }
+ }
filter := &binlogdatapb.Filter{
Rules: []*binlogdatapb.Rule{{
@@ -785,6 +892,7 @@ func TestMultiVStreamsKeyspaceReshard(t *testing.T) {
switch shard {
case "-80", "80-":
oldShardRowEvents++
+ recordNames(ev.RowEvent)
case "0":
// We expect some for the sequence backing table, but don't care.
default:
@@ -826,9 +934,14 @@ func TestMultiVStreamsKeyspaceReshard(t *testing.T) {
reshardAction(t, "SwitchTraffic", wf, ks, oldShards, newShards, defaultCellName, tabletType)
// Now start a new VStream from our previous VGTID which only has the old/original shards.
+ // Once it has crossed the reshard, stop inserting and stream until every inserted
+ // row has been seen.
func() {
- reader, err := vstreamConn.VStream(ctx, topodatapb.TabletType_PRIMARY, newVGTID, filter, flags)
+ resumeCtx, resumeCancel := context.WithTimeout(ctx, 2*time.Minute)
+ defer resumeCancel()
+ reader, err := vstreamConn.VStream(resumeCtx, topodatapb.TabletType_PRIMARY, newVGTID, filter, flags)
require.NoError(t, err)
+ var insertedNames []string // nil until the inserts have stopped
for {
evs, err := reader.Recv()
@@ -841,8 +954,10 @@ func TestMultiVStreamsKeyspaceReshard(t *testing.T) {
switch shard {
case "-80", "80-":
oldShardRowEvents++
+ recordNames(ev.RowEvent)
case "-40", "40-80", "80-c0", "c0-":
newShardRowEvents++
+ recordNames(ev.RowEvent)
case "0":
// Again, we expect some for the sequence backing table, but don't care.
default:
@@ -854,12 +969,21 @@ func TestMultiVStreamsKeyspaceReshard(t *testing.T) {
}
}
default:
- require.FailNow(t, fmt.Sprintf("VStream returned unexpected error: %v", err))
+ require.FailNow(t, fmt.Sprintf("VStream returned unexpected error: %v", err),
+ "old shard rows: %d, new shard rows: %d, journal events: %d, inserts stopped: %t",
+ oldShardRowEvents, newShardRowEvents, journalEvents, insertedNames != nil)
}
- select {
- case <-done:
+ if insertedNames == nil && newShardRowEvents > 0 && journalEvents > 0 {
+ close(stopInserts)
+ <-insertsDone
+ qr := execVtgateQuery(t, vtgateConn, ks, "select name from customer")
+ insertedNames = make([]string, 0, len(qr.Rows))
+ for _, row := range qr.Rows {
+ insertedNames = append(insertedNames, row[0].ToString())
+ }
+ }
+ if insertedNames != nil && !slices.ContainsFunc(insertedNames, func(name string) bool { return !streamedNames[name] }) {
return
- default:
}
}
}()
@@ -1128,15 +1252,16 @@ const (
numExpectedHeartbeats = 10
)
-func doVStream(t *testing.T, vc *VitessCluster, flags *vtgatepb.VStreamFlags) (numRowEvents map[string]int, numFieldEvents map[string]int) {
- // Stream for a while to ensure heartbeats are sent.
- ctx, cancel := context.WithTimeout(context.Background(), vstreamHeartbeatsTestContextTimeout)
- defer cancel()
-
+// doVStream streams the customer and, if flags ask for them, heartbeat events
+// until ctx ends. It calls onHeartbeat, if set, with the number of heartbeats
+// received so far. It returns an error only if the stream could not start.
+func doVStream(t *testing.T, ctx context.Context, vc *VitessCluster, flags *vtgatepb.VStreamFlags, onHeartbeat func(int)) (numRowEvents map[string]int, numFieldEvents map[string]int, err error) {
numRowEvents = make(map[string]int)
numFieldEvents = make(map[string]int)
vstreamConn, err := vtgateconn.Dial(ctx, fmt.Sprintf("%s:%d", vc.ClusterConfig.hostname, vc.ClusterConfig.vtgateGrpcPort))
- require.NoError(t, err)
+ if err != nil {
+ return nil, nil, err
+ }
defer vstreamConn.Close()
done := false
@@ -1155,7 +1280,9 @@ func doVStream(t *testing.T, vc *VitessCluster, flags *vtgatepb.VStreamFlags) (n
}
// Stream events from the VStream API.
reader, err := vstreamConn.VStream(ctx, topodatapb.TabletType_PRIMARY, vgtid, filter, flags)
- require.NoError(t, err)
+ if err != nil {
+ return nil, nil, err
+ }
for !done {
evs, err := reader.Recv()
switch err {
@@ -1165,19 +1292,26 @@ func doVStream(t *testing.T, vc *VitessCluster, flags *vtgatepb.VStreamFlags) (n
case binlogdatapb.VEventType_ROW:
rowEvent := ev.RowEvent
arr := strings.Split(rowEvent.TableName, ".")
- require.Equal(t, len(arr), 2)
+ if !assert.Len(t, arr, 2) {
+ continue
+ }
tableName := arr[1]
- require.Equal(t, defaultSourceKs, rowEvent.Keyspace)
- require.Equal(t, "0", rowEvent.Shard)
+ assert.Equal(t, defaultSourceKs, rowEvent.Keyspace)
+ assert.Equal(t, "0", rowEvent.Shard)
numRowEvents[tableName]++
+ if tableName == "heartbeat" && onHeartbeat != nil {
+ onHeartbeat(numRowEvents[tableName])
+ }
case binlogdatapb.VEventType_FIELD:
fieldEvent := ev.FieldEvent
arr := strings.Split(fieldEvent.TableName, ".")
- require.Equal(t, len(arr), 2)
+ if !assert.Len(t, arr, 2) {
+ continue
+ }
tableName := arr[1]
- require.Equal(t, defaultSourceKs, fieldEvent.Keyspace)
- require.Equal(t, "0", fieldEvent.Shard)
+ assert.Equal(t, defaultSourceKs, fieldEvent.Keyspace)
+ assert.Equal(t, "0", fieldEvent.Shard)
numFieldEvents[tableName]++
default:
}
@@ -1186,11 +1320,11 @@ func doVStream(t *testing.T, vc *VitessCluster, flags *vtgatepb.VStreamFlags) (n
log.Infof("Stream Ended")
done = true
default:
- log.Errorf("remote error: %v", err)
+ log.Infof("stream ended: %v", err)
done = true
}
}
- return numRowEvents, numFieldEvents
+ return numRowEvents, numFieldEvents, nil
}
// TestVStreamHeartbeats enables streaming of the internal Vitess heartbeat tables in the VStream API and
@@ -1243,16 +1377,44 @@ func TestVStreamHeartbeats(t *testing.T) {
},
}
- for _, tc := range testCases {
+ // Run both streams at the same time, and stop them once the stream with
+ // heartbeats on has received the expected heartbeats. The stream with
+ // heartbeats off was open while those heartbeats were written.
+ ctx, cancel := context.WithTimeout(t.Context(), vstreamHeartbeatsTestContextTimeout)
+ defer cancel()
+ gotNumRowEvents := make([]map[string]int, len(testCases))
+ gotNumFieldEvents := make([]map[string]int, len(testCases))
+ streamErrs := make([]error, len(testCases))
+ var streams sync.WaitGroup
+ for i, tc := range testCases {
+ var onHeartbeat func(int)
+ if tc.expectedHeartbeats > 0 {
+ onHeartbeat = func(heartbeats int) {
+ if heartbeats >= tc.expectedHeartbeats {
+ cancel()
+ }
+ }
+ }
+ streams.Go(func() {
+ gotNumRowEvents[i], gotNumFieldEvents[i], streamErrs[i] = doVStream(t, ctx, vc, tc.flags, onHeartbeat)
+ })
+ }
+ streams.Wait()
+
+ for i, tc := range testCases {
t.Run(tc.name, func(t *testing.T) {
- gotNumRowEvents, gotNumFieldEvents := doVStream(t, vc, tc.flags)
+ require.NoError(t, streamErrs[i])
for k := range expectedNumRowEvents {
- require.Equalf(t, 1, gotNumFieldEvents[k], "incorrect number of field events for table %s, got %d", k, gotNumFieldEvents[k])
+ require.Equalf(t, 1, gotNumFieldEvents[i][k], "incorrect number of field events for table %s, got %d", k, gotNumFieldEvents[i][k])
+ }
+ if tc.expectedHeartbeats == 0 {
+ require.Zero(t, gotNumRowEvents[i]["heartbeat"], "received heartbeat events with keyspace heartbeats off")
+ } else {
+ require.GreaterOrEqual(t, gotNumRowEvents[i]["heartbeat"], tc.expectedHeartbeats, "incorrect number of heartbeat events received")
}
- require.GreaterOrEqual(t, gotNumRowEvents["heartbeat"], tc.expectedHeartbeats, "incorrect number of heartbeat events received")
- log.Infof("Total number of heartbeat events received: %v", gotNumRowEvents["heartbeat"])
- delete(gotNumRowEvents, "heartbeat")
- require.Equal(t, expectedNumRowEvents, gotNumRowEvents)
+ log.Infof("Total number of heartbeat events received: %v", gotNumRowEvents[i]["heartbeat"])
+ delete(gotNumRowEvents[i], "heartbeat")
+ require.Equal(t, expectedNumRowEvents, gotNumRowEvents[i])
})
}
}
@@ -1295,21 +1457,22 @@ func TestVStreamPushdownFilters(t *testing.T) {
// Coordinate go-routines.
streamCtx, streamCancel := context.WithTimeout(context.Background(), 10*time.Second)
defer streamCancel()
- done := make(chan struct{})
+ insertsDone := make(chan struct{})
// First goroutine that keeps inserting rows into the table being streamed until the
- // stream context is cancelled.
+ // stream context is cancelled, and then inserts the sentinel row, which is a paul too.
createdPauls := startingPauls
createdNonPauls := 0
go func() {
+ defer close(insertsDone)
id := 1
for {
select {
case <-streamCtx.Done():
- // Give the VStream a little catch-up time before telling it to stop
- // via the done channel.
- time.Sleep(10 * time.Second)
- close(done)
+ _, err := vtgateConn.ExecuteFetch(fmt.Sprintf("insert into `%s`.customer (cid, name) values (%d, 'paÜl')", ks, sentinelCID), 1, false)
+ if assert.NoError(t, err) {
+ createdPauls++
+ }
return
default:
if id%10 == 0 {
@@ -1345,7 +1508,8 @@ func TestVStreamPushdownFilters(t *testing.T) {
// So we should have at least one paul row event in the copy phase, and
// we should have many paul row events in the running phase.
- copyPhaseRowEvents, runningPhaseRowEvents := runVStreamAndGetNumOfRowEvents(t, ctx, vstreamConn, vgtid, filter, done)
+ copyPhaseRowEvents, runningPhaseRowEvents := runVStreamAndGetNumOfRowEvents(t, ctx, vstreamConn, vgtid, filter)
+ <-insertsDone
require.NotZero(t, createdPauls)
require.NotZero(t, createdNonPauls)
@@ -1357,12 +1521,15 @@ func TestVStreamPushdownFilters(t *testing.T) {
require.Equal(t, createdPauls, copyPhaseRowEvents+runningPhaseRowEvents)
}
-// runVStreamAndGetNumOfRowEvents runs VStream with the specified filter and
-// returns number of copy phase and running phase row events.
+// runVStreamAndGetNumOfRowEvents runs VStream with the specified filter until
+// it receives the sentinel row, and returns number of copy phase and running
+// phase row events.
func runVStreamAndGetNumOfRowEvents(t *testing.T, ctx context.Context, vstreamConn *vtgateconn.VTGateConn,
- vgtid *binlogdatapb.VGtid, filter *binlogdatapb.Filter, done chan struct{}) (copyPhaseRowEvents int, runningPhaseRowEvents int) {
+ vgtid *binlogdatapb.VGtid, filter *binlogdatapb.Filter) (copyPhaseRowEvents int, runningPhaseRowEvents int) {
copyPhase := true
func() {
+ ctx, cancel := context.WithTimeout(ctx, time.Minute)
+ defer cancel()
reader, err := vstreamConn.VStream(ctx, topodatapb.TabletType_PRIMARY, vgtid, filter, &vtgatepb.VStreamFlags{})
require.NoError(t, err)
for {
@@ -1370,6 +1537,7 @@ func runVStreamAndGetNumOfRowEvents(t *testing.T, ctx context.Context, vstreamCo
switch err {
case nil:
+ sentinelSeen := false
for _, ev := range evs {
switch ev.Type {
case binlogdatapb.VEventType_COPY_COMPLETED:
@@ -1380,15 +1548,14 @@ func runVStreamAndGetNumOfRowEvents(t *testing.T, ctx context.Context, vstreamCo
} else {
runningPhaseRowEvents++
}
+ sentinelSeen = sentinelSeen || isSentinelRow(ev.RowEvent)
}
}
+ if sentinelSeen {
+ return
+ }
default:
- require.FailNow(t, fmt.Sprintf("VStream returned unexpected error: %v", err))
- }
- select {
- case <-done:
- return
- default:
+ require.FailNow(t, fmt.Sprintf("VStream returned unexpected error before the sentinel row: %v", err))
}
}
}()
From d8701819f04cd152056e52e2c03e184f994b5295 Mon Sep 17 00:00:00 2001
From: "vitess-bot[bot]" <108069721+vitess-bot[bot]@users.noreply.github.com>
Date: Tue, 20 Oct 2026 09:23:23 -0400
Subject: [PATCH 14/31] [release-23.0] tabletserver: update the sequence cache
only after the refill commits (#21375) (#21417)
Signed-off-by: Arthur Schreiber
Co-authored-by: vitess-bot[bot] <108069721+vitess-bot[bot]@users.noreply.github.com>
Co-authored-by: Arthur Schreiber
Co-authored-by: Claude Opus 5.5
---
go/vt/vttablet/tabletserver/query_executor.go | 27 +++---
.../tabletserver/query_executor_test.go | 93 +++++++++++++++++++
2 files changed, 109 insertions(+), 11 deletions(-)
diff --git a/go/vt/vttablet/tabletserver/query_executor.go b/go/vt/vttablet/tabletserver/query_executor.go
index 039e8499a15..4f133d11db3 100644
--- a/go/vt/vttablet/tabletserver/query_executor.go
+++ b/go/vt/vttablet/tabletserver/query_executor.go
@@ -821,6 +821,9 @@ func (qre *QueryExecutor) execNextval() (*sqltypes.Result, error) {
t.SequenceInfo.Lock()
defer t.SequenceInfo.Unlock()
if t.SequenceInfo.NextVal == 0 || t.SequenceInfo.NextVal+inc > t.SequenceInfo.LastVal {
+ // Stage the new cache range and write it to SequenceInfo after the COMMIT succeeds.
+ // A failed COMMIT can leave the old next_id in the sequence table.
+ nextVal, lastVal := t.SequenceInfo.NextVal, t.SequenceInfo.LastVal
_, err := qre.execAsTransaction(func(conn *StatefulConnection) (*sqltypes.Result, error) {
query := fmt.Sprintf("select next_id, cache from %s where id = 0 for update", sqlparser.String(tableName))
qr, err := qre.execStatefulConn(conn, query, false)
@@ -834,16 +837,15 @@ func (qre *QueryExecutor) execNextval() (*sqltypes.Result, error) {
if err != nil {
return nil, vterrors.Wrapf(err, "error loading sequence %s", tableName)
}
- // If LastVal does not match next ID, then either:
- // VTTablet just started, and we're initializing the cache, or
- // Someone reset the id underneath us.
- if t.SequenceInfo.LastVal != nextID {
- if nextID < t.SequenceInfo.LastVal {
- log.Warningf("Sequence next ID value %v is below the currently cached max %v, updating it to max", nextID, t.SequenceInfo.LastVal)
- nextID = t.SequenceInfo.LastVal
+ // Start the staged range at next_id when next_id differs from the cached last value.
+ // The two differ when the cache is empty, when a write outside this cache changed next_id,
+ // or when an earlier refill's COMMIT applied but returned an error.
+ if lastVal != nextID {
+ if nextID < lastVal {
+ log.Warningf("Sequence next ID value %v is below the currently cached max %v, updating it to max", nextID, lastVal)
+ nextID = lastVal
}
- t.SequenceInfo.NextVal = nextID
- t.SequenceInfo.LastVal = nextID
+ nextVal = nextID
}
cache, err := qr.Rows[0][1].ToCastInt64()
if err != nil {
@@ -853,7 +855,7 @@ func (qre *QueryExecutor) execNextval() (*sqltypes.Result, error) {
return nil, vterrors.Errorf(vtrpcpb.Code_INVALID_ARGUMENT, "invalid cache value for sequence %s: %d", tableName, cache)
}
newLast := nextID + cache
- for newLast < t.SequenceInfo.NextVal+inc {
+ for newLast < nextVal+inc {
newLast += cache
}
query = fmt.Sprintf("update %s set next_id = %d where id = 0", sqlparser.String(tableName), newLast)
@@ -861,12 +863,15 @@ func (qre *QueryExecutor) execNextval() (*sqltypes.Result, error) {
if err != nil {
return nil, err
}
- t.SequenceInfo.LastVal = newLast
+ lastVal = newLast
return nil, nil
})
if err != nil {
return nil, err
}
+
+ t.SequenceInfo.NextVal = nextVal
+ t.SequenceInfo.LastVal = lastVal
}
ret := t.SequenceInfo.NextVal
t.SequenceInfo.NextVal += inc
diff --git a/go/vt/vttablet/tabletserver/query_executor_test.go b/go/vt/vttablet/tabletserver/query_executor_test.go
index 31d964927e3..c8cef06bf3b 100644
--- a/go/vt/vttablet/tabletserver/query_executor_test.go
+++ b/go/vt/vttablet/tabletserver/query_executor_test.go
@@ -856,6 +856,99 @@ func TestQueryExecutorPlanNextval(t *testing.T) {
}
}
+// TestQueryExecutorPlanNextvalCommitFailureKeepsCache verifies that a failed
+// refill COMMIT leaves the sequence cache unchanged and that the next call
+// refills the cache from the sequence table.
+func TestQueryExecutorPlanNextvalCommitFailureKeepsCache(t *testing.T) {
+ db := setUpQueryExecutorTest(t)
+ t.Cleanup(db.Close)
+
+ db.AddQuery("select next_id, cache from seq where id = 0 for update", &sqltypes.Result{
+ Fields: []*querypb.Field{{Type: sqltypes.Int64}, {Type: sqltypes.Int64}},
+ Rows: [][]sqltypes.Value{{sqltypes.NewInt64(1), sqltypes.NewInt64(3)}},
+ })
+ db.AddQuery("update seq set next_id = 4 where id = 0", &sqltypes.Result{})
+
+ ctx := t.Context()
+ tsv := newTestTabletServer(ctx, noFlags, db)
+ t.Cleanup(tsv.StopService)
+
+ db.AddRejectedQuery("commit", errors.New("commit failed"))
+ qre := newTestQueryExecutor(ctx, tsv, "select next value from seq", 0)
+ _, err := qre.Execute()
+ require.ErrorContains(t, err, "commit failed")
+
+ // Check that the cache stays empty. The table still holds next_id = 1.
+ seq := qre.plan.Table.SequenceInfo
+ require.Zero(t, seq.NextVal)
+ require.Zero(t, seq.LastVal)
+
+ // Make the retry read next_id = 4 from the table. A stale cache returns 1.
+ db.AddQuery("select next_id, cache from seq where id = 0 for update", &sqltypes.Result{
+ Fields: []*querypb.Field{{Type: sqltypes.Int64}, {Type: sqltypes.Int64}},
+ Rows: [][]sqltypes.Value{{sqltypes.NewInt64(4), sqltypes.NewInt64(3)}},
+ })
+ db.AddQuery("update seq set next_id = 7 where id = 0", &sqltypes.Result{})
+ db.DeleteRejectedQuery("commit")
+
+ qre = newTestQueryExecutor(ctx, tsv, "select next value from seq", 0)
+ got, err := qre.Execute()
+ require.NoError(t, err)
+
+ want := &sqltypes.Result{
+ Fields: []*querypb.Field{{
+ Name: "nextval",
+ Type: sqltypes.Int64,
+ }},
+ Rows: [][]sqltypes.Value{{
+ sqltypes.NewInt64(4),
+ }},
+ }
+ require.Truef(t, got.Equal(want), "qre.Execute() =\n%#v, want:\n%#v", got, want)
+}
+
+// TestQueryExecutorPlanNextvalPartialRefillCommitFailureKeepsCache verifies
+// that a failed refill COMMIT on a non-empty cache leaves the cached range
+// unchanged. The refill starts from the cached last value, which equals the
+// next_id in the sequence table.
+func TestQueryExecutorPlanNextvalPartialRefillCommitFailureKeepsCache(t *testing.T) {
+ db := setUpQueryExecutorTest(t)
+ t.Cleanup(db.Close)
+
+ db.AddQuery("select next_id, cache from seq where id = 0 for update", &sqltypes.Result{
+ Fields: []*querypb.Field{{Type: sqltypes.Int64}, {Type: sqltypes.Int64}},
+ Rows: [][]sqltypes.Value{{sqltypes.NewInt64(1), sqltypes.NewInt64(3)}},
+ })
+ db.AddQuery("update seq set next_id = 4 where id = 0", &sqltypes.Result{})
+
+ ctx := t.Context()
+ tsv := newTestTabletServer(ctx, noFlags, db)
+ t.Cleanup(tsv.StopService)
+
+ // Use up the cached range [1, 4). The table now holds next_id = 4.
+ for range 3 {
+ qre := newTestQueryExecutor(ctx, tsv, "select next value from seq", 0)
+ _, err := qre.Execute()
+ require.NoError(t, err)
+ }
+
+ db.AddQuery("select next_id, cache from seq where id = 0 for update", &sqltypes.Result{
+ Fields: []*querypb.Field{{Type: sqltypes.Int64}, {Type: sqltypes.Int64}},
+ Rows: [][]sqltypes.Value{{sqltypes.NewInt64(4), sqltypes.NewInt64(3)}},
+ })
+ db.AddQuery("update seq set next_id = 7 where id = 0", &sqltypes.Result{})
+ db.AddRejectedQuery("commit", errors.New("commit failed"))
+
+ qre := newTestQueryExecutor(ctx, tsv, "select next value from seq", 0)
+ _, err := qre.Execute()
+ require.ErrorContains(t, err, "commit failed")
+
+ // Check that the cache keeps the used up range. A stale cache holds LastVal = 7.
+ seq := qre.plan.Table.SequenceInfo
+ require.EqualValues(t, 4, seq.NextVal)
+ require.EqualValues(t, 4, seq.LastVal)
+}
+
func TestQueryExecutorMessageStreamACL(t *testing.T) {
ctx, cancel := context.WithCancel(context.Background())
defer cancel()
From 70e7e5b7cf88cec543864db16210e735b37b48d5 Mon Sep 17 00:00:00 2001
From: "vitess-bot[bot]" <108069721+vitess-bot[bot]@users.noreply.github.com>
Date: Tue, 20 Oct 2026 09:31:32 -0400
Subject: [PATCH 15/31] [release-23.0] test: kill processes instead of shutting
them down in e2e teardown (#21598) (#21604)
Signed-off-by: Arthur Schreiber
Co-authored-by: vitess-bot[bot] <108069721+vitess-bot[bot]@users.noreply.github.com>
Co-authored-by: Arthur Schreiber
Co-authored-by: Claude Opus 5.5
---
go/test/endtoend/cluster/cluster_process.go | 20 +++++++++-
go/test/endtoend/cluster/mysqlctl_process.go | 32 +++++++++++----
go/test/endtoend/cluster/vtgate_process.go | 22 +++++++----
go/test/endtoend/vreplication/cluster_test.go | 39 +++++++++++++++++--
4 files changed, 94 insertions(+), 19 deletions(-)
diff --git a/go/test/endtoend/cluster/cluster_process.go b/go/test/endtoend/cluster/cluster_process.go
index 99dde80359a..417966c5b45 100644
--- a/go/test/endtoend/cluster/cluster_process.go
+++ b/go/test/endtoend/cluster/cluster_process.go
@@ -79,6 +79,13 @@ var (
PerfTest = flag.Bool("perf-test", false, "include end-to-end performance tests")
)
+// IsCoverage reports whether this is a coverage run (-is-coverage). Binaries
+// then write their coverage profiles on a graceful exit, so teardown must not
+// kill them.
+func IsCoverage() bool {
+ return *isCoverage
+}
+
// LocalProcessCluster Testcases need to use this to iniate a cluster
type LocalProcessCluster struct {
Keyspaces []Keyspace
@@ -1069,13 +1076,24 @@ func (cluster *LocalProcessCluster) Teardown() {
log.Errorf("Error in vtadmin teardown: %v", err)
}
+ // On CI the data directory is discarded after the test run, so nothing
+ // needs to be flushed to disk and a graceful mysqld shutdown buys us
+ // nothing. Killing mysqld skips the shutdown ack wait that can stall a
+ // semi-sync primary for many seconds per cluster. Coverage runs still
+ // shut down gracefully so that the mysqlctl shutdown path stays exercised.
+ killMySQL := os.Getenv("CI") == "true" && !*isCoverage
+
var mysqlctlProcessList []*exec.Cmd
var mysqlctlTabletUIDs []int
for _, keyspace := range cluster.Keyspaces {
for _, shard := range keyspace.Shards {
for _, tablet := range shard.Vttablets {
if tablet.MysqlctlProcess.TabletUID > 0 {
- if proc, err := tablet.MysqlctlProcess.StopProcess(); err != nil {
+ if killMySQL {
+ if err := tablet.MysqlctlProcess.Kill(); err != nil {
+ log.Errorf("Error in mysqlctl teardown: %v", err)
+ }
+ } else if proc, err := tablet.MysqlctlProcess.StopProcess(); err != nil {
log.Errorf("Error in mysqlctl teardown: %v", err)
} else {
mysqlctlProcessList = append(mysqlctlProcessList, proc)
diff --git a/go/test/endtoend/cluster/mysqlctl_process.go b/go/test/endtoend/cluster/mysqlctl_process.go
index ca741c2814c..edf76ac13e2 100644
--- a/go/test/endtoend/cluster/mysqlctl_process.go
+++ b/go/test/endtoend/cluster/mysqlctl_process.go
@@ -197,6 +197,14 @@ func (mysqlctl *MysqlctlProcess) Stop() (err error) {
}
break
}
+ return mysqlctl.Kill()
+}
+
+// Kill kills the mysqld and any associated mysqld_safe processes without a
+// graceful shutdown. This is safe when the data directory is discarded right
+// after: nothing needs to be flushed, and it skips the semi-sync ack wait
+// that can stall a graceful shutdown of a primary for many seconds.
+func (mysqlctl *MysqlctlProcess) Kill() error {
pidFile := path.Join(os.Getenv("VTDATAROOT"), fmt.Sprintf("/vt_%010d/mysql.pid", mysqlctl.TabletUID))
pidBytes, err := os.ReadFile(pidFile)
if err != nil {
@@ -210,16 +218,26 @@ func (mysqlctl *MysqlctlProcess) Stop() (err error) {
}
// We first need to try and kill any associated mysqld_safe process or
// else it will immediately restart the mysqld process when we kill it.
- mspidb, err := exec.Command("sh", "-c",
- fmt.Sprintf("ps auxww | grep -E 'mysqld_safe|mariadbd-safe' | grep vt_%010d | awk '{print $2}'", mysqlctl.TabletUID)).Output()
+ // mysqld_safe runs with --defaults-file=/my.cnf, so matching
+ // the full tablet directory keeps another cluster's tablet with the same
+ // UID from matching. The process list is filtered here rather than in a
+ // shell pipeline, so the path needs no quoting.
+ tabletDir := path.Dir(pidFile) + "/"
+ psOut, err := exec.Command("ps", "-eo", "pid=,args=").Output()
if err != nil {
return err
}
- mysqldSafePID, err := strconv.Atoi(strings.TrimSpace(string(mspidb)))
- // If we found a valid associated mysqld_safe process then let's kill
- // it first.
- if err == nil && mysqldSafePID > 0 {
- if err = syscallutil.Kill(mysqldSafePID, syscall.SIGKILL); err != nil {
+ for line := range strings.Lines(string(psOut)) {
+ pidField, args, _ := strings.Cut(strings.TrimSpace(line), " ")
+ if !strings.Contains(args, tabletDir) ||
+ (!strings.Contains(args, "mysqld_safe") && !strings.Contains(args, "mariadbd-safe")) {
+ continue
+ }
+ mysqldSafePID, err := strconv.Atoi(pidField)
+ if err != nil {
+ return err
+ }
+ if err := syscallutil.Kill(mysqldSafePID, syscall.SIGKILL); err != nil {
return err
}
}
diff --git a/go/test/endtoend/cluster/vtgate_process.go b/go/test/endtoend/cluster/vtgate_process.go
index 2946f5444f6..12faf3ab391 100644
--- a/go/test/endtoend/cluster/vtgate_process.go
+++ b/go/test/endtoend/cluster/vtgate_process.go
@@ -239,12 +239,14 @@ func (vtgate *VtgateProcess) Setup() (err error) {
if err != nil {
return
}
- vtgate.exit = make(chan error)
+ // The waiter captures this process and channel: TearDown returns once it
+ // receives the exit result, and a restart then replaces both fields, so
+ // the waiter must not read them again when it closes the channel.
+ proc, exit := vtgate.proc, make(chan error)
+ vtgate.exit = exit
go func() {
- if vtgate.proc != nil {
- vtgate.exit <- vtgate.proc.Wait()
- close(vtgate.exit)
- }
+ exit <- proc.Wait()
+ close(exit)
}()
timeout := time.Now().Add(60 * time.Second)
@@ -354,16 +356,20 @@ func (vtgate *VtgateProcess) TearDown() error {
// We are not checking vtgate's exit code because it sometimes
// returns exit code 2, even though vtgate terminates cleanly.
+ // Since the exit result is ignored, a long wait for a graceful exit
+ // buys nothing: force-kill after a short grace period. The forced kill
+ // is not an error either, so that callers like RestartVtgate go on to
+ // start the new vtgate.
select {
case <-vtgate.exit:
vtgate.proc = nil
return nil
- case <-time.After(30 * time.Second):
+ case <-time.After(5 * time.Second):
vtgate.proc.Process.Kill()
- err := <-vtgate.exit
+ <-vtgate.exit
vtgate.proc = nil
- return err
+ return nil
}
}
diff --git a/go/test/endtoend/vreplication/cluster_test.go b/go/test/endtoend/vreplication/cluster_test.go
index 6f0952830d3..876671ae0c1 100644
--- a/go/test/endtoend/vreplication/cluster_test.go
+++ b/go/test/endtoend/vreplication/cluster_test.go
@@ -790,7 +790,13 @@ func (vc *VitessCluster) teardown() {
}
for _, keyspace := range keyspaces {
- _ = vc.TearDownKeyspace(keyspace)
+ if cluster.IsCoverage() {
+ // Coverage runs need a graceful exit so that the instrumented
+ // binaries write their coverage profiles.
+ _ = vc.TearDownKeyspace(keyspace)
+ } else {
+ _ = vc.killKeyspaceProcesses(keyspace)
+ }
}
if err := vc.Vtctld.TearDown(); err != nil {
log.Infof("Error stopping Vtctld: %s", err.Error())
@@ -813,6 +819,34 @@ func (vc *VitessCluster) teardown() {
}
}
+// killKeyspaceProcesses kills the keyspace's vttablet and mysqld processes
+// without a graceful shutdown. This is only safe during the final cluster
+// teardown, where the data directory is deleted right afterwards: nothing
+// needs to be flushed, and killing skips both the semi-sync ack wait that
+// stalls a graceful primary mysqld shutdown and the vttablet termination
+// timeout once its mysqld is gone. Mid-test decommissioning of a keyspace
+// must keep using TearDownKeyspace.
+func (vc *VitessCluster) killKeyspaceProcesses(ks *Keyspace) error {
+ eg := errgroup.Group{}
+ for _, shard := range ks.Shards {
+ for _, tablet := range shard.Tablets {
+ eg.Go(func() error {
+ // The returned error is the process exit status: after a kill
+ // that is always non-nil ("signal: killed"), so it is not
+ // logged here.
+ _ = tablet.Vttablet.Kill()
+ if tablet.DbServer != nil && tablet.DbServer.TabletUID > 0 {
+ if err := tablet.DbServer.Kill(); err != nil {
+ log.Infof("Error killing mysql process associated with vttablet %s: %v", tablet.Name, err)
+ }
+ }
+ return nil
+ })
+ }
+ }
+ return eg.Wait()
+}
+
func (vc *VitessCluster) TearDownKeyspace(ks *Keyspace) error {
eg := errgroup.Group{}
for _, shard := range ks.Shards {
@@ -861,8 +895,7 @@ func (vc *VitessCluster) TearDown() {
case <-time.After(1 * time.Minute):
log.Infof("TearDown() timed out")
}
- // some processes seem to hang around for a bit
- time.Sleep(5 * time.Second)
+ // Straggling processes are covered by CleanupDataroot's retry loop.
vc.CleanupDataroot(vc.t, false)
}
From 183581d7727ae5f9e8ee96295905c9c6f7686f0b Mon Sep 17 00:00:00 2001
From: "vitess-bot[bot]" <108069721+vitess-bot[bot]@users.noreply.github.com>
Date: Tue, 20 Oct 2026 16:03:03 +0200
Subject: [PATCH 16/31] [release-23.0] ci: stop PR runs from saving Go caches,
split module and build caches (#20646) (#21659)
Signed-off-by: Arthur Schreiber
Co-authored-by: vitess-bot[bot] <108069721+vitess-bot[bot]@users.noreply.github.com>
Co-authored-by: Arthur Schreiber
Co-authored-by: Claude Opus 5.5
---
.github/actions/setup-go/action.yml | 96 +++++++++++++++++++++++++----
.github/workflows/unit_test.yml | 11 +---
2 files changed, 84 insertions(+), 23 deletions(-)
diff --git a/.github/actions/setup-go/action.yml b/.github/actions/setup-go/action.yml
index 14e00e6dde5..427e2df7d6f 100644
--- a/.github/actions/setup-go/action.yml
+++ b/.github/actions/setup-go/action.yml
@@ -1,8 +1,8 @@
name: "Set up Go"
-description: "Set up Go with shared module caching"
+description: "Set up Go with shared module and build caching"
inputs:
cache:
- description: "Whether to cache Go modules"
+ description: "Whether to restore and save the Go module and build caches"
default: "true"
runs:
using: "composite"
@@ -12,19 +12,89 @@ runs:
uses: actions/setup-go@b7ad1dad31e06c5925ef5d2fc7ad053ef454303e # v7.0.0
with:
go-version-file: go.mod
- # Disable built-in caching; its key includes ImageOS which
- # creates duplicate cache entries across runner types.
+ # Disable built-in caching: its key includes ImageOS, which duplicates
+ # entries across runner types, it stores the platform-independent
+ # module cache once per platform, and it saves from pull request runs,
+ # which crowds the branch-scoped entries pull requests restore from
+ # out of the repository cache quota.
cache: false
+ # Only pushes to main and the release branches save caches; everything
+ # else restores. Caches saved from any other run are scoped to a ref that
+ # pull requests do not restore from, while still counting against the
+ # repository quota and evicting the shared entries.
+ - name: Determine cache mode
+ id: cache-mode
+ shell: bash
+ env:
+ SAVE: ${{ github.event_name == 'push' && (github.ref == 'refs/heads/main' || startsWith(github.ref, 'refs/heads/release-')) }}
+ run: echo "save=${SAVE}" >> "${GITHUB_OUTPUT}"
+
+ - name: Restore Go module cache
+ if: inputs.cache == 'true' && steps.cache-mode.outputs.save == 'false'
+ uses: actions/cache/restore@55cc8345863c7cc4c66a329aec7e433d2d1c52a9 # v6.1.0
+ with:
+ path: ~/go/pkg/mod
+ key: go-mod-${{ hashFiles('go.sum', 'tools/**/go.sum') }}
+ restore-keys: |
+ go-mod-
+
+ - name: Restore Go build cache
+ if: inputs.cache == 'true' && steps.cache-mode.outputs.save == 'false'
+ uses: actions/cache/restore@55cc8345863c7cc4c66a329aec7e433d2d1c52a9 # v6.1.0
+ with:
+ path: ~/.cache/go-build
+ key: go-build-${{ runner.os }}-${{ runner.arch }}-go${{ steps.setup-go.outputs.go-version }}-${{ hashFiles('go.sum', 'tools/**/go.sum') }}
+ restore-keys: |
+ go-build-${{ runner.os }}-${{ runner.arch }}-go${{ steps.setup-go.outputs.go-version }}-
+
+ # Pushes to main and the release branches save the entries every other run
+ # restores from. The saves deliberately start from an empty cache instead
+ # of a restored one, so a go.sum change produces a minimal entry without
+ # stale module versions or dead build cache contents. actions/cache saves
+ # in its post step, after the job has populated the caches, and only when
+ # the job succeeds and the key does not exist yet.
- name: Cache Go modules
- if: inputs.cache == 'true' && (github.base_ref == 'main' || (github.base_ref == '' && github.ref_name == 'main'))
+ if: inputs.cache == 'true' && steps.cache-mode.outputs.save == 'true'
uses: actions/cache@55cc8345863c7cc4c66a329aec7e433d2d1c52a9 # v6.1.0
with:
- # Same paths cached by actions/setup-go internally.
- path: |
- ~/go/pkg/mod
- ~/.cache/go-build
- # Cache by version/arch/hash. Construct hash using same method as actions/setup-go.
- key: go-${{ steps.setup-go.outputs.go-version }}-${{ runner.os }}-${{ runner.arch }}-${{ hashFiles('go.sum', 'tools/**/go.sum') }}
- restore-keys: |
- go-${{ steps.setup-go.outputs.go-version }}-${{ runner.os }}-${{ runner.arch }}-
+ path: ~/go/pkg/mod
+ key: go-mod-${{ hashFiles('go.sum', 'tools/**/go.sum') }}
+
+ - name: Cache Go build cache
+ if: inputs.cache == 'true' && steps.cache-mode.outputs.save == 'true'
+ uses: actions/cache@55cc8345863c7cc4c66a329aec7e433d2d1c52a9 # v6.1.0
+ with:
+ path: ~/.cache/go-build
+ key: go-build-${{ runner.os }}-${{ runner.arch }}-go${{ steps.setup-go.outputs.go-version }}-${{ hashFiles('go.sum', 'tools/**/go.sum') }}
+
+ # Download the root module and every tool module, so a saved module cache
+ # always contains the full dependency set its key covers, no matter which
+ # job saves it first; the tool modules are otherwise only fetched on first
+ # use. On a cache hit this is a fast no-op. Retried because
+ # proxy.golang.org occasionally drops connections mid-download.
+ - name: Download Go modules
+ shell: bash
+ run: |
+ download() {
+ go mod download || return 1
+ local modfile
+ for modfile in tools/*/go.mod; do
+ # Older release trees, which the upgrade/downgrade workflows also
+ # set up, have no tool modules; the unmatched glob stays literal.
+ [ -f "${modfile}" ] || continue
+ go mod download -modfile="${modfile}" || return 1
+ done
+ }
+
+ for attempt in 1 2 3; do
+ if download; then
+ break
+ fi
+ if [ "${attempt}" = 3 ]; then
+ echo "go mod download failed after ${attempt} attempts"
+ exit 1
+ fi
+ echo "go mod download failed (attempt ${attempt}); retrying"
+ sleep 10
+ done
diff --git a/.github/workflows/unit_test.yml b/.github/workflows/unit_test.yml
index 2d9c56a8b21..1ef4836771f 100644
--- a/.github/workflows/unit_test.yml
+++ b/.github/workflows/unit_test.yml
@@ -139,14 +139,7 @@ jobs:
- name: Set up Go
if: needs.changes.outputs.unit_tests == 'true'
- # zizmor: ignore[cache-poisoning] this workflow publishes no artifacts
- uses: actions/setup-go@b7ad1dad31e06c5925ef5d2fc7ad053ef454303e # v7.0.0
- with:
- go-version-file: go.mod
- cache: ${{ (github.base_ref == 'main' || (github.base_ref == '' && github.ref_name == 'main')) && 'true' || 'false' }}
- cache-dependency-path: |
- go.sum
- tools/**/go.sum
+ uses: $/.github/actions/setup-go
- name: Set up python
if: needs.changes.outputs.unit_tests == 'true'
@@ -172,8 +165,6 @@ jobs:
curl --max-time 10 --retry 3 --retry-max-time 45 -s -L https://github.com/coreos/etcd/releases/download/v3.5.25/etcd-v3.5.25-linux-amd64.tar.gz | tar -zxC dist
mv dist/etcd-v3.5.25-linux-amd64/{etcd,etcdctl} bin/
- go mod download
-
- name: Run make tools
if: needs.changes.outputs.unit_tests == 'true'
run: |
From 5e6d032bdcc9735759efe721be575b27e15a277b Mon Sep 17 00:00:00 2001
From: "vitess-bot[bot]" <108069721+vitess-bot[bot]@users.noreply.github.com>
Date: Tue, 20 Oct 2026 16:35:46 +0200
Subject: [PATCH 17/31] [release-23.0] onlineddl: shorten the test suite's
post-cut-over position wait (#21629) (#21653)
Signed-off-by: Arthur Schreiber
Co-authored-by: vitess-bot[bot] <108069721+vitess-bot[bot]@users.noreply.github.com>
Co-authored-by: Arthur Schreiber
Co-authored-by: Claude Opus 5.5
---
.../vrepl_suite/onlineddl_vrepl_suite_test.go | 51 +++++++++++--------
go/vt/vttablet/onlineddl/executor.go | 18 +++++--
2 files changed, 42 insertions(+), 27 deletions(-)
diff --git a/go/test/endtoend/onlineddl/vrepl_suite/onlineddl_vrepl_suite_test.go b/go/test/endtoend/onlineddl/vrepl_suite/onlineddl_vrepl_suite_test.go
index a1bf634334a..e193e27d8ea 100644
--- a/go/test/endtoend/onlineddl/vrepl_suite/onlineddl_vrepl_suite_test.go
+++ b/go/test/endtoend/onlineddl/vrepl_suite/onlineddl_vrepl_suite_test.go
@@ -342,30 +342,37 @@ func testOnlineDDLStatement(t *testing.T, alterStatement string, ddlStrategy str
return uuid
}
-func readMigration(t *testing.T, uuid string) sqltypes.RowNamedValues {
- rs := onlineddl.ReadMigrations(t, &vtParams, uuid)
- require.NotNil(t, rs)
- row := rs.Named().Row()
- require.NotNil(t, row)
- return row
-}
-
func waitForMigration(t *testing.T, uuid string, timeout time.Duration) sqltypes.RowNamedValues {
- var status string
- sleepDuration := time.Second
- for timeout > 0 {
- row := readMigration(t, uuid)
- status = row["migration_status"].ToString()
- switch status {
- case string(schema.OnlineDDLStatusComplete), string(schema.OnlineDDLStatusFailed), string(schema.OnlineDDLStatusCancelled):
- // migration is complete, either successful or not
- return row
+ terminalStatuses := []string{string(schema.OnlineDDLStatusComplete), string(schema.OnlineDDLStatusFailed), string(schema.OnlineDDLStatusCancelled)}
+ query, err := sqlparser.ParseAndBind("show vitess_migrations like %a", sqltypes.StringBindVariable(uuid))
+ require.NoError(t, err)
+ var row sqltypes.RowNamedValues
+ require.EventuallyWithT(t, func(c *assert.CollectT) {
+ conn, err := mysql.Connect(t.Context(), &vtParams)
+ if !assert.NoError(c, err) {
+ return
}
- time.Sleep(sleepDuration)
- timeout = timeout - sleepDuration
- }
- require.NoError(t, fmt.Errorf("timeout in waitForMigration(%s). status is: %s", uuid, status))
- return nil
+ defer conn.Close()
+ rs, err := conn.ExecuteFetch(query, -1, true)
+ if !assert.NoError(c, err) || !assert.NotNil(c, rs) {
+ return
+ }
+ migration := rs.Named().Row()
+ if !assert.NotNil(c, migration) {
+ return
+ }
+ // The migration is complete, either successful or not.
+ status := migration["migration_status"].ToString()
+ if !assert.Contains(c, terminalStatuses, status, "migration %s is not complete", uuid) {
+ return
+ }
+ // A failing migration gets its status before its message, so wait for the message too.
+ if status == string(schema.OnlineDDLStatusFailed) && !assert.NotEmpty(c, migration["message"].ToString(), "migration %s has no failure message yet", uuid) {
+ return
+ }
+ row = migration
+ }, timeout, 100*time.Millisecond)
+ return row
}
func getTablet() *cluster.Vttablet {
diff --git a/go/vt/vttablet/onlineddl/executor.go b/go/vt/vttablet/onlineddl/executor.go
index a564b9ee793..09b3eccde32 100644
--- a/go/vt/vttablet/onlineddl/executor.go
+++ b/go/vt/vttablet/onlineddl/executor.go
@@ -1119,6 +1119,7 @@ func (e *Executor) cutOverVReplMigration(ctx context.Context, s *VReplStream, sh
}
}
+ var postWritesPos replication.Position
if isVreplicationTestSuite {
// The testing suite may inject queries internally from the server via a recurring EVENT.
// Those queries are unaffected by query rules (ACLs) because they don't go through Vitess.
@@ -1129,6 +1130,14 @@ func (e *Executor) cutOverVReplMigration(ctx context.Context, s *VReplStream, sh
if _, err := e.execQuery(ctx, renameBeforeQuery); err != nil {
return err
}
+ // No write to the table can follow the RENAME, so the position right after it covers
+ // all of them. Reading it before the stage writes below makes the position end in the
+ // RENAME itself, which VReplication saves at once, rather than in the stage writes,
+ // which reach the stream as empty transactions that it saves only after its idle
+ // timeout.
+ if postWritesPos, err = e.primaryPosition(ctx); err != nil {
+ return vterrors.Wrapf(err, "failed reading pos after renaming")
+ }
e.updateMigrationStage(ctx, onlineDDL.UUID, "test suite 'before' table renamed")
} else {
// real production
@@ -1164,12 +1173,11 @@ func (e *Executor) cutOverVReplMigration(ctx context.Context, s *VReplStream, sh
return vterrors.Wrapf(err, "failed killing table lock holders and accessors")
}
}
- }
- e.updateMigrationStage(ctx, onlineDDL.UUID, "reading post-lock pos")
- postWritesPos, err := e.primaryPosition(ctx)
- if err != nil {
- return vterrors.Wrapf(err, "failed reading pos after locking")
+ e.updateMigrationStage(ctx, onlineDDL.UUID, "reading post-lock pos")
+ if postWritesPos, err = e.primaryPosition(ctx); err != nil {
+ return vterrors.Wrapf(err, "failed reading pos after locking")
+ }
}
// Right now: new queries are buffered, any existing query will have executed, and worst case scenario is
From 7c527d0c30033a0ba473349420a9e486f9c64b68 Mon Sep 17 00:00:00 2001
From: "vitess-bot[bot]" <108069721+vitess-bot[bot]@users.noreply.github.com>
Date: Tue, 20 Oct 2026 18:20:05 +0000
Subject: [PATCH 18/31] [release-23.0] vtctldclient: register the gRPC
tabletconn dialer for --server=internal (#21661) (#21674)
Signed-off-by: Mikhail Udalov <2630842+udalmik@users.noreply.github.com>
Co-authored-by: vitess-bot[bot] <108069721+vitess-bot[bot]@users.noreply.github.com>
Co-authored-by: Mikhail Udalov <2630842+udalmik@users.noreply.github.com>
---
go/cmd/vtctldclient/plugin_grpctabletconn.go | 26 ++++++++++++++
.../plugin_grpctabletconn_test.go | 34 +++++++++++++++++++
2 files changed, 60 insertions(+)
create mode 100644 go/cmd/vtctldclient/plugin_grpctabletconn.go
create mode 100644 go/cmd/vtctldclient/plugin_grpctabletconn_test.go
diff --git a/go/cmd/vtctldclient/plugin_grpctabletconn.go b/go/cmd/vtctldclient/plugin_grpctabletconn.go
new file mode 100644
index 00000000000..a4700adb704
--- /dev/null
+++ b/go/cmd/vtctldclient/plugin_grpctabletconn.go
@@ -0,0 +1,26 @@
+/*
+Copyright 2026 The Vitess Authors.
+
+Licensed under the Apache License, Version 2.0 (the "License");
+you may not use this file except in compliance with the License.
+You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing, software
+distributed under the License is distributed on an "AS IS" BASIS,
+WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+See the License for the specific language governing permissions and
+limitations under the License.
+*/
+
+package main
+
+// Imports and registers the gRPC tabletconn client.
+// This is needed when --server=internal as some commands, such as
+// switching writes (SwitchTraffic --tablet-types primary), open
+// queryservice connections to tablets.
+
+import (
+ _ "vitess.io/vitess/go/vt/vttablet/grpctabletconn"
+)
diff --git a/go/cmd/vtctldclient/plugin_grpctabletconn_test.go b/go/cmd/vtctldclient/plugin_grpctabletconn_test.go
new file mode 100644
index 00000000000..5d6115ae9fa
--- /dev/null
+++ b/go/cmd/vtctldclient/plugin_grpctabletconn_test.go
@@ -0,0 +1,34 @@
+/*
+Copyright 2026 The Vitess Authors.
+
+Licensed under the Apache License, Version 2.0 (the "License");
+you may not use this file except in compliance with the License.
+You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing, software
+distributed under the License is distributed on an "AS IS" BASIS,
+WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+See the License for the specific language governing permissions and
+limitations under the License.
+*/
+
+package main
+
+import (
+ "testing"
+
+ "github.com/stretchr/testify/assert"
+
+ "vitess.io/vitess/go/vt/vttablet/tabletconn"
+)
+
+// TestTabletDialerRegistered checks that the binary registers a dialer for the
+// default tablet protocol, which --server=internal needs to dial tablets when
+// switching primary traffic. GetDialer exits the process instead of returning
+// nil when no dialer is registered, so without the plugin this test fails by
+// exiting.
+func TestTabletDialerRegistered(t *testing.T) {
+ assert.NotNil(t, tabletconn.GetDialer())
+}
From a026d97b35489e03914ac3c9512a2d4a4c0f4763 Mon Sep 17 00:00:00 2001
From: "vitess-bot[bot]" <108069721+vitess-bot[bot]@users.noreply.github.com>
Date: Tue, 20 Oct 2026 14:45:05 -0400
Subject: [PATCH 19/31] [release-23.0] ERS: only go on without the primary when
stopping replication (#21658) (#21671)
Signed-off-by: Arthur Schreiber
Co-authored-by: vitess-bot[bot] <108069721+vitess-bot[bot]@users.noreply.github.com>
Co-authored-by: Arthur Schreiber
Co-authored-by: Claude Opus 5.5
---
go/vt/vtctl/reparentutil/replication.go | 5 +-
go/vt/vtctl/reparentutil/replication_test.go | 184 +++++++++++++++++++
2 files changed, 188 insertions(+), 1 deletion(-)
diff --git a/go/vt/vtctl/reparentutil/replication.go b/go/vt/vtctl/reparentutil/replication.go
index a201be19bc8..e1080593cc8 100644
--- a/go/vt/vtctl/reparentutil/replication.go
+++ b/go/vt/vtctl/reparentutil/replication.go
@@ -370,7 +370,10 @@ func stopReplicationAndBuildStatusMaps(
for alias, tabletInfo := range tabletMap {
allTablets = append(allTablets, tabletInfo.Tablet)
if !ignoredTablets.Has(alias) {
- mustWaitFor := tabletAliasToWaitFor == alias
+ // Only the primary may be left behind: any other tablet may be the most
+ // advanced one, and if it's cancelled, its position is lost.
+ isPrimary := primaryAlias != nil && topoproto.TabletAliasEqual(primaryAlias, tabletInfo.Alias)
+ mustWaitFor := tabletAliasToWaitFor == alias || !isPrimary
// If this is a tablet that we must wait for
// we increment numErrorsToWaitFor and pass in this to the
// fillStatus function to indicate we must send this with the boolean
diff --git a/go/vt/vtctl/reparentutil/replication_test.go b/go/vt/vtctl/reparentutil/replication_test.go
index 44f2142126f..da8c5783d0e 100644
--- a/go/vt/vtctl/reparentutil/replication_test.go
+++ b/go/vt/vtctl/reparentutil/replication_test.go
@@ -18,7 +18,9 @@ package reparentutil
import (
"context"
+ "maps"
"os"
+ "slices"
"testing"
"time"
@@ -1395,6 +1397,188 @@ func Test_stopReplicationAndBuildStatusMaps(t *testing.T) {
}
}
+// Test_stopReplicationAndBuildStatusMaps_waitsForAllButThePrimary checks that
+// stopReplicationAndBuildStatusMaps goes on without a tablet that hasn't
+// answered only when that tablet is the shard's primary. Any other tablet that
+// is cancelled may be the most advanced one.
+func Test_stopReplicationAndBuildStatusMaps_waitsForAllButThePrimary(t *testing.T) {
+ type stopResult = struct {
+ StopStatus *replicationdatapb.StopReplicationStatus
+ Err error
+ }
+ type demoteResult = struct {
+ PrimaryStatus *replicationdatapb.PrimaryStatus
+ Err error
+ }
+ stopStatus := func(pos string) *stopResult {
+ return &stopResult{
+ StopStatus: &replicationdatapb.StopReplicationStatus{
+ Before: &replicationdatapb.Status{Position: pos, IoState: int32(replication.ReplicationStateRunning), SqlState: int32(replication.ReplicationStateRunning)},
+ After: &replicationdatapb.Status{Position: pos},
+ },
+ }
+ }
+ // notReplica is what a tablet that thinks it's the primary returns, so that
+ // it gets demoted.
+ notReplica := &stopResult{Err: vterrors.ToGRPC(vterrors.Wrap(mysql.ErrNotReplica, "before status failed"))}
+ demoted := func(pos string) *demoteResult {
+ return &demoteResult{PrimaryStatus: &replicationdatapb.PrimaryStatus{Position: pos}}
+ }
+ tabletInfo := func(uid uint32, tabletType topodatapb.TabletType) *topo.TabletInfo {
+ return &topo.TabletInfo{
+ Tablet: &topodatapb.Tablet{
+ Type: tabletType,
+ Alias: &topodatapb.TabletAlias{Cell: "zone1", Uid: uid},
+ },
+ }
+ }
+ replicas := map[string]*topo.TabletInfo{
+ "zone1-0000000101": tabletInfo(101, topodatapb.TabletType_REPLICA),
+ "zone1-0000000102": tabletInfo(102, topodatapb.TabletType_REPLICA),
+ "zone1-0000000103": tabletInfo(103, topodatapb.TabletType_REPLICA),
+ }
+ withTablets := func(tablets map[string]*topo.TabletInfo, extra ...*topo.TabletInfo) map[string]*topo.TabletInfo {
+ tabletMap := maps.Clone(tablets)
+ for _, tablet := range extra {
+ tabletMap[topoproto.TabletAliasString(tablet.Alias)] = tablet
+ }
+ return tabletMap
+ }
+ withResults := func(results map[string]*stopResult, alias string, result *stopResult) map[string]*stopResult {
+ results = maps.Clone(results)
+ results[alias] = result
+ return results
+ }
+ // zone1-0000000103 is the most advanced replica and the last one to answer.
+ slowestReplicaResults := map[string]*stopResult{
+ "zone1-0000000101": stopStatus("MySQL56/3E11FA47-71CA-11E1-9E33-C80AA9429100:1-9"),
+ "zone1-0000000102": stopStatus("MySQL56/3E11FA47-71CA-11E1-9E33-C80AA9429100:1-9"),
+ "zone1-0000000103": stopStatus("MySQL56/3E11FA47-71CA-11E1-9E33-C80AA9429100:1-10"),
+ }
+ slowestReplicaDelays := map[string]time.Duration{
+ "zone1-0000000103": 100 * time.Millisecond,
+ }
+ primaryAlias := &topodatapb.TabletAlias{Cell: "zone1", Uid: 100}
+
+ tests := []struct {
+ name string
+ tmc *stopReplicationAndBuildStatusMapsTestTMClient
+ tabletMap map[string]*topo.TabletInfo
+ primaryAlias *topodatapb.TabletAlias
+ ignoredTablets sets.Set[string]
+ expectedStatusMap []string
+ expectedPrimaryStatusMap []string
+ }{
+ {
+ name: "primary ignored",
+ tmc: &stopReplicationAndBuildStatusMapsTestTMClient{
+ stopReplicationAndGetStatusResults: slowestReplicaResults,
+ stopReplicationAndGetStatusDelays: slowestReplicaDelays,
+ },
+ tabletMap: withTablets(replicas, tabletInfo(100, topodatapb.TabletType_PRIMARY)),
+ primaryAlias: primaryAlias,
+ ignoredTablets: sets.New("zone1-0000000100"),
+ expectedStatusMap: []string{"zone1-0000000101", "zone1-0000000102", "zone1-0000000103"},
+ },
+ {
+ name: "primary not in tablet map",
+ tmc: &stopReplicationAndBuildStatusMapsTestTMClient{
+ stopReplicationAndGetStatusResults: slowestReplicaResults,
+ stopReplicationAndGetStatusDelays: slowestReplicaDelays,
+ },
+ tabletMap: replicas,
+ primaryAlias: primaryAlias,
+ ignoredTablets: sets.New[string](),
+ expectedStatusMap: []string{"zone1-0000000101", "zone1-0000000102", "zone1-0000000103"},
+ },
+ {
+ name: "no primary in the shard record",
+ tmc: &stopReplicationAndBuildStatusMapsTestTMClient{
+ stopReplicationAndGetStatusResults: slowestReplicaResults,
+ stopReplicationAndGetStatusDelays: slowestReplicaDelays,
+ },
+ tabletMap: replicas,
+ ignoredTablets: sets.New[string](),
+ expectedStatusMap: []string{"zone1-0000000101", "zone1-0000000102", "zone1-0000000103"},
+ },
+ {
+ name: "primary answers before the slowest replica",
+ tmc: &stopReplicationAndBuildStatusMapsTestTMClient{
+ demotePrimaryResults: map[string]*demoteResult{
+ "zone1-0000000100": demoted("MySQL56/3E11FA47-71CA-11E1-9E33-C80AA9429100:1-10"),
+ },
+ stopReplicationAndGetStatusResults: withResults(slowestReplicaResults, "zone1-0000000100", notReplica),
+ stopReplicationAndGetStatusDelays: slowestReplicaDelays,
+ },
+ tabletMap: withTablets(replicas, tabletInfo(100, topodatapb.TabletType_PRIMARY)),
+ primaryAlias: primaryAlias,
+ ignoredTablets: sets.New[string](),
+ expectedStatusMap: []string{"zone1-0000000101", "zone1-0000000102", "zone1-0000000103"},
+ expectedPrimaryStatusMap: []string{"zone1-0000000100"},
+ },
+ {
+ // The shard record still names zone1-0000000100, which is a replica by
+ // now. zone1-0000000103 is the actual primary and the most advanced
+ // tablet; its demotion must not be cancelled.
+ name: "stale primary in the shard record",
+ tmc: &stopReplicationAndBuildStatusMapsTestTMClient{
+ demotePrimaryResults: map[string]*demoteResult{
+ "zone1-0000000103": demoted("MySQL56/3E11FA47-71CA-11E1-9E33-C80AA9429100:1-12"),
+ },
+ demotePrimaryDelays: map[string]time.Duration{
+ "zone1-0000000103": 100 * time.Millisecond,
+ },
+ stopReplicationAndGetStatusResults: map[string]*stopResult{
+ "zone1-0000000100": stopStatus("MySQL56/3E11FA47-71CA-11E1-9E33-C80AA9429100:1-9"),
+ "zone1-0000000101": stopStatus("MySQL56/3E11FA47-71CA-11E1-9E33-C80AA9429100:1-9"),
+ "zone1-0000000102": stopStatus("MySQL56/3E11FA47-71CA-11E1-9E33-C80AA9429100:1-9"),
+ "zone1-0000000103": notReplica,
+ },
+ },
+ tabletMap: withTablets(map[string]*topo.TabletInfo{
+ "zone1-0000000101": replicas["zone1-0000000101"],
+ "zone1-0000000102": replicas["zone1-0000000102"],
+ }, tabletInfo(100, topodatapb.TabletType_REPLICA), tabletInfo(103, topodatapb.TabletType_PRIMARY)),
+ primaryAlias: primaryAlias,
+ ignoredTablets: sets.New[string](),
+ expectedStatusMap: []string{"zone1-0000000100", "zone1-0000000101", "zone1-0000000102"},
+ expectedPrimaryStatusMap: []string{"zone1-0000000103"},
+ },
+ }
+ for _, tt := range tests {
+ t.Run(tt.name, func(t *testing.T) {
+ durability, err := policy.GetDurabilityPolicy(policy.DurabilitySemiSync)
+ require.NoError(t, err)
+
+ res, err := stopReplicationAndBuildStatusMaps(t.Context(), tt.tmc, &events.Reparent{}, tt.tabletMap, tt.primaryAlias, time.Minute, tt.ignoredTablets, nil, durability, false, logutil.NewMemoryLogger())
+ require.NoError(t, err)
+ assert.ElementsMatch(t, tt.expectedStatusMap, slices.Collect(maps.Keys(res.statusMap)))
+ assert.ElementsMatch(t, tt.expectedPrimaryStatusMap, slices.Collect(maps.Keys(res.primaryStatusMap)))
+ })
+ }
+
+ t.Run("unreachable primary is not waited for", func(t *testing.T) {
+ tmc := &stopReplicationAndBuildStatusMapsTestTMClient{
+ demotePrimaryResults: map[string]*demoteResult{
+ "zone1-0000000100": demoted("MySQL56/3E11FA47-71CA-11E1-9E33-C80AA9429100:1-10"),
+ },
+ demotePrimaryDelays: map[string]time.Duration{
+ "zone1-0000000100": time.Minute,
+ },
+ stopReplicationAndGetStatusResults: withResults(slowestReplicaResults, "zone1-0000000100", notReplica),
+ }
+ durability, err := policy.GetDurabilityPolicy(policy.DurabilitySemiSync)
+ require.NoError(t, err)
+
+ start := time.Now()
+ res, err := stopReplicationAndBuildStatusMaps(t.Context(), tmc, &events.Reparent{}, withTablets(replicas, tabletInfo(100, topodatapb.TabletType_PRIMARY)), primaryAlias, time.Minute, sets.New[string](), nil, durability, false, logutil.NewMemoryLogger())
+ require.NoError(t, err)
+ assert.Less(t, time.Since(start), 30*time.Second)
+ assert.Len(t, res.statusMap, 3)
+ assert.Empty(t, res.primaryStatusMap)
+ })
+}
+
func TestReplicaWasRunning(t *testing.T) {
t.Parallel()
From 4014a3a71f618500068219f16df3b6894e36634e Mon Sep 17 00:00:00 2001
From: "vitess-bot[bot]" <108069721+vitess-bot[bot]@users.noreply.github.com>
Date: Wed, 21 Oct 2026 20:36:40 +0000
Subject: [PATCH 20/31] [release-23.0] ci: run each upgrade/downgrade version
mix in its own job (#21642) (#21680)
Signed-off-by: Arthur Schreiber
Co-authored-by: vitess-bot[bot] <108069721+vitess-bot[bot]@users.noreply.github.com>
Co-authored-by: Arthur Schreiber
Co-authored-by: Claude Opus 5.5
---
.../upgrade_downgrade_test_backups_e2e.yml | 66 ++++++++++--------
...owngrade_test_backups_e2e_next_release.yml | 66 ++++++++++--------
...e_downgrade_test_query_serving_queries.yml | 69 ++++++++++---------
...downgrade_test_query_serving_queries_2.yml | 69 ++++++++++---------
...t_query_serving_queries_2_next_release.yml | 65 +++++++++--------
...est_query_serving_queries_next_release.yml | 65 +++++++++--------
...de_downgrade_test_query_serving_schema.yml | 64 +++++++++--------
...test_query_serving_schema_next_release.yml | 64 +++++++++--------
8 files changed, 296 insertions(+), 232 deletions(-)
diff --git a/.github/workflows/upgrade_downgrade_test_backups_e2e.yml b/.github/workflows/upgrade_downgrade_test_backups_e2e.yml
index e3624093e40..022ec01eeb1 100644
--- a/.github/workflows/upgrade_downgrade_test_backups_e2e.yml
+++ b/.github/workflows/upgrade_downgrade_test_backups_e2e.yml
@@ -74,10 +74,20 @@ jobs:
# a required status check.
if: ${{ !cancelled() && (needs.changes.result != 'success' || contains(github.event.pull_request.labels.*.name, 'Skip CI') || (needs.changes.outputs.end_to_end == 'true')) }}
timeout-minutes: 60
- name: Run Upgrade Downgrade Test - Backups - E2E
+ name: Run Upgrade Downgrade Test - Backups - E2E (${{ matrix.name }})
# The large runner is only claimed when the tests will actually run; a
# failed or cancelled gate and the 'Skip CI' label only report a failure.
runs-on: ${{ needs.changes.result == 'success' && needs.changes.outputs.end_to_end == 'true' && !contains(github.event.pull_request.labels.*.name, 'Skip CI') && github.repository == 'vitessio/vitess' && 'oracle-vm-16cpu-64gb-x86-64' || 'ubuntu-24.04' }}
+ # Each version mix runs the whole suite, so the mixes run as separate
+ # jobs in parallel instead of one after the other in a single job.
+ strategy:
+ fail-fast: false
+ matrix:
+ include:
+ - name: vttablet=N-1, vtbackup=N
+ other_version_binaries: vttablet mysqlctl mysqlctld
+ - name: vttablet=N, vtbackup=N-1
+ other_version_binaries: vtbackup
steps:
- name: Skip CI
@@ -168,19 +178,22 @@ jobs:
mkdir -p /tmp/vitess-build-current/
cp -R bin /tmp/vitess-build-current/
- # Swap binaries, use last release's VTTablet
- - name: Use last release's VTTablet
+ # Start from this commit's binaries, then swap in the other version's
+ # binaries for this matrix entry's version mix.
+ - name: Use the other version's ${{ matrix.other_version_binaries }}
+ env:
+ OTHER_VERSION_BINARIES: ${{ matrix.other_version_binaries }}
run: |
source build.env
- rm -f $PWD/bin/vttablet $PWD/bin/mysqlctl $PWD/bin/mysqlctld
- cp /tmp/vitess-build-other/bin/vttablet $PWD/bin/vttablet
- cp /tmp/vitess-build-other/bin/mysqlctl $PWD/bin/mysqlctl
- cp /tmp/vitess-build-other/bin/mysqlctld $PWD/bin/mysqlctld
+ cp -r /tmp/vitess-build-current/bin/* $PWD/bin/
+ for binary in $OTHER_VERSION_BINARIES; do
+ cp "/tmp/vitess-build-other/bin/$binary" "$PWD/bin/$binary"
+ done
vttablet --version
+ vtbackup --version
- # Run test with VTTablet at version N-1 and VTBackup at version N
- - name: Run backups tests (vttablet=N-1, vtbackup=N)
+ - name: Run backups tests (${{ matrix.name }})
run: |
rm -rf /tmp/vtdataroot
mkdir -p /tmp/vtdataroot
@@ -188,24 +201,19 @@ jobs:
source build.env
go run test.go -skip-build -docker=false -print-log -follow -tag upgrade_downgrade_backups
- # Swap binaries again, use current version's VTTablet, and last release's VTBackup
- - name: Use current version VTTablet, and other version VTBackup
- run: |
- source build.env
-
- rm -f $PWD/bin/vtbackup $PWD/bin/vttablet $PWD/bin/mysqlctl $PWD/bin/mysqlctld
- cp /tmp/vitess-build-current/bin/vtbackup $PWD/bin/vtbackup
- cp /tmp/vitess-build-other/bin/vttablet $PWD/bin/vttablet
- cp /tmp/vitess-build-other/bin/mysqlctl $PWD/bin/mysqlctl
- cp /tmp/vitess-build-other/bin/mysqlctld $PWD/bin/mysqlctld
- vtbackup --version
- vttablet --version
-
- # Run test again with VTTablet at version N, and VTBackup at version N-1
- - name: Run backups tests (vttablet=N, vtbackup=N-1)
+ # The required status check is the name the single job had, so this job
+ # keeps it. It passes only when every version mix passed, or when they were
+ # skipped because nothing relevant changed.
+ upgrade_downgrade_test_e2e_result:
+ needs: upgrade_downgrade_test_e2e
+ if: ${{ !cancelled() }}
+ name: Run Upgrade Downgrade Test - Backups - E2E
+ runs-on: ubuntu-24.04
+ timeout-minutes: 5
+ steps:
+ - name: Check the result of every version mix
+ env:
+ RESULT: ${{ needs.upgrade_downgrade_test_e2e.result }}
run: |
- rm -rf /tmp/vtdataroot
- mkdir -p /tmp/vtdataroot
- set -x
- source build.env
- go run test.go -skip-build -keep-data -docker=false -print-log -follow -tag upgrade_downgrade_backups
+ echo "upgrade_downgrade_test_e2e: $RESULT"
+ [[ "$RESULT" == "success" || "$RESULT" == "skipped" ]]
diff --git a/.github/workflows/upgrade_downgrade_test_backups_e2e_next_release.yml b/.github/workflows/upgrade_downgrade_test_backups_e2e_next_release.yml
index 37d34c227e0..982e99e6f9c 100644
--- a/.github/workflows/upgrade_downgrade_test_backups_e2e_next_release.yml
+++ b/.github/workflows/upgrade_downgrade_test_backups_e2e_next_release.yml
@@ -75,10 +75,20 @@ jobs:
# a required status check.
if: ${{ !cancelled() && (needs.changes.result != 'success' || contains(github.event.pull_request.labels.*.name, 'Skip CI') || (needs.changes.outputs.end_to_end == 'true' && needs.changes.outputs.next_release_ref != '')) }}
timeout-minutes: 60
- name: Run Upgrade Downgrade Test - Backups - E2E - Next Release
+ name: Run Upgrade Downgrade Test - Backups - E2E - Next Release (${{ matrix.name }})
# The large runner is only claimed when the tests will actually run; a
# failed or cancelled gate and the 'Skip CI' label only report a failure.
runs-on: ${{ needs.changes.result == 'success' && needs.changes.outputs.end_to_end == 'true' && !contains(github.event.pull_request.labels.*.name, 'Skip CI') && github.repository == 'vitessio/vitess' && 'oracle-vm-16cpu-64gb-x86-64' || 'ubuntu-24.04' }}
+ # Each version mix runs the whole suite, so the mixes run as separate
+ # jobs in parallel instead of one after the other in a single job.
+ strategy:
+ fail-fast: false
+ matrix:
+ include:
+ - name: vttablet=N+1, vtbackup=N
+ other_version_binaries: vttablet mysqlctl mysqlctld
+ - name: vttablet=N, vtbackup=N+1
+ other_version_binaries: vtbackup
steps:
- name: Skip CI
@@ -169,19 +179,22 @@ jobs:
mkdir -p /tmp/vitess-build-current/
cp -R bin /tmp/vitess-build-current/
- # Swap binaries, use next release's VTTablet
- - name: Use next release's VTTablet
+ # Start from this commit's binaries, then swap in the other version's
+ # binaries for this matrix entry's version mix.
+ - name: Use the other version's ${{ matrix.other_version_binaries }}
+ env:
+ OTHER_VERSION_BINARIES: ${{ matrix.other_version_binaries }}
run: |
source build.env
- rm -f $PWD/bin/vttablet $PWD/bin/mysqlctl $PWD/bin/mysqlctld
- cp /tmp/vitess-build-other/bin/vttablet $PWD/bin/vttablet
- cp /tmp/vitess-build-other/bin/mysqlctl $PWD/bin/mysqlctl
- cp /tmp/vitess-build-other/bin/mysqlctld $PWD/bin/mysqlctld
+ cp -r /tmp/vitess-build-current/bin/* $PWD/bin/
+ for binary in $OTHER_VERSION_BINARIES; do
+ cp "/tmp/vitess-build-other/bin/$binary" "$PWD/bin/$binary"
+ done
vttablet --version
+ vtbackup --version
- # Run test with VTTablet at version N+1 and VTBackup at version N
- - name: Run backups tests (vttablet=N+1, vtbackup=N)
+ - name: Run backups tests (${{ matrix.name }})
run: |
rm -rf /tmp/vtdataroot
mkdir -p /tmp/vtdataroot
@@ -189,24 +202,19 @@ jobs:
source build.env
go run test.go -skip-build -docker=false -print-log -follow -tag upgrade_downgrade_backups
- # Swap binaries again, use current version's VTTablet, and next release's VTBackup
- - name: Use current version VTTablet, and other version VTBackup
- run: |
- source build.env
-
- rm -f $PWD/bin/vtbackup $PWD/bin/vttablet $PWD/bin/mysqlctl $PWD/bin/mysqlctld
- cp /tmp/vitess-build-other/bin/vtbackup $PWD/bin/vtbackup
- cp /tmp/vitess-build-current/bin/vttablet $PWD/bin/vttablet
- cp /tmp/vitess-build-current/bin/mysqlctl $PWD/bin/mysqlctl
- cp /tmp/vitess-build-current/bin/mysqlctld $PWD/bin/mysqlctld
- vtbackup --version
- vttablet --version
-
- # Run test again with VTTablet at version N, and VTBackup at version N+1
- - name: Run backups tests (vttablet=N, vtbackup=N+1)
+ # The required status check is the name the single job had, so this job
+ # keeps it. It passes only when every version mix passed, or when they were
+ # skipped because nothing relevant changed.
+ upgrade_downgrade_test_e2e_result:
+ needs: upgrade_downgrade_test_e2e
+ if: ${{ !cancelled() }}
+ name: Run Upgrade Downgrade Test - Backups - E2E - Next Release
+ runs-on: ubuntu-24.04
+ timeout-minutes: 5
+ steps:
+ - name: Check the result of every version mix
+ env:
+ RESULT: ${{ needs.upgrade_downgrade_test_e2e.result }}
run: |
- rm -rf /tmp/vtdataroot
- mkdir -p /tmp/vtdataroot
- set -x
- source build.env
- go run test.go -skip-build -keep-data -docker=false -print-log -follow -tag upgrade_downgrade_backups
+ echo "upgrade_downgrade_test_e2e: $RESULT"
+ [[ "$RESULT" == "success" || "$RESULT" == "skipped" ]]
diff --git a/.github/workflows/upgrade_downgrade_test_query_serving_queries.yml b/.github/workflows/upgrade_downgrade_test_query_serving_queries.yml
index 3c0f59c3f2e..e26c60ea3db 100644
--- a/.github/workflows/upgrade_downgrade_test_query_serving_queries.yml
+++ b/.github/workflows/upgrade_downgrade_test_query_serving_queries.yml
@@ -78,10 +78,20 @@ jobs:
# a required status check.
if: ${{ !cancelled() && (needs.changes.result != 'success' || contains(github.event.pull_request.labels.*.name, 'Skip CI') || (needs.changes.outputs.end_to_end == 'true')) }}
timeout-minutes: 60
- name: Run Upgrade Downgrade Test - Query Serving (Queries)
+ name: Run Upgrade Downgrade Test - Query Serving (Queries) (${{ matrix.name }})
# The large runner is only claimed when the tests will actually run; a
# failed or cancelled gate and the 'Skip CI' label only report a failure.
runs-on: ${{ needs.changes.result == 'success' && needs.changes.outputs.end_to_end == 'true' && !contains(github.event.pull_request.labels.*.name, 'Skip CI') && github.repository == 'vitessio/vitess' && 'oracle-vm-16cpu-64gb-x86-64' || 'ubuntu-24.04' }}
+ # Each version mix runs the whole suite, so the mixes run as separate
+ # jobs in parallel instead of one after the other in a single job.
+ strategy:
+ fail-fast: false
+ matrix:
+ include:
+ - name: vtgate=N-1, vttablet=N, vtctld=N
+ other_version_binaries: vtgate
+ - name: vtgate=N, vttablet=N-1, vtctld=N-1
+ other_version_binaries: vttablet mysqlctl mysqlctld vtctld vtctldclient vtctl vtctlclient
steps:
- name: Skip CI
@@ -165,18 +175,22 @@ jobs:
find ./go/test/endtoend -name '*.go' -exec sed -i 's/ErrorContains/Error/g' {} +
find ./go/test/endtoend -name '*.go' -exec sed -i 's/EqualError/Error/g' {} +
- # Swap the binaries in the bin. Use vtgate version n-1 and keep vttablet at version n
- - name: Use last release's VTGate
+ # Start from this commit's binaries, then swap in the other version's
+ # binaries for this matrix entry's version mix.
+ - name: Use the other version's ${{ matrix.other_version_binaries }}
+ env:
+ OTHER_VERSION_BINARIES: ${{ matrix.other_version_binaries }}
run: |
source build.env
cp -r /tmp/vitess-build-current/bin/* $PWD/bin/
- rm -f $PWD/bin/vtgate
- cp /tmp/vitess-build-other/bin/vtgate $PWD/bin/vtgate
+ for binary in $OTHER_VERSION_BINARIES; do
+ cp "/tmp/vitess-build-other/bin/$binary" "$PWD/bin/$binary"
+ done
vtgate --version
+ vttablet --version
- # Running a test with vtgate at version n-1 and vttablet/vtctld at version n
- - name: Run query serving tests (vtgate=N-1, vttablet=N, vtctld=N)
+ - name: Run query serving tests (${{ matrix.name }})
run: |
rm -rf /tmp/vtdataroot
mkdir -p /tmp/vtdataroot
@@ -184,30 +198,19 @@ jobs:
source build.env
go run test.go -skip-build -keep-data=false -docker=false -print-log -follow -tag upgrade_downgrade_query_serving_queries
- # Swap the binaries again. This time, vtgate will be at version n, and vttablet/vtctld will be at version n-1
- - name: Use current version VTGate, and other version VTTablet/VTctld
- run: |
- source build.env
-
- rm -f $PWD/bin/vtgate $PWD/bin/vttablet $PWD/bin/mysqlctl $PWD/bin/mysqlctld
- cp /tmp/vitess-build-current/bin/vtgate $PWD/bin/vtgate
-
- cp /tmp/vitess-build-other/bin/vtctld $PWD/bin
- cp /tmp/vitess-build-other/bin/vtctldclient $PWD/bin
- cp /tmp/vitess-build-other/bin/vtctl $PWD/bin
- cp /tmp/vitess-build-other/bin/vtctlclient $PWD/bin
-
- cp /tmp/vitess-build-other/bin/vttablet $PWD/bin/vttablet
- cp /tmp/vitess-build-other/bin/mysqlctl $PWD/bin/mysqlctl
- cp /tmp/vitess-build-other/bin/mysqlctld $PWD/bin/mysqlctld
- vtgate --version
- vttablet --version
-
- # Running a test with vtgate at version n and vttablet/vtctld at version n-1
- - name: Run query serving tests (vtgate=N, vttablet=N-1, vtctld=N-1)
+ # The required status check is the name the single job had, so this job
+ # keeps it. It passes only when every version mix passed, or when they were
+ # skipped because nothing relevant changed.
+ upgrade_downgrade_test_result:
+ needs: upgrade_downgrade_test
+ if: ${{ !cancelled() }}
+ name: Run Upgrade Downgrade Test - Query Serving (Queries)
+ runs-on: ubuntu-24.04
+ timeout-minutes: 5
+ steps:
+ - name: Check the result of every version mix
+ env:
+ RESULT: ${{ needs.upgrade_downgrade_test.result }}
run: |
- rm -rf /tmp/vtdataroot
- mkdir -p /tmp/vtdataroot
-
- source build.env
- go run test.go -skip-build -keep-data=false -docker=false -print-log -follow -tag upgrade_downgrade_query_serving_queries
+ echo "upgrade_downgrade_test: $RESULT"
+ [[ "$RESULT" == "success" || "$RESULT" == "skipped" ]]
diff --git a/.github/workflows/upgrade_downgrade_test_query_serving_queries_2.yml b/.github/workflows/upgrade_downgrade_test_query_serving_queries_2.yml
index dc57b577b71..18778e58943 100644
--- a/.github/workflows/upgrade_downgrade_test_query_serving_queries_2.yml
+++ b/.github/workflows/upgrade_downgrade_test_query_serving_queries_2.yml
@@ -77,10 +77,20 @@ jobs:
# a required status check.
if: ${{ !cancelled() && (needs.changes.result != 'success' || contains(github.event.pull_request.labels.*.name, 'Skip CI') || (needs.changes.outputs.end_to_end == 'true')) }}
timeout-minutes: 60
- name: Run Upgrade Downgrade Test - Query Serving (Queries - 2)
+ name: Run Upgrade Downgrade Test - Query Serving (Queries - 2) (${{ matrix.name }})
# The large runner is only claimed when the tests will actually run; a
# failed or cancelled gate and the 'Skip CI' label only report a failure.
runs-on: ${{ needs.changes.result == 'success' && needs.changes.outputs.end_to_end == 'true' && !contains(github.event.pull_request.labels.*.name, 'Skip CI') && github.repository == 'vitessio/vitess' && 'oracle-vm-16cpu-64gb-x86-64' || 'ubuntu-24.04' }}
+ # Each version mix runs the whole suite, so the mixes run as separate
+ # jobs in parallel instead of one after the other in a single job.
+ strategy:
+ fail-fast: false
+ matrix:
+ include:
+ - name: vtgate=N-1, vttablet=N, vtctld=N
+ other_version_binaries: vtgate
+ - name: vtgate=N, vttablet=N-1, vtctld=N-1
+ other_version_binaries: vttablet mysqlctl mysqlctld vtctld vtctldclient vtctl vtctlclient
steps:
- name: Skip CI
@@ -164,18 +174,22 @@ jobs:
find ./go/test/endtoend -name '*.go' -exec sed -i 's/ErrorContains/Error/g' {} +
find ./go/test/endtoend -name '*.go' -exec sed -i 's/EqualError/Error/g' {} +
- # Swap the binaries in the bin. Use vtgate version n-1 and keep vttablet at version n
- - name: Use last release's VTGate
+ # Start from this commit's binaries, then swap in the other version's
+ # binaries for this matrix entry's version mix.
+ - name: Use the other version's ${{ matrix.other_version_binaries }}
+ env:
+ OTHER_VERSION_BINARIES: ${{ matrix.other_version_binaries }}
run: |
source build.env
cp -r /tmp/vitess-build-current/bin/* $PWD/bin/
- rm -f $PWD/bin/vtgate
- cp /tmp/vitess-build-other/bin/vtgate $PWD/bin/vtgate
+ for binary in $OTHER_VERSION_BINARIES; do
+ cp "/tmp/vitess-build-other/bin/$binary" "$PWD/bin/$binary"
+ done
vtgate --version
+ vttablet --version
- # Running a test with vtgate at version n-1 and vttablet/vtctld at version n
- - name: Run query serving tests (vtgate=N-1, vttablet=N, vtctld=N)
+ - name: Run query serving tests (${{ matrix.name }})
run: |
rm -rf /tmp/vtdataroot
mkdir -p /tmp/vtdataroot
@@ -183,30 +197,19 @@ jobs:
source build.env
go run test.go -skip-build -keep-data=false -docker=false -print-log -follow -tag upgrade_downgrade_query_serving_queries_2
- # Swap the binaries again. This time, vtgate will be at version n, and vttablet/vtctld will be at version n-1
- - name: Use current version VTGate, and other version VTTablet/VTctld
- run: |
- source build.env
-
- rm -f $PWD/bin/vtgate $PWD/bin/vttablet $PWD/bin/mysqlctl $PWD/bin/mysqlctld
- cp /tmp/vitess-build-current/bin/vtgate $PWD/bin/vtgate
-
- cp /tmp/vitess-build-other/bin/vtctld $PWD/bin
- cp /tmp/vitess-build-other/bin/vtctldclient $PWD/bin
- cp /tmp/vitess-build-other/bin/vtctl $PWD/bin
- cp /tmp/vitess-build-other/bin/vtctlclient $PWD/bin
-
- cp /tmp/vitess-build-other/bin/vttablet $PWD/bin/vttablet
- cp /tmp/vitess-build-other/bin/mysqlctl $PWD/bin/mysqlctl
- cp /tmp/vitess-build-other/bin/mysqlctld $PWD/bin/mysqlctld
- vtgate --version
- vttablet --version
-
- # Running a test with vtgate at version n and vttablet/vtctld at version n-1
- - name: Run query serving tests (vtgate=N, vttablet=N-1, vtctld=N-1)
+ # The required status check is the name the single job had, so this job
+ # keeps it. It passes only when every version mix passed, or when they were
+ # skipped because nothing relevant changed.
+ upgrade_downgrade_test_result:
+ needs: upgrade_downgrade_test
+ if: ${{ !cancelled() }}
+ name: Run Upgrade Downgrade Test - Query Serving (Queries - 2)
+ runs-on: ubuntu-24.04
+ timeout-minutes: 5
+ steps:
+ - name: Check the result of every version mix
+ env:
+ RESULT: ${{ needs.upgrade_downgrade_test.result }}
run: |
- rm -rf /tmp/vtdataroot
- mkdir -p /tmp/vtdataroot
-
- source build.env
- go run test.go -skip-build -keep-data=false -docker=false -print-log -follow -tag upgrade_downgrade_query_serving_queries_2
+ echo "upgrade_downgrade_test: $RESULT"
+ [[ "$RESULT" == "success" || "$RESULT" == "skipped" ]]
diff --git a/.github/workflows/upgrade_downgrade_test_query_serving_queries_2_next_release.yml b/.github/workflows/upgrade_downgrade_test_query_serving_queries_2_next_release.yml
index baf2f3d4990..9fb67bb080e 100644
--- a/.github/workflows/upgrade_downgrade_test_query_serving_queries_2_next_release.yml
+++ b/.github/workflows/upgrade_downgrade_test_query_serving_queries_2_next_release.yml
@@ -78,10 +78,20 @@ jobs:
# a required status check.
if: ${{ !cancelled() && (needs.changes.result != 'success' || contains(github.event.pull_request.labels.*.name, 'Skip CI') || (needs.changes.outputs.end_to_end == 'true' && needs.changes.outputs.next_release_ref != '')) }}
timeout-minutes: 60
- name: Run Upgrade Downgrade Test - Query Serving (Queries - 2) Next Release
+ name: Run Upgrade Downgrade Test - Query Serving (Queries - 2) Next Release (${{ matrix.name }})
# The large runner is only claimed when the tests will actually run; a
# failed or cancelled gate and the 'Skip CI' label only report a failure.
runs-on: ${{ needs.changes.result == 'success' && needs.changes.outputs.end_to_end == 'true' && !contains(github.event.pull_request.labels.*.name, 'Skip CI') && github.repository == 'vitessio/vitess' && 'oracle-vm-16cpu-64gb-x86-64' || 'ubuntu-24.04' }}
+ # Each version mix runs the whole suite, so the mixes run as separate
+ # jobs in parallel instead of one after the other in a single job.
+ strategy:
+ fail-fast: false
+ matrix:
+ include:
+ - name: vtgate=N+1, vttablet=N
+ other_version_binaries: vtgate
+ - name: vtgate=N, vttablet=N+1
+ other_version_binaries: vttablet mysqlctl mysqlctld
steps:
- name: Skip CI
@@ -169,41 +179,42 @@ jobs:
find ./go/test/endtoend -name '*.go' -exec sed -i 's/ErrorContains/Error/g' {} +
find ./go/test/endtoend -name '*.go' -exec sed -i 's/EqualError/Error/g' {} +
- # Swap the binaries in the bin. Use vtgate version n+1 and keep vttablet at version n
- - name: Use next release's VTGate
- run: |
- source build.env
- rm -f $PWD/bin/vtgate
- cp /tmp/vitess-build-other/bin/vtgate $PWD/bin/vtgate
- vtgate --version
-
- # Running a test with vtgate at version n+1 and vttablet at version n
- - name: Run query serving tests (vtgate=N+1, vttablet=N)
- run: |
- rm -rf /tmp/vtdataroot
- mkdir -p /tmp/vtdataroot
-
- source build.env
- go run test.go -skip-build -keep-data=false -docker=false -print-log -follow -tag upgrade_downgrade_query_serving_queries_2
-
- # Swap the binaries again. This time, vtgate will be at version n, and vttablet will be at version n+1
- - name: Use current version VTGate, and other version VTTablet
+ # Start from this commit's binaries, then swap in the other version's
+ # binaries for this matrix entry's version mix.
+ - name: Use the other version's ${{ matrix.other_version_binaries }}
+ env:
+ OTHER_VERSION_BINARIES: ${{ matrix.other_version_binaries }}
run: |
source build.env
- rm -f $PWD/bin/vtgate $PWD/bin/vttablet $PWD/bin/mysqlctl $PWD/bin/mysqlctld
- cp /tmp/vitess-build-current/bin/vtgate $PWD/bin/vtgate
- cp /tmp/vitess-build-other/bin/vttablet $PWD/bin/vttablet
- cp /tmp/vitess-build-other/bin/mysqlctl $PWD/bin/mysqlctl
- cp /tmp/vitess-build-other/bin/mysqlctld $PWD/bin/mysqlctld
+ cp -r /tmp/vitess-build-current/bin/* $PWD/bin/
+ for binary in $OTHER_VERSION_BINARIES; do
+ cp "/tmp/vitess-build-other/bin/$binary" "$PWD/bin/$binary"
+ done
vtgate --version
vttablet --version
- # Running a test with vtgate at version n and vttablet at version n+1
- - name: Run query serving tests (vtgate=N, vttablet=N+1)
+ - name: Run query serving tests (${{ matrix.name }})
run: |
rm -rf /tmp/vtdataroot
mkdir -p /tmp/vtdataroot
source build.env
go run test.go -skip-build -keep-data=false -docker=false -print-log -follow -tag upgrade_downgrade_query_serving_queries_2
+
+ # The required status check is the name the single job had, so this job
+ # keeps it. It passes only when every version mix passed, or when they were
+ # skipped because nothing relevant changed.
+ upgrade_downgrade_test_result:
+ needs: upgrade_downgrade_test
+ if: ${{ !cancelled() }}
+ name: Run Upgrade Downgrade Test - Query Serving (Queries - 2) Next Release
+ runs-on: ubuntu-24.04
+ timeout-minutes: 5
+ steps:
+ - name: Check the result of every version mix
+ env:
+ RESULT: ${{ needs.upgrade_downgrade_test.result }}
+ run: |
+ echo "upgrade_downgrade_test: $RESULT"
+ [[ "$RESULT" == "success" || "$RESULT" == "skipped" ]]
diff --git a/.github/workflows/upgrade_downgrade_test_query_serving_queries_next_release.yml b/.github/workflows/upgrade_downgrade_test_query_serving_queries_next_release.yml
index 41cab616751..37c75efddd5 100644
--- a/.github/workflows/upgrade_downgrade_test_query_serving_queries_next_release.yml
+++ b/.github/workflows/upgrade_downgrade_test_query_serving_queries_next_release.yml
@@ -78,10 +78,20 @@ jobs:
# a required status check.
if: ${{ !cancelled() && (needs.changes.result != 'success' || contains(github.event.pull_request.labels.*.name, 'Skip CI') || (needs.changes.outputs.end_to_end == 'true' && needs.changes.outputs.next_release_ref != '')) }}
timeout-minutes: 60
- name: Run Upgrade Downgrade Test - Query Serving (Queries) Next Release
+ name: Run Upgrade Downgrade Test - Query Serving (Queries) Next Release (${{ matrix.name }})
# The large runner is only claimed when the tests will actually run; a
# failed or cancelled gate and the 'Skip CI' label only report a failure.
runs-on: ${{ needs.changes.result == 'success' && needs.changes.outputs.end_to_end == 'true' && !contains(github.event.pull_request.labels.*.name, 'Skip CI') && github.repository == 'vitessio/vitess' && 'oracle-vm-16cpu-64gb-x86-64' || 'ubuntu-24.04' }}
+ # Each version mix runs the whole suite, so the mixes run as separate
+ # jobs in parallel instead of one after the other in a single job.
+ strategy:
+ fail-fast: false
+ matrix:
+ include:
+ - name: vtgate=N+1, vttablet=N
+ other_version_binaries: vtgate
+ - name: vtgate=N, vttablet=N+1
+ other_version_binaries: vttablet mysqlctl mysqlctld
steps:
- name: Skip CI
@@ -169,41 +179,42 @@ jobs:
find ./go/test/endtoend -name '*.go' -exec sed -i 's/ErrorContains/Error/g' {} +
find ./go/test/endtoend -name '*.go' -exec sed -i 's/EqualError/Error/g' {} +
- # Swap the binaries in the bin. Use vtgate version n+1 and keep vttablet at version n
- - name: Use next release's VTGate
- run: |
- source build.env
- rm -f $PWD/bin/vtgate
- cp /tmp/vitess-build-other/bin/vtgate $PWD/bin/vtgate
- vtgate --version
-
- # Running a test with vtgate at version n+1 and vttablet at version n
- - name: Run query serving tests (vtgate=N+1, vttablet=N)
- run: |
- rm -rf /tmp/vtdataroot
- mkdir -p /tmp/vtdataroot
-
- source build.env
- go run test.go -skip-build -keep-data=false -docker=false -print-log -follow -tag upgrade_downgrade_query_serving_queries
-
- # Swap the binaries again. This time, vtgate will be at version n, and vttablet will be at version n+1
- - name: Use current version VTGate, and other version VTTablet
+ # Start from this commit's binaries, then swap in the other version's
+ # binaries for this matrix entry's version mix.
+ - name: Use the other version's ${{ matrix.other_version_binaries }}
+ env:
+ OTHER_VERSION_BINARIES: ${{ matrix.other_version_binaries }}
run: |
source build.env
- rm -f $PWD/bin/vtgate $PWD/bin/vttablet $PWD/bin/mysqlctl $PWD/bin/mysqlctld
- cp /tmp/vitess-build-current/bin/vtgate $PWD/bin/vtgate
- cp /tmp/vitess-build-other/bin/vttablet $PWD/bin/vttablet
- cp /tmp/vitess-build-other/bin/mysqlctl $PWD/bin/mysqlctl
- cp /tmp/vitess-build-other/bin/mysqlctld $PWD/bin/mysqlctld
+ cp -r /tmp/vitess-build-current/bin/* $PWD/bin/
+ for binary in $OTHER_VERSION_BINARIES; do
+ cp "/tmp/vitess-build-other/bin/$binary" "$PWD/bin/$binary"
+ done
vtgate --version
vttablet --version
- # Running a test with vtgate at version n and vttablet at version n+1
- - name: Run query serving tests (vtgate=N, vttablet=N+1)
+ - name: Run query serving tests (${{ matrix.name }})
run: |
rm -rf /tmp/vtdataroot
mkdir -p /tmp/vtdataroot
source build.env
go run test.go -skip-build -keep-data=false -docker=false -print-log -follow -tag upgrade_downgrade_query_serving_queries
+
+ # The required status check is the name the single job had, so this job
+ # keeps it. It passes only when every version mix passed, or when they were
+ # skipped because nothing relevant changed.
+ upgrade_downgrade_test_result:
+ needs: upgrade_downgrade_test
+ if: ${{ !cancelled() }}
+ name: Run Upgrade Downgrade Test - Query Serving (Queries) Next Release
+ runs-on: ubuntu-24.04
+ timeout-minutes: 5
+ steps:
+ - name: Check the result of every version mix
+ env:
+ RESULT: ${{ needs.upgrade_downgrade_test.result }}
+ run: |
+ echo "upgrade_downgrade_test: $RESULT"
+ [[ "$RESULT" == "success" || "$RESULT" == "skipped" ]]
diff --git a/.github/workflows/upgrade_downgrade_test_query_serving_schema.yml b/.github/workflows/upgrade_downgrade_test_query_serving_schema.yml
index 86a82a3771d..ed7fa251a21 100644
--- a/.github/workflows/upgrade_downgrade_test_query_serving_schema.yml
+++ b/.github/workflows/upgrade_downgrade_test_query_serving_schema.yml
@@ -78,10 +78,20 @@ jobs:
# a required status check.
if: ${{ !cancelled() && (needs.changes.result != 'success' || contains(github.event.pull_request.labels.*.name, 'Skip CI') || (needs.changes.outputs.end_to_end == 'true')) }}
timeout-minutes: 60
- name: Run Upgrade Downgrade Test - Query Serving (Schema)
+ name: Run Upgrade Downgrade Test - Query Serving (Schema) (${{ matrix.name }})
# The large runner is only claimed when the tests will actually run; a
# failed or cancelled gate and the 'Skip CI' label only report a failure.
runs-on: ${{ needs.changes.result == 'success' && needs.changes.outputs.end_to_end == 'true' && !contains(github.event.pull_request.labels.*.name, 'Skip CI') && github.repository == 'vitessio/vitess' && 'oracle-vm-16cpu-64gb-x86-64' || 'ubuntu-24.04' }}
+ # Each version mix runs the whole suite, so the mixes run as separate
+ # jobs in parallel instead of one after the other in a single job.
+ strategy:
+ fail-fast: false
+ matrix:
+ include:
+ - name: vtgate=N-1, vttablet=N
+ other_version_binaries: vtgate
+ - name: vtgate=N, vttablet=N-1
+ other_version_binaries: vttablet mysqlctl mysqlctld
steps:
- name: Skip CI
@@ -169,17 +179,22 @@ jobs:
find ./go/test/endtoend -name '*.go' -exec sed -i 's/ErrorContains/Error/g' {} +
find ./go/test/endtoend -name '*.go' -exec sed -i 's/EqualError/Error/g' {} +
- # Swap the binaries in the bin. Use vtgate version n-1 and keep vttablet at version n
- - name: Use last release's VTGate
+ # Start from this commit's binaries, then swap in the other version's
+ # binaries for this matrix entry's version mix.
+ - name: Use the other version's ${{ matrix.other_version_binaries }}
+ env:
+ OTHER_VERSION_BINARIES: ${{ matrix.other_version_binaries }}
run: |
source build.env
- rm -f $PWD/bin/vtgate
- cp /tmp/vitess-build-other/bin/vtgate $PWD/bin/vtgate
+ cp -r /tmp/vitess-build-current/bin/* $PWD/bin/
+ for binary in $OTHER_VERSION_BINARIES; do
+ cp "/tmp/vitess-build-other/bin/$binary" "$PWD/bin/$binary"
+ done
vtgate --version
+ vttablet --version
- # Running a test with vtgate at version n-1 and vttablet at version n
- - name: Run query serving tests (vtgate=N-1, vttablet=N)
+ - name: Run query serving tests (${{ matrix.name }})
run: |
rm -rf /tmp/vtdataroot
mkdir -p /tmp/vtdataroot
@@ -187,24 +202,19 @@ jobs:
source build.env
go run test.go -skip-build -keep-data=false -docker=false -print-log -follow -tag upgrade_downgrade_query_serving_schema
- # Swap the binaries again. This time, vtgate will be at version n, and vttablet will be at version n-1
- - name: Use current version VTGate, and other version VTTablet
- run: |
- source build.env
-
- rm -f $PWD/bin/vtgate $PWD/bin/vttablet $PWD/bin/mysqlctl $PWD/bin/mysqlctld
- cp /tmp/vitess-build-current/bin/vtgate $PWD/bin/vtgate
- cp /tmp/vitess-build-other/bin/vttablet $PWD/bin/vttablet
- cp /tmp/vitess-build-other/bin/mysqlctl $PWD/bin/mysqlctl
- cp /tmp/vitess-build-other/bin/mysqlctld $PWD/bin/mysqlctld
- vtgate --version
- vttablet --version
-
- # Running a test with vtgate at version n and vttablet at version n-1
- - name: Run query serving tests (vtgate=N, vttablet=N-1)
+ # The required status check is the name the single job had, so this job
+ # keeps it. It passes only when every version mix passed, or when they were
+ # skipped because nothing relevant changed.
+ upgrade_downgrade_test_result:
+ needs: upgrade_downgrade_test
+ if: ${{ !cancelled() }}
+ name: Run Upgrade Downgrade Test - Query Serving (Schema)
+ runs-on: ubuntu-24.04
+ timeout-minutes: 5
+ steps:
+ - name: Check the result of every version mix
+ env:
+ RESULT: ${{ needs.upgrade_downgrade_test.result }}
run: |
- rm -rf /tmp/vtdataroot
- mkdir -p /tmp/vtdataroot
-
- source build.env
- go run test.go -skip-build -keep-data=false -docker=false -print-log -follow -tag upgrade_downgrade_query_serving_schema
+ echo "upgrade_downgrade_test: $RESULT"
+ [[ "$RESULT" == "success" || "$RESULT" == "skipped" ]]
diff --git a/.github/workflows/upgrade_downgrade_test_query_serving_schema_next_release.yml b/.github/workflows/upgrade_downgrade_test_query_serving_schema_next_release.yml
index 54a31dd4081..25cd16d1e56 100644
--- a/.github/workflows/upgrade_downgrade_test_query_serving_schema_next_release.yml
+++ b/.github/workflows/upgrade_downgrade_test_query_serving_schema_next_release.yml
@@ -78,10 +78,20 @@ jobs:
# a required status check.
if: ${{ !cancelled() && (needs.changes.result != 'success' || contains(github.event.pull_request.labels.*.name, 'Skip CI') || (needs.changes.outputs.end_to_end == 'true' && needs.changes.outputs.next_release_ref != '')) }}
timeout-minutes: 60
- name: Run Upgrade Downgrade Test - Query Serving (Schema) Next Release
+ name: Run Upgrade Downgrade Test - Query Serving (Schema) Next Release (${{ matrix.name }})
# The large runner is only claimed when the tests will actually run; a
# failed or cancelled gate and the 'Skip CI' label only report a failure.
runs-on: ${{ needs.changes.result == 'success' && needs.changes.outputs.end_to_end == 'true' && !contains(github.event.pull_request.labels.*.name, 'Skip CI') && github.repository == 'vitessio/vitess' && 'oracle-vm-16cpu-64gb-x86-64' || 'ubuntu-24.04' }}
+ # Each version mix runs the whole suite, so the mixes run as separate
+ # jobs in parallel instead of one after the other in a single job.
+ strategy:
+ fail-fast: false
+ matrix:
+ include:
+ - name: vtgate=N+1, vttablet=N
+ other_version_binaries: vtgate
+ - name: vtgate=N, vttablet=N+1
+ other_version_binaries: vttablet mysqlctl mysqlctld
steps:
- name: Skip CI
@@ -169,17 +179,22 @@ jobs:
find ./go/test/endtoend -name '*.go' -exec sed -i 's/ErrorContains/Error/g' {} +
find ./go/test/endtoend -name '*.go' -exec sed -i 's/EqualError/Error/g' {} +
- # Swap the binaries in the bin. Use vtgate version n+1 and keep vttablet at version n
- - name: Use next release's VTGate
+ # Start from this commit's binaries, then swap in the other version's
+ # binaries for this matrix entry's version mix.
+ - name: Use the other version's ${{ matrix.other_version_binaries }}
+ env:
+ OTHER_VERSION_BINARIES: ${{ matrix.other_version_binaries }}
run: |
source build.env
- rm -f $PWD/bin/vtgate
- cp /tmp/vitess-build-other/bin/vtgate $PWD/bin/vtgate
+ cp -r /tmp/vitess-build-current/bin/* $PWD/bin/
+ for binary in $OTHER_VERSION_BINARIES; do
+ cp "/tmp/vitess-build-other/bin/$binary" "$PWD/bin/$binary"
+ done
vtgate --version
+ vttablet --version
- # Running a test with vtgate at version n+1 and vttablet at version n
- - name: Run query serving tests (vtgate=N+1, vttablet=N)
+ - name: Run query serving tests (${{ matrix.name }})
run: |
rm -rf /tmp/vtdataroot
mkdir -p /tmp/vtdataroot
@@ -187,24 +202,19 @@ jobs:
source build.env
go run test.go -skip-build -keep-data=false -docker=false -print-log -follow -tag upgrade_downgrade_query_serving_schema
- # Swap the binaries again. This time, vtgate will be at version n, and vttablet will be at version n+1
- - name: Use current version VTGate, and other version VTTablet
- run: |
- source build.env
-
- rm -f $PWD/bin/vtgate $PWD/bin/vttablet $PWD/bin/mysqlctl $PWD/bin/mysqlctld
- cp /tmp/vitess-build-current/bin/vtgate $PWD/bin/vtgate
- cp /tmp/vitess-build-other/bin/vttablet $PWD/bin/vttablet
- cp /tmp/vitess-build-other/bin/mysqlctl $PWD/bin/mysqlctl
- cp /tmp/vitess-build-other/bin/mysqlctld $PWD/bin/mysqlctld
- vtgate --version
- vttablet --version
-
- # Running a test with vtgate at version n and vttablet at version n+1
- - name: Run query serving tests (vtgate=N, vttablet=N+1)
+ # The required status check is the name the single job had, so this job
+ # keeps it. It passes only when every version mix passed, or when they were
+ # skipped because nothing relevant changed.
+ upgrade_downgrade_test_result:
+ needs: upgrade_downgrade_test
+ if: ${{ !cancelled() }}
+ name: Run Upgrade Downgrade Test - Query Serving (Schema) Next Release
+ runs-on: ubuntu-24.04
+ timeout-minutes: 5
+ steps:
+ - name: Check the result of every version mix
+ env:
+ RESULT: ${{ needs.upgrade_downgrade_test.result }}
run: |
- rm -rf /tmp/vtdataroot
- mkdir -p /tmp/vtdataroot
-
- source build.env
- go run test.go -skip-build -keep-data=false -docker=false -print-log -follow -tag upgrade_downgrade_query_serving_schema
+ echo "upgrade_downgrade_test: $RESULT"
+ [[ "$RESULT" == "success" || "$RESULT" == "skipped" ]]
From 8b580f68b6f342b751f402d0c3f990acc682dc39 Mon Sep 17 00:00:00 2001
From: "vitess-bot[bot]" <108069721+vitess-bot[bot]@users.noreply.github.com>
Date: Wed, 21 Oct 2026 21:26:47 +0000
Subject: [PATCH 21/31] [release-23.0] vstreamer: restore test globals even
when newEngine fails (#19945) (#21698)
Signed-off-by: Arthur Schreiber
Co-authored-by: vitess-bot[bot] <108069721+vitess-bot[bot]@users.noreply.github.com>
---
go/vt/vttablet/tabletserver/vstreamer/vstreamer_test.go | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/go/vt/vttablet/tabletserver/vstreamer/vstreamer_test.go b/go/vt/vttablet/tabletserver/vstreamer/vstreamer_test.go
index a6fd2523433..10ce00d7d99 100644
--- a/go/vt/vttablet/tabletserver/vstreamer/vstreamer_test.go
+++ b/go/vt/vttablet/tabletserver/vstreamer/vstreamer_test.go
@@ -1935,7 +1935,6 @@ func TestMinimalMode(t *testing.T) {
engine = nil
oldEnv := env
env = nil
- newEngine(t, ctx, "minimal")
defer func() {
if engine != nil {
engine.Close()
@@ -1946,6 +1945,7 @@ func TestMinimalMode(t *testing.T) {
engine = oldEngine
env = oldEnv
}()
+ newEngine(t, ctx, "minimal")
err := engine.Stream(context.Background(), "current", nil, nil, throttlerapp.VStreamerName, func(evs []*binlogdatapb.VEvent) error { return nil }, nil)
require.Error(t, err, "minimal binlog_row_image is not supported by Vitess VReplication")
}
From 383170ce5c784ee1e3788f18fd9b62b05392e528 Mon Sep 17 00:00:00 2001
From: "vitess-bot[bot]" <108069721+vitess-bot[bot]@users.noreply.github.com>
Date: Thu, 22 Oct 2026 09:23:09 +0200
Subject: [PATCH 22/31] [release-23.0] VReplication: refresh target shards
concurrently when switching reads (#21663) (#21702)
Signed-off-by: Mikhail Udalov
Co-authored-by: vitess-bot[bot] <108069721+vitess-bot[bot]@users.noreply.github.com>
---
go/vt/topotools/keyspace.go | 24 +++++--
go/vt/topotools/keyspace_test.go | 120 +++++++++++++++++++++++++++++++
go/vt/vtctl/workflow/server.go | 2 +-
go/vt/wrangler/keyspace.go | 2 +-
4 files changed, 140 insertions(+), 8 deletions(-)
create mode 100644 go/vt/topotools/keyspace_test.go
diff --git a/go/vt/topotools/keyspace.go b/go/vt/topotools/keyspace.go
index d197345c3f6..c42ca86b270 100644
--- a/go/vt/topotools/keyspace.go
+++ b/go/vt/topotools/keyspace.go
@@ -114,6 +114,7 @@ func UpdateShardRecords(
servedType topodatapb.TabletType,
isFrom bool,
clearSourceShards bool,
+ refreshTimeout time.Duration,
logger logutil.Logger,
) error {
disableQueryService := isFrom
@@ -132,13 +133,24 @@ func UpdateShardRecords(
return err
}
shards[i] = updatedShard
- // For 'to' shards, refresh to make them serve. The 'from' shards will
- // be refreshed after traffic has migrated.
- if !isFrom {
- if _, _, err := RefreshTabletsByShard(ctx, ts, tmc, si, cells, logger); err != nil {
- logger.Warningf("RefreshTabletsByShard(%v/%v, cells=%v) failed with %v; continuing ...", si.Keyspace(), si.ShardName(), cells, err)
- }
+ }
+ // For 'to' shards, refresh to make them serve. The 'from' shards will
+ // be refreshed after traffic has migrated. The shards are refreshed
+ // concurrently because the caller holds the keyspace lock, and refreshing
+ // many shards one at a time can outlast the lock's lease. For the same
+ // reason one slow tablet must not stall the refresh past refreshTimeout.
+ if !isFrom {
+ refreshCtx, cancel := context.WithTimeout(ctx, refreshTimeout)
+ defer cancel()
+ var wg sync.WaitGroup
+ for _, si := range shards {
+ wg.Go(func() {
+ if _, _, err := RefreshTabletsByShard(refreshCtx, ts, tmc, si, cells, logger); err != nil {
+ logger.Warningf("RefreshTabletsByShard(%v/%v, cells=%v) failed with %v; continuing ...", si.Keyspace(), si.ShardName(), cells, err)
+ }
+ })
}
+ wg.Wait()
}
return nil
}
diff --git a/go/vt/topotools/keyspace_test.go b/go/vt/topotools/keyspace_test.go
new file mode 100644
index 00000000000..bfc12144ee8
--- /dev/null
+++ b/go/vt/topotools/keyspace_test.go
@@ -0,0 +1,120 @@
+/*
+Copyright 2026 The Vitess Authors.
+
+Licensed under the Apache License, Version 2.0 (the "License");
+you may not use this file except in compliance with the License.
+You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing, software
+distributed under the License is distributed on an "AS IS" BASIS,
+WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+See the License for the specific language governing permissions and
+limitations under the License.
+*/
+
+package topotools
+
+import (
+ "context"
+ "sync"
+ "testing"
+ "time"
+
+ "github.com/stretchr/testify/require"
+
+ "vitess.io/vitess/go/vt/key"
+ "vitess.io/vitess/go/vt/logutil"
+ "vitess.io/vitess/go/vt/topo"
+ "vitess.io/vitess/go/vt/topo/memorytopo"
+ "vitess.io/vitess/go/vt/vttablet/tmclient"
+
+ topodatapb "vitess.io/vitess/go/vt/proto/topodata"
+)
+
+// barrierRefreshTMC holds every RefreshState call until all of the expected
+// calls have started, or until the call's context is done. It records the
+// longest time any call had left before its context deadline.
+type barrierRefreshTMC struct {
+ tmclient.TabletManagerClient
+
+ expected int
+ mu sync.Mutex
+ started int
+ maxLeft time.Duration
+ allIn chan struct{}
+}
+
+func (c *barrierRefreshTMC) RefreshState(ctx context.Context, tablet *topodatapb.Tablet) error {
+ c.mu.Lock()
+ c.started++
+ if c.started == c.expected {
+ close(c.allIn)
+ }
+ if deadline, ok := ctx.Deadline(); ok {
+ c.maxLeft = max(c.maxLeft, time.Until(deadline))
+ }
+ c.mu.Unlock()
+
+ select {
+ case <-c.allIn:
+ return nil
+ case <-ctx.Done():
+ return ctx.Err()
+ }
+}
+
+// TestUpdateShardRecordsRefreshesShardsConcurrently checks that UpdateShardRecords
+// refreshes the tablets of all the 'to' shards concurrently, within refreshTimeout.
+// Each shard has one tablet whose RefreshState returns only once every shard's
+// RefreshState has started, so refreshing the shards one at a time runs into the
+// refresh deadline.
+func TestUpdateShardRecordsRefreshesShardsConcurrently(t *testing.T) {
+ const (
+ cell = "cell1"
+ keyspace = "ks"
+ numShards = 16
+ refreshTimeout = 30 * time.Second
+ )
+ ctx, cancel := context.WithTimeout(t.Context(), 2*refreshTimeout)
+ t.Cleanup(cancel)
+ ts := memorytopo.NewServer(ctx, cell)
+ t.Cleanup(ts.Close)
+
+ require.NoError(t, ts.CreateKeyspace(ctx, keyspace, &topodatapb.Keyspace{}))
+ shardNames, err := key.GenerateShardRanges(numShards, 2)
+ require.NoError(t, err)
+ shards := make([]*topo.ShardInfo, 0, numShards)
+ for i, shardName := range shardNames {
+ require.NoError(t, ts.CreateShard(ctx, keyspace, shardName))
+ require.NoError(t, ts.CreateTablet(ctx, &topodatapb.Tablet{
+ Alias: &topodatapb.TabletAlias{Cell: cell, Uid: uint32(i + 1)},
+ Hostname: "host",
+ Keyspace: keyspace,
+ Shard: shardName,
+ Type: topodatapb.TabletType_REPLICA,
+ }))
+ si, err := ts.GetShard(ctx, keyspace, shardName)
+ require.NoError(t, err)
+ shards = append(shards, si)
+ }
+
+ lockCtx, unlock, err := ts.LockKeyspace(ctx, keyspace, "TestUpdateShardRecordsRefreshesShardsConcurrently")
+ require.NoError(t, err)
+ t.Cleanup(func() {
+ var unlockErr error
+ unlock(&unlockErr)
+ require.NoError(t, unlockErr)
+ })
+
+ tmc := &barrierRefreshTMC{expected: numShards, allIn: make(chan struct{})}
+ err = UpdateShardRecords(lockCtx, ts, tmc, keyspace, shards, []string{cell}, topodatapb.TabletType_REPLICA,
+ false /* isFrom */, false /* clearSourceShards */, refreshTimeout, logutil.NewMemoryLogger())
+ require.NoError(t, err)
+
+ tmc.mu.Lock()
+ defer tmc.mu.Unlock()
+ require.Equal(t, numShards, tmc.started)
+ require.LessOrEqual(t, tmc.maxLeft, refreshTimeout)
+}
diff --git a/go/vt/vtctl/workflow/server.go b/go/vt/vtctl/workflow/server.go
index 5935c9d6949..51df33558cf 100644
--- a/go/vt/vtctl/workflow/server.go
+++ b/go/vt/vtctl/workflow/server.go
@@ -2619,7 +2619,7 @@ func (s *Server) DeleteShard(ctx context.Context, keyspace, shard string, recurs
func (s *Server) updateShardRecords(ctx context.Context, keyspace string, shards []*topo.ShardInfo, cells []string,
servedType topodatapb.TabletType, isFrom bool, clearSourceShards bool, logger logutil.Logger,
) (err error) {
- return topotools.UpdateShardRecords(ctx, s.ts, s.tmc, keyspace, shards, cells, servedType, isFrom, clearSourceShards, logger)
+ return topotools.UpdateShardRecords(ctx, s.ts, s.tmc, keyspace, shards, cells, servedType, isFrom, clearSourceShards, shardTabletRefreshTimeout, logger)
}
// refreshPrimaryTablets will just RPC-ping all the primary tablets with RefreshState
diff --git a/go/vt/wrangler/keyspace.go b/go/vt/wrangler/keyspace.go
index 6fce73b1f0f..d8ae469c02e 100644
--- a/go/vt/wrangler/keyspace.go
+++ b/go/vt/wrangler/keyspace.go
@@ -120,7 +120,7 @@ func (wr *Wrangler) refreshPrimaryTablets(ctx context.Context, shards []*topo.Sh
// updateShardRecords updates the shard records based on 'from' or 'to' direction.
func (wr *Wrangler) updateShardRecords(ctx context.Context, keyspace string, shards []*topo.ShardInfo, cells []string, servedType topodatapb.TabletType, isFrom bool, clearSourceShards bool) (err error) {
- return topotools.UpdateShardRecords(ctx, wr.ts, wr.tmc, keyspace, shards, cells, servedType, isFrom, clearSourceShards, wr.Logger())
+ return topotools.UpdateShardRecords(ctx, wr.ts, wr.tmc, keyspace, shards, cells, servedType, isFrom, clearSourceShards, shardTabletRefreshTimeout, wr.Logger())
}
func encodeString(in string) string {
From 605aaf8365bc71d0cdee28a6986ec5f563e05c12 Mon Sep 17 00:00:00 2001
From: "vitess-bot[bot]" <108069721+vitess-bot[bot]@users.noreply.github.com>
Date: Thu, 22 Oct 2026 11:50:31 +0200
Subject: [PATCH 23/31] [release-23.0] vtgate: support row comparisons with
subqueries that can't be merged (#21634) (#21704)
Signed-off-by: Matt Lord
Co-authored-by: vitess-bot[bot] <108069721+vitess-bot[bot]@users.noreply.github.com>
Co-authored-by: Matt Lord
---
.../vtgate/queries/subquery/subquery_test.go | 20 +
go/vt/vtgate/engine/cached_size.go | 9 +-
go/vt/vtgate/engine/uncorrelated_subquery.go | 81 +++-
.../engine/uncorrelated_subquery_test.go | 87 +++++
.../planbuilder/operator_transformers.go | 18 +-
.../vtgate/planbuilder/operators/subquery.go | 71 +++-
.../operators/subquery_planning.go | 42 ++-
.../plancontext/planning_context.go | 6 +
.../planbuilder/testdata/dml_cases.json | 152 ++++++++
.../planbuilder/testdata/filter_cases.json | 354 ++++++++++++++++++
.../planbuilder/testdata/select_cases.json | 101 +++++
.../testdata/unsupported_cases.json | 15 +
12 files changed, 936 insertions(+), 20 deletions(-)
diff --git a/go/test/endtoend/vtgate/queries/subquery/subquery_test.go b/go/test/endtoend/vtgate/queries/subquery/subquery_test.go
index 135b86195a5..8db6bce74e6 100644
--- a/go/test/endtoend/vtgate/queries/subquery/subquery_test.go
+++ b/go/test/endtoend/vtgate/queries/subquery/subquery_test.go
@@ -56,6 +56,15 @@ func TestSubqueriesHasValues(t *testing.T) {
mcmp.Exec("insert into t1(id1, id2) values (0,1),(1,2),(2,3),(3,4),(4,5),(5,6)")
mcmp.AssertMatches(`SELECT id2 FROM t1 WHERE id1 IN (SELECT id1 FROM t1 WHERE id1 > 10)`, `[]`)
mcmp.AssertMatches(`SELECT id2 FROM t1 WHERE id1 NOT IN (SELECT id1 FROM t1 WHERE id1 > 10) ORDER BY id2`, `[[INT64(1)] [INT64(2)] [INT64(3)] [INT64(4)] [INT64(5)] [INT64(6)]]`)
+
+ // Row IN and NOT IN subqueries that can't be merged bind each row as a tuple, also when they return no rows.
+ if utils.BinaryIsAtLeastAtVersion(23, "vtgate") {
+ mcmp.Exec("insert into t2(id3, id4) values (1, 2), (3, 4), (7, 8)")
+ mcmp.AssertMatches(`SELECT id2 FROM t1 WHERE (id1, id2) IN (SELECT id3, id4 FROM t2) ORDER BY id2`, `[[INT64(2)] [INT64(4)]]`)
+ mcmp.AssertMatches(`SELECT id2 FROM t1 WHERE (id1, id2) NOT IN (SELECT id3, id4 FROM t2) ORDER BY id2`, `[[INT64(1)] [INT64(3)] [INT64(5)] [INT64(6)]]`)
+ mcmp.AssertMatches(`SELECT id2 FROM t1 WHERE (id1, id2) IN (SELECT id3, id4 FROM t2 WHERE id3 > 10)`, `[]`)
+ mcmp.AssertMatches(`SELECT id2 FROM t1 WHERE (id1, id2) NOT IN (SELECT id3, id4 FROM t2 WHERE id3 > 10) ORDER BY id2`, `[[INT64(1)] [INT64(2)] [INT64(3)] [INT64(4)] [INT64(5)] [INT64(6)]]`)
+ }
}
func TestNotINQueries(t *testing.T) {
@@ -221,6 +230,17 @@ func TestSubqueries(t *testing.T) {
`SELECT id, name, (SELECT COUNT(*) FROM user_extra) + id AS total_extra_count_plus_id, AVG(id) AS avg_ids FROM user WHERE id < (SELECT MAX(user_id) FROM user_extra) GROUP BY id, name`,
}
+ // Row comparisons with value subqueries that can't be merged, including one that returns no rows, which
+ // compares as a row of NULLs.
+ if utils.BinaryIsAtLeastAtVersion(23, "vtgate") {
+ queries = append(queries,
+ `SELECT id FROM user WHERE (id, name) < (SELECT user_id, extra_info FROM user_extra WHERE user_id = 3 ORDER BY extra_info LIMIT 1) ORDER BY id`,
+ `SELECT id FROM user WHERE (id, 'info1') = (SELECT user_id, extra_info FROM user_extra WHERE user_id = 7)`,
+ `SELECT id FROM user WHERE (id, name) <=> (SELECT user_id, extra_info FROM user_extra WHERE user_id = 42)`,
+ `SELECT id, (id, name) >= (SELECT user_id, extra_info FROM user_extra WHERE user_id = 5) FROM user ORDER BY id`,
+ )
+ }
+
for idx, query := range queries {
mcmp.Run(fmt.Sprintf("%d %s", idx, query), func(mcmp *utils.MySQLCompare) {
mcmp.Exec(query)
diff --git a/go/vt/vtgate/engine/cached_size.go b/go/vt/vtgate/engine/cached_size.go
index f3a4e884370..9de2eda380b 100644
--- a/go/vt/vtgate/engine/cached_size.go
+++ b/go/vt/vtgate/engine/cached_size.go
@@ -1346,12 +1346,19 @@ func (cached *UncorrelatedSubquery) CachedSize(alloc bool) int64 {
}
size := int64(0)
if alloc {
- size += int64(80)
+ size += int64(112)
}
// field SubqueryResult string
size += hack.RuntimeAllocSize(int64(len(cached.SubqueryResult)))
// field HasValues string
size += hack.RuntimeAllocSize(int64(len(cached.HasValues)))
+ // field RowResults []string
+ {
+ size += hack.RuntimeAllocSize(int64(cap(cached.RowResults)) * int64(16))
+ for _, elem := range cached.RowResults {
+ size += hack.RuntimeAllocSize(int64(len(elem)))
+ }
+ }
// field Subquery vitess.io/vitess/go/vt/vtgate/engine.Primitive
if cc, ok := cached.Subquery.(cachedObject); ok {
size += cc.CachedSize(true)
diff --git a/go/vt/vtgate/engine/uncorrelated_subquery.go b/go/vt/vtgate/engine/uncorrelated_subquery.go
index aaa36c06f2b..9eb6a308411 100644
--- a/go/vt/vtgate/engine/uncorrelated_subquery.go
+++ b/go/vt/vtgate/engine/uncorrelated_subquery.go
@@ -18,6 +18,7 @@ package engine
import (
"context"
+ "fmt"
"vitess.io/vitess/go/sqltypes"
querypb "vitess.io/vitess/go/vt/proto/query"
@@ -36,6 +37,13 @@ type UncorrelatedSubquery struct {
// SubqueryResult and HasValues are used to send in the bindvar used in the query to the underlying primitive
SubqueryResult string
HasValues string
+ // RowColumns is how many columns each row of a PulloutIn or PulloutNotIn subquery has, when it is more than
+ // one, as in `(a, b) in (select x, y ...)`. SubqueryResult is then bound to a list of tuples rather than of values.
+ RowColumns int
+ // RowResults holds one bind variable per column for a PulloutValue subquery whose row has more than one column,
+ // as in `(a, b) < (select x, y ...)`. Each column is bound to its own variable, and SubqueryResult is not bound,
+ // because outside of an IN list a bind variable can only hold a single value.
+ RowResults []string
Subquery Primitive
Outer Primitive
@@ -76,13 +84,10 @@ func (ps *UncorrelatedSubquery) GetFields(ctx context.Context, vcursor VCursor,
}
switch ps.Opcode {
case opcode.PulloutValue:
- combinedVars[ps.SubqueryResult] = sqltypes.NullBindVariable
+ ps.bindNullValue(combinedVars)
case opcode.PulloutIn, opcode.PulloutNotIn:
combinedVars[ps.HasValues] = sqltypes.Int64BindVariable(0)
- combinedVars[ps.SubqueryResult] = &querypb.BindVariable{
- Type: querypb.Type_TUPLE,
- Values: []*querypb.Value{sqltypes.ValueToProto(sqltypes.NewInt64(0))},
- }
+ combinedVars[ps.SubqueryResult] = ps.placeholderList()
case opcode.PulloutExists:
combinedVars[ps.HasValues] = sqltypes.Int64BindVariable(0)
}
@@ -111,13 +116,25 @@ func (ps *UncorrelatedSubquery) execSubquery(ctx context.Context, vcursor VCurso
for k, v := range bindVars {
combinedVars[k] = v
}
+ width := max(ps.RowColumns, len(ps.RowResults))
+ for _, row := range result.Rows {
+ if len(row) < width {
+ return nil, vterrors.VT13001(fmt.Sprintf("subquery returned %d columns for a row of %d", len(row), width))
+ }
+ }
switch ps.Opcode {
case opcode.PulloutValue:
switch len(result.Rows) {
case 0:
- combinedVars[ps.SubqueryResult] = sqltypes.NullBindVariable
+ ps.bindNullValue(combinedVars)
case 1:
- combinedVars[ps.SubqueryResult] = sqltypes.ValueBindVariable(result.Rows[0][0])
+ if len(ps.RowResults) == 0 {
+ combinedVars[ps.SubqueryResult] = sqltypes.ValueBindVariable(result.Rows[0][0])
+ break
+ }
+ for i, name := range ps.RowResults {
+ combinedVars[name] = sqltypes.ValueBindVariable(result.Rows[0][i])
+ }
default:
return nil, errSqRow
}
@@ -126,10 +143,7 @@ func (ps *UncorrelatedSubquery) execSubquery(ctx context.Context, vcursor VCurso
case 0:
combinedVars[ps.HasValues] = sqltypes.Int64BindVariable(0)
// Add a bogus value. It will not be checked.
- combinedVars[ps.SubqueryResult] = &querypb.BindVariable{
- Type: querypb.Type_TUPLE,
- Values: []*querypb.Value{sqltypes.ValueToProto(sqltypes.NewInt64(0))},
- }
+ combinedVars[ps.SubqueryResult] = ps.placeholderList()
default:
combinedVars[ps.HasValues] = sqltypes.Int64BindVariable(1)
values := &querypb.BindVariable{
@@ -137,7 +151,12 @@ func (ps *UncorrelatedSubquery) execSubquery(ctx context.Context, vcursor VCurso
Values: make([]*querypb.Value, len(result.Rows)),
}
for i, v := range result.Rows {
- values.Values[i] = sqltypes.ValueToProto(v[0])
+ if ps.RowColumns > 1 {
+ // The subquery can return more columns than the row, such as a weight_string for its ordering.
+ values.Values[i] = sqltypes.TupleToProto(v[:ps.RowColumns])
+ } else {
+ values.Values[i] = sqltypes.ValueToProto(v[0])
+ }
}
combinedVars[ps.SubqueryResult] = values
}
@@ -152,18 +171,54 @@ func (ps *UncorrelatedSubquery) execSubquery(ctx context.Context, vcursor VCurso
return combinedVars, nil
}
+// bindNullValue binds the result of a PulloutValue subquery that returned no rows: NULL, or a NULL for each
+// column of its row, which is how MySQL compares a row with an empty row subquery.
+func (ps *UncorrelatedSubquery) bindNullValue(bindVars map[string]*querypb.BindVariable) {
+ if len(ps.RowResults) == 0 {
+ bindVars[ps.SubqueryResult] = sqltypes.NullBindVariable
+ return
+ }
+ for _, name := range ps.RowResults {
+ bindVars[name] = sqltypes.NullBindVariable
+ }
+}
+
+// placeholderList returns the list bound for a PulloutIn or PulloutNotIn subquery that returned no rows. The
+// has-values guard keeps it from being compared, but MySQL still rejects it unless it is as wide as the row.
+func (ps *UncorrelatedSubquery) placeholderList() *querypb.BindVariable {
+ if ps.RowColumns <= 1 {
+ return &querypb.BindVariable{
+ Type: querypb.Type_TUPLE,
+ Values: []*querypb.Value{sqltypes.ValueToProto(sqltypes.NewInt64(0))},
+ }
+ }
+ row := make([]sqltypes.Value, ps.RowColumns)
+ for i := range row {
+ row[i] = sqltypes.NewInt64(0)
+ }
+ return &querypb.BindVariable{
+ Type: querypb.Type_TUPLE,
+ Values: []*querypb.Value{sqltypes.TupleToProto(row)},
+ }
+}
+
func (ps *UncorrelatedSubquery) description() PrimitiveDescription {
other := map[string]any{}
var pulloutVars []string
if ps.HasValues != "" {
pulloutVars = append(pulloutVars, ps.HasValues)
}
- if ps.SubqueryResult != "" {
+ if len(ps.RowResults) > 0 {
+ pulloutVars = append(pulloutVars, ps.RowResults...)
+ } else if ps.SubqueryResult != "" {
pulloutVars = append(pulloutVars, ps.SubqueryResult)
}
if len(pulloutVars) > 0 {
other["PulloutVars"] = pulloutVars
}
+ if ps.RowColumns > 1 {
+ other["RowColumns"] = ps.RowColumns
+ }
return PrimitiveDescription{
OperatorType: "UncorrelatedSubquery",
Variant: ps.Opcode.String(),
diff --git a/go/vt/vtgate/engine/uncorrelated_subquery_test.go b/go/vt/vtgate/engine/uncorrelated_subquery_test.go
index 668b071d527..23c71bbf6c8 100644
--- a/go/vt/vtgate/engine/uncorrelated_subquery_test.go
+++ b/go/vt/vtgate/engine/uncorrelated_subquery_test.go
@@ -67,6 +67,26 @@ func TestPulloutSubqueryValueGood(t *testing.T) {
sfp.ExpectLog(t, []string{fmt.Sprintf(`Execute aa: %v false`, sqltypes.Int64BindVariable(1))})
ufp.ExpectLog(t, []string{fmt.Sprintf(`Execute aa: %v sq: %v false`, sqltypes.Int64BindVariable(1), sqltypes.Int64BindVariable(1))})
expectResult(t, result, underlyingResult)
+
+ // A row of more than one column binds each column to its own variable, leaving out any extra columns the
+ // subquery returns, such as a weight_string for its ordering.
+ rowResult := sqltypes.MakeTestResult(
+ sqltypes.MakeTestFields(
+ "col1|col2|weight_string(col2)",
+ "int64|varchar|varbinary",
+ ),
+ "1|a|A",
+ )
+ sfp = &fakePrimitive{
+ results: []*sqltypes.Result{rowResult},
+ }
+ ufp.rewind()
+ ps.Subquery = sfp
+ ps.RowResults = []string{"sq_0", "sq_1"}
+
+ _, err = ps.TryExecute(t.Context(), &noopVCursor{}, bindVars, false)
+ require.NoError(t, err)
+ ufp.ExpectLog(t, []string{fmt.Sprintf(`Execute aa: %v sq_0: %v sq_1: %v false`, sqltypes.Int64BindVariable(1), sqltypes.Int64BindVariable(1), sqltypes.StringBindVariable("a"))})
}
func TestPulloutSubqueryValueNone(t *testing.T) {
@@ -92,6 +112,15 @@ func TestPulloutSubqueryValueNone(t *testing.T) {
}
sfp.ExpectLog(t, []string{`Execute false`})
ufp.ExpectLog(t, []string{`Execute sq: false`})
+
+ // For a row of more than one column, each column is NULL, which is how MySQL compares a row with an empty
+ // row subquery.
+ sfp.rewind()
+ ufp.rewind()
+ ps.RowResults = []string{"sq_0", "sq_1"}
+ _, err := ps.TryExecute(t.Context(), &noopVCursor{}, make(map[string]*querypb.BindVariable), false)
+ require.NoError(t, err)
+ ufp.ExpectLog(t, []string{`Execute sq_0: sq_1: false`})
}
func TestPulloutSubqueryValueBadRows(t *testing.T) {
@@ -114,6 +143,28 @@ func TestPulloutSubqueryValueBadRows(t *testing.T) {
_, err := ps.TryExecute(context.Background(), &noopVCursor{}, make(map[string]*querypb.BindVariable), false)
require.EqualError(t, err, "subquery returned more than one row")
+
+ // A row that is narrower than the comparison it is bound for is a planner bug, for a value comparison and for
+ // IN alike.
+ narrowResult := sqltypes.MakeTestResult(
+ sqltypes.MakeTestFields(
+ "col1",
+ "int64",
+ ),
+ "1",
+ )
+ ps.Subquery = &fakePrimitive{results: []*sqltypes.Result{narrowResult}}
+ ps.RowResults = []string{"sq_0", "sq_1"}
+ _, err = ps.TryExecute(t.Context(), &noopVCursor{}, make(map[string]*querypb.BindVariable), false)
+ require.EqualError(t, err, "VT13001: [BUG] subquery returned 1 columns for a row of 2")
+
+ ps.Subquery = &fakePrimitive{results: []*sqltypes.Result{narrowResult}}
+ ps.Opcode = PulloutIn
+ ps.HasValues = "has_values"
+ ps.RowResults = nil
+ ps.RowColumns = 2
+ _, err = ps.TryExecute(t.Context(), &noopVCursor{}, make(map[string]*querypb.BindVariable), false)
+ require.EqualError(t, err, "VT13001: [BUG] subquery returned 1 columns for a row of 2")
}
func TestPulloutSubqueryInNotinGood(t *testing.T) {
@@ -152,6 +203,30 @@ func TestPulloutSubqueryInNotinGood(t *testing.T) {
}
sfp.ExpectLog(t, []string{`Execute false`})
ufp.ExpectLog(t, []string{fmt.Sprintf(`Execute has_values: %v sq: %v false`, sqltypes.Int64BindVariable(1), &querypb.BindVariable{Type: querypb.Type_TUPLE, Values: []*querypb.Value{{Type: querypb.Type_INT64, Value: []byte("1")}, {Type: querypb.Type_INT64, Value: []byte("2")}}})})
+
+ // Rows of more than one column are bound as a list of tuples, leaving out any extra columns the subquery
+ // returns.
+ rowResult := sqltypes.MakeTestResult(
+ sqltypes.MakeTestFields(
+ "col1|col2|weight_string(col2)",
+ "int64|varchar|varbinary",
+ ),
+ "1|a|A",
+ "2|b|B",
+ )
+ sfp = &fakePrimitive{
+ results: []*sqltypes.Result{rowResult},
+ }
+ ufp.rewind()
+ ps.Subquery = sfp
+ ps.RowColumns = 2
+ _, err := ps.TryExecute(t.Context(), &noopVCursor{}, make(map[string]*querypb.BindVariable), false)
+ require.NoError(t, err)
+ rows := &querypb.BindVariable{Type: querypb.Type_TUPLE, Values: []*querypb.Value{
+ sqltypes.TupleToProto([]sqltypes.Value{sqltypes.NewInt64(1), sqltypes.NewVarChar("a")}),
+ sqltypes.TupleToProto([]sqltypes.Value{sqltypes.NewInt64(2), sqltypes.NewVarChar("b")}),
+ }}
+ ufp.ExpectLog(t, []string{fmt.Sprintf(`Execute has_values: %v sq: %v false`, sqltypes.Int64BindVariable(1), rows)})
}
func TestPulloutSubqueryInNone(t *testing.T) {
@@ -178,6 +253,18 @@ func TestPulloutSubqueryInNone(t *testing.T) {
}
sfp.ExpectLog(t, []string{`Execute false`})
ufp.ExpectLog(t, []string{fmt.Sprintf(`Execute has_values: %v sq: %v false`, sqltypes.Int64BindVariable(0), &querypb.BindVariable{Type: querypb.Type_TUPLE, Values: []*querypb.Value{{Type: querypb.Type_INT64, Value: []byte("0")}}})})
+
+ // For rows of more than one column, the placeholder is a tuple as wide as the row: MySQL rejects anything
+ // else, even when the has-values guard is false.
+ sfp.rewind()
+ ufp.rewind()
+ ps.RowColumns = 2
+ _, err := ps.TryExecute(t.Context(), &noopVCursor{}, make(map[string]*querypb.BindVariable), false)
+ require.NoError(t, err)
+ placeholder := &querypb.BindVariable{Type: querypb.Type_TUPLE, Values: []*querypb.Value{
+ sqltypes.TupleToProto([]sqltypes.Value{sqltypes.NewInt64(0), sqltypes.NewInt64(0)}),
+ }}
+ ufp.ExpectLog(t, []string{fmt.Sprintf(`Execute has_values: %v sq: %v false`, sqltypes.Int64BindVariable(0), placeholder)})
}
func TestPulloutSubqueryExists(t *testing.T) {
diff --git a/go/vt/vtgate/planbuilder/operator_transformers.go b/go/vt/vtgate/planbuilder/operator_transformers.go
index c9246f9ec7b..0fd437f5ba6 100644
--- a/go/vt/vtgate/planbuilder/operator_transformers.go
+++ b/go/vt/vtgate/planbuilder/operator_transformers.go
@@ -277,13 +277,27 @@ func transformSubQuery(ctx *plancontext.PlanningContext, op *operators.SubQuery)
}
if len(cols) == 0 {
// no correlation, so uncorrelated it is
- return &engine.UncorrelatedSubquery{
+ sq := &engine.UncorrelatedSubquery{
Opcode: op.FilterType,
SubqueryResult: op.SubqueryValueName,
HasValues: op.HasValuesName,
Subquery: inner,
Outer: outer,
- }, nil
+ }
+ if rowColumns := op.RowColumns(); rowColumns > 1 {
+ switch op.FilterType {
+ case opcode.PulloutValue:
+ sq.RowResults = ctx.RowSubqueryArgs[op.ArgName]
+ case opcode.PulloutIn, opcode.PulloutNotIn:
+ // Only a comparison guarded by HasValues is safe to bind as a list of rows: without the guard, an
+ // empty result would be compared with the placeholder row. In select expressions and UPDATE ... SET
+ // there is no guard, so leave those as they were, which MySQL rejects for a row.
+ if op.HasValuesName != "" {
+ sq.RowColumns = rowColumns
+ }
+ }
+ }
+ return sq, nil
}
return &engine.SemiJoin{
diff --git a/go/vt/vtgate/planbuilder/operators/subquery.go b/go/vt/vtgate/planbuilder/operators/subquery.go
index 62b6e7a725e..f06efe8ce7c 100644
--- a/go/vt/vtgate/planbuilder/operators/subquery.go
+++ b/go/vt/vtgate/planbuilder/operators/subquery.go
@@ -230,6 +230,8 @@ func (sq *SubQuery) settle(ctx *plancontext.PlanningContext, outer Operator) Ope
var correlatedSubqueryErr = vterrors.VT12001("correlated subquery is only supported for EXISTS")
var subqueryNotAtTopErr = vterrors.VT12001("unmergable subquery can not be inside complex expression")
+var rowSubqueryAmongOthersErr = vterrors.VT12001("row comparison with an unmergable subquery in a predicate with other subqueries")
+
func (sq *SubQuery) addLimit() {
// for a correlated subquery, we can add a limit 1 to the subquery
sq.Subquery = newLimit(sq.Subquery, &sqlparser.Limit{Rowcount: sqlparser.NewIntLiteral("1")}, true)
@@ -243,6 +245,12 @@ func (sq *SubQuery) settleFilter(ctx *plancontext.PlanningContext, outer Operato
sq.addLimit()
return outer
}
+ // Every subquery in the predicate is replaced with this subquery's argument below, which is only right when it
+ // is the only one (#21638). Refuse a row comparison in such a predicate, instead of comparing a row with the
+ // result of another subquery.
+ if hasRowSubqueryAmongOthers(sq.Original) {
+ panic(rowSubqueryAmongOthersErr)
+ }
hasValuesArg := func() string {
s := ctx.ReservedVars.ReserveVariable(string(sqlparser.HasValueSubQueryBaseName))
@@ -270,9 +278,12 @@ func (sq *SubQuery) settleFilter(ctx *plancontext.PlanningContext, outer Operato
}
var arg sqlparser.Expr
- if sq.FilterType.NeedsListArg() {
+ switch {
+ case sq.FilterType.NeedsListArg():
arg = sqlparser.NewListArg(sq.ArgName)
- } else {
+ case sq.FilterType == opcode.PulloutValue && sq.RowColumns() > 1:
+ arg = sq.rowArguments(ctx)
+ default:
arg = sqlparser.NewArgument(sq.ArgName)
}
cursor.Replace(arg)
@@ -309,6 +320,62 @@ func (sq *SubQuery) settleFilter(ctx *plancontext.PlanningContext, outer Operato
return newFilter(outer, predicates...)
}
+// RowColumns returns how many columns each row of the subquery has. It returns 1 when that is not known, which
+// is the case for a subquery selecting `*`.
+func (sq *SubQuery) RowColumns() int {
+ return subqueryRowColumns(sq.originalSubquery)
+}
+
+func subqueryRowColumns(subq *sqlparser.Subquery) int {
+ columns := subq.Select.GetColumns()
+ for _, column := range columns {
+ if _, isStar := column.(*sqlparser.StarExpr); isStar {
+ return 1
+ }
+ }
+ return max(len(columns), 1)
+}
+
+// hasRowSubqueryAmongOthers reports whether expr contains more than one subquery, not counting those nested in
+// another, and one of them, other than an EXISTS, returns rows of more than one column.
+func hasRowSubqueryAmongOthers(expr sqlparser.Expr) bool {
+ count, hasRow := 0, false
+ _ = sqlparser.Walk(func(node sqlparser.SQLNode) (bool, error) {
+ switch node := node.(type) {
+ case *sqlparser.ExistsExpr:
+ count++
+ return false, nil
+ case *sqlparser.Subquery:
+ count++
+ hasRow = hasRow || subqueryRowColumns(node) > 1
+ return false, nil
+ }
+ return true, nil
+ }, expr)
+ return count > 1 && hasRow
+}
+
+// rowArguments returns the row of arguments that stands in for a value subquery whose row has more than one
+// column, as in `(a, b) < (select x, y ...)`. A single argument can't hold a row, so each column gets its own.
+// The arguments are reserved the first time they're needed, and reused after that. They are left untyped: the
+// select expressions of a UNION's first arm don't give the types of the row it returns.
+func (sq *SubQuery) rowArguments(ctx *plancontext.PlanningContext) sqlparser.ValTuple {
+ names, ok := ctx.RowSubqueryArgs[sq.ArgName]
+ if !ok {
+ names = make([]string, sq.RowColumns())
+ for i := range names {
+ names[i] = ctx.ReservedVars.ReserveVariable(fmt.Sprintf("%s_%d", sq.ArgName, i))
+ }
+ ctx.RowSubqueryArgs[sq.ArgName] = names
+ }
+
+ row := make(sqlparser.ValTuple, len(names))
+ for i, name := range names {
+ row[i] = sqlparser.NewArgument(name)
+ }
+ return row
+}
+
func dontEnterSubqueries(node, _ sqlparser.SQLNode) bool {
if _, ok := node.(*sqlparser.Subquery); ok {
return false
diff --git a/go/vt/vtgate/planbuilder/operators/subquery_planning.go b/go/vt/vtgate/planbuilder/operators/subquery_planning.go
index 95a45440578..908b7af2a29 100644
--- a/go/vt/vtgate/planbuilder/operators/subquery_planning.go
+++ b/go/vt/vtgate/planbuilder/operators/subquery_planning.go
@@ -98,7 +98,7 @@ func settleSubqueries(ctx *plancontext.PlanningContext, op Operator) Operator {
}
case *Aggregator:
for _, aggr := range op.Aggregations {
- newExpr, rewritten := rewriteMergedSubqueryExpr(ctx, aggr.SubQueryExpression, aggr.Original.Expr)
+ newExpr, rewritten := settleSubqueryExpr(ctx, aggr.SubQueryExpression, aggr.Original.Expr)
if rewritten {
aggr.Original.Expr = newExpr
op.Columns[aggr.ColOffset].Expr = newExpr
@@ -141,12 +141,50 @@ func mergeSubqueryExpr(ctx *plancontext.PlanningContext, pe *ProjExpr) {
if !ok {
return
}
- newExpr, rewritten := rewriteMergedSubqueryExpr(ctx, se, pe.EvalExpr)
+ newExpr, rewritten := settleSubqueryExpr(ctx, se, pe.EvalExpr)
if rewritten {
pe.EvalExpr = newExpr
}
}
+// settleSubqueryExpr rewrites the subqueries that an expression uses: back into the expression for those that
+// were merged, and into a row of arguments for value subqueries that were pulled out with rows of more than one
+// column.
+func settleSubqueryExpr(ctx *plancontext.PlanningContext, se SubQueryExpression, expr sqlparser.Expr) (sqlparser.Expr, bool) {
+ expr, merged := rewriteMergedSubqueryExpr(ctx, se, expr)
+ expr, expanded := expandRowSubqueryArgs(ctx, se, expr)
+ return expr, merged || expanded
+}
+
+// expandRowSubqueryArgs replaces the placeholder of each pulled-out value subquery whose row has more than one
+// column with a row of arguments, one per column, since a single argument can't hold a row.
+func expandRowSubqueryArgs(ctx *plancontext.PlanningContext, se SubQueryExpression, expr sqlparser.Expr) (sqlparser.Expr, bool) {
+ rewritten := false
+ for _, sq := range se {
+ if sq.FilterType != opcode.PulloutValue || sq.isMerged(ctx) || sq.RowColumns() <= 1 {
+ continue
+ }
+ expr = sqlparser.Rewrite(expr, nil, func(cursor *sqlparser.Cursor) bool {
+ switch node := cursor.Node().(type) {
+ case *sqlparser.ColName:
+ if !node.Qualifier.IsEmpty() || node.Name.String() != sq.ArgName {
+ return true
+ }
+ case *sqlparser.Argument:
+ if node.Name != sq.ArgName {
+ return true
+ }
+ default:
+ return true
+ }
+ cursor.Replace(sq.rowArguments(ctx))
+ rewritten = true
+ return false
+ }).(sqlparser.Expr)
+ }
+ return expr, rewritten
+}
+
func rewriteMergedSubqueryExpr(ctx *plancontext.PlanningContext, se SubQueryExpression, expr sqlparser.Expr) (sqlparser.Expr, bool) {
rewritten := false
diff --git a/go/vt/vtgate/planbuilder/plancontext/planning_context.go b/go/vt/vtgate/planbuilder/plancontext/planning_context.go
index 17b12718349..7ffe977706c 100644
--- a/go/vt/vtgate/planbuilder/plancontext/planning_context.go
+++ b/go/vt/vtgate/planbuilder/plancontext/planning_context.go
@@ -48,6 +48,10 @@ type PlanningContext struct {
// Projected subqueries that have been merged
MergedSubqueries []*sqlparser.Subquery
+ // RowSubqueryArgs holds, keyed by a subquery's arg name, the arguments that stand in for each column of a
+ // value subquery whose row has more than one column, once the subquery has been pulled out.
+ RowSubqueryArgs map[string][]string
+
// CurrentPhase keeps track of how far we've gone in the planning process
// The type should be operators.Phase, but depending on that would lead to circular dependencies
CurrentPhase int
@@ -105,6 +109,7 @@ func CreatePlanningContext(stmt sqlparser.Statement,
VSchema: vschema,
PlannerVersion: version,
ReservedArguments: map[sqlparser.Expr]string{},
+ RowSubqueryArgs: map[string][]string{},
Statement: stmt,
PredTracker: predicates.NewTracker(),
}, nil
@@ -359,6 +364,7 @@ func (ctx *PlanningContext) UseMirror() *PlanningContext {
ReservedArguments: map[sqlparser.Expr]string{},
VerifyAllFKs: ctx.VerifyAllFKs,
MergedSubqueries: ctx.MergedSubqueries,
+ RowSubqueryArgs: ctx.RowSubqueryArgs,
CurrentPhase: ctx.CurrentPhase,
Statement: ctx.Statement,
OuterTables: ctx.OuterTables,
diff --git a/go/vt/vtgate/planbuilder/testdata/dml_cases.json b/go/vt/vtgate/planbuilder/testdata/dml_cases.json
index f5d9d9ea965..2c8457ecbcc 100644
--- a/go/vt/vtgate/planbuilder/testdata/dml_cases.json
+++ b/go/vt/vtgate/planbuilder/testdata/dml_cases.json
@@ -7177,5 +7177,157 @@
"user.user"
]
}
+ },
+ {
+ "comment": "update with a row comparison against a value subquery binds each column of the row",
+ "query": "update user set col = 1 where (col, name) < (select user_id, col from music where user_id = 5)",
+ "plan": {
+ "Type": "Complex",
+ "QueryType": "UPDATE",
+ "Original": "update user set col = 1 where (col, name) < (select user_id, col from music where user_id = 5)",
+ "Instructions": {
+ "OperatorType": "UncorrelatedSubquery",
+ "Variant": "PulloutValue",
+ "PulloutVars": [
+ "__sq1_0",
+ "__sq1_1"
+ ],
+ "Inputs": [
+ {
+ "InputName": "SubQuery",
+ "OperatorType": "Route",
+ "Variant": "EqualUnique",
+ "Keyspace": {
+ "Name": "user",
+ "Sharded": true
+ },
+ "FieldQuery": "select user_id, col from music where 1 != 1",
+ "Query": "select user_id, col from music where user_id = 5 lock in share mode",
+ "Values": [
+ "5"
+ ],
+ "Vindex": "user_index"
+ },
+ {
+ "InputName": "Outer",
+ "OperatorType": "Update",
+ "Variant": "Scatter",
+ "Keyspace": {
+ "Name": "user",
+ "Sharded": true
+ },
+ "Query": "update `user` set col = 1 where (col, `name`) < (:__sq1_0, :__sq1_1)"
+ }
+ ]
+ },
+ "TablesUsed": [
+ "user.music",
+ "user.user"
+ ]
+ }
+ },
+ {
+ "comment": "update set with a row comparison against a value subquery binds each column of the row",
+ "query": "update user set col = ((col, name) = (select user_id, col from music where user_id = 5)) where id = 1",
+ "plan": {
+ "Type": "Complex",
+ "QueryType": "UPDATE",
+ "Original": "update user set col = ((col, name) = (select user_id, col from music where user_id = 5)) where id = 1",
+ "Instructions": {
+ "OperatorType": "UncorrelatedSubquery",
+ "Variant": "PulloutValue",
+ "PulloutVars": [
+ "__sq1_0",
+ "__sq1_1"
+ ],
+ "Inputs": [
+ {
+ "InputName": "SubQuery",
+ "OperatorType": "Route",
+ "Variant": "EqualUnique",
+ "Keyspace": {
+ "Name": "user",
+ "Sharded": true
+ },
+ "FieldQuery": "select user_id, col from music where 1 != 1",
+ "Query": "select user_id, col from music where user_id = 5 lock in share mode",
+ "Values": [
+ "5"
+ ],
+ "Vindex": "user_index"
+ },
+ {
+ "InputName": "Outer",
+ "OperatorType": "Update",
+ "Variant": "EqualUnique",
+ "Keyspace": {
+ "Name": "user",
+ "Sharded": true
+ },
+ "Query": "update `user` set col = (col, `name`) = (:__sq1_0, :__sq1_1) where id = 1",
+ "Values": [
+ "1"
+ ],
+ "Vindex": "user_index"
+ }
+ ]
+ },
+ "TablesUsed": [
+ "user.music",
+ "user.user"
+ ]
+ }
+ },
+ {
+ "comment": "delete with a row NOT IN subquery binds each row as a tuple",
+ "query": "delete from user where (col, name) not in (select user_id, col from music where user_id = 5)",
+ "plan": {
+ "Type": "Complex",
+ "QueryType": "DELETE",
+ "Original": "delete from user where (col, name) not in (select user_id, col from music where user_id = 5)",
+ "Instructions": {
+ "OperatorType": "UncorrelatedSubquery",
+ "Variant": "PulloutNotIn",
+ "PulloutVars": [
+ "__sq_has_values",
+ "__sq1"
+ ],
+ "RowColumns": 2,
+ "Inputs": [
+ {
+ "InputName": "SubQuery",
+ "OperatorType": "Route",
+ "Variant": "EqualUnique",
+ "Keyspace": {
+ "Name": "user",
+ "Sharded": true
+ },
+ "FieldQuery": "select user_id, col from music where 1 != 1",
+ "Query": "select user_id, col from music where user_id = 5",
+ "Values": [
+ "5"
+ ],
+ "Vindex": "user_index"
+ },
+ {
+ "InputName": "Outer",
+ "OperatorType": "Delete",
+ "Variant": "Scatter",
+ "Keyspace": {
+ "Name": "user",
+ "Sharded": true
+ },
+ "KsidLength": 1,
+ "KsidVindex": "user_index",
+ "OwnedVindexQuery": "select Id, `Name`, Costly from `user` where not :__sq_has_values or (col, `name`) not in ::__sq1 for update",
+ "Query": "delete from `user` where not :__sq_has_values or (col, `name`) not in ::__sq1"
+ }
+ ]
+ },
+ "TablesUsed": [
+ "user.music",
+ "user.user"
+ ]
+ }
}
]
diff --git a/go/vt/vtgate/planbuilder/testdata/filter_cases.json b/go/vt/vtgate/planbuilder/testdata/filter_cases.json
index ea78afe8451..0226a94ec49 100644
--- a/go/vt/vtgate/planbuilder/testdata/filter_cases.json
+++ b/go/vt/vtgate/planbuilder/testdata/filter_cases.json
@@ -5042,5 +5042,359 @@
"user.sales_extra"
]
}
+ },
+ {
+ "comment": "row comparison with a value subquery that can't be merged binds each column of the row",
+ "query": "select id from user where id = 1 and (col, name) < (select col, name from user where id in (2, 3) limit 1)",
+ "plan": {
+ "Type": "Complex",
+ "QueryType": "SELECT",
+ "Original": "select id from user where id = 1 and (col, name) < (select col, name from user where id in (2, 3) limit 1)",
+ "Instructions": {
+ "OperatorType": "UncorrelatedSubquery",
+ "Variant": "PulloutValue",
+ "PulloutVars": [
+ "__sq1_0",
+ "__sq1_1"
+ ],
+ "Inputs": [
+ {
+ "InputName": "SubQuery",
+ "OperatorType": "Limit",
+ "Count": "1",
+ "Inputs": [
+ {
+ "OperatorType": "Route",
+ "Variant": "IN",
+ "Keyspace": {
+ "Name": "user",
+ "Sharded": true
+ },
+ "FieldQuery": "select col, `name` from `user` where 1 != 1",
+ "Query": "select col, `name` from `user` where id in ::__vals limit 1",
+ "Values": [
+ "(2, 3)"
+ ],
+ "Vindex": "user_index"
+ }
+ ]
+ },
+ {
+ "InputName": "Outer",
+ "OperatorType": "Route",
+ "Variant": "EqualUnique",
+ "Keyspace": {
+ "Name": "user",
+ "Sharded": true
+ },
+ "FieldQuery": "select id from `user` where 1 != 1",
+ "Query": "select id from `user` where id = 1 and (col, `name`) < (:__sq1_0, :__sq1_1)",
+ "Values": [
+ "1"
+ ],
+ "Vindex": "user_index"
+ }
+ ]
+ },
+ "TablesUsed": [
+ "user.user"
+ ]
+ }
+ },
+ {
+ "comment": "row IN subquery that can't be merged routes on the tuple column and binds each row as a tuple",
+ "query": "select id from user where (id, col) in (select id, col from user where name = 'x')",
+ "plan": {
+ "Type": "Complex",
+ "QueryType": "SELECT",
+ "Original": "select id from user where (id, col) in (select id, col from user where name = 'x')",
+ "Instructions": {
+ "OperatorType": "UncorrelatedSubquery",
+ "Variant": "PulloutIn",
+ "PulloutVars": [
+ "__sq_has_values",
+ "__sq1"
+ ],
+ "RowColumns": 2,
+ "Inputs": [
+ {
+ "InputName": "SubQuery",
+ "OperatorType": "VindexLookup",
+ "Variant": "Equal",
+ "Keyspace": {
+ "Name": "user",
+ "Sharded": true
+ },
+ "Values": [
+ "'x'"
+ ],
+ "Vindex": "name_user_map",
+ "Inputs": [
+ {
+ "OperatorType": "Route",
+ "Variant": "IN",
+ "Keyspace": {
+ "Name": "user",
+ "Sharded": true
+ },
+ "FieldQuery": "select `name`, keyspace_id from name_user_vdx where 1 != 1",
+ "Query": "select `name`, keyspace_id from name_user_vdx where `name` in ::__vals",
+ "Values": [
+ "::name"
+ ],
+ "Vindex": "user_index"
+ },
+ {
+ "OperatorType": "Route",
+ "Variant": "ByDestination",
+ "Keyspace": {
+ "Name": "user",
+ "Sharded": true
+ },
+ "FieldQuery": "select id, col from `user` where 1 != 1",
+ "Query": "select id, col from `user` where `name` = 'x'"
+ }
+ ]
+ },
+ {
+ "InputName": "Outer",
+ "OperatorType": "Route",
+ "Variant": "MultiEqual",
+ "Keyspace": {
+ "Name": "user",
+ "Sharded": true
+ },
+ "FieldQuery": "select id from `user` where 1 != 1",
+ "Query": "select id from `user` where :__sq_has_values and (id, col) in ::__sq1",
+ "Values": [
+ "__sq1:0"
+ ],
+ "Vindex": "user_index"
+ }
+ ]
+ },
+ "TablesUsed": [
+ "user.user"
+ ]
+ }
+ },
+ {
+ "comment": "row comparison with a value subquery in HAVING is evaluated with an argument per column",
+ "query": "select col, count(*) from user group by col having (col, count(*)) <=> (select col, id from user where id = 5)",
+ "plan": {
+ "Type": "Complex",
+ "QueryType": "SELECT",
+ "Original": "select col, count(*) from user group by col having (col, count(*)) <=> (select col, id from user where id = 5)",
+ "Instructions": {
+ "OperatorType": "UncorrelatedSubquery",
+ "Variant": "PulloutValue",
+ "PulloutVars": [
+ "__sq1_0",
+ "__sq1_1"
+ ],
+ "Inputs": [
+ {
+ "InputName": "SubQuery",
+ "OperatorType": "Route",
+ "Variant": "EqualUnique",
+ "Keyspace": {
+ "Name": "user",
+ "Sharded": true
+ },
+ "FieldQuery": "select col, id from `user` where 1 != 1",
+ "Query": "select col, id from `user` where id = 5",
+ "Values": [
+ "5"
+ ],
+ "Vindex": "user_index"
+ },
+ {
+ "InputName": "Outer",
+ "OperatorType": "Filter",
+ "Predicate": "(`user`.col, count(*)) <=> (:__sq1_0, :__sq1_1)",
+ "Inputs": [
+ {
+ "OperatorType": "Aggregate",
+ "Variant": "Ordered",
+ "Aggregates": "sum_count_star(1) AS count(*)",
+ "GroupBy": "0",
+ "Inputs": [
+ {
+ "OperatorType": "Route",
+ "Variant": "Scatter",
+ "Keyspace": {
+ "Name": "user",
+ "Sharded": true
+ },
+ "FieldQuery": "select col, count(*) from `user` where 1 != 1 group by col",
+ "OrderBy": "0 ASC",
+ "Query": "select col, count(*) from `user` group by col order by col asc"
+ }
+ ]
+ }
+ ]
+ }
+ ]
+ },
+ "TablesUsed": [
+ "user.user"
+ ]
+ }
+ },
+ {
+ "comment": "row arguments of a UNION subquery are untyped, since its first arm doesn't give the types of the row it returns",
+ "query": "select col, count(*) from user group by col having (col, count(*)) <=> (select null, null from user where id = 99 union all select col, id from user where id = 5)",
+ "plan": {
+ "Type": "Complex",
+ "QueryType": "SELECT",
+ "Original": "select col, count(*) from user group by col having (col, count(*)) <=> (select null, null from user where id = 99 union all select col, id from user where id = 5)",
+ "Instructions": {
+ "OperatorType": "UncorrelatedSubquery",
+ "Variant": "PulloutValue",
+ "PulloutVars": [
+ "__sq1_0",
+ "__sq1_1"
+ ],
+ "Inputs": [
+ {
+ "InputName": "SubQuery",
+ "OperatorType": "Concatenate",
+ "Inputs": [
+ {
+ "OperatorType": "Route",
+ "Variant": "EqualUnique",
+ "Keyspace": {
+ "Name": "user",
+ "Sharded": true
+ },
+ "FieldQuery": "select null, null from `user` where 1 != 1",
+ "Query": "select null, null from `user` where id = 99",
+ "Values": [
+ "99"
+ ],
+ "Vindex": "user_index"
+ },
+ {
+ "OperatorType": "Route",
+ "Variant": "EqualUnique",
+ "Keyspace": {
+ "Name": "user",
+ "Sharded": true
+ },
+ "FieldQuery": "select col, id from `user` where 1 != 1",
+ "Query": "select col, id from `user` where id = 5",
+ "Values": [
+ "5"
+ ],
+ "Vindex": "user_index"
+ }
+ ]
+ },
+ {
+ "InputName": "Outer",
+ "OperatorType": "Filter",
+ "Predicate": "(`user`.col, count(*)) <=> (:__sq1_0, :__sq1_1)",
+ "Inputs": [
+ {
+ "OperatorType": "Aggregate",
+ "Variant": "Ordered",
+ "Aggregates": "sum_count_star(1) AS count(*)",
+ "GroupBy": "0",
+ "Inputs": [
+ {
+ "OperatorType": "Route",
+ "Variant": "Scatter",
+ "Keyspace": {
+ "Name": "user",
+ "Sharded": true
+ },
+ "FieldQuery": "select col, count(*) from `user` where 1 != 1 group by col",
+ "OrderBy": "0 ASC",
+ "Query": "select col, count(*) from `user` group by col order by col asc"
+ }
+ ]
+ }
+ ]
+ }
+ ]
+ },
+ "TablesUsed": [
+ "user.user"
+ ]
+ }
+ },
+ {
+ "comment": "a row comparison and a scalar comparison with subqueries that can't be merged, in separate AND-ed predicates, each get their own arguments",
+ "query": "select id from user where (col, name) < (select user_id, col from music where user_id = 3) and col > (select user_id from music where user_id = 8)",
+ "plan": {
+ "Type": "Complex",
+ "QueryType": "SELECT",
+ "Original": "select id from user where (col, name) < (select user_id, col from music where user_id = 3) and col > (select user_id from music where user_id = 8)",
+ "Instructions": {
+ "OperatorType": "UncorrelatedSubquery",
+ "Variant": "PulloutValue",
+ "PulloutVars": [
+ "__sq2"
+ ],
+ "Inputs": [
+ {
+ "InputName": "SubQuery",
+ "OperatorType": "Route",
+ "Variant": "EqualUnique",
+ "Keyspace": {
+ "Name": "user",
+ "Sharded": true
+ },
+ "FieldQuery": "select user_id from music where 1 != 1",
+ "Query": "select user_id from music where user_id = 8",
+ "Values": [
+ "8"
+ ],
+ "Vindex": "user_index"
+ },
+ {
+ "InputName": "Outer",
+ "OperatorType": "UncorrelatedSubquery",
+ "Variant": "PulloutValue",
+ "PulloutVars": [
+ "__sq1_0",
+ "__sq1_1"
+ ],
+ "Inputs": [
+ {
+ "InputName": "SubQuery",
+ "OperatorType": "Route",
+ "Variant": "EqualUnique",
+ "Keyspace": {
+ "Name": "user",
+ "Sharded": true
+ },
+ "FieldQuery": "select user_id, col from music where 1 != 1",
+ "Query": "select user_id, col from music where user_id = 3",
+ "Values": [
+ "3"
+ ],
+ "Vindex": "user_index"
+ },
+ {
+ "InputName": "Outer",
+ "OperatorType": "Route",
+ "Variant": "Scatter",
+ "Keyspace": {
+ "Name": "user",
+ "Sharded": true
+ },
+ "FieldQuery": "select id from `user` where 1 != 1",
+ "Query": "select id from `user` where (col, `name`) < (:__sq1_0, :__sq1_1) and col > :__sq2"
+ }
+ ]
+ }
+ ]
+ },
+ "TablesUsed": [
+ "user.music",
+ "user.user"
+ ]
+ }
}
]
diff --git a/go/vt/vtgate/planbuilder/testdata/select_cases.json b/go/vt/vtgate/planbuilder/testdata/select_cases.json
index 33d6fc95992..a92cb0597f1 100644
--- a/go/vt/vtgate/planbuilder/testdata/select_cases.json
+++ b/go/vt/vtgate/planbuilder/testdata/select_cases.json
@@ -6238,5 +6238,106 @@
"user.user"
]
}
+ },
+ {
+ "comment": "row comparison with a value subquery in the select list binds each column of the row",
+ "query": "select id, (col, name) = (select col, name from user where id = 5) from user where id = 1",
+ "plan": {
+ "Type": "Complex",
+ "QueryType": "SELECT",
+ "Original": "select id, (col, name) = (select col, name from user where id = 5) from user where id = 1",
+ "Instructions": {
+ "OperatorType": "UncorrelatedSubquery",
+ "Variant": "PulloutValue",
+ "PulloutVars": [
+ "__sq1_0",
+ "__sq1_1"
+ ],
+ "Inputs": [
+ {
+ "InputName": "SubQuery",
+ "OperatorType": "Route",
+ "Variant": "EqualUnique",
+ "Keyspace": {
+ "Name": "user",
+ "Sharded": true
+ },
+ "FieldQuery": "select col, `name` from `user` where 1 != 1",
+ "Query": "select col, `name` from `user` where id = 5",
+ "Values": [
+ "5"
+ ],
+ "Vindex": "user_index"
+ },
+ {
+ "InputName": "Outer",
+ "OperatorType": "Route",
+ "Variant": "EqualUnique",
+ "Keyspace": {
+ "Name": "user",
+ "Sharded": true
+ },
+ "FieldQuery": "select id, (col, `name`) = (:__sq1_0, :__sq1_1) as `(col, ``name``) = (select col, ``name`` from ``user`` where id = 5)` from `user` where 1 != 1",
+ "Query": "select id, (col, `name`) = (:__sq1_0, :__sq1_1) as `(col, ``name``) = (select col, ``name`` from ``user`` where id = 5)` from `user` where id = 1",
+ "Values": [
+ "1"
+ ],
+ "Vindex": "user_index"
+ }
+ ]
+ },
+ "TablesUsed": [
+ "user.user"
+ ]
+ }
+ },
+ {
+ "comment": "row IN subquery in the select list has no has-values guard, so its rows are not bound as tuples",
+ "query": "select id, (col, name) in (select user_id, col from music where user_id = 5) from user",
+ "skip_e2e": true,
+ "plan": {
+ "Type": "Complex",
+ "QueryType": "SELECT",
+ "Original": "select id, (col, name) in (select user_id, col from music where user_id = 5) from user",
+ "Instructions": {
+ "OperatorType": "UncorrelatedSubquery",
+ "Variant": "PulloutIn",
+ "PulloutVars": [
+ "__sq1"
+ ],
+ "Inputs": [
+ {
+ "InputName": "SubQuery",
+ "OperatorType": "Route",
+ "Variant": "EqualUnique",
+ "Keyspace": {
+ "Name": "user",
+ "Sharded": true
+ },
+ "FieldQuery": "select user_id, col from music where 1 != 1",
+ "Query": "select user_id, col from music where user_id = 5",
+ "Values": [
+ "5"
+ ],
+ "Vindex": "user_index"
+ },
+ {
+ "InputName": "Outer",
+ "OperatorType": "Route",
+ "Variant": "Scatter",
+ "Keyspace": {
+ "Name": "user",
+ "Sharded": true
+ },
+ "FieldQuery": "select id, (col, `name`) in ::__sq1 as `(col, ``name``) in (select user_id, col from music where user_id = 5)` from `user` where 1 != 1",
+ "Query": "select id, (col, `name`) in ::__sq1 as `(col, ``name``) in (select user_id, col from music where user_id = 5)` from `user`"
+ }
+ ]
+ },
+ "TablesUsed": [
+ "user.music",
+ "user.user"
+ ]
+ }
}
]
diff --git a/go/vt/vtgate/planbuilder/testdata/unsupported_cases.json b/go/vt/vtgate/planbuilder/testdata/unsupported_cases.json
index 95994b678a9..5a6d70e8850 100644
--- a/go/vt/vtgate/planbuilder/testdata/unsupported_cases.json
+++ b/go/vt/vtgate/planbuilder/testdata/unsupported_cases.json
@@ -423,5 +423,20 @@
"comment": "unknown sql_mode names fail with MySQL's error",
"query": "set sql_mode = 'BOGUS'",
"plan": "Variable 'sql_mode' can't be set to the value of 'BOGUS'"
+ },
+ {
+ "comment": "row comparisons with two subqueries that can't be merged in one predicate are refused, since the second subquery's result would be lost",
+ "query": "select id from user where (col, name) < (select user_id, col from music where user_id = 3) or (col, name) > (select user_id, col from music where user_id = 8)",
+ "plan": "VT12001: unsupported: row comparison with an unmergable subquery in a predicate with other subqueries"
+ },
+ {
+ "comment": "a row comparison and a scalar comparison with subqueries that can't be merged in one predicate are refused",
+ "query": "select id from user where col < (select user_id from music where user_id = 3) or (col, name) > (select user_id, col from music where user_id = 8)",
+ "plan": "VT12001: unsupported: row comparison with an unmergable subquery in a predicate with other subqueries"
+ },
+ {
+ "comment": "a DELETE with row comparisons against two subqueries that can't be merged in one predicate is refused",
+ "query": "delete from user where (col, name) in (select user_id, col from music where user_id = 3) or (col, name) = (select user_id, col from music where user_id = 8)",
+ "plan": "VT12001: unsupported: row comparison with an unmergable subquery in a predicate with other subqueries"
}
]
From 946d0772fbb5d76f14bbe258c489d7f54f649cca Mon Sep 17 00:00:00 2001
From: "vitess-bot[bot]" <108069721+vitess-bot[bot]@users.noreply.github.com>
Date: Thu, 22 Oct 2026 11:51:36 +0200
Subject: [PATCH 24/31] [release-23.0] evalengine: remove every repeated remstr
in TRIM (#21237) (#21490)
Signed-off-by: breken-ai <312387581+breken-ai@users.noreply.github.com>
Co-authored-by: vitess-bot[bot] <108069721+vitess-bot[bot]@users.noreply.github.com>
Co-authored-by: breken-ai <312387581+breken-ai@users.noreply.github.com>
Co-authored-by: Claude Opus 5.5 (1M context)
---
go/vt/vtgate/evalengine/compiler_asm.go | 6 ++---
go/vt/vtgate/evalengine/compiler_test.go | 17 ++++++++++++
go/vt/vtgate/evalengine/fn_string.go | 30 ++++++++++++++++++---
go/vt/vtgate/evalengine/testcases/inputs.go | 1 +
4 files changed, 48 insertions(+), 6 deletions(-)
diff --git a/go/vt/vtgate/evalengine/compiler_asm.go b/go/vt/vtgate/evalengine/compiler_asm.go
index 7513637e8ab..e1d245193be 100644
--- a/go/vt/vtgate/evalengine/compiler_asm.go
+++ b/go/vt/vtgate/evalengine/compiler_asm.go
@@ -3040,7 +3040,7 @@ func (asm *assembler) Fn_LTRIM2(col collations.TypedCollation) {
str := env.vm.stack[env.vm.sp-2].(*evalBytes)
pat := env.vm.stack[env.vm.sp-1].(*evalBytes)
str.tt = int16(sqltypes.VarChar)
- str.bytes = bytes.TrimPrefix(str.bytes, pat.bytes)
+ str.bytes = trimLeftRepeated(str.bytes, pat.bytes)
str.col = col
env.vm.sp--
return 1
@@ -3053,7 +3053,7 @@ func (asm *assembler) Fn_RTRIM2(col collations.TypedCollation) {
str := env.vm.stack[env.vm.sp-2].(*evalBytes)
pat := env.vm.stack[env.vm.sp-1].(*evalBytes)
str.tt = int16(sqltypes.VarChar)
- str.bytes = bytes.TrimSuffix(str.bytes, pat.bytes)
+ str.bytes = trimRightRepeated(str.bytes, pat.bytes)
str.col = col
env.vm.sp--
return 1
@@ -3066,7 +3066,7 @@ func (asm *assembler) Fn_TRIM2(col collations.TypedCollation) {
str := env.vm.stack[env.vm.sp-2].(*evalBytes)
pat := env.vm.stack[env.vm.sp-1].(*evalBytes)
str.tt = int16(sqltypes.VarChar)
- str.bytes = bytes.TrimPrefix(bytes.TrimSuffix(str.bytes, pat.bytes), pat.bytes)
+ str.bytes = trimRightRepeated(trimLeftRepeated(str.bytes, pat.bytes), pat.bytes)
str.col = col
env.vm.sp--
return 1
diff --git a/go/vt/vtgate/evalengine/compiler_test.go b/go/vt/vtgate/evalengine/compiler_test.go
index af7cc144c83..8cf1390490a 100644
--- a/go/vt/vtgate/evalengine/compiler_test.go
+++ b/go/vt/vtgate/evalengine/compiler_test.go
@@ -871,6 +871,23 @@ func TestCompilerSingle(t *testing.T) {
expression: `GREATEST(JSON_OBJECT(), JSON_ARRAY())`,
result: `VARCHAR("{}")`,
},
+ {
+ // TRIM with a remstr removes every repeated occurrence, not only one.
+ expression: `TRIM(BOTH 'x' FROM 'xxxbarxxx')`,
+ result: `VARCHAR("bar")`,
+ },
+ {
+ expression: `TRIM('x' FROM 'xxxbarxxx')`,
+ result: `VARCHAR("bar")`,
+ },
+ {
+ expression: `TRIM(LEADING 'ab' FROM 'ababcab')`,
+ result: `VARCHAR("cab")`,
+ },
+ {
+ expression: `TRIM(TRAILING '0' FROM '1.500')`,
+ result: `VARCHAR("1.5")`,
+ },
}
tz, _ := time.LoadLocation("Europe/Madrid")
diff --git a/go/vt/vtgate/evalengine/fn_string.go b/go/vt/vtgate/evalengine/fn_string.go
index 34d2bdaac9e..2ad5e9c63f3 100644
--- a/go/vt/vtgate/evalengine/fn_string.go
+++ b/go/vt/vtgate/evalengine/fn_string.go
@@ -1469,14 +1469,38 @@ func (call *builtinTrim) eval(env *ExpressionEnv) (eval, error) {
switch call.trim {
case sqlparser.LeadingTrimType:
- return newEvalText(bytes.TrimPrefix(text.bytes, pat.bytes), text.col), nil
+ return newEvalText(trimLeftRepeated(text.bytes, pat.bytes), text.col), nil
case sqlparser.TrailingTrimType:
- return newEvalText(bytes.TrimSuffix(text.bytes, pat.bytes), text.col), nil
+ return newEvalText(trimRightRepeated(text.bytes, pat.bytes), text.col), nil
default:
- return newEvalText(bytes.TrimPrefix(bytes.TrimSuffix(text.bytes, pat.bytes), pat.bytes), text.col), nil
+ return newEvalText(trimRightRepeated(trimLeftRepeated(text.bytes, pat.bytes), pat.bytes), text.col), nil
}
}
+// trimLeftRepeated removes every leading occurrence of pat from str, the way
+// MySQL's TRIM(LEADING pat FROM str) does: TRIM(LEADING 'x' FROM 'xxxa') is 'a'.
+func trimLeftRepeated(str, pat []byte) []byte {
+ if len(pat) == 0 {
+ return str
+ }
+ for bytes.HasPrefix(str, pat) {
+ str = str[len(pat):]
+ }
+ return str
+}
+
+// trimRightRepeated removes every trailing occurrence of pat from str, the way
+// MySQL's TRIM(TRAILING pat FROM str) does: TRIM(TRAILING '0' FROM '1.500') is '1.5'.
+func trimRightRepeated(str, pat []byte) []byte {
+ if len(pat) == 0 {
+ return str
+ }
+ for bytes.HasSuffix(str, pat) {
+ str = str[:len(str)-len(pat)]
+ }
+ return str
+}
+
func (call *builtinTrim) compile(c *compiler) (ctype, error) {
str, err := call.Arguments[0].compile(c)
if err != nil {
diff --git a/go/vt/vtgate/evalengine/testcases/inputs.go b/go/vt/vtgate/evalengine/testcases/inputs.go
index c6aa41d3f79..f4a82c18ccc 100644
--- a/go/vt/vtgate/evalengine/testcases/inputs.go
+++ b/go/vt/vtgate/evalengine/testcases/inputs.go
@@ -339,6 +339,7 @@ var inputTrimStrings = []string{
"\"a\"",
"\"abc\"",
"'abca'",
+ "'aabcaa'",
"1",
"-1",
"0123",
From 40f044ca90966aed19356e8742e795e4cc9a232d Mon Sep 17 00:00:00 2001
From: "vitess-bot[bot]" <108069721+vitess-bot[bot]@users.noreply.github.com>
Date: Thu, 22 Oct 2026 08:58:16 -0400
Subject: [PATCH 25/31] [release-23.0] test: remove dead waits from the
reparent e2e tests (#21623) (#21646)
Signed-off-by: Arthur Schreiber
Co-authored-by: Arthur Schreiber
Co-authored-by: Claude Opus 5.5
---
go/test/endtoend/cluster/cluster_process.go | 17 +++--
.../reparent/emergencyreparent/ers_test.go | 22 ++++---
.../reparent/newfeaturetest/reparent_test.go | 6 +-
.../reparent_with_open_tx_test.go | 4 ++
.../reparent/plannedreparent/reparent_test.go | 27 ++++----
go/test/endtoend/reparent/utils/utils.go | 63 ++++++++++++++++---
6 files changed, 99 insertions(+), 40 deletions(-)
diff --git a/go/test/endtoend/cluster/cluster_process.go b/go/test/endtoend/cluster/cluster_process.go
index 417966c5b45..3d112244bb8 100644
--- a/go/test/endtoend/cluster/cluster_process.go
+++ b/go/test/endtoend/cluster/cluster_process.go
@@ -86,6 +86,16 @@ func IsCoverage() bool {
return *isCoverage
}
+// KillDiscardedMySQL reports whether a mysqld whose data is never read again
+// is killed instead of shut down gracefully. On CI the data directory is
+// discarded after the test run, so nothing needs to be flushed to disk and a
+// graceful shutdown buys nothing: killing skips the shutdown ack wait that
+// can stall a semi-sync primary for many seconds. Coverage runs still shut
+// down gracefully so that the mysqlctl shutdown path stays exercised.
+func KillDiscardedMySQL() bool {
+ return os.Getenv("CI") == "true" && !*isCoverage
+}
+
// LocalProcessCluster Testcases need to use this to iniate a cluster
type LocalProcessCluster struct {
Keyspaces []Keyspace
@@ -1076,12 +1086,7 @@ func (cluster *LocalProcessCluster) Teardown() {
log.Errorf("Error in vtadmin teardown: %v", err)
}
- // On CI the data directory is discarded after the test run, so nothing
- // needs to be flushed to disk and a graceful mysqld shutdown buys us
- // nothing. Killing mysqld skips the shutdown ack wait that can stall a
- // semi-sync primary for many seconds per cluster. Coverage runs still
- // shut down gracefully so that the mysqlctl shutdown path stays exercised.
- killMySQL := os.Getenv("CI") == "true" && !*isCoverage
+ killMySQL := KillDiscardedMySQL()
var mysqlctlProcessList []*exec.Cmd
var mysqlctlTabletUIDs []int
diff --git a/go/test/endtoend/reparent/emergencyreparent/ers_test.go b/go/test/endtoend/reparent/emergencyreparent/ers_test.go
index cf0adaf507f..d8eb4a791ce 100644
--- a/go/test/endtoend/reparent/emergencyreparent/ers_test.go
+++ b/go/test/endtoend/reparent/emergencyreparent/ers_test.go
@@ -19,6 +19,7 @@ package emergencyreparent
import (
"context"
"os/exec"
+ "slices"
"sync"
"testing"
"time"
@@ -48,7 +49,12 @@ func TestTrivialERS(t *testing.T) {
out, err := utils.Ers(clusterInstance, nil, "60s", "30s")
log.Infof("ERS loop %d. EmergencyReparentShard Output: %v", i, out)
require.NoError(t, err)
- time.Sleep(5 * time.Second)
+
+ // ERS repoints some replicas after it returns: wait until every
+ // tablet replicates from the new primary before the next ERS.
+ primary := utils.GetShardPrimary(t, clusterInstance)
+ replicas := slices.DeleteFunc(slices.Clone(tablets), func(tablet *cluster.Vttablet) bool { return tablet == primary })
+ utils.ConfirmReplication(t, primary, replicas)
}
// We should do the same for vtctl binary
for i := 1; i <= 4; i++ {
@@ -211,7 +217,7 @@ func TestEmergencyReparentWithBlockedPrimary(t *testing.T) {
}()
wg.Add(1)
- waitReplicasTimeout := time.Second * 10
+ waitReplicasTimeout := time.Second * 5
go func() {
defer wg.Done()
@@ -228,7 +234,7 @@ func TestEmergencyReparentWithBlockedPrimary(t *testing.T) {
wg.Wait()
- // We need to wait at least 10 seconds here to ensure the wait-for-replicas-timeout has passed,
+ // We need to wait until the wait-for-replicas-timeout has passed (twice it, for margin),
// before we resume the old primary - otherwise the old primary will receive a `SetReplicationSource` call.
time.Sleep(waitReplicasTimeout * 2)
@@ -366,7 +372,7 @@ func TestERSPromoteRdonly(t *testing.T) {
utils.ConfirmReplication(t, tablets[0], tablets[1:])
// Make the current primary agent and database unavailable.
- utils.StopTablet(t, tablets[0], true)
+ utils.KillTablet(t, tablets[0])
// We expect this one to fail because we have ignored all the replicas and have only the rdonly's which should not be promoted
out, err := utils.ErsIgnoreTablet(clusterInstance, nil, "30s", "30s", []*cluster.Vttablet{tablets[3]}, false)
@@ -388,7 +394,7 @@ func TestERSPreventCrossCellPromotion(t *testing.T) {
utils.ConfirmReplication(t, tablets[0], []*cluster.Vttablet{tablets[1], tablets[2], tablets[3]})
// Make the current primary agent and database unavailable.
- utils.StopTablet(t, tablets[0], true)
+ utils.KillTablet(t, tablets[0])
// We expect that tablets[2] will be promoted since it is in the same cell as the previous primary
out, err := utils.ErsIgnoreTablet(clusterInstance, nil, "60s", "30s", []*cluster.Vttablet{tablets[1]}, true)
@@ -437,7 +443,7 @@ func TestPullFromRdonly(t *testing.T) {
insertVal := utils.ConfirmReplication(t, tablets[0], []*cluster.Vttablet{rdonly})
// Make the current primary agent and database unavailable.
- utils.StopTablet(t, tablets[0], true)
+ utils.KillTablet(t, tablets[0])
// start the replication back on the two tablets
err = clusterInstance.VtctldClientProcess.ExecuteCommand("StartReplication", tablets[2].Alias)
@@ -585,8 +591,8 @@ func TestRecoverWithMultipleFailures(t *testing.T) {
utils.ConfirmReplication(t, tablets[0], tablets[1:])
// Make the rdonly and primary tablets and databases unavailable.
- utils.StopTablet(t, tablets[1], true)
- utils.StopTablet(t, tablets[0], true)
+ utils.KillTablet(t, tablets[1])
+ utils.KillTablet(t, tablets[0])
// We expect this to succeed since we only have 1 primary eligible tablet which is down
out, err := utils.Ers(clusterInstance, nil, "30s", "10s")
diff --git a/go/test/endtoend/reparent/newfeaturetest/reparent_test.go b/go/test/endtoend/reparent/newfeaturetest/reparent_test.go
index 6d4a5fb0f2b..b8010877e51 100644
--- a/go/test/endtoend/reparent/newfeaturetest/reparent_test.go
+++ b/go/test/endtoend/reparent/newfeaturetest/reparent_test.go
@@ -83,8 +83,8 @@ func TestSingleReplicaERS(t *testing.T) {
// Delete and stop two tablets. We only want to have 2 tablets for this test.
utils.DeleteTablet(t, clusterInstance, tablets[2])
utils.DeleteTablet(t, clusterInstance, tablets[3])
- utils.StopTablet(t, tablets[2], true)
- utils.StopTablet(t, tablets[3], true)
+ utils.KillTablet(t, tablets[2])
+ utils.KillTablet(t, tablets[3])
// Reparent to the other replica
output, err := utils.Prs(t, clusterInstance, tablets[1])
@@ -94,7 +94,7 @@ func TestSingleReplicaERS(t *testing.T) {
utils.ConfirmReplication(t, tablets[1], []*cluster.Vttablet{tablets[0]})
// Make the current primary vttablet unavailable.
- utils.StopTablet(t, tablets[1], true)
+ utils.KillTablet(t, tablets[1])
// Run an ERS with only one replica reachable. Also, this replica is such that it was a primary before.
output, err = utils.Ers(clusterInstance, tablets[0], "", "")
diff --git a/go/test/endtoend/reparent/newfeaturetest/reparent_with_open_tx_test.go b/go/test/endtoend/reparent/newfeaturetest/reparent_with_open_tx_test.go
index 541378a5604..c718ae32307 100644
--- a/go/test/endtoend/reparent/newfeaturetest/reparent_with_open_tx_test.go
+++ b/go/test/endtoend/reparent/newfeaturetest/reparent_with_open_tx_test.go
@@ -189,6 +189,10 @@ func TestErrorsInTransaction(t *testing.T) {
clusterInstance := utils.SetupShardedReparentCluster(t, policy.DurabilitySemiSync, []string{
"--queryserver-config-transaction-timeout", "5m",
"--queryserver-config-query-timeout", "5m",
+ // vtgate keeps a health stream open to every tablet, so each vttablet
+ // stop waits out the whole OnTermSync timeout (10s by default) for the
+ // gRPC server to stop gracefully.
+ "--onterm-timeout", "2s",
})
defer utils.TeardownCluster(clusterInstance)
diff --git a/go/test/endtoend/reparent/plannedreparent/reparent_test.go b/go/test/endtoend/reparent/plannedreparent/reparent_test.go
index 520a08cd42e..2a4936eb58f 100644
--- a/go/test/endtoend/reparent/plannedreparent/reparent_test.go
+++ b/go/test/endtoend/reparent/plannedreparent/reparent_test.go
@@ -31,7 +31,6 @@ import (
"vitess.io/vitess/go/mysql/replication"
"vitess.io/vitess/go/test/endtoend/cluster"
"vitess.io/vitess/go/test/endtoend/reparent/utils"
- "vitess.io/vitess/go/vt/log"
replicationdatapb "vitess.io/vitess/go/vt/proto/replicationdata"
"vitess.io/vitess/go/vt/vtctl/reparentutil/policy"
)
@@ -102,8 +101,16 @@ func TestPRSWithDrainedLaggingTablet(t *testing.T) {
res := utils.RunSQL(context.Background(), t, `select msg from vt_insert_test`, tablets[1])
assert.Equal(t, 1, len(res.Rows))
- // Perform a graceful reparent operation
- utils.Prs(t, clusterInstance, tablets[2])
+ // Perform a graceful reparent operation. The drained tablet can't reach
+ // the reparent journal within the wait-replicas-timeout because of its
+ // replication delay, so PRS may report it as failed, but no other tablet.
+ out, err := utils.PrsWithTimeout(t, clusterInstance, tablets[2], false, "", "5s")
+ if err != nil {
+ assert.Contains(t, out, fmt.Sprintf("tablet %s failed to SetReplicationSource", tablets[1].Alias))
+ for _, tablet := range []*cluster.Vttablet{tablets[0], tablets[3]} {
+ assert.NotContains(t, out, fmt.Sprintf("tablet %s failed", tablet.Alias))
+ }
+ }
utils.ValidateTopology(t, clusterInstance, false)
utils.CheckPrimaryTablet(t, clusterInstance, tablets[2])
}
@@ -155,7 +162,7 @@ func TestReparentAvoid(t *testing.T) {
utils.CheckPrimaryTablet(t, clusterInstance, tablets[1])
// If we kill the tablet in the same cell as primary then reparent --avoid_tablet will fail.
- utils.StopTablet(t, tablets[0], true)
+ utils.KillTablet(t, tablets[0])
out, err := utils.PrsAvoid(t, clusterInstance, tablets[1])
require.Error(t, err)
vtctldVersion, err := cluster.GetMajorVersion("vtctld")
@@ -194,20 +201,8 @@ func TestReparentFromOutside(t *testing.T) {
func TestReparentFromOutsideWithNoPrimary(t *testing.T) {
clusterInstance := utils.SetupReparentCluster(t, policy.DurabilitySemiSync)
defer utils.TeardownCluster(clusterInstance)
- tablets := clusterInstance.Keyspaces[0].Shards[0].Vttablets
reparentFromOutside(t, clusterInstance, true)
-
- // FIXME: @Deepthi: is this needed, since we teardown the cluster, does this achieve any additional test coverage?
- // We will have to restart mysql to avoid hanging/locks due to external Reparent
- for _, tablet := range tablets {
- log.Infof("Restarting MySql for tablet %v", tablet.Alias)
- err := tablet.MysqlctlProcess.Stop()
- require.NoError(t, err)
- tablet.MysqlctlProcess.InitMysql = false
- err = tablet.MysqlctlProcess.Start()
- require.NoError(t, err)
- }
}
func reparentFromOutside(t *testing.T, clusterInstance *cluster.LocalProcessCluster, downPrimary bool) {
diff --git a/go/test/endtoend/reparent/utils/utils.go b/go/test/endtoend/reparent/utils/utils.go
index 1ab4ce543b6..a549fb57bc6 100644
--- a/go/test/endtoend/reparent/utils/utils.go
+++ b/go/test/endtoend/reparent/utils/utils.go
@@ -19,11 +19,14 @@ package utils
import (
"context"
"encoding/json"
+ "errors"
"fmt"
+ "net"
"os"
"os/exec"
"path"
"reflect"
+ "strconv"
"strings"
"testing"
"time"
@@ -37,6 +40,7 @@ import (
"vitess.io/vitess/go/vt/log"
querypb "vitess.io/vitess/go/vt/proto/query"
topodatapb "vitess.io/vitess/go/vt/proto/topodata"
+ "vitess.io/vitess/go/vt/topo/topoproto"
"vitess.io/vitess/go/vt/utils"
"vitess.io/vitess/go/vt/vtctl/reparentutil/policy"
"vitess.io/vitess/go/vt/vttablet/tabletconn"
@@ -578,6 +582,37 @@ func StopTablet(t *testing.T, tab *cluster.Vttablet, stopDatabase bool) {
}
}
+// KillTablet stops the tablet's vttablet gracefully, then kills its mysqld
+// when cluster.KillDiscardedMySQL allows it, and shuts mysqld down
+// gracefully otherwise. Use it only for a tablet whose mysqld is never
+// started or read again: a kill models a dead primary at least as well as a
+// clean shutdown, which takes many seconds for a semi-sync primary.
+func KillTablet(t *testing.T, tab *cluster.Vttablet) {
+ err := tab.VttabletProcess.TearDownWithTimeout(30 * time.Second)
+ require.NoError(t, err)
+ if !cluster.KillDiscardedMySQL() {
+ require.NoError(t, tab.MysqlctlProcess.Stop())
+ return
+ }
+ require.NoError(t, tab.MysqlctlProcess.Kill())
+ // Kill only sends the signal, so wait until mysqld refuses connections.
+ addr := net.JoinHostPort(Hostname, strconv.Itoa(tab.MySQLPort))
+ require.Eventually(t, func() bool {
+ conn, err := net.DialTimeout("tcp", addr, time.Second)
+ if err != nil {
+ return true
+ }
+ conn.Close()
+ return false
+ }, 30*time.Second, 10*time.Millisecond, "mysqld of %s still accepts connections", tab.Alias)
+ // The teardown kills mysqld by the pid in this file, which may belong to
+ // another process by then.
+ err = os.Remove(path.Join(tab.MysqlctlProcess.BasePath(), "mysql.pid"))
+ if !errors.Is(err, os.ErrNotExist) {
+ require.NoError(t, err)
+ }
+}
+
// RestartTablet restarts the tablet
func RestartTablet(t *testing.T, clusterInstance *cluster.LocalProcessCluster, tab *cluster.Vttablet) {
tab.MysqlctlProcess.InitMysql = false
@@ -631,6 +666,20 @@ func GetNewPrimary(t *testing.T, clusterInstance *cluster.LocalProcessCluster) *
return newPrimary
}
+// GetShardPrimary returns the tablet that the shard record names as primary.
+func GetShardPrimary(t *testing.T, clusterInstance *cluster.LocalProcessCluster) *cluster.Vttablet {
+ shard, err := clusterInstance.VtctldClientProcess.GetShard(KeyspaceName, ShardName)
+ require.NoError(t, err)
+ alias := topoproto.TabletAliasString(shard.GetShard().GetPrimaryAlias())
+ for _, tablet := range clusterInstance.Keyspaces[0].Shards[0].Vttablets {
+ if tablet.Alias == alias {
+ return tablet
+ }
+ }
+ require.FailNow(t, "the shard primary is not a tablet of the cluster", "primary alias: %q", alias)
+ return nil
+}
+
// GetShardReplicationPositions gets the shards replication positions.
// This should not generally be called directly, instead use the WaitForReplicationToCatchup method.
func GetShardReplicationPositions(t *testing.T, clusterInstance *cluster.LocalProcessCluster, keyspaceName, shardName string, doPrint bool) []string {
@@ -651,19 +700,19 @@ func GetShardReplicationPositions(t *testing.T, clusterInstance *cluster.LocalPr
}
func WaitForReplicationToStart(t *testing.T, clusterInstance *cluster.LocalProcessCluster, keyspaceName, shardName string, tabletCnt int, doPrint bool) {
- tkr := time.NewTicker(500 * time.Millisecond)
+ timeout := time.After(replicationWaitTimeout)
+ tkr := time.NewTicker(100 * time.Millisecond)
defer tkr.Stop()
for {
+ strArray := GetShardReplicationPositions(t, clusterInstance, keyspaceName, shardName, true)
+ if len(strArray) == tabletCnt && strings.Contains(strArray[0], "primary") { // primary first
+ return
+ }
select {
case <-tkr.C:
- strArray := GetShardReplicationPositions(t, clusterInstance, KeyspaceName, shardName, true)
- if len(strArray) == tabletCnt && strings.Contains(strArray[0], "primary") { // primary first
- return
- }
- case <-time.After(replicationWaitTimeout):
+ case <-timeout:
require.FailNow(t, fmt.Sprintf("replication did not start everywhere in %s/%s within the timeout of %v",
keyspaceName, shardName, replicationWaitTimeout))
- return
}
}
}
From 0424593b49bce4f990ba06374a0707fe190988c9 Mon Sep 17 00:00:00 2001
From: "vitess-bot[bot]" <108069721+vitess-bot[bot]@users.noreply.github.com>
Date: Thu, 22 Oct 2026 09:08:04 -0400
Subject: [PATCH 26/31] [release-23.0] CI: diff paths-filter against the base
of the pull request's merge commit (#21445) (#21503)
Signed-off-by: Arthur Schreiber
Co-authored-by: vitess-bot[bot] <108069721+vitess-bot[bot]@users.noreply.github.com>
Co-authored-by: Arthur Schreiber
Co-authored-by: Claude Opus 5.5
---
.../check_make_vtadmin_authz_testgen.yml | 12 ++
.../check_make_vtadmin_web_proto.yml | 12 ++
.github/workflows/cluster_endtoend.yml | 12 ++
.../cluster_endtoend_disk_health_monitor.yml | 145 ++++++++++++++++++
.github/workflows/codecov.yml | 10 ++
.github/workflows/docker_ci.yml | 12 ++
.github/workflows/e2e_race.yml | 12 ++
.github/workflows/endtoend.yml | 12 ++
.github/workflows/local_example.yml | 12 ++
.github/workflows/region_example.yml | 12 ++
.github/workflows/static_checks_etc.yml | 12 ++
.github/workflows/unit_test.yml | 12 ++
.../upgrade_downgrade_test_backups_e2e.yml | 10 ++
...owngrade_test_backups_e2e_next_release.yml | 10 ++
.../upgrade_downgrade_test_backups_manual.yml | 10 ++
...grade_test_backups_manual_next_release.yml | 10 ++
.../upgrade_downgrade_test_onlineddl_flow.yml | 10 ++
...e_downgrade_test_query_serving_queries.yml | 10 ++
...downgrade_test_query_serving_queries_2.yml | 10 ++
...t_query_serving_queries_2_next_release.yml | 10 ++
...est_query_serving_queries_next_release.yml | 10 ++
...de_downgrade_test_query_serving_schema.yml | 10 ++
...test_query_serving_schema_next_release.yml | 10 ++
...rade_downgrade_test_reparent_new_vtctl.yml | 10 ++
...e_downgrade_test_reparent_new_vttablet.yml | 10 ++
...rade_downgrade_test_reparent_old_vtctl.yml | 10 ++
...e_downgrade_test_reparent_old_vttablet.yml | 10 ++
.../upgrade_downgrade_test_semi_sync.yml | 10 ++
.github/workflows/vitess_tester_vtgate.yml | 12 ++
.github/workflows/vtop_example.yml | 12 ++
30 files changed, 459 insertions(+)
create mode 100644 .github/workflows/cluster_endtoend_disk_health_monitor.yml
diff --git a/.github/workflows/check_make_vtadmin_authz_testgen.yml b/.github/workflows/check_make_vtadmin_authz_testgen.yml
index 7a16e038d5d..14e97abce5c 100644
--- a/.github/workflows/check_make_vtadmin_authz_testgen.yml
+++ b/.github/workflows/check_make_vtadmin_authz_testgen.yml
@@ -25,13 +25,25 @@ jobs:
- name: Check out code
uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
with:
+ # The merge commit and its first parent, for the path filter.
+ fetch-depth: 2
persist-credentials: 'false'
+ - name: Find the base of the pull request's merge commit
+ # github.event.pull_request.base.sha is not updated when the base branch
+ # moves, so paths-filter would also count the base branch's newer commits.
+ # With token: '', paths-filter diffs against `base` on pull_request
+ # events too (see its README); action.yml's input description is stale.
+ id: merge-base
+ if: github.event_name == 'pull_request'
+ run: echo "sha=$(git rev-parse HEAD^1)" >> "$GITHUB_OUTPUT"
+
- name: Check for changes in relevant files
uses: dorny/paths-filter@ceb8a2b8f2d89434be7ff52d3de7ec3738c5cc9d # v4.0.3
id: changes
with:
token: ''
+ base: ${{ steps.merge-base.outputs.sha }}
filters: |
vtadmin_changes:
- 'bootstrap.sh'
diff --git a/.github/workflows/check_make_vtadmin_web_proto.yml b/.github/workflows/check_make_vtadmin_web_proto.yml
index 961db086c98..cbfaeb02338 100644
--- a/.github/workflows/check_make_vtadmin_web_proto.yml
+++ b/.github/workflows/check_make_vtadmin_web_proto.yml
@@ -25,16 +25,28 @@ jobs:
- name: Check out code
uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
with:
+ # The merge commit and its first parent, for the path filter.
+ fetch-depth: 2
persist-credentials: 'false'
- name: Tune the OS
uses: $/.github/actions/tune-os
+ - name: Find the base of the pull request's merge commit
+ # github.event.pull_request.base.sha is not updated when the base branch
+ # moves, so paths-filter would also count the base branch's newer commits.
+ # With token: '', paths-filter diffs against `base` on pull_request
+ # events too (see its README); action.yml's input description is stale.
+ id: merge-base
+ if: github.event_name == 'pull_request'
+ run: echo "sha=$(git rev-parse HEAD^1)" >> "$GITHUB_OUTPUT"
+
- name: Check for changes in relevant files
uses: dorny/paths-filter@ceb8a2b8f2d89434be7ff52d3de7ec3738c5cc9d # v4.0.3
id: changes
with:
token: ''
+ base: ${{ steps.merge-base.outputs.sha }}
filters: |
proto_changes:
- 'bootstrap.sh'
diff --git a/.github/workflows/cluster_endtoend.yml b/.github/workflows/cluster_endtoend.yml
index 785529e01e1..63138ac7b2e 100644
--- a/.github/workflows/cluster_endtoend.yml
+++ b/.github/workflows/cluster_endtoend.yml
@@ -36,6 +36,8 @@ jobs:
- name: Check out code
uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
with:
+ # The merge commit and its first parent, for the path filter.
+ fetch-depth: 2
persist-credentials: "false"
# Generated before the path filter so that a filter failure still leaves
@@ -73,11 +75,21 @@ jobs:
echo "matrix={\"include\":$matrix}" >> $GITHUB_OUTPUT
echo "shard_count=$(echo "$matrix" | jq length)" >> $GITHUB_OUTPUT
+ - name: Find the base of the pull request's merge commit
+ # github.event.pull_request.base.sha is not updated when the base branch
+ # moves, so paths-filter would also count the base branch's newer commits.
+ # With token: '', paths-filter diffs against `base` on pull_request
+ # events too (see its README); action.yml's input description is stale.
+ id: merge-base
+ if: github.event_name == 'pull_request'
+ run: echo "sha=$(git rev-parse HEAD^1)" >> "$GITHUB_OUTPUT"
+
- name: Check for changes in relevant files
uses: dorny/paths-filter@ceb8a2b8f2d89434be7ff52d3de7ec3738c5cc9d # v4.0.3
id: changes
with:
token: ""
+ base: ${{ steps.merge-base.outputs.sha }}
filters: |
end_to_end:
- 'test/config.json'
diff --git a/.github/workflows/cluster_endtoend_disk_health_monitor.yml b/.github/workflows/cluster_endtoend_disk_health_monitor.yml
new file mode 100644
index 00000000000..59892c4c6a4
--- /dev/null
+++ b/.github/workflows/cluster_endtoend_disk_health_monitor.yml
@@ -0,0 +1,145 @@
+name: Cluster End-to-End Tests (tabletmanager_disk_health_monitor)
+
+on:
+ push:
+ branches:
+ - "main"
+ - "release-[0-9]+.[0-9]"
+ tags: "**"
+ pull_request:
+ branches: "**"
+
+concurrency:
+ group: format('{0}-{1}', ${{ github.ref }}, 'Cluster End-to-End Tests (tabletmanager_disk_health_monitor)')
+ cancel-in-progress: true
+
+permissions: read-all
+
+env:
+ LAUNCHABLE_ORGANIZATION: "vitess"
+ LAUNCHABLE_WORKSPACE: "vitess-app"
+ GITHUB_PR_HEAD_SHA: "${{ github.event.pull_request.head.sha }}"
+
+jobs:
+ test:
+ name: Run endtoend tests on Cluster (tabletmanager_disk_health_monitor)
+ runs-on: ubuntu-24.04
+ timeout-minutes: 60
+
+ steps:
+ - name: Harden the runner (Audit all outbound calls)
+ uses: step-security/harden-runner@e14015d583714f6e62063499dc959a02595150a1 # v2.21.1
+ with:
+ egress-policy: audit
+
+ - name: Skip CI
+ run: |
+ if [[ "${{ contains(github.event.pull_request.labels.*.name, 'Skip CI') }}" == "true" ]]; then
+ echo "skipping CI due to the 'Skip CI' label"
+ exit 1
+ fi
+
+ - name: Check out code
+ uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
+ with:
+ # The merge commit and its first parent, for the path filter.
+ fetch-depth: 2
+ persist-credentials: "false"
+
+ - name: Find the base of the pull request's merge commit
+ # github.event.pull_request.base.sha is not updated when the base branch
+ # moves, so paths-filter would also count the base branch's newer commits.
+ # With token: '', paths-filter diffs against `base` on pull_request
+ # events too (see its README); action.yml's input description is stale.
+ id: merge-base
+ if: github.event_name == 'pull_request'
+ run: echo "sha=$(git rev-parse HEAD^1)" >> "$GITHUB_OUTPUT"
+
+ - name: Check for changes in relevant files
+ uses: dorny/paths-filter@ceb8a2b8f2d89434be7ff52d3de7ec3738c5cc9d # v4.0.3
+ id: changes
+ with:
+ token: ""
+ base: ${{ steps.merge-base.outputs.sha }}
+ filters: |
+ end_to_end:
+ - 'go/vt/vttablet/tabletserver/**'
+ - 'go/test/endtoend/cluster/**'
+ - 'go/test/endtoend/tabletmanager/disk_health_monitor/**'
+ - 'test/config.json'
+ - 'test.go'
+ - 'Makefile'
+ - 'build.env'
+ - 'go.sum'
+ - 'go.mod'
+ - 'tools/**'
+ - 'config/**'
+ - 'bootstrap.sh'
+ - '.github/workflows/cluster_endtoend_disk_health_monitor.yml'
+ - '.github/actions/setup-mysql/action.yml'
+ - '.github/actions/setup-go/action.yml'
+
+ - name: Set up Go
+ if: steps.changes.outputs.end_to_end == 'true'
+ uses: $/.github/actions/setup-go
+
+ - name: Set up python
+ if: steps.changes.outputs.end_to_end == 'true'
+ uses: actions/setup-python@5fda3b95a4ea91299a34e894583c3862153e4b97 # v7.0.0
+
+ - name: Tune the OS
+ if: steps.changes.outputs.end_to_end == 'true'
+ timeout-minutes: 5
+ uses: $/.github/actions/tune-os
+
+ - name: Setup MySQL
+ if: steps.changes.outputs.end_to_end == 'true'
+ timeout-minutes: 8
+ uses: $/.github/actions/setup-mysql
+ with:
+ flavor: mysql-8.4
+
+ - name: Get dependencies
+ if: steps.changes.outputs.end_to_end == 'true'
+ timeout-minutes: 10
+ run: |
+ sudo apt-get -qq install -y mysql-shell
+ sudo apt-get -qq install -y make unzip g++ etcd-client etcd-server curl git wget xz-utils libncurses6 fuse3
+ sudo service etcd stop
+
+ - name: Setup launchable dependencies
+ if: |
+ github.event_name == 'pull_request' &&
+ github.event.pull_request.draft == false &&
+ steps.changes.outputs.end_to_end == 'true' &&
+ github.base_ref == 'main'
+ run: |
+ pip3 install --user launchable~=1.0 > /dev/null
+ launchable verify || true
+ launchable record build --name "$GITHUB_RUN_ID" --no-commit-collection --source .
+
+ - name: Run cluster endtoend test
+ if: steps.changes.outputs.end_to_end == 'true'
+ timeout-minutes: 45
+ run: |
+ export VTDATAROOT="/tmp/"
+ source build.env
+ set -exo pipefail
+
+ go run test.go -docker=false -follow -shard tabletmanager_disk_health_monitor
+
+ - name: Record test results in launchable
+ if: |
+ github.event_name == 'pull_request' &&
+ github.event.pull_request.draft == false &&
+ steps.changes.outputs.end_to_end == 'true' &&
+ github.base_ref == 'main' &&
+ !cancelled()
+ run: |
+ launchable record tests --build "$GITHUB_RUN_ID" go-test . || true
+
+ - name: Test Summary
+ if: steps.changes.outputs.end_to_end == 'true' && failure()
+ uses: test-summary/action@37b508cfee6d4d080eedd00b5bb240a6a784a6a5 # v2.6
+ with:
+ paths: "_test/junit/*.xml"
diff --git a/.github/workflows/codecov.yml b/.github/workflows/codecov.yml
index aaea4873f01..f110ae77eb3 100644
--- a/.github/workflows/codecov.yml
+++ b/.github/workflows/codecov.yml
@@ -42,12 +42,22 @@ jobs:
echo "is_full_run=false" >> "$GITHUB_OUTPUT"
fi
+ - name: Find the base of the pull request's merge commit
+ # github.event.pull_request.base.sha is not updated when the base branch
+ # moves, so paths-filter would also count the base branch's newer commits.
+ # With token: '', paths-filter diffs against `base` on pull_request
+ # events too (see its README); action.yml's input description is stale.
+ id: merge-base
+ if: github.event_name == 'pull_request'
+ run: echo "sha=$(git rev-parse HEAD^1)" >> "$GITHUB_OUTPUT"
+
- name: Check for changes in files relevant to code coverage
if: steps.mode.outputs.is_full_run != 'true'
uses: dorny/paths-filter@ceb8a2b8f2d89434be7ff52d3de7ec3738c5cc9d # v4.0.3
id: changes
with:
token: ''
+ base: ${{ steps.merge-base.outputs.sha }}
filters: |
changed_files:
- .github/workflows/codecov.yml
diff --git a/.github/workflows/docker_ci.yml b/.github/workflows/docker_ci.yml
index 1bfd859881c..5b73e59d9f3 100644
--- a/.github/workflows/docker_ci.yml
+++ b/.github/workflows/docker_ci.yml
@@ -47,13 +47,25 @@ jobs:
- name: Check out code
uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
with:
+ # The merge commit and its first parent, for the path filter.
+ fetch-depth: 2
persist-credentials: "false"
+ - name: Find the base of the pull request's merge commit
+ # github.event.pull_request.base.sha is not updated when the base branch
+ # moves, so paths-filter would also count the base branch's newer commits.
+ # With token: '', paths-filter diffs against `base` on pull_request
+ # events too (see its README); action.yml's input description is stale.
+ id: merge-base
+ if: github.event_name == 'pull_request'
+ run: echo "sha=$(git rev-parse HEAD^1)" >> "$GITHUB_OUTPUT"
+
- name: Check for changes in relevant files
uses: dorny/paths-filter@ceb8a2b8f2d89434be7ff52d3de7ec3738c5cc9d # v4.0.3
id: changes
with:
token: ""
+ base: ${{ steps.merge-base.outputs.sha }}
filters: |
end_to_end:
- 'test/config.json'
diff --git a/.github/workflows/e2e_race.yml b/.github/workflows/e2e_race.yml
index bacc4b1def4..8879b1d4b6b 100644
--- a/.github/workflows/e2e_race.yml
+++ b/.github/workflows/e2e_race.yml
@@ -28,13 +28,25 @@ jobs:
- name: Check out code
uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
with:
+ # The merge commit and its first parent, for the path filter.
+ fetch-depth: 2
persist-credentials: 'false'
+ - name: Find the base of the pull request's merge commit
+ # github.event.pull_request.base.sha is not updated when the base branch
+ # moves, so paths-filter would also count the base branch's newer commits.
+ # With token: '', paths-filter diffs against `base` on pull_request
+ # events too (see its README); action.yml's input description is stale.
+ id: merge-base
+ if: github.event_name == 'pull_request'
+ run: echo "sha=$(git rev-parse HEAD^1)" >> "$GITHUB_OUTPUT"
+
- name: Check for changes in relevant files
uses: dorny/paths-filter@ceb8a2b8f2d89434be7ff52d3de7ec3738c5cc9d # v4.0.3
id: changes
with:
token: ''
+ base: ${{ steps.merge-base.outputs.sha }}
filters: |
end_to_end:
- 'go/**/*.go'
diff --git a/.github/workflows/endtoend.yml b/.github/workflows/endtoend.yml
index 8f69d46d2c9..13169a27452 100644
--- a/.github/workflows/endtoend.yml
+++ b/.github/workflows/endtoend.yml
@@ -28,13 +28,25 @@ jobs:
- name: Check out code
uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
with:
+ # The merge commit and its first parent, for the path filter.
+ fetch-depth: 2
persist-credentials: 'false'
+ - name: Find the base of the pull request's merge commit
+ # github.event.pull_request.base.sha is not updated when the base branch
+ # moves, so paths-filter would also count the base branch's newer commits.
+ # With token: '', paths-filter diffs against `base` on pull_request
+ # events too (see its README); action.yml's input description is stale.
+ id: merge-base
+ if: github.event_name == 'pull_request'
+ run: echo "sha=$(git rev-parse HEAD^1)" >> "$GITHUB_OUTPUT"
+
- name: Check for changes in relevant files
uses: dorny/paths-filter@ceb8a2b8f2d89434be7ff52d3de7ec3738c5cc9d # v4.0.3
id: changes
with:
token: ''
+ base: ${{ steps.merge-base.outputs.sha }}
filters: |
end_to_end:
- 'go/**/*.go'
diff --git a/.github/workflows/local_example.yml b/.github/workflows/local_example.yml
index aaae80f972f..17f63525353 100644
--- a/.github/workflows/local_example.yml
+++ b/.github/workflows/local_example.yml
@@ -32,13 +32,25 @@ jobs:
- name: Check out code
uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
with:
+ # The merge commit and its first parent, for the path filter.
+ fetch-depth: 2
persist-credentials: 'false'
+ - name: Find the base of the pull request's merge commit
+ # github.event.pull_request.base.sha is not updated when the base branch
+ # moves, so paths-filter would also count the base branch's newer commits.
+ # With token: '', paths-filter diffs against `base` on pull_request
+ # events too (see its README); action.yml's input description is stale.
+ id: merge-base
+ if: github.event_name == 'pull_request'
+ run: echo "sha=$(git rev-parse HEAD^1)" >> "$GITHUB_OUTPUT"
+
- name: Check for changes in relevant files
uses: dorny/paths-filter@ceb8a2b8f2d89434be7ff52d3de7ec3738c5cc9d # v4.0.3
id: changes
with:
token: ''
+ base: ${{ steps.merge-base.outputs.sha }}
filters: |
examples:
- 'test/config.json'
diff --git a/.github/workflows/region_example.yml b/.github/workflows/region_example.yml
index 709ed2bce42..78c45b730a5 100644
--- a/.github/workflows/region_example.yml
+++ b/.github/workflows/region_example.yml
@@ -32,13 +32,25 @@ jobs:
- name: Check out code
uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
with:
+ # The merge commit and its first parent, for the path filter.
+ fetch-depth: 2
persist-credentials: 'false'
+ - name: Find the base of the pull request's merge commit
+ # github.event.pull_request.base.sha is not updated when the base branch
+ # moves, so paths-filter would also count the base branch's newer commits.
+ # With token: '', paths-filter diffs against `base` on pull_request
+ # events too (see its README); action.yml's input description is stale.
+ id: merge-base
+ if: github.event_name == 'pull_request'
+ run: echo "sha=$(git rev-parse HEAD^1)" >> "$GITHUB_OUTPUT"
+
- name: Check for changes in relevant files
uses: dorny/paths-filter@ceb8a2b8f2d89434be7ff52d3de7ec3738c5cc9d # v4.0.3
id: changes
with:
token: ''
+ base: ${{ steps.merge-base.outputs.sha }}
filters: |
examples:
- 'test/config.json'
diff --git a/.github/workflows/static_checks_etc.yml b/.github/workflows/static_checks_etc.yml
index f8b9e80dd9c..a774c1f411c 100644
--- a/.github/workflows/static_checks_etc.yml
+++ b/.github/workflows/static_checks_etc.yml
@@ -31,6 +31,8 @@ jobs:
- name: Checkout code
uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
with:
+ # The merge commit and its first parent, for the path filter.
+ fetch-depth: 2
persist-credentials: 'false'
# Only uploads dependency data for FOSSA's license tracking; the policy
@@ -44,11 +46,21 @@ jobs:
fossa-api-key: f62c11ef0c249fef239947f01279aa0f
github-token: ${{ github.token }}
+ - name: Find the base of the pull request's merge commit
+ # github.event.pull_request.base.sha is not updated when the base branch
+ # moves, so paths-filter would also count the base branch's newer commits.
+ # With token: '', paths-filter diffs against `base` on pull_request
+ # events too (see its README); action.yml's input description is stale.
+ id: merge-base
+ if: github.event_name == 'pull_request'
+ run: echo "sha=$(git rev-parse HEAD^1)" >> "$GITHUB_OUTPUT"
+
- name: Check for changes in Go files
uses: dorny/paths-filter@ceb8a2b8f2d89434be7ff52d3de7ec3738c5cc9d # v4.0.3
id: changes
with:
token: ''
+ base: ${{ steps.merge-base.outputs.sha }}
filters: |
go_files:
- '**/*.go'
diff --git a/.github/workflows/unit_test.yml b/.github/workflows/unit_test.yml
index 1ef4836771f..d059dad42cc 100644
--- a/.github/workflows/unit_test.yml
+++ b/.github/workflows/unit_test.yml
@@ -34,13 +34,25 @@ jobs:
- name: Check out code
uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
with:
+ # The merge commit and its first parent, for the path filter.
+ fetch-depth: 2
persist-credentials: "false"
+ - name: Find the base of the pull request's merge commit
+ # github.event.pull_request.base.sha is not updated when the base branch
+ # moves, so paths-filter would also count the base branch's newer commits.
+ # With token: '', paths-filter diffs against `base` on pull_request
+ # events too (see its README); action.yml's input description is stale.
+ id: merge-base
+ if: github.event_name == 'pull_request'
+ run: echo "sha=$(git rev-parse HEAD^1)" >> "$GITHUB_OUTPUT"
+
- name: Check for changes in relevant files
uses: dorny/paths-filter@ceb8a2b8f2d89434be7ff52d3de7ec3738c5cc9d # v4.0.3
id: changes
with:
token: ""
+ base: ${{ steps.merge-base.outputs.sha }}
filters: |
unit_tests:
- 'test/config.json'
diff --git a/.github/workflows/upgrade_downgrade_test_backups_e2e.yml b/.github/workflows/upgrade_downgrade_test_backups_e2e.yml
index 022ec01eeb1..0400ecce1b8 100644
--- a/.github/workflows/upgrade_downgrade_test_backups_e2e.yml
+++ b/.github/workflows/upgrade_downgrade_test_backups_e2e.yml
@@ -43,11 +43,21 @@ jobs:
echo $previous_release_ref
echo "previous_release_ref=${previous_release_ref}" >> $GITHUB_OUTPUT
+ - name: Find the base of the pull request's merge commit
+ # github.event.pull_request.base.sha is not updated when the base branch
+ # moves, so paths-filter would also count the base branch's newer commits.
+ # With token: '', paths-filter diffs against `base` on pull_request
+ # events too (see its README); action.yml's input description is stale.
+ id: merge-base
+ if: github.event_name == 'pull_request'
+ run: echo "sha=$(git rev-parse HEAD^1)" >> "$GITHUB_OUTPUT"
+
- name: Check for changes in relevant files
uses: dorny/paths-filter@ceb8a2b8f2d89434be7ff52d3de7ec3738c5cc9d # v4.0.3
id: changes
with:
token: ''
+ base: ${{ steps.merge-base.outputs.sha }}
filters: |
end_to_end:
- 'test/config.json'
diff --git a/.github/workflows/upgrade_downgrade_test_backups_e2e_next_release.yml b/.github/workflows/upgrade_downgrade_test_backups_e2e_next_release.yml
index 982e99e6f9c..5ec54deafe5 100644
--- a/.github/workflows/upgrade_downgrade_test_backups_e2e_next_release.yml
+++ b/.github/workflows/upgrade_downgrade_test_backups_e2e_next_release.yml
@@ -44,11 +44,21 @@ jobs:
echo $next_release_ref
echo "next_release_ref=${next_release_ref}" >> $GITHUB_OUTPUT
+ - name: Find the base of the pull request's merge commit
+ # github.event.pull_request.base.sha is not updated when the base branch
+ # moves, so paths-filter would also count the base branch's newer commits.
+ # With token: '', paths-filter diffs against `base` on pull_request
+ # events too (see its README); action.yml's input description is stale.
+ id: merge-base
+ if: github.event_name == 'pull_request'
+ run: echo "sha=$(git rev-parse HEAD^1)" >> "$GITHUB_OUTPUT"
+
- name: Check for changes in relevant files
uses: dorny/paths-filter@ceb8a2b8f2d89434be7ff52d3de7ec3738c5cc9d # v4.0.3
id: changes
with:
token: ''
+ base: ${{ steps.merge-base.outputs.sha }}
filters: |
end_to_end:
- 'test/config.json'
diff --git a/.github/workflows/upgrade_downgrade_test_backups_manual.yml b/.github/workflows/upgrade_downgrade_test_backups_manual.yml
index f5f14f64f3f..84e4445a2d1 100644
--- a/.github/workflows/upgrade_downgrade_test_backups_manual.yml
+++ b/.github/workflows/upgrade_downgrade_test_backups_manual.yml
@@ -44,11 +44,21 @@ jobs:
echo $previous_release_ref
echo "previous_release_ref=${previous_release_ref}" >> $GITHUB_OUTPUT
+ - name: Find the base of the pull request's merge commit
+ # github.event.pull_request.base.sha is not updated when the base branch
+ # moves, so paths-filter would also count the base branch's newer commits.
+ # With token: '', paths-filter diffs against `base` on pull_request
+ # events too (see its README); action.yml's input description is stale.
+ id: merge-base
+ if: github.event_name == 'pull_request'
+ run: echo "sha=$(git rev-parse HEAD^1)" >> "$GITHUB_OUTPUT"
+
- name: Check for changes in relevant files
uses: dorny/paths-filter@ceb8a2b8f2d89434be7ff52d3de7ec3738c5cc9d # v4.0.3
id: changes
with:
token: ''
+ base: ${{ steps.merge-base.outputs.sha }}
filters: |
end_to_end:
- 'test/config.json'
diff --git a/.github/workflows/upgrade_downgrade_test_backups_manual_next_release.yml b/.github/workflows/upgrade_downgrade_test_backups_manual_next_release.yml
index 8cc4a9db20d..809ef612305 100644
--- a/.github/workflows/upgrade_downgrade_test_backups_manual_next_release.yml
+++ b/.github/workflows/upgrade_downgrade_test_backups_manual_next_release.yml
@@ -44,11 +44,21 @@ jobs:
echo $next_release_ref
echo "next_release_ref=${next_release_ref}" >> $GITHUB_OUTPUT
+ - name: Find the base of the pull request's merge commit
+ # github.event.pull_request.base.sha is not updated when the base branch
+ # moves, so paths-filter would also count the base branch's newer commits.
+ # With token: '', paths-filter diffs against `base` on pull_request
+ # events too (see its README); action.yml's input description is stale.
+ id: merge-base
+ if: github.event_name == 'pull_request'
+ run: echo "sha=$(git rev-parse HEAD^1)" >> "$GITHUB_OUTPUT"
+
- name: Check for changes in relevant files
uses: dorny/paths-filter@ceb8a2b8f2d89434be7ff52d3de7ec3738c5cc9d # v4.0.3
id: changes
with:
token: ''
+ base: ${{ steps.merge-base.outputs.sha }}
filters: |
end_to_end:
- 'test/config.json'
diff --git a/.github/workflows/upgrade_downgrade_test_onlineddl_flow.yml b/.github/workflows/upgrade_downgrade_test_onlineddl_flow.yml
index 6345b7409cb..2ee93d1978f 100644
--- a/.github/workflows/upgrade_downgrade_test_onlineddl_flow.yml
+++ b/.github/workflows/upgrade_downgrade_test_onlineddl_flow.yml
@@ -58,11 +58,21 @@ jobs:
echo $next_release_ref
echo "next_release_ref=${next_release_ref}" >> $GITHUB_OUTPUT
+ - name: Find the base of the pull request's merge commit
+ # github.event.pull_request.base.sha is not updated when the base branch
+ # moves, so paths-filter would also count the base branch's newer commits.
+ # With token: '', paths-filter diffs against `base` on pull_request
+ # events too (see its README); action.yml's input description is stale.
+ id: merge-base
+ if: github.event_name == 'pull_request'
+ run: echo "sha=$(git rev-parse HEAD^1)" >> "$GITHUB_OUTPUT"
+
- name: Check for changes in relevant files
uses: dorny/paths-filter@ceb8a2b8f2d89434be7ff52d3de7ec3738c5cc9d # v4.0.3
id: changes
with:
token: ''
+ base: ${{ steps.merge-base.outputs.sha }}
filters: |
end_to_end:
- 'test/config.json'
diff --git a/.github/workflows/upgrade_downgrade_test_query_serving_queries.yml b/.github/workflows/upgrade_downgrade_test_query_serving_queries.yml
index e26c60ea3db..0ac96339309 100644
--- a/.github/workflows/upgrade_downgrade_test_query_serving_queries.yml
+++ b/.github/workflows/upgrade_downgrade_test_query_serving_queries.yml
@@ -47,11 +47,21 @@ jobs:
echo $previous_release_ref
echo "previous_release_ref=${previous_release_ref}" >> $GITHUB_OUTPUT
+ - name: Find the base of the pull request's merge commit
+ # github.event.pull_request.base.sha is not updated when the base branch
+ # moves, so paths-filter would also count the base branch's newer commits.
+ # With token: '', paths-filter diffs against `base` on pull_request
+ # events too (see its README); action.yml's input description is stale.
+ id: merge-base
+ if: github.event_name == 'pull_request'
+ run: echo "sha=$(git rev-parse HEAD^1)" >> "$GITHUB_OUTPUT"
+
- name: Check for changes in relevant files
uses: dorny/paths-filter@ceb8a2b8f2d89434be7ff52d3de7ec3738c5cc9d # v4.0.3
id: changes
with:
token: ''
+ base: ${{ steps.merge-base.outputs.sha }}
filters: |
end_to_end:
- 'test/config.json'
diff --git a/.github/workflows/upgrade_downgrade_test_query_serving_queries_2.yml b/.github/workflows/upgrade_downgrade_test_query_serving_queries_2.yml
index 18778e58943..4374f2ae337 100644
--- a/.github/workflows/upgrade_downgrade_test_query_serving_queries_2.yml
+++ b/.github/workflows/upgrade_downgrade_test_query_serving_queries_2.yml
@@ -46,11 +46,21 @@ jobs:
echo $previous_release_ref
echo "previous_release_ref=${previous_release_ref}" >> $GITHUB_OUTPUT
+ - name: Find the base of the pull request's merge commit
+ # github.event.pull_request.base.sha is not updated when the base branch
+ # moves, so paths-filter would also count the base branch's newer commits.
+ # With token: '', paths-filter diffs against `base` on pull_request
+ # events too (see its README); action.yml's input description is stale.
+ id: merge-base
+ if: github.event_name == 'pull_request'
+ run: echo "sha=$(git rev-parse HEAD^1)" >> "$GITHUB_OUTPUT"
+
- name: Check for changes in relevant files
uses: dorny/paths-filter@ceb8a2b8f2d89434be7ff52d3de7ec3738c5cc9d # v4.0.3
id: changes
with:
token: ''
+ base: ${{ steps.merge-base.outputs.sha }}
filters: |
end_to_end:
- 'test/config.json'
diff --git a/.github/workflows/upgrade_downgrade_test_query_serving_queries_2_next_release.yml b/.github/workflows/upgrade_downgrade_test_query_serving_queries_2_next_release.yml
index 9fb67bb080e..08cf7c86c88 100644
--- a/.github/workflows/upgrade_downgrade_test_query_serving_queries_2_next_release.yml
+++ b/.github/workflows/upgrade_downgrade_test_query_serving_queries_2_next_release.yml
@@ -47,11 +47,21 @@ jobs:
echo $next_release_ref
echo "next_release_ref=${next_release_ref}" >> $GITHUB_OUTPUT
+ - name: Find the base of the pull request's merge commit
+ # github.event.pull_request.base.sha is not updated when the base branch
+ # moves, so paths-filter would also count the base branch's newer commits.
+ # With token: '', paths-filter diffs against `base` on pull_request
+ # events too (see its README); action.yml's input description is stale.
+ id: merge-base
+ if: github.event_name == 'pull_request'
+ run: echo "sha=$(git rev-parse HEAD^1)" >> "$GITHUB_OUTPUT"
+
- name: Check for changes in relevant files
uses: dorny/paths-filter@ceb8a2b8f2d89434be7ff52d3de7ec3738c5cc9d # v4.0.3
id: changes
with:
token: ''
+ base: ${{ steps.merge-base.outputs.sha }}
filters: |
end_to_end:
- 'test/config.json'
diff --git a/.github/workflows/upgrade_downgrade_test_query_serving_queries_next_release.yml b/.github/workflows/upgrade_downgrade_test_query_serving_queries_next_release.yml
index 37c75efddd5..5caacc386ed 100644
--- a/.github/workflows/upgrade_downgrade_test_query_serving_queries_next_release.yml
+++ b/.github/workflows/upgrade_downgrade_test_query_serving_queries_next_release.yml
@@ -47,11 +47,21 @@ jobs:
echo $next_release_ref
echo "next_release_ref=${next_release_ref}" >> $GITHUB_OUTPUT
+ - name: Find the base of the pull request's merge commit
+ # github.event.pull_request.base.sha is not updated when the base branch
+ # moves, so paths-filter would also count the base branch's newer commits.
+ # With token: '', paths-filter diffs against `base` on pull_request
+ # events too (see its README); action.yml's input description is stale.
+ id: merge-base
+ if: github.event_name == 'pull_request'
+ run: echo "sha=$(git rev-parse HEAD^1)" >> "$GITHUB_OUTPUT"
+
- name: Check for changes in relevant files
uses: dorny/paths-filter@ceb8a2b8f2d89434be7ff52d3de7ec3738c5cc9d # v4.0.3
id: changes
with:
token: ''
+ base: ${{ steps.merge-base.outputs.sha }}
filters: |
end_to_end:
- 'test/config.json'
diff --git a/.github/workflows/upgrade_downgrade_test_query_serving_schema.yml b/.github/workflows/upgrade_downgrade_test_query_serving_schema.yml
index ed7fa251a21..32aa834f0cf 100644
--- a/.github/workflows/upgrade_downgrade_test_query_serving_schema.yml
+++ b/.github/workflows/upgrade_downgrade_test_query_serving_schema.yml
@@ -47,11 +47,21 @@ jobs:
echo $previous_release_ref
echo "previous_release_ref=${previous_release_ref}" >> $GITHUB_OUTPUT
+ - name: Find the base of the pull request's merge commit
+ # github.event.pull_request.base.sha is not updated when the base branch
+ # moves, so paths-filter would also count the base branch's newer commits.
+ # With token: '', paths-filter diffs against `base` on pull_request
+ # events too (see its README); action.yml's input description is stale.
+ id: merge-base
+ if: github.event_name == 'pull_request'
+ run: echo "sha=$(git rev-parse HEAD^1)" >> "$GITHUB_OUTPUT"
+
- name: Check for changes in relevant files
uses: dorny/paths-filter@ceb8a2b8f2d89434be7ff52d3de7ec3738c5cc9d # v4.0.3
id: changes
with:
token: ''
+ base: ${{ steps.merge-base.outputs.sha }}
filters: |
end_to_end:
- 'test/config.json'
diff --git a/.github/workflows/upgrade_downgrade_test_query_serving_schema_next_release.yml b/.github/workflows/upgrade_downgrade_test_query_serving_schema_next_release.yml
index 25cd16d1e56..0b2588f9659 100644
--- a/.github/workflows/upgrade_downgrade_test_query_serving_schema_next_release.yml
+++ b/.github/workflows/upgrade_downgrade_test_query_serving_schema_next_release.yml
@@ -47,11 +47,21 @@ jobs:
echo $next_release_ref
echo "next_release_ref=${next_release_ref}" >> $GITHUB_OUTPUT
+ - name: Find the base of the pull request's merge commit
+ # github.event.pull_request.base.sha is not updated when the base branch
+ # moves, so paths-filter would also count the base branch's newer commits.
+ # With token: '', paths-filter diffs against `base` on pull_request
+ # events too (see its README); action.yml's input description is stale.
+ id: merge-base
+ if: github.event_name == 'pull_request'
+ run: echo "sha=$(git rev-parse HEAD^1)" >> "$GITHUB_OUTPUT"
+
- name: Check for changes in relevant files
uses: dorny/paths-filter@ceb8a2b8f2d89434be7ff52d3de7ec3738c5cc9d # v4.0.3
id: changes
with:
token: ''
+ base: ${{ steps.merge-base.outputs.sha }}
filters: |
end_to_end:
- 'test/config.json'
diff --git a/.github/workflows/upgrade_downgrade_test_reparent_new_vtctl.yml b/.github/workflows/upgrade_downgrade_test_reparent_new_vtctl.yml
index 2fbd5269fc4..6ee8b7355df 100644
--- a/.github/workflows/upgrade_downgrade_test_reparent_new_vtctl.yml
+++ b/.github/workflows/upgrade_downgrade_test_reparent_new_vtctl.yml
@@ -47,11 +47,21 @@ jobs:
echo $next_release_ref
echo "next_release_ref=${next_release_ref}" >> $GITHUB_OUTPUT
+ - name: Find the base of the pull request's merge commit
+ # github.event.pull_request.base.sha is not updated when the base branch
+ # moves, so paths-filter would also count the base branch's newer commits.
+ # With token: '', paths-filter diffs against `base` on pull_request
+ # events too (see its README); action.yml's input description is stale.
+ id: merge-base
+ if: github.event_name == 'pull_request'
+ run: echo "sha=$(git rev-parse HEAD^1)" >> "$GITHUB_OUTPUT"
+
- name: Check for changes in relevant files
uses: dorny/paths-filter@ceb8a2b8f2d89434be7ff52d3de7ec3738c5cc9d # v4.0.3
id: changes
with:
token: ''
+ base: ${{ steps.merge-base.outputs.sha }}
filters: |
end_to_end:
- 'test/config.json'
diff --git a/.github/workflows/upgrade_downgrade_test_reparent_new_vttablet.yml b/.github/workflows/upgrade_downgrade_test_reparent_new_vttablet.yml
index 3016bc9414a..42cb577e379 100644
--- a/.github/workflows/upgrade_downgrade_test_reparent_new_vttablet.yml
+++ b/.github/workflows/upgrade_downgrade_test_reparent_new_vttablet.yml
@@ -47,11 +47,21 @@ jobs:
echo $next_release_ref
echo "next_release_ref=${next_release_ref}" >> $GITHUB_OUTPUT
+ - name: Find the base of the pull request's merge commit
+ # github.event.pull_request.base.sha is not updated when the base branch
+ # moves, so paths-filter would also count the base branch's newer commits.
+ # With token: '', paths-filter diffs against `base` on pull_request
+ # events too (see its README); action.yml's input description is stale.
+ id: merge-base
+ if: github.event_name == 'pull_request'
+ run: echo "sha=$(git rev-parse HEAD^1)" >> "$GITHUB_OUTPUT"
+
- name: Check for changes in relevant files
uses: dorny/paths-filter@ceb8a2b8f2d89434be7ff52d3de7ec3738c5cc9d # v4.0.3
id: changes
with:
token: ''
+ base: ${{ steps.merge-base.outputs.sha }}
filters: |
end_to_end:
- 'test/config.json'
diff --git a/.github/workflows/upgrade_downgrade_test_reparent_old_vtctl.yml b/.github/workflows/upgrade_downgrade_test_reparent_old_vtctl.yml
index 498f3c62741..c82654873ad 100644
--- a/.github/workflows/upgrade_downgrade_test_reparent_old_vtctl.yml
+++ b/.github/workflows/upgrade_downgrade_test_reparent_old_vtctl.yml
@@ -47,11 +47,21 @@ jobs:
echo $previous_release_ref
echo "previous_release_ref=${previous_release_ref}" >> $GITHUB_OUTPUT
+ - name: Find the base of the pull request's merge commit
+ # github.event.pull_request.base.sha is not updated when the base branch
+ # moves, so paths-filter would also count the base branch's newer commits.
+ # With token: '', paths-filter diffs against `base` on pull_request
+ # events too (see its README); action.yml's input description is stale.
+ id: merge-base
+ if: github.event_name == 'pull_request'
+ run: echo "sha=$(git rev-parse HEAD^1)" >> "$GITHUB_OUTPUT"
+
- name: Check for changes in relevant files
uses: dorny/paths-filter@ceb8a2b8f2d89434be7ff52d3de7ec3738c5cc9d # v4.0.3
id: changes
with:
token: ''
+ base: ${{ steps.merge-base.outputs.sha }}
filters: |
end_to_end:
- 'test/config.json'
diff --git a/.github/workflows/upgrade_downgrade_test_reparent_old_vttablet.yml b/.github/workflows/upgrade_downgrade_test_reparent_old_vttablet.yml
index 441663c8d3c..28fd1f3d708 100644
--- a/.github/workflows/upgrade_downgrade_test_reparent_old_vttablet.yml
+++ b/.github/workflows/upgrade_downgrade_test_reparent_old_vttablet.yml
@@ -47,11 +47,21 @@ jobs:
echo $previous_release_ref
echo "previous_release_ref=${previous_release_ref}" >> $GITHUB_OUTPUT
+ - name: Find the base of the pull request's merge commit
+ # github.event.pull_request.base.sha is not updated when the base branch
+ # moves, so paths-filter would also count the base branch's newer commits.
+ # With token: '', paths-filter diffs against `base` on pull_request
+ # events too (see its README); action.yml's input description is stale.
+ id: merge-base
+ if: github.event_name == 'pull_request'
+ run: echo "sha=$(git rev-parse HEAD^1)" >> "$GITHUB_OUTPUT"
+
- name: Check for changes in relevant files
uses: dorny/paths-filter@ceb8a2b8f2d89434be7ff52d3de7ec3738c5cc9d # v4.0.3
id: changes
with:
token: ''
+ base: ${{ steps.merge-base.outputs.sha }}
filters: |
end_to_end:
- 'test/config.json'
diff --git a/.github/workflows/upgrade_downgrade_test_semi_sync.yml b/.github/workflows/upgrade_downgrade_test_semi_sync.yml
index 21b5c9f0e26..6b4df30d019 100644
--- a/.github/workflows/upgrade_downgrade_test_semi_sync.yml
+++ b/.github/workflows/upgrade_downgrade_test_semi_sync.yml
@@ -34,11 +34,21 @@ jobs:
fetch-depth: 0
persist-credentials: 'false'
+ - name: Find the base of the pull request's merge commit
+ # github.event.pull_request.base.sha is not updated when the base branch
+ # moves, so paths-filter would also count the base branch's newer commits.
+ # With token: '', paths-filter diffs against `base` on pull_request
+ # events too (see its README); action.yml's input description is stale.
+ id: merge-base
+ if: github.event_name == 'pull_request'
+ run: echo "sha=$(git rev-parse HEAD^1)" >> "$GITHUB_OUTPUT"
+
- name: Check for changes in relevant files
uses: dorny/paths-filter@ceb8a2b8f2d89434be7ff52d3de7ec3738c5cc9d # v4.0.3
id: changes
with:
token: ''
+ base: ${{ steps.merge-base.outputs.sha }}
filters: |
end_to_end:
- 'test/config.json'
diff --git a/.github/workflows/vitess_tester_vtgate.yml b/.github/workflows/vitess_tester_vtgate.yml
index 3ca9da870dd..da691c7c0fe 100644
--- a/.github/workflows/vitess_tester_vtgate.yml
+++ b/.github/workflows/vitess_tester_vtgate.yml
@@ -34,13 +34,25 @@ jobs:
- name: Check out code
uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
with:
+ # The merge commit and its first parent, for the path filter.
+ fetch-depth: 2
persist-credentials: 'false'
+ - name: Find the base of the pull request's merge commit
+ # github.event.pull_request.base.sha is not updated when the base branch
+ # moves, so paths-filter would also count the base branch's newer commits.
+ # With token: '', paths-filter diffs against `base` on pull_request
+ # events too (see its README); action.yml's input description is stale.
+ id: merge-base
+ if: github.event_name == 'pull_request'
+ run: echo "sha=$(git rev-parse HEAD^1)" >> "$GITHUB_OUTPUT"
+
- name: Check for changes in relevant files
uses: dorny/paths-filter@ceb8a2b8f2d89434be7ff52d3de7ec3738c5cc9d # v4.0.3
id: changes
with:
token: ''
+ base: ${{ steps.merge-base.outputs.sha }}
filters: |
end_to_end:
- 'test/config.json'
diff --git a/.github/workflows/vtop_example.yml b/.github/workflows/vtop_example.yml
index af82606d1f9..1ef61530a39 100644
--- a/.github/workflows/vtop_example.yml
+++ b/.github/workflows/vtop_example.yml
@@ -28,13 +28,25 @@ jobs:
- name: Check out code
uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
with:
+ # The merge commit and its first parent, for the path filter.
+ fetch-depth: 2
persist-credentials: "false"
+ - name: Find the base of the pull request's merge commit
+ # github.event.pull_request.base.sha is not updated when the base branch
+ # moves, so paths-filter would also count the base branch's newer commits.
+ # With token: '', paths-filter diffs against `base` on pull_request
+ # events too (see its README); action.yml's input description is stale.
+ id: merge-base
+ if: github.event_name == 'pull_request'
+ run: echo "sha=$(git rev-parse HEAD^1)" >> "$GITHUB_OUTPUT"
+
- name: Check for changes in relevant files
uses: dorny/paths-filter@ceb8a2b8f2d89434be7ff52d3de7ec3738c5cc9d # v4.0.3
id: changes
with:
token: ""
+ base: ${{ steps.merge-base.outputs.sha }}
filters: |
end_to_end:
- 'go/**/*.go'
From fd9a66842c344c1f6d49e04249cee6975bb9da45 Mon Sep 17 00:00:00 2001
From: "vitess-bot[bot]" <108069721+vitess-bot[bot]@users.noreply.github.com>
Date: Thu, 22 Oct 2026 09:11:35 -0400
Subject: [PATCH 27/31] [release-23.0] vtgate: fix goroutine leak on failure in
buffering tests (#19944) (#21696)
Signed-off-by: Arthur Schreiber
Co-authored-by: vitess-bot[bot] <108069721+vitess-bot[bot]@users.noreply.github.com>
Co-authored-by: Arthur Schreiber
Co-authored-by: Claude Opus 5.5
---
go/vt/vtgate/tabletgateway_flaky_test.go | 18 +++++++++---------
1 file changed, 9 insertions(+), 9 deletions(-)
diff --git a/go/vt/vtgate/tabletgateway_flaky_test.go b/go/vt/vtgate/tabletgateway_flaky_test.go
index 124997bea9e..8c691eee3df 100644
--- a/go/vt/vtgate/tabletgateway_flaky_test.go
+++ b/go/vt/vtgate/tabletgateway_flaky_test.go
@@ -112,10 +112,10 @@ func TestGatewayBufferingWhenPrimarySwitchesServingState(t *testing.T) {
waitForBuffering(true)
// execute the query in a go routine since it should be buffered, and check that it eventually succeed
- queryChan := make(chan struct{})
+ done := make(chan struct{}, 1)
go func() {
res, err = tg.Execute(ctx, target, "query", nil, 0, 0, nil)
- queryChan <- struct{}{}
+ done <- struct{}{}
}()
// set the serving type for the primary tablet true and broadcast it so that the buffering code registers this change
@@ -127,7 +127,7 @@ func TestGatewayBufferingWhenPrimarySwitchesServingState(t *testing.T) {
// wait for the query to execute before checking for results
select {
- case <-queryChan:
+ case <-done:
require.NoError(t, err)
require.Equal(t, sqlResult1, res)
case <-time.After(15 * time.Second):
@@ -222,10 +222,10 @@ func TestGatewayBufferingWhileReparenting(t *testing.T) {
sbcReplica.SetResults([]*sqltypes.Result{sqlResult1})
// execute the query in a go routine since it should be buffered, and check that it eventually succeed
- queryChan := make(chan struct{})
+ done := make(chan struct{}, 1)
go func() {
res, err = tg.Execute(ctx, target, "query", nil, 0, 0, nil)
- queryChan <- struct{}{}
+ done <- struct{}{}
}()
// set the serving type for the new primary tablet true and broadcast it so that the buffering code registers this change
@@ -256,7 +256,7 @@ outer:
// wait for the query to execute before checking for results
select {
- case <-queryChan:
+ case <-done:
require.NoError(t, err)
require.Equal(t, sqlResult1, res)
case <-time.After(15 * time.Second):
@@ -330,14 +330,14 @@ func TestInconsistentStateDetectedBuffering(t *testing.T) {
var res *sqltypes.Result
var err error
- queryChan := make(chan struct{})
+ done := make(chan struct{}, 1)
go func() {
res, err = tg.Execute(ctx, target, "query", nil, 0, 0, nil)
- queryChan <- struct{}{}
+ done <- struct{}{}
}()
select {
- case <-queryChan:
+ case <-done:
require.Nil(t, res)
require.Error(t, err)
// depending on whether the health check ticks before or after the buffering code, we might get different errors
From b5e58b8752a2fd436edd985816ed51738ed21c21 Mon Sep 17 00:00:00 2001
From: "vitess-bot[bot]" <108069721+vitess-bot[bot]@users.noreply.github.com>
Date: Thu, 22 Oct 2026 09:20:54 -0400
Subject: [PATCH 28/31] [release-23.0] test: deflake the foreign key stress
test (#20777) (#21699)
Signed-off-by: Arthur Schreiber
Co-authored-by: vitess-bot[bot] <108069721+vitess-bot[bot]@users.noreply.github.com>
Co-authored-by: Arthur Schreiber
Co-authored-by: Claude Opus 5.5
---
go/test/endtoend/cluster/cluster_util.go | 1 +
.../foreignkey/stress/fk_stress_test.go | 81 ++++++++++++++-----
2 files changed, 60 insertions(+), 22 deletions(-)
diff --git a/go/test/endtoend/cluster/cluster_util.go b/go/test/endtoend/cluster/cluster_util.go
index 492e5b22c0b..6b34a1d36df 100644
--- a/go/test/endtoend/cluster/cluster_util.go
+++ b/go/test/endtoend/cluster/cluster_util.go
@@ -225,6 +225,7 @@ func filterResultWhenRunsForCoverage(input string) string {
}
func ValidateReplicationIsHealthy(t *testing.T, tablet *Vttablet) bool {
+ require.NotNil(t, tablet)
query := "show replica status"
rs, err := tablet.VttabletProcess.QueryTablet(query, "", true)
assert.NoError(t, err)
diff --git a/go/test/endtoend/vtgate/foreignkey/stress/fk_stress_test.go b/go/test/endtoend/vtgate/foreignkey/stress/fk_stress_test.go
index c51dba7d0bd..f0b337e4fb5 100644
--- a/go/test/endtoend/vtgate/foreignkey/stress/fk_stress_test.go
+++ b/go/test/endtoend/vtgate/foreignkey/stress/fk_stress_test.go
@@ -124,6 +124,13 @@ func (w *WriteMetrics) Clear() {
w.deletesFKErrors = 0
}
+func (w *WriteMetrics) Deletes() int64 {
+ w.mu.Lock()
+ defer w.mu.Unlock()
+
+ return w.deletes
+}
+
func (w *WriteMetrics) String() string {
return fmt.Sprintf(`WriteMetrics: inserts-deletes=%d, updates-deletes=%d,
insertsAttempts=%d, insertsFailures=%d, insertsNoops=%d, inserts=%d,
@@ -159,7 +166,8 @@ var (
tableNames = []string{parentTableName, childTableName, child2TableName, grandchildTableName, selfTableName, nofkTableName}
reverseTableNames []string
- seedOnce sync.Once
+ seedOnce sync.Once
+ initGlobalsOnce sync.Once
referenceActionMap = map[sqlparser.ReferenceAction]string{
sqlparser.NoAction: "NO ACTION",
@@ -415,6 +423,10 @@ func queryTablet(t *testing.T, tablet *cluster.Vttablet, query string, expectErr
}
func tabletTestName(t *testing.T, tablet *cluster.Vttablet) string {
+ // A nil tablet must fail here: when the tablet globals are unset, a
+ // nil argument would otherwise match the first case below and
+ // mislabel the subtest.
+ require.NotNil(t, tablet)
switch tablet {
case primary:
return "primary"
@@ -507,27 +519,38 @@ func validateMetrics(t *testing.T, tcase *testCase) {
}
}
+// initTestGlobals wires the package globals (tablets, table orderings,
+// write metrics). Every root test must call it first: the test runner
+// reruns a failed root test with an exact -run filter, so a root test
+// cannot rely on another root test having run before it in the same
+// process.
+func initTestGlobals(t *testing.T) {
+ initGlobalsOnce.Do(func() {
+ shards = clusterInstance.Keyspaces[0].Shards
+ require.Len(t, shards, 1)
+ require.Len(t, shards[0].Vttablets, 3) // primary, no-fk replica, fk replica
+ primary = shards[0].Vttablets[0]
+ require.NotNil(t, primary)
+ replicaNoFK = shards[0].Vttablets[1]
+ require.NotNil(t, replicaNoFK)
+ require.NotEqual(t, primary.Alias, replicaNoFK.Alias)
+ replicaFK = shards[0].Vttablets[2]
+ require.NotNil(t, replicaFK)
+ require.NotEqual(t, primary.Alias, replicaFK.Alias)
+ require.NotEqual(t, replicaNoFK.Alias, replicaFK.Alias)
+
+ reverseTableNames = slices.Clone(tableNames)
+ slices.Reverse(reverseTableNames)
+ require.ElementsMatch(t, tableNames, reverseTableNames)
+
+ for _, tableName := range tableNames {
+ writeMetrics[tableName] = &WriteMetrics{}
+ }
+ })
+}
+
func TestInitialSetup(t *testing.T) {
- shards = clusterInstance.Keyspaces[0].Shards
- require.Equal(t, 1, len(shards))
- require.Equal(t, 3, len(shards[0].Vttablets)) // primary, no-fk replica, fk replica
- primary = shards[0].Vttablets[0]
- require.NotNil(t, primary)
- replicaNoFK = shards[0].Vttablets[1]
- require.NotNil(t, replicaNoFK)
- require.NotEqual(t, primary.Alias, replicaNoFK.Alias)
- replicaFK = shards[0].Vttablets[2]
- require.NotNil(t, replicaFK)
- require.NotEqual(t, primary.Alias, replicaFK.Alias)
- require.NotEqual(t, replicaNoFK.Alias, replicaFK.Alias)
-
- reverseTableNames = slices.Clone(tableNames)
- slices.Reverse(reverseTableNames)
- require.ElementsMatch(t, tableNames, reverseTableNames)
-
- for _, tableName := range tableNames {
- writeMetrics[tableName] = &WriteMetrics{}
- }
+ initTestGlobals(t)
}
type testCase struct {
@@ -653,6 +676,7 @@ func ExecuteFKTest(t *testing.T, tcase *testCase) {
}
func TestStressFK(t *testing.T) {
+ initTestGlobals(t)
t.Run("validate replication health", func(t *testing.T) {
validateReplicationIsHealthy(t, replicaNoFK)
@@ -1240,9 +1264,22 @@ func populateTables(t *testing.T, tcase *testCase) {
for i := 0; i < maxTableRows/4; i++ {
generateUpdate(t, tableName, conn)
}
- for i := 0; i < maxTableRows/4; i++ {
+ // A delete only succeeds when the random id hits a row
+ // whose updates column is 1 and which no child row (or,
+ // for stress_self, the row itself) references. On
+ // stress_self most rows are self-referencing, so only a
+ // handful of the random attempts succeed, and a fixed
+ // attempt count can end the loop with zero successful
+ // deletes; testSelectTableMetrics requires at least one.
+ // The loop exits after the base attempt count once a
+ // delete has succeeded, or after maxTableRows attempts.
+ for i := range maxTableRows {
+ if i >= maxTableRows/4 && writeMetrics[tableName].Deletes() > 0 {
+ break
+ }
generateDelete(t, tableName, conn)
}
+ require.NotZerof(t, writeMetrics[tableName].Deletes(), "no successful delete on %s while seeding", tableName)
})
t.Run("creating seed", func(t *testing.T) {
// We create the seed table in the likeness of stress_parent, because that's the only table
From 139c891fc5c383bb98c9c52acd40a3064862bfc6 Mon Sep 17 00:00:00 2001
From: "vitess-bot[bot]" <108069721+vitess-bot[bot]@users.noreply.github.com>
Date: Thu, 22 Oct 2026 23:05:40 +0000
Subject: [PATCH 29/31] [release-23.0] vtgate: fix None routing handling when
merging unions (#20629) (#20940)
Signed-off-by: Arthur Schreiber
Co-authored-by: vitess-bot[bot] <108069721+vitess-bot[bot]@users.noreply.github.com>
Co-authored-by: Arthur Schreiber
Co-authored-by: Claude Opus 5.5 (1M context)
---
.../vtgate/queries/union/union_test.go | 2 +
go/vt/vtgate/planbuilder/operators/route.go | 5 +
.../planbuilder/operators/route_planning.go | 58 ++
.../operators/route_planning_test.go | 179 ++++
.../planbuilder/operators/union_merging.go | 87 +-
.../planbuilder/testdata/dml_cases.json | 124 +++
.../planbuilder/testdata/union_cases.json | 790 ++++++++++++++++++
7 files changed, 1240 insertions(+), 5 deletions(-)
create mode 100644 go/vt/vtgate/planbuilder/operators/route_planning_test.go
diff --git a/go/test/endtoend/vtgate/queries/union/union_test.go b/go/test/endtoend/vtgate/queries/union/union_test.go
index 36b7204bdad..2180cae37e1 100644
--- a/go/test/endtoend/vtgate/queries/union/union_test.go
+++ b/go/test/endtoend/vtgate/queries/union/union_test.go
@@ -67,6 +67,8 @@ func TestUnionDistinct(t *testing.T) {
mcmp.AssertMatchesNoOrder("select id1, id2 from t1 union select 827, 452 union select id3,id4 from t2",
"[[INT64(4) INT64(4)] [INT64(1) INT64(1)] [INT64(2) INT64(2)] [INT64(3) INT64(3)] [INT64(827) INT64(452)] [INT64(2) INT64(3)] [INT64(3) INT64(4)] [INT64(5) INT64(5)]]")
mcmp.AssertMatches("select 1 from dual where 1 IN (select 1 as col union select 2)", "[[INT64(1)]]")
+ mcmp.AssertMatches("select 1 from dual union select id1 from t1 where id1 in (null)", "[[INT64(1)]]")
+ mcmp.AssertMatches("select id1 from t1 where id1 in (null) union select 1 from dual", "[[INT64(1)]]")
if utils.BinaryIsAtLeastAtVersion(19, "vtgate") {
mcmp.AssertMatches(`SELECT 1 from t1 UNION SELECT 2 from t1`, `[[INT64(1)] [INT64(2)]]`)
mcmp.AssertMatches(`SELECT 5 from t1 UNION SELECT 6 from t1`, `[[INT64(5)] [INT64(6)]]`)
diff --git a/go/vt/vtgate/planbuilder/operators/route.go b/go/vt/vtgate/planbuilder/operators/route.go
index 9fcd58b80bc..a47cd2a87c7 100644
--- a/go/vt/vtgate/planbuilder/operators/route.go
+++ b/go/vt/vtgate/planbuilder/operators/route.go
@@ -116,6 +116,11 @@ type (
// UpdateRoutingLogic first checks if we are dealing with a predicate that
func UpdateRoutingLogic(ctx *plancontext.PlanningContext, in sqlparser.Expr, r Routing) Routing {
+ if nr, ok := r.(*NoneRouting); ok {
+ // a none routing stays none no matter what further predicates say.
+ return nr
+ }
+
ks := r.Keyspace()
if ks == nil {
var err error
diff --git a/go/vt/vtgate/planbuilder/operators/route_planning.go b/go/vt/vtgate/planbuilder/operators/route_planning.go
index 7e7307b097c..0c16036bdcb 100644
--- a/go/vt/vtgate/planbuilder/operators/route_planning.go
+++ b/go/vt/vtgate/planbuilder/operators/route_planning.go
@@ -19,6 +19,7 @@ package operators
import (
"bytes"
"io"
+ "slices"
querypb "vitess.io/vitess/go/vt/proto/query"
topodatapb "vitess.io/vitess/go/vt/proto/topodata"
@@ -322,6 +323,63 @@ func mergeOrJoin(ctx *plancontext.PlanningContext, lhs, rhs Operator, joinPredic
return join, Rewrote("logical join to applyJoin ")
}
+// realTableKeyspaces collects the distinct keyspaces of the real tables under
+// op. Virtual tables (recursive CTE references) have no vschema table behind
+// them, dual is only a synthetic reference table that exists on every shard,
+// and information_schema tables only get a synthetic VTable in an arbitrary
+// keyspace (createInfSchemaRoute), so none of them contributes anything.
+// This reflects where the referenced tables actually live rather than where a
+// routing points.
+func realTableKeyspaces(op Operator) []*vindexes.Keyspace {
+ if op == nil {
+ return nil
+ }
+ var result []*vindexes.Keyspace
+ _ = Visit(op, func(this Operator) error {
+ tbl, ok := this.(*Table)
+ if !ok || tbl.VTable == nil {
+ return nil
+ }
+ if tbl.QTable != nil && tbl.QTable.IsInfSchema {
+ return nil
+ }
+ if tbl.VTable.Type == vindexes.TypeReference && tbl.VTable.Name.String() == "dual" {
+ return nil
+ }
+ addOperatorKeyspace(&result, tbl.VTable.Keyspace)
+ return nil
+ })
+ return result
+}
+
+// addOperatorKeyspace appends ks to result unless it is nil or already present.
+// Uses slice-based dedup with pointer equality (Vitess shares keyspace objects by
+// pointer within a planning context) since the number of distinct keyspaces is
+// very small.
+func addOperatorKeyspace(result *[]*vindexes.Keyspace, ks *vindexes.Keyspace) {
+ if ks == nil {
+ return
+ }
+ if slices.Contains(*result, ks) {
+ return
+ }
+ *result = append(*result, ks)
+}
+
+// hasInfoSchemaTables reports whether any table under op reads from
+// information_schema.
+func hasInfoSchemaTables(op Operator) bool {
+ var found bool
+ _ = Visit(op, func(this Operator) error {
+ if tbl, ok := this.(*Table); ok && tbl.QTable != nil && tbl.QTable.IsInfSchema {
+ found = true
+ return io.EOF
+ }
+ return nil
+ })
+ return found
+}
+
func operatorsToRoutes(a, b Operator) (*Route, *Route) {
aRoute, ok := a.(*Route)
if !ok {
diff --git a/go/vt/vtgate/planbuilder/operators/route_planning_test.go b/go/vt/vtgate/planbuilder/operators/route_planning_test.go
new file mode 100644
index 00000000000..d464d8c4878
--- /dev/null
+++ b/go/vt/vtgate/planbuilder/operators/route_planning_test.go
@@ -0,0 +1,179 @@
+/*
+Copyright 2026 The Vitess Authors.
+
+Licensed under the Apache License, Version 2.0 (the "License");
+you may not use this file except in compliance with the License.
+You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing, software
+distributed under the License is distributed on an "AS IS" BASIS,
+WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+See the License for the specific language governing permissions and
+limitations under the License.
+*/
+
+package operators
+
+import (
+ "testing"
+
+ "github.com/stretchr/testify/assert"
+
+ "vitess.io/vitess/go/vt/sqlparser"
+ "vitess.io/vitess/go/vt/vtgate/planbuilder/plancontext"
+ "vitess.io/vitess/go/vt/vtgate/semantics"
+ "vitess.io/vitess/go/vt/vtgate/vindexes"
+)
+
+func TestRealTableKeyspaces(t *testing.T) {
+ ks1 := &vindexes.Keyspace{Name: "ks1"}
+ ks2 := &vindexes.Keyspace{Name: "ks2"}
+
+ makeTable := func(ks *vindexes.Keyspace) *Table {
+ return &Table{
+ QTable: &QueryTable{Table: sqlparser.NewTableName("t")},
+ VTable: &vindexes.BaseTable{Name: sqlparser.NewIdentifierCS("t"), Keyspace: ks},
+ }
+ }
+ makeInfSchemaTable := func(ks *vindexes.Keyspace) *Table {
+ return &Table{
+ QTable: &QueryTable{Table: sqlparser.NewTableName("tables"), IsInfSchema: true},
+ VTable: &vindexes.BaseTable{Name: sqlparser.NewIdentifierCS("tables"), Keyspace: ks},
+ }
+ }
+
+ tests := []struct {
+ name string
+ op Operator
+ expected []*vindexes.Keyspace
+ }{
+ {
+ name: "real table",
+ op: makeTable(ks1),
+ expected: []*vindexes.Keyspace{ks1},
+ },
+ {
+ name: "virtual dual table has no keyspace",
+ op: &Table{},
+ expected: nil,
+ },
+ {
+ name: "synthetic dual reference table has no keyspace",
+ op: &Table{
+ QTable: &QueryTable{Table: sqlparser.NewTableName("dual")},
+ VTable: &vindexes.BaseTable{Name: sqlparser.NewIdentifierCS("dual"), Keyspace: ks1, Type: vindexes.TypeReference},
+ },
+ expected: nil,
+ },
+ {
+ name: "table nested under a projection",
+ op: &Projection{unaryOperator: newUnaryOp(makeTable(ks1))},
+ expected: []*vindexes.Keyspace{ks1},
+ },
+ {
+ name: "same keyspace tables are deduplicated",
+ op: &Join{binaryOperator: newBinaryOp(makeTable(ks1), makeTable(ks1))},
+ expected: []*vindexes.Keyspace{ks1},
+ },
+ {
+ name: "tables from different keyspaces",
+ op: &Join{binaryOperator: newBinaryOp(makeTable(ks1), makeTable(ks2))},
+ expected: []*vindexes.Keyspace{ks1, ks2},
+ },
+ {
+ name: "real table joined with a virtual dual",
+ op: &Join{binaryOperator: newBinaryOp(makeTable(ks1), &Table{})},
+ expected: []*vindexes.Keyspace{ks1},
+ },
+ {
+ name: "information_schema table with a synthetic vtable contributes nothing",
+ op: makeInfSchemaTable(ks1),
+ expected: nil,
+ },
+ {
+ name: "information_schema table joined with a real table",
+ op: &Join{binaryOperator: newBinaryOp(makeInfSchemaTable(ks1), makeTable(ks2))},
+ expected: []*vindexes.Keyspace{ks2},
+ },
+ }
+
+ for _, tt := range tests {
+ t.Run(tt.name, func(t *testing.T) {
+ assert.Equal(t, tt.expected, realTableKeyspaces(tt.op))
+ })
+ }
+}
+
+func TestUpdateRoutingLogicKeepsNoneRouting(t *testing.T) {
+ ks := &vindexes.Keyspace{Name: "ks1"}
+ ctx := &plancontext.PlanningContext{
+ SemTable: &semantics.SemTable{},
+ }
+ orig := &NoneRouting{keyspace: ks}
+ falseCmp := &sqlparser.ComparisonExpr{
+ Operator: sqlparser.EqualOp,
+ Left: sqlparser.NewIntLiteral("1"),
+ Right: sqlparser.NewIntLiteral("2"),
+ }
+
+ got := UpdateRoutingLogic(ctx, falseCmp, orig)
+
+ assert.Same(t, orig, got)
+}
+
+func TestHasInfoSchemaTables(t *testing.T) {
+ ks1 := &vindexes.Keyspace{Name: "ks1"}
+
+ makeTable := func() *Table {
+ return &Table{
+ QTable: &QueryTable{Table: sqlparser.NewTableName("t")},
+ VTable: &vindexes.BaseTable{Name: sqlparser.NewIdentifierCS("t"), Keyspace: ks1},
+ }
+ }
+ makeInfSchemaTable := func() *Table {
+ return &Table{
+ QTable: &QueryTable{Table: sqlparser.NewTableName("tables"), IsInfSchema: true},
+ VTable: &vindexes.BaseTable{Name: sqlparser.NewIdentifierCS("tables"), Keyspace: ks1},
+ }
+ }
+
+ tests := []struct {
+ name string
+ op Operator
+ expected bool
+ }{
+ {
+ name: "real table",
+ op: makeTable(),
+ expected: false,
+ },
+ {
+ name: "information_schema table",
+ op: makeInfSchemaTable(),
+ expected: true,
+ },
+ {
+ name: "virtual dual table",
+ op: &Table{},
+ expected: false,
+ },
+ {
+ name: "information_schema table nested under a projection",
+ op: &Projection{unaryOperator: newUnaryOp(makeInfSchemaTable())},
+ expected: true,
+ },
+ {
+ name: "information_schema table joined with a real table",
+ op: &Join{binaryOperator: newBinaryOp(makeTable(), makeInfSchemaTable())},
+ expected: true,
+ },
+ }
+
+ for _, tt := range tests {
+ t.Run(tt.name, func(t *testing.T) {
+ assert.Equal(t, tt.expected, hasInfoSchemaTables(tt.op))
+ })
+ }
+}
diff --git a/go/vt/vtgate/planbuilder/operators/union_merging.go b/go/vt/vtgate/planbuilder/operators/union_merging.go
index 6fafdb4fe4d..cf8a582320e 100644
--- a/go/vt/vtgate/planbuilder/operators/union_merging.go
+++ b/go/vt/vtgate/planbuilder/operators/union_merging.go
@@ -17,6 +17,8 @@ limitations under the License.
package operators
import (
+ "slices"
+
"vitess.io/vitess/go/vt/sqlparser"
"vitess.io/vitess/go/vt/vtgate/engine"
"vitess.io/vitess/go/vt/vtgate/evalengine"
@@ -113,6 +115,17 @@ func mergeUnionInputs(
return nil, nil
}
+ // a none routing resolves to no shards at execution time, so its side of the
+ // union contributes no rows. None pairings must be decided before the dual
+ // and anyShard cases below: those would retain the none routing and
+ // incorrectly discard the other side's rows.
+ if a == none || b == none {
+ if op, exprs, merged := tryMergeNoneUnion(ctx, lhsRoute, rhsRoute, lhsExprs, rhsExprs, distinct, routingA, routingB, a, b); merged {
+ return op, exprs
+ }
+ return nil, nil
+ }
+
switch {
// if either side is a dual query, we can always merge them together
// an unsharded/reference route can be merged with anything going to that keyspace
@@ -121,11 +134,6 @@ func mergeUnionInputs(
case a == dual || (a == anyShard && sameKeyspace):
return createMergedUnion(ctx, lhsRoute, rhsRoute, lhsExprs, rhsExprs, distinct, routingB, nil)
- case a == none:
- return createMergedUnion(ctx, lhsRoute, rhsRoute, lhsExprs, rhsExprs, distinct, routingB, nil)
- case b == none:
- return createMergedUnion(ctx, lhsRoute, rhsRoute, lhsExprs, rhsExprs, distinct, routingA, nil)
-
case a == sharded && b == sharded && sameKeyspace:
res, exprs := tryMergeUnionShardedRouting(ctx, lhsRoute, rhsRoute, lhsExprs, rhsExprs, distinct)
if res != nil {
@@ -135,6 +143,75 @@ func mergeUnionInputs(
return nil, nil
}
+// tryMergeNoneUnion merges a union pairing in which at least one side has a
+// none routing. The none side contributes no rows, but its query text (and the
+// field query derived from it) still references its tables, so a merge may only
+// adopt a routing whose keyspace holds every real table of the none side.
+func tryMergeNoneUnion(
+ ctx *plancontext.PlanningContext,
+ lhsRoute, rhsRoute *Route,
+ lhsExprs, rhsExprs []sqlparser.SelectExpr,
+ distinct bool,
+ routingA, routingB Routing,
+ a, b routingType,
+) (Operator, []sqlparser.SelectExpr, bool) {
+ otherRouting, otherType := routingB, b
+ noneRoute, otherRoute := lhsRoute, rhsRoute
+ if a != none {
+ otherRouting, otherType = routingA, a
+ noneRoute, otherRoute = rhsRoute, lhsRoute
+ }
+ noneKeyspaces := realTableKeyspaces(noneRoute.Source)
+
+ var routing Routing
+ switch {
+ case otherType == none:
+ // both sides are empty. They can collapse into a single none route as
+ // long as their combined real tables live in one keyspace: the merged
+ // route's field query must be executable on a shard of that keyspace.
+ for _, ks := range realTableKeyspaces(otherRoute.Source) {
+ if !slices.Contains(noneKeyspaces, ks) {
+ noneKeyspaces = append(noneKeyspaces, ks)
+ }
+ }
+ switch len(noneKeyspaces) {
+ case 0:
+ routing = noneRoute.Routing
+ case 1:
+ routing = &NoneRouting{keyspace: noneKeyspaces[0]}
+ default:
+ return nil, nil, false
+ }
+ case hasInfoSchemaTables(noneRoute.Source):
+ // an information_schema comparison may have been rewritten to a
+ // planner-generated argument (e.g. :__vtschemaname) that only a DBA
+ // route binds. Adopting an executable routing would ship that argument
+ // to a shard with no binding for it, so this branch must stay separate.
+ return nil, nil, false
+ case len(noneKeyspaces) == 0:
+ // the none side references no real tables, so its keyspace is only a
+ // placeholder: adopt the other side's routing unconditionally.
+ routing = otherRouting
+ case otherType == dual:
+ // a dual side has no keyspace and no tables of its own, so any shard
+ // in the none side's single keyspace can produce its rows.
+ if len(noneKeyspaces) != 1 {
+ return nil, nil, false
+ }
+ routing = &AnyShardRouting{keyspace: noneKeyspaces[0]}
+ default:
+ // the other side's routing is retained, but only when it targets the
+ // keyspace holding the none side's tables: they exist nowhere else.
+ if len(noneKeyspaces) != 1 || noneKeyspaces[0] != otherRouting.Keyspace() {
+ return nil, nil, false
+ }
+ routing = otherRouting
+ }
+
+ op, exprs := createMergedUnion(ctx, lhsRoute, rhsRoute, lhsExprs, rhsExprs, distinct, routing, nil)
+ return op, exprs, true
+}
+
func tryMergeUnionShardedRouting(
ctx *plancontext.PlanningContext,
routeA, routeB *Route,
diff --git a/go/vt/vtgate/planbuilder/testdata/dml_cases.json b/go/vt/vtgate/planbuilder/testdata/dml_cases.json
index 2c8457ecbcc..188950fcd83 100644
--- a/go/vt/vtgate/planbuilder/testdata/dml_cases.json
+++ b/go/vt/vtgate/planbuilder/testdata/dml_cases.json
@@ -7178,6 +7178,130 @@
]
}
},
+ {
+ "comment": "a destination-targeted union subquery with an empty same-keyspace branch merges into the destination route",
+ "query": "update `user[-80]`.user_extra set val = 1 where user_id in (select id from `user[-80]`.`user` where id in (null) union select id from `user[-80]`.`user`)",
+ "plan": {
+ "Type": "Complex",
+ "QueryType": "UPDATE",
+ "Original": "update `user[-80]`.user_extra set val = 1 where user_id in (select id from `user[-80]`.`user` where id in (null) union select id from `user[-80]`.`user`)",
+ "Instructions": {
+ "OperatorType": "UncorrelatedSubquery",
+ "Variant": "PulloutIn",
+ "PulloutVars": [
+ "__sq_has_values",
+ "__sq1"
+ ],
+ "Inputs": [
+ {
+ "InputName": "SubQuery",
+ "OperatorType": "Distinct",
+ "Collations": [
+ "(0:1)"
+ ],
+ "Inputs": [
+ {
+ "OperatorType": "Route",
+ "Variant": "ByDestination",
+ "Keyspace": {
+ "Name": "user",
+ "Sharded": true
+ },
+ "TargetDestination": "ExactKeyRange(-80)",
+ "FieldQuery": "select id, weight_string(id) from `user` where 1 != 1 union select id, weight_string(id) from `user` where 1 != 1",
+ "Query": "select id, weight_string(id) from `user` where id in (null) union select id, weight_string(id) from `user`"
+ }
+ ]
+ },
+ {
+ "InputName": "Outer",
+ "OperatorType": "Update",
+ "Variant": "ByDestination",
+ "Keyspace": {
+ "Name": "user",
+ "Sharded": true
+ },
+ "Query": "update user_extra set val = 1 where :__sq_has_values and user_id in ::__sq1"
+ }
+ ]
+ },
+ "TablesUsed": [
+ "user.user",
+ "user.user_extra"
+ ]
+ },
+ "skip_e2e": true
+ },
+ {
+ "comment": "a cross-keyspace empty branch stays separate from a destination-targeted branch",
+ "query": "update `user[-80]`.user_extra set val = 1 where user_id in (select oid from ordering.order_event where oid in (null) union select id from `user[-80]`.`user`)",
+ "plan": {
+ "Type": "Complex",
+ "QueryType": "UPDATE",
+ "Original": "update `user[-80]`.user_extra set val = 1 where user_id in (select oid from ordering.order_event where oid in (null) union select id from `user[-80]`.`user`)",
+ "Instructions": {
+ "OperatorType": "UncorrelatedSubquery",
+ "Variant": "PulloutIn",
+ "PulloutVars": [
+ "__sq_has_values",
+ "__sq1"
+ ],
+ "Inputs": [
+ {
+ "InputName": "SubQuery",
+ "OperatorType": "Distinct",
+ "Collations": [
+ "(0:1)"
+ ],
+ "Inputs": [
+ {
+ "OperatorType": "Concatenate",
+ "Inputs": [
+ {
+ "OperatorType": "Route",
+ "Variant": "None",
+ "Keyspace": {
+ "Name": "ordering",
+ "Sharded": true
+ },
+ "FieldQuery": "select oid, weight_string(oid) from order_event where 1 != 1",
+ "Query": "select distinct oid, weight_string(oid) from order_event where oid in (null) lock in share mode"
+ },
+ {
+ "OperatorType": "Route",
+ "Variant": "ByDestination",
+ "Keyspace": {
+ "Name": "user",
+ "Sharded": true
+ },
+ "TargetDestination": "ExactKeyRange(-80)",
+ "FieldQuery": "select id, weight_string(id) from `user` where 1 != 1",
+ "Query": "select distinct id, weight_string(id) from `user` lock in share mode"
+ }
+ ]
+ }
+ ]
+ },
+ {
+ "InputName": "Outer",
+ "OperatorType": "Update",
+ "Variant": "ByDestination",
+ "Keyspace": {
+ "Name": "user",
+ "Sharded": true
+ },
+ "Query": "update user_extra set val = 1 where :__sq_has_values and user_id in ::__sq1"
+ }
+ ]
+ },
+ "TablesUsed": [
+ "ordering.order_event",
+ "user.user",
+ "user.user_extra"
+ ]
+ },
+ "skip_e2e": true
+ },
{
"comment": "update with a row comparison against a value subquery binds each column of the row",
"query": "update user set col = 1 where (col, name) < (select user_id, col from music where user_id = 5)",
diff --git a/go/vt/vtgate/planbuilder/testdata/union_cases.json b/go/vt/vtgate/planbuilder/testdata/union_cases.json
index 0c953187990..151522bd119 100644
--- a/go/vt/vtgate/planbuilder/testdata/union_cases.json
+++ b/go/vt/vtgate/planbuilder/testdata/union_cases.json
@@ -454,6 +454,687 @@
]
}
},
+ {
+ "comment": "none routing merged with dual: any shard in the none side's keyspace serves the dual rows",
+ "query": "select id from user where id in (null) union select 1 from dual",
+ "plan": {
+ "Type": "Passthrough",
+ "QueryType": "SELECT",
+ "Original": "select id from user where id in (null) union select 1 from dual",
+ "Instructions": {
+ "OperatorType": "Route",
+ "Variant": "Reference",
+ "Keyspace": {
+ "Name": "user",
+ "Sharded": true
+ },
+ "FieldQuery": "select id from `user` where 1 != 1 union select 1 from dual where 1 != 1",
+ "Query": "select id from `user` where id in (null) union select 1 from dual"
+ },
+ "TablesUsed": [
+ "main.dual",
+ "user.user"
+ ]
+ }
+ },
+ {
+ "comment": "dual merged with a none routing on the right: any shard in the none side's keyspace serves the dual rows",
+ "query": "select 1 from dual union select id from user where id in (null)",
+ "plan": {
+ "Type": "Passthrough",
+ "QueryType": "SELECT",
+ "Original": "select 1 from dual union select id from user where id in (null)",
+ "Instructions": {
+ "OperatorType": "Route",
+ "Variant": "Reference",
+ "Keyspace": {
+ "Name": "user",
+ "Sharded": true
+ },
+ "FieldQuery": "select 1 from dual where 1 != 1 union select id from `user` where 1 != 1",
+ "Query": "select 1 from dual union select id from `user` where id in (null)"
+ },
+ "TablesUsed": [
+ "main.dual",
+ "user.user"
+ ]
+ }
+ },
+ {
+ "comment": "none routings from different keyspaces stay unmerged; the dual leg merges into one none side's keyspace",
+ "query": "select oid from ordering.order_event where oid in (null) union select id from user where id in (null) union select 1 from dual",
+ "plan": {
+ "Type": "Complex",
+ "QueryType": "SELECT",
+ "Original": "select oid from ordering.order_event where oid in (null) union select id from user where id in (null) union select 1 from dual",
+ "Instructions": {
+ "OperatorType": "Distinct",
+ "Collations": [
+ "(0:1)"
+ ],
+ "ResultColumns": 1,
+ "Inputs": [
+ {
+ "OperatorType": "Concatenate",
+ "Inputs": [
+ {
+ "OperatorType": "Route",
+ "Variant": "Reference",
+ "Keyspace": {
+ "Name": "ordering",
+ "Sharded": true
+ },
+ "FieldQuery": "select oid, weight_string(oid) from order_event where 1 != 1 union select 1, weight_string(1) from dual where 1 != 1",
+ "Query": "select oid, weight_string(oid) from order_event where oid in (null) union select 1, weight_string(1) from dual"
+ },
+ {
+ "OperatorType": "Route",
+ "Variant": "None",
+ "Keyspace": {
+ "Name": "user",
+ "Sharded": true
+ },
+ "FieldQuery": "select dt.c0 as id, weight_string(dt.c0) from (select id from `user` where 1 != 1) as dt(c0) where 1 != 1",
+ "Query": "select dt.c0 as id, weight_string(dt.c0) from (select distinct id from `user` where id in (null)) as dt(c0)"
+ }
+ ]
+ }
+ ]
+ },
+ "TablesUsed": [
+ "main.dual",
+ "ordering.order_event",
+ "user.user"
+ ]
+ },
+ "skip_e2e": true
+ },
+ {
+ "comment": "a none routing only merges with a sharded routing in its own keyspace",
+ "query": "select oid from ordering.order_event where oid in (null) union select id from user",
+ "plan": {
+ "Type": "Complex",
+ "QueryType": "SELECT",
+ "Original": "select oid from ordering.order_event where oid in (null) union select id from user",
+ "Instructions": {
+ "OperatorType": "Distinct",
+ "Collations": [
+ "(0:1)"
+ ],
+ "ResultColumns": 1,
+ "Inputs": [
+ {
+ "OperatorType": "Concatenate",
+ "Inputs": [
+ {
+ "OperatorType": "Route",
+ "Variant": "None",
+ "Keyspace": {
+ "Name": "ordering",
+ "Sharded": true
+ },
+ "FieldQuery": "select dt.c0 as oid, weight_string(dt.c0) from (select oid from order_event where 1 != 1) as dt(c0) where 1 != 1",
+ "Query": "select dt.c0 as oid, weight_string(dt.c0) from (select distinct oid from order_event where oid in (null)) as dt(c0)"
+ },
+ {
+ "OperatorType": "Route",
+ "Variant": "Scatter",
+ "Keyspace": {
+ "Name": "user",
+ "Sharded": true
+ },
+ "FieldQuery": "select dt.c0 as id, weight_string(dt.c0) from (select id from `user` where 1 != 1) as dt(c0) where 1 != 1",
+ "Query": "select dt.c0 as id, weight_string(dt.c0) from (select distinct id from `user`) as dt(c0)"
+ }
+ ]
+ }
+ ]
+ },
+ "TablesUsed": [
+ "ordering.order_event",
+ "user.user"
+ ]
+ },
+ "skip_e2e": true
+ },
+ {
+ "comment": "a none routing only merges with an unsharded routing in its own keyspace",
+ "query": "select oid from ordering.order_event where oid in (null) union select col from unsharded",
+ "plan": {
+ "Type": "Complex",
+ "QueryType": "SELECT",
+ "Original": "select oid from ordering.order_event where oid in (null) union select col from unsharded",
+ "Instructions": {
+ "OperatorType": "Distinct",
+ "Collations": [
+ "(0:1)"
+ ],
+ "ResultColumns": 1,
+ "Inputs": [
+ {
+ "OperatorType": "Concatenate",
+ "Inputs": [
+ {
+ "OperatorType": "Route",
+ "Variant": "None",
+ "Keyspace": {
+ "Name": "ordering",
+ "Sharded": true
+ },
+ "FieldQuery": "select dt.c0 as oid, weight_string(dt.c0) from (select oid from order_event where 1 != 1) as dt(c0) where 1 != 1",
+ "Query": "select dt.c0 as oid, weight_string(dt.c0) from (select distinct oid from order_event where oid in (null)) as dt(c0)"
+ },
+ {
+ "OperatorType": "Route",
+ "Variant": "Unsharded",
+ "Keyspace": {
+ "Name": "main",
+ "Sharded": false
+ },
+ "FieldQuery": "select dt.c0 as col, weight_string(dt.c0) from (select col from unsharded where 1 != 1) as dt(c0) where 1 != 1",
+ "Query": "select dt.c0 as col, weight_string(dt.c0) from (select distinct col from unsharded) as dt(c0)"
+ }
+ ]
+ }
+ ]
+ },
+ "TablesUsed": [
+ "main.unsharded",
+ "ordering.order_event"
+ ]
+ },
+ "skip_e2e": true
+ },
+ {
+ "comment": "a none routing merges with a sharded routing in the same keyspace",
+ "query": "select id from user where id in (null) union select id from user_extra",
+ "plan": {
+ "Type": "Complex",
+ "QueryType": "SELECT",
+ "Original": "select id from user where id in (null) union select id from user_extra",
+ "Instructions": {
+ "OperatorType": "Distinct",
+ "Collations": [
+ "(0:1)"
+ ],
+ "ResultColumns": 1,
+ "Inputs": [
+ {
+ "OperatorType": "Route",
+ "Variant": "Scatter",
+ "Keyspace": {
+ "Name": "user",
+ "Sharded": true
+ },
+ "FieldQuery": "select id, weight_string(id) from `user` where 1 != 1 union select id, weight_string(id) from user_extra where 1 != 1",
+ "Query": "select id, weight_string(id) from `user` where id in (null) union select id, weight_string(id) from user_extra"
+ }
+ ]
+ },
+ "TablesUsed": [
+ "user.user",
+ "user.user_extra"
+ ]
+ }
+ },
+ {
+ "comment": "union all keeps cross-keyspace none legs unmerged while the dual leg merges in order",
+ "query": "select oid from ordering.order_event where oid in (null) union all select id from user where id in (null) union all select 1 from dual",
+ "plan": {
+ "Type": "Complex",
+ "QueryType": "SELECT",
+ "Original": "select oid from ordering.order_event where oid in (null) union all select id from user where id in (null) union all select 1 from dual",
+ "Instructions": {
+ "OperatorType": "Concatenate",
+ "Inputs": [
+ {
+ "OperatorType": "Route",
+ "Variant": "None",
+ "Keyspace": {
+ "Name": "ordering",
+ "Sharded": true
+ },
+ "FieldQuery": "select oid from order_event where 1 != 1",
+ "Query": "select oid from order_event where oid in (null)"
+ },
+ {
+ "OperatorType": "Route",
+ "Variant": "Reference",
+ "Keyspace": {
+ "Name": "user",
+ "Sharded": true
+ },
+ "FieldQuery": "select id from `user` where 1 != 1 union all select 1 from dual where 1 != 1",
+ "Query": "select id from `user` where id in (null) union all select 1 from dual"
+ }
+ ]
+ },
+ "TablesUsed": [
+ "main.dual",
+ "ordering.order_event",
+ "user.user"
+ ]
+ },
+ "skip_e2e": true
+ },
+ {
+ "comment": "a dual-derived none routing that absorbed a real table only merges into that table's keyspace",
+ "query": "select u.col from unsharded as u, (select 1 from dual where 1 in (null)) as x union all select id from user",
+ "plan": {
+ "Type": "Complex",
+ "QueryType": "SELECT",
+ "Original": "select u.col from unsharded as u, (select 1 from dual where 1 in (null)) as x union all select id from user",
+ "Instructions": {
+ "OperatorType": "Concatenate",
+ "Inputs": [
+ {
+ "OperatorType": "Route",
+ "Variant": "None",
+ "Keyspace": {
+ "Name": "main",
+ "Sharded": false
+ },
+ "FieldQuery": "select u.col from (select 1 from dual where 1 != 1) as x, unsharded as u where 1 != 1",
+ "Query": "select u.col from (select 1 from dual where 1 in (null)) as x, unsharded as u"
+ },
+ {
+ "OperatorType": "Route",
+ "Variant": "Scatter",
+ "Keyspace": {
+ "Name": "user",
+ "Sharded": true
+ },
+ "FieldQuery": "select id from `user` where 1 != 1",
+ "Query": "select id from `user`"
+ }
+ ]
+ },
+ "TablesUsed": [
+ "main.dual",
+ "main.unsharded",
+ "user.user"
+ ]
+ }
+ },
+ {
+ "comment": "a dual-derived none routing that absorbed a real table merges with a branch in that table's keyspace",
+ "query": "select u.col from unsharded as u, (select 1 from dual where 1 in (null)) as x union select col2 from unsharded_auto",
+ "plan": {
+ "Type": "Passthrough",
+ "QueryType": "SELECT",
+ "Original": "select u.col from unsharded as u, (select 1 from dual where 1 in (null)) as x union select col2 from unsharded_auto",
+ "Instructions": {
+ "OperatorType": "Route",
+ "Variant": "Unsharded",
+ "Keyspace": {
+ "Name": "main",
+ "Sharded": false
+ },
+ "FieldQuery": "select u.col from unsharded as u, (select 1 from dual where 1 != 1) as x where 1 != 1 union select col2 from unsharded_auto where 1 != 1",
+ "Query": "select u.col from unsharded as u, (select 1 from dual where 1 in (null)) as x union select col2 from unsharded_auto"
+ },
+ "TablesUsed": [
+ "main.dual",
+ "main.unsharded",
+ "main.unsharded_auto"
+ ]
+ }
+ },
+ {
+ "comment": "none routings from different keyspaces stay unmerged: no single keyspace could resolve the merged field query",
+ "query": "select id from user where id in (null) union select oid from ordering.order_event where oid in (null)",
+ "plan": {
+ "Type": "Complex",
+ "QueryType": "SELECT",
+ "Original": "select id from user where id in (null) union select oid from ordering.order_event where oid in (null)",
+ "Instructions": {
+ "OperatorType": "Distinct",
+ "Collations": [
+ "(0:1)"
+ ],
+ "ResultColumns": 1,
+ "Inputs": [
+ {
+ "OperatorType": "Concatenate",
+ "Inputs": [
+ {
+ "OperatorType": "Route",
+ "Variant": "None",
+ "Keyspace": {
+ "Name": "user",
+ "Sharded": true
+ },
+ "FieldQuery": "select dt.c0 as id, weight_string(dt.c0) from (select id from `user` where 1 != 1) as dt(c0) where 1 != 1",
+ "Query": "select dt.c0 as id, weight_string(dt.c0) from (select distinct id from `user` where id in (null)) as dt(c0)"
+ },
+ {
+ "OperatorType": "Route",
+ "Variant": "None",
+ "Keyspace": {
+ "Name": "ordering",
+ "Sharded": true
+ },
+ "FieldQuery": "select dt.c0 as oid, weight_string(dt.c0) from (select oid from order_event where 1 != 1) as dt(c0) where 1 != 1",
+ "Query": "select dt.c0 as oid, weight_string(dt.c0) from (select distinct oid from order_event where oid in (null)) as dt(c0)"
+ }
+ ]
+ }
+ ]
+ },
+ "TablesUsed": [
+ "ordering.order_event",
+ "user.user"
+ ]
+ },
+ "skip_e2e": true
+ },
+ {
+ "comment": "a none routing over a rewritten information_schema branch must not adopt the dual side: only a DBA route binds :__vtschemaname",
+ "query": "select table_name from information_schema.tables where table_schema = 'user' and 1 = 2 union select 1 from dual",
+ "plan": {
+ "Type": "Complex",
+ "QueryType": "SELECT",
+ "Original": "select table_name from information_schema.tables where table_schema = 'user' and 1 = 2 union select 1 from dual",
+ "Instructions": {
+ "OperatorType": "Distinct",
+ "Collations": [
+ "0: utf8mb3_general_ci"
+ ],
+ "Inputs": [
+ {
+ "OperatorType": "Concatenate",
+ "Inputs": [
+ {
+ "OperatorType": "Route",
+ "Variant": "None",
+ "Keyspace": {
+ "Name": "main",
+ "Sharded": false
+ },
+ "FieldQuery": "select `table_name` from information_schema.`tables` where 1 != 1",
+ "Query": "select distinct `table_name` from information_schema.`tables` where table_schema = :__vtschemaname /* VARCHAR */ and 0"
+ },
+ {
+ "OperatorType": "Route",
+ "Variant": "Reference",
+ "Keyspace": {
+ "Name": "main",
+ "Sharded": false
+ },
+ "FieldQuery": "select 1 from dual where 1 != 1",
+ "Query": "select distinct 1 from dual"
+ }
+ ]
+ }
+ ]
+ },
+ "TablesUsed": [
+ "main.dual"
+ ]
+ }
+ },
+ {
+ "comment": "the information_schema guard also applies when the other side lands on the inferred keyspace",
+ "query": "select table_name from information_schema.tables where table_schema = 'user' and 1 = 2 union select col from unsharded",
+ "plan": {
+ "Type": "Complex",
+ "QueryType": "SELECT",
+ "Original": "select table_name from information_schema.tables where table_schema = 'user' and 1 = 2 union select col from unsharded",
+ "Instructions": {
+ "OperatorType": "Distinct",
+ "Collations": [
+ "(0:1)"
+ ],
+ "ResultColumns": 1,
+ "Inputs": [
+ {
+ "OperatorType": "Concatenate",
+ "Inputs": [
+ {
+ "OperatorType": "Route",
+ "Variant": "None",
+ "Keyspace": {
+ "Name": "main",
+ "Sharded": false
+ },
+ "FieldQuery": "select dt.c0 as `table_name`, weight_string(dt.c0) from (select `table_name` from information_schema.`tables` where 1 != 1) as dt(c0) where 1 != 1",
+ "Query": "select dt.c0 as `table_name`, weight_string(dt.c0) from (select distinct `table_name` from information_schema.`tables` where table_schema = :__vtschemaname /* VARCHAR */ and 0) as dt(c0)"
+ },
+ {
+ "OperatorType": "Route",
+ "Variant": "Unsharded",
+ "Keyspace": {
+ "Name": "main",
+ "Sharded": false
+ },
+ "FieldQuery": "select dt.c0 as col, weight_string(dt.c0) from (select col from unsharded where 1 != 1) as dt(c0) where 1 != 1",
+ "Query": "select dt.c0 as col, weight_string(dt.c0) from (select distinct col from unsharded) as dt(c0)"
+ }
+ ]
+ }
+ ]
+ },
+ "TablesUsed": [
+ "main.unsharded"
+ ]
+ }
+ },
+ {
+ "comment": "a degraded information_schema branch stays separate from a sharded side",
+ "query": "select table_name from information_schema.tables where table_schema = 'user' and 1 = 2 union select id from user",
+ "plan": {
+ "Type": "Complex",
+ "QueryType": "SELECT",
+ "Original": "select table_name from information_schema.tables where table_schema = 'user' and 1 = 2 union select id from user",
+ "Instructions": {
+ "OperatorType": "Distinct",
+ "Collations": [
+ "(0:1)"
+ ],
+ "ResultColumns": 1,
+ "Inputs": [
+ {
+ "OperatorType": "Concatenate",
+ "Inputs": [
+ {
+ "OperatorType": "Route",
+ "Variant": "None",
+ "Keyspace": {
+ "Name": "main",
+ "Sharded": false
+ },
+ "FieldQuery": "select dt.c0 as `table_name`, weight_string(dt.c0) from (select `table_name` from information_schema.`tables` where 1 != 1) as dt(c0) where 1 != 1",
+ "Query": "select dt.c0 as `table_name`, weight_string(dt.c0) from (select distinct `table_name` from information_schema.`tables` where table_schema = :__vtschemaname /* VARCHAR */ and 0) as dt(c0)"
+ },
+ {
+ "OperatorType": "Route",
+ "Variant": "Scatter",
+ "Keyspace": {
+ "Name": "user",
+ "Sharded": true
+ },
+ "FieldQuery": "select dt.c0 as id, weight_string(dt.c0) from (select id from `user` where 1 != 1) as dt(c0) where 1 != 1",
+ "Query": "select dt.c0 as id, weight_string(dt.c0) from (select distinct id from `user`) as dt(c0)"
+ }
+ ]
+ }
+ ]
+ },
+ "TablesUsed": [
+ "user.user"
+ ]
+ }
+ },
+ {
+ "comment": "a degraded information_schema branch stays separate from a live DBA route",
+ "query": "select table_name from information_schema.tables where table_schema = 'user' and 1 = 2 union select table_name from information_schema.columns",
+ "plan": {
+ "Type": "Complex",
+ "QueryType": "SELECT",
+ "Original": "select table_name from information_schema.tables where table_schema = 'user' and 1 = 2 union select table_name from information_schema.columns",
+ "Instructions": {
+ "OperatorType": "Distinct",
+ "Collations": [
+ "0: utf8mb3_general_ci"
+ ],
+ "Inputs": [
+ {
+ "OperatorType": "Concatenate",
+ "Inputs": [
+ {
+ "OperatorType": "Route",
+ "Variant": "None",
+ "Keyspace": {
+ "Name": "main",
+ "Sharded": false
+ },
+ "FieldQuery": "select `table_name` from information_schema.`tables` where 1 != 1",
+ "Query": "select distinct `table_name` from information_schema.`tables` where table_schema = :__vtschemaname /* VARCHAR */ and 0"
+ },
+ {
+ "OperatorType": "Route",
+ "Variant": "DBA",
+ "Keyspace": {
+ "Name": "main",
+ "Sharded": false
+ },
+ "FieldQuery": "select `table_name` from information_schema.`columns` where 1 != 1",
+ "Query": "select distinct `table_name` from information_schema.`columns`"
+ }
+ ]
+ }
+ ]
+ }
+ },
+ "skip_e2e": true
+ },
+ {
+ "comment": "a reference-degraded none routing keeps its canonical keyspace and declines a cross-keyspace merge",
+ "query": "select id from ambiguous_ref_with_source where id in (null) union select id from user",
+ "plan": {
+ "Type": "Complex",
+ "QueryType": "SELECT",
+ "Original": "select id from ambiguous_ref_with_source where id in (null) union select id from user",
+ "Instructions": {
+ "OperatorType": "Distinct",
+ "Collations": [
+ "(0:1)"
+ ],
+ "ResultColumns": 1,
+ "Inputs": [
+ {
+ "OperatorType": "Concatenate",
+ "Inputs": [
+ {
+ "OperatorType": "Route",
+ "Variant": "None",
+ "Keyspace": {
+ "Name": "main",
+ "Sharded": false
+ },
+ "FieldQuery": "select dt.c0 as id, weight_string(dt.c0) from (select id from ambiguous_ref_with_source where 1 != 1) as dt(c0) where 1 != 1",
+ "Query": "select dt.c0 as id, weight_string(dt.c0) from (select distinct id from ambiguous_ref_with_source where id in (null)) as dt(c0)"
+ },
+ {
+ "OperatorType": "Route",
+ "Variant": "Scatter",
+ "Keyspace": {
+ "Name": "user",
+ "Sharded": true
+ },
+ "FieldQuery": "select dt.c0 as id, weight_string(dt.c0) from (select id from `user` where 1 != 1) as dt(c0) where 1 != 1",
+ "Query": "select dt.c0 as id, weight_string(dt.c0) from (select distinct id from `user`) as dt(c0)"
+ }
+ ]
+ }
+ ]
+ },
+ "TablesUsed": [
+ "main.ambiguous_ref_with_source",
+ "user.user"
+ ]
+ }
+ },
+ {
+ "comment": "differing physical reference names must not merge: the none side's table does not exist in the other keyspace",
+ "query": "select id from source_of_ref where id in (null) union select id from user",
+ "plan": {
+ "Type": "Complex",
+ "QueryType": "SELECT",
+ "Original": "select id from source_of_ref where id in (null) union select id from user",
+ "Instructions": {
+ "OperatorType": "Distinct",
+ "Collations": [
+ "(0:1)"
+ ],
+ "ResultColumns": 1,
+ "Inputs": [
+ {
+ "OperatorType": "Concatenate",
+ "Inputs": [
+ {
+ "OperatorType": "Route",
+ "Variant": "None",
+ "Keyspace": {
+ "Name": "main",
+ "Sharded": false
+ },
+ "FieldQuery": "select dt.c0 as id, weight_string(dt.c0) from (select id from source_of_ref where 1 != 1) as dt(c0) where 1 != 1",
+ "Query": "select dt.c0 as id, weight_string(dt.c0) from (select distinct id from source_of_ref where id in (null)) as dt(c0)"
+ },
+ {
+ "OperatorType": "Route",
+ "Variant": "Scatter",
+ "Keyspace": {
+ "Name": "user",
+ "Sharded": true
+ },
+ "FieldQuery": "select dt.c0 as id, weight_string(dt.c0) from (select id from `user` where 1 != 1) as dt(c0) where 1 != 1",
+ "Query": "select dt.c0 as id, weight_string(dt.c0) from (select distinct id from `user`) as dt(c0)"
+ }
+ ]
+ }
+ ]
+ },
+ "TablesUsed": [
+ "main.source_of_ref",
+ "user.user"
+ ]
+ }
+ },
+ {
+ "comment": "a reference-degraded none routing whose keyspace matches the other side still merges",
+ "query": "select id from ref_with_source where id in (null) union select id from user",
+ "plan": {
+ "Type": "Complex",
+ "QueryType": "SELECT",
+ "Original": "select id from ref_with_source where id in (null) union select id from user",
+ "Instructions": {
+ "OperatorType": "Distinct",
+ "Collations": [
+ "(0:1)"
+ ],
+ "ResultColumns": 1,
+ "Inputs": [
+ {
+ "OperatorType": "Route",
+ "Variant": "Scatter",
+ "Keyspace": {
+ "Name": "user",
+ "Sharded": true
+ },
+ "FieldQuery": "select id, weight_string(id) from ref_with_source where 1 != 1 union select id, weight_string(id) from `user` where 1 != 1",
+ "Query": "select id, weight_string(id) from ref_with_source where id in (null) union select id, weight_string(id) from `user`"
+ }
+ ]
+ },
+ "TablesUsed": [
+ "user.ref_with_source",
+ "user.user"
+ ]
+ },
+ "skip_e2e": true
+ },
{
"comment": "union with the same target shard because of vindex",
"query": "select * from music where user_id = 1 union select * from user where id = 1",
@@ -2125,5 +2806,114 @@
"user.user"
]
}
+ },
+ {
+ "comment": "statically false dual branch merges into the other side's keyspace",
+ "query": "select 42 from dual where false union select id from user",
+ "plan": {
+ "Type": "Complex",
+ "QueryType": "SELECT",
+ "Original": "select 42 from dual where false union select id from user",
+ "Instructions": {
+ "OperatorType": "Distinct",
+ "Collations": [
+ "0"
+ ],
+ "Inputs": [
+ {
+ "OperatorType": "Route",
+ "Variant": "Scatter",
+ "Keyspace": {
+ "Name": "user",
+ "Sharded": true
+ },
+ "FieldQuery": "select 42 from dual where 1 != 1 union select id from `user` where 1 != 1",
+ "Query": "select 42 from dual where 0 union select id from `user`"
+ }
+ ]
+ },
+ "TablesUsed": [
+ "main.dual",
+ "user.user"
+ ]
+ }
+ },
+ {
+ "comment": "statically false dual branch on the right merges into the other side's keyspace",
+ "query": "select id from user union select 42 from dual where false",
+ "plan": {
+ "Type": "Complex",
+ "QueryType": "SELECT",
+ "Original": "select id from user union select 42 from dual where false",
+ "Instructions": {
+ "OperatorType": "Distinct",
+ "Collations": [
+ "0"
+ ],
+ "Inputs": [
+ {
+ "OperatorType": "Route",
+ "Variant": "Scatter",
+ "Keyspace": {
+ "Name": "user",
+ "Sharded": true
+ },
+ "FieldQuery": "select id from `user` where 1 != 1 union select 42 from dual where 1 != 1",
+ "Query": "select id from `user` union select 42 from dual where 0"
+ }
+ ]
+ },
+ "TablesUsed": [
+ "main.dual",
+ "user.user"
+ ]
+ }
+ },
+ {
+ "comment": "a none routing over a sharded table stays separate from a live DBA route",
+ "query": "select id from user where id in (null) union select table_name from information_schema.tables",
+ "plan": {
+ "Type": "Complex",
+ "QueryType": "SELECT",
+ "Original": "select id from user where id in (null) union select table_name from information_schema.tables",
+ "Instructions": {
+ "OperatorType": "Distinct",
+ "Collations": [
+ "(0:1)"
+ ],
+ "ResultColumns": 1,
+ "Inputs": [
+ {
+ "OperatorType": "Concatenate",
+ "Inputs": [
+ {
+ "OperatorType": "Route",
+ "Variant": "None",
+ "Keyspace": {
+ "Name": "user",
+ "Sharded": true
+ },
+ "FieldQuery": "select dt.c0 as id, weight_string(dt.c0) from (select id from `user` where 1 != 1) as dt(c0) where 1 != 1",
+ "Query": "select dt.c0 as id, weight_string(dt.c0) from (select distinct id from `user` where id in (null)) as dt(c0)"
+ },
+ {
+ "OperatorType": "Route",
+ "Variant": "DBA",
+ "Keyspace": {
+ "Name": "main",
+ "Sharded": false
+ },
+ "FieldQuery": "select dt.c0 as `table_name`, weight_string(dt.c0) from (select `table_name` from information_schema.`tables` where 1 != 1) as dt(c0) where 1 != 1",
+ "Query": "select dt.c0 as `table_name`, weight_string(dt.c0) from (select distinct `table_name` from information_schema.`tables`) as dt(c0)"
+ }
+ ]
+ }
+ ]
+ },
+ "TablesUsed": [
+ "user.user"
+ ]
+ },
+ "skip_e2e": true
}
]
From 11e2d868c70bc5b02da63e4cf76a807278e6e5e0 Mon Sep 17 00:00:00 2001
From: Arthur Schreiber
Date: Fri, 23 Oct 2026 17:43:06 +0200
Subject: [PATCH 30/31] [release-23.0] test: pass vtbackup the flag names its
version accepts (#21706)
Signed-off-by: Arthur Schreiber
Co-authored-by: Claude Opus 5.5
---
.../backup/vtbackup/backup_only_test.go | 9 ++--
go/test/endtoend/cluster/vtbackup_process.go | 44 ++++++++-----------
2 files changed, 24 insertions(+), 29 deletions(-)
diff --git a/go/test/endtoend/backup/vtbackup/backup_only_test.go b/go/test/endtoend/backup/vtbackup/backup_only_test.go
index c841ef43a12..a0541e88853 100644
--- a/go/test/endtoend/backup/vtbackup/backup_only_test.go
+++ b/go/test/endtoend/backup/vtbackup/backup_only_test.go
@@ -241,16 +241,19 @@ func startVtBackup(t *testing.T, initialBackup bool, restartBeforeBackup, disabl
// Prepare opentsdb stats file path.
statsPath := path.Join(t.TempDir(), fmt.Sprintf("opentsdb.%s.txt", t.Name()))
+ vtbackupVer, err := cluster.GetMajorVersion("vtbackup")
+ require.NoError(t, err)
+
// Take the back using vtbackup executable
extraArgs := []string{
"--allow_first_backup",
"--db-credentials-file", dbCredentialFile,
- utils.GetFlagVariantForTests("--mysql-socket"), mysqlSocket.Name(),
+ utils.GetFlagVariantForTestsByVersion("--mysql-socket", vtbackupVer), mysqlSocket.Name(),
// Use opentsdb for stats.
- utils.GetFlagVariantForTests("--stats-backend"), "opentsdb",
+ utils.GetFlagVariantForTestsByVersion("--stats-backend", vtbackupVer), "opentsdb",
// Write stats to file for reading afterwards.
- utils.GetFlagVariantForTests("--opentsdb-uri"), fmt.Sprintf("file://%s", statsPath),
+ utils.GetFlagVariantForTestsByVersion("--opentsdb-uri", vtbackupVer), fmt.Sprintf("file://%s", statsPath),
}
if restartBeforeBackup {
extraArgs = append(extraArgs, "--restart_before_backup")
diff --git a/go/test/endtoend/cluster/vtbackup_process.go b/go/test/endtoend/cluster/vtbackup_process.go
index 8114924ee2a..e9cde27f116 100644
--- a/go/test/endtoend/cluster/vtbackup_process.go
+++ b/go/test/endtoend/cluster/vtbackup_process.go
@@ -60,36 +60,28 @@ func (vtbackup *VtbackupProcess) Setup() (err error) {
if err != nil {
return err
}
- flags := map[string]string{
- "--topo-implementation": vtbackup.TopoImplementation,
- "--topo-global-server-address": vtbackup.TopoGlobalAddress,
- "--topo-global-root": vtbackup.TopoGlobalRoot,
- "--log_dir": vtbackup.LogDir,
+ // The dashed flag names only exist from v23 on, and vtbackup may be the
+ // previous release in upgrade/downgrade tests.
+ flagFor := func(name string) string {
+ return utils.GetFlagVariantForTestsByVersion(name, vtbackupVer)
+ }
+ vtbackup.proc = exec.Command(
+ vtbackup.Binary,
+ flagFor("--topo-implementation"), vtbackup.TopoImplementation,
+ flagFor("--topo-global-server-address"), vtbackup.TopoGlobalAddress,
+ flagFor("--topo-global-root"), vtbackup.TopoGlobalRoot,
+ "--log_dir", vtbackup.LogDir,
//initDBfile is required to run vtbackup
- "--mysql-port": fmt.Sprintf("%d", vtbackup.MysqlPort),
- "--init-db-sql-file": vtbackup.initDBfile,
- "--init-keyspace": vtbackup.Keyspace,
- "--init-shard": vtbackup.Shard,
+ flagFor("--mysql-port"), fmt.Sprintf("%d", vtbackup.MysqlPort),
+ flagFor("--init-db-sql-file"), vtbackup.initDBfile,
+ flagFor("--init-keyspace"), vtbackup.Keyspace,
+ flagFor("--init-shard"), vtbackup.Shard,
//Backup Arguments are not optional
- utils.GetFlagVariantForTestsByVersion("--file-backup-storage-root", vtbackupVer): vtbackup.BackupStorageImplementation,
- "--file-backup-storage-root": vtbackup.FileBackupStorageRoot,
- }
-
- utils.SetFlagVariantsForTests(flags, "--topo-implementation", vtbackup.TopoImplementation)
- utils.SetFlagVariantsForTests(flags, "--topo-global-server-address", vtbackup.TopoGlobalAddress)
- utils.SetFlagVariantsForTests(flags, "--topo-global-root", vtbackup.TopoGlobalRoot)
- utils.SetFlagVariantsForTests(flags, "--mysql-port", fmt.Sprintf("%d", vtbackup.MysqlPort))
- utils.SetFlagVariantsForTests(flags, "--init-db-sql-file", vtbackup.initDBfile)
- utils.SetFlagVariantsForTests(flags, "--init-keyspace", vtbackup.Keyspace)
- utils.SetFlagVariantsForTests(flags, "--init-shard", vtbackup.Shard)
- utils.SetFlagVariantsForTests(flags, "--backup-storage-implementation", vtbackup.BackupStorageImplementation)
-
- vtbackup.proc = exec.Command(vtbackup.Binary)
- for k, v := range flags {
- vtbackup.proc.Args = append(vtbackup.proc.Args, k, v)
- }
+ flagFor("--backup-storage-implementation"), vtbackup.BackupStorageImplementation,
+ flagFor("--file-backup-storage-root"), vtbackup.FileBackupStorageRoot,
+ )
if vtbackup.initialBackup {
vtbackup.proc.Args = append(vtbackup.proc.Args, "--initial_backup")
From 19c0637a061fa4f02b1f66524c182fb55b7a6d5f Mon Sep 17 00:00:00 2001
From: "vitess-bot[bot]" <108069721+vitess-bot[bot]@users.noreply.github.com>
Date: Fri, 23 Oct 2026 15:58:52 +0000
Subject: [PATCH 31/31] [release-23.0] CI: point apt at a responsive Ubuntu
archive server (#21724) (#21731)
Signed-off-by: Arthur Schreiber
Co-authored-by: vitess-bot[bot] <108069721+vitess-bot[bot]@users.noreply.github.com>
Co-authored-by: Arthur Schreiber
Co-authored-by: Claude Opus 5.5
---
.github/actions/tune-os/action.yml | 3 +
.github/actions/tune-os/pin-ubuntu-mirror.sh | 110 ++++++++++++++++++
.github/workflows/cluster_endtoend.yml | 1 +
.../cluster_endtoend_disk_health_monitor.yml | 1 +
.github/workflows/codecov.yml | 1 +
.github/workflows/e2e_race.yml | 1 +
.github/workflows/endtoend.yml | 1 +
.github/workflows/unit_test.yml | 1 +
.../upgrade_downgrade_test_backups_e2e.yml | 1 +
...owngrade_test_backups_e2e_next_release.yml | 1 +
.../upgrade_downgrade_test_backups_manual.yml | 1 +
...grade_test_backups_manual_next_release.yml | 1 +
.../upgrade_downgrade_test_onlineddl_flow.yml | 1 +
...e_downgrade_test_query_serving_queries.yml | 1 +
...downgrade_test_query_serving_queries_2.yml | 1 +
...t_query_serving_queries_2_next_release.yml | 1 +
...est_query_serving_queries_next_release.yml | 1 +
...de_downgrade_test_query_serving_schema.yml | 1 +
...test_query_serving_schema_next_release.yml | 1 +
...rade_downgrade_test_reparent_new_vtctl.yml | 1 +
...e_downgrade_test_reparent_new_vttablet.yml | 1 +
...rade_downgrade_test_reparent_old_vtctl.yml | 1 +
...e_downgrade_test_reparent_old_vttablet.yml | 1 +
.github/workflows/vitess_tester_vtgate.yml | 1 +
.github/workflows/vtop_example.yml | 1 +
25 files changed, 136 insertions(+)
create mode 100755 .github/actions/tune-os/pin-ubuntu-mirror.sh
diff --git a/.github/actions/tune-os/action.yml b/.github/actions/tune-os/action.yml
index d3522c38d8a..1d4aa77254a 100644
--- a/.github/actions/tune-os/action.yml
+++ b/.github/actions/tune-os/action.yml
@@ -6,6 +6,9 @@ runs:
- name: Tune the OS
shell: bash -e {0}
run: |
+ # Before the first apt run, so that all of the job's apt runs use it.
+ "${GITHUB_ACTION_PATH}/pin-ubuntu-mirror.sh"
+
# Install eatmydata and ensure it's used for every operation
sudo apt-get update && sudo apt-get install -y eatmydata
echo "/usr/\${LIB}/libeatmydata.so" | sudo tee -a /etc/ld.so.preload
diff --git a/.github/actions/tune-os/pin-ubuntu-mirror.sh b/.github/actions/tune-os/pin-ubuntu-mirror.sh
new file mode 100755
index 00000000000..05a1b9b503a
--- /dev/null
+++ b/.github/actions/tune-os/pin-ubuntu-mirror.sh
@@ -0,0 +1,110 @@
+#!/bin/bash
+
+# Copyright 2026 The Vitess Authors.
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+# Points apt at a responsive Ubuntu archive server before the job's first apt
+# run. The archive's host name resolves to several servers, some of which
+# intermittently answer only after 10-20 seconds and then send 50 kB/s, and apt
+# keeps downloading from them however long that takes. The Azure mirror that
+# the runner images list first sometimes does not answer at all, or sends
+# packages at 40 kB/s while it serves the release file instantly, so a probe
+# cannot tell when to trust it. This times a download of the release file over
+# HTTP and HTTPS from each of the archive's addresses, pins the archive's host
+# names in /etc/hosts to every address that answered both within 1 second or
+# within 3 times the fastest one's time, so that whatever resolves them still
+# has other addresses to fail over to even when one address is much closer than
+# the others, and points apt at the archive instead of the Azure mirror.
+# When no address answers, the archive itself is down, so it leaves apt on the
+# Azure mirror.
+
+set -uo pipefail
+
+if [[ "$(dpkg --print-architecture)" == "arm64" ]]; then
+ archive=ports.ubuntu.com
+ path=ubuntu-ports
+else
+ archive=archive.ubuntu.com
+ path=ubuntu
+fi
+codename="$(awk -F= '$1 == "VERSION_CODENAME" {print $2}' /etc/os-release)"
+
+# Prints HOST's IPv4 addresses. The resolver of GitHub's hosted runners returns
+# only one of the archive's addresses, which may be a slow one, so this also
+# asks two public resolvers over HTTPS for all of them.
+resolve() {
+ local host="$1"
+ {
+ getent ahostsv4 "${host}" | awk '{print $1}'
+ curl -fsS --max-time 3 -H 'accept: application/dns-json' \
+ "https://cloudflare-dns.com/dns-query?name=${host}&type=A" 2> /dev/null |
+ grep -oE '"data": ?"[0-9.]+"' | grep -oE '[0-9.]+'
+ curl -fsS --max-time 3 "https://dns.google/resolve?name=${host}&type=A" 2> /dev/null |
+ grep -oE '"data": ?"[0-9.]+"' | grep -oE '[0-9.]+'
+ } | grep -xE '[0-9]+\.[0-9]+\.[0-9]+\.[0-9]+' | sort -u
+}
+
+# Prints the seconds it took to download the release file from HOST via IP
+# over SCHEME, or nothing if that failed or took longer than 3 seconds.
+probe() {
+ local host="$1" ip="$2" root="$3" scheme="$4" port=80
+ if [[ "${scheme}" == https ]]; then
+ port=443
+ fi
+ curl -fsS -o /dev/null --connect-timeout 2 --max-time 3 --resolve "${host}:${port}:${ip}" \
+ -w '%{time_total}\n' "${scheme}://${host}/${root}/dists/${codename}/InRelease" 2> /dev/null
+}
+
+# Prints the slower of the HTTP and HTTPS times, or nothing if either failed.
+probe_both() {
+ local http https
+ http="$(probe "$@" http)" && https="$(probe "$@" https)" &&
+ awk -v a="${http}" -v b="${https}" 'BEGIN { print (a > b ? a : b) }'
+}
+
+results="$(mktemp)"
+trap 'rm -f "${results}"' EXIT
+for ip in $(resolve "${archive}"); do
+ (
+ if t="$(probe_both "${archive}" "${ip}" "${path}")"; then
+ echo "${t} ${ip}" >> "${results}"
+ else
+ echo "Ubuntu archive probe: ${ip} did not answer within 3 seconds"
+ fi
+ ) &
+done
+wait
+
+sort -n "${results}" | sed 's/^/Ubuntu archive probe: /'
+best="$(sort -n "${results}" | head -1 | cut -d' ' -f2)"
+if [[ -z "${best}" ]]; then
+ echo "No Ubuntu archive server answered within 3 seconds; leaving apt as it is."
+ exit 0
+fi
+# security.ubuntu.com is served by the same servers as archive.ubuntu.com.
+security="$(resolve security.ubuntu.com)"
+fastest="$(sort -n "${results}" | head -1 | cut -d' ' -f1)"
+sort -n "${results}" | awk -v max="$(awk -v t="${fastest}" 'BEGIN { print (3 * t > 1 ? 3 * t : 1) }')" '$1 <= max { print $2 }' |
+ while read -r ip; do
+ names="${archive}"
+ if grep -qx "${ip}" <<< "${security}"; then
+ names="${names} security.ubuntu.com"
+ fi
+ echo "Pinning ${names} to ${ip}"
+ echo "${ip} ${names}" | sudo tee -a /etc/hosts > /dev/null
+ done
+files="$(sudo grep -rlF azure.archive.ubuntu.com /etc/apt 2> /dev/null || true)"
+if [[ -n "${files}" ]]; then
+ echo "${files}" | xargs sudo sed -i 's|azure\.archive\.ubuntu\.com|archive.ubuntu.com|g'
+fi
diff --git a/.github/workflows/cluster_endtoend.yml b/.github/workflows/cluster_endtoend.yml
index 63138ac7b2e..8af0e22b609 100644
--- a/.github/workflows/cluster_endtoend.yml
+++ b/.github/workflows/cluster_endtoend.yml
@@ -108,6 +108,7 @@ jobs:
- 'bootstrap.sh'
- '.github/workflows/cluster_endtoend.yml'
- '.github/actions/setup-mysql/action.yml'
+ - '.github/actions/tune-os/**'
- '.github/actions/setup-go/action.yml'
- '.github/actions/setup-microceph/action.yml'
diff --git a/.github/workflows/cluster_endtoend_disk_health_monitor.yml b/.github/workflows/cluster_endtoend_disk_health_monitor.yml
index 59892c4c6a4..f3ca0b4782c 100644
--- a/.github/workflows/cluster_endtoend_disk_health_monitor.yml
+++ b/.github/workflows/cluster_endtoend_disk_health_monitor.yml
@@ -77,6 +77,7 @@ jobs:
- 'bootstrap.sh'
- '.github/workflows/cluster_endtoend_disk_health_monitor.yml'
- '.github/actions/setup-mysql/action.yml'
+ - '.github/actions/tune-os/**'
- '.github/actions/setup-go/action.yml'
- name: Set up Go
diff --git a/.github/workflows/codecov.yml b/.github/workflows/codecov.yml
index f110ae77eb3..8284f809bd9 100644
--- a/.github/workflows/codecov.yml
+++ b/.github/workflows/codecov.yml
@@ -62,6 +62,7 @@ jobs:
changed_files:
- .github/workflows/codecov.yml
- .github/actions/setup-mysql/action.yml
+ - '.github/actions/tune-os/**'
- .github/actions/setup-go/action.yml
- 'go/**'
- go.mod
diff --git a/.github/workflows/e2e_race.yml b/.github/workflows/e2e_race.yml
index 8879b1d4b6b..73fff9f1f55 100644
--- a/.github/workflows/e2e_race.yml
+++ b/.github/workflows/e2e_race.yml
@@ -61,6 +61,7 @@ jobs:
- 'bootstrap.sh'
- '.github/workflows/e2e_race.yml'
- '.github/actions/setup-mysql/action.yml'
+ - '.github/actions/tune-os/**'
- '.github/actions/setup-go/action.yml'
- name: Set up Go
diff --git a/.github/workflows/endtoend.yml b/.github/workflows/endtoend.yml
index 13169a27452..86c21af2615 100644
--- a/.github/workflows/endtoend.yml
+++ b/.github/workflows/endtoend.yml
@@ -61,6 +61,7 @@ jobs:
- 'bootstrap.sh'
- '.github/workflows/endtoend.yml'
- '.github/actions/setup-mysql/action.yml'
+ - '.github/actions/tune-os/**'
- '.github/actions/setup-go/action.yml'
- name: Set up Go
diff --git a/.github/workflows/unit_test.yml b/.github/workflows/unit_test.yml
index d059dad42cc..7708259d543 100644
--- a/.github/workflows/unit_test.yml
+++ b/.github/workflows/unit_test.yml
@@ -68,6 +68,7 @@ jobs:
- 'bootstrap.sh'
- '.github/workflows/unit_test.yml'
- '.github/actions/setup-mysql/action.yml'
+ - '.github/actions/tune-os/**'
- '.github/actions/setup-go/action.yml'
test:
diff --git a/.github/workflows/upgrade_downgrade_test_backups_e2e.yml b/.github/workflows/upgrade_downgrade_test_backups_e2e.yml
index 0400ecce1b8..dbcb0494376 100644
--- a/.github/workflows/upgrade_downgrade_test_backups_e2e.yml
+++ b/.github/workflows/upgrade_downgrade_test_backups_e2e.yml
@@ -74,6 +74,7 @@ jobs:
- 'bootstrap.sh'
- '.github/workflows/upgrade_downgrade_test_backups_e2e.yml'
- '.github/actions/setup-mysql/action.yml'
+ - '.github/actions/tune-os/**'
- '.github/actions/setup-go/action.yml'
upgrade_downgrade_test_e2e:
diff --git a/.github/workflows/upgrade_downgrade_test_backups_e2e_next_release.yml b/.github/workflows/upgrade_downgrade_test_backups_e2e_next_release.yml
index 5ec54deafe5..a1c0c17946d 100644
--- a/.github/workflows/upgrade_downgrade_test_backups_e2e_next_release.yml
+++ b/.github/workflows/upgrade_downgrade_test_backups_e2e_next_release.yml
@@ -75,6 +75,7 @@ jobs:
- 'bootstrap.sh'
- '.github/workflows/upgrade_downgrade_test_backups_e2e_next_release.yml'
- '.github/actions/setup-mysql/action.yml'
+ - '.github/actions/tune-os/**'
- '.github/actions/setup-go/action.yml'
upgrade_downgrade_test_e2e:
diff --git a/.github/workflows/upgrade_downgrade_test_backups_manual.yml b/.github/workflows/upgrade_downgrade_test_backups_manual.yml
index 84e4445a2d1..4894553fc0e 100644
--- a/.github/workflows/upgrade_downgrade_test_backups_manual.yml
+++ b/.github/workflows/upgrade_downgrade_test_backups_manual.yml
@@ -75,6 +75,7 @@ jobs:
- 'bootstrap.sh'
- '.github/workflows/upgrade_downgrade_test_backups_manual.yml'
- '.github/actions/setup-mysql/action.yml'
+ - '.github/actions/tune-os/**'
- '.github/actions/setup-go/action.yml'
- 'examples/**'
diff --git a/.github/workflows/upgrade_downgrade_test_backups_manual_next_release.yml b/.github/workflows/upgrade_downgrade_test_backups_manual_next_release.yml
index 809ef612305..af974891214 100644
--- a/.github/workflows/upgrade_downgrade_test_backups_manual_next_release.yml
+++ b/.github/workflows/upgrade_downgrade_test_backups_manual_next_release.yml
@@ -75,6 +75,7 @@ jobs:
- 'bootstrap.sh'
- '.github/workflows/upgrade_downgrade_test_backups_manual_next_release.yml'
- '.github/actions/setup-mysql/action.yml'
+ - '.github/actions/tune-os/**'
- '.github/actions/setup-go/action.yml'
- 'examples/**'
diff --git a/.github/workflows/upgrade_downgrade_test_onlineddl_flow.yml b/.github/workflows/upgrade_downgrade_test_onlineddl_flow.yml
index 2ee93d1978f..044c9eb5db1 100644
--- a/.github/workflows/upgrade_downgrade_test_onlineddl_flow.yml
+++ b/.github/workflows/upgrade_downgrade_test_onlineddl_flow.yml
@@ -89,6 +89,7 @@ jobs:
- 'bootstrap.sh'
- '.github/workflows/upgrade_downgrade_test_onlineddl_flow.yml'
- '.github/actions/setup-mysql/action.yml'
+ - '.github/actions/tune-os/**'
- '.github/actions/setup-go/action.yml'
upgrade_downgrade_test:
diff --git a/.github/workflows/upgrade_downgrade_test_query_serving_queries.yml b/.github/workflows/upgrade_downgrade_test_query_serving_queries.yml
index 0ac96339309..d1ac38dcd07 100644
--- a/.github/workflows/upgrade_downgrade_test_query_serving_queries.yml
+++ b/.github/workflows/upgrade_downgrade_test_query_serving_queries.yml
@@ -78,6 +78,7 @@ jobs:
- 'bootstrap.sh'
- '.github/workflows/upgrade_downgrade_test_query_serving_queries.yml'
- '.github/actions/setup-mysql/action.yml'
+ - '.github/actions/tune-os/**'
- '.github/actions/setup-go/action.yml'
upgrade_downgrade_test:
diff --git a/.github/workflows/upgrade_downgrade_test_query_serving_queries_2.yml b/.github/workflows/upgrade_downgrade_test_query_serving_queries_2.yml
index 4374f2ae337..6d22e14460e 100644
--- a/.github/workflows/upgrade_downgrade_test_query_serving_queries_2.yml
+++ b/.github/workflows/upgrade_downgrade_test_query_serving_queries_2.yml
@@ -77,6 +77,7 @@ jobs:
- 'bootstrap.sh'
- '.github/workflows/upgrade_downgrade_test_query_serving_queries_2.yml'
- '.github/actions/setup-mysql/action.yml'
+ - '.github/actions/tune-os/**'
- '.github/actions/setup-go/action.yml'
upgrade_downgrade_test:
diff --git a/.github/workflows/upgrade_downgrade_test_query_serving_queries_2_next_release.yml b/.github/workflows/upgrade_downgrade_test_query_serving_queries_2_next_release.yml
index 08cf7c86c88..8692696aec7 100644
--- a/.github/workflows/upgrade_downgrade_test_query_serving_queries_2_next_release.yml
+++ b/.github/workflows/upgrade_downgrade_test_query_serving_queries_2_next_release.yml
@@ -78,6 +78,7 @@ jobs:
- 'bootstrap.sh'
- '.github/workflows/upgrade_downgrade_test_query_serving_queries_2_next_release.yml'
- '.github/actions/setup-mysql/action.yml'
+ - '.github/actions/tune-os/**'
- '.github/actions/setup-go/action.yml'
upgrade_downgrade_test:
diff --git a/.github/workflows/upgrade_downgrade_test_query_serving_queries_next_release.yml b/.github/workflows/upgrade_downgrade_test_query_serving_queries_next_release.yml
index 5caacc386ed..9fce6e9bf9a 100644
--- a/.github/workflows/upgrade_downgrade_test_query_serving_queries_next_release.yml
+++ b/.github/workflows/upgrade_downgrade_test_query_serving_queries_next_release.yml
@@ -78,6 +78,7 @@ jobs:
- 'bootstrap.sh'
- '.github/workflows/upgrade_downgrade_test_query_serving_queries_next_release.yml'
- '.github/actions/setup-mysql/action.yml'
+ - '.github/actions/tune-os/**'
- '.github/actions/setup-go/action.yml'
upgrade_downgrade_test:
diff --git a/.github/workflows/upgrade_downgrade_test_query_serving_schema.yml b/.github/workflows/upgrade_downgrade_test_query_serving_schema.yml
index 32aa834f0cf..384e4d3f9c2 100644
--- a/.github/workflows/upgrade_downgrade_test_query_serving_schema.yml
+++ b/.github/workflows/upgrade_downgrade_test_query_serving_schema.yml
@@ -78,6 +78,7 @@ jobs:
- 'bootstrap.sh'
- '.github/workflows/upgrade_downgrade_test_query_serving_schema.yml'
- '.github/actions/setup-mysql/action.yml'
+ - '.github/actions/tune-os/**'
- '.github/actions/setup-go/action.yml'
upgrade_downgrade_test:
diff --git a/.github/workflows/upgrade_downgrade_test_query_serving_schema_next_release.yml b/.github/workflows/upgrade_downgrade_test_query_serving_schema_next_release.yml
index 0b2588f9659..ab2e2ccfce4 100644
--- a/.github/workflows/upgrade_downgrade_test_query_serving_schema_next_release.yml
+++ b/.github/workflows/upgrade_downgrade_test_query_serving_schema_next_release.yml
@@ -78,6 +78,7 @@ jobs:
- 'bootstrap.sh'
- '.github/workflows/upgrade_downgrade_test_query_serving_schema_next_release.yml'
- '.github/actions/setup-mysql/action.yml'
+ - '.github/actions/tune-os/**'
- '.github/actions/setup-go/action.yml'
upgrade_downgrade_test:
diff --git a/.github/workflows/upgrade_downgrade_test_reparent_new_vtctl.yml b/.github/workflows/upgrade_downgrade_test_reparent_new_vtctl.yml
index 6ee8b7355df..848ad065533 100644
--- a/.github/workflows/upgrade_downgrade_test_reparent_new_vtctl.yml
+++ b/.github/workflows/upgrade_downgrade_test_reparent_new_vtctl.yml
@@ -78,6 +78,7 @@ jobs:
- 'bootstrap.sh'
- '.github/workflows/upgrade_downgrade_test_reparent_new_vtctl.yml'
- '.github/actions/setup-mysql/action.yml'
+ - '.github/actions/tune-os/**'
- '.github/actions/setup-go/action.yml'
upgrade_downgrade_test:
diff --git a/.github/workflows/upgrade_downgrade_test_reparent_new_vttablet.yml b/.github/workflows/upgrade_downgrade_test_reparent_new_vttablet.yml
index 42cb577e379..3f0f2bcf4a3 100644
--- a/.github/workflows/upgrade_downgrade_test_reparent_new_vttablet.yml
+++ b/.github/workflows/upgrade_downgrade_test_reparent_new_vttablet.yml
@@ -78,6 +78,7 @@ jobs:
- 'bootstrap.sh'
- '.github/workflows/upgrade_downgrade_test_reparent_new_vttablet.yml'
- '.github/actions/setup-mysql/action.yml'
+ - '.github/actions/tune-os/**'
- '.github/actions/setup-go/action.yml'
upgrade_downgrade_test:
diff --git a/.github/workflows/upgrade_downgrade_test_reparent_old_vtctl.yml b/.github/workflows/upgrade_downgrade_test_reparent_old_vtctl.yml
index c82654873ad..a9c1b730616 100644
--- a/.github/workflows/upgrade_downgrade_test_reparent_old_vtctl.yml
+++ b/.github/workflows/upgrade_downgrade_test_reparent_old_vtctl.yml
@@ -78,6 +78,7 @@ jobs:
- 'bootstrap.sh'
- '.github/workflows/upgrade_downgrade_test_reparent_old_vtctl.yml'
- '.github/actions/setup-mysql/action.yml'
+ - '.github/actions/tune-os/**'
- '.github/actions/setup-go/action.yml'
upgrade_downgrade_test:
diff --git a/.github/workflows/upgrade_downgrade_test_reparent_old_vttablet.yml b/.github/workflows/upgrade_downgrade_test_reparent_old_vttablet.yml
index 28fd1f3d708..821917afdd3 100644
--- a/.github/workflows/upgrade_downgrade_test_reparent_old_vttablet.yml
+++ b/.github/workflows/upgrade_downgrade_test_reparent_old_vttablet.yml
@@ -78,6 +78,7 @@ jobs:
- 'bootstrap.sh'
- '.github/workflows/upgrade_downgrade_test_reparent_old_vttablet.yml'
- '.github/actions/setup-mysql/action.yml'
+ - '.github/actions/tune-os/**'
- '.github/actions/setup-go/action.yml'
upgrade_downgrade_test:
diff --git a/.github/workflows/vitess_tester_vtgate.yml b/.github/workflows/vitess_tester_vtgate.yml
index da691c7c0fe..74f320c5458 100644
--- a/.github/workflows/vitess_tester_vtgate.yml
+++ b/.github/workflows/vitess_tester_vtgate.yml
@@ -70,6 +70,7 @@ jobs:
- 'bootstrap.sh'
- '.github/workflows/vitess_tester_vtgate.yml'
- '.github/actions/setup-mysql/action.yml'
+ - '.github/actions/tune-os/**'
- '.github/actions/setup-go/action.yml'
- name: Set up Go
diff --git a/.github/workflows/vtop_example.yml b/.github/workflows/vtop_example.yml
index 1ef61530a39..0fb922eafef 100644
--- a/.github/workflows/vtop_example.yml
+++ b/.github/workflows/vtop_example.yml
@@ -63,6 +63,7 @@ jobs:
- 'test/**'
- '.github/workflows/vtop_example.yml'
- '.github/actions/setup-mysql/action.yml'
+ - '.github/actions/tune-os/**'
- '.github/actions/setup-go/action.yml'
build: