Skip to content
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

sql: add a SHOW TENANTS command #94734

Merged
merged 1 commit into from
Jan 12, 2023

Conversation

lidorcarmel
Copy link
Contributor

This command prints all available tenants and their status.
To get the status for replication (c2c) tenants we need to get the job info.

For example:

    [email protected]:26257/defaultdb> show tenants;
      id |   name   |                               status
    -----+----------+----------------------------------------------------------------------
       1 | system   | ACTIVE
       2 | src      | ACTIVE
       3 | dest     | REPLICATION PAUSED
       4 | dest2    | REPLICATION UNKNOWN (succeeded)
       6 | dest3    | REPLICATION UNKNOWN (job with ID 819888096954253313 does not exist)
      11 | dest4    | ACTIVE
      12 | dest5    | REPLICATING
      13 | dest6    | INITIALIZING REPLICATION
    (13 rows)

    Time: 67ms total (execution 67ms / network 0ms)

Fixes: #92641

Epic: CRDB-18749

Release note: None

@lidorcarmel lidorcarmel requested a review from a team as a code owner January 5, 2023 01:19
@lidorcarmel lidorcarmel requested a review from a team January 5, 2023 01:19
@lidorcarmel lidorcarmel requested a review from a team as a code owner January 5, 2023 01:19
@lidorcarmel lidorcarmel requested review from smg260 and renatolabs and removed request for a team January 5, 2023 01:19
@cockroach-teamcity
Copy link
Member

This change is Reviewable

@lidorcarmel lidorcarmel force-pushed the lidor_show_tenants branch 6 times, most recently from f97766d to 62c6e2b Compare January 7, 2023 00:39
@@ -161,7 +161,7 @@ func alterReplicationJobHook(
return err
}
if tenInfo.TenantReplicationJobID == 0 {
return errors.Newf("tenant %q does not have an active replication job", tenantName)
return errors.Newf("tenant %q is not a replicated tenant", tenantName)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

hmm is this change necessary? Tenant foo could have been created as a result of c2c replication, so it could be confusing to say that it is not a replicated tenant if the job ID is 0. IMO it is sufficient to say that there is no active replication job associated with this tenant and so the replication information you are trying to access is unavailable.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

not necessary in this pr, dropping.
FWIW I think we should avoid saying "job" when possible.. ( I executed SHOW TENANT WITH REPLICATION STATUS why are you mentioning jobs?).


tenants := make([]roachpb.TenantName, 0, len(rows))
for _, tenant := range rows {
// If the tenants is in the DROP state the then name is nil.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I believe tenant name can also be zero if it was created prior to V23_1TenantNames, or using the create_tenant(id) builtin.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I was assuming future tenants will always have a name, but maybe there is no need to assume that.. and also, it would be nice to show dropped tenants. anyway, changed this code to use ids instead of names.

@@ -202,6 +202,33 @@ func CreateTenantRecord(
)
}

func GetAllTenantNames(
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nit: linter might scream at you to add a comment to this exported method

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

it should! but it didn't.. fixed.

default:
return errors.Newf("unknown tenant status %s", n.tenantInfo.State)
status := fmt.Sprintf("tenant status: %s", values.tenantInfo.State)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I prefer if we leave this an error. If we see a tenant in a state other than ADD, DROP, ACTIVE then it means someone has added a state and not considered all the places it effects, so I'd rather it fail tests loudly. wdyt?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

sure, done. I don't like it that the show command just breaks when one tenant has an issue but here it's fine.


func (n *showTenantNode) getTenantValues(
params runParams, tenantName roachpb.TenantName,
) (*tenantValues, error) {
tenantRecord, err := GetTenantRecordByName(params.ctx, params.p.execCfg, params.p.Txn(), tenantName)
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

As a heads up, there is another PR in flight to make most of these commands work with either IDs or names. Not sure there is anything we want to do here other than being willing to help resolve the conflict when it occurs :D.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

got it, thanks.

@@ -93,100 +110,145 @@ func (n *showTenantNode) getTenantName(params runParams) (roachpb.TenantName, er
}

func (n *showTenantNode) startExec(params runParams) error {
tenantName, err := n.getTenantName(params)
if n.all {
names, err := GetAllTenantNames(params.ctx, params.p.execCfg, params.p.Txn())
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm wondering, instead of passing this list of names around. Could we do more of this in sql? That is, we are essentially pretty-printing the results of SELECT id, FROM system.tenants and annotating it with job details. I wonder if we could either: (1) use an iterator over a query we construct to select the correct nodes or (2) implement this as a delegated statement instead.

I'm OK doing this as a follow-up, just a little suspect of anywhere that we require passing around complete sets of user-generatable data.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

good point, as we discussed we might want to do this in a followup.

@adityamaru adityamaru self-requested a review January 10, 2023 14:22
Copy link
Contributor Author

@lidorcarmel lidorcarmel left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

unfortunately too many changes :(
PTAL
mostly - this pr now gets the list of ids, not names, which means we also show dropped tenants without a name! (I thought of putting the droppedName there but then the name would not be unique which is not fun). because of that this pr is sorting the list by tenant id (probably better than by name?).
added some tests.
thanks!!

@@ -161,7 +161,7 @@ func alterReplicationJobHook(
return err
}
if tenInfo.TenantReplicationJobID == 0 {
return errors.Newf("tenant %q does not have an active replication job", tenantName)
return errors.Newf("tenant %q is not a replicated tenant", tenantName)
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

not necessary in this pr, dropping.
FWIW I think we should avoid saying "job" when possible.. ( I executed SHOW TENANT WITH REPLICATION STATUS why are you mentioning jobs?).


func (n *showTenantNode) getTenantValues(
params runParams, tenantName roachpb.TenantName,
) (*tenantValues, error) {
tenantRecord, err := GetTenantRecordByName(params.ctx, params.p.execCfg, params.p.Txn(), tenantName)
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

got it, thanks.

default:
return errors.Newf("unknown tenant status %s", n.tenantInfo.State)
status := fmt.Sprintf("tenant status: %s", values.tenantInfo.State)
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

sure, done. I don't like it that the show command just breaks when one tenant has an issue but here it's fine.

@@ -202,6 +202,33 @@ func CreateTenantRecord(
)
}

func GetAllTenantNames(
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

it should! but it didn't.. fixed.


tenants := make([]roachpb.TenantName, 0, len(rows))
for _, tenant := range rows {
// If the tenants is in the DROP state the then name is nil.
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I was assuming future tenants will always have a name, but maybe there is no need to assume that.. and also, it would be nice to show dropped tenants. anyway, changed this code to use ids instead of names.

@@ -93,100 +110,145 @@ func (n *showTenantNode) getTenantName(params runParams) (roachpb.TenantName, er
}

func (n *showTenantNode) startExec(params runParams) error {
tenantName, err := n.getTenantName(params)
if n.all {
names, err := GetAllTenantNames(params.ctx, params.p.execCfg, params.p.Txn())
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

good point, as we discussed we might want to do this in a followup.

@lidorcarmel lidorcarmel force-pushed the lidor_show_tenants branch 6 times, most recently from f983dfc to 72c5903 Compare January 12, 2023 01:27
Copy link
Collaborator

@stevendanna stevendanna left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Overall, this seems reasonable to me. I think a few new logic tests would be great though.

@@ -201,6 +201,35 @@ func CreateTenantRecord(
)
}

// GetAllTenantIds returns all tenants in the system table, excluding those in
// the DROP state.
func GetAllTenantIds(
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

[nit] Ids -> IDs. Should this be GetAllNonDropTenantIDs?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

done.

iTenantId := uint64(tree.MustBeDInt(tenant[0]))
tenantId, err := roachpb.MakeTenantID(iTenantId)
if err != nil {
return nil, err
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We might want to make this an AssertionFailedf since it implies we allowed someone to write an invalid tenant ID into the tenants table.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

done.

@@ -76,10 +76,10 @@ id name status
statement error tenant "seven" does not exist
SHOW TENANT seven

statement error tenant "tenant-one" does not have an active replication job
query error pq: tenant "tenant-one" does not have an active replication job
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Could we add a test to this file to show the output of SHOW TENANTS?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

definitely, forgot about those.. thanks! done. also added some in the tenant datadriven test.

Copy link
Contributor Author

@lidorcarmel lidorcarmel left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

thanks! done.

@@ -201,6 +201,35 @@ func CreateTenantRecord(
)
}

// GetAllTenantIds returns all tenants in the system table, excluding those in
// the DROP state.
func GetAllTenantIds(
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

done.

@@ -76,10 +76,10 @@ id name status
statement error tenant "seven" does not exist
SHOW TENANT seven

statement error tenant "tenant-one" does not have an active replication job
query error pq: tenant "tenant-one" does not have an active replication job
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

definitely, forgot about those.. thanks! done. also added some in the tenant datadriven test.

iTenantId := uint64(tree.MustBeDInt(tenant[0]))
tenantId, err := roachpb.MakeTenantID(iTenantId)
if err != nil {
return nil, err
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

done.

@lidorcarmel lidorcarmel requested a review from a team January 12, 2023 19:34
@lidorcarmel lidorcarmel requested review from a team as code owners January 12, 2023 19:34
@lidorcarmel lidorcarmel requested a review from a team January 12, 2023 19:34
@lidorcarmel lidorcarmel requested review from a team as code owners January 12, 2023 19:34
@lidorcarmel lidorcarmel requested a review from a team January 12, 2023 19:34
@lidorcarmel lidorcarmel requested review from a team as code owners January 12, 2023 19:34
@lidorcarmel lidorcarmel requested a review from a team January 12, 2023 19:34
@lidorcarmel lidorcarmel requested a review from a team as a code owner January 12, 2023 19:34
@lidorcarmel lidorcarmel requested a review from a team January 12, 2023 19:34
@lidorcarmel lidorcarmel requested review from a team as code owners January 12, 2023 19:34
@lidorcarmel lidorcarmel requested review from a team, rharding6373 and shermanCRL and removed request for a team January 12, 2023 19:34
This command prints all available tenants and their status.
To get the status for replication (c2c) tenants we need to get the
job info.

For example:

```
[email protected]:26257/defaultdb> show tenants;
  id |   name   |                               status
-----+----------+----------------------------------------------------------------------
   1 | system   | ACTIVE
   2 | src      | ACTIVE
   3 | dest     | REPLICATION PAUSED
   4 | dest2    | REPLICATION UNKNOWN (succeeded)
   6 | dest3    | REPLICATION UNKNOWN (job with ID 819888096954253313 does not exist)
  11 | dest4    | ACTIVE
  12 | dest5    | REPLICATING
  13 | dest6    | INITIALIZING REPLICATION
(8 rows)

Time: 67ms total (execution 67ms / network 0ms)
```

Fixes: cockroachdb#92641

Epic: CRDB-18749

Release note: None
@lidorcarmel lidorcarmel merged commit c009ad7 into cockroachdb:master Jan 12, 2023
@lidorcarmel lidorcarmel deleted the lidor_show_tenants branch January 24, 2023 20:07
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

sql: implement SHOW TENANTS
4 participants