Skip to content

Purge (micro)schema versions#1753

Open
plyhun wants to merge 19 commits into
devfrom
f-gpu-2209
Open

Purge (micro)schema versions#1753
plyhun wants to merge 19 commits into
devfrom
f-gpu-2209

Conversation

@plyhun

@plyhun plyhun commented Mar 24, 2026

Copy link
Copy Markdown
Contributor

Abstract

To same database time/space, we could delete empty versions.

Checklist

General

  • Added abstract that describes the change
  • Added changelog entry to /CHANGELOG.adoc
  • Ensured that the change is covered by tests
  • Ensured that the change is documented in the docs

On API Changes

  • Checked if the changes are breaking or not
  • Added GraphQL API if applicable
  • Added Elasticsearch mapping if applicable

@plyhun plyhun requested a review from npomaroli March 24, 2026 15:45
@plyhun plyhun self-assigned this Mar 24, 2026
@@ -1,140 +0,0 @@
package com.gentics.mesh.core.project.maintenance;

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

Completely unused. The correct implementation of ProjectVersionPurgeHandler is loaded elsewhere.

// truncate the error detail message to the max length for the error detail property
setErrorDetail(truncateStackTrace(stackTrace));
setErrorMessage(e.getMessage());
setErrorMessage(StringUtils.substring(e.getMessage(), 0, 255));

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

DB limits overflow.

}
if (version.getPreviousVersion() != null) {
version.getPreviousVersion().setNextVersion(null);
version.getPreviousVersion().setNextVersion(version.getNextVersion());

@plyhun plyhun Mar 24, 2026

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

Bug in version removal. Worth porting to hotfix.

if (status != null) {
boolean allMatching = true;
for (JobResponse info : response.getData()) {
if (before.getData().stream().anyMatch(j -> Objects.equal(j.getUuid(), info.getUuid()))) {

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

We count only new jobs.


@Parameters(name = "{index}: {0}")
public static Collection<Object[]> parameters() {
return List.of(new Object[] { 0 }, new Object[] { 1 }, new Object[] { 2 }, new Object[] { 5 }, new Object[] { 8 });

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

Random meaningful numbers, including 1 (nothing to clean) and 0 (no changes).

}

@Test
@Category({FailingTests.class})

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

Not anymore failing.

Updated the changelog entry to specify that the purge process saves storage resources.
* @param version
* @return
*/
Stream<? extends HibNodeFieldContainer> getFieldsContainers(HibSchemaVersion version);

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Reading all contents for a schema version is extremely inefficient. Also this method is apparently not used anywhere, so better remove it.

* @param version
* @return
*/
Stream<? extends HibMicronode> getFieldsContainers(HibMicroschemaVersion version);

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Same comment as above. This method is used from PersistingMicroschemaDao.delete(HibMicroschema), but only to check, whether there is still a micronode using a specific version (before deleting it). There are better methods to check this.

.map(version -> version.getUuid())
.collect(Collectors.toSet());

containerDao.findAll().stream()

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

This seems to be inefficient and to produce long lasting db locks.
I tested with a database containing a schema with 22.000 versions. The job was running for several minutes until I gave up (there is no visible progress information). During that time, some requests (like getting the schemas for a specific branch) were hanging.

crudHandler.handleDelete(ac, uuid);
}, isOrderedBlockingHandlers());

InternalEndpointRoute purgeVersionsEndpoint = createRoute();

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Using the endpoint DELETE /api/v2/schemas for purging unused schema versions is counterintuitive (same for micoschemas).

plyhun and others added 3 commits April 1, 2026 09:59
Updated the purge process for schemas and microschemas to use new REST API endpoints, allowing for parameterization by schema name/UUID filters.
@@ -0,0 +1,2 @@
Core: Now it is possible to purge empty (micro)schema versions automatically, via new background jobs. This will save storage and runtime resources of the database.
The purge process is triggered via REST API `POST /utilities/purge/schemas/versions` and `POST /utilities/purge/microschemas/versions` respectively, and can be parameterized by schema name/UUID filters.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

The calls have to be moved to /utilities because of POST /schemas/{uuid} taking over the /schemas/purge calls

endpoint.exampleRequest(microschemaExamples.getGeolocationMicroschemaCreateRequest());
endpoint.exampleResponse(OK, utilityExamples.createValidationResponse(), "The validation report");
endpoint.blockingHandler(rc -> {
private void addValidationHandler() {

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

Endpoints grouped.

/**
* Set the job start query.
*/
void setQuery(String query);

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

General purpose job query.

@plyhun plyhun requested a review from npomaroli April 1, 2026 08:52
purgeSchemaVersionsEndpoint.method(POST);
purgeSchemaVersionsEndpoint.description("Purge the unused schema versions.");
purgeSchemaVersionsEndpoint.consumes(APPLICATION_JSON);
purgeSchemaVersionsEndpoint.exampleRequest(miscExamples.createNameOrUuidsRequest());

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

I favored a POST body over query parameters request, as it can hold more values, if required. Matter of a discussion though.


@Override
public void beforeVersionDeletedFromDatabase(HibMicroschemaVersion version) {
HibernateTx tx = HibernateTx.get();

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

It really looks to me that no one had ever tested the deletion of microschema versions until this moment.

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.

2 participants