-
Notifications
You must be signed in to change notification settings - Fork 3.7k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
spanconfigsqltranslator: introduce a pts table reader #74737
Conversation
First commit is from #74297. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Mostly looks good 💯
Reviewed 19 of 19 files at r1, 2 of 5 files at r2, all commit messages.
Reviewable status:complete! 0 of 0 LGTMs obtained (waiting on @adityamaru, @irfansharif, and @stevendanna)
pkg/spanconfig/spanconfig.go, line 247 at r2 (raw file):
// protected timestamps that apply to the different targets that can be // protected from GC. type ProtectedTimestampTableReader interface {
Now that we're only using this thing in the Translator
, and not in the Reconciler
, does this thing need to be a top level interface? Or can we contain it to the spanconfigsqltranslator
package
pkg/spanconfig/spanconfigprotectedts/protectedts_table_reader.go, line 76 at r2 (raw file):
// read from the in-memory store. type ProtectedTimestampTableReader struct { protections map[key][]hlc.Timestamp
Instead of this single map, you could instead have 3 separate fields for cluster, schema objects, and tenants instead. For schema objects/tenants you could use a map keyed by descriptor ID/tenantID. This would allow you to get rid of the key encoding scheme (and string allocations) above.
pkg/spanconfig/spanconfigprotectedts/protectedts_table_reader.go, line 124 at r2 (raw file):
} func (p *ProtectedTimestampTableReader) unmarshalProtectedTimestampRecord(
Should we make this into a decoder struct similar to what we do for system.zones
and system.descriptors
? It might be worth doing that because we'll use this thing in the sqlwatcher
as well.
pkg/spanconfig/spanconfigprotectedts/protectedts_table_reader.go, line 163 at r2 (raw file):
ctx context.Context, ptsRecordsSystemTable string, ie sqlutil.InternalExecutor, txn *kv.Txn, ) (retErr error) { getProtectedTimestampRecordStmt := fmt.Sprintf(`SELECT ts, target FROM %s`, ptsRecordsSystemTable)
Can we use the GetState
method on protectedts.Storage
instead by threading in that interface into here?
pkg/spanconfig/spanconfigprotectedts/protectedts_table_reader_test.go, line 36 at r2 (raw file):
) func TestProtectedTimestampTableReader(t *testing.T) {
You could convert this thing into a datadriven test -- it'll allow you to test things like different records that target the same schema object/tenant/cluster easily.
pkg/spanconfig/spanconfigprotectedts/protectedts_table_reader_test.go, line 66 at r2 (raw file):
// Protect the cluster. clusterProtect := s0.Clock().Now()
nit: Instead of using Now()
, you can instead create synthetic timestamps. Check out the TestBuffer
in the spanconfigsqlwatcher
package
pkg/spanconfig/spanconfigprotectedts/protectedts_table_reader_test.go, line 72 at r2 (raw file):
tenantProtect := s0.Clock().Now() mkRecordAndProtect(tenantProtect, ptpb.MakeTenantsTarget([]roachpb.TenantID{roachpb.MakeTenantID(1), roachpb.MakeTenantID(2)}))
Might be worth protecting a tenant in a separate record and ensuring that all tenant protections are returned.
080e7ae
to
5318673
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Reviewable status:
complete! 0 of 0 LGTMs obtained (waiting on @arulajmani, @irfansharif, and @stevendanna)
pkg/spanconfig/spanconfig.go, line 247 at r2 (raw file):
Previously, arulajmani (Arul Ajmani) wrote…
Now that we're only using this thing in the
Translator
, and not in theReconciler
, does this thing need to be a top level interface? Or can we contain it to thespanconfigsqltranslator
package
i don't think it needs to be a top-level interface, removed and moved into the spanconfigsqltranslator package.
pkg/spanconfig/spanconfigprotectedts/protectedts_table_reader.go, line 76 at r2 (raw file):
Previously, arulajmani (Arul Ajmani) wrote…
Instead of this single map, you could instead have 3 separate fields for cluster, schema objects, and tenants instead. For schema objects/tenants you could use a map keyed by descriptor ID/tenantID. This would allow you to get rid of the key encoding scheme (and string allocations) above.
good idea yeah, simplifies everything.
pkg/spanconfig/spanconfigprotectedts/protectedts_table_reader.go, line 124 at r2 (raw file):
Previously, arulajmani (Arul Ajmani) wrote…
Should we make this into a decoder struct similar to what we do for
system.zones
andsystem.descriptors
? It might be worth doing that because we'll use this thing in thesqlwatcher
as well.
As discussed offline, i'll bring this in the PR that sets up the rangefeed in the SQLWatcher, and come back and clean this up then.
pkg/spanconfig/spanconfigprotectedts/protectedts_table_reader.go, line 163 at r2 (raw file):
Can we use the GetState method on protectedts.Storage instead by threading in that interface into here?
Very nice catch. I think we can, the SQLTranslator which will use this reader already has an ExecCfg which in turn has a ptpb.Provider. Changed to do that instead!
pkg/spanconfig/spanconfigprotectedts/protectedts_table_reader_test.go, line 36 at r2 (raw file):
Previously, arulajmani (Arul Ajmani) wrote…
You could convert this thing into a datadriven test -- it'll allow you to test things like different records that target the same schema object/tenant/cluster easily.
Done.
pkg/spanconfig/spanconfigprotectedts/protectedts_table_reader_test.go, line 72 at r2 (raw file):
Previously, arulajmani (Arul Ajmani) wrote…
Might be worth protecting a tenant in a separate record and ensuring that all tenant protections are returned.
Done.
5318673
to
580a386
Compare
580a386
to
1715deb
Compare
Rebased, and RFAL! |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Couple of testing suggestions but otherwise
Thanks for putting in the effort to make the tests here datadriven!
Reviewed 35 of 35 files at r4, all commit messages.
Reviewable status:complete! 1 of 0 LGTMs obtained (waiting on @adityamaru, @arulajmani, @irfansharif, and @stevendanna)
pkg/spanconfig/spanconfigsqltranslator/protectedts_table_reader.go, line 39 at r4 (raw file):
ctx context.Context, txn *kv.Txn, ptsProvider protectedts.Provider, ) (*ProtectedTimestampTableReader, error) { reader := &ProtectedTimestampTableReader{
nit: Let's add an assertion failure if the passed in txn is nil?
pkg/spanconfig/spanconfigsqltranslator/testdata/ptstablereader, line 8 at r4 (raw file):
query-sql SELECT id FROM system.namespace WHERE name='db'
nit: Instead of the queries to system.namespace
below, just comment the IDs of these objects here instead.
pkg/spanconfig/spanconfigsqltranslator/testdata/ptstablereader, line 49 at r4 (raw file):
# Write a protected timestamp on tenant 2. protect id=6 ts=6 tenant 2
Maybe add another on this tenant for completeness?
pkg/spanconfig/spanconfigsqltranslator/testdata/ptstablereader, line 75 at r4 (raw file):
tablereader tenants ---- id=1 [ts=5]
nit: s/id/tenant_id/g (in the datadriven test where such output is printed) considering "id" is overloaded here.
pkg/spanconfig/spanconfigsqltranslator/testdata/ptstablereader, line 89 at r4 (raw file):
# Records on t1. tablereader schemaObject=56
Let's add a test that releases either id=1 or id=2 as well, to test that records being protected/released don't affect other records that apply to a particular ID.
1715deb
to
1864096
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Reviewable status:
complete! 1 of 0 LGTMs obtained (waiting on @arulajmani, @irfansharif, and @stevendanna)
pkg/spanconfig/spanconfigsqltranslator/protectedts_table_reader.go, line 39 at r4 (raw file):
Previously, arulajmani (Arul Ajmani) wrote…
nit: Let's add an assertion failure if the passed in txn is nil?
Since we're passing in a state now this check happens in GetState()
itself.
pkg/spanconfig/spanconfigsqltranslator/testdata/ptstablereader, line 8 at r4 (raw file):
Previously, arulajmani (Arul Ajmani) wrote…
nit: Instead of the queries to
system.namespace
below, just comment the IDs of these objects here instead.
done.
pkg/spanconfig/spanconfigsqltranslator/testdata/ptstablereader, line 49 at r4 (raw file):
Previously, arulajmani (Arul Ajmani) wrote…
Maybe add another on this tenant for completeness?
Done.
pkg/spanconfig/spanconfigsqltranslator/testdata/ptstablereader, line 75 at r4 (raw file):
Previously, arulajmani (Arul Ajmani) wrote…
nit: s/id/tenant_id/g (in the datadriven test where such output is printed) considering "id" is overloaded here.
done.
pkg/spanconfig/spanconfigsqltranslator/testdata/ptstablereader, line 89 at r4 (raw file):
Previously, arulajmani (Arul Ajmani) wrote…
Let's add a test that releases either id=1 or id=2 as well, to test that records being protected/released don't affect other records that apply to a particular ID.
Done.
@irfansharif changed the state reader to take in a |
defer spanConfigTestCluster.Cleanup() | ||
|
||
var tenant *spanconfigtestcluster.Tenant | ||
// TODO(adityamaru): When secondary tenants have a "real" |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Take the opportunity to move this test code to pkg/ccl/spanconfigccl/...; when using tenant code you need a CCL binary, and need to sit under pkg/ccl.
|
||
// ProtectedTimestampStateReader provides a target specific view of the | ||
// protected timestamp records stored in the system table. | ||
type ProtectedTimestampStateReader struct { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This doesn't need to be exported from this package, right?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
doesn't yup, changed.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
ahh can't do this because the linter doesn't like it:
exported func TestingNewProtectedTimestampStateReader returns unexported type *spanconfigsqltranslator.protectedTimestampStateReader, which can be annoying to use
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Well, you don't need that method either?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
yup removed it in the most recent push once i changed the pkg to non _test
|
||
// TenantProtectedTimestamps represents all the Protections that apply to a | ||
// tenant's keyspace. | ||
type TenantProtectedTimestamps struct { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Ditto, we don't expect to be used outside the translator package, do we?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We need it in the testing package when comparing output so had to leave it exported.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It's an internal type, right? Would using a package internal test make more sense? s/package spanconfigsqltranslator_test/package spanconfigsqltranslator
. It would let you unexport as well.
pkg/spanconfig/spanconfigsqltranslator/protectedts_state_reader.go
Outdated
Show resolved
Hide resolved
"github.com/stretchr/testify/require" | ||
) | ||
|
||
// TestProtectedTimestampStateReader is a data driven test for the |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Discussed a bit offline, but for now while we're just testing this state reader type, and given that it operates off a static ptpb.State snapshot, a simple unit test would suffice. We can graft pieces of this test we've written when hooking it up to the translator as a way to conveniently write to the protected_ts table and ensure the right span configs are generated.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Changed to a unit test, kept some of the stringer methods around for readabilty, and ease of comparison since I already had them written out.
1864096
to
dd14c03
Compare
dd14c03
to
8ac46f1
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Reviewable status:
complete! 0 of 0 LGTMs obtained (and 1 stale) (waiting on @adityamaru, @arulajmani, @irfansharif, and @stevendanna)
pkg/spanconfig/spanconfigsqltranslator/protectedts_state_reader_test.go, line 47 at r5 (raw file):
Previously, adityamaru (Aditya Maru) wrote…
Changed to a unit test, kept some of the stringer methods around for readabilty, and ease of comparison since I already had them written out.
Not to rehash what we talked about offline, but I'm not a fan of going from the datadriven test we had here before to this unit test. We're reducing coverage at worst, and reducing readability at best. Sure, you can test these things using the Translator
in a future PR, but that feels very indirect to me.
In particular, having a data driven test allows us to write multiple records to the same schema object/tenant, records that apply to various schema objects/tenants, and release records. Considering this struct responsible for transforming this state and providing accessors over it, what we had earlier provided value.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This does not feel much less readable to me. This is a pretty small component, and I think it's fine for our testing of it not have to use the full datadriven machinery. We're really only testing loadProtectedTimestampRecords
, right? (which is <20 lines of Go code.)
|
||
// TenantProtectedTimestamps represents all the Protections that apply to a | ||
// tenant's keyspace. | ||
type TenantProtectedTimestamps struct { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It's an internal type, right? Would using a package internal test make more sense? s/package spanconfigsqltranslator_test/package spanconfigsqltranslator
. It would let you unexport as well.
pkg/spanconfig/spanconfigsqltranslator/protectedts_state_reader_test.go
Outdated
Show resolved
Hide resolved
8ac46f1
to
f6cfcd8
Compare
pkg/spanconfig/spanconfigsqltranslator/protectedts_state_reader.go
Outdated
Show resolved
Hide resolved
This change introduces a `ProtectedTimestampStateReader` that provides an in-memory view of the system table that stores protected timestamp records. The `SQLTranslator` will use this table reader to generate SpanConfigs and SystemSpanConfigs in a follow up PR. Informs: cockroachdb#73727 Release note: None
f6cfcd8
to
67170ed
Compare
bazel ORM failures are unrelated TFTRs! bors r+ |
Build succeeded: |
This change introduces a
ProtectedTimestampTableReader
that provides a txn scoped, in-memory view of the system
table that stores protected timestamp records.
The
SQLTranslator
will use this table reader to generateSpanConfigs and SystemSpanConfigs in a follow up PR.
Informs: #73727
Release note: None