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

Fix garbage collection not working properly and add periodic jemalloc purge #1471

Merged
merged 19 commits into from Nov 14, 2023

Conversation

imilinovic
Copy link
Contributor

@imilinovic imilinovic commented Nov 7, 2023

Fix garbage collection not working properly, add periodic jemalloc memory purge

[master < Epic] PR

  • Check, and update documentation if necessary
  • Write E2E tests
  • Compare the benchmarking results between the master branch and the Epic branch
  • Provide the full content or a guide for the final git message

[master < Task] PR

  • Check, and update documentation if necessary
  • Provide the full content or a guide for the final git message

This fixes Issue1220

To keep docs changelog up to date, one more thing to do:

  • Write a release note here, including added/changed clauses
  • Tag someone from docs team in the comments

@imilinovic imilinovic self-assigned this Nov 7, 2023
@imilinovic imilinovic added bug bug community community Docs unnecessary Docs unnecessary memory and removed Docs unnecessary Docs unnecessary labels Nov 7, 2023
@imilinovic imilinovic added the Docs needed Docs needed label Nov 8, 2023
@imilinovic imilinovic marked this pull request as ready for review November 8, 2023 08:28
Copy link
Contributor

@antepusic antepusic left a comment

Choose a reason for hiding this comment

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

Good work! I’ve left a few comments, answer appreciated 🙏

src/storage/v2/inmemory/storage.hpp Outdated Show resolved Hide resolved
src/storage/v2/inmemory/storage.cpp Show resolved Hide resolved
src/storage/v2/inmemory/storage.cpp Show resolved Hide resolved
src/storage/v2/inmemory/storage.cpp Outdated Show resolved Hide resolved
src/flags/general.cpp Outdated Show resolved Hide resolved
src/flags/general.cpp Outdated Show resolved Hide resolved
src/storage/v2/config.hpp Outdated Show resolved Hide resolved
src/storage/v2/inmemory/storage.cpp Outdated Show resolved Hide resolved
Copy link
Contributor

@as51340 as51340 left a comment

Choose a reason for hiding this comment

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

I think this is good enough. Could we add some test which will check that memory is actually reclaimed after purging it?

Copy link
Collaborator

@antoniofilipovic antoniofilipovic left a comment

Choose a reason for hiding this comment

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

Seems fine to me. The only option for me that seems possible to add a test is a stress test where we do a bunch of creates and wait for the GC cycle to kick in, so we assert that memory after gc should kick in is lower than before. Check if that is possible, and put a small gc cycle of 5 seconds, and in the meantime, you can do one FOREACH transaction. That is my idea for the test, otherwise, I am not sure

@Josipmrden
Copy link
Contributor

I'm a bit more for having this under one flag only, and not displaying to the user the info about jemalloc. Couldn't hurt since now we have both cycle seconds set to 30 seconds. I'd also add @Ignition to review this before merging.

@Josipmrden
Copy link
Contributor

PreparedQuery PrepareFreeMemoryQuery(ParsedQuery parsed_query, bool in_explicit_transaction, CurrentDB &current_db) {
  if (in_explicit_transaction) {
    throw FreeMemoryModificationInMulticommandTxException();
  }

  MG_ASSERT(current_db.db_acc_, "Free Memory query expects a current DB");
  storage::Storage *storage = current_db.db_acc_->get()->storage();

  if (storage->GetStorageMode() == storage::StorageMode::ON_DISK_TRANSACTIONAL) {
    throw FreeMemoryDisabledOnDiskStorage();
  }

  return PreparedQuery{{},
                       std::move(parsed_query.required_privileges),
                       [storage](AnyStream *stream, std::optional<int> n) -> std::optional<QueryHandlerResult> {
                         storage->FreeMemory();
                         memory::PurgeUnusedMemory();
                         return QueryHandlerResult::COMMIT;
                       },
                       RWType::NONE};
}

this is the code from the interpreter. After doing free memory, it automatically purges it so it's returned back to the process. I would then assume that we need to do both actions with one flag. User should not be concerned about what jemalloc is, and if we ever need to debug it separately, we can do so later

@gitbuda gitbuda added the Severity - S1 Severity - S1 label Nov 12, 2023
@gitbuda gitbuda added this to the mg-v2.13.0 milestone Nov 12, 2023
@antoniofilipovic
Copy link
Collaborator

@imilinovic @Josipmrden I am more than okay to have two separate threads, one for GC for our internal stuff, one for jemalloc. I think users already are impacted by jemalloc via vm.max_map_count and they can read about that already there, so it is one more config that they can set up. Also if jemalloc purge blocks the whole thread, I think it will be too slow to do gc cycles and it might be an issue later on.

@Josipmrden
Copy link
Contributor

@imilinovic @Josipmrden I am more than okay to have two separate threads, one for GC for our internal stuff, one for jemalloc. I think users already are impacted by jemalloc via vm.max_map_count and they can read about that already there, so it is one more config that they can set up. Also if jemalloc purge blocks the whole thread, I think it will be too slow to do gc cycles and it might be an issue later on.

Please discuss with @gitbuda about the feature before we merge this

Copy link
Contributor

@as51340 as51340 left a comment

Choose a reason for hiding this comment

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

💪

Copy link
Collaborator

@antoniofilipovic antoniofilipovic left a comment

Choose a reason for hiding this comment

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

💪

@imilinovic imilinovic mentioned this pull request Nov 14, 2023
8 tasks
@imilinovic
Copy link
Contributor Author

imilinovic commented Nov 14, 2023

More proactive GC deletion moved to #1508 because I found a bug in it. More info in the PR.

src/flags/general.cpp Outdated Show resolved Hide resolved
@gitbuda gitbuda modified the milestones: mg-v2.13.0, mg-v2.12.1 Nov 14, 2023
@gitbuda gitbuda merged commit ced08fd into master Nov 14, 2023
6 checks passed
@gitbuda gitbuda deleted the MG_gc_tune branch November 14, 2023 20:06
@vpavicic vpavicic added Docs - changelog only Docs - changelog only and removed Docs needed Docs needed labels Nov 16, 2023
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug bug community community Docs - changelog only Docs - changelog only memory Severity - S1 Severity - S1
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Fix deleting nodes increases memory usage & eventually crashes server as it OOM's
8 participants