forked from cockroachdb/cockroach
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
sql/row: fix multi-range reads from PCR standby
Reads from tables with external row data (i.e. reads from a PCR standby cluster) need to use the fixed timestamp specified by the external row data. This timestamp might be different from the transaction timestamp, so we were explicitly setting BatchRequest.Timestamp in kv_batch_fetcher. The KV API only allows BatchRequest.Timestamp to be set for non-transactional requests (i.e. requests sent with a NonTransactionalSender, which is a CrossRangeTxnWrapperSender in this case). We were using a NonTransactionalSender, but this had two problems: 1. CrossRangeTxnWrapperSender in turn sends the BatchRequest with a transactional sender, which again does not allow BatchRequest.Timestamp to be set. 2. CrossRangeTxnWrapperSender uses `kv.(*Txn).CommitInBatch`, which does not provide the 1-to-1 request-response guarantee required by txnKVFetcher. It is `kv.(*Txn).Send` which provides this guarantee. Because of these two problems, whenever the txnKVFetcher would send a multi-range-spanning BatchRequest to CrossRangeTxnWrapperSender, it would either fail with a "transactional request must not set batch timestamp" error or would return an unexpected number of responses, violating the txnKVFetcher's assumed mapping from request to response. To fix both these problems, instead of using a NonTransactionalSender, change the txnKVFetcher to open a new root transaction with the correct fixed timestamp, and then use txn.Send. Fixes: cockroachdb#132608 Release note: None
- Loading branch information
Showing
3 changed files
with
137 additions
and
3 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,110 @@ | ||
// Copyright 2024 The Cockroach Authors. | ||
// | ||
// Use of this software is governed by the CockroachDB Software License | ||
// included in the /LICENSE file. | ||
|
||
package sqlccl | ||
|
||
import ( | ||
"context" | ||
"testing" | ||
|
||
"github.com/cockroachdb/cockroach/pkg/base" | ||
"github.com/cockroachdb/cockroach/pkg/sql" | ||
"github.com/cockroachdb/cockroach/pkg/sql/catalog/lease" | ||
"github.com/cockroachdb/cockroach/pkg/sql/catalog/replication" | ||
"github.com/cockroachdb/cockroach/pkg/testutils" | ||
"github.com/cockroachdb/cockroach/pkg/testutils/serverutils" | ||
"github.com/cockroachdb/cockroach/pkg/testutils/sqlutils" | ||
"github.com/cockroachdb/cockroach/pkg/util/leaktest" | ||
"github.com/cockroachdb/cockroach/pkg/util/log" | ||
"github.com/cockroachdb/errors" | ||
"github.com/stretchr/testify/require" | ||
) | ||
|
||
func TestStandbyRead(t *testing.T) { | ||
defer leaktest.AfterTest(t)() | ||
defer log.Scope(t).Close(t) | ||
|
||
testcases := []struct { | ||
standby bool | ||
stmt string | ||
expected [][]string | ||
}{ | ||
{stmt: `CREATE TABLE abc (a INT PRIMARY KEY, b INT, c JSONB)`}, | ||
{stmt: `INSERT INTO abc VALUES (1, 10, '[100]'), (3, 30, '[300]'), (5, 50, '[500]')`}, | ||
{stmt: `ALTER TABLE abc SPLIT AT VALUES (2), (4)`}, | ||
{stmt: `SELECT count(*) FROM [SHOW TABLES]`, expected: [][]string{{"1"}}}, | ||
{stmt: `SELECT count(*) FROM abc`, expected: [][]string{{"3"}}}, | ||
{standby: true, stmt: `SELECT count(*) FROM [SHOW TABLES]`, expected: [][]string{{"1"}}}, | ||
{standby: true, stmt: `SELECT count(*) FROM abc`, expected: [][]string{{"3"}}}, | ||
} | ||
|
||
ctx := context.Background() | ||
tc := serverutils.StartCluster(t, 3, /* numNodes */ | ||
base.TestClusterArgs{ | ||
ReplicationMode: base.ReplicationManual, | ||
ServerArgs: base.TestServerArgs{ | ||
DefaultTestTenant: base.TestControlsTenantsExplicitly, | ||
}, | ||
}) | ||
defer tc.Stopper().Stop(ctx) | ||
ts := tc.Server(0) | ||
|
||
_, srcDB, err := ts.TenantController().StartSharedProcessTenant(ctx, | ||
base.TestSharedProcessTenantArgs{ | ||
TenantID: serverutils.TestTenantID(), | ||
TenantName: "src", | ||
UseDatabase: "defaultdb", | ||
}, | ||
) | ||
require.NoError(t, err) | ||
dstTenant, dstDB, err := ts.TenantController().StartSharedProcessTenant(ctx, | ||
base.TestSharedProcessTenantArgs{ | ||
TenantID: serverutils.TestTenantID2(), | ||
TenantName: "dst", | ||
UseDatabase: "defaultdb", | ||
}, | ||
) | ||
require.NoError(t, err) | ||
|
||
srcRunner := sqlutils.MakeSQLRunner(srcDB) | ||
dstRunner := sqlutils.MakeSQLRunner(dstDB) | ||
dstInternal := dstTenant.InternalDB().(*sql.InternalDB) | ||
|
||
dstRunner.Exec(t, `SET CLUSTER SETTING sql.defaults.distsql = always`) | ||
dstRunner.Exec(t, `SET distsql = always`) | ||
|
||
waitForReplication := func() { | ||
now := ts.Clock().Now() | ||
err := replication.SetupOrAdvanceStandbyReaderCatalog( | ||
ctx, serverutils.TestTenantID(), now, dstInternal, dstTenant.ClusterSettings(), | ||
) | ||
if err != nil { | ||
t.Fatal(err) | ||
} | ||
now = ts.Clock().Now() | ||
lm := dstTenant.LeaseManager().(*lease.Manager) | ||
testutils.SucceedsSoon(t, func() error { | ||
if lm.GetSafeReplicationTS().Less(now) { | ||
return errors.AssertionFailedf("waiting for descriptor close timestamp to catch up") | ||
} | ||
return nil | ||
}) | ||
} | ||
|
||
for _, tc := range testcases { | ||
var runner *sqlutils.SQLRunner | ||
if tc.standby { | ||
waitForReplication() | ||
runner = dstRunner | ||
} else { | ||
runner = srcRunner | ||
} | ||
if tc.expected == nil { | ||
runner.Exec(t, tc.stmt) | ||
} else { | ||
runner.CheckQueryResultsRetry(t, tc.stmt, tc.expected) | ||
} | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters