Skip to content

sql: avoid splitting the planner when expanding sub-queries #11730

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

Merged
merged 1 commit into from
Dec 5, 2016

Conversation

knz
Copy link
Contributor

@knz knz commented Nov 30, 2016

Prior to this patch, the code that expands sub-queries would duplicate
the planner object to create the sub-query planNode's
recursively. This was perceived to be needed, as indicated by a
previous comment that had been erased in
4acdc8a, because there may be nested
sub-queries that would cause the subqueryVisitor embedded in planner
to be reset during the recursion.

The problem with this approach is that whichever leases were acquired
by the sub-queries, and embedded in the planner copy, are then lost
after the sub-query is replaced and cannot be released at the end of
the session.

This patch fixes this problem by ensuring the same planner object is
reused throughout the recursion, and preserves only the state of the
embedded subqueryVisitor across the recursive call.

A proper long-term protection against this type of issue would be to
avoid embedding visitors in the planner object, and instead managing a
cache of visitor objects if profiling shows that visitor allocation is
hurting performance.

Fixes #11701.


This change is Reviewable

@knz
Copy link
Contributor Author

knz commented Nov 30, 2016

@vivekmenezes could you guide me about how to best test this. You explain in the linked issue we can check that all leases are released. How do you propose to do this?

My proposal would be to add a new directive in our testdata input parser (in TestLogic) to forcefully/manually purge leases currently held in the planner, then use a SELECT query in the lease table just after that to see whether there are remaining entries in the lease table. What do you think about this?

@vivekmenezes
Copy link
Contributor

Look at the code in lease.go that references removeOnceDereferenced . From the logic tests we should always set this to true, that way the leases are released as soon as they are dereferenced. And then at the end of each test file query the lease table and ensure there are no records.

@vivekmenezes
Copy link
Contributor

thanks for fixing it!

@tamird
Copy link
Contributor

tamird commented Nov 30, 2016

Should there be a NoCopy in planner?


Reviewed 1 of 1 files at r1.
Review status: all files reviewed at latest revision, all discussions resolved, some commit checks failed.


Comments from Reviewable

@knz
Copy link
Contributor Author

knz commented Nov 30, 2016

@tamird yes, that's a good idea too!
(Doing so didn't uncover other unwanted copies. Yay.)

@vivekmenezes
Copy link
Contributor

golang/go#8005 (comment)

is what tamir is referring to

@tamird
Copy link
Contributor

tamird commented Nov 30, 2016

@knz
Copy link
Contributor Author

knz commented Nov 30, 2016

I've used that before, thanks

@knz knz force-pushed the fix-subquery-planning branch from 0939d00 to 5bec628 Compare November 30, 2016 22:07
@knz
Copy link
Contributor Author

knz commented Nov 30, 2016

Ok I have added the NoCopy members and a specific test. PTAL.

@knz knz force-pushed the fix-subquery-planning branch from 5bec628 to 5156138 Compare November 30, 2016 22:45
@tamird
Copy link
Contributor

tamird commented Dec 1, 2016

:lgtm:


Reviewed 4 of 4 files at r2.
Review status: all files reviewed at latest revision, 2 unresolved discussions, all commit checks successful.


pkg/sql/lease_test.go, line 646 at r2 (raw file):

			LeaseStoreTestingKnobs: csql.LeaseStoreTestingKnobs{
				RemoveOnceDereferenced: true,
				LeaseReleasedEvent: func(lease *csql.LeaseState, err error) {

s/err/_/


pkg/sql/lease_test.go, line 677 at r2 (raw file):

		t.Fatal("lease from sub-query was not released")
	case <-fooRelease:
		return

remove


Comments from Reviewable

RemoveOnceDereferenced: true,
LeaseReleasedEvent: func(lease *csql.LeaseState, err error) {
if lease.Name == "foo" {
fooRelease <- struct{}{}
Copy link
Contributor

Choose a reason for hiding this comment

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

close fooRelease

// The above SELECT has acquired a lease on the table. Now close the
// session, which should release the new lease and delete it because
// of the testing knob set above.
sqlDB.Close()
Copy link
Contributor

Choose a reason for hiding this comment

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

is this really needed?

@knz
Copy link
Contributor Author

knz commented Dec 1, 2016

TFYRs!


Review status: all files reviewed at latest revision, 4 unresolved discussions, all commit checks successful.


pkg/sql/lease_test.go, line 646 at r2 (raw file):

Previously, tamird (Tamir Duberstein) wrote…

s/err/_/

Done.


pkg/sql/lease_test.go, line 648 at r2 (raw file):

Previously, vivekmenezes wrote…

close fooRelease

Done.


pkg/sql/lease_test.go, line 668 at r2 (raw file):

Previously, vivekmenezes wrote…

is this really needed?

the leases are not released until the session is closed. Closing the connection releases the session.


pkg/sql/lease_test.go, line 677 at r2 (raw file):

Previously, tamird (Tamir Duberstein) wrote…

remove

Done.


Comments from Reviewable

@knz knz force-pushed the fix-subquery-planning branch 2 times, most recently from cb0eda1 to f5a9477 Compare December 1, 2016 09:29
@tamird
Copy link
Contributor

tamird commented Dec 1, 2016

Reviewed 1 of 1 files at r3.
Review status: all files reviewed at latest revision, 2 unresolved discussions, some commit checks pending.


Comments from Reviewable

@knz knz force-pushed the fix-subquery-planning branch from f5a9477 to 200f9eb Compare December 1, 2016 14:56
@vivekmenezes
Copy link
Contributor

:lgtm:


Review status: 4 of 5 files reviewed at latest revision, 2 unresolved discussions, some commit checks failed.


pkg/sql/lease_test.go, line 668 at r2 (raw file):

Previously, knz (kena) wrote…

the leases are not released until the session is closed. Closing the connection releases the session.

https://github.com/cockroachdb/cockroach/blob/master/pkg/sql/executor.go#L673

is where it gets released at the end of a transaction. Are you sure this is needed?


Comments from Reviewable

@RaduBerinde
Copy link
Member

LGTM

@knz knz force-pushed the fix-subquery-planning branch from 200f9eb to 9802f30 Compare December 5, 2016 12:19
@knz
Copy link
Contributor Author

knz commented Dec 5, 2016

TFYRs


Review status: 2 of 5 files reviewed at latest revision, 2 unresolved discussions.


pkg/sql/lease_test.go, line 668 at r2 (raw file):

Previously, vivekmenezes wrote…

https://github.com/cockroachdb/cockroach/blob/master/pkg/sql/executor.go#L673

is where it gets released at the end of a transaction. Are you sure this is needed?

No you are right the close was unnecessary! Thanks for hinting.


Comments from Reviewable

@knz knz force-pushed the fix-subquery-planning branch 2 times, most recently from a6e35bd to 173ea52 Compare December 5, 2016 14:00
Prior to this patch, the code that expands sub-queries would duplicate
the `planner` object to create the sub-query planNode's
recursively. This was perceived to be needed, as indicated by a
previous comment that had been erased in
4acdc8a, because there may be nested
sub-queries that would cause the `subqueryVisitor` embedded in planner
to be reset during the recursion.

The problem with this approach is that whichever leases were acquired
by the sub-queries, and embedded in the planner copy, are then lost
after the sub-query is replaced and cannot be released at the end of
the session.

This patch fixes this problem by ensuring the same planner object is
reused throughout the recursion, and preserves only the state of the
embedded `subqueryVisitor` across the recursive call.

A proper long-term protection against this type of issue would be to
avoid embedding visitors in the planner object, and instead managing a
cache of visitor objects if profiling shows that visitor allocation is
hurting performance.
@knz knz force-pushed the fix-subquery-planning branch from 173ea52 to db58a73 Compare December 5, 2016 15:14
@knz knz merged commit c832c84 into cockroachdb:master Dec 5, 2016
@knz knz deleted the fix-subquery-planning branch December 5, 2016 15:32
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: DROP DATABASE can hang forever in waitForOneVersion
4 participants