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
commit 5e4ec67ac0ba337d21b815e5a8c5cb95f49a5f89 Merge: 5220f009cc 5aca4f67bc Author: Christopher L. Shannon <cshan...@apache.org> AuthorDate: Fri May 10 17:05:27 2024 -0400 Merge branch 'main' into elasticity .../org/apache/accumulo/core/logging/TabletLogger.java | 7 +++---- .../accumulo/core/metadata/SuspendingTServer.java | 17 ++++++++++------- .../org/apache/accumulo/core/metadata/schema/Ample.java | 3 ++- .../core/metadata/schema/TabletMetadataBuilder.java | 3 ++- .../core/metadata/schema/TabletMutatorBase.java | 3 ++- .../org/apache/accumulo/core/util/time/SteadyTime.java | 14 ++++++++++++++ .../core/metadata/schema/TabletMetadataTest.java | 16 ++++++++++------ .../server/manager/state/AbstractTabletStateStore.java | 9 +++++---- .../server/manager/state/LoggingTabletStateStore.java | 6 +++--- .../server/manager/state/MetaDataStateStore.java | 7 ++++--- .../accumulo/server/manager/state/TabletStateStore.java | 5 +++-- .../server/manager/state/ZooTabletStateStore.java | 5 +++-- .../org/apache/accumulo/manager/TabletGroupWatcher.java | 4 ++-- .../apache/accumulo/tserver/TabletClientHandler.java | 5 +++-- .../apache/accumulo/tserver/UnloadTabletHandler.java | 14 ++++++++------ 15 files changed, 74 insertions(+), 44 deletions(-) diff --cc core/src/main/java/org/apache/accumulo/core/logging/TabletLogger.java index e76c62a6c9,2209e41c27..40dc0b5eb1 --- a/core/src/main/java/org/apache/accumulo/core/logging/TabletLogger.java +++ b/core/src/main/java/org/apache/accumulo/core/logging/TabletLogger.java @@@ -23,15 -23,12 +23,14 @@@ import static java.util.stream.Collecto import java.util.Collection; import java.util.List; import java.util.Optional; +import java.util.SortedSet; import java.util.UUID; - import java.util.concurrent.TimeUnit; -import org.apache.accumulo.core.client.admin.CompactionConfig; import org.apache.accumulo.core.client.admin.compaction.CompactableFile; import org.apache.accumulo.core.dataImpl.KeyExtent; +import org.apache.accumulo.core.fate.FateId; import org.apache.accumulo.core.metadata.CompactableFileImpl; +import org.apache.accumulo.core.metadata.ReferencedTabletFile; import org.apache.accumulo.core.metadata.StoredTabletFile; import org.apache.accumulo.core.metadata.TServerInstance; import org.apache.accumulo.core.metadata.TabletFile; @@@ -40,8 -36,8 +39,9 @@@ import org.apache.accumulo.core.metadat import org.apache.accumulo.core.spi.compaction.CompactionJob; import org.apache.accumulo.core.spi.compaction.CompactionKind; import org.apache.accumulo.core.tabletserver.log.LogEntry; + import org.apache.accumulo.core.util.time.SteadyTime; import org.apache.commons.io.FileUtils; +import org.apache.hadoop.io.Text; import org.slf4j.Logger; import org.slf4j.LoggerFactory; diff --cc core/src/main/java/org/apache/accumulo/core/metadata/schema/Ample.java index 27856c899b,931e415774..7d7086649a --- a/core/src/main/java/org/apache/accumulo/core/metadata/schema/Ample.java +++ b/core/src/main/java/org/apache/accumulo/core/metadata/schema/Ample.java @@@ -342,87 -265,50 +343,87 @@@ public interface Ample /** * Interface for changing a tablets persistent data. */ - interface TabletMutator { - TabletMutator putPrevEndRow(Text per); + interface TabletUpdates<T> { + T putPrevEndRow(Text per); + + T putFile(ReferencedTabletFile path, DataFileValue dfv); + + T putFile(StoredTabletFile path, DataFileValue dfv); - TabletMutator putFile(ReferencedTabletFile path, DataFileValue dfv); + T deleteFile(StoredTabletFile path); - TabletMutator putFile(StoredTabletFile path, DataFileValue dfv); + T putScan(StoredTabletFile path); - TabletMutator deleteFile(StoredTabletFile path); + T deleteScan(StoredTabletFile path); - TabletMutator putScan(StoredTabletFile path); + T putFlushId(long flushId); - TabletMutator deleteScan(StoredTabletFile path); + T putFlushNonce(long flushNonce); - TabletMutator putCompactionId(long compactionId); + T putLocation(Location location); - TabletMutator putFlushId(long flushId); + T deleteLocation(Location location); - TabletMutator putLocation(Location location); + T putDirName(String dirName); - TabletMutator deleteLocation(Location location); + T putWal(LogEntry logEntry); - TabletMutator putZooLock(ServiceLock zooLock); + T deleteWal(LogEntry logEntry); - TabletMutator putDirName(String dirName); + T putTime(MetadataTime time); - TabletMutator putWal(LogEntry logEntry); + T putBulkFile(ReferencedTabletFile bulkref, FateId fateId); - TabletMutator deleteWal(LogEntry wal); + T deleteBulkFile(StoredTabletFile bulkref); - T putSuspension(TServerInstance tserver, long suspensionTime); - TabletMutator putTime(MetadataTime time); ++ T putSuspension(TServerInstance tserver, SteadyTime suspensionTime); - TabletMutator putBulkFile(ReferencedTabletFile bulkref, long tid); + T deleteSuspension(); - TabletMutator deleteBulkFile(StoredTabletFile bulkref); + T putExternalCompaction(ExternalCompactionId ecid, CompactionMetadata ecMeta); - TabletMutator putSuspension(TServerInstance tserver, SteadyTime suspensionTime); + T deleteExternalCompaction(ExternalCompactionId ecid); - TabletMutator deleteSuspension(); + T putCompacted(FateId fateId); - TabletMutator putExternalCompaction(ExternalCompactionId ecid, - ExternalCompactionMetadata ecMeta); + T deleteCompacted(FateId fateId); - TabletMutator deleteExternalCompaction(ExternalCompactionId ecid); + T putTabletAvailability(TabletAvailability tabletAvailability); + + T setHostingRequested(); + + T deleteHostingRequested(); + + T putOperation(TabletOperationId opId); + + T deleteOperation(); + + T putSelectedFiles(SelectedFiles selectedFiles); + + T deleteSelectedFiles(); + + /** + * Deletes all the columns in the keys. + * + * @throws IllegalArgumentException if rows in keys do not match tablet row or column visibility + * is not empty + */ + T deleteAll(Set<Key> keys); + + T setMerged(); + + T deleteMerged(); + + T putUserCompactionRequested(FateId fateId); + + T deleteUserCompactionRequested(FateId fateId); + + T setUnSplittable(UnSplittableMetadata unSplittableMeta); + + T deleteUnSplittable(); + } + interface TabletMutator extends TabletUpdates<TabletMutator> { /** * This method persist (or queues for persisting) previous put and deletes against this object. * Unless this method is called, previous calls will never be persisted. The purpose of this diff --cc core/src/main/java/org/apache/accumulo/core/metadata/schema/TabletMetadataBuilder.java index 8b7e96e59e,0000000000..4121ad2005 mode 100644,000000..100644 --- a/core/src/main/java/org/apache/accumulo/core/metadata/schema/TabletMetadataBuilder.java +++ b/core/src/main/java/org/apache/accumulo/core/metadata/schema/TabletMetadataBuilder.java @@@ -1,327 -1,0 +1,328 @@@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ +package org.apache.accumulo.core.metadata.schema; + +import static org.apache.accumulo.core.metadata.schema.TabletMetadata.ColumnType.AVAILABILITY; +import static org.apache.accumulo.core.metadata.schema.TabletMetadata.ColumnType.COMPACTED; +import static org.apache.accumulo.core.metadata.schema.TabletMetadata.ColumnType.DIR; +import static org.apache.accumulo.core.metadata.schema.TabletMetadata.ColumnType.ECOMP; +import static org.apache.accumulo.core.metadata.schema.TabletMetadata.ColumnType.FILES; +import static org.apache.accumulo.core.metadata.schema.TabletMetadata.ColumnType.FLUSH_ID; +import static org.apache.accumulo.core.metadata.schema.TabletMetadata.ColumnType.FLUSH_NONCE; +import static org.apache.accumulo.core.metadata.schema.TabletMetadata.ColumnType.HOSTING_REQUESTED; +import static org.apache.accumulo.core.metadata.schema.TabletMetadata.ColumnType.LOADED; +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.MERGED; +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.SCANS; +import static org.apache.accumulo.core.metadata.schema.TabletMetadata.ColumnType.SELECTED; +import static org.apache.accumulo.core.metadata.schema.TabletMetadata.ColumnType.SUSPEND; +import static org.apache.accumulo.core.metadata.schema.TabletMetadata.ColumnType.TIME; +import static org.apache.accumulo.core.metadata.schema.TabletMetadata.ColumnType.UNSPLITTABLE; +import static org.apache.accumulo.core.metadata.schema.TabletMetadata.ColumnType.USER_COMPACTION_REQUESTED; + +import java.util.Arrays; +import java.util.EnumSet; +import java.util.Set; +import java.util.SortedMap; +import java.util.TreeMap; + +import org.apache.accumulo.core.client.admin.TabletAvailability; +import org.apache.accumulo.core.data.Key; +import org.apache.accumulo.core.data.Mutation; +import org.apache.accumulo.core.data.Value; +import org.apache.accumulo.core.dataImpl.KeyExtent; +import org.apache.accumulo.core.fate.FateId; +import org.apache.accumulo.core.metadata.ReferencedTabletFile; +import org.apache.accumulo.core.metadata.StoredTabletFile; +import org.apache.accumulo.core.metadata.TServerInstance; +import org.apache.accumulo.core.tabletserver.log.LogEntry; ++import org.apache.accumulo.core.util.time.SteadyTime; +import org.apache.hadoop.io.Text; + +public class TabletMetadataBuilder implements Ample.TabletUpdates<TabletMetadataBuilder> { + + public static class InternalBuilder extends TabletMutatorBase<InternalBuilder> { + protected InternalBuilder(KeyExtent extent) { + super(extent); + } + + @Override + public Mutation getMutation() { + return super.getMutation(); + } + } + + private final InternalBuilder internalBuilder; + EnumSet<TabletMetadata.ColumnType> fetched; + + protected TabletMetadataBuilder(KeyExtent extent) { + internalBuilder = new InternalBuilder(extent); + fetched = EnumSet.noneOf(TabletMetadata.ColumnType.class); + putPrevEndRow(extent.prevEndRow()); + } + + @Override + public TabletMetadataBuilder putPrevEndRow(Text per) { + fetched.add(PREV_ROW); + internalBuilder.putPrevEndRow(per); + return this; + } + + @Override + public TabletMetadataBuilder putFile(ReferencedTabletFile path, DataFileValue dfv) { + fetched.add(FILES); + internalBuilder.putFile(path, dfv); + return this; + } + + @Override + public TabletMetadataBuilder putFile(StoredTabletFile path, DataFileValue dfv) { + fetched.add(FILES); + internalBuilder.putFile(path, dfv); + return this; + } + + @Override + public TabletMetadataBuilder deleteFile(StoredTabletFile path) { + throw new UnsupportedOperationException(); + } + + @Override + public TabletMetadataBuilder putScan(StoredTabletFile path) { + fetched.add(SCANS); + internalBuilder.putScan(path); + return this; + } + + @Override + public TabletMetadataBuilder deleteScan(StoredTabletFile path) { + throw new UnsupportedOperationException(); + } + + @Override + public TabletMetadataBuilder putFlushId(long flushId) { + fetched.add(FLUSH_ID); + internalBuilder.putFlushId(flushId); + return this; + } + + @Override + public TabletMetadataBuilder putFlushNonce(long flushNonce) { + fetched.add(FLUSH_NONCE); + internalBuilder.putFlushId(flushNonce); + return this; + } + + @Override + public TabletMetadataBuilder putLocation(TabletMetadata.Location location) { + fetched.add(LOCATION); + internalBuilder.putLocation(location); + return this; + } + + @Override + public TabletMetadataBuilder deleteLocation(TabletMetadata.Location location) { + throw new UnsupportedOperationException(); + } + + @Override + public TabletMetadataBuilder putDirName(String dirName) { + fetched.add(DIR); + internalBuilder.putDirName(dirName); + return this; + } + + @Override + public TabletMetadataBuilder putWal(LogEntry logEntry) { + fetched.add(LOGS); + internalBuilder.putWal(logEntry); + return this; + } + + @Override + public TabletMetadataBuilder deleteWal(LogEntry logEntry) { + throw new UnsupportedOperationException(); + } + + @Override + public TabletMetadataBuilder putTime(MetadataTime time) { + fetched.add(TIME); + internalBuilder.putTime(time); + return this; + } + + @Override + public TabletMetadataBuilder putBulkFile(ReferencedTabletFile bulkref, FateId fateId) { + fetched.add(LOADED); + internalBuilder.putBulkFile(bulkref, fateId); + return this; + } + + @Override + public TabletMetadataBuilder deleteBulkFile(StoredTabletFile bulkref) { + throw new UnsupportedOperationException(); + } + + @Override - public TabletMetadataBuilder putSuspension(TServerInstance tserver, long suspensionTime) { ++ public TabletMetadataBuilder putSuspension(TServerInstance tserver, SteadyTime suspensionTime) { + fetched.add(SUSPEND); + internalBuilder.putSuspension(tserver, suspensionTime); + return this; + } + + @Override + public TabletMetadataBuilder deleteSuspension() { + throw new UnsupportedOperationException(); + } + + @Override + public TabletMetadataBuilder putExternalCompaction(ExternalCompactionId ecid, + CompactionMetadata ecMeta) { + fetched.add(ECOMP); + internalBuilder.putExternalCompaction(ecid, ecMeta); + return this; + } + + @Override + public TabletMetadataBuilder deleteExternalCompaction(ExternalCompactionId ecid) { + throw new UnsupportedOperationException(); + } + + @Override + public TabletMetadataBuilder putCompacted(FateId fateId) { + fetched.add(COMPACTED); + internalBuilder.putCompacted(fateId); + return this; + } + + @Override + public TabletMetadataBuilder deleteCompacted(FateId fateId) { + throw new UnsupportedOperationException(); + } + + @Override + public TabletMetadataBuilder putTabletAvailability(TabletAvailability tabletAvailability) { + fetched.add(AVAILABILITY); + internalBuilder.putTabletAvailability(tabletAvailability); + return this; + } + + @Override + public TabletMetadataBuilder setHostingRequested() { + fetched.add(HOSTING_REQUESTED); + internalBuilder.setHostingRequested(); + return this; + } + + @Override + public TabletMetadataBuilder deleteHostingRequested() { + throw new UnsupportedOperationException(); + } + + @Override + public TabletMetadataBuilder putOperation(TabletOperationId opId) { + fetched.add(OPID); + internalBuilder.putOperation(opId); + return this; + } + + @Override + public TabletMetadataBuilder deleteOperation() { + throw new UnsupportedOperationException(); + } + + @Override + public TabletMetadataBuilder putSelectedFiles(SelectedFiles selectedFiles) { + fetched.add(SELECTED); + internalBuilder.putSelectedFiles(selectedFiles); + return this; + } + + @Override + public TabletMetadataBuilder deleteSelectedFiles() { + throw new UnsupportedOperationException(); + } + + @Override + public TabletMetadataBuilder deleteAll(Set<Key> keys) { + throw new UnsupportedOperationException(); + } + + @Override + public TabletMetadataBuilder setMerged() { + fetched.add(MERGED); + internalBuilder.setMerged(); + return this; + } + + @Override + public TabletMetadataBuilder deleteMerged() { + throw new UnsupportedOperationException(); + } + + @Override + public TabletMetadataBuilder putUserCompactionRequested(FateId fateId) { + fetched.add(USER_COMPACTION_REQUESTED); + internalBuilder.putUserCompactionRequested(fateId); + return this; + } + + @Override + public TabletMetadataBuilder deleteUserCompactionRequested(FateId fateId) { + throw new UnsupportedOperationException(); + } + + @Override + public TabletMetadataBuilder setUnSplittable(UnSplittableMetadata unSplittableMeta) { + fetched.add(UNSPLITTABLE); + internalBuilder.setUnSplittable(unSplittableMeta); + return this; + } + + @Override + public TabletMetadataBuilder deleteUnSplittable() { + throw new UnsupportedOperationException(); + } + + /** + * @param extraFetched Anything that was put on the builder will automatically be added to the + * fetched set. However, for the case where something was not put and it needs to be + * fetched it can be passed here. For example to simulate a tablet w/o a location it, no + * location will be put and LOCATION would be passed in via this argument. + */ + public TabletMetadata build(TabletMetadata.ColumnType... extraFetched) { + var mutation = internalBuilder.getMutation(); + + SortedMap<Key,Value> rowMap = new TreeMap<>(); + mutation.getUpdates().forEach(cu -> { + Key k = new Key(mutation.getRow(), cu.getColumnFamily(), cu.getColumnQualifier(), + cu.getTimestamp()); + Value v = new Value(cu.getValue()); + rowMap.put(k, v); + }); + + fetched.addAll(Arrays.asList(extraFetched)); + + return TabletMetadata.convertRow(rowMap.entrySet().iterator(), fetched, true, false); + } + +} diff --cc core/src/main/java/org/apache/accumulo/core/metadata/schema/TabletMutatorBase.java index 4fc978f150,a8b567775a..f4ee38e28d --- a/core/src/main/java/org/apache/accumulo/core/metadata/schema/TabletMutatorBase.java +++ b/core/src/main/java/org/apache/accumulo/core/metadata/schema/TabletMutatorBase.java @@@ -51,6 -46,8 +51,7 @@@ import org.apache.accumulo.core.metadat import org.apache.accumulo.core.metadata.schema.TabletMetadata.Location; import org.apache.accumulo.core.metadata.schema.TabletMetadata.LocationType; import org.apache.accumulo.core.tabletserver.log.LogEntry; + import org.apache.accumulo.core.util.time.SteadyTime; -import org.apache.accumulo.server.ServerContext; import org.apache.hadoop.io.Text; import com.google.common.base.Preconditions; @@@ -223,15 -202,7 +224,15 @@@ public abstract class TabletMutatorBase } @Override - public Ample.TabletMutator putSuspension(TServerInstance tServer, SteadyTime suspensionTime) { + public T deleteSelectedFiles() { + Preconditions.checkState(updatesEnabled, "Cannot make updates after calling mutate."); + mutation.putDelete(ServerColumnFamily.SELECTED_COLUMN.getColumnFamily(), + ServerColumnFamily.SELECTED_COLUMN.getColumnQualifier()); + return getThis(); + } + + @Override - public T putSuspension(TServerInstance tServer, long suspensionTime) { ++ public T putSuspension(TServerInstance tServer, SteadyTime suspensionTime) { Preconditions.checkState(updatesEnabled, "Cannot make updates after calling mutate."); mutation.put(SuspendLocationColumn.SUSPEND_COLUMN.getColumnFamily(), SuspendLocationColumn.SUSPEND_COLUMN.getColumnQualifier(), diff --cc core/src/test/java/org/apache/accumulo/core/metadata/schema/TabletMetadataTest.java index c2f6a19e69,3b2b4a85ac..109be1aadc --- a/core/src/test/java/org/apache/accumulo/core/metadata/schema/TabletMetadataTest.java +++ b/core/src/test/java/org/apache/accumulo/core/metadata/schema/TabletMetadataTest.java @@@ -77,16 -71,15 +78,17 @@@ import org.apache.accumulo.core.metadat import org.apache.accumulo.core.metadata.schema.MetadataSchema.TabletsSection.FutureLocationColumnFamily; import org.apache.accumulo.core.metadata.schema.MetadataSchema.TabletsSection.LastLocationColumnFamily; import org.apache.accumulo.core.metadata.schema.MetadataSchema.TabletsSection.ScanFileColumnFamily; +import org.apache.accumulo.core.metadata.schema.MetadataSchema.TabletsSection.SplitColumnFamily; import org.apache.accumulo.core.metadata.schema.MetadataSchema.TabletsSection.TabletColumnFamily; +import org.apache.accumulo.core.metadata.schema.MetadataSchema.TabletsSection.UserCompactionRequestedColumnFamily; import org.apache.accumulo.core.metadata.schema.TabletMetadata.Builder; import org.apache.accumulo.core.metadata.schema.TabletMetadata.ColumnType; +import org.apache.accumulo.core.metadata.schema.TabletMetadata.Location; import org.apache.accumulo.core.metadata.schema.TabletMetadata.LocationType; -import org.apache.accumulo.core.spi.compaction.CompactionExecutorId; import org.apache.accumulo.core.spi.compaction.CompactionKind; +import org.apache.accumulo.core.spi.compaction.CompactorGroupId; import org.apache.accumulo.core.tabletserver.log.LogEntry; -import org.apache.accumulo.core.util.compaction.CompactionExecutorIdImpl; + import org.apache.accumulo.core.util.time.SteadyTime; import org.apache.hadoop.fs.Path; import org.apache.hadoop.io.Text; import org.junit.jupiter.api.Test; @@@ -138,13 -128,9 +140,13 @@@ public class TabletMetadataTest mutation.at().family(ScanFileColumnFamily.NAME).qualifier(sf2.getMetadata()).put(""); MERGED_COLUMN.put(mutation, new Value()); + FateId userCompactFateId = FateId.from(type, UUID.randomUUID()); + mutation.put(UserCompactionRequestedColumnFamily.STR_NAME, userCompactFateId.canonical(), ""); + var unsplittableMeta = + UnSplittableMetadata.toUnSplittable(extent, 100, 110, 120, Set.of(sf1, sf2)); + SplitColumnFamily.UNSPLITTABLE_COLUMN.put(mutation, new Value(unsplittableMeta.toBase64())); - long suspensionTime = System.currentTimeMillis(); - OLD_PREV_ROW_COLUMN.put(mutation, TabletColumnFamily.encodePrevEndRow(new Text("oldPrev"))); + SteadyTime suspensionTime = SteadyTime.from(System.currentTimeMillis(), TimeUnit.MILLISECONDS); TServerInstance ser1 = new TServerInstance(HostAndPort.fromParts("server1", 8555), "s001"); Value suspend = SuspendingTServer.toValue(ser1, suspensionTime); SUSPEND_COLUMN.put(mutation, suspend); @@@ -303,13 -291,14 +305,14 @@@ // test SUSPENDED mutation = TabletColumnFamily.createPrevRowMutation(extent); mutation.at().family(SUSPEND_COLUMN.getColumnFamily()) - .qualifier(SUSPEND_COLUMN.getColumnQualifier()).put(SuspendingTServer.toValue(ser2, 1000L)); + .qualifier(SUSPEND_COLUMN.getColumnQualifier()) + .put(SuspendingTServer.toValue(ser2, SteadyTime.from(1000L, TimeUnit.MILLISECONDS))); rowMap = toRowMap(mutation); - tm = TabletMetadata.convertRow(rowMap.entrySet().iterator(), colsToFetch, false); + tm = TabletMetadata.convertRow(rowMap.entrySet().iterator(), colsToFetch, false, false); - assertEquals(TabletState.SUSPENDED, tm.getTabletState(tservers)); + assertEquals(TabletState.SUSPENDED, TabletState.compute(tm, tservers)); - assertEquals(1000L, tm.getSuspend().suspensionTime); + assertEquals(1000L, tm.getSuspend().suspensionTime.getMillis()); assertEquals(ser2.getHostAndPort(), tm.getSuspend().server); assertNull(tm.getLocation()); assertFalse(tm.hasCurrent()); @@@ -573,121 -422,4 +576,122 @@@ }); return rowMap; } + + @Test + public void testBuilder() { + TServerInstance ser1 = new TServerInstance(HostAndPort.fromParts("server1", 8555), "s001"); + + KeyExtent extent = new KeyExtent(TableId.of("5"), new Text("df"), new Text("da")); + + FateInstanceType type = FateInstanceType.fromTableId(extent.tableId()); + + StoredTabletFile sf1 = + new ReferencedTabletFile(new Path("hdfs://nn1/acc/tables/1/t-0001/sf1.rf")).insert(); + DataFileValue dfv1 = new DataFileValue(89, 67); + + StoredTabletFile sf2 = + new ReferencedTabletFile(new Path("hdfs://nn1/acc/tables/1/t-0001/sf2.rf")).insert(); + DataFileValue dfv2 = new DataFileValue(890, 670); + + ReferencedTabletFile rf1 = + new ReferencedTabletFile(new Path("hdfs://nn1/acc/tables/1/t-0001/imp1.rf")); + ReferencedTabletFile rf2 = + new ReferencedTabletFile(new Path("hdfs://nn1/acc/tables/1/t-0001/imp2.rf")); + + StoredTabletFile sf3 = + new ReferencedTabletFile(new Path("hdfs://nn1/acc/tables/1/t-0001/sf3.rf")).insert(); + StoredTabletFile sf4 = + new ReferencedTabletFile(new Path("hdfs://nn1/acc/tables/1/t-0001/sf4.rf")).insert(); + + FateId loadedFateId1 = FateId.from(type, UUID.randomUUID()); + FateId loadedFateId2 = FateId.from(type, UUID.randomUUID()); + FateId compactFateId1 = FateId.from(type, UUID.randomUUID()); + FateId compactFateId2 = FateId.from(type, UUID.randomUUID()); + + TabletMetadata tm = TabletMetadata.builder(extent) + .putTabletAvailability(TabletAvailability.UNHOSTED).putLocation(Location.future(ser1)) + .putFile(sf1, dfv1).putFile(sf2, dfv2).putBulkFile(rf1, loadedFateId1) + .putBulkFile(rf2, loadedFateId2).putFlushId(27).putDirName("dir1").putScan(sf3).putScan(sf4) + .putCompacted(compactFateId1).putCompacted(compactFateId2) + .build(ECOMP, HOSTING_REQUESTED, MERGED, USER_COMPACTION_REQUESTED, UNSPLITTABLE); + + assertEquals(extent, tm.getExtent()); + assertEquals(TabletAvailability.UNHOSTED, tm.getTabletAvailability()); + assertEquals(Location.future(ser1), tm.getLocation()); + assertEquals(27L, tm.getFlushId().orElse(-1)); + assertEquals(Map.of(sf1, dfv1, sf2, dfv2), tm.getFilesMap()); + assertEquals(tm.getFilesMap().values().stream().mapToLong(DataFileValue::getSize).sum(), + tm.getFileSize()); + assertEquals(Map.of(rf1.insert(), loadedFateId1, rf2.insert(), loadedFateId2), tm.getLoaded()); + assertEquals("dir1", tm.getDirName()); + assertEquals(Set.of(sf3, sf4), Set.copyOf(tm.getScans())); + assertEquals(Set.of(), tm.getExternalCompactions().keySet()); + assertEquals(Set.of(compactFateId1, compactFateId2), tm.getCompacted()); + assertFalse(tm.getHostingRequested()); + assertTrue(tm.getUserCompactionsRequested().isEmpty()); + assertFalse(tm.hasMerged()); + assertNull(tm.getUnSplittable()); + assertThrows(IllegalStateException.class, tm::getOperationId); + assertThrows(IllegalStateException.class, tm::getSuspend); + assertThrows(IllegalStateException.class, tm::getTime); + + TabletOperationId opid1 = + TabletOperationId.from(TabletOperationType.SPLITTING, FateId.from(type, UUID.randomUUID())); + TabletMetadata tm2 = TabletMetadata.builder(extent).putOperation(opid1).build(LOCATION); + + assertEquals(extent, tm2.getExtent()); + assertEquals(opid1, tm2.getOperationId()); + assertNull(tm2.getLocation()); + assertThrows(IllegalStateException.class, tm2::getFiles); + assertThrows(IllegalStateException.class, tm2::getTabletAvailability); + assertThrows(IllegalStateException.class, tm2::getFlushId); + assertThrows(IllegalStateException.class, tm2::getFiles); + assertThrows(IllegalStateException.class, tm2::getLogs); + assertThrows(IllegalStateException.class, tm2::getLoaded); + assertThrows(IllegalStateException.class, tm2::getDirName); + assertThrows(IllegalStateException.class, tm2::getScans); + assertThrows(IllegalStateException.class, tm2::getExternalCompactions); + assertThrows(IllegalStateException.class, tm2::getHostingRequested); + assertThrows(IllegalStateException.class, tm2::getSelectedFiles); + assertThrows(IllegalStateException.class, tm2::getCompacted); + assertThrows(IllegalStateException.class, tm2::hasMerged); + assertThrows(IllegalStateException.class, tm2::getUserCompactionsRequested); + assertThrows(IllegalStateException.class, tm2::getUnSplittable); + + var ecid1 = ExternalCompactionId.generate(UUID.randomUUID()); + CompactionMetadata ecm = + new CompactionMetadata(Set.of(sf1, sf2), rf1, "cid1", CompactionKind.USER, (short) 3, + CompactorGroupId.of("Q1"), true, FateId.from(type, UUID.randomUUID())); + + LogEntry le1 = LogEntry.fromPath("localhost+8020/" + UUID.randomUUID()); + LogEntry le2 = LogEntry.fromPath("localhost+8020/" + UUID.randomUUID()); + + FateId selFilesFateId = FateId.from(type, UUID.randomUUID()); + SelectedFiles selFiles = new SelectedFiles(Set.of(sf1, sf4), false, selFilesFateId); + var unsplittableMeta = + UnSplittableMetadata.toUnSplittable(extent, 100, 110, 120, Set.of(sf1, sf2)); + + TabletMetadata tm3 = TabletMetadata.builder(extent).putExternalCompaction(ecid1, ecm) - .putSuspension(ser1, 45L).putTime(new MetadataTime(479, TimeType.LOGICAL)).putWal(le1) - .putWal(le2).setHostingRequested().putSelectedFiles(selFiles).setMerged() ++ .putSuspension(ser1, SteadyTime.from(45L, TimeUnit.MILLISECONDS)) ++ .putTime(new MetadataTime(479, TimeType.LOGICAL)).putWal(le1).putWal(le2) ++ .setHostingRequested().putSelectedFiles(selFiles).setMerged() + .putUserCompactionRequested(selFilesFateId).setUnSplittable(unsplittableMeta).build(); + + assertEquals(Set.of(ecid1), tm3.getExternalCompactions().keySet()); + assertEquals(Set.of(sf1, sf2), tm3.getExternalCompactions().get(ecid1).getJobFiles()); + assertEquals(ser1.getHostAndPort(), tm3.getSuspend().server); - assertEquals(45L, tm3.getSuspend().suspensionTime); ++ assertEquals(SteadyTime.from(45L, TimeUnit.MILLISECONDS), tm3.getSuspend().suspensionTime); + assertEquals(new MetadataTime(479, TimeType.LOGICAL), tm3.getTime()); + assertTrue(tm3.getHostingRequested()); + assertEquals(Stream.of(le1, le2).map(LogEntry::toString).collect(toSet()), + tm3.getLogs().stream().map(LogEntry::toString).collect(toSet())); + assertEquals(Set.of(sf1, sf4), tm3.getSelectedFiles().getFiles()); + assertEquals(selFilesFateId, tm3.getSelectedFiles().getFateId()); + assertFalse(tm3.getSelectedFiles().initiallySelectedAll()); + assertEquals(selFiles.getMetadataValue(), tm3.getSelectedFiles().getMetadataValue()); + assertTrue(tm3.hasMerged()); + assertTrue(tm3.getUserCompactionsRequested().contains(selFilesFateId)); + assertEquals(unsplittableMeta, tm3.getUnSplittable()); + } + } diff --cc server/base/src/main/java/org/apache/accumulo/server/manager/state/AbstractTabletStateStore.java index 977aa98afb,0000000000..e6c78ace50 mode 100644,000000..100644 --- a/server/base/src/main/java/org/apache/accumulo/server/manager/state/AbstractTabletStateStore.java +++ b/server/base/src/main/java/org/apache/accumulo/server/manager/state/AbstractTabletStateStore.java @@@ -1,189 -1,0 +1,190 @@@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ +package org.apache.accumulo.server.manager.state; + +import java.util.Collection; +import java.util.List; +import java.util.Map; +import java.util.Map.Entry; + +import org.apache.accumulo.core.dataImpl.KeyExtent; +import org.apache.accumulo.core.metadata.TServerInstance; +import org.apache.accumulo.core.metadata.schema.Ample; +import org.apache.accumulo.core.metadata.schema.Ample.ConditionalResult; +import org.apache.accumulo.core.metadata.schema.Ample.ConditionalResult.Status; +import org.apache.accumulo.core.metadata.schema.TabletMetadata; +import org.apache.accumulo.core.metadata.schema.TabletMetadata.Location; +import org.apache.accumulo.core.metadata.schema.TabletMetadata.LocationType; +import org.apache.accumulo.core.tabletserver.log.LogEntry; ++import org.apache.accumulo.core.util.time.SteadyTime; +import org.apache.accumulo.server.ServerContext; +import org.apache.hadoop.fs.Path; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import com.google.common.base.Preconditions; + +public abstract class AbstractTabletStateStore implements TabletStateStore { + + private static final Logger LOG = LoggerFactory.getLogger(AbstractTabletStateStore.class); + + private final Ample ample; + + protected AbstractTabletStateStore(ServerContext context) { + this.ample = context.getAmple(); + } + + @Override + public void setLocations(Collection<Assignment> assignments) throws DistributedStoreException { + try (var tabletsMutator = ample.conditionallyMutateTablets()) { + for (Assignment assignment : assignments) { + var conditionalMutator = tabletsMutator.mutateTablet(assignment.tablet) + .requireLocation(TabletMetadata.Location.future(assignment.server)) + .putLocation(TabletMetadata.Location.current(assignment.server)) + .deleteLocation(TabletMetadata.Location.future(assignment.server)).deleteSuspension(); + + updateLastLocation(conditionalMutator, assignment.server, assignment.lastLocation); + + conditionalMutator.submit(tabletMetadata -> { + Preconditions.checkArgument(tabletMetadata.getExtent().equals(assignment.tablet)); + return tabletMetadata.getLocation() != null && tabletMetadata.getLocation() + .equals(TabletMetadata.Location.current(assignment.server)); + }); + } + + if (tabletsMutator.process().values().stream() + .anyMatch(result -> result.getStatus() != Status.ACCEPTED)) { + throw new DistributedStoreException( + "failed to set tablet location, conditional mutation failed"); + } + } catch (RuntimeException ex) { + throw new DistributedStoreException(ex); + } + } + + @Override + public void setFutureLocations(Collection<Assignment> assignments) + throws DistributedStoreException { + try (var tabletsMutator = ample.conditionallyMutateTablets()) { + for (Assignment assignment : assignments) { + tabletsMutator.mutateTablet(assignment.tablet).requireAbsentOperation() + .requireAbsentLocation().deleteSuspension() + .putLocation(TabletMetadata.Location.future(assignment.server)) + .submit(tabletMetadata -> { + Preconditions.checkArgument(tabletMetadata.getExtent().equals(assignment.tablet)); + return tabletMetadata.getLocation() != null && tabletMetadata.getLocation() + .equals(TabletMetadata.Location.future(assignment.server)); + }); + } + + Map<KeyExtent,ConditionalResult> results = tabletsMutator.process(); + + for (Entry<KeyExtent,ConditionalResult> entry : results.entrySet()) { + if (entry.getValue().getStatus() != Status.ACCEPTED) { + LOG.debug("Likely concurrent FATE operation prevented setting future location for {}, " + + "Manager will retry soon.", entry.getKey()); + } + } + + } catch (RuntimeException ex) { + throw new DistributedStoreException(ex); + } + } + + @Override + public void unassign(Collection<TabletMetadata> tablets, + Map<TServerInstance,List<Path>> logsForDeadServers) throws DistributedStoreException { - unassign(tablets, logsForDeadServers, -1); ++ unassign(tablets, logsForDeadServers, null); + } + + @Override + public void suspend(Collection<TabletMetadata> tablets, - Map<TServerInstance,List<Path>> logsForDeadServers, long suspensionTimestamp) ++ Map<TServerInstance,List<Path>> logsForDeadServers, SteadyTime suspensionTimestamp) + throws DistributedStoreException { + unassign(tablets, logsForDeadServers, suspensionTimestamp); + } + + protected abstract void processSuspension(Ample.ConditionalTabletMutator tabletMutator, - TabletMetadata tm, long suspensionTimestamp); ++ TabletMetadata tm, SteadyTime suspensionTimestamp); + + private void unassign(Collection<TabletMetadata> tablets, - Map<TServerInstance,List<Path>> logsForDeadServers, long suspensionTimestamp) ++ Map<TServerInstance,List<Path>> logsForDeadServers, SteadyTime suspensionTimestamp) + throws DistributedStoreException { + try (var tabletsMutator = ample.conditionallyMutateTablets()) { + for (TabletMetadata tm : tablets) { + if (tm.getLocation() == null) { + continue; + } + + var tabletMutator = + tabletsMutator.mutateTablet(tm.getExtent()).requireLocation(tm.getLocation()); + + if (tm.hasCurrent()) { + + updateLastLocation(tabletMutator, tm.getLocation().getServerInstance(), tm.getLast()); + tabletMutator.deleteLocation(tm.getLocation()); + if (logsForDeadServers != null) { + List<Path> logs = logsForDeadServers.get(tm.getLocation().getServerInstance()); + if (logs != null) { + for (Path log : logs) { + LogEntry entry = LogEntry.fromPath(log.toString()); + tabletMutator.putWal(entry); + } + } + } + } + + if (tm.getLocation() != null && tm.getLocation().getType() != null + && tm.getLocation().getType().equals(LocationType.FUTURE)) { + tabletMutator.deleteLocation(tm.getLocation()); + } + + processSuspension(tabletMutator, tm, suspensionTimestamp); + + tabletMutator.submit(tabletMetadata -> tabletMetadata.getLocation() == null); + } + + Map<KeyExtent,Ample.ConditionalResult> results = tabletsMutator.process(); + + if (results.values().stream() + .anyMatch(conditionalResult -> conditionalResult.getStatus() != Status.ACCEPTED)) { + throw new DistributedStoreException("Some unassignments did not satisfy conditions."); + } + + } catch (RuntimeException ex) { + throw new DistributedStoreException(ex); + } + } + + protected static void updateLastLocation(Ample.TabletUpdates<?> tabletMutator, + TServerInstance location, Location lastLocation) { + Preconditions.checkArgument( + lastLocation == null || lastLocation.getType() == TabletMetadata.LocationType.LAST); + Location newLocation = Location.last(location); + if (lastLocation != null) { + if (!lastLocation.equals(newLocation)) { + tabletMutator.deleteLocation(lastLocation); + tabletMutator.putLocation(newLocation); + } + } else { + tabletMutator.putLocation(newLocation); + } + } + +} diff --cc server/base/src/main/java/org/apache/accumulo/server/manager/state/LoggingTabletStateStore.java index 8545ecd7c7,63b00064e6..ec93787abb --- a/server/base/src/main/java/org/apache/accumulo/server/manager/state/LoggingTabletStateStore.java +++ b/server/base/src/main/java/org/apache/accumulo/server/manager/state/LoggingTabletStateStore.java @@@ -21,14 -21,12 +21,14 @@@ package org.apache.accumulo.server.mana import java.util.Collection; import java.util.List; import java.util.Map; - import java.util.concurrent.TimeUnit; +import org.apache.accumulo.core.data.Range; import org.apache.accumulo.core.logging.TabletLogger; +import org.apache.accumulo.core.manager.state.TabletManagement; import org.apache.accumulo.core.metadata.TServerInstance; -import org.apache.accumulo.core.metadata.TabletLocationState; import org.apache.accumulo.core.metadata.schema.Ample.DataLevel; +import org.apache.accumulo.core.metadata.schema.TabletMetadata; + import org.apache.accumulo.core.util.time.SteadyTime; import org.apache.hadoop.fs.Path; import com.google.common.net.HostAndPort; @@@ -88,8 -85,8 +88,8 @@@ class LoggingTabletStateStore implement } @Override - public void suspend(Collection<TabletLocationState> tablets, + public void suspend(Collection<TabletMetadata> tablets, - Map<TServerInstance,List<Path>> logsForDeadServers, long suspensionTimestamp) + Map<TServerInstance,List<Path>> logsForDeadServers, SteadyTime suspensionTimestamp) throws DistributedStoreException { wrapped.suspend(tablets, logsForDeadServers, suspensionTimestamp); @@@ -103,8 -100,7 +103,8 @@@ if (location != null) { server = location.getHostAndPort(); } - TabletLogger.suspended(tm.getExtent(), server, suspensionTimestamp, TimeUnit.MILLISECONDS, - TabletLogger.suspended(tls.extent, server, suspensionTimestamp, logsForDeadServers.size()); ++ TabletLogger.suspended(tm.getExtent(), server, suspensionTimestamp, + logsForDeadServers.size()); } } diff --cc server/base/src/main/java/org/apache/accumulo/server/manager/state/MetaDataStateStore.java index 972d6e927e,acc37a2075..a7e22a75e8 --- a/server/base/src/main/java/org/apache/accumulo/server/manager/state/MetaDataStateStore.java +++ b/server/base/src/main/java/org/apache/accumulo/server/manager/state/MetaDataStateStore.java @@@ -18,26 -18,28 +18,27 @@@ */ package org.apache.accumulo.server.manager.state; +import static org.apache.accumulo.core.metadata.schema.TabletMetadata.ColumnType.SUSPEND; + import java.util.Collection; import java.util.List; -import java.util.Map; import org.apache.accumulo.core.clientImpl.ClientContext; +import org.apache.accumulo.core.data.Range; +import org.apache.accumulo.core.manager.state.TabletManagement; import org.apache.accumulo.core.metadata.AccumuloTable; -import org.apache.accumulo.core.metadata.TServerInstance; -import org.apache.accumulo.core.metadata.TabletLocationState; import org.apache.accumulo.core.metadata.schema.Ample; +import org.apache.accumulo.core.metadata.schema.Ample.ConditionalResult.Status; import org.apache.accumulo.core.metadata.schema.Ample.DataLevel; -import org.apache.accumulo.core.metadata.schema.Ample.TabletMutator; -import org.apache.accumulo.core.metadata.schema.MetadataSchema.TabletsSection; -import org.apache.accumulo.core.metadata.schema.TabletMetadata.Location; -import org.apache.accumulo.core.tabletserver.log.LogEntry; +import org.apache.accumulo.core.metadata.schema.TabletMetadata; + import org.apache.accumulo.core.util.time.SteadyTime; -import org.apache.accumulo.server.util.ManagerMetadataUtil; -import org.apache.hadoop.fs.Path; +import org.apache.accumulo.server.ServerContext; + +import com.google.common.base.Preconditions; -class MetaDataStateStore implements TabletStateStore { +class MetaDataStateStore extends AbstractTabletStateStore implements TabletStateStore { protected final ClientContext context; - protected final CurrentState state; private final String targetTableName; private final Ample ample; private final DataLevel level; @@@ -93,16 -104,64 +94,16 @@@ } @Override - public void suspend(Collection<TabletLocationState> tablets, - Map<TServerInstance,List<Path>> logsForDeadServers, SteadyTime suspensionTimestamp) - throws DistributedStoreException { - unassign(tablets, logsForDeadServers, suspensionTimestamp); - } - - private void unassign(Collection<TabletLocationState> tablets, - Map<TServerInstance,List<Path>> logsForDeadServers, SteadyTime suspensionTimestamp) - throws DistributedStoreException { - try (var tabletsMutator = ample.mutateTablets()) { - for (TabletLocationState tls : tablets) { - TabletMutator tabletMutator = tabletsMutator.mutateTablet(tls.extent); - if (tls.current != null) { - ManagerMetadataUtil.updateLastForAssignmentMode(context, tabletMutator, - tls.current.getServerInstance(), tls.last); - tabletMutator.deleteLocation(tls.current); - if (logsForDeadServers != null) { - List<Path> logs = logsForDeadServers.get(tls.current.getServerInstance()); - if (logs != null) { - for (Path log : logs) { - LogEntry entry = LogEntry.fromPath(log.toString()); - tabletMutator.putWal(entry); - } - } - } - if (suspensionTimestamp != null && suspensionTimestamp.getMillis() >= 0) { - tabletMutator.putSuspension(tls.current.getServerInstance(), suspensionTimestamp); - } - } - if (tls.suspend != null && suspensionTimestamp == null) { - tabletMutator.deleteSuspension(); - } - if (tls.hasFuture()) { - tabletMutator.deleteLocation(tls.future); - } - tabletMutator.mutate(); + protected void processSuspension(Ample.ConditionalTabletMutator tabletMutator, TabletMetadata tm, - long suspensionTimestamp) { ++ SteadyTime suspensionTimestamp) { + if (tm.hasCurrent()) { - if (suspensionTimestamp >= 0) { ++ if (suspensionTimestamp != null) { + tabletMutator.putSuspension(tm.getLocation().getServerInstance(), suspensionTimestamp); } - } catch (RuntimeException ex) { - throw new DistributedStoreException(ex); } - } - if (tm.getSuspend() != null && suspensionTimestamp < 0) { - @Override - public void unsuspend(Collection<TabletLocationState> tablets) throws DistributedStoreException { - try (var tabletsMutator = ample.mutateTablets()) { - for (TabletLocationState tls : tablets) { - if (tls.suspend != null) { - tabletsMutator.mutateTablet(tls.extent).deleteSuspension().mutate(); - } - } - } catch (RuntimeException ex) { - throw new DistributedStoreException(ex); ++ if (tm.getSuspend() != null && suspensionTimestamp == null) { + tabletMutator.deleteSuspension(); } } - - @Override - public String name() { - return "Normal Tablets"; - } - } diff --cc server/base/src/main/java/org/apache/accumulo/server/manager/state/TabletStateStore.java index ee81950fe7,9f4302bfdb..602409125e --- a/server/base/src/main/java/org/apache/accumulo/server/manager/state/TabletStateStore.java +++ b/server/base/src/main/java/org/apache/accumulo/server/manager/state/TabletStateStore.java @@@ -23,13 -23,12 +23,14 @@@ import java.util.Collections import java.util.List; import java.util.Map; -import org.apache.accumulo.core.clientImpl.ClientContext; +import org.apache.accumulo.core.data.Range; import org.apache.accumulo.core.dataImpl.KeyExtent; +import org.apache.accumulo.core.manager.state.TabletManagement; import org.apache.accumulo.core.metadata.TServerInstance; -import org.apache.accumulo.core.metadata.TabletLocationState; import org.apache.accumulo.core.metadata.schema.Ample.DataLevel; +import org.apache.accumulo.core.metadata.schema.MetadataSchema; +import org.apache.accumulo.core.metadata.schema.TabletMetadata; + import org.apache.accumulo.core.util.time.SteadyTime; import org.apache.accumulo.server.ServerContext; import org.apache.hadoop.fs.Path; @@@ -85,8 -76,8 +86,8 @@@ public interface TabletStateStore * Mark tablets as having no known or future location, but desiring to be returned to their * previous tserver. */ - void suspend(Collection<TabletLocationState> tablets, + void suspend(Collection<TabletMetadata> tablets, - Map<TServerInstance,List<Path>> logsForDeadServers, long suspensionTimestamp) + Map<TServerInstance,List<Path>> logsForDeadServers, SteadyTime suspensionTimestamp) throws DistributedStoreException; /** @@@ -100,10 -91,10 +101,10 @@@ logsForDeadServers); } - public static void suspend(ServerContext context, TabletLocationState tls, + public static void suspend(ServerContext context, TabletMetadata tm, - Map<TServerInstance,List<Path>> logsForDeadServers, long suspensionTimestamp) + Map<TServerInstance,List<Path>> logsForDeadServers, SteadyTime suspensionTimestamp) throws DistributedStoreException { - getStoreForTablet(tls.extent, context).suspend(Collections.singletonList(tls), + getStoreForTablet(tm.getExtent(), context).suspend(Collections.singletonList(tm), logsForDeadServers, suspensionTimestamp); } diff --cc server/base/src/main/java/org/apache/accumulo/server/manager/state/ZooTabletStateStore.java index f355f291ec,639c72f47f..cbb5c280ac --- a/server/base/src/main/java/org/apache/accumulo/server/manager/state/ZooTabletStateStore.java +++ b/server/base/src/main/java/org/apache/accumulo/server/manager/state/ZooTabletStateStore.java @@@ -26,28 -22,23 +26,29 @@@ import java.util.AbstractMap import java.util.Collection; import java.util.List; import java.util.Map; - -import org.apache.accumulo.core.clientImpl.ClientContext; +import java.util.Map.Entry; +import java.util.NoSuchElementException; +import java.util.concurrent.atomic.AtomicBoolean; + +import org.apache.accumulo.core.data.Key; +import org.apache.accumulo.core.data.Range; +import org.apache.accumulo.core.data.Value; +import org.apache.accumulo.core.iterators.IteratorUtil.IteratorScope; +import org.apache.accumulo.core.iterators.user.WholeRowIterator; +import org.apache.accumulo.core.iteratorsImpl.system.SortedMapIterator; +import org.apache.accumulo.core.manager.state.TabletManagement; +import org.apache.accumulo.core.metadata.AccumuloTable; import org.apache.accumulo.core.metadata.RootTable; import org.apache.accumulo.core.metadata.TServerInstance; -import org.apache.accumulo.core.metadata.TabletLocationState; -import org.apache.accumulo.core.metadata.TabletLocationState.BadLocationStateException; import org.apache.accumulo.core.metadata.schema.Ample; import org.apache.accumulo.core.metadata.schema.Ample.DataLevel; -import org.apache.accumulo.core.metadata.schema.Ample.ReadConsistency; -import org.apache.accumulo.core.metadata.schema.Ample.TabletMutator; +import org.apache.accumulo.core.metadata.schema.RootTabletMetadata; import org.apache.accumulo.core.metadata.schema.TabletMetadata; -import org.apache.accumulo.core.metadata.schema.TabletMetadata.Location; -import org.apache.accumulo.core.metadata.schema.TabletMetadata.LocationType; -import org.apache.accumulo.core.tabletserver.log.LogEntry; + import org.apache.accumulo.core.util.time.SteadyTime; -import org.apache.accumulo.server.util.ManagerMetadataUtil; +import org.apache.accumulo.server.ServerContext; +import org.apache.accumulo.server.iterators.TabletIteratorEnvironment; import org.apache.hadoop.fs.Path; +import org.apache.zookeeper.KeeperException; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@@ -189,17 -188,11 +190,17 @@@ class ZooTabletStateStore extends Abstr } @Override - public void suspend(Collection<TabletLocationState> tablets, + public void suspend(Collection<TabletMetadata> tablets, - Map<TServerInstance,List<Path>> logsForDeadServers, long suspensionTimestamp) + Map<TServerInstance,List<Path>> logsForDeadServers, SteadyTime suspensionTimestamp) throws DistributedStoreException { - // No support for suspending root tablet. - unassign(tablets, logsForDeadServers); + validateTablets(tablets); + super.suspend(tablets, logsForDeadServers, suspensionTimestamp); + } + + @Override + protected void processSuspension(Ample.ConditionalTabletMutator tabletMutator, TabletMetadata tm, - long suspensionTimestamp) { ++ SteadyTime suspensionTimestamp) { + // No support for suspending root tablet, so this is a NOOP } @Override diff --cc server/manager/src/main/java/org/apache/accumulo/manager/TabletGroupWatcher.java index ca69231394,7adba90fe0..7ab6415646 --- a/server/manager/src/main/java/org/apache/accumulo/manager/TabletGroupWatcher.java +++ b/server/manager/src/main/java/org/apache/accumulo/manager/TabletGroupWatcher.java @@@ -768,9 -452,9 +768,9 @@@ abstract class TabletGroupWatcher exten } } - private void hostSuspendedTablet(TabletLists tLists, TabletLocationState tls, Location location, + private void hostSuspendedTablet(TabletLists tLists, TabletMetadata tm, Location location, TableConfiguration tableConf) { - if (manager.getSteadyTime().getMillis() - tm.getSuspend().suspensionTime - if (manager.getSteadyTime().minus(tls.suspend.suspensionTime).toMillis() ++ if (manager.getSteadyTime().minus(tm.getSuspend().suspensionTime).toMillis() < tableConf.getTimeInMillis(Property.TABLE_SUSPEND_DURATION)) { // Tablet is suspended. See if its tablet server is back. TServerInstance returnInstance = null; diff --cc server/tserver/src/main/java/org/apache/accumulo/tserver/TabletClientHandler.java index a1770b90cb,af16beed4c..4309c0bfe8 --- a/server/tserver/src/main/java/org/apache/accumulo/tserver/TabletClientHandler.java +++ b/server/tserver/src/main/java/org/apache/accumulo/tserver/TabletClientHandler.java @@@ -92,7 -101,9 +92,8 @@@ import org.apache.accumulo.core.tablets import org.apache.accumulo.core.trace.TraceUtil; import org.apache.accumulo.core.util.ByteBufferUtil; import org.apache.accumulo.core.util.Halt; -import org.apache.accumulo.core.util.Pair; import org.apache.accumulo.core.util.threads.Threads; + import org.apache.accumulo.core.util.time.SteadyTime; import org.apache.accumulo.server.ServerContext; import org.apache.accumulo.server.compaction.CompactionInfo; import org.apache.accumulo.server.compaction.FileCompactor; diff --cc server/tserver/src/main/java/org/apache/accumulo/tserver/UnloadTabletHandler.java index a1d46257ec,27c1048b24..c7db2ed117 --- a/server/tserver/src/main/java/org/apache/accumulo/tserver/UnloadTabletHandler.java +++ b/server/tserver/src/main/java/org/apache/accumulo/tserver/UnloadTabletHandler.java @@@ -21,10 -21,13 +21,10 @@@ package org.apache.accumulo.tserver import org.apache.accumulo.core.conf.Property; import org.apache.accumulo.core.dataImpl.KeyExtent; import org.apache.accumulo.core.manager.thrift.TabletLoadState; -import org.apache.accumulo.core.metadata.TServerInstance; -import org.apache.accumulo.core.metadata.TabletLocationState; -import org.apache.accumulo.core.metadata.TabletLocationState.BadLocationStateException; -import org.apache.accumulo.core.metadata.schema.TabletMetadata.Location; +import org.apache.accumulo.core.metadata.schema.TabletMetadata; import org.apache.accumulo.core.tablet.thrift.TUnloadTabletGoal; + import org.apache.accumulo.core.util.time.NanoTime; + import org.apache.accumulo.core.util.time.SteadyTime; import org.apache.accumulo.server.manager.state.DistributedStoreException; import org.apache.accumulo.server.manager.state.TabletStateStore; import org.apache.accumulo.tserver.managermessage.TabletStatusMessage; @@@ -109,10 -120,10 +111,10 @@@ class UnloadTabletHandler implements Ru if (!goalState.equals(TUnloadTabletGoal.SUSPENDED) || extent.isRootTablet() || (extent.isMeta() && !server.getConfiguration().getBoolean(Property.MANAGER_METADATA_SUSPENDABLE))) { - TabletStateStore.unassign(server.getContext(), tls, null); + TabletStateStore.unassign(server.getContext(), tm, null); } else { - TabletStateStore.suspend(server.getContext(), tls, null, + TabletStateStore.suspend(server.getContext(), tm, null, - requestTimeSkew + NANOSECONDS.toMillis(System.nanoTime())); + requestTime.plus(createTime.elapsed())); } } catch (DistributedStoreException ex) { log.warn("Unable to update storage", ex);