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

Refactor conversionstate cleanup in Hypercore TAM #7475

Open
wants to merge 1 commit into
base: main
Choose a base branch
from

Conversation

erimatnor
Copy link
Contributor

@erimatnor erimatnor commented Nov 21, 2024

When converting a table to using Hypercore TAM, the table is rewritten using a tuple sort state. This state was allocated on the CacheMemoryContext and cleaned up in a transaction callback in case of abort.

Instead, allocate the conversion state in its own memory context, which is a child of PortalContext. That makes it possible to do clean up in a memory context callback that guarantees cleanup when the conversion command is complete or when a failure occurs.

Disable-check: force-changelog-file

@erimatnor erimatnor force-pushed the refactor-hypercore-conversionstate branch from ae5cd83 to 47ff474 Compare November 21, 2024 15:16
Copy link

codecov bot commented Nov 21, 2024

Codecov Report

Attention: Patch coverage is 75.00000% with 8 lines in your changes missing coverage. Please review.

Project coverage is 82.17%. Comparing base (59f50f2) to head (bcf3837).
Report is 618 commits behind head on main.

Files with missing lines Patch % Lines
tsl/src/hypercore/hypercore_handler.c 75.00% 3 Missing and 5 partials ⚠️
Additional details and impacted files
@@            Coverage Diff             @@
##             main    #7475      +/-   ##
==========================================
+ Coverage   80.06%   82.17%   +2.10%     
==========================================
  Files         190      230      +40     
  Lines       37181    43143    +5962     
  Branches     9450    10848    +1398     
==========================================
+ Hits        29770    35453    +5683     
- Misses       2997     3373     +376     
+ Partials     4414     4317      -97     

☔ View full report in Codecov by Sentry.
📢 Have feedback on the report? Share it here.


🚨 Try these New Features:

When converting a table to using Hypercore TAM, the table is rewritten
using a tuple sort state. This state was allocated on the
CacheMemoryContext and cleaned up in a transaction callback in case of
abort.

Instead, allocate the conversion state in its own memory context,
which is a child of PortalContext. That makes it possible to do clean
up in a memory context callback that guarantees cleanup when the
conversion command is complete or when a failure occurs.
@erimatnor erimatnor force-pushed the refactor-hypercore-conversionstate branch from 47ff474 to bcf3837 Compare November 22, 2024 07:53
@erimatnor erimatnor marked this pull request as ready for review November 22, 2024 07:53
Comment on lines +3370 to +3374
if (state->tuplesortstate)
{
tuplesort_end(state->tuplesortstate);
state->tuplesortstate = NULL;
}
Copy link
Contributor

Choose a reason for hiding this comment

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

Is it possible to test this code some way? I am not entirely sure why this is not covered by normal execution though, so might not be possible.

Copy link
Contributor Author

@erimatnor erimatnor Nov 22, 2024

Choose a reason for hiding this comment

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

I did it manually by injecting a elog(ERROR) in places where the tuplesort state is not ended. It works for those cases. Not sure how to inject errors in random places for a specific test. Any suggestions?

Comment on lines +3402 to +3405
* parent. Instead, make both the tuplesort and conversion state children
* of PortalContext. Since they are destroyed in reverse order, the memory
* context callback for the conversion state can call tuplesort_end()
* before the tuplesort is freed.
Copy link
Contributor

Choose a reason for hiding this comment

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

So, if I read this right the tuplesort and conversion state are "siblings" and in that case the order of the destruction is not imposed by the structure of the parent-child relationship, which means that the order can change if modifications are done here (for rational reasons or inadvertently).

Is it possible to make the conversion state a child of the tuplesort state? In that case the ordering would always be correct since the child context (that is, the conversion state) needs to be destroyed before the parent state (that is, the tuplesort state), but I am not sure if that leads to other problems.

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 tried it, and it is possible. But I ran into some strange issues. I can check again.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

So, the reason why making it a child is that it creates a circular memory release problem.

Basically, when tuplesort_end() is called due to normal processing, it will destroy its memory context, including child contexts first. But if the child then also calls tuplesort_end() to clean up the parent it doesn't work.

Copy link
Contributor

@mkindahl mkindahl Nov 25, 2024

Choose a reason for hiding this comment

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

Ah, IC. Thanks for checking!

tsl/src/hypercore/hypercore_handler.c Show resolved Hide resolved
Assert(state->tuplesortstate);
state->relid = RelationGetRelid(rel);
state->cb.arg = state;
/* MemoryContext trees are cleaned up bootom up, so children are freed
Copy link
Contributor Author

Choose a reason for hiding this comment

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

Suggested change
/* MemoryContext trees are cleaned up bootom up, so children are freed
/* MemoryContext trees are cleaned up bottom up, so children are freed

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

Successfully merging this pull request may close these issues.

2 participants