Skip to content

Commit 9b71606

Browse files
Deprecate twopc_enable flag and change input type for twopc_abandon_age to time.Duration (#17279)
Signed-off-by: Harshit Gangal <[email protected]>
1 parent 9181115 commit 9b71606

File tree

22 files changed

+234
-143
lines changed

22 files changed

+234
-143
lines changed

changelog/22.0/22.0.0/summary.md

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,9 +3,13 @@
33
### Table of Contents
44

55
- **[Major Changes](#major-changes)**
6+
- **[Deprecations and Deletions](#deprecations-and-deletions)**
7+
- [Deprecated VTTablet Flags](#vttablet-flags)
68
- **[RPC Changes](#rpc-changes)**
79
- **[Prefer not promoting a replica that is currently taking a backup](#reparents-prefer-not-backing-up)**
810
- **[VTOrc Config File Changes](#vtorc-config-file-changes)**
11+
- **[Minor Changes](#minor-changes)**
12+
- **[VTTablet Flags](#flags-vttablet)**
913

1014

1115
## <a id="major-changes"/>Major Changes</a>
@@ -16,6 +20,12 @@ These are the RPC changes made in this release -
1620

1721
1. `GetTransactionInfo` RPC has been added to both `VtctldServer`, and `TabletManagerClient` interface. These RPCs are used to fecilitate the users in reading the state of an unresolved distributed transaction. This can be useful in debugging what went wrong and how to fix the problem.
1822

23+
### <a id="deprecations-and-deletions"/>Deprecations and Deletions</a>
24+
25+
#### <a id="vttablet-flags"/>Deprecated VTTablet Flags</a>
26+
27+
- `twopc_enable` flag is deprecated. Usage of TwoPC commit will be determined by the `transaction_mode` set on VTGate via flag or session variable.
28+
1929
### <a id="reparents-prefer-not-backing-up"/>Prefer not promoting a replica that is currently taking a backup
2030

2131
Emergency reparents now prefer not promoting replicas that are currently taking backups with a backup engine other than
@@ -48,3 +58,12 @@ The following fields can be dynamically changed -
4858
13. `change-tablets-with-errant-gtid-to-drained`
4959

5060
To upgrade to the newer version of the configuration file, first switch to using the flags in your current deployment before upgrading. Then you can switch to using the configuration file in the newer release.
61+
62+
63+
## <a id="minor-changes"/>Minor Changes</a>
64+
65+
#### <a id="flags-vttablet"/>VTTablet Flags</a>
66+
67+
- `twopc_abandon_age` flag now supports values in the time.Duration format (e.g., 1s, 2m, 1h).
68+
While the flag will continue to accept float values (interpreted as seconds) for backward compatibility,
69+
**float inputs are deprecated** and will be removed in a future release.

go/flags/endtoend/vtcombo.txt

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -395,8 +395,7 @@ Flags:
395395
--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)
396396
--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")
397397
--truncate-error-len int truncate errors sent to client if they are longer than this value (0 means do not truncate)
398-
--twopc_abandon_age float time in seconds. Any unresolved transaction older than this time will be sent to the coordinator to be resolved.
399-
--twopc_enable if the flag is on, 2pc is enabled. Other 2pc flags must be supplied.
398+
--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)
400399
--tx-throttler-config string Synonym to -tx_throttler_config (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")
401400
--tx-throttler-default-priority int Default priority assigned to queries that lack priority information (default 100)
402401
--tx-throttler-dry-run If present, the transaction throttler only records metrics about requests received and throttled, but does not actually throttle any requests.

go/flags/endtoend/vttablet.txt

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -395,8 +395,7 @@ Flags:
395395
--transaction_limit_by_subcomponent Include CallerID.subcomponent when considering who the user is for the purpose of transaction limit.
396396
--transaction_limit_by_username Include VTGateCallerID.username when considering who the user is for the purpose of transaction limit. (default true)
397397
--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)
398-
--twopc_abandon_age float time in seconds. Any unresolved transaction older than this time will be sent to the coordinator to be resolved.
399-
--twopc_enable if the flag is on, 2pc is enabled. Other 2pc flags must be supplied.
398+
--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)
400399
--tx-throttler-config string Synonym to -tx_throttler_config (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")
401400
--tx-throttler-default-priority int Default priority assigned to queries that lack priority information (default 100)
402401
--tx-throttler-dry-run If present, the transaction throttler only records metrics about requests received and throttled, but does not actually throttle any requests.

go/flagutil/float_to_duration.go

Lines changed: 71 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,71 @@
1+
/*
2+
Copyright 2024 The Vitess Authors.
3+
4+
Licensed under the Apache License, Version 2.0 (the "License");
5+
you may not use this file except in compliance with the License.
6+
You may obtain a copy of the License at
7+
8+
http://www.apache.org/licenses/LICENSE-2.0
9+
10+
Unless required by applicable law or agreed to in writing, software
11+
distributed under the License is distributed on an "AS IS" BASIS,
12+
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
See the License for the specific language governing permissions and
14+
limitations under the License.
15+
*/
16+
17+
package flagutil
18+
19+
import (
20+
"errors"
21+
"strconv"
22+
"time"
23+
24+
"github.com/spf13/pflag"
25+
)
26+
27+
// FloatOrDuration is a flag that can be set with either a float64 (interpreted as seconds) or a time.Duration
28+
// The parsed value is stored in the Duration field, and the target pointer is updated with the parsed value
29+
type FloatOrDuration struct {
30+
Target *time.Duration // Pointer to the external duration
31+
Duration time.Duration // Stores the current parsed value
32+
}
33+
34+
// String returns the current value as a string
35+
func (f *FloatOrDuration) String() string {
36+
return f.Duration.String()
37+
}
38+
39+
// Set parses the input and updates the duration
40+
func (f *FloatOrDuration) Set(value string) error {
41+
// Try to parse as float64 first (interpreted as seconds)
42+
if floatVal, err := strconv.ParseFloat(value, 64); err == nil {
43+
f.Duration = time.Duration(floatVal * float64(time.Second))
44+
*f.Target = f.Duration // Update the target pointer
45+
return nil
46+
}
47+
48+
// Try to parse as time.Duration
49+
if duration, err := time.ParseDuration(value); err == nil {
50+
f.Duration = duration
51+
*f.Target = f.Duration // Update the target pointer
52+
return nil
53+
}
54+
55+
return errors.New("value must be either a float64 (interpreted as seconds) or a valid time.Duration")
56+
}
57+
58+
// Type returns the type description
59+
func (f *FloatOrDuration) Type() string {
60+
return "time.Duration"
61+
}
62+
63+
// FloatDuration defines a flag with the specified name, default value, and usage string and binds it to a time.Duration variable.
64+
func FloatDuration(fs *pflag.FlagSet, p *time.Duration, name string, defaultValue time.Duration, usage string) {
65+
*p = defaultValue
66+
fd := FloatOrDuration{
67+
Target: p,
68+
Duration: defaultValue,
69+
}
70+
fs.Var(&fd, name, usage)
71+
}
Lines changed: 104 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,104 @@
1+
/*
2+
Copyright 2024 The Vitess Authors.
3+
4+
Licensed under the Apache License, Version 2.0 (the "License");
5+
you may not use this file except in compliance with the License.
6+
You may obtain a copy of the License at
7+
8+
http://www.apache.org/licenses/LICENSE-2.0
9+
10+
Unless required by applicable law or agreed to in writing, software
11+
distributed under the License is distributed on an "AS IS" BASIS,
12+
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
See the License for the specific language governing permissions and
14+
limitations under the License.
15+
*/
16+
17+
package flagutil
18+
19+
import (
20+
"testing"
21+
"time"
22+
23+
"github.com/spf13/pflag"
24+
"github.com/stretchr/testify/assert"
25+
)
26+
27+
// TestFloatOrDuration_ValidFloat64Input verifies that a float64 input
28+
// (representing seconds) is correctly converted to a time.Duration.
29+
func TestFloatOrDuration_ValidFloat64Input(t *testing.T) {
30+
var duration time.Duration
31+
fs := pflag.NewFlagSet("test", pflag.ContinueOnError)
32+
33+
FloatDuration(fs, &duration, "test_flag", 10*time.Second, "Test flag")
34+
err := fs.Parse([]string{"--test_flag=2"})
35+
assert.NoError(t, err)
36+
assert.Equal(t, 2*time.Second, duration)
37+
}
38+
39+
// TestFloatOrDuration_ValidDurationInput verifies that a valid time.Duration
40+
// input (e.g., "1m30s") is parsed and stored correctly.
41+
func TestFloatOrDuration_ValidDurationInput(t *testing.T) {
42+
var duration time.Duration
43+
fs := pflag.NewFlagSet("test", pflag.ContinueOnError)
44+
45+
FloatDuration(fs, &duration, "test_flag", 10*time.Second, "Test flag")
46+
err := fs.Parse([]string{"--test_flag=1m30s"})
47+
assert.NoError(t, err)
48+
assert.Equal(t, 90*time.Second, duration)
49+
}
50+
51+
// TestFloatOrDuration_DefaultValue ensures that the default value is correctly
52+
// assigned to the duration when the flag is not provided.
53+
func TestFloatOrDuration_DefaultValue(t *testing.T) {
54+
var duration time.Duration
55+
fs := pflag.NewFlagSet("test", pflag.ContinueOnError)
56+
57+
defaultValue := 15 * time.Second
58+
FloatDuration(fs, &duration, "test_flag", defaultValue, "Test flag")
59+
err := fs.Parse([]string{})
60+
assert.NoError(t, err)
61+
assert.Equal(t, defaultValue, duration)
62+
}
63+
64+
// TestFloatOrDuration_InvalidInput verifies that an invalid input string
65+
// results in an appropriate error.
66+
func TestFloatOrDuration_InvalidInput(t *testing.T) {
67+
var duration time.Duration
68+
fs := pflag.NewFlagSet("test", pflag.ContinueOnError)
69+
70+
FloatDuration(fs, &duration, "test_flag", 10*time.Second, "Test flag")
71+
err := fs.Parse([]string{"--test_flag=invalid"})
72+
assert.Error(t, err)
73+
assert.Contains(t, err.Error(), "value must be either a float64 (interpreted as seconds) or a valid time.Duration")
74+
}
75+
76+
// TestFloatOrDuration_MultipleFlags ensures that multiple FloatDuration flags
77+
// can coexist and maintain independent values.
78+
func TestFloatOrDuration_MultipleFlags(t *testing.T) {
79+
var duration1, duration2 time.Duration
80+
fs := pflag.NewFlagSet("test", pflag.ContinueOnError)
81+
82+
FloatDuration(fs, &duration1, "flag1", 10*time.Second, "First test flag")
83+
FloatDuration(fs, &duration2, "flag2", 20*time.Second, "Second test flag")
84+
85+
err := fs.Parse([]string{"--flag1=2.5", "--flag2=1m"})
86+
assert.NoError(t, err)
87+
assert.Equal(t, 2500*time.Millisecond, duration1)
88+
assert.Equal(t, 1*time.Minute, duration2)
89+
}
90+
91+
// TestFloatOrDuration_HelpMessage verifies that the help message includes
92+
// the correct flag name, description, and default value.
93+
func TestFloatOrDuration_HelpMessage(t *testing.T) {
94+
var duration time.Duration
95+
fs := pflag.NewFlagSet("test", pflag.ContinueOnError)
96+
97+
defaultValue := 10 * time.Second
98+
FloatDuration(fs, &duration, "test_flag", defaultValue, "Test flag with default value")
99+
100+
helpOutput := fs.FlagUsages()
101+
assert.Contains(t, helpOutput, "--test_flag time.Duration")
102+
assert.Contains(t, helpOutput, "Test flag with default value")
103+
assert.Contains(t, helpOutput, "(default 10s)")
104+
}

go/test/endtoend/tabletmanager/main_test.go

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -105,7 +105,6 @@ func TestMain(m *testing.M) {
105105
"--heartbeat_enable",
106106
"--health_check_interval", tabletHealthcheckRefreshInterval.String(),
107107
"--unhealthy_threshold", tabletUnhealthyThreshold.String(),
108-
"--twopc_enable",
109108
"--twopc_abandon_age", "200",
110109
}
111110

go/test/endtoend/transaction/twopc/fuzz/main_test.go

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -70,7 +70,6 @@ func TestMain(m *testing.M) {
7070
"--tablet_refresh_interval", "2s",
7171
)
7272
clusterInstance.VtTabletExtraArgs = append(clusterInstance.VtTabletExtraArgs,
73-
"--twopc_enable",
7473
"--twopc_abandon_age", "1",
7574
"--migration_check_interval", "2s",
7675
)

go/test/endtoend/transaction/twopc/main_test.go

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -82,7 +82,6 @@ func TestMain(m *testing.M) {
8282
"--grpc_use_effective_callerid",
8383
)
8484
clusterInstance.VtTabletExtraArgs = append(clusterInstance.VtTabletExtraArgs,
85-
"--twopc_enable",
8685
"--twopc_abandon_age", "1",
8786
"--queryserver-config-transaction-cap", "3",
8887
"--queryserver-config-transaction-timeout", "400s",

go/test/endtoend/transaction/twopc/metric/main_test.go

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -69,7 +69,6 @@ func TestMain(m *testing.M) {
6969
"--grpc_use_effective_callerid",
7070
)
7171
clusterInstance.VtTabletExtraArgs = append(clusterInstance.VtTabletExtraArgs,
72-
"--twopc_enable",
7372
"--twopc_abandon_age", "1",
7473
"--queryserver-config-transaction-cap", "100",
7574
)

go/test/endtoend/transaction/twopc/stress/main_test.go

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -70,7 +70,6 @@ func TestMain(m *testing.M) {
7070
"--tablet_refresh_interval", "2s",
7171
)
7272
clusterInstance.VtTabletExtraArgs = append(clusterInstance.VtTabletExtraArgs,
73-
"--twopc_enable",
7473
"--twopc_abandon_age", "1",
7574
"--migration_check_interval", "2s",
7675
"--onterm_timeout", "1s",

0 commit comments

Comments
 (0)