diff --git a/go/cmd/vtctldclient/command/query.go b/go/cmd/vtctldclient/command/query.go index 8232deaceb6..13d0d25f6de 100644 --- a/go/cmd/vtctldclient/command/query.go +++ b/go/cmd/vtctldclient/command/query.go @@ -23,9 +23,9 @@ import ( "vitess.io/vitess/go/cmd/vtctldclient/cli" "vitess.io/vitess/go/sqltypes" - "vitess.io/vitess/go/vt/topo/topoproto" - + querypb "vitess.io/vitess/go/vt/proto/query" vtctldatapb "vitess.io/vitess/go/vt/proto/vtctldata" + "vitess.io/vitess/go/vt/topo/topoproto" ) var ( @@ -62,6 +62,13 @@ var ( Args: cobra.ExactArgs(1), RunE: commandGetUnresolvedTransactions, } + // ConcludeTransaction makes a ConcludeTransaction gRPC call to a vtctld. + ConcludeTransaction = &cobra.Command{ + Use: "ConcludeTransaction [ ...]", + Short: "Concludes the unresolved transaction by rolling back any prepared transaction and deleting the transaction metadata record.", + Args: cobra.MinimumNArgs(1), + RunE: commandConcludeTransaction, + } ) var executeFetchAsAppOptions = struct { @@ -225,6 +232,35 @@ func commandGetUnresolvedTransactions(cmd *cobra.Command, args []string) error { return nil } +func commandConcludeTransaction(cmd *cobra.Command, args []string) error { + allArgs := cmd.Flags().Args() + shards, err := cli.ParseKeyspaceShards(allArgs[1:]) + if err != nil { + return err + } + cli.FinishedParsing(cmd) + + dtid := allArgs[0] + var participants []*querypb.Target + for _, shard := range shards { + participants = append(participants, &querypb.Target{ + Keyspace: shard.Keyspace, + Shard: shard.Name, + }) + } + _, err = client.ConcludeTransaction(commandCtx, + &vtctldatapb.ConcludeTransactionRequest{ + Dtid: dtid, + Participants: participants, + }) + if err != nil { + return err + } + fmt.Println("Successfully concluded the distributed transaction") + + return nil +} + func init() { ExecuteFetchAsApp.Flags().Int64Var(&executeFetchAsAppOptions.MaxRows, "max-rows", 10_000, "The maximum number of rows to fetch from the remote tablet.") ExecuteFetchAsApp.Flags().BoolVar(&executeFetchAsAppOptions.UsePool, "use-pool", false, "Use the tablet connection pool instead of creating a fresh connection.") @@ -244,4 +280,5 @@ func init() { Root.AddCommand(ExecuteMultiFetchAsDBA) Root.AddCommand(GetUnresolvedTransactions) + Root.AddCommand(ConcludeTransaction) }