keith-turner commented on code in PR #4254:
URL: https://github.com/apache/accumulo/pull/4254#discussion_r1500021001


##########
server/base/src/main/java/org/apache/accumulo/server/metadata/ConditionalTabletMutatorImpl.java:
##########
@@ -231,6 +232,13 @@ private void requireSameSingle(TabletMetadata 
tabletMetadata, ColumnType type) {
         mutation.addCondition(c);
       }
         break;
+      case USER_COMPACTION_REQUESTED: {

Review Comment:
   Could add test code to AmpleConditionalWriterIT for this change.



##########
server/manager/src/main/java/org/apache/accumulo/manager/tableOps/compact/CompactionDriver.java:
##########
@@ -257,8 +259,14 @@ public int updateAndCheckTablets(Manager manager, FateId 
fateId)
             otherSelected++;
           }
         } else {

Review Comment:
   Would be good to make the requirements for entering the else explicit rather 
than relying on all of the other elseifs
   
   ```suggestion
           } else if(!tablet.getExternalCompactions().isEmpty() && 
!tablet.getUserCompactionsRequested().contains(fateId)) {
   ```



##########
test/src/main/java/org/apache/accumulo/test/functional/CompactionIT.java:
##########
@@ -909,6 +912,124 @@ public void testDeleteCompactionService() throws 
Exception {
     }
   }
 
+  @Test
+  public void testUserCompactionRequested() throws Exception {
+
+    String tableName = getUniqueNames(1)[0];
+    try (final AccumuloClient client = 
Accumulo.newClient().from(getClientProps()).build()) {
+
+      // configure tablet compaction iterator that slows compaction down so we 
can test
+      // that the USER_COMPACTION_REQUESTED column is set when a user 
compaction is requested
+      // when a system compaction is running and blocking
+
+      var ntc = new NewTableConfiguration();
+      IteratorSetting iterSetting = new IteratorSetting(50, 
SlowIterator.class);
+      SlowIterator.setSleepTime(iterSetting, 1);
+      ntc.attachIterator(iterSetting, EnumSet.of(IteratorScope.majc));
+      ntc.setProperties(Map.of(Property.TABLE_MAJC_RATIO.getKey(), "20"));
+      client.tableOperations().create(tableName, ntc);
+
+      // Insert MAX_DATA rows
+      writeRows((ClientContext) client, tableName, MAX_DATA, false);
+
+      // set the compaction ratio 1 to trigger a system compaction
+      client.tableOperations().setProperty(tableName, 
Property.TABLE_MAJC_RATIO.getKey(), "1");
+
+      var tableId = 
TableId.of(client.tableOperations().tableIdMap().get(tableName));
+      var extent = new KeyExtent(tableId, null, null);
+
+      AtomicReference<ExternalCompactionId> initialCompaction = new 
AtomicReference<>();
+
+      // Wait for the system compaction to start
+      Wait.waitFor(() -> {
+        var tabletMeta = ((ClientContext) 
client).getAmple().readTablet(extent);
+        var externalCompactions = tabletMeta.getExternalCompactions();
+        log.debug("Current external compactions {}", 
externalCompactions.size());
+        var current = externalCompactions.keySet().stream().findFirst();
+        current.ifPresent(initialCompaction::set);
+        return current.isPresent();
+      }, Wait.MAX_WAIT_MILLIS, 100);
+
+      // Trigger a user compaction which should be blocked by the system 
compaction
+      // and should result in the userRequestedCompactions column being set so 
no more
+      // system compactions run
+      client.tableOperations().compact(tableName, new 
CompactionConfig().setWait(false));
+      Wait.waitFor(() -> {
+        var tabletMeta = ((ClientContext) 
client).getAmple().readTablet(extent);
+        var userRequestedCompactions = 
tabletMeta.getUserCompactionsRequested().size();
+        log.debug("Current user requested compaction markers {}", 
userRequestedCompactions);
+        return userRequestedCompactions == 1;
+      }, Wait.MAX_WAIT_MILLIS, 100);
+
+      // Send more data to trigger another system compaction but the user 
compaction
+      // should go next and the column marker should block it
+      writeRows((ClientContext) client, tableName, MAX_DATA, false);
+
+      // Verify that when the next compaction starts it is a USER compaction 
as the
+      // SYSTEM compaction should be blocked by the marker
+      Wait.waitFor(() -> {
+        var tabletMeta = ((ClientContext) 
client).getAmple().readTablet(extent);
+        log.debug("Waiting for USER compaction to start {}", extent);
+
+        var userRequestedCompactions = 
tabletMeta.getUserCompactionsRequested().size();
+        log.debug("Current user requested compaction markers {}", 
userRequestedCompactions);
+        var externalCompactions = tabletMeta.getExternalCompactions();
+        log.debug("External compactions size {}", externalCompactions.size());
+        var current = externalCompactions.entrySet().stream().findFirst();
+        current.ifPresent(c -> log.debug("Current running compaction {}", 
c.getKey()));
+
+        if (current.isPresent()) {
+          var currentCompaction = current.orElseThrow();
+          log.debug("Current running compaction {}", 
currentCompaction.getKey());

Review Comment:
   I think this log stmt is redundant.



##########
server/base/src/main/java/org/apache/accumulo/server/constraints/MetadataConstraints.java:
##########
@@ -266,7 +269,8 @@ public List<Short> check(Environment env, Mutation 
mutation) {
         } catch (RuntimeException e) {
           violations = addViolation(violations, 11);
         }
-      } else if (CompactedColumnFamily.NAME.equals(columnFamily)) {
+      } else if (CompactedColumnFamily.NAME.equals(columnFamily)
+          || UserCompactionRequestedColumnFamily.NAME.equals(columnFamily)) {

Review Comment:
   Could add test to MetadataConstraintsTest for this change



##########
server/manager/src/main/java/org/apache/accumulo/manager/tableOps/compact/CompactionDriver.java:
##########
@@ -257,8 +259,14 @@ public int updateAndCheckTablets(Manager manager, FateId 
fateId)
             otherSelected++;
           }
         } else {
-          // ELASTICITY_TODO if there are compactions preventing selection of 
files, then add
+          // If there are compactions preventing selection of files, then add
           // selecting marker that prevents new compactions from starting
+          log.debug("Marking {} as needing a user requested compaction for 
{}", tablet.getExtent(),
+              fateId);
+          var mutator = 
tabletsMutator.mutateTablet(tablet.getExtent()).requireAbsentOperation()
+              .requireSame(tablet, ECOMP, USER_COMPACTION_REQUESTED)
+              .putUserCompactionRequested(fateId);
+          mutator.submit(tm -> 
tm.getUserCompactionsRequested().contains(fateId));
           otherCompaction++;

Review Comment:
   We could break this `otherCompacion`counter into two counters.  One to 
indicate we set the new column and another to indicate the  new colwas 
previously set and now we are just waiting.  The counters are only used in the 
debug stmt,I have found them useful to track what exactly is happening when 
something goes wrong with compactions.



-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: [email protected]

For queries about this service, please contact Infrastructure at:
[email protected]

Reply via email to