From 4edb4cf575d277e6bfb659811ecab84d74576b6b Mon Sep 17 00:00:00 2001 From: Tobias Grieger Date: Mon, 10 Oct 2022 10:46:14 +0200 Subject: [PATCH] go.mod: bump raft ``` go get go.etcd.io/etcd/raft/v3@d19116e6ee66e52a5fd8cce2e10f9422fb80e42f go: downloading go.etcd.io/etcd/raft/v3 v3.6.0-alpha.0.0.20221009201006-d19116e6ee66 go: module github.com/golang/protobuf is deprecated: Use the "google.golang.org/protobuf" module instead. go: upgraded go.etcd.io/etcd/api/v3 v3.5.0 => v3.6.0-alpha.0 go: upgraded go.etcd.io/etcd/raft/v3 v3.0.0-20210320072418-e51c697ec6e8 => v3.6.0-alpha.0.0.20221009201006-d19116e6ee66 ``` This picks up - https://github.com/etcd-io/etcd/pull/14413 - https://github.com/etcd-io/etcd/pull/14538 Closes #87264. Release note: None --- DEPS.bzl | 34 ++++++------ build/bazelutil/distdir_files.bzl | 7 ++- build/patches/io_etcd_go_etcd_api_v3.patch | 48 +++++++++++++++++ build/vendor_rebuild.sh | 5 ++ docs/generated/http/BUILD.bazel | 1 + go.mod | 3 +- go.sum | 16 ++---- pkg/cmd/mirror/mirror.go | 3 ++ pkg/cmd/protoc-gen-gogoroach/main.go | 1 + pkg/kv/kvclient/kvcoord/integration_test.go | 2 +- pkg/kv/kvserver/client_migration_test.go | 2 +- pkg/kv/kvserver/client_mvcc_gc_test.go | 5 +- pkg/kv/kvserver/client_raft_test.go | 19 ++++--- .../client_replica_circuit_breaker_test.go | 4 +- pkg/kv/kvserver/client_replica_test.go | 9 +++- pkg/kv/kvserver/client_split_burst_test.go | 2 +- pkg/kv/kvserver/client_split_test.go | 28 ++++++---- pkg/kv/kvserver/client_status_test.go | 7 ++- pkg/kv/kvserver/consistency_queue_test.go | 2 +- .../loqrecovery/collect_raft_log_test.go | 4 +- pkg/kv/kvserver/replica_application_result.go | 1 + .../replica_application_state_machine.go | 2 +- .../replica_application_state_machine_test.go | 45 +++++++++++----- .../replica_closedts_internal_test.go | 21 ++++++-- pkg/kv/kvserver/replica_closedts_test.go | 2 +- pkg/kv/kvserver/replica_follower_read_test.go | 1 + pkg/kv/kvserver/replica_probe_test.go | 2 +- pkg/kv/kvserver/replica_raft.go | 6 ++- pkg/kv/kvserver/replica_rankings_test.go | 6 ++- pkg/kv/kvserver/replica_test.go | 53 ++++++++++++------- pkg/kv/kvserver/split_queue_test.go | 17 +++++- pkg/kv/kvserver/testing_knobs.go | 26 +++++++-- vendor | 2 +- 33 files changed, 272 insertions(+), 114 deletions(-) create mode 100644 build/patches/io_etcd_go_etcd_api_v3.patch diff --git a/DEPS.bzl b/DEPS.bzl index 1ab0a0dea06d..d33482c2648b 100644 --- a/DEPS.bzl +++ b/DEPS.bzl @@ -8804,20 +8804,24 @@ def go_deps(): name = "io_etcd_go_etcd_api_v3", build_file_proto_mode = "disable_global", importpath = "go.etcd.io/etcd/api/v3", - sha256 = "8754587bf6d4b1bc889d519355ea8899e093d8550e0d98730f8570d608f998f9", - strip_prefix = "go.etcd.io/etcd/api/v3@v3.5.0", + patch_args = ["-p1"], + patches = [ + "@com_github_cockroachdb_cockroach//build/patches:io_etcd_go_etcd_api_v3.patch", + ], + sha256 = "7664ddbf05148db36ec74d8c5e72ba65db25cd594ea38a471077298c398a9ea7", + strip_prefix = "go.etcd.io/etcd/api/v3@v3.6.0-alpha.0", urls = [ - "https://storage.googleapis.com/cockroach-godeps/gomod/go.etcd.io/etcd/api/v3/io_etcd_go_etcd_api_v3-v3.5.0.zip", + "https://storage.googleapis.com/cockroach-godeps/gomod/go.etcd.io/etcd/api/v3/io_etcd_go_etcd_api_v3-v3.6.0-alpha.0.zip", ], ) go_repository( name = "io_etcd_go_etcd_client_pkg_v3", build_file_proto_mode = "disable_global", importpath = "go.etcd.io/etcd/client/pkg/v3", - sha256 = "c0ca209767c5734c6ed023888ba5be02aab5bd3c4d018999467f2bfa8bf65ee3", - strip_prefix = "go.etcd.io/etcd/client/pkg/v3@v3.5.0", + sha256 = "abfb4724be4ea8b042737efbdd1bc11ba4d3c4c8dd8e749c7791adf8d16ef062", + strip_prefix = "go.etcd.io/etcd/client/pkg/v3@v3.6.0-alpha.0", urls = [ - "https://storage.googleapis.com/cockroach-godeps/gomod/go.etcd.io/etcd/client/pkg/v3/io_etcd_go_etcd_client_pkg_v3-v3.5.0.zip", + "https://storage.googleapis.com/cockroach-godeps/gomod/go.etcd.io/etcd/client/pkg/v3/io_etcd_go_etcd_client_pkg_v3-v3.6.0-alpha.0.zip", ], ) go_repository( @@ -8830,16 +8834,6 @@ def go_deps(): "https://storage.googleapis.com/cockroach-godeps/gomod/go.etcd.io/etcd/client/v2/io_etcd_go_etcd_client_v2-v2.305.0.zip", ], ) - go_repository( - name = "io_etcd_go_etcd_pkg_v3", - build_file_proto_mode = "disable_global", - importpath = "go.etcd.io/etcd/pkg/v3", - sha256 = "1700dfed48becf82ccfe6865fe59daac2121d48f60b7c4bf090f0ff2320d33d4", - strip_prefix = "go.etcd.io/etcd/pkg/v3@v3.0.0-20201109164711-01844fd28560", - urls = [ - "https://storage.googleapis.com/cockroach-godeps/gomod/go.etcd.io/etcd/pkg/v3/io_etcd_go_etcd_pkg_v3-v3.0.0-20201109164711-01844fd28560.zip", - ], - ) go_repository( name = "io_etcd_go_etcd_raft_v3", build_directives = [ @@ -8848,13 +8842,15 @@ def go_deps(): "gazelle:go_proto_compilers @com_github_cockroachdb_cockroach//pkg/cmd/protoc-gen-gogoroach:protoc-gen-gogoroach_compiler", "gazelle:go_grpc_compilers @com_github_cockroachdb_cockroach//pkg/cmd/protoc-gen-gogoroach:protoc-gen-gogoroach_grpc_compiler", "gazelle:proto_import_prefix etcd/raft/v3", + "gazelle:resolve proto proto etcd/api/versionpb/version.proto @io_etcd_go_etcd_api_v3//versionpb:versionpb_proto", + "gazelle:resolve proto go etcd/api/versionpb/version.proto @io_etcd_go_etcd_api_v3//versionpb:versionpb", ], build_file_proto_mode = "default", importpath = "go.etcd.io/etcd/raft/v3", - sha256 = "62faedd81e10061a4e0d7476865a62b84121ea462514afeaa1b9d66cc53b5a4b", - strip_prefix = "go.etcd.io/etcd/raft/v3@v3.0.0-20210320072418-e51c697ec6e8", + sha256 = "dfe1caafc6ba5b17d52218c1b393a6829195c3c06d38c9e7492301433f6b6bd7", + strip_prefix = "go.etcd.io/etcd/raft/v3@v3.6.0-alpha.0.0.20221009201006-d19116e6ee66", urls = [ - "https://storage.googleapis.com/cockroach-godeps/gomod/go.etcd.io/etcd/raft/v3/io_etcd_go_etcd_raft_v3-v3.0.0-20210320072418-e51c697ec6e8.zip", + "https://storage.googleapis.com/cockroach-godeps/gomod/go.etcd.io/etcd/raft/v3/io_etcd_go_etcd_raft_v3-v3.6.0-alpha.0.0.20221009201006-d19116e6ee66.zip", ], ) go_repository( diff --git a/build/bazelutil/distdir_files.bzl b/build/bazelutil/distdir_files.bzl index dcafff56ca89..09053b21272e 100644 --- a/build/bazelutil/distdir_files.bzl +++ b/build/bazelutil/distdir_files.bzl @@ -843,12 +843,11 @@ DISTDIR_FILES = { "https://storage.googleapis.com/cockroach-godeps/gomod/github.com/zenazn/goji/com_github_zenazn_goji-v0.9.0.zip": "0807a255d9d715d18427a6eedd8e4f5a22670b09e5f45fddd229c1ae38da25a9", "https://storage.googleapis.com/cockroach-godeps/gomod/github.com/ziutek/mymysql/com_github_ziutek_mymysql-v1.5.4.zip": "1ea104186e0990a3d97a1e67fcd31177849c975de4abd9399270ab0a04c025de", "https://storage.googleapis.com/cockroach-godeps/gomod/go.etcd.io/bbolt/io_etcd_go_bbolt-v1.3.5.zip": "cbb488f86631df05edb2aa3e2c25e0d5994d46a118fc5f2150932fa6ed469cff", - "https://storage.googleapis.com/cockroach-godeps/gomod/go.etcd.io/etcd/api/v3/io_etcd_go_etcd_api_v3-v3.5.0.zip": "8754587bf6d4b1bc889d519355ea8899e093d8550e0d98730f8570d608f998f9", - "https://storage.googleapis.com/cockroach-godeps/gomod/go.etcd.io/etcd/client/pkg/v3/io_etcd_go_etcd_client_pkg_v3-v3.5.0.zip": "c0ca209767c5734c6ed023888ba5be02aab5bd3c4d018999467f2bfa8bf65ee3", + "https://storage.googleapis.com/cockroach-godeps/gomod/go.etcd.io/etcd/api/v3/io_etcd_go_etcd_api_v3-v3.6.0-alpha.0.zip": "7664ddbf05148db36ec74d8c5e72ba65db25cd594ea38a471077298c398a9ea7", + "https://storage.googleapis.com/cockroach-godeps/gomod/go.etcd.io/etcd/client/pkg/v3/io_etcd_go_etcd_client_pkg_v3-v3.6.0-alpha.0.zip": "abfb4724be4ea8b042737efbdd1bc11ba4d3c4c8dd8e749c7791adf8d16ef062", "https://storage.googleapis.com/cockroach-godeps/gomod/go.etcd.io/etcd/client/v2/io_etcd_go_etcd_client_v2-v2.305.0.zip": "91fcb507fe8c193844b56bfb6c8741aaeb6ffa11ee9043de2af0f141173679f3", "https://storage.googleapis.com/cockroach-godeps/gomod/go.etcd.io/etcd/io_etcd_go_etcd-v0.5.0-alpha.5.0.20200910180754-dd1b699fc489.zip": "d982ee501979b41b68625693bad77d15e4ae79ab9d0eae5f6028205f96a74e49", - "https://storage.googleapis.com/cockroach-godeps/gomod/go.etcd.io/etcd/pkg/v3/io_etcd_go_etcd_pkg_v3-v3.0.0-20201109164711-01844fd28560.zip": "1700dfed48becf82ccfe6865fe59daac2121d48f60b7c4bf090f0ff2320d33d4", - "https://storage.googleapis.com/cockroach-godeps/gomod/go.etcd.io/etcd/raft/v3/io_etcd_go_etcd_raft_v3-v3.0.0-20210320072418-e51c697ec6e8.zip": "62faedd81e10061a4e0d7476865a62b84121ea462514afeaa1b9d66cc53b5a4b", + "https://storage.googleapis.com/cockroach-godeps/gomod/go.etcd.io/etcd/raft/v3/io_etcd_go_etcd_raft_v3-v3.6.0-alpha.0.0.20221009201006-d19116e6ee66.zip": "dfe1caafc6ba5b17d52218c1b393a6829195c3c06d38c9e7492301433f6b6bd7", "https://storage.googleapis.com/cockroach-godeps/gomod/go.mongodb.org/mongo-driver/org_mongodb_go_mongo_driver-v1.5.1.zip": "446cff132e82c64af7ffcf48e268eb16ec81f694914aa6baecb06cbbae1be0d7", "https://storage.googleapis.com/cockroach-godeps/gomod/go.mozilla.org/pkcs7/org_mozilla_go_pkcs7-v0.0.0-20200128120323-432b2356ecb1.zip": "3c4c1667907ff3127e371d44696326bad9e965216d4257917ae28e8b82a9e08d", "https://storage.googleapis.com/cockroach-godeps/gomod/go.opencensus.io/io_opencensus_go-v0.23.0.zip": "81c78beb84872084d6d5ddc0a0bffc47294412898472c891a29cfcb66f3fa2d8", diff --git a/build/patches/io_etcd_go_etcd_api_v3.patch b/build/patches/io_etcd_go_etcd_api_v3.patch new file mode 100644 index 000000000000..8f6f34581739 --- /dev/null +++ b/build/patches/io_etcd_go_etcd_api_v3.patch @@ -0,0 +1,48 @@ +diff -urN a/versionpb/BUILD.bazel b/versionpb/BUILD.bazel +--- a/versionpb/BUILD.bazel 1970-01-01 00:00:00.000000000 +0000 ++++ b/versionpb/BUILD.bazel 2000-01-01 00:00:00.000000000 -0000 +@@ -1,4 +1,16 @@ + load("@io_bazel_rules_go//go:def.bzl", "go_library") ++load("@rules_proto//proto:defs.bzl", "proto_library") ++ ++proto_library( ++ name = "versionpb_proto", ++ visibility = ["//visibility:public"], ++ deps = [ ++ "@com_github_gogo_protobuf//gogoproto:gogo_proto", ++ "@com_google_protobuf//:descriptor_proto", ++ ], ++ import_prefix = "etcd/api", ++ srcs = ["@io_etcd_go_etcd_api_v3//versionpb:version.proto"], ++) + + go_library( + name = "versionpb", +diff -urN a/versionpb/version.proto b/versionpb/version.proto +--- a/versionpb/version.proto 1970-01-01 00:00:00.000000000 +0000 ++++ b/versionpb/version.proto 2000-01-01 00:00:00.000000000 -0000 +@@ -9,20 +9,20 @@ + + // Indicates etcd version that introduced the message, used to determine minimal etcd version required to interpret wal that includes this message. + extend google.protobuf.MessageOptions { +- optional string etcd_version_msg = 50000; ++ string etcd_version_msg = 50000; + } + + // Indicates etcd version that introduced the field, used to determine minimal etcd version required to interpret wal that sets this field. + extend google.protobuf.FieldOptions { +- optional string etcd_version_field = 50001; ++ string etcd_version_field = 50001; + } + + // Indicates etcd version that introduced the enum, used to determine minimal etcd version required to interpret wal that uses this enum. + extend google.protobuf.EnumOptions { +- optional string etcd_version_enum = 50002; ++ string etcd_version_enum = 50002; + } + + // Indicates etcd version that introduced the enum value, used to determine minimal etcd version required to interpret wal that sets this enum value. + extend google.protobuf.EnumValueOptions { +- optional string etcd_version_enum_value = 50003; ++ string etcd_version_enum_value = 50003; + } diff --git a/build/vendor_rebuild.sh b/build/vendor_rebuild.sh index 4915f761874d..1b31024b9b3e 100755 --- a/build/vendor_rebuild.sh +++ b/build/vendor_rebuild.sh @@ -16,5 +16,10 @@ function restore() { mv vendor $TMP_VENDOR_DIR go mod vendor modvendor -copy="**/*.c **/*.h **/*.proto" -include 'github.com/grpc-ecosystem/grpc-gateway/third_party/googleapis/google/api,github.com/grpc-ecosystem/grpc-gateway/third_party/googleapis/google/rpc,github.com/prometheus/client_model' + +# See https://github.com/cockroachdb/cockroach/issues/89640. +sed 's~etcd/api/versionpb/version.proto~etcd/api/v3/versionpb/version.proto~' vendor/go.etcd.io/etcd/raft/v3/raftpb/raft.proto > vendor/go.etcd.io/etcd/raft/v3/raftpb/raft.proto.sed +mv vendor/go.etcd.io/etcd/raft/v3/raftpb/raft.proto{.sed,} + mv $TMP_VENDOR_DIR/.git vendor/.git rm -rf $TMP_VENDOR_DIR diff --git a/docs/generated/http/BUILD.bazel b/docs/generated/http/BUILD.bazel index 8f7c570c246d..a1b9ec8f00df 100644 --- a/docs/generated/http/BUILD.bazel +++ b/docs/generated/http/BUILD.bazel @@ -48,6 +48,7 @@ genrule( "@com_google_protobuf//:timestamp_proto", "@go_googleapis//google/api:annotations_proto", "@io_etcd_go_etcd_raft_v3//raftpb:raftpb_proto", + "@io_etcd_go_etcd_api_v3//versionpb:versionpb_proto", ], outs = [ "full.md", diff --git a/go.mod b/go.mod index 76a0ad3bd38a..6bb389500336 100644 --- a/go.mod +++ b/go.mod @@ -153,7 +153,7 @@ require ( github.com/xdg-go/scram v1.0.2 github.com/xdg-go/stringprep v1.0.2 github.com/zabawaba99/go-gitignore v0.0.0-20200117185801-39e6bddfb292 - go.etcd.io/etcd/raft/v3 v3.0.0-20210320072418-e51c697ec6e8 + go.etcd.io/etcd/raft/v3 v3.6.0-alpha.0.0.20221009201006-d19116e6ee66 go.opentelemetry.io/otel v1.0.0-RC3 go.opentelemetry.io/otel/exporters/jaeger v1.0.0-RC3 go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc v1.0.0-RC3 @@ -330,6 +330,7 @@ require ( github.com/twpayne/go-kml v1.5.2 // indirect github.com/urfave/cli/v2 v2.3.0 // indirect github.com/yusufpapurcu/wmi v1.2.2 // indirect + go.etcd.io/etcd/api/v3 v3.6.0-alpha.0 // indirect go.mongodb.org/mongo-driver v1.5.1 // indirect go.opencensus.io v0.23.0 // indirect go.opentelemetry.io/proto/otlp v0.9.0 // indirect diff --git a/go.sum b/go.sum index 901d39119752..b94ec3e0a4ca 100644 --- a/go.sum +++ b/go.sum @@ -397,8 +397,6 @@ github.com/cenkalti/backoff/v4 v4.1.2/go.mod h1:scbssz8iZGpm3xbr14ovlUdkxfGXNInq github.com/cenkalti/backoff/v4 v4.1.3 h1:cFAlzYUlVYDysBEH2T5hyJZMh3+5+WCBvSnK6Q8UtC4= github.com/cenkalti/backoff/v4 v4.1.3/go.mod h1:scbssz8iZGpm3xbr14ovlUdkxfGXNInqkPWOWmG2CLw= github.com/census-instrumentation/opencensus-proto v0.2.1/go.mod h1:f6KPmirojxKA12rnyqOA5BBL4O983OfeGPqjHWSTneU= -github.com/certifi/gocertifi v0.0.0-20191021191039-0944d244cd40/go.mod h1:sGbDF6GwGcLpkNXPUTkMRoywsNa/ol15pxFe6ERfguA= -github.com/certifi/gocertifi v0.0.0-20200922220541-2c3bb06c6054/go.mod h1:sGbDF6GwGcLpkNXPUTkMRoywsNa/ol15pxFe6ERfguA= github.com/cespare/xxhash v1.1.0/go.mod h1:XrSqR1VqqWfGrhpAt58auRo0WTKS1nRRg3ghfAqPWnc= github.com/cespare/xxhash/v2 v2.1.0/go.mod h1:dgIUBU3pDso/gPgZ1osOZ0iQf77oPR28Tjxl5dIMyVM= github.com/cespare/xxhash/v2 v2.1.1/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs= @@ -444,12 +442,10 @@ github.com/cockroachdb/cockroach-go/v2 v2.2.6/go.mod h1:q4ZRgO6CQpwNyEvEwSxwNrOS github.com/cockroachdb/crlfmt v0.0.0-20210128092314-b3eff0b87c79 h1:4s0GWs4NXFK4JEeUc0Q1pRbL4oMbqh1DK70qeQ+viOA= github.com/cockroachdb/crlfmt v0.0.0-20210128092314-b3eff0b87c79/go.mod h1:EOI6rrXIdP+4EXwM8837kmmb6IJesf7k7W6bUu8BDOg= github.com/cockroachdb/datadriven v0.0.0-20190809214429-80d97fb3cbaa/go.mod h1:zn76sxSg3SzpJ0PPJaLDCu+Bu0Lg3sKTORVIj19EIF8= -github.com/cockroachdb/datadriven v0.0.0-20200714090401-bf6692d28da5/go.mod h1:h6jFvWxBdQXxjopDMZyH2UVceIRfR84bdzbkoKrsWNo= github.com/cockroachdb/datadriven v1.0.1-0.20211007161720-b558070c3be0/go.mod h1:5Ib8Meh+jk1RlHIXej6Pzevx/NLlNvQB9pmSBZErGA4= github.com/cockroachdb/datadriven v1.0.1-0.20220214170620-9913f5bc19b7/go.mod h1:hi0MtSY3AYDQNDi83kDkMH5/yqM/CsIrsOITkSoH7KI= github.com/cockroachdb/datadriven v1.0.1 h1:eb8u+AQ1BnWwsINwqh9Ts2bdIZKdP87sUvT0k3wde7s= github.com/cockroachdb/datadriven v1.0.1/go.mod h1:ayXb8FgaXxgGObAHeeLXa1bPh52ZpuWSY560iFfB3jI= -github.com/cockroachdb/errors v1.2.4/go.mod h1:rQD95gz6FARkaKkQXUksEje/d9a6wBJoCr5oaCLELYA= github.com/cockroachdb/errors v1.6.1/go.mod h1:tm6FTP5G81vwJ5lC0SizQo374JNCOPrHyXGitRJoDqM= github.com/cockroachdb/errors v1.8.8/go.mod h1:z6VnEL3hZ/2ONZEvG7S5Ym0bU2AqPcEKnIiA1wbsSu0= github.com/cockroachdb/errors v1.9.0 h1:B48dYem5SlAY7iU8AKsgedb4gH6mo+bDkbtLIvM/a88= @@ -757,7 +753,6 @@ github.com/fullsailor/pkcs7 v0.0.0-20190404230743-d7302db945fa/go.mod h1:KnogPXt github.com/garyburd/redigo v0.0.0-20150301180006-535138d7bcd7/go.mod h1:NR3MbYisc3/PwhQ00EMzDiPmrwpPxAn5GI05/YaO1SY= github.com/gavv/httpexpect v2.0.0+incompatible/go.mod h1:x+9tiU1YnrOvnB725RkpoLv1M62hOWzwo5OXotisrKc= github.com/getkin/kin-openapi v0.53.0/go.mod h1:7Yn5whZr5kJi6t+kShccXS8ae1APpYTW6yheSwk8Yi4= -github.com/getsentry/raven-go v0.2.0/go.mod h1:KungGk8q33+aIAZUIVWZDr2OfAEBsO49PX4NzFV5kcQ= github.com/getsentry/sentry-go v0.12.0 h1:era7g0re5iY13bHSdN/xMkyV+5zZppjRVQhZrXCaEIk= github.com/getsentry/sentry-go v0.12.0/go.mod h1:NSap0JBYWzHND8oMbyi0+XZhUalc1TBdRL1M71JZW2c= github.com/ghemawat/stream v0.0.0-20171120220530-696b145b53b9 h1:r5GgOLGbza2wVHRzK7aAj6lWZjfbAwiu/RDCVOKjRyM= @@ -2232,12 +2227,13 @@ go.etcd.io/etcd v0.0.0-20191023171146-3cf2f69b5738/go.mod h1:dnLIgRNXwCJa5e+c6mI go.etcd.io/etcd v0.5.0-alpha.5.0.20200910180754-dd1b699fc489 h1:1JFLBqwIgdyHN1ZtgjTBwO+blA6gVOmZurpiMEsETKo= go.etcd.io/etcd v0.5.0-alpha.5.0.20200910180754-dd1b699fc489/go.mod h1:yVHk9ub3CSBatqGNg7GRmsnfLWtoW60w4eDYfh7vHDg= go.etcd.io/etcd/api/v3 v3.5.0/go.mod h1:cbVKeC6lCfl7j/8jBhAK6aIYO9XOjdptoxU/nLQcPvs= +go.etcd.io/etcd/api/v3 v3.6.0-alpha.0 h1:se+XckWlVTTfwjZSsAZJ2zGPzmIMq3j7fKBCmHoB9UA= +go.etcd.io/etcd/api/v3 v3.6.0-alpha.0/go.mod h1:z13pg39zewDLZeXIKeM0xELOeFKcqjLocfwl5M820+w= go.etcd.io/etcd/client/pkg/v3 v3.5.0/go.mod h1:IJHfcCEKxYu1Os13ZdwCwIUTUVGYTSAM3YSwc9/Ac1g= +go.etcd.io/etcd/client/pkg/v3 v3.6.0-alpha.0 h1:2UyRzFWbZZzgu/xzxoRukgixvafiJtGyxO+3IKUyJ6c= go.etcd.io/etcd/client/v2 v2.305.0/go.mod h1:h9puh54ZTgAKtEbut2oe9P4L/oqKCVB6xsXlzd7alYQ= -go.etcd.io/etcd/pkg/v3 v3.0.0-20201109164711-01844fd28560 h1:U/PIBuOTa8JXLPKF81Xh7xhIjA0jbpyqFWUPIiT4Ilc= -go.etcd.io/etcd/pkg/v3 v3.0.0-20201109164711-01844fd28560/go.mod h1:0HiXlybqS+XtfgnNkiEZWwGXYYEhWsWL8fDVdZzb7is= -go.etcd.io/etcd/raft/v3 v3.0.0-20210320072418-e51c697ec6e8 h1:aRP8pJvbOsFy8SaZ0tcWeV4RYTlp8ZIWS49usJjO4Ac= -go.etcd.io/etcd/raft/v3 v3.0.0-20210320072418-e51c697ec6e8/go.mod h1:i+srOieUHQl4y/EwlGOpuYtoKG7nb2uhtA/hrFsFTsc= +go.etcd.io/etcd/raft/v3 v3.6.0-alpha.0.0.20221009201006-d19116e6ee66 h1:jvWNsQyNPwM6OQiN7Z+d7SOxok/+69GEnpas1RFc/r0= +go.etcd.io/etcd/raft/v3 v3.6.0-alpha.0.0.20221009201006-d19116e6ee66/go.mod h1:tW2/2laPtjMV+ITtHu87FnnnxeGn62sjDTlwB1+Gg08= go.mongodb.org/mongo-driver v1.0.3/go.mod h1:u7ryQJ+DOzQmeO7zB6MHyr8jkEQvC8vH7qLUO4lqsUM= go.mongodb.org/mongo-driver v1.1.1/go.mod h1:u7ryQJ+DOzQmeO7zB6MHyr8jkEQvC8vH7qLUO4lqsUM= go.mongodb.org/mongo-driver v1.1.2/go.mod h1:u7ryQJ+DOzQmeO7zB6MHyr8jkEQvC8vH7qLUO4lqsUM= @@ -2303,7 +2299,6 @@ go.uber.org/zap v1.10.0/go.mod h1:vwi/ZaCAaUcBkycHslxD9B2zi4UTXhF60s6SWpuDF0Q= go.uber.org/zap v1.13.0/go.mod h1:zwrFLgMcdUuIBviXEYEH1YKNaOBnKXsx2IPda5bBwHM= go.uber.org/zap v1.14.0/go.mod h1:zwrFLgMcdUuIBviXEYEH1YKNaOBnKXsx2IPda5bBwHM= go.uber.org/zap v1.14.1/go.mod h1:Mb2vm2krFEG5DV0W9qcHBYFtp/Wku1cvYaqPsS/WYfc= -go.uber.org/zap v1.16.0/go.mod h1:MA8QOfq0BHJwdXa996Y4dYkAqRKB8/1K1QMMZVaNZjQ= go.uber.org/zap v1.17.0/go.mod h1:MXVU+bhUf/A7Xi2HNOnopQOrmycQ5Ih87HtOu4q5SSo= go.uber.org/zap v1.19.0 h1:mZQZefskPPCMIBCSEH0v2/iUqqLrYtaeqwD6FUGUnFE= go.uber.org/zap v1.19.0/go.mod h1:xg/QME4nWcxGxrpdeYfq7UvYrLh66cuVKdrbD1XF/NI= @@ -2626,7 +2621,6 @@ golang.org/x/sys v0.0.0-20200909081042-eff7692f9009/go.mod h1:h1NjWce9XRLGQEsW7w golang.org/x/sys v0.0.0-20200916030750-2334cc1a136f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200922070232-aee5d888a860/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200930185726-fdedc70b468f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20201009025420-dfb3f7c4e634/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20201112073958-5cba982894dd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20201117170446-d9b008d0a637/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= diff --git a/pkg/cmd/mirror/mirror.go b/pkg/cmd/mirror/mirror.go index 9ff08641f3af..49aaf85e52cb 100644 --- a/pkg/cmd/mirror/mirror.go +++ b/pkg/cmd/mirror/mirror.go @@ -286,6 +286,9 @@ func dumpBuildDirectivesForRepo(repoName string) { directives = append(directives, protoDirectives...) directives = append(directives, "gazelle:proto_import_prefix etcd/raft/v3") + directives = append(directives, + "gazelle:resolve proto proto etcd/api/versionpb/version.proto @io_etcd_go_etcd_api_v3//versionpb:versionpb_proto", + "gazelle:resolve proto go etcd/api/versionpb/version.proto @io_etcd_go_etcd_api_v3//versionpb:versionpb") } else if repoName == "io_opentelemetry_go_proto_otlp" { directives = append(directives, diff --git a/pkg/cmd/protoc-gen-gogoroach/main.go b/pkg/cmd/protoc-gen-gogoroach/main.go index 4fc5515d43d4..54dbe1fb4cc0 100644 --- a/pkg/cmd/protoc-gen-gogoroach/main.go +++ b/pkg/cmd/protoc-gen-gogoroach/main.go @@ -28,6 +28,7 @@ func fixImports(s string) string { lines := strings.Split(s, "\n") var builder strings.Builder for _, line := range lines { + line = strings.ReplaceAll(line, "\"etcd/api/versionpb\"", "\"go.etcd.io/etcd/api/v3/versionpb\"") if strings.Contains(line, "import _ ") || strings.Contains(line, "import fmt \"github.com/cockroachdb/cockroach/pkg/fmt\"") || strings.Contains(line, "import math \"github.com/cockroachdb/cockroach/pkg/math\"") { diff --git a/pkg/kv/kvclient/kvcoord/integration_test.go b/pkg/kv/kvclient/kvcoord/integration_test.go index 38007282a06c..ba337da9a25f 100644 --- a/pkg/kv/kvclient/kvcoord/integration_test.go +++ b/pkg/kv/kvclient/kvcoord/integration_test.go @@ -92,7 +92,7 @@ func TestWaiterOnRejectedCommit(t *testing.T) { commitCmdID.Store(args.CmdID) return nil }, - TestingApplyFilter: func(args kvserverbase.ApplyFilterArgs) (int, *roachpb.Error) { + TestingApplyCalledTwiceFilter: func(args kvserverbase.ApplyFilterArgs) (int, *roachpb.Error) { // We'll trap the processing of the commit command and return an error // for it. v := commitCmdID.Load() diff --git a/pkg/kv/kvserver/client_migration_test.go b/pkg/kv/kvserver/client_migration_test.go index 4e41acb8ede4..761f8516affc 100644 --- a/pkg/kv/kvserver/client_migration_test.go +++ b/pkg/kv/kvserver/client_migration_test.go @@ -254,7 +254,7 @@ func TestMigrateWaitsForApplication(t *testing.T) { DisableAutomaticVersionUpgrade: make(chan struct{}), }, Store: &kvserver.StoreTestingKnobs{ - TestingApplyFilter: func(args kvserverbase.ApplyFilterArgs) (int, *roachpb.Error) { + TestingApplyCalledTwiceFilter: func(args kvserverbase.ApplyFilterArgs) (int, *roachpb.Error) { if args.StoreID == roachpb.StoreID(n3) && args.State != nil && args.State.Version != nil { <-blockApplicationCh } diff --git a/pkg/kv/kvserver/client_mvcc_gc_test.go b/pkg/kv/kvserver/client_mvcc_gc_test.go index ad266065a5d6..dac2f4b8ed34 100644 --- a/pkg/kv/kvserver/client_mvcc_gc_test.go +++ b/pkg/kv/kvserver/client_mvcc_gc_test.go @@ -16,6 +16,7 @@ import ( "time" "github.com/cockroachdb/cockroach/pkg/base" + "github.com/cockroachdb/cockroach/pkg/kv/kvserver" "github.com/cockroachdb/cockroach/pkg/roachpb" "github.com/cockroachdb/cockroach/pkg/server" "github.com/cockroachdb/cockroach/pkg/testutils/serverutils" @@ -32,7 +33,9 @@ func TestMVCCGCCorrectStats(t *testing.T) { defer log.Scope(t).Close(t) ctx := context.Background() - serv, _, _ := serverutils.StartServer(t, base.TestServerArgs{}) + var args base.TestServerArgs + args.Knobs.Store = &kvserver.StoreTestingKnobs{DisableCanAckBeforeApplication: true} + serv, _, _ := serverutils.StartServer(t, args) s := serv.(*server.TestServer) defer s.Stopper().Stop(ctx) diff --git a/pkg/kv/kvserver/client_raft_test.go b/pkg/kv/kvserver/client_raft_test.go index d2f70b4e8d00..249fd917377c 100644 --- a/pkg/kv/kvserver/client_raft_test.go +++ b/pkg/kv/kvserver/client_raft_test.go @@ -4285,7 +4285,7 @@ func TestFailedConfChange(t *testing.T) { ServerArgs: base.TestServerArgs{ Knobs: base.TestingKnobs{ Store: &kvserver.StoreTestingKnobs{ - TestingApplyFilter: testingApplyFilter, + TestingApplyCalledTwiceFilter: testingApplyFilter, }, }, }, @@ -4829,11 +4829,7 @@ func TestAckWriteBeforeApplication(t *testing.T) { repls int expAckBeforeAppl bool }{ - // In a single-replica Range, each handleRaftReady iteration will append - // new entries to the Raft log and immediately apply them. This prevents - // "early acknowledgement" from being possible or useful. See the comment - // on apply.Task.AckCommittedEntriesBeforeApplication. - {1, false}, + // In a three-replica Range, each handleRaftReady iteration will append // a set of entries to the Raft log and then apply the previous set of // entries. This makes "early acknowledgement" a major optimization, as @@ -4841,6 +4837,9 @@ func TestAckWriteBeforeApplication(t *testing.T) { // to the Raft log out of the client-perceived latency of the previous // set of entries. {3, true}, + // In the past, single-replica groups behaved differently but as of #89632 + // they too rely on early-acks as a major performance improvement. + {1, true}, } { t.Run(fmt.Sprintf("numRepls=%d", testcase.repls), func(t *testing.T) { var filterActive int32 @@ -4862,8 +4861,8 @@ func TestAckWriteBeforeApplication(t *testing.T) { ServerArgs: base.TestServerArgs{ Knobs: base.TestingKnobs{ Store: &kvserver.StoreTestingKnobs{ - TestingApplyFilter: applyFilterFn(blockPreApplication), - TestingPostApplyFilter: applyFilterFn(blockPostApplication), + TestingApplyCalledTwiceFilter: applyFilterFn(blockPreApplication), + TestingPostApplyFilter: applyFilterFn(blockPostApplication), }, }, }, @@ -4892,7 +4891,7 @@ func TestAckWriteBeforeApplication(t *testing.T) { expResult := func() { t.Helper() if pErr := <-ch; pErr != nil { - t.Fatalf("unexpected proposal result error: %v", pErr) + t.Errorf("unexpected proposal result error: %v", pErr) } } dontExpResult := func() { @@ -4901,7 +4900,7 @@ func TestAckWriteBeforeApplication(t *testing.T) { case <-time.After(10 * time.Millisecond): // Expected. case pErr := <-ch: - t.Fatalf("unexpected proposal acknowledged before TestingApplyFilter: %v", pErr) + t.Errorf("unexpected proposal acknowledged before TestingApplyCalledTwiceFilter: %v", pErr) } } diff --git a/pkg/kv/kvserver/client_replica_circuit_breaker_test.go b/pkg/kv/kvserver/client_replica_circuit_breaker_test.go index 472c52cbc71f..1167d794b117 100644 --- a/pkg/kv/kvserver/client_replica_circuit_breaker_test.go +++ b/pkg/kv/kvserver/client_replica_circuit_breaker_test.go @@ -706,10 +706,10 @@ func setupCircuitBreakerTest(t *testing.T) *circuitBreakerTest { // n1. However, we don't control raft leadership placement and without this knob, // n1 may refuse to acquire the lease, which we don't want. AllowLeaseRequestProposalsWhenNotLeader: true, - // The TestingApplyFilter prevents n2 from requesting a lease (or from the lease + // The TestingApplyCalledTwiceFilter prevents n2 from requesting a lease (or from the lease // being transferred to n2). The test seems to pass pretty reliably without this // but it can't hurt. - TestingApplyFilter: func(args kvserverbase.ApplyFilterArgs) (int, *roachpb.Error) { + TestingApplyCalledTwiceFilter: func(args kvserverbase.ApplyFilterArgs) (int, *roachpb.Error) { if !args.IsLeaseRequest { return 0, nil } diff --git a/pkg/kv/kvserver/client_replica_test.go b/pkg/kv/kvserver/client_replica_test.go index 4b50b3e397b7..841cd0a71c7e 100644 --- a/pkg/kv/kvserver/client_replica_test.go +++ b/pkg/kv/kvserver/client_replica_test.go @@ -163,6 +163,7 @@ func TestLeaseholdersRejectClockUpdateWithJump(t *testing.T) { Server: &server.TestingKnobs{ WallClock: manual, }, + Store: &kvserver.StoreTestingKnobs{DisableCanAckBeforeApplication: true}, }, }) s := serv.(*server.TestServer) @@ -2688,7 +2689,13 @@ func TestClearRange(t *testing.T) { defer log.Scope(t).Close(t) ctx := context.Background() - serv, _, _ := serverutils.StartServer(t, base.TestServerArgs{}) + serv, _, _ := serverutils.StartServer(t, base.TestServerArgs{ + Knobs: base.TestingKnobs{Store: &kvserver.StoreTestingKnobs{ + // This makes sure that our writes are visible when we go + // straight to the engine to check them. + DisableCanAckBeforeApplication: true, + }}, + }) s := serv.(*server.TestServer) defer s.Stopper().Stop(ctx) store, err := s.Stores().GetStore(s.GetFirstStoreID()) diff --git a/pkg/kv/kvserver/client_split_burst_test.go b/pkg/kv/kvserver/client_split_burst_test.go index a02f528a0d3b..89a010853cfd 100644 --- a/pkg/kv/kvserver/client_split_burst_test.go +++ b/pkg/kv/kvserver/client_split_burst_test.go @@ -74,7 +74,7 @@ func setupSplitBurstTest(t *testing.T, delay time.Duration) *splitBurstTest { numSplitsSeenOnSlowFollower := new(int32) // atomic var quiesceCh <-chan struct{} knobs := base.TestingKnobs{Store: &kvserver.StoreTestingKnobs{ - TestingApplyFilter: func(args kvserverbase.ApplyFilterArgs) (int, *roachpb.Error) { + TestingApplyCalledTwiceFilter: func(args kvserverbase.ApplyFilterArgs) (int, *roachpb.Error) { if args.Split == nil || delay == 0 { return 0, nil } diff --git a/pkg/kv/kvserver/client_split_test.go b/pkg/kv/kvserver/client_split_test.go index 3c4a981895f3..2b8743b03cde 100644 --- a/pkg/kv/kvserver/client_split_test.go +++ b/pkg/kv/kvserver/client_split_test.go @@ -599,8 +599,9 @@ func TestStoreRangeSplitIdempotency(t *testing.T) { serv, _, _ := serverutils.StartServer(t, base.TestServerArgs{ Knobs: base.TestingKnobs{ Store: &kvserver.StoreTestingKnobs{ - DisableMergeQueue: true, - DisableSplitQueue: true, + DisableMergeQueue: true, + DisableSplitQueue: true, + DisableCanAckBeforeApplication: true, }, }, }) @@ -760,8 +761,9 @@ func TestStoreRangeSplitMergeStats(t *testing.T) { serv, _, _ := serverutils.StartServer(t, base.TestServerArgs{ Knobs: base.TestingKnobs{ Store: &kvserver.StoreTestingKnobs{ - DisableMergeQueue: true, - DisableSplitQueue: true, + DisableMergeQueue: true, + DisableSplitQueue: true, + DisableCanAckBeforeApplication: true, }, }, }) @@ -843,7 +845,8 @@ func TestStoreRangeSplitMergeStats(t *testing.T) { // Merge the ranges back together, and assert that the merged stats // agree with the pre-split stats. - _, pErr = kv.SendWrapped(ctx, store.TestSender(), adminMergeArgs(repl.Desc().StartKey.AsRawKey())) + mergeKey := repl.Desc().StartKey.AsRawKey() + _, pErr = kv.SendWrapped(ctx, store.TestSender(), adminMergeArgs(mergeKey)) require.NoError(t, pErr.GoError()) repl = store.LookupReplica(roachpb.RKey(keyPrefix)) @@ -1250,10 +1253,11 @@ func TestStoreRangeSplitBackpressureWrites(t *testing.T) { DefaultZoneConfigOverride: &zoneConfig, }, Store: &kvserver.StoreTestingKnobs{ - DisableGCQueue: true, - DisableMergeQueue: true, - DisableSplitQueue: true, - TestingRequestFilter: testingRequestFilter, + DisableCanAckBeforeApplication: true, + DisableGCQueue: true, + DisableMergeQueue: true, + DisableSplitQueue: true, + TestingRequestFilter: testingRequestFilter, }, }, }) @@ -2558,6 +2562,9 @@ func TestUnsplittableRange(t *testing.T) { Store: &kvserver.StoreTestingKnobs{ DisableMergeQueue: true, SplitQueuePurgatoryChan: splitQueuePurgatoryChan, + // Without this, the test is flaky: the range does not end up in + // purgatory "synchronously". + DisableCanAckBeforeApplication: true, }, Server: &server.TestingKnobs{ WallClock: manualClock, @@ -2769,6 +2776,9 @@ func TestStoreCapacityAfterSplit(t *testing.T) { Server: &server.TestingKnobs{ WallClock: manualClock, }, + Store: &kvserver.StoreTestingKnobs{ + DisableCanAckBeforeApplication: true, + }, }, }, }) diff --git a/pkg/kv/kvserver/client_status_test.go b/pkg/kv/kvserver/client_status_test.go index 00607a04fb34..69eb92152501 100644 --- a/pkg/kv/kvserver/client_status_test.go +++ b/pkg/kv/kvserver/client_status_test.go @@ -15,6 +15,7 @@ import ( "testing" "github.com/cockroachdb/cockroach/pkg/base" + "github.com/cockroachdb/cockroach/pkg/kv/kvserver" "github.com/cockroachdb/cockroach/pkg/roachpb" "github.com/cockroachdb/cockroach/pkg/server" "github.com/cockroachdb/cockroach/pkg/testutils" @@ -30,7 +31,11 @@ func TestComputeStatsForKeySpan(t *testing.T) { defer log.Scope(t).Close(t) ctx := context.Background() - serv, _, _ := serverutils.StartServer(t, base.TestServerArgs{}) + serv, _, _ := serverutils.StartServer(t, base.TestServerArgs{ + Knobs: base.TestingKnobs{ + Store: &kvserver.StoreTestingKnobs{DisableCanAckBeforeApplication: true}, + }, + }) s := serv.(*server.TestServer) defer s.Stopper().Stop(ctx) store, err := s.Stores().GetStore(s.GetFirstStoreID()) diff --git a/pkg/kv/kvserver/consistency_queue_test.go b/pkg/kv/kvserver/consistency_queue_test.go index 095ab2fcc0d6..fa50e493bdd5 100644 --- a/pkg/kv/kvserver/consistency_queue_test.go +++ b/pkg/kv/kvserver/consistency_queue_test.go @@ -157,7 +157,7 @@ func TestCheckConsistencyReplay(t *testing.T) { } // Arrange to count the number of times each checksum command applies to each // store. - testKnobs.TestingApplyFilter = func(args kvserverbase.ApplyFilterArgs) (int, *roachpb.Error) { + testKnobs.TestingPostApplyFilter = func(args kvserverbase.ApplyFilterArgs) (int, *roachpb.Error) { state.Lock() defer state.Unlock() if ccr := args.ComputeChecksum; ccr != nil { diff --git a/pkg/kv/kvserver/loqrecovery/collect_raft_log_test.go b/pkg/kv/kvserver/loqrecovery/collect_raft_log_test.go index 95376ea8d8fa..96776eb7795d 100644 --- a/pkg/kv/kvserver/loqrecovery/collect_raft_log_test.go +++ b/pkg/kv/kvserver/loqrecovery/collect_raft_log_test.go @@ -177,8 +177,8 @@ func checkRaftLog( nodeToMonitor: { Knobs: base.TestingKnobs{ Store: &kvserver.StoreTestingKnobs{ - TestingApplyFilter: raftFilter, - DisableGCQueue: true, + TestingPostApplyFilter: raftFilter, + DisableGCQueue: true, }, }, StoreSpecs: []base.StoreSpec{{InMemory: true}}, diff --git a/pkg/kv/kvserver/replica_application_result.go b/pkg/kv/kvserver/replica_application_result.go index 4f01270616e1..c7ccb04dd594 100644 --- a/pkg/kv/kvserver/replica_application_result.go +++ b/pkg/kv/kvserver/replica_application_result.go @@ -123,6 +123,7 @@ func (r *Replica) prepareLocalResult(ctx context.Context, cmd *replicatedCmd) { StoreID: r.store.StoreID(), RangeID: r.RangeID, Req: cmd.proposal.Request, + ForcedError: cmd.forcedErr, }) if cmd.proposalRetry == 0 { cmd.proposalRetry = proposalReevaluationReason(newPropRetry) diff --git a/pkg/kv/kvserver/replica_application_state_machine.go b/pkg/kv/kvserver/replica_application_state_machine.go index 3e5731f50672..ff9ea1668f7c 100644 --- a/pkg/kv/kvserver/replica_application_state_machine.go +++ b/pkg/kv/kvserver/replica_application_state_machine.go @@ -152,7 +152,7 @@ func (r *Replica) shouldApplyCommand( ctx, cmd.idKey, &cmd.raftCmd, cmd.IsLocal(), replicaState, ) // Consider testing-only filters. - if filter := r.store.cfg.TestingKnobs.TestingApplyFilter; cmd.forcedErr != nil || filter != nil { + if filter := r.store.cfg.TestingKnobs.TestingApplyCalledTwiceFilter; cmd.forcedErr != nil || filter != nil { args := kvserverbase.ApplyFilterArgs{ CmdID: cmd.idKey, ReplicatedEvalResult: *cmd.replicatedResult(), diff --git a/pkg/kv/kvserver/replica_application_state_machine_test.go b/pkg/kv/kvserver/replica_application_state_machine_test.go index 96d932947da4..3d3df3b18c9d 100644 --- a/pkg/kv/kvserver/replica_application_state_machine_test.go +++ b/pkg/kv/kvserver/replica_application_state_machine_test.go @@ -255,24 +255,40 @@ func TestReplicaStateMachineRaftLogTruncationLooselyCoupled(t *testing.T) { // non-deterministic flush to cause the test to fail. tc.store.engine.RegisterFlushCompletedCallback(func() {}) r := tc.repl - r.mu.Lock() - raftAppliedIndex := r.mu.state.RaftAppliedIndex - truncatedIndex := r.mu.state.TruncatedState.Index - raftLogSize := r.mu.raftLogSize - // Overwrite to be trusted, since we want to check if transitions to false - // or not. - r.mu.raftLogSizeTrusted = true - r.mu.Unlock() - expectedFirstIndex := truncatedIndex + 1 - if !accurate { - expectedFirstIndex = truncatedIndex + + { + k := tc.repl.Desc().EndKey.AsRawKey().Prevish(10) + pArgs := putArgs(k, []byte("foo")) + _, pErr := tc.SendWrapped(&pArgs) + require.NoError(t, pErr.GoError()) + gArgs := getArgs(k) + _, pErr = tc.SendWrapped(&gArgs) + require.NoError(t, pErr.GoError()) } - // Enqueue the truncation. - func() { - // Lock the replica. + raftLogSize, truncatedIndex := func() (_rls int64, truncIdx uint64) { + // Lock the replica. We do this early to avoid interference from any other + // moving parts on the Replica, whatever they may be. For example, we don't + // want a skewed lease applied index because commands are applying concurrently + // while we are busy picking values. Though note that we flush out commands above + // because even if we serialize correctly, there might be an unapplied command + // that already consumed our chosen lease index, we just wouldn't know. r.raftMu.Lock() defer r.raftMu.Unlock() + r.mu.Lock() + raftAppliedIndex := r.mu.state.RaftAppliedIndex + truncatedIndex := r.mu.state.TruncatedState.Index + raftLogSize := r.mu.raftLogSize + // Overwrite to be trusted, since we want to check if transitions to false + // or not. + r.mu.raftLogSizeTrusted = true + r.mu.Unlock() + expectedFirstIndex := truncatedIndex + 1 + if !accurate { + expectedFirstIndex = truncatedIndex + } + + // Enqueue the truncation. sm := r.getStateMachine() // Create a new application batch. @@ -329,6 +345,7 @@ func TestReplicaStateMachineRaftLogTruncationLooselyCoupled(t *testing.T) { require.Equal(t, expectedFirstIndex, trunc.expectedFirstIndex) require.EqualValues(t, -1, trunc.logDeltaBytes) require.True(t, trunc.isDeltaTrusted) + return raftLogSize, truncatedIndex }() require.NoError(t, tc.store.Engine().Flush()) // Asynchronous call to advance durability. diff --git a/pkg/kv/kvserver/replica_closedts_internal_test.go b/pkg/kv/kvserver/replica_closedts_internal_test.go index a7e1e9b5bd73..fd499bf4c0bb 100644 --- a/pkg/kv/kvserver/replica_closedts_internal_test.go +++ b/pkg/kv/kvserver/replica_closedts_internal_test.go @@ -656,14 +656,25 @@ func TestQueryResolvedTimestamp(t *testing.T) { tc.manualClock = timeutil.NewManualTime(timeutil.Unix(0, 1)) // required by StartWithStoreConfig cfg := TestStoreConfig(hlc.NewClock(tc.manualClock, 100*time.Nanosecond) /* maxOffset */) cfg.TestingKnobs.DontCloseTimestamps = true + // Make sure commands are visible by the time they are applied. Otherwise + // this test can be flaky because we might have a lease applied index + // assigned to a command that is committed but not applied yet. When we + // then "commit" a command out of band, and the stored command gets + // applied, their indexes will clash and cause a fatal error. + cfg.TestingKnobs.DisableCanAckBeforeApplication = true tc.StartWithStoreConfig(ctx, t, stopper, cfg) // Write an intent. txn := roachpb.MakeTransaction("test", intentKey, 0, intentTS, 0, 0) - pArgs := putArgs(intentKey, []byte("val")) - assignSeqNumsForReqs(&txn, &pArgs) - _, pErr := kv.SendWrappedWith(ctx, tc.Sender(), roachpb.Header{Txn: &txn}, &pArgs) - require.Nil(t, pErr) + { + pArgs := putArgs(intentKey, []byte("val")) + assignSeqNumsForReqs(&txn, &pArgs) + _, pErr := kv.SendWrappedWith(ctx, tc.Sender(), roachpb.Header{Txn: &txn}, &pArgs) + require.Nil(t, pErr) + } + + // NB: the put is now visible, in particular it has applied, thanks + // to the testing knobs in this test. // Inject a closed timestamp. tc.repl.mu.Lock() @@ -958,6 +969,7 @@ func TestServerSideBoundedStalenessNegotiation(t *testing.T) { tc.manualClock = timeutil.NewManualTime(timeutil.Unix(0, 1)) // required by StartWithStoreConfig cfg := TestStoreConfig(hlc.NewClock(tc.manualClock, 100*time.Nanosecond) /* maxOffset */) cfg.TestingKnobs.DontCloseTimestamps = true + cfg.TestingKnobs.DisableCanAckBeforeApplication = true tc.StartWithStoreConfig(ctx, t, stopper, cfg) // Write an intent. @@ -1135,6 +1147,7 @@ func TestServerSideBoundedStalenessNegotiationWithResumeSpan(t *testing.T) { tc.manualClock = timeutil.NewManualTime(timeutil.Unix(0, 1)) // required by StartWithStoreConfig cfg := TestStoreConfig(hlc.NewClock(tc.manualClock, 100*time.Nanosecond) /* maxOffset */) cfg.TestingKnobs.DontCloseTimestamps = true + cfg.TestingKnobs.DisableCanAckBeforeApplication = true tc.StartWithStoreConfig(ctx, t, stopper, cfg) // Set up the test. diff --git a/pkg/kv/kvserver/replica_closedts_test.go b/pkg/kv/kvserver/replica_closedts_test.go index 7713692f00f8..37201223c8bb 100644 --- a/pkg/kv/kvserver/replica_closedts_test.go +++ b/pkg/kv/kvserver/replica_closedts_test.go @@ -152,7 +152,7 @@ func TestBumpSideTransportClosed(t *testing.T) { } return 0, nil } - return &kvserver.StoreTestingKnobs{TestingApplyFilter: testingApplyFilter}, applyC + return &kvserver.StoreTestingKnobs{TestingApplyCalledTwiceFilter: testingApplyFilter}, applyC }, setup: func(a setupArgs) (chan struct{}, chan error, error) { // Initiate a Raft proposal and pause it during application. diff --git a/pkg/kv/kvserver/replica_follower_read_test.go b/pkg/kv/kvserver/replica_follower_read_test.go index a13d0c08e621..0e9304f8e5c5 100644 --- a/pkg/kv/kvserver/replica_follower_read_test.go +++ b/pkg/kv/kvserver/replica_follower_read_test.go @@ -110,6 +110,7 @@ func TestCheckExecutionCanProceedAllowsFollowerReadWithInvalidLease(t *testing.T manual := timeutil.NewManualTime(timeutil.Unix(5, 0)) clock := hlc.NewClock(manual, 1 /* maxOffset */) tsc := TestStoreConfig(clock) + tsc.TestingKnobs.DisableCanAckBeforeApplication = true // Permit only one lease attempt. The test is flaky if we allow the lease to // be renewed by background processes. var leaseOnce sync.Once diff --git a/pkg/kv/kvserver/replica_probe_test.go b/pkg/kv/kvserver/replica_probe_test.go index 8c7917a42e8a..1e0109983462 100644 --- a/pkg/kv/kvserver/replica_probe_test.go +++ b/pkg/kv/kvserver/replica_probe_test.go @@ -62,7 +62,7 @@ func TestReplicaProbeRequest(t *testing.T) { // We set an ApplyFilter even though the probe should never // show up there (since it always catches a forced error), // precisely to ensure that it doesn't. - TestingApplyFilter: filter, + TestingApplyCalledTwiceFilter: filter, // This is the main workhorse that counts probes and injects // errors. TestingApplyForcedErrFilter: filter, diff --git a/pkg/kv/kvserver/replica_raft.go b/pkg/kv/kvserver/replica_raft.go index 4a05edcd6d6c..a4a944e1280c 100644 --- a/pkg/kv/kvserver/replica_raft.go +++ b/pkg/kv/kvserver/replica_raft.go @@ -857,8 +857,10 @@ func (r *Replica) handleRaftReadyRaftMuLocked( if err := appTask.Decode(ctx, rd.CommittedEntries); err != nil { return stats, getNonDeterministicFailureExplanation(err), err } - if err := appTask.AckCommittedEntriesBeforeApplication(ctx, lastIndex); err != nil { - return stats, getNonDeterministicFailureExplanation(err), err + if knobs := r.store.TestingKnobs(); knobs == nil || !knobs.DisableCanAckBeforeApplication { + if err := appTask.AckCommittedEntriesBeforeApplication(ctx, lastIndex); err != nil { + return stats, getNonDeterministicFailureExplanation(err), err + } } // Separate the MsgApp messages from all other Raft message types so that we diff --git a/pkg/kv/kvserver/replica_rankings_test.go b/pkg/kv/kvserver/replica_rankings_test.go index 1365b440d4b1..d27553703074 100644 --- a/pkg/kv/kvserver/replica_rankings_test.go +++ b/pkg/kv/kvserver/replica_rankings_test.go @@ -206,9 +206,11 @@ func TestWriteLoadStatsAccounting(t *testing.T) { defer log.Scope(t).Close(t) ctx := context.Background() - tc := serverutils.StartNewTestCluster(t, 1, base.TestClusterArgs{ + args := base.TestClusterArgs{ ReplicationMode: base.ReplicationManual, - }) + } + args.ServerArgs.Knobs.Store = &StoreTestingKnobs{DisableCanAckBeforeApplication: true} + tc := serverutils.StartNewTestCluster(t, 1, args) const epsilonAllowed = 4 diff --git a/pkg/kv/kvserver/replica_test.go b/pkg/kv/kvserver/replica_test.go index 2d24789d73ab..9db3105cedb2 100644 --- a/pkg/kv/kvserver/replica_test.go +++ b/pkg/kv/kvserver/replica_test.go @@ -908,7 +908,7 @@ func TestReplicaLease(t *testing.T) { tc.manualClock = timeutil.NewManualTime(timeutil.Unix(0, 123)) tsc := TestStoreConfig(hlc.NewClock(tc.manualClock, time.Nanosecond) /* maxOffset */) tsc.TestingKnobs.DisableAutomaticLeaseRenewal = true - tsc.TestingKnobs.TestingApplyFilter = applyFilter + tsc.TestingKnobs.TestingApplyCalledTwiceFilter = applyFilter tc.StartWithStoreConfig(ctx, t, stopper, tsc) secondReplica, err := tc.addBogusReplicaToRangeDesc(ctx) if err != nil { @@ -2922,7 +2922,9 @@ func TestReplicaTSCacheForwardsIntentTS(t *testing.T) { tc := testContext{} stopper := stop.NewStopper() defer stopper.Stop(ctx) - tc.Start(ctx, t, stopper) + sc := TestStoreConfig(nil) + sc.TestingKnobs.DisableCanAckBeforeApplication = true + tc.StartWithStoreConfig(ctx, t, stopper, sc) tsOld := tc.Clock().Now() tsNew := tsOld.Add(time.Millisecond.Nanoseconds(), 0).WithSynthetic(synthetic) @@ -6229,7 +6231,11 @@ func TestRangeStatsComputation(t *testing.T) { tc := testContext{} stopper := stop.NewStopper() defer stopper.Stop(ctx) - tc.Start(ctx, t, stopper) + tc.manualClock = timeutil.NewManualTime(timeutil.Unix(0, 123)) + sc := TestStoreConfig(hlc.NewClock(tc.manualClock, 500*time.Millisecond)) + + sc.TestingKnobs.DisableCanAckBeforeApplication = true + tc.StartWithStoreConfig(ctx, t, stopper, sc) baseStats := tc.repl.GetMVCCStats() @@ -6466,7 +6472,9 @@ func TestAppliedIndex(t *testing.T) { tc := testContext{} stopper := stop.NewStopper() defer stopper.Stop(ctx) - tc.Start(ctx, t, stopper) + sc := TestStoreConfig(nil) + sc.TestingKnobs.DisableCanAckBeforeApplication = true + tc.StartWithStoreConfig(ctx, t, stopper, sc) var appliedIndex uint64 var sum int64 @@ -6608,6 +6616,7 @@ func TestReplicaDanglingMetaIntent(t *testing.T) { defer stopper.Stop(ctx) cfg := TestStoreConfig(nil) cfg.TestingKnobs.DontPushOnWriteIntentError = true + cfg.TestingKnobs.DisableCanAckBeforeApplication = true tc.StartWithStoreConfig(ctx, t, stopper, cfg) key := roachpb.Key("a") @@ -7342,7 +7351,9 @@ func TestGCIncorrectRange(t *testing.T) { tc := testContext{} stopper := stop.NewStopper() defer stopper.Stop(ctx) - tc.Start(ctx, t, stopper) + sc := TestStoreConfig(nil) + sc.TestingKnobs.DisableCanAckBeforeApplication = true + tc.StartWithStoreConfig(ctx, t, stopper, sc) // Split range into two ranges. splitKey := roachpb.RKey("c") @@ -7690,7 +7701,9 @@ func TestReplicaRetryRaftProposal(t *testing.T) { var tc testContext stopper := stop.NewStopper() defer stopper.Stop(ctx) - tc.Start(ctx, t, stopper) + sc := TestStoreConfig(nil) + sc.TestingKnobs.DisableCanAckBeforeApplication = true + tc.StartWithStoreConfig(ctx, t, stopper, sc) type magicKey struct{} @@ -7860,6 +7873,7 @@ func TestReplicaBurstPendingCommandsAndRepropose(t *testing.T) { // Raft leadership instability. cfg.TestingKnobs.DisableRefreshReasonNewLeader = true cfg.TestingKnobs.DisableRefreshReasonNewLeaderOrConfigChange = true + cfg.TestingKnobs.DisableCanAckBeforeApplication = true ctx := context.Background() stopper := stop.NewStopper() defer stopper.Stop(ctx) @@ -8080,12 +8094,11 @@ func TestReplicaRefreshMultiple(t *testing.T) { ctx := context.Background() - var filterActive int32 - var incCmdID kvserverbase.CmdIDKey + const incCmdID = "deadbeef" var incApplyCount int64 tsc := TestStoreConfig(nil) - tsc.TestingKnobs.TestingApplyFilter = func(filterArgs kvserverbase.ApplyFilterArgs) (int, *roachpb.Error) { - if atomic.LoadInt32(&filterActive) != 0 && filterArgs.CmdID == incCmdID { + tsc.TestingKnobs.TestingPostApplyFilter = func(filterArgs kvserverbase.ApplyFilterArgs) (int, *roachpb.Error) { + if filterArgs.ForcedError == nil && filterArgs.CmdID == incCmdID { atomic.AddInt64(&incApplyCount, 1) } return 0, nil @@ -8129,8 +8142,6 @@ func TestReplicaRefreshMultiple(t *testing.T) { ba.Add(inc) ba.Timestamp = tc.Clock().Now() - incCmdID = makeIDKey() - atomic.StoreInt32(&filterActive, 1) st := repl.CurrentLeaseStatus(ctx) proposal, pErr := repl.requestToProposal(ctx, incCmdID, &ba, allSpansGuard(), &st, uncertainty.Interval{}) if pErr != nil { @@ -8151,6 +8162,7 @@ func TestReplicaRefreshMultiple(t *testing.T) { repl.mu.proposalBuf.testing.leaseIndexFilter = func(p *ProposalData) (indexOverride uint64) { if p == proposal && !assigned { assigned = true + t.Logf("assigned wrong LAI %d", ai-1) return ai - 1 } return 0 @@ -9692,7 +9704,7 @@ func TestErrorInRaftApplicationClearsIntents(t *testing.T) { if err != nil { t.Fatal(err) } - storeKnobs.TestingApplyFilter = func(filterArgs kvserverbase.ApplyFilterArgs) (int, *roachpb.Error) { + storeKnobs.TestingApplyCalledTwiceFilter = func(filterArgs kvserverbase.ApplyFilterArgs) (int, *roachpb.Error) { if atomic.LoadInt32(&filterActive) == 1 { return 0, roachpb.NewErrorf("boom") } @@ -9768,7 +9780,7 @@ func TestProposeWithAsyncConsensus(t *testing.T) { var filterActive int32 blockRaftApplication := make(chan struct{}) - tsc.TestingKnobs.TestingApplyFilter = + tsc.TestingKnobs.TestingApplyCalledTwiceFilter = func(filterArgs kvserverbase.ApplyFilterArgs) (int, *roachpb.Error) { if atomic.LoadInt32(&filterActive) == 1 { <-blockRaftApplication @@ -9829,7 +9841,7 @@ func TestApplyPaginatedCommittedEntries(t *testing.T) { var filterActive int32 blockRaftApplication := make(chan struct{}) blockingRaftApplication := make(chan struct{}, 1) - tsc.TestingKnobs.TestingApplyFilter = + tsc.TestingKnobs.TestingApplyCalledTwiceFilter = func(filterArgs kvserverbase.ApplyFilterArgs) (int, *roachpb.Error) { if atomic.LoadInt32(&filterActive) == 1 { select { @@ -10514,7 +10526,10 @@ func TestReplicaServersideRefreshes(t *testing.T) { tc := testContext{} stopper := stop.NewStopper() defer stopper.Stop(ctx) - tc.Start(ctx, t, stopper) + sc := TestStoreConfig(nil) + sc.TestingKnobs.DisableCanAckBeforeApplication = true + tc.manualClock = timeutil.NewManualTime(timeutil.Unix(0, 123)) + tc.StartWithStoreConfig(ctx, t, stopper, sc) // Increment the clock so that all the transactions in the tests run at a // different physical timestamp than the one used to initialize the replica's @@ -11560,7 +11575,9 @@ func TestRangeStatsRequest(t *testing.T) { ctx := context.Background() stopper := stop.NewStopper() defer stopper.Stop(ctx) - tc.Start(ctx, t, stopper) + sc := TestStoreConfig(nil) + sc.TestingKnobs.DisableCanAckBeforeApplication = true + tc.StartWithStoreConfig(ctx, t, stopper, sc) keyPrefix := roachpb.Key("dummy-prefix") @@ -13290,7 +13307,7 @@ func TestProposalNotAcknowledgedOrReproposedAfterApplication(t *testing.T) { }, // Detect the application of the proposal to repropose it and also // invalidate the lease. - TestingApplyFilter: func(args kvserverbase.ApplyFilterArgs) (retry int, pErr *roachpb.Error) { + TestingApplyCalledTwiceFilter: func(args kvserverbase.ApplyFilterArgs) (retry int, pErr *roachpb.Error) { if seen || args.CmdID != cmdID { return 0, nil } diff --git a/pkg/kv/kvserver/split_queue_test.go b/pkg/kv/kvserver/split_queue_test.go index 27111c5ecaad..acfacc9c431a 100644 --- a/pkg/kv/kvserver/split_queue_test.go +++ b/pkg/kv/kvserver/split_queue_test.go @@ -18,12 +18,14 @@ import ( "github.com/cockroachdb/cockroach/pkg/config" "github.com/cockroachdb/cockroach/pkg/config/zonepb" "github.com/cockroachdb/cockroach/pkg/keys" + "github.com/cockroachdb/cockroach/pkg/kv" "github.com/cockroachdb/cockroach/pkg/roachpb" "github.com/cockroachdb/cockroach/pkg/storage/enginepb" "github.com/cockroachdb/cockroach/pkg/util/leaktest" "github.com/cockroachdb/cockroach/pkg/util/log" "github.com/cockroachdb/cockroach/pkg/util/stop" "github.com/gogo/protobuf/proto" + "github.com/stretchr/testify/require" ) // TestSplitQueueShouldQueue verifies shouldSplitRange method correctly @@ -35,7 +37,9 @@ func TestSplitQueueShouldQueue(t *testing.T) { tc := testContext{} stopper := stop.NewStopper() defer stopper.Stop(ctx) - tc.Start(ctx, t, stopper) + sc := TestStoreConfig(nil) + sc.TestingKnobs.DisableCanAckBeforeApplication = true + tc.StartWithStoreConfig(ctx, t, stopper, sc) // Set zone configs. config.TestingSetZoneConfig(2000, zonepb.ZoneConfig{RangeMaxBytes: proto.Int64(32 << 20)}) @@ -74,6 +78,17 @@ func TestSplitQueueShouldQueue(t *testing.T) { if err != nil { t.Fatal(err) } + + { + // This test plays fast and loose and if there are raft commands ongoing then + // we'll hit internal assertions in the tests below. Sending a write through + // before mucking with internals and waiting for it to show up in the state + // machine appears to be good enough. + put := putArgs(tc.repl.Desc().EndKey.AsRawKey().Prevish(5), []byte("foo")) + _, pErr := kv.SendWrapped(ctx, tc.Sender(), &put) + require.NoError(t, pErr.GoError()) + } + for i, test := range testCases { // Create a replica for testing that is not hooked up to the store. This // ensures that the store won't be mucking with our replica concurrently diff --git a/pkg/kv/kvserver/testing_knobs.go b/pkg/kv/kvserver/testing_knobs.go index 9b9a2640f3da..644671840dbd 100644 --- a/pkg/kv/kvserver/testing_knobs.go +++ b/pkg/kv/kvserver/testing_knobs.go @@ -61,16 +61,25 @@ type StoreTestingKnobs struct { // reproposed due to ticks. TestingProposalSubmitFilter func(*ProposalData) (drop bool, err error) - // TestingApplyFilter is called before applying the results of a command on + // TestingApplyCalledTwiceFilter is called before applying the results of a command on // each replica assuming the command was cleared for application (i.e. no // forced error occurred; the supplied AppliedFilterArgs will have a nil // ForcedError field). If this function returns an error, it is treated as // a forced error and the command will not be applied. If it returns an error // on some replicas but not others, the behavior is poorly defined. The // returned int is interpreted as a proposalReevaluationReason. - TestingApplyFilter kvserverbase.ReplicaApplyFilter - // TestingApplyForcedErrFilter is like TestingApplyFilter, but it is only - // invoked when there is a pre-existing forced error. The returned int and + // + // Users have to expect the filter to be invoked twice for each command, once + // from ephemerealReplicaAppBatch.Stage, and once from replicaAppBatch.Stage; + // this has to do with wanting to early-ack successful proposals. The second + // call is conditional on the first call succeeding. + // + // Consider using a TestPostApplyFilter instead, and use a + // TestingApplyCalledTwiceFilter only to inject forced errors. + TestingApplyCalledTwiceFilter kvserverbase.ReplicaApplyFilter + // TestingApplyForcedErrFilter is like TestingApplyCalledTwiceFilter, but it + // is only invoked when there is a pre-existing forced error (and in + // particular, it will be invoked only once per command). The returned int and // *Error replace the existing proposalReevaluationReason (if initially zero // only) and forced error. TestingApplyForcedErrFilter kvserverbase.ReplicaApplyFilter @@ -78,6 +87,10 @@ type StoreTestingKnobs struct { // TestingPostApplyFilter is called after a command is applied to // rocksdb but before in-memory side effects have been processed. // It is only called on the replica the proposed the command. + // + // Filters need to handle the case in which the command applies + // with a forced error. That is, the "command" will apply as a + // no-op write, and the ForcedError field will be set. TestingPostApplyFilter kvserverbase.ReplicaApplyFilter // TestingResponseErrorEvent is called when an error is returned applying @@ -439,6 +452,11 @@ type StoreTestingKnobs struct { // making high priority replica scans. MVCCGCQueueLeaseCheckInterceptor func(ctx context.Context, replica *Replica, now hlc.ClockTimestamp) bool + // DisableCanAckBeforeApplication disables acknowledging committed entries + // before they apply. This can simplify some tests by making sure that a write + // is on the engine when the request returns. + DisableCanAckBeforeApplication bool + // SmallEngineBlocks will configure the engine with a very small block size of // 1 byte, resulting in each key having its own block. This can provoke bugs // in time-bound iterators. diff --git a/vendor b/vendor index 1e5720b5eac2..a47be4d893eb 160000 --- a/vendor +++ b/vendor @@ -1 +1 @@ -Subproject commit 1e5720b5eac24eaace1795f29cf745a20cc1db0c +Subproject commit a47be4d893ebc027ce304b3ca37ca89df65458cd