This is an automated email from the ASF dual-hosted git repository. cshannon pushed a commit to branch elasticity in repository https://gitbox.apache.org/repos/asf/accumulo.git
The following commit(s) were added to refs/heads/elasticity by this push: new e8688474b2 Prevent merge/delete operations when wals exist (#3903) e8688474b2 is described below commit e8688474b2e6eeda739fb67da1b6c1fc9cf9fa6b Author: Christopher L. Shannon <christopher.l.shan...@gmail.com> AuthorDate: Mon Oct 30 17:55:36 2023 -0400 Prevent merge/delete operations when wals exist (#3903) This commit updates the merge and delete rows FATE ops to verify that if tablets being processed do not have any wals This closes #3845 Co-authored-by: Keith Turner <ktur...@apache.org> --- .../server/manager/state/TabletManagementIterator.java | 7 +++++++ .../java/org/apache/accumulo/manager/TabletGroupWatcher.java | 10 +++++++++- .../apache/accumulo/manager/tableOps/merge/DeleteRows.java | 3 ++- .../apache/accumulo/manager/tableOps/merge/MergeTablets.java | 6 +++++- .../accumulo/manager/tableOps/merge/ReserveTablets.java | 12 ++++++++---- 5 files changed, 31 insertions(+), 7 deletions(-) diff --git a/server/base/src/main/java/org/apache/accumulo/server/manager/state/TabletManagementIterator.java b/server/base/src/main/java/org/apache/accumulo/server/manager/state/TabletManagementIterator.java index b44bc5d37e..76ac7576a0 100644 --- a/server/base/src/main/java/org/apache/accumulo/server/manager/state/TabletManagementIterator.java +++ b/server/base/src/main/java/org/apache/accumulo/server/manager/state/TabletManagementIterator.java @@ -69,6 +69,7 @@ import org.apache.accumulo.core.metadata.schema.MetadataSchema.TabletsSection.Se import org.apache.accumulo.core.metadata.schema.MetadataSchema.TabletsSection.SuspendLocationColumn; import org.apache.accumulo.core.metadata.schema.MetadataSchema.TabletsSection.TabletColumnFamily; import org.apache.accumulo.core.metadata.schema.TabletMetadata; +import org.apache.accumulo.core.metadata.schema.TabletOperationType; import org.apache.accumulo.core.spi.balancer.SimpleLoadBalancer; import org.apache.accumulo.core.spi.balancer.TabletBalancer; import org.apache.accumulo.core.spi.balancer.data.TabletServerId; @@ -280,6 +281,12 @@ public class TabletManagementIterator extends SkippingIterator { || (tm.getHostingGoal() == TabletHostingGoal.ONDEMAND && tm.getHostingRequested()))) { return true; } + // If the Tablet has walogs and operation id then need to return so + // TGW can bring online to process the logs + if (!tm.getLogs().isEmpty() && tm.getOperationId() != null + && tm.getOperationId().getType() == TabletOperationType.MERGING) { + return true; + } break; default: throw new AssertionError("Inconceivable! The tablet is an unrecognized state: " + state); diff --git a/server/manager/src/main/java/org/apache/accumulo/manager/TabletGroupWatcher.java b/server/manager/src/main/java/org/apache/accumulo/manager/TabletGroupWatcher.java index e0d0e5db7e..0b7902bd46 100644 --- a/server/manager/src/main/java/org/apache/accumulo/manager/TabletGroupWatcher.java +++ b/server/manager/src/main/java/org/apache/accumulo/manager/TabletGroupWatcher.java @@ -67,6 +67,7 @@ import org.apache.accumulo.core.metadata.schema.MetadataSchema.TabletsSection.Cu import org.apache.accumulo.core.metadata.schema.MetadataSchema.TabletsSection.FutureLocationColumnFamily; import org.apache.accumulo.core.metadata.schema.TabletMetadata; import org.apache.accumulo.core.metadata.schema.TabletMetadata.Location; +import org.apache.accumulo.core.metadata.schema.TabletOperationType; import org.apache.accumulo.core.security.Authorizations; import org.apache.accumulo.core.spi.balancer.data.TabletServerId; import org.apache.accumulo.core.util.TextUtil; @@ -418,7 +419,14 @@ abstract class TabletGroupWatcher extends AccumuloDaemonThread { } if (tm.getOperationId() != null) { - goal = TabletGoalState.UNASSIGNED; + // If there are still wals the tablet needs to be hosted + // to process the wals before starting the merge op + if (!tm.getLogs().isEmpty() + && tm.getOperationId().getType() == TabletOperationType.MERGING) { + goal = TabletGoalState.HOSTED; + } else { + goal = TabletGoalState.UNASSIGNED; + } } if (Manager.log.isTraceEnabled()) { diff --git a/server/manager/src/main/java/org/apache/accumulo/manager/tableOps/merge/DeleteRows.java b/server/manager/src/main/java/org/apache/accumulo/manager/tableOps/merge/DeleteRows.java index b67417f321..6413e83c14 100644 --- a/server/manager/src/main/java/org/apache/accumulo/manager/tableOps/merge/DeleteRows.java +++ b/server/manager/src/main/java/org/apache/accumulo/manager/tableOps/merge/DeleteRows.java @@ -20,6 +20,7 @@ package org.apache.accumulo.manager.tableOps.merge; import static org.apache.accumulo.core.metadata.schema.TabletMetadata.ColumnType.FILES; import static org.apache.accumulo.core.metadata.schema.TabletMetadata.ColumnType.LOCATION; +import static org.apache.accumulo.core.metadata.schema.TabletMetadata.ColumnType.LOGS; import static org.apache.accumulo.core.metadata.schema.TabletMetadata.ColumnType.OPID; import static org.apache.accumulo.core.metadata.schema.TabletMetadata.ColumnType.PREV_ROW; import static org.apache.accumulo.manager.tableOps.merge.MergeTablets.validateTablet; @@ -90,7 +91,7 @@ public class DeleteRows extends ManagerRepo { try ( var tabletsMetadata = manager.getContext().getAmple().readTablets() .forTable(range.tableId()).overlapping(range.prevEndRow(), range.endRow()) - .fetch(OPID, LOCATION, FILES, PREV_ROW).checkConsistency().build(); + .fetch(OPID, LOCATION, FILES, PREV_ROW, LOGS).checkConsistency().build(); var tabletsMutator = manager.getContext().getAmple().conditionallyMutateTablets()) { KeyExtent firstCompleteContained = null; diff --git a/server/manager/src/main/java/org/apache/accumulo/manager/tableOps/merge/MergeTablets.java b/server/manager/src/main/java/org/apache/accumulo/manager/tableOps/merge/MergeTablets.java index 8d5dbc8d7c..ddb1616f80 100644 --- a/server/manager/src/main/java/org/apache/accumulo/manager/tableOps/merge/MergeTablets.java +++ b/server/manager/src/main/java/org/apache/accumulo/manager/tableOps/merge/MergeTablets.java @@ -23,6 +23,7 @@ import static org.apache.accumulo.core.metadata.schema.TabletMetadata.ColumnType import static org.apache.accumulo.core.metadata.schema.TabletMetadata.ColumnType.FILES; import static org.apache.accumulo.core.metadata.schema.TabletMetadata.ColumnType.HOSTING_GOAL; import static org.apache.accumulo.core.metadata.schema.TabletMetadata.ColumnType.LOCATION; +import static org.apache.accumulo.core.metadata.schema.TabletMetadata.ColumnType.LOGS; import static org.apache.accumulo.core.metadata.schema.TabletMetadata.ColumnType.OPID; import static org.apache.accumulo.core.metadata.schema.TabletMetadata.ColumnType.PREV_ROW; import static org.apache.accumulo.core.metadata.schema.TabletMetadata.ColumnType.TIME; @@ -95,7 +96,7 @@ public class MergeTablets extends ManagerRepo { try (var tabletsMetadata = manager.getContext().getAmple().readTablets() .forTable(range.tableId()).overlapping(range.prevEndRow(), range.endRow()) - .fetch(OPID, LOCATION, HOSTING_GOAL, FILES, TIME, DIR, ECOMP, PREV_ROW).build()) { + .fetch(OPID, LOCATION, HOSTING_GOAL, FILES, TIME, DIR, ECOMP, PREV_ROW, LOGS).build()) { int tabletsSeen = 0; @@ -233,6 +234,9 @@ public class MergeTablets extends ManagerRepo { Preconditions.checkState(expectedTableId.equals(tabletMeta.getTableId()), "%s tablet %s has unexpected table id %s expected %s", fateStr, tabletMeta.getExtent(), tabletMeta.getTableId(), expectedTableId); + Preconditions.checkState(tabletMeta.getLogs().isEmpty(), + "%s merging tablet %s has unexpected walogs %s", fateStr, tabletMeta.getExtent(), + tabletMeta.getLogs().size()); } /** diff --git a/server/manager/src/main/java/org/apache/accumulo/manager/tableOps/merge/ReserveTablets.java b/server/manager/src/main/java/org/apache/accumulo/manager/tableOps/merge/ReserveTablets.java index 04a5511b68..87f319f633 100644 --- a/server/manager/src/main/java/org/apache/accumulo/manager/tableOps/merge/ReserveTablets.java +++ b/server/manager/src/main/java/org/apache/accumulo/manager/tableOps/merge/ReserveTablets.java @@ -19,6 +19,7 @@ package org.apache.accumulo.manager.tableOps.merge; import static org.apache.accumulo.core.metadata.schema.TabletMetadata.ColumnType.LOCATION; +import static org.apache.accumulo.core.metadata.schema.TabletMetadata.ColumnType.LOGS; import static org.apache.accumulo.core.metadata.schema.TabletMetadata.ColumnType.OPID; import static org.apache.accumulo.core.metadata.schema.TabletMetadata.ColumnType.PREV_ROW; @@ -54,7 +55,7 @@ public class ReserveTablets extends ManagerRepo { try ( var tablets = env.getContext().getAmple().readTablets().forTable(data.tableId) - .overlapping(range.prevEndRow(), range.endRow()).fetch(PREV_ROW, LOCATION, OPID) + .overlapping(range.prevEndRow(), range.endRow()).fetch(PREV_ROW, LOCATION, LOGS, OPID) .checkConsistency().build(); var tabletsMutator = env.getContext().getAmple().conditionallyMutateTablets();) { @@ -62,6 +63,7 @@ public class ReserveTablets extends ManagerRepo { int otherOps = 0; int opsSet = 0; int locations = 0; + int wals = 0; for (var tabletMeta : tablets) { @@ -77,6 +79,8 @@ public class ReserveTablets extends ManagerRepo { locations++; } + wals += tabletMeta.getLogs().size(); + count++; } @@ -84,8 +88,8 @@ public class ReserveTablets extends ManagerRepo { .filter(conditionalResult -> conditionalResult.getStatus() == Status.ACCEPTED).count(); log.debug( - "{} reserve tablets op:{} count:{} other opids:{} opids set:{} locations:{} accepted:{}", - FateTxId.formatTid(tid), data.op, count, otherOps, opsSet, locations, opsAccepted); + "{} reserve tablets op:{} count:{} other opids:{} opids set:{} locations:{} accepted:{} wals:{}", + FateTxId.formatTid(tid), data.op, count, otherOps, opsSet, locations, opsAccepted, wals); // while there are table lock a tablet can be concurrently deleted, so should always see // tablets @@ -98,7 +102,7 @@ public class ReserveTablets extends ManagerRepo { FateTxId.formatTid(tid)); } - if (locations > 0 || otherOps > 0) { + if (locations > 0 || otherOps > 0 || wals > 0) { // need to wait on these tablets return Math.max(1000, count); }