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: Implement ALTER TABLE ... LOCALITY REGIONAL BY TABLE from GLOBAL #59407

Merged
merged 2 commits into from Jan 28, 2021

Conversation

ajstorm
Copy link
Collaborator

@ajstorm ajstorm commented Jan 25, 2021

Implements ALTER TABLE ... LOCALITY REGIONAL BY TABLE (all permutations)
from LOCALITY GLOBAL.

Release note (sql change): Implements ALTER TABLE ... LOCALITY REGIONAL
BY TABLE from LOCALITY GLOBAL.

Resolves #58343.
Also resolves #59249.

@ajstorm ajstorm requested a review from otan January 25, 2021 21:54
@cockroach-teamcity
Copy link
Member

This change is Reviewable

@ajstorm ajstorm force-pushed the ajstorm-even-more-alter branch 3 times, most recently from 8ae95f6 to 31fb880 Compare January 25, 2021 23:39
Copy link
Contributor

@otan otan left a comment

Choose a reason for hiding this comment

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

Resolves #58343
Also resolves #59249.

put these as separate lines in the description, and github will close the issues when this merges

}
}

func generateNewLocalityConfigForLocalityRegionalByTable(
Copy link
Contributor

Choose a reason for hiding this comment

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

nit: i'd get rid of generate or new -- generateLocalityConfigFor... or newLOcalityFor...

params runParams, dbDesc *dbdesc.Immutable, tableName tree.TableName,
) error {
const operation string = "alter table locality REGIONAL BY TABLE to GLOBAL"
if err := assertIsMultiRegionDatabase(dbDesc, operation); err != nil {
Copy link
Contributor

Choose a reason for hiding this comment

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

can we do just the once at the startExec phase?

@ajstorm ajstorm force-pushed the ajstorm-even-more-alter branch 3 times, most recently from 638324b to 7e7cecb Compare January 27, 2021 02:20
Copy link
Collaborator Author

@ajstorm ajstorm left a comment

Choose a reason for hiding this comment

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

Ahh, didn't realize it had to be in the commit message. Changed.

TFTR!

Reviewable status: :shipit: complete! 0 of 0 LGTMs obtained (waiting on @arulajmani and @otan)


pkg/sql/alter_table_locality.go, line 108 at r2 (raw file):

Previously, otan (Oliver Tan) wrote…

can we do just the once at the startExec phase?

I was worried about the helper functions being called from elsewhere, but considering that they're methods of the alterTableSetLocalityNode, that fear seems to be unwarranted. I've removed the checks from the helpers.


pkg/sql/alter_table_locality.go, line 280 at r2 (raw file):

Previously, otan (Oliver Tan) wrote…

nit: i'd get rid of generate or new -- generateLocalityConfigFor... or newLOcalityFor...

You're in luck - these helper methods will be gone once I rebase with @arulajmani's changes.

@otan
Copy link
Contributor

otan commented Jan 27, 2021

not commit message, just PR description

(personal nit but putting it in the commit messages spams the issue with commit hashes)

@ajstorm
Copy link
Collaborator Author

ajstorm commented Jan 27, 2021

Taking them out also spams the issue :-P

They're out now. Will use PR technique going forward.

@ajstorm ajstorm force-pushed the ajstorm-even-more-alter branch 3 times, most recently from 44d78bd to b30d3f4 Compare January 27, 2021 20:58
@ajstorm
Copy link
Collaborator Author

ajstorm commented Jan 27, 2021

@arulajmani Merge is done now. When you have time, PTAL.

Copy link
Collaborator

@arulajmani arulajmani left a comment

Choose a reason for hiding this comment

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

Reviewable status: :shipit: complete! 0 of 0 LGTMs obtained (waiting on @ajstorm, @arulajmani, and @otan)


pkg/sql/alter_table_locality.go, line 76 at r6 (raw file):

	params runParams, dbDesc *dbdesc.Immutable, tableName tree.TableName,
) error {
	const operation string = "alter table locality GLOBAL to REGIONAL BY TABLE"

nit: we can just move this inline


pkg/sql/alter_table_locality.go, line 81 at r6 (raw file):

			"invalid call %q on incorrect table locality. %v",
			operation,
			n.tableDesc.LocalityConfig,

I don't like the idea of printing the entire locality config here (which is quite unreadable because of how nested it is). Can we instead use the FormatLocalityConfig here?


pkg/sql/alter_table_locality.go, line 87 at r6 (raw file):

	n.tableDesc.SetTableLocalityRegionalByTable(n.n.Locality.TableRegion)

	// Finalize the alter by writing a new table descriptor and updating the zone configuration.

nit: could you wrap this comment at 80 chars please.


pkg/sql/alter_table_locality.go, line 113 at r6 (raw file):

	n.tableDesc.SetTableLocalityGlobal()

	// Finalize the alter by writing a new table descriptor and updating the zone configuration.

nit: 80 chars 😅


pkg/sql/alter_table_locality.go, line 170 at r6 (raw file):

	// Get the fully resolved table name for use in the calls below.
	resolvedSchema, err := params.p.Descriptors().GetImmutableSchemaByID(

I like that we've moved this thing to one place, instead of duplicating it in a bunch of places as before. I think it'll be cleaner if we move this (and tableName below) to validateAndWriteNewTableLocalityAndZoneConfig instead. That way, we don't have to pass this around in all the locality change functions (and we're constructing this closer to its use).


pkg/sql/alter_table_locality.go, line 249 at r6 (raw file):

}

// validateAndWriteNewTableLocalityAndZoneConfig validates the newly updated LocalityConfig

nit: could you wrap this comment to 80 chars please.


pkg/sql/alter_table_locality.go, line 275 at r6 (raw file):

	// Update the zone configuration.
	if err := params.p.applyZoneConfigFromTableLocalityConfig(

nit: you can just return the function call here as opposed to if err := ...

Copy link
Collaborator Author

@ajstorm ajstorm left a comment

Choose a reason for hiding this comment

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

TFTR! Changes made below

Reviewable status: :shipit: complete! 0 of 0 LGTMs obtained (waiting on @arulajmani and @otan)


pkg/sql/alter_table_locality.go, line 76 at r6 (raw file):

Previously, arulajmani (Arul Ajmani) wrote…

nit: we can just move this inline

Done


pkg/sql/alter_table_locality.go, line 81 at r6 (raw file):

Previously, arulajmani (Arul Ajmani) wrote…

I don't like the idea of printing the entire locality config here (which is quite unreadable because of how nested it is). Can we instead use the FormatLocalityConfig here?

I'm assuming you mean FormatTableLocalityConfig. If so, Done. If not 🤷‍♂️


pkg/sql/alter_table_locality.go, line 87 at r6 (raw file):

Previously, arulajmani (Arul Ajmani) wrote…

nit: could you wrap this comment at 80 chars please.

Happy to do this, but is this formalized anywhere? I'm pretty sure I have many more comments that are longer than 80 chars. I also just now went down a deep rabbit hole about standardization of line length. While we do lint for line length (at 100 chars), I don't see any linting (or mention of linting) around comments. In fact, internal documentation around commenting style presents examples where the comments are longer than 80 chars.

Again, no objection, but if we're going to suggest this in code reviews, we should write it down somewhere. Maybe in the code commenting guidelines in Confluence? That being said, that would only be visible to CRL members. Ideally, we'd want this in the repo somewhere.

Oh, and BTW, done. 😄


pkg/sql/alter_table_locality.go, line 113 at r6 (raw file):

Previously, arulajmani (Arul Ajmani) wrote…

nit: 80 chars 😅

Done.


pkg/sql/alter_table_locality.go, line 170 at r6 (raw file):

Previously, arulajmani (Arul Ajmani) wrote…

I like that we've moved this thing to one place, instead of duplicating it in a bunch of places as before. I think it'll be cleaner if we move this (and tableName below) to validateAndWriteNewTableLocalityAndZoneConfig instead. That way, we don't have to pass this around in all the locality change functions (and we're constructing this closer to its use).

Good call! I refactored this code a bunch of times and didn't realize at the end that tableName only got used in validate. Fixed.


pkg/sql/alter_table_locality.go, line 249 at r6 (raw file):

Previously, arulajmani (Arul Ajmani) wrote…

nit: could you wrap this comment to 80 chars please.

Done.


pkg/sql/alter_table_locality.go, line 275 at r6 (raw file):

Previously, arulajmani (Arul Ajmani) wrote…

nit: you can just return the function call here as opposed to if err := ...

I'm inclined to leave it as is. What I worry about is if someone later comes along and has to make a call after the applyZoneConfig call, if they don't change the return, then their call will get silently skipped. You'd think the compiler would catch this, but it's only a warning.

I think it's fine for stuff like logEvent, which should always be the last line of the function.

Copy link
Collaborator

@arulajmani arulajmani left a comment

Choose a reason for hiding this comment

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

Thanks for making the changes! :shipit:

Reviewable status: :shipit: complete! 0 of 0 LGTMs obtained (waiting on @ajstorm, @arulajmani, and @otan)


pkg/sql/alter_table_locality.go, line 81 at r6 (raw file):

Previously, ajstorm wrote…

I'm assuming you mean FormatTableLocalityConfig. If so, Done. If not 🤷‍♂️

Yeah that's what I meant, my bad on mistyping.


pkg/sql/alter_table_locality.go, line 87 at r6 (raw file):

Previously, ajstorm wrote…

Happy to do this, but is this formalized anywhere? I'm pretty sure I have many more comments that are longer than 80 chars. I also just now went down a deep rabbit hole about standardization of line length. While we do lint for line length (at 100 chars), I don't see any linting (or mention of linting) around comments. In fact, internal documentation around commenting style presents examples where the comments are longer than 80 chars.

Again, no objection, but if we're going to suggest this in code reviews, we should write it down somewhere. Maybe in the code commenting guidelines in Confluence? That being said, that would only be visible to CRL members. Ideally, we'd want this in the repo somewhere.

Oh, and BTW, done. 😄

It's in the style guide here: https://cockroachlabs.atlassian.net/wiki/spaces/CRDB/pages/181371303/Go+coding+guidelines#Gocodingguidelines-LineLengthO


pkg/sql/alter_table_locality.go, line 170 at r6 (raw file):

Previously, ajstorm wrote…

Good call! I refactored this code a bunch of times and didn't realize at the end that tableName only got used in validate. Fixed.

🙌


pkg/sql/alter_table_locality.go, line 275 at r6 (raw file):

You'd think the compiler would catch this, but it's only a warning.

Doesn't the IDE shout at you though? FWIW I think this is one of those things that we strive to do as much as possible in our code, anecdotally from a bunch of reviews I've gotten, but we sometimes things slip by.


pkg/sql/alter_table_locality.go, line 81 at r8 (raw file):

			// While we're in an error path and generally it's bad to return a
			// different error in an error path, we will only get an error here if the
			// locality is corrupted, in which case, it's probably the right error

Maybe this is for another PR, but I'm wondering if FormatTableLocalityConfig should return an error at all. Rather, this might just benefit from returning an invalid locality string instead if the table locality is of the wrong type (which shouldn't really happen, as validation of the table desc should ensure the locality is type is sane, if it doesn't do so already). Lemme know if you're on board with this and I'll make this change the next time I'm around here.

Copy link
Collaborator Author

@ajstorm ajstorm left a comment

Choose a reason for hiding this comment

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

Reviewable status: :shipit: complete! 0 of 0 LGTMs obtained (waiting on @ajstorm, @arulajmani, and @otan)


pkg/sql/alter_table_locality.go, line 87 at r6 (raw file):

Previously, arulajmani (Arul Ajmani) wrote…

It's in the style guide here: https://cockroachlabs.atlassian.net/wiki/spaces/CRDB/pages/181371303/Go+coding+guidelines#Gocodingguidelines-LineLengthO

TIL! 😄


pkg/sql/alter_table_locality.go, line 275 at r6 (raw file):

Previously, arulajmani (Arul Ajmani) wrote…

You'd think the compiler would catch this, but it's only a warning.

Doesn't the IDE shout at you though? FWIW I think this is one of those things that we strive to do as much as possible in our code, anecdotally from a bunch of reviews I've gotten, but we sometimes things slip by.

The IDE "shouts" by highlighting the call in yellow. Very easy to miss.


pkg/sql/alter_table_locality.go, line 81 at r8 (raw file):

Previously, arulajmani (Arul Ajmani) wrote…

Maybe this is for another PR, but I'm wondering if FormatTableLocalityConfig should return an error at all. Rather, this might just benefit from returning an invalid locality string instead if the table locality is of the wrong type (which shouldn't really happen, as validation of the table desc should ensure the locality is type is sane, if it doesn't do so already). Lemme know if you're on board with this and I'll make this change the next time I'm around here.

I thought that too earlier today. The problem is that in some of the cases where it's used, it's better to return the error than print "INVALID LOCALITY". For instance, look at the call in showCreateLocality(). There's also the call in ValidateTableLocalityConfig(). That call does what you're suggesting, but I'd argue that's the wrong thing to do here as we're (somewhat) silently ignoring database corruption. As I've done here, I think we need to return the right (and far worse) error here. That being said, if you're looking for a follow-on project, I'd clean up the callers that are silently eating the error.

@ajstorm
Copy link
Collaborator Author

ajstorm commented Jan 28, 2021

TFTR all.

bors r=arulajmani, otan

Copy link
Collaborator

@arulajmani arulajmani left a comment

Choose a reason for hiding this comment

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

Reviewable status: :shipit: complete! 0 of 0 LGTMs obtained (waiting on @ajstorm, @arulajmani, and @otan)


pkg/sql/alter_table_locality.go, line 81 at r8 (raw file):

Previously, ajstorm wrote…

I thought that too earlier today. The problem is that in some of the cases where it's used, it's better to return the error than print "INVALID LOCALITY". For instance, look at the call in showCreateLocality(). There's also the call in ValidateTableLocalityConfig(). That call does what you're suggesting, but I'd argue that's the wrong thing to do here as we're (somewhat) silently ignoring database corruption. As I've done here, I think we need to return the right (and far worse) error here. That being said, if you're looking for a follow-on project, I'd clean up the callers that are silently eating the error.

That call does what you're suggesting, but I'd argue that's the wrong thing to do here as we're (somewhat) silently ignoring database corruption.

It's not really database corruption though -- this can only happen if someone added a new type of locality config but forgot to add a case for it in the FormatTableLocalityConfig method.

Copy link
Collaborator Author

@ajstorm ajstorm left a comment

Choose a reason for hiding this comment

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

Reviewable status: :shipit: complete! 0 of 0 LGTMs obtained (waiting on @ajstorm, @arulajmani, and @otan)


pkg/sql/alter_table_locality.go, line 81 at r8 (raw file):

Previously, arulajmani (Arul Ajmani) wrote…

That call does what you're suggesting, but I'd argue that's the wrong thing to do here as we're (somewhat) silently ignoring database corruption.

It's not really database corruption though -- this can only happen if someone added a new type of locality config but forgot to add a case for it in the FormatTableLocalityConfig method.

True, that can also occur. The case I'm more worried about though, is that the proto gets corrupted and we get some garbage value back here. Isn't that possible as well?

Copy link
Collaborator

@arulajmani arulajmani left a comment

Choose a reason for hiding this comment

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

Reviewable status: :shipit: complete! 0 of 0 LGTMs obtained (waiting on @ajstorm, @arulajmani, and @otan)


pkg/sql/alter_table_locality.go, line 81 at r8 (raw file):

Previously, ajstorm wrote…

True, that can also occur. The case I'm more worried about though, is that the proto gets corrupted and we get some garbage value back here. Isn't that possible as well?

Theoretically, yes, but there's more pressing concerns if storage gets corrupted. We have a replica consistency checker, which will crash the node if it detects that one of the replicas doesn't hash the same as other replicas of the same range.

@craig
Copy link
Contributor

craig bot commented Jan 28, 2021

Build failed:

@ajstorm
Copy link
Collaborator Author

ajstorm commented Jan 28, 2021

Had to rebase. Trying again...

bors r=arulajmani,otan

Copy link
Collaborator Author

@ajstorm ajstorm left a comment

Choose a reason for hiding this comment

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

Reviewable status: :shipit: complete! 0 of 0 LGTMs obtained (waiting on @ajstorm, @arulajmani, and @otan)


pkg/sql/alter_table_locality.go, line 81 at r8 (raw file):

Previously, arulajmani (Arul Ajmani) wrote…

Theoretically, yes, but there's more pressing concerns if storage gets corrupted. We have a replica consistency checker, which will crash the node if it detects that one of the replicas doesn't hash the same as other replicas of the same range.

Let's bikeshed on Slack. Corruption or no corruption, I think returning the error is better than silently mapping it to an "INVALID LOCALITY" string, which in theory could get missed by human readers, and even perhaps some testcases.

@craig
Copy link
Contributor

craig bot commented Jan 28, 2021

Build failed (retrying...):

Implements ALTER TABLE ... LOCALITY REGIONAL BY TABLE (all permutations)
from LOCALITY GLOBAL.

Release note (sql change): Implements ALTER TABLE ... LOCALITY REGIONAL
BY TABLE from LOCALITY GLOBAL.
Changed the ordering of the regions in SHOW REGIONS FROM DATABASE so
that the PRIMARY REGION is at the top.

Release note: None
@craig
Copy link
Contributor

craig bot commented Jan 28, 2021

Canceled.

@ajstorm
Copy link
Collaborator Author

ajstorm commented Jan 28, 2021

Merge problems fixed.

bors r=arulajmani,otan

@craig
Copy link
Contributor

craig bot commented Jan 28, 2021

Build succeeded:

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
4 participants