[NO ISSUE][STO] Adapt Storage Structure To Rebalance - user model changes: no - storage format changes: no - interface changes: yes -- Added IResource#setPath to use for the resource storage migration.
Details: - Unify storage structure to support dataset rebalance: Old format: ./storage/partition_#/dataverse/datasetName_idx_indexName New format: ./storage/partition_#/dataverse/datasetName/rebalanaceNum/indexName - Adapt recovery and replication to new storage structure. - Add old structure -> new structure NC migration task. - Add CompatibilityUtil to ensure NC can be upgraded during NC startup. - Centralize the logic for parsing file path to its components in ResourceReference/DatasetResourceReference. - Add storage structure migration test case. - Add test case for recovery after rebalance. Change-Id: I0f968b9f493bf5aa2d49f503afe21f0d438bb7f0 Reviewed-on: https://asterix-gerrit.ics.uci.edu/2181 Sonar-Qube: Jenkins <jenk...@fulliautomatix.ics.uci.edu> Integration-Tests: Jenkins <jenk...@fulliautomatix.ics.uci.edu> Tested-by: Jenkins <jenk...@fulliautomatix.ics.uci.edu> Contrib: Jenkins <jenk...@fulliautomatix.ics.uci.edu> Reviewed-by: abdullah alamoudi <bamou...@gmail.com> Project: http://git-wip-us.apache.org/repos/asf/asterixdb/repo Commit: http://git-wip-us.apache.org/repos/asf/asterixdb/commit/f9e6bae9 Tree: http://git-wip-us.apache.org/repos/asf/asterixdb/tree/f9e6bae9 Diff: http://git-wip-us.apache.org/repos/asf/asterixdb/diff/f9e6bae9 Branch: refs/heads/master Commit: f9e6bae98de7664cab3054a9e06168323ebd894c Parents: 98b9d60 Author: Murtadha Hubail <mhub...@apache.org> Authored: Sat Nov 25 23:25:30 2017 +0300 Committer: Murtadha Hubail <mhub...@apache.org> Committed: Sun Nov 26 15:45:13 2017 -0800 ---------------------------------------------------------------------- .../apache/asterix/app/nc/RecoveryManager.java | 2 +- .../asterix/app/nc/TransactionSubsystem.java | 5 - .../nc/task/MigrateStorageResourcesTask.java | 143 +++++++++++++ .../hyracks/bootstrap/NCApplication.java | 8 +- .../apache/asterix/utils/CompatibilityUtil.java | 66 ++++++ .../http/servlet/ConnectorApiServletTest.java | 2 +- .../org/apache/asterix/common/TestDataUtil.java | 124 +++++++++++ .../MigrateStorageResourcesTaskTest.java | 104 ++++++++++ .../asterix/test/txn/RecoveryManagerTest.java | 77 ++++--- .../rebalance/all_datasets/all_datasets.11.adm | 2 +- .../rebalance/all_datasets/all_datasets.12.adm | 2 +- .../rebalance/all_datasets/all_datasets.5.adm | 2 +- .../rebalance/all_datasets/all_datasets.6.adm | 2 +- .../single_dataset/single_dataset.5.adm | 2 +- .../single_dataset/single_dataset.9.adm | 2 +- .../single_dataset_with_index.10.adm | 2 +- .../single_dataset_with_index.5.adm | 2 +- .../single_dataverse/single_dataverse.11.adm | 2 +- .../single_dataverse/single_dataverse.12.adm | 2 +- .../single_dataverse/single_dataverse.5.adm | 2 +- .../single_dataverse/single_dataverse.6.adm | 2 +- .../common/dataflow/DatasetLocalResource.java | 5 + .../replication/IReplicaResourcesManager.java | 5 +- .../storage/DatasetResourceReference.java | 77 +++++++ .../common/storage/IndexFileProperties.java | 74 ------- .../common/storage/IndexPathElements.java | 44 ++++ .../common/storage/ResourceReference.java | 110 ++++++++++ .../asterix/common/utils/StorageConstants.java | 18 +- .../asterix/common/utils/StoragePathUtil.java | 23 ++- asterixdb/asterix-replication/pom.xml | 5 - .../management/ReplicationChannel.java | 4 +- .../management/ReplicationManager.java | 4 +- .../storage/LSMComponentProperties.java | 41 +--- .../storage/LSMIndexFileProperties.java | 46 +---- .../storage/ReplicaResourcesManager.java | 80 +++---- .../PersistentLocalResourceRepository.java | 207 +++++++------------ .../recovery/ReplicationCheckpointManager.java | 2 +- .../am/btree/dataflow/BTreeResource.java | 7 +- .../am/lsm/common/dataflow/LsmResource.java | 17 +- .../am/rtree/dataflow/RTreeResource.java | 6 +- .../hyracks/storage/common/IResource.java | 7 + 41 files changed, 904 insertions(+), 433 deletions(-) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/asterixdb/blob/f9e6bae9/asterixdb/asterix-app/src/main/java/org/apache/asterix/app/nc/RecoveryManager.java ---------------------------------------------------------------------- diff --git a/asterixdb/asterix-app/src/main/java/org/apache/asterix/app/nc/RecoveryManager.java b/asterixdb/asterix-app/src/main/java/org/apache/asterix/app/nc/RecoveryManager.java index 19966fe..e29e3fe 100644 --- a/asterixdb/asterix-app/src/main/java/org/apache/asterix/app/nc/RecoveryManager.java +++ b/asterixdb/asterix-app/src/main/java/org/apache/asterix/app/nc/RecoveryManager.java @@ -443,7 +443,7 @@ public class RecoveryManager implements IRecoveryManager, ILifeCycleComponent { return minFirstLSN; } - private long getRemoteMinFirstLSN() { + private long getRemoteMinFirstLSN() throws HyracksDataException { IReplicaResourcesManager remoteResourcesManager = txnSubsystem.getAsterixAppRuntimeContextProvider().getAppContext().getReplicaResourcesManager(); return remoteResourcesManager.getPartitionsMinLSN(localResourceRepository.getInactivePartitions()); http://git-wip-us.apache.org/repos/asf/asterixdb/blob/f9e6bae9/asterixdb/asterix-app/src/main/java/org/apache/asterix/app/nc/TransactionSubsystem.java ---------------------------------------------------------------------- diff --git a/asterixdb/asterix-app/src/main/java/org/apache/asterix/app/nc/TransactionSubsystem.java b/asterixdb/asterix-app/src/main/java/org/apache/asterix/app/nc/TransactionSubsystem.java index f922832..47f9315 100644 --- a/asterixdb/asterix-app/src/main/java/org/apache/asterix/app/nc/TransactionSubsystem.java +++ b/asterixdb/asterix-app/src/main/java/org/apache/asterix/app/nc/TransactionSubsystem.java @@ -81,11 +81,6 @@ public class TransactionSubsystem implements ITransactionSubsystem { checkpointManager = CheckpointManagerFactory.create(this, checkpointProperties, replicationEnabled); final Checkpoint latestCheckpoint = checkpointManager.getLatest(); if (latestCheckpoint != null) { - if (latestCheckpoint.getStorageVersion() != StorageConstants.VERSION) { - throw new IllegalStateException( - String.format("Storage version mismatch. Current version (%s). On disk version: (%s)", - StorageConstants.VERSION, latestCheckpoint.getStorageVersion())); - } transactionManager.ensureMaxTxnId(latestCheckpoint.getMaxTxnId()); } http://git-wip-us.apache.org/repos/asf/asterixdb/blob/f9e6bae9/asterixdb/asterix-app/src/main/java/org/apache/asterix/app/nc/task/MigrateStorageResourcesTask.java ---------------------------------------------------------------------- diff --git a/asterixdb/asterix-app/src/main/java/org/apache/asterix/app/nc/task/MigrateStorageResourcesTask.java b/asterixdb/asterix-app/src/main/java/org/apache/asterix/app/nc/task/MigrateStorageResourcesTask.java new file mode 100644 index 0000000..503b8de --- /dev/null +++ b/asterixdb/asterix-app/src/main/java/org/apache/asterix/app/nc/task/MigrateStorageResourcesTask.java @@ -0,0 +1,143 @@ +/* + * 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 + * + * http://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.asterix.app.nc.task; + +import java.io.IOException; +import java.nio.file.Files; +import java.nio.file.Path; +import java.nio.file.Paths; +import java.util.List; +import java.util.function.Predicate; +import java.util.logging.Logger; +import java.util.stream.Collectors; +import java.util.stream.Stream; + +import org.apache.asterix.common.api.INCLifecycleTask; +import org.apache.asterix.common.api.INcApplicationContext; +import org.apache.asterix.common.dataflow.DatasetLocalResource; +import org.apache.asterix.common.storage.DatasetResourceReference; +import org.apache.asterix.common.transactions.Checkpoint; +import org.apache.asterix.common.transactions.ICheckpointManager; +import org.apache.asterix.common.utils.StorageConstants; +import org.apache.asterix.transaction.management.resource.PersistentLocalResourceRepository; +import org.apache.commons.io.FileUtils; +import org.apache.hyracks.api.exceptions.HyracksDataException; +import org.apache.hyracks.api.io.FileReference; +import org.apache.hyracks.api.io.IIOManager; +import org.apache.hyracks.api.io.IODeviceHandle; +import org.apache.hyracks.api.service.IControllerService; +import org.apache.hyracks.storage.common.ILocalResourceRepository; +import org.apache.hyracks.storage.common.LocalResource; + +/** + * Migrates a legacy storage structure to the current one + */ +public class MigrateStorageResourcesTask implements INCLifecycleTask { + + private static final Logger LOGGER = Logger.getLogger(MigrateStorageResourcesTask.class.getName()); + private static final long serialVersionUID = 1L; + public static final int LEGACY_RESOURCES_TREE_DEPTH_FROM_STORAGE_ROOT = 5; + + @Override + public void perform(IControllerService cs) throws HyracksDataException { + final INcApplicationContext appCtx = (INcApplicationContext) cs.getApplicationContext(); + final ICheckpointManager checkpointMgr = appCtx.getTransactionSubsystem().getCheckpointManager(); + final Checkpoint latestCheckpoint = checkpointMgr.getLatest(); + if (latestCheckpoint == null) { + // nothing to migrate + return; + } + final IIOManager ioManager = appCtx.getIoManager(); + final List<IODeviceHandle> ioDevices = ioManager.getIODevices(); + for (IODeviceHandle ioDeviceHandle : ioDevices) { + final Path root = Paths.get(ioDeviceHandle.getMount().getAbsolutePath()); + if (!root.toFile().exists()) { + continue; + } + try (Stream<Path> stream = Files.find(root, LEGACY_RESOURCES_TREE_DEPTH_FROM_STORAGE_ROOT, + (path, attr) -> path.getFileName().toString().equals(StorageConstants.METADATA_FILE_NAME))) { + final List<Path> resourceToMigrate = stream.map(Path::getParent).collect(Collectors.toList()); + for (Path src : resourceToMigrate) { + final Path dest = + migrateResourceMetadata(root.relativize(src), appCtx, latestCheckpoint.getStorageVersion()); + copyResourceFiles(root.resolve(src), root.resolve(dest), + PersistentLocalResourceRepository.INDEX_COMPONENTS); + FileUtils.deleteDirectory(root.resolve(src).toFile()); + } + } catch (IOException e) { + throw HyracksDataException.create(e); + } + } + } + + /** + * Migrates the resource metadata file at {@code resourcePath} to the new storage structure + * and updates the migrated resource's metadata to reflect the new path. + * + * @param resourcePath + * @param appCtx + * @param resourceVersion + * @return The migrated resource relative path + * @throws HyracksDataException + */ + private Path migrateResourceMetadata(Path resourcePath, INcApplicationContext appCtx, int resourceVersion) + throws HyracksDataException { + final ILocalResourceRepository localResourceRepository = appCtx.getLocalResourceRepository(); + final LocalResource srcResource = localResourceRepository.get(resourcePath.toFile().getPath()); + final DatasetLocalResource lsmResource = (DatasetLocalResource) srcResource.getResource(); + // recreate the resource with the new path and version + final DatasetResourceReference lrr = DatasetResourceReference.of(srcResource, resourceVersion); + final Path destPath = lrr.getRelativePath(); + final FileReference destDir = appCtx.getIoManager().resolve(destPath.toString()); + // ensure the new dest dir is empty + if (destDir.getFile().exists()) { + FileUtils.deleteQuietly(destDir.getFile()); + } + lsmResource.setPath(destPath.toString()); + + final LocalResource destResource = + new LocalResource(srcResource.getId(), srcResource.getVersion(), srcResource.isDurable(), lsmResource); + LOGGER.info(() -> "Migrating resource from: " + srcResource.getPath() + " to " + destResource.getPath()); + localResourceRepository.insert(destResource); + return destPath; + } + + /** + * Copies the files matching {@code filter} at {@code src} path to {@code dest} + * + * @param src + * @param dest + * @param filter + * @throws IOException + */ + private void copyResourceFiles(Path src, Path dest, Predicate<Path> filter) throws IOException { + try (Stream<Path> stream = Files.list(src)) { + final List<Path> srcFiles = stream.filter(filter).collect(Collectors.toList()); + for (Path srcFile : srcFiles) { + Path fileDest = Paths.get(dest.toString(), srcFile.getFileName().toString()); + Files.copy(srcFile, fileDest); + } + } + } + + @Override + public String toString() { + return "{ \"class\" : \"" + getClass().getSimpleName() + "\" }"; + } +} http://git-wip-us.apache.org/repos/asf/asterixdb/blob/f9e6bae9/asterixdb/asterix-app/src/main/java/org/apache/asterix/hyracks/bootstrap/NCApplication.java ---------------------------------------------------------------------- diff --git a/asterixdb/asterix-app/src/main/java/org/apache/asterix/hyracks/bootstrap/NCApplication.java b/asterixdb/asterix-app/src/main/java/org/apache/asterix/hyracks/bootstrap/NCApplication.java index 63f5bfc..47e5ac9 100644 --- a/asterixdb/asterix-app/src/main/java/org/apache/asterix/hyracks/bootstrap/NCApplication.java +++ b/asterixdb/asterix-app/src/main/java/org/apache/asterix/hyracks/bootstrap/NCApplication.java @@ -37,6 +37,7 @@ import org.apache.asterix.common.config.MetadataProperties; import org.apache.asterix.common.config.NodeProperties; import org.apache.asterix.common.config.StorageProperties; import org.apache.asterix.common.config.TransactionProperties; +import org.apache.asterix.common.transactions.Checkpoint; import org.apache.asterix.common.transactions.IRecoveryManager; import org.apache.asterix.common.transactions.IRecoveryManager.SystemState; import org.apache.asterix.common.utils.PrintUtil; @@ -46,6 +47,7 @@ import org.apache.asterix.event.schema.cluster.Node; import org.apache.asterix.messaging.MessagingChannelInterfaceFactory; import org.apache.asterix.messaging.NCMessageBroker; import org.apache.asterix.transaction.management.resource.PersistentLocalResourceRepository; +import org.apache.asterix.utils.CompatibilityUtil; import org.apache.hyracks.api.application.INCServiceContext; import org.apache.hyracks.api.application.IServiceContext; import org.apache.hyracks.api.client.NodeStatus; @@ -54,7 +56,6 @@ import org.apache.hyracks.api.exceptions.HyracksDataException; import org.apache.hyracks.api.io.IFileDeviceResolver; import org.apache.hyracks.api.job.resource.NodeCapacity; import org.apache.hyracks.api.messages.IMessageBroker; -import org.apache.hyracks.api.util.IoUtil; import org.apache.hyracks.control.common.controllers.NCConfig; import org.apache.hyracks.control.nc.BaseNCApplication; import org.apache.hyracks.control.nc.NodeControllerService; @@ -115,7 +116,10 @@ public class NCApplication extends BaseNCApplication { MessagingChannelInterfaceFactory interfaceFactory = new MessagingChannelInterfaceFactory((NCMessageBroker) messageBroker, messagingProperties); this.ncServiceCtx.setMessagingChannelInterfaceFactory(interfaceFactory); - + final Checkpoint latestCheckpoint = runtimeContext.getTransactionSubsystem().getCheckpointManager().getLatest(); + if (latestCheckpoint != null) { + CompatibilityUtil.ensureCompatibility(controllerService, latestCheckpoint.getStorageVersion()); + } IRecoveryManager recoveryMgr = runtimeContext.getTransactionSubsystem().getRecoveryManager(); final SystemState stateOnStartup = recoveryMgr.getSystemState(); if (stateOnStartup == SystemState.PERMANENT_DATA_LOSS) { http://git-wip-us.apache.org/repos/asf/asterixdb/blob/f9e6bae9/asterixdb/asterix-app/src/main/java/org/apache/asterix/utils/CompatibilityUtil.java ---------------------------------------------------------------------- diff --git a/asterixdb/asterix-app/src/main/java/org/apache/asterix/utils/CompatibilityUtil.java b/asterixdb/asterix-app/src/main/java/org/apache/asterix/utils/CompatibilityUtil.java new file mode 100644 index 0000000..5d44fc9 --- /dev/null +++ b/asterixdb/asterix-app/src/main/java/org/apache/asterix/utils/CompatibilityUtil.java @@ -0,0 +1,66 @@ +/* + * 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 + * + * http://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.asterix.utils; + +import java.util.ArrayList; +import java.util.List; +import java.util.logging.Logger; + +import org.apache.asterix.app.nc.task.MigrateStorageResourcesTask; +import org.apache.asterix.common.api.INCLifecycleTask; +import org.apache.asterix.common.utils.StorageConstants; +import org.apache.hyracks.api.exceptions.HyracksDataException; +import org.apache.hyracks.control.nc.NodeControllerService; + +public class CompatibilityUtil { + + private static final Logger LOGGER = Logger.getLogger(CompatibilityUtil.class.getName()); + private static final int MIN_COMPATIBLE_VERSION = 1; + + private CompatibilityUtil() { + } + + public static void ensureCompatibility(NodeControllerService ncs, int onDiskVerson) throws HyracksDataException { + if (onDiskVerson == StorageConstants.VERSION) { + return; + } + ensureUpgradability(onDiskVerson); + LOGGER.info(() -> "Upgrading from storage version " + onDiskVerson + " to " + StorageConstants.VERSION); + final List<INCLifecycleTask> upgradeTasks = getUpgradeTasks(onDiskVerson); + for (INCLifecycleTask task : upgradeTasks) { + task.perform(ncs); + } + } + + private static void ensureUpgradability(int onDiskVerson) { + if (onDiskVerson < MIN_COMPATIBLE_VERSION) { + throw new IllegalStateException(String.format( + "Storage cannot be upgraded to new version. Current version (%s). On disk version: (%s)", + StorageConstants.VERSION, onDiskVerson)); + } + } + + private static List<INCLifecycleTask> getUpgradeTasks(int fromVersion) { + List<INCLifecycleTask> upgradeTasks = new ArrayList<>(); + if (fromVersion < StorageConstants.REBALANCE_STORAGE_VERSION) { + upgradeTasks.add(new MigrateStorageResourcesTask()); + } + return upgradeTasks; + } +} \ No newline at end of file http://git-wip-us.apache.org/repos/asf/asterixdb/blob/f9e6bae9/asterixdb/asterix-app/src/test/java/org/apache/asterix/api/http/servlet/ConnectorApiServletTest.java ---------------------------------------------------------------------- diff --git a/asterixdb/asterix-app/src/test/java/org/apache/asterix/api/http/servlet/ConnectorApiServletTest.java b/asterixdb/asterix-app/src/test/java/org/apache/asterix/api/http/servlet/ConnectorApiServletTest.java index 33f3a42..87ee2ef 100644 --- a/asterixdb/asterix-app/src/test/java/org/apache/asterix/api/http/servlet/ConnectorApiServletTest.java +++ b/asterixdb/asterix-app/src/test/java/org/apache/asterix/api/http/servlet/ConnectorApiServletTest.java @@ -122,7 +122,7 @@ public class ConnectorApiServletTest { // Checks the correctness of results. ArrayNode splits = (ArrayNode) actualResponse.get("splits"); String path = (splits.get(0)).get("path").asText(); - Assert.assertTrue(path.endsWith("Metadata/Dataset_idx_Dataset")); + Assert.assertTrue(path.endsWith("Metadata/Dataset/0/Dataset")); } @Test http://git-wip-us.apache.org/repos/asf/asterixdb/blob/f9e6bae9/asterixdb/asterix-app/src/test/java/org/apache/asterix/common/TestDataUtil.java ---------------------------------------------------------------------- diff --git a/asterixdb/asterix-app/src/test/java/org/apache/asterix/common/TestDataUtil.java b/asterixdb/asterix-app/src/test/java/org/apache/asterix/common/TestDataUtil.java new file mode 100644 index 0000000..e24ef2d --- /dev/null +++ b/asterixdb/asterix-app/src/test/java/org/apache/asterix/common/TestDataUtil.java @@ -0,0 +1,124 @@ +/* + * 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 + * + * http://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.asterix.common; + +import java.io.InputStream; +import java.util.Arrays; +import java.util.LinkedHashSet; + +import org.apache.asterix.api.common.AsterixHyracksIntegrationUtil; +import org.apache.asterix.app.active.ActiveNotificationHandler; +import org.apache.asterix.common.api.IMetadataLockManager; +import org.apache.asterix.common.dataflow.ICcApplicationContext; +import org.apache.asterix.common.utils.Servlets; +import org.apache.asterix.metadata.declared.MetadataProvider; +import org.apache.asterix.rebalance.NoOpDatasetRebalanceCallback; +import org.apache.asterix.test.common.TestExecutor; +import org.apache.asterix.testframework.context.TestCaseContext; +import org.apache.asterix.utils.RebalanceUtil; +import org.junit.Assert; + +import com.fasterxml.jackson.databind.JsonNode; +import com.fasterxml.jackson.databind.ObjectMapper; +import com.fasterxml.jackson.databind.node.ObjectNode; + +public class TestDataUtil { + + private static final TestExecutor TEST_EXECUTOR = new TestExecutor(); + private static final TestCaseContext.OutputFormat OUTPUT_FORMAT = TestCaseContext.OutputFormat.CLEAN_JSON; + private static final ObjectMapper OBJECT_MAPPER = new ObjectMapper(); + + private TestDataUtil() { + } + + /** + * Creates dataset with a single field called id as its primary key. + * + * @param dataset + * @throws Exception + */ + public static void createIdOnlyDataset(String dataset) throws Exception { + TEST_EXECUTOR.executeSqlppUpdateOrDdl("CREATE TYPE KeyType IF NOT EXISTS AS { id: int };", OUTPUT_FORMAT); + TEST_EXECUTOR.executeSqlppUpdateOrDdl("CREATE DATASET " + dataset + "(KeyType) PRIMARY KEY id;", OUTPUT_FORMAT); + } + + /** + * Upserts {@code count} ids into {@code dataset} + * + * @param dataset + * @param count + * @throws Exception + */ + public static void upsertData(String dataset, long count) throws Exception { + for (int i = 0; i < count; i++) { + TEST_EXECUTOR.executeSqlppUpdateOrDdl("UPSERT INTO " + dataset + " ({\"id\": " + i + "});", + TestCaseContext.OutputFormat.CLEAN_JSON); + } + } + + /** + * Gets the number of records in dataset {@code dataset} + * + * @param datasetName + * @return The count + * @throws Exception + */ + public static long getDatasetCount(String datasetName) throws Exception { + final String query = "SELECT VALUE COUNT(*) FROM `" + datasetName + "`;"; + final InputStream responseStream = TEST_EXECUTOR + .executeQueryService(query, TEST_EXECUTOR.getEndpoint(Servlets.QUERY_SERVICE), OUTPUT_FORMAT); + final ObjectNode response = OBJECT_MAPPER.readValue(responseStream, ObjectNode.class); + final JsonNode result = response.get("results"); + // make sure there is a single value in result + Assert.assertEquals(1, result.size()); + return result.get(0).asInt(); + } + + /** + * Rebalances a dataset to {@code targetNodes} + * + * @param integrationUtil + * @param dataverseName + * @param datasetName + * @param targetNodes + * @throws Exception + */ + public static void rebalanceDataset(AsterixHyracksIntegrationUtil integrationUtil, String dataverseName, + String datasetName, String[] targetNodes) throws Exception { + ICcApplicationContext ccAppCtx = + (ICcApplicationContext) integrationUtil.getClusterControllerService().getApplicationContext(); + MetadataProvider metadataProvider = new MetadataProvider(ccAppCtx, null); + try { + ActiveNotificationHandler activeNotificationHandler = + (ActiveNotificationHandler) ccAppCtx.getActiveNotificationHandler(); + activeNotificationHandler.suspend(metadataProvider); + try { + IMetadataLockManager lockManager = ccAppCtx.getMetadataLockManager(); + lockManager.acquireDatasetExclusiveModificationLock(metadataProvider.getLocks(), + dataverseName + '.' + datasetName); + RebalanceUtil.rebalance(dataverseName, datasetName, new LinkedHashSet<>(Arrays.asList(targetNodes)), + metadataProvider, ccAppCtx.getHcc(), NoOpDatasetRebalanceCallback.INSTANCE); + } finally { + activeNotificationHandler.resume(metadataProvider); + } + } finally { + metadataProvider.getLocks().unlock(); + } + } +} http://git-wip-us.apache.org/repos/asf/asterixdb/blob/f9e6bae9/asterixdb/asterix-app/src/test/java/org/apache/asterix/test/storage/MigrateStorageResourcesTaskTest.java ---------------------------------------------------------------------- diff --git a/asterixdb/asterix-app/src/test/java/org/apache/asterix/test/storage/MigrateStorageResourcesTaskTest.java b/asterixdb/asterix-app/src/test/java/org/apache/asterix/test/storage/MigrateStorageResourcesTaskTest.java new file mode 100644 index 0000000..5b53041 --- /dev/null +++ b/asterixdb/asterix-app/src/test/java/org/apache/asterix/test/storage/MigrateStorageResourcesTaskTest.java @@ -0,0 +1,104 @@ +/* + * 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 + * + * http://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.asterix.test.storage; + +import java.io.BufferedWriter; +import java.io.File; +import java.io.IOException; +import java.nio.file.Files; +import java.nio.file.Path; +import java.util.function.Function; + +import org.apache.asterix.api.common.AsterixHyracksIntegrationUtil; +import org.apache.asterix.common.TestDataUtil; +import org.apache.asterix.common.api.INcApplicationContext; +import org.apache.asterix.common.config.GlobalConfig; +import org.apache.asterix.common.storage.IndexPathElements; +import org.apache.asterix.common.transactions.Checkpoint; +import org.apache.asterix.common.utils.StorageConstants; +import org.apache.asterix.common.utils.StoragePathUtil; +import org.apache.asterix.transaction.management.service.recovery.AbstractCheckpointManager; +import org.apache.hyracks.api.exceptions.HyracksDataException; +import org.junit.After; +import org.junit.Assert; +import org.junit.Before; +import org.junit.Test; + +public class MigrateStorageResourcesTaskTest { + + private static final String DEFAULT_TEST_CONFIG_FILE_NAME = "asterix-build-configuration.xml"; + private static final AsterixHyracksIntegrationUtil integrationUtil = new AsterixHyracksIntegrationUtil(); + + @Before + public void setUp() throws Exception { + System.setProperty(GlobalConfig.CONFIG_FILE_PROPERTY, DEFAULT_TEST_CONFIG_FILE_NAME); + } + + @After + public void tearDown() throws Exception { + integrationUtil.deinit(true); + } + + @Test + public void storageStructureMigration() throws Exception { + Function<IndexPathElements, String> legacyIndexPathProvider = (pathElements) -> + (pathElements.getRebalanceCount().equals("0") ? "" : pathElements.getRebalanceCount() + File.separator) + + pathElements.getDatasetName() + StoragePathUtil.DATASET_INDEX_NAME_SEPARATOR + pathElements + .getIndexName(); + StoragePathUtil.setIndexPathProvider(legacyIndexPathProvider); + integrationUtil.init(true); + // create dataset and insert data using legacy structure + String datasetName = "ds"; + TestDataUtil.createIdOnlyDataset(datasetName); + TestDataUtil.upsertData(datasetName, 100); + final long countBeforeMigration = TestDataUtil.getDatasetCount(datasetName); + // stop NCs + integrationUtil.deinit(false); + // forge a checkpoint with old version to force migration to new storage structure on all ncs + final INcApplicationContext nc1AppCtx = (INcApplicationContext) integrationUtil.ncs[0].getApplicationContext(); + final AbstractCheckpointManager nc1CheckpointManager = + (AbstractCheckpointManager) nc1AppCtx.getTransactionSubsystem().getCheckpointManager(); + forgeOldVersionCheckpoint(nc1CheckpointManager); + final INcApplicationContext nc2AppCtx = (INcApplicationContext) integrationUtil.ncs[1].getApplicationContext(); + final AbstractCheckpointManager nc2CheckpointManager = + (AbstractCheckpointManager) nc2AppCtx.getTransactionSubsystem().getCheckpointManager(); + forgeOldVersionCheckpoint(nc2CheckpointManager); + + // remove the legacy path provider to use the new default structure + StoragePathUtil.setIndexPathProvider(null); + // start the NCs to do the migration + integrationUtil.init(false); + final long countAfterMigration = TestDataUtil.getDatasetCount(datasetName); + // ensure data migrated to new structure without issues + Assert.assertEquals(countBeforeMigration, countAfterMigration); + } + + private void forgeOldVersionCheckpoint(AbstractCheckpointManager manger) throws HyracksDataException { + Checkpoint cp = new Checkpoint(-1, -1, 0, System.currentTimeMillis(), true, + StorageConstants.REBALANCE_STORAGE_VERSION - 1); + Path path = manger.getCheckpointPath(cp.getTimeStamp()); + // Write checkpoint file to disk + try (BufferedWriter writer = Files.newBufferedWriter(path)) { + writer.write(cp.asJson()); + writer.flush(); + } catch (IOException e) { + throw HyracksDataException.create(e); + } + } +} http://git-wip-us.apache.org/repos/asf/asterixdb/blob/f9e6bae9/asterixdb/asterix-app/src/test/java/org/apache/asterix/test/txn/RecoveryManagerTest.java ---------------------------------------------------------------------- diff --git a/asterixdb/asterix-app/src/test/java/org/apache/asterix/test/txn/RecoveryManagerTest.java b/asterixdb/asterix-app/src/test/java/org/apache/asterix/test/txn/RecoveryManagerTest.java index 723786c..29efa47 100644 --- a/asterixdb/asterix-app/src/test/java/org/apache/asterix/test/txn/RecoveryManagerTest.java +++ b/asterixdb/asterix-app/src/test/java/org/apache/asterix/test/txn/RecoveryManagerTest.java @@ -19,38 +19,30 @@ package org.apache.asterix.test.txn; import java.io.File; -import java.io.InputStream; -import java.util.Random; +import java.util.logging.ConsoleHandler; +import java.util.logging.Level; +import java.util.logging.Logger; import org.apache.asterix.api.common.AsterixHyracksIntegrationUtil; +import org.apache.asterix.common.TestDataUtil; import org.apache.asterix.common.config.GlobalConfig; import org.apache.asterix.common.configuration.AsterixConfiguration; import org.apache.asterix.common.configuration.Property; -import org.apache.asterix.common.utils.Servlets; -import org.apache.asterix.test.common.TestExecutor; +import org.apache.asterix.metadata.bootstrap.MetadataBuiltinEntities; import org.apache.asterix.test.common.TestHelper; -import org.apache.asterix.testframework.context.TestCaseContext; import org.junit.After; import org.junit.Assert; import org.junit.Before; import org.junit.Test; -import com.fasterxml.jackson.databind.JsonNode; -import com.fasterxml.jackson.databind.ObjectMapper; -import com.fasterxml.jackson.databind.node.ObjectNode; - public class RecoveryManagerTest { - private static final ObjectMapper OBJECT_MAPPER = new ObjectMapper(); private static final String DEFAULT_TEST_CONFIG_FILE_NAME = "asterix-build-configuration.xml"; private static final String TEST_CONFIG_FILE_NAME = "asterix-test-configuration.xml"; private static final String TEST_CONFIG_PATH = System.getProperty("user.dir") + File.separator + "target" + File.separator + "config"; private static final String TEST_CONFIG_FILE_PATH = TEST_CONFIG_PATH + File.separator + TEST_CONFIG_FILE_NAME; - private static final TestExecutor testExecutor = new TestExecutor(); private static final AsterixHyracksIntegrationUtil integrationUtil = new AsterixHyracksIntegrationUtil(); - private static final Random random = new Random(); - private static final int numRecords = 1; @Before public void setUp() throws Exception { @@ -74,52 +66,53 @@ public class RecoveryManagerTest { @Test public void multiDatasetRecovery() throws Exception { String datasetNamePrefix = "ds_"; - final TestCaseContext.OutputFormat format = TestCaseContext.OutputFormat.CLEAN_JSON; - testExecutor.executeSqlppUpdateOrDdl("CREATE TYPE KeyType AS { id: int };", format); int numDatasets = 50; String datasetName = null; for (int i = 1; i <= numDatasets; i++) { datasetName = datasetNamePrefix + i; - testExecutor.executeSqlppUpdateOrDdl("CREATE DATASET " + datasetName + "(KeyType) PRIMARY KEY id;", format); - insertData(datasetName); + TestDataUtil.createIdOnlyDataset(datasetName); + TestDataUtil.upsertData(datasetName, 10); } + final long countBeforeFirstRecovery = TestDataUtil.getDatasetCount(datasetName); // do ungraceful shutdown to enforce recovery integrationUtil.deinit(false); integrationUtil.init(false); - validateRecovery(datasetName); - + final long countAfterFirstRecovery = TestDataUtil.getDatasetCount(datasetName); + Assert.assertEquals(countBeforeFirstRecovery, countAfterFirstRecovery); // create more datasets after recovery numDatasets = 100; for (int i = 51; i <= numDatasets; i++) { datasetName = datasetNamePrefix + i; - testExecutor.executeSqlppUpdateOrDdl("CREATE DATASET " + datasetName + "(KeyType) PRIMARY KEY id;", format); - insertData(datasetName); + TestDataUtil.createIdOnlyDataset(datasetName); + TestDataUtil.upsertData(datasetName, 1); } + final long countBeforeSecondRecovery = TestDataUtil.getDatasetCount(datasetName); // do ungraceful shutdown to enforce recovery again integrationUtil.deinit(false); integrationUtil.init(false); - validateRecovery(datasetName); - } - - private void insertData(String datasetName) throws Exception { - for (int i = 0; i < numRecords; i++) { - testExecutor.executeSqlppUpdateOrDdl("UPSERT INTO " + datasetName + " ({\"id\": " + random.nextInt() + "})", - TestCaseContext.OutputFormat.CLEAN_JSON); - } + final long countAfterSecondRecovery = TestDataUtil.getDatasetCount(datasetName); + Assert.assertEquals(countBeforeSecondRecovery, countAfterSecondRecovery); } - private void validateRecovery(String datasetName) throws Exception { - final String query = "select value count(*) from `" + datasetName + "`;"; - final InputStream inputStream = testExecutor - .executeQueryService(query, testExecutor.getEndpoint(Servlets.QUERY_SERVICE), - TestCaseContext.OutputFormat.CLEAN_JSON); - final ObjectNode jsonNodes = OBJECT_MAPPER.readValue(inputStream, ObjectNode.class); - JsonNode result = jsonNodes.get("results"); - // make sure there is result - Assert.assertEquals(1, result.size()); - for (int i = 0; i < result.size(); i++) { - JsonNode json = result.get(i); - Assert.assertEquals(numRecords, json.asInt()); - } + @Test + public void reoveryAfterRebalance() throws Exception { + String datasetName = "ds"; + TestDataUtil.createIdOnlyDataset(datasetName); + TestDataUtil.upsertData(datasetName, 10); + final long countBeforeRebalance = TestDataUtil.getDatasetCount(datasetName); + // rebalance dataset to single nc + TestDataUtil.rebalanceDataset(integrationUtil, MetadataBuiltinEntities.DEFAULT_DATAVERSE.getDataverseName(), + datasetName, new String[] { "asterix_nc2" }); + // check data after rebalance + final long countAfterRebalance = TestDataUtil.getDatasetCount(datasetName); + Assert.assertEquals(countBeforeRebalance, countAfterRebalance); + // insert data after rebalance + TestDataUtil.upsertData(datasetName, 20); + final long countBeforeRecovery = TestDataUtil.getDatasetCount(datasetName); + // do ungraceful shutdown to enforce recovery + integrationUtil.deinit(false); + integrationUtil.init(false); + final long countAfterRecovery = TestDataUtil.getDatasetCount(datasetName); + Assert.assertEquals(countBeforeRecovery, countAfterRecovery); } } \ No newline at end of file http://git-wip-us.apache.org/repos/asf/asterixdb/blob/f9e6bae9/asterixdb/asterix-app/src/test/resources/runtimets/results/rebalance/all_datasets/all_datasets.11.adm ---------------------------------------------------------------------- diff --git a/asterixdb/asterix-app/src/test/resources/runtimets/results/rebalance/all_datasets/all_datasets.11.adm b/asterixdb/asterix-app/src/test/resources/runtimets/results/rebalance/all_datasets/all_datasets.11.adm index f57b230..d970119 100644 --- a/asterixdb/asterix-app/src/test/resources/runtimets/results/rebalance/all_datasets/all_datasets.11.adm +++ b/asterixdb/asterix-app/src/test/resources/runtimets/results/rebalance/all_datasets/all_datasets.11.adm @@ -1 +1 @@ -{"keys":"l_orderkey,l_linenumber","type":{"type":"org.apache.asterix.om.types.ARecordType","name":"LineItemType","open":false,"fields":[{"l_orderkey":{"type":"AInt64"}},{"l_partkey":{"type":"AInt64"}},{"l_suppkey":{"type":"AInt64"}},{"l_linenumber":{"type":"AInt64"}},{"l_quantity":{"type":"ADouble"}},{"l_extendedprice":{"type":"ADouble"}},{"l_discount":{"type":"ADouble"}},{"l_tax":{"type":"ADouble"}},{"l_returnflag":{"type":"AString"}},{"l_linestatus":{"type":"AString"}},{"l_shipdate":{"type":"AString"}},{"l_commitdate":{"type":"AString"}},{"l_receiptdate":{"type":"AString"}},{"l_shipinstruct":{"type":"AString"}},{"l_shipmode":{"type":"AString"}},{"l_comment":{"type":"AString"}}]},"splits":[{"ip":"127.0.0.1","path":"storage/partition_0/tpch1/2/LineItem_idx_LineItem"},{"ip":"127.0.0.1","path":"storage/partition_1/tpch1/2/LineItem_idx_LineItem"},{"ip":"127.0.0.1","path":"storage/partition_2/tpch1/2/LineItem_idx_LineItem"},{"ip":"127.0.0.1","path":"storage/partition_3/tpch1/2/LineItem_ idx_LineItem"}]} \ No newline at end of file +{"keys":"l_orderkey,l_linenumber","type":{"type":"org.apache.asterix.om.types.ARecordType","name":"LineItemType","open":false,"fields":[{"l_orderkey":{"type":"AInt64"}},{"l_partkey":{"type":"AInt64"}},{"l_suppkey":{"type":"AInt64"}},{"l_linenumber":{"type":"AInt64"}},{"l_quantity":{"type":"ADouble"}},{"l_extendedprice":{"type":"ADouble"}},{"l_discount":{"type":"ADouble"}},{"l_tax":{"type":"ADouble"}},{"l_returnflag":{"type":"AString"}},{"l_linestatus":{"type":"AString"}},{"l_shipdate":{"type":"AString"}},{"l_commitdate":{"type":"AString"}},{"l_receiptdate":{"type":"AString"}},{"l_shipinstruct":{"type":"AString"}},{"l_shipmode":{"type":"AString"}},{"l_comment":{"type":"AString"}}]},"splits":[{"ip":"127.0.0.1","path":"storage/partition_0/tpch1/LineItem/2/LineItem"},{"ip":"127.0.0.1","path":"storage/partition_1/tpch1/LineItem/2/LineItem"},{"ip":"127.0.0.1","path":"storage/partition_2/tpch1/LineItem/2/LineItem"},{"ip":"127.0.0.1","path":"storage/partition_3/tpch1/LineItem/2/LineItem"}]} \ No newline at end of file http://git-wip-us.apache.org/repos/asf/asterixdb/blob/f9e6bae9/asterixdb/asterix-app/src/test/resources/runtimets/results/rebalance/all_datasets/all_datasets.12.adm ---------------------------------------------------------------------- diff --git a/asterixdb/asterix-app/src/test/resources/runtimets/results/rebalance/all_datasets/all_datasets.12.adm b/asterixdb/asterix-app/src/test/resources/runtimets/results/rebalance/all_datasets/all_datasets.12.adm index 39cad23..38d2eac 100644 --- a/asterixdb/asterix-app/src/test/resources/runtimets/results/rebalance/all_datasets/all_datasets.12.adm +++ b/asterixdb/asterix-app/src/test/resources/runtimets/results/rebalance/all_datasets/all_datasets.12.adm @@ -1 +1 @@ -{"keys":"o_orderkey","type":{"type":"org.apache.asterix.om.types.ARecordType","name":"OrderType","open":false,"fields":[{"o_orderkey":{"type":"AInt64"}},{"o_custkey":{"type":"AInt64"}},{"o_orderstatus":{"type":"AString"}},{"o_totalprice":{"type":"ADouble"}},{"o_orderdate":{"type":"AString"}},{"o_orderpriority":{"type":"AString"}},{"o_clerk":{"type":"AString"}},{"o_shippriority":{"type":"AInt64"}},{"o_comment":{"type":"AString"}}]},"splits":[{"ip":"127.0.0.1","path":"storage/partition_0/tpch2/2/Orders_idx_Orders"},{"ip":"127.0.0.1","path":"storage/partition_1/tpch2/2/Orders_idx_Orders"},{"ip":"127.0.0.1","path":"storage/partition_2/tpch2/2/Orders_idx_Orders"},{"ip":"127.0.0.1","path":"storage/partition_3/tpch2/2/Orders_idx_Orders"}]} \ No newline at end of file +{"keys":"o_orderkey","type":{"type":"org.apache.asterix.om.types.ARecordType","name":"OrderType","open":false,"fields":[{"o_orderkey":{"type":"AInt64"}},{"o_custkey":{"type":"AInt64"}},{"o_orderstatus":{"type":"AString"}},{"o_totalprice":{"type":"ADouble"}},{"o_orderdate":{"type":"AString"}},{"o_orderpriority":{"type":"AString"}},{"o_clerk":{"type":"AString"}},{"o_shippriority":{"type":"AInt64"}},{"o_comment":{"type":"AString"}}]},"splits":[{"ip":"127.0.0.1","path":"storage/partition_0/tpch2/Orders/2/Orders"},{"ip":"127.0.0.1","path":"storage/partition_1/tpch2/Orders/2/Orders"},{"ip":"127.0.0.1","path":"storage/partition_2/tpch2/Orders/2/Orders"},{"ip":"127.0.0.1","path":"storage/partition_3/tpch2/Orders/2/Orders"}]} \ No newline at end of file http://git-wip-us.apache.org/repos/asf/asterixdb/blob/f9e6bae9/asterixdb/asterix-app/src/test/resources/runtimets/results/rebalance/all_datasets/all_datasets.5.adm ---------------------------------------------------------------------- diff --git a/asterixdb/asterix-app/src/test/resources/runtimets/results/rebalance/all_datasets/all_datasets.5.adm b/asterixdb/asterix-app/src/test/resources/runtimets/results/rebalance/all_datasets/all_datasets.5.adm index fa5763e..af9759b 100644 --- a/asterixdb/asterix-app/src/test/resources/runtimets/results/rebalance/all_datasets/all_datasets.5.adm +++ b/asterixdb/asterix-app/src/test/resources/runtimets/results/rebalance/all_datasets/all_datasets.5.adm @@ -1 +1 @@ -{"keys":"l_orderkey,l_linenumber","type":{"type":"org.apache.asterix.om.types.ARecordType","name":"LineItemType","open":false,"fields":[{"l_orderkey":{"type":"AInt64"}},{"l_partkey":{"type":"AInt64"}},{"l_suppkey":{"type":"AInt64"}},{"l_linenumber":{"type":"AInt64"}},{"l_quantity":{"type":"ADouble"}},{"l_extendedprice":{"type":"ADouble"}},{"l_discount":{"type":"ADouble"}},{"l_tax":{"type":"ADouble"}},{"l_returnflag":{"type":"AString"}},{"l_linestatus":{"type":"AString"}},{"l_shipdate":{"type":"AString"}},{"l_commitdate":{"type":"AString"}},{"l_receiptdate":{"type":"AString"}},{"l_shipinstruct":{"type":"AString"}},{"l_shipmode":{"type":"AString"}},{"l_comment":{"type":"AString"}}]},"splits":[{"ip":"127.0.0.1","path":"storage/partition_0/tpch1/1/LineItem_idx_LineItem"},{"ip":"127.0.0.1","path":"storage/partition_1/tpch1/1/LineItem_idx_LineItem"}]} \ No newline at end of file +{"keys":"l_orderkey,l_linenumber","type":{"type":"org.apache.asterix.om.types.ARecordType","name":"LineItemType","open":false,"fields":[{"l_orderkey":{"type":"AInt64"}},{"l_partkey":{"type":"AInt64"}},{"l_suppkey":{"type":"AInt64"}},{"l_linenumber":{"type":"AInt64"}},{"l_quantity":{"type":"ADouble"}},{"l_extendedprice":{"type":"ADouble"}},{"l_discount":{"type":"ADouble"}},{"l_tax":{"type":"ADouble"}},{"l_returnflag":{"type":"AString"}},{"l_linestatus":{"type":"AString"}},{"l_shipdate":{"type":"AString"}},{"l_commitdate":{"type":"AString"}},{"l_receiptdate":{"type":"AString"}},{"l_shipinstruct":{"type":"AString"}},{"l_shipmode":{"type":"AString"}},{"l_comment":{"type":"AString"}}]},"splits":[{"ip":"127.0.0.1","path":"storage/partition_0/tpch1/LineItem/1/LineItem"},{"ip":"127.0.0.1","path":"storage/partition_1/tpch1/LineItem/1/LineItem"}]} \ No newline at end of file http://git-wip-us.apache.org/repos/asf/asterixdb/blob/f9e6bae9/asterixdb/asterix-app/src/test/resources/runtimets/results/rebalance/all_datasets/all_datasets.6.adm ---------------------------------------------------------------------- diff --git a/asterixdb/asterix-app/src/test/resources/runtimets/results/rebalance/all_datasets/all_datasets.6.adm b/asterixdb/asterix-app/src/test/resources/runtimets/results/rebalance/all_datasets/all_datasets.6.adm index b3dea05..0003101 100644 --- a/asterixdb/asterix-app/src/test/resources/runtimets/results/rebalance/all_datasets/all_datasets.6.adm +++ b/asterixdb/asterix-app/src/test/resources/runtimets/results/rebalance/all_datasets/all_datasets.6.adm @@ -1 +1 @@ -{"keys":"o_orderkey","type":{"type":"org.apache.asterix.om.types.ARecordType","name":"OrderType","open":false,"fields":[{"o_orderkey":{"type":"AInt64"}},{"o_custkey":{"type":"AInt64"}},{"o_orderstatus":{"type":"AString"}},{"o_totalprice":{"type":"ADouble"}},{"o_orderdate":{"type":"AString"}},{"o_orderpriority":{"type":"AString"}},{"o_clerk":{"type":"AString"}},{"o_shippriority":{"type":"AInt64"}},{"o_comment":{"type":"AString"}}]},"splits":[{"ip":"127.0.0.1","path":"storage/partition_0/tpch2/1/Orders_idx_Orders"},{"ip":"127.0.0.1","path":"storage/partition_1/tpch2/1/Orders_idx_Orders"}]} \ No newline at end of file +{"keys":"o_orderkey","type":{"type":"org.apache.asterix.om.types.ARecordType","name":"OrderType","open":false,"fields":[{"o_orderkey":{"type":"AInt64"}},{"o_custkey":{"type":"AInt64"}},{"o_orderstatus":{"type":"AString"}},{"o_totalprice":{"type":"ADouble"}},{"o_orderdate":{"type":"AString"}},{"o_orderpriority":{"type":"AString"}},{"o_clerk":{"type":"AString"}},{"o_shippriority":{"type":"AInt64"}},{"o_comment":{"type":"AString"}}]},"splits":[{"ip":"127.0.0.1","path":"storage/partition_0/tpch2/Orders/1/Orders"},{"ip":"127.0.0.1","path":"storage/partition_1/tpch2/Orders/1/Orders"}]} \ No newline at end of file http://git-wip-us.apache.org/repos/asf/asterixdb/blob/f9e6bae9/asterixdb/asterix-app/src/test/resources/runtimets/results/rebalance/single_dataset/single_dataset.5.adm ---------------------------------------------------------------------- diff --git a/asterixdb/asterix-app/src/test/resources/runtimets/results/rebalance/single_dataset/single_dataset.5.adm b/asterixdb/asterix-app/src/test/resources/runtimets/results/rebalance/single_dataset/single_dataset.5.adm index 8ff99de..374e1af 100644 --- a/asterixdb/asterix-app/src/test/resources/runtimets/results/rebalance/single_dataset/single_dataset.5.adm +++ b/asterixdb/asterix-app/src/test/resources/runtimets/results/rebalance/single_dataset/single_dataset.5.adm @@ -1 +1 @@ -{"keys":"l_orderkey,l_linenumber","type":{"type":"org.apache.asterix.om.types.ARecordType","name":"LineItemType","open":false,"fields":[{"l_orderkey":{"type":"AInt64"}},{"l_partkey":{"type":"AInt64"}},{"l_suppkey":{"type":"AInt64"}},{"l_linenumber":{"type":"AInt64"}},{"l_quantity":{"type":"ADouble"}},{"l_extendedprice":{"type":"ADouble"}},{"l_discount":{"type":"ADouble"}},{"l_tax":{"type":"ADouble"}},{"l_returnflag":{"type":"AString"}},{"l_linestatus":{"type":"AString"}},{"l_shipdate":{"type":"AString"}},{"l_commitdate":{"type":"AString"}},{"l_receiptdate":{"type":"AString"}},{"l_shipinstruct":{"type":"AString"}},{"l_shipmode":{"type":"AString"}},{"l_comment":{"type":"AString"}}]},"splits":[{"ip":"127.0.0.1","path":"storage/partition_0/tpch/1/LineItem_idx_LineItem"},{"ip":"127.0.0.1","path":"storage/partition_1/tpch/1/LineItem_idx_LineItem"}]} +{"keys":"l_orderkey,l_linenumber","type":{"type":"org.apache.asterix.om.types.ARecordType","name":"LineItemType","open":false,"fields":[{"l_orderkey":{"type":"AInt64"}},{"l_partkey":{"type":"AInt64"}},{"l_suppkey":{"type":"AInt64"}},{"l_linenumber":{"type":"AInt64"}},{"l_quantity":{"type":"ADouble"}},{"l_extendedprice":{"type":"ADouble"}},{"l_discount":{"type":"ADouble"}},{"l_tax":{"type":"ADouble"}},{"l_returnflag":{"type":"AString"}},{"l_linestatus":{"type":"AString"}},{"l_shipdate":{"type":"AString"}},{"l_commitdate":{"type":"AString"}},{"l_receiptdate":{"type":"AString"}},{"l_shipinstruct":{"type":"AString"}},{"l_shipmode":{"type":"AString"}},{"l_comment":{"type":"AString"}}]},"splits":[{"ip":"127.0.0.1","path":"storage/partition_0/tpch/LineItem/1/LineItem"},{"ip":"127.0.0.1","path":"storage/partition_1/tpch/LineItem/1/LineItem"}]} http://git-wip-us.apache.org/repos/asf/asterixdb/blob/f9e6bae9/asterixdb/asterix-app/src/test/resources/runtimets/results/rebalance/single_dataset/single_dataset.9.adm ---------------------------------------------------------------------- diff --git a/asterixdb/asterix-app/src/test/resources/runtimets/results/rebalance/single_dataset/single_dataset.9.adm b/asterixdb/asterix-app/src/test/resources/runtimets/results/rebalance/single_dataset/single_dataset.9.adm index 6eece47..ae6e2fb 100644 --- a/asterixdb/asterix-app/src/test/resources/runtimets/results/rebalance/single_dataset/single_dataset.9.adm +++ b/asterixdb/asterix-app/src/test/resources/runtimets/results/rebalance/single_dataset/single_dataset.9.adm @@ -1 +1 @@ -{"keys":"l_orderkey,l_linenumber","type":{"type":"org.apache.asterix.om.types.ARecordType","name":"LineItemType","open":false,"fields":[{"l_orderkey":{"type":"AInt64"}},{"l_partkey":{"type":"AInt64"}},{"l_suppkey":{"type":"AInt64"}},{"l_linenumber":{"type":"AInt64"}},{"l_quantity":{"type":"ADouble"}},{"l_extendedprice":{"type":"ADouble"}},{"l_discount":{"type":"ADouble"}},{"l_tax":{"type":"ADouble"}},{"l_returnflag":{"type":"AString"}},{"l_linestatus":{"type":"AString"}},{"l_shipdate":{"type":"AString"}},{"l_commitdate":{"type":"AString"}},{"l_receiptdate":{"type":"AString"}},{"l_shipinstruct":{"type":"AString"}},{"l_shipmode":{"type":"AString"}},{"l_comment":{"type":"AString"}}]},"splits":[{"ip":"127.0.0.1","path":"storage/partition_0/tpch/2/LineItem_idx_LineItem"},{"ip":"127.0.0.1","path":"storage/partition_1/tpch/2/LineItem_idx_LineItem"},{"ip":"127.0.0.1","path":"storage/partition_2/tpch/2/LineItem_idx_LineItem"},{"ip":"127.0.0.1","path":"storage/partition_3/tpch/2/LineItem_idx_ LineItem"}]} \ No newline at end of file +{"keys":"l_orderkey,l_linenumber","type":{"type":"org.apache.asterix.om.types.ARecordType","name":"LineItemType","open":false,"fields":[{"l_orderkey":{"type":"AInt64"}},{"l_partkey":{"type":"AInt64"}},{"l_suppkey":{"type":"AInt64"}},{"l_linenumber":{"type":"AInt64"}},{"l_quantity":{"type":"ADouble"}},{"l_extendedprice":{"type":"ADouble"}},{"l_discount":{"type":"ADouble"}},{"l_tax":{"type":"ADouble"}},{"l_returnflag":{"type":"AString"}},{"l_linestatus":{"type":"AString"}},{"l_shipdate":{"type":"AString"}},{"l_commitdate":{"type":"AString"}},{"l_receiptdate":{"type":"AString"}},{"l_shipinstruct":{"type":"AString"}},{"l_shipmode":{"type":"AString"}},{"l_comment":{"type":"AString"}}]},"splits":[{"ip":"127.0.0.1","path":"storage/partition_0/tpch/LineItem/2/LineItem"},{"ip":"127.0.0.1","path":"storage/partition_1/tpch/LineItem/2/LineItem"},{"ip":"127.0.0.1","path":"storage/partition_2/tpch/LineItem/2/LineItem"},{"ip":"127.0.0.1","path":"storage/partition_3/tpch/LineItem/2/LineItem"}]} \ No newline at end of file http://git-wip-us.apache.org/repos/asf/asterixdb/blob/f9e6bae9/asterixdb/asterix-app/src/test/resources/runtimets/results/rebalance/single_dataset_with_index/single_dataset_with_index.10.adm ---------------------------------------------------------------------- diff --git a/asterixdb/asterix-app/src/test/resources/runtimets/results/rebalance/single_dataset_with_index/single_dataset_with_index.10.adm b/asterixdb/asterix-app/src/test/resources/runtimets/results/rebalance/single_dataset_with_index/single_dataset_with_index.10.adm index 6eece47..ae6e2fb 100644 --- a/asterixdb/asterix-app/src/test/resources/runtimets/results/rebalance/single_dataset_with_index/single_dataset_with_index.10.adm +++ b/asterixdb/asterix-app/src/test/resources/runtimets/results/rebalance/single_dataset_with_index/single_dataset_with_index.10.adm @@ -1 +1 @@ -{"keys":"l_orderkey,l_linenumber","type":{"type":"org.apache.asterix.om.types.ARecordType","name":"LineItemType","open":false,"fields":[{"l_orderkey":{"type":"AInt64"}},{"l_partkey":{"type":"AInt64"}},{"l_suppkey":{"type":"AInt64"}},{"l_linenumber":{"type":"AInt64"}},{"l_quantity":{"type":"ADouble"}},{"l_extendedprice":{"type":"ADouble"}},{"l_discount":{"type":"ADouble"}},{"l_tax":{"type":"ADouble"}},{"l_returnflag":{"type":"AString"}},{"l_linestatus":{"type":"AString"}},{"l_shipdate":{"type":"AString"}},{"l_commitdate":{"type":"AString"}},{"l_receiptdate":{"type":"AString"}},{"l_shipinstruct":{"type":"AString"}},{"l_shipmode":{"type":"AString"}},{"l_comment":{"type":"AString"}}]},"splits":[{"ip":"127.0.0.1","path":"storage/partition_0/tpch/2/LineItem_idx_LineItem"},{"ip":"127.0.0.1","path":"storage/partition_1/tpch/2/LineItem_idx_LineItem"},{"ip":"127.0.0.1","path":"storage/partition_2/tpch/2/LineItem_idx_LineItem"},{"ip":"127.0.0.1","path":"storage/partition_3/tpch/2/LineItem_idx_ LineItem"}]} \ No newline at end of file +{"keys":"l_orderkey,l_linenumber","type":{"type":"org.apache.asterix.om.types.ARecordType","name":"LineItemType","open":false,"fields":[{"l_orderkey":{"type":"AInt64"}},{"l_partkey":{"type":"AInt64"}},{"l_suppkey":{"type":"AInt64"}},{"l_linenumber":{"type":"AInt64"}},{"l_quantity":{"type":"ADouble"}},{"l_extendedprice":{"type":"ADouble"}},{"l_discount":{"type":"ADouble"}},{"l_tax":{"type":"ADouble"}},{"l_returnflag":{"type":"AString"}},{"l_linestatus":{"type":"AString"}},{"l_shipdate":{"type":"AString"}},{"l_commitdate":{"type":"AString"}},{"l_receiptdate":{"type":"AString"}},{"l_shipinstruct":{"type":"AString"}},{"l_shipmode":{"type":"AString"}},{"l_comment":{"type":"AString"}}]},"splits":[{"ip":"127.0.0.1","path":"storage/partition_0/tpch/LineItem/2/LineItem"},{"ip":"127.0.0.1","path":"storage/partition_1/tpch/LineItem/2/LineItem"},{"ip":"127.0.0.1","path":"storage/partition_2/tpch/LineItem/2/LineItem"},{"ip":"127.0.0.1","path":"storage/partition_3/tpch/LineItem/2/LineItem"}]} \ No newline at end of file http://git-wip-us.apache.org/repos/asf/asterixdb/blob/f9e6bae9/asterixdb/asterix-app/src/test/resources/runtimets/results/rebalance/single_dataset_with_index/single_dataset_with_index.5.adm ---------------------------------------------------------------------- diff --git a/asterixdb/asterix-app/src/test/resources/runtimets/results/rebalance/single_dataset_with_index/single_dataset_with_index.5.adm b/asterixdb/asterix-app/src/test/resources/runtimets/results/rebalance/single_dataset_with_index/single_dataset_with_index.5.adm index 8ff99de..374e1af 100644 --- a/asterixdb/asterix-app/src/test/resources/runtimets/results/rebalance/single_dataset_with_index/single_dataset_with_index.5.adm +++ b/asterixdb/asterix-app/src/test/resources/runtimets/results/rebalance/single_dataset_with_index/single_dataset_with_index.5.adm @@ -1 +1 @@ -{"keys":"l_orderkey,l_linenumber","type":{"type":"org.apache.asterix.om.types.ARecordType","name":"LineItemType","open":false,"fields":[{"l_orderkey":{"type":"AInt64"}},{"l_partkey":{"type":"AInt64"}},{"l_suppkey":{"type":"AInt64"}},{"l_linenumber":{"type":"AInt64"}},{"l_quantity":{"type":"ADouble"}},{"l_extendedprice":{"type":"ADouble"}},{"l_discount":{"type":"ADouble"}},{"l_tax":{"type":"ADouble"}},{"l_returnflag":{"type":"AString"}},{"l_linestatus":{"type":"AString"}},{"l_shipdate":{"type":"AString"}},{"l_commitdate":{"type":"AString"}},{"l_receiptdate":{"type":"AString"}},{"l_shipinstruct":{"type":"AString"}},{"l_shipmode":{"type":"AString"}},{"l_comment":{"type":"AString"}}]},"splits":[{"ip":"127.0.0.1","path":"storage/partition_0/tpch/1/LineItem_idx_LineItem"},{"ip":"127.0.0.1","path":"storage/partition_1/tpch/1/LineItem_idx_LineItem"}]} +{"keys":"l_orderkey,l_linenumber","type":{"type":"org.apache.asterix.om.types.ARecordType","name":"LineItemType","open":false,"fields":[{"l_orderkey":{"type":"AInt64"}},{"l_partkey":{"type":"AInt64"}},{"l_suppkey":{"type":"AInt64"}},{"l_linenumber":{"type":"AInt64"}},{"l_quantity":{"type":"ADouble"}},{"l_extendedprice":{"type":"ADouble"}},{"l_discount":{"type":"ADouble"}},{"l_tax":{"type":"ADouble"}},{"l_returnflag":{"type":"AString"}},{"l_linestatus":{"type":"AString"}},{"l_shipdate":{"type":"AString"}},{"l_commitdate":{"type":"AString"}},{"l_receiptdate":{"type":"AString"}},{"l_shipinstruct":{"type":"AString"}},{"l_shipmode":{"type":"AString"}},{"l_comment":{"type":"AString"}}]},"splits":[{"ip":"127.0.0.1","path":"storage/partition_0/tpch/LineItem/1/LineItem"},{"ip":"127.0.0.1","path":"storage/partition_1/tpch/LineItem/1/LineItem"}]} http://git-wip-us.apache.org/repos/asf/asterixdb/blob/f9e6bae9/asterixdb/asterix-app/src/test/resources/runtimets/results/rebalance/single_dataverse/single_dataverse.11.adm ---------------------------------------------------------------------- diff --git a/asterixdb/asterix-app/src/test/resources/runtimets/results/rebalance/single_dataverse/single_dataverse.11.adm b/asterixdb/asterix-app/src/test/resources/runtimets/results/rebalance/single_dataverse/single_dataverse.11.adm index 6eece47..ae6e2fb 100644 --- a/asterixdb/asterix-app/src/test/resources/runtimets/results/rebalance/single_dataverse/single_dataverse.11.adm +++ b/asterixdb/asterix-app/src/test/resources/runtimets/results/rebalance/single_dataverse/single_dataverse.11.adm @@ -1 +1 @@ -{"keys":"l_orderkey,l_linenumber","type":{"type":"org.apache.asterix.om.types.ARecordType","name":"LineItemType","open":false,"fields":[{"l_orderkey":{"type":"AInt64"}},{"l_partkey":{"type":"AInt64"}},{"l_suppkey":{"type":"AInt64"}},{"l_linenumber":{"type":"AInt64"}},{"l_quantity":{"type":"ADouble"}},{"l_extendedprice":{"type":"ADouble"}},{"l_discount":{"type":"ADouble"}},{"l_tax":{"type":"ADouble"}},{"l_returnflag":{"type":"AString"}},{"l_linestatus":{"type":"AString"}},{"l_shipdate":{"type":"AString"}},{"l_commitdate":{"type":"AString"}},{"l_receiptdate":{"type":"AString"}},{"l_shipinstruct":{"type":"AString"}},{"l_shipmode":{"type":"AString"}},{"l_comment":{"type":"AString"}}]},"splits":[{"ip":"127.0.0.1","path":"storage/partition_0/tpch/2/LineItem_idx_LineItem"},{"ip":"127.0.0.1","path":"storage/partition_1/tpch/2/LineItem_idx_LineItem"},{"ip":"127.0.0.1","path":"storage/partition_2/tpch/2/LineItem_idx_LineItem"},{"ip":"127.0.0.1","path":"storage/partition_3/tpch/2/LineItem_idx_ LineItem"}]} \ No newline at end of file +{"keys":"l_orderkey,l_linenumber","type":{"type":"org.apache.asterix.om.types.ARecordType","name":"LineItemType","open":false,"fields":[{"l_orderkey":{"type":"AInt64"}},{"l_partkey":{"type":"AInt64"}},{"l_suppkey":{"type":"AInt64"}},{"l_linenumber":{"type":"AInt64"}},{"l_quantity":{"type":"ADouble"}},{"l_extendedprice":{"type":"ADouble"}},{"l_discount":{"type":"ADouble"}},{"l_tax":{"type":"ADouble"}},{"l_returnflag":{"type":"AString"}},{"l_linestatus":{"type":"AString"}},{"l_shipdate":{"type":"AString"}},{"l_commitdate":{"type":"AString"}},{"l_receiptdate":{"type":"AString"}},{"l_shipinstruct":{"type":"AString"}},{"l_shipmode":{"type":"AString"}},{"l_comment":{"type":"AString"}}]},"splits":[{"ip":"127.0.0.1","path":"storage/partition_0/tpch/LineItem/2/LineItem"},{"ip":"127.0.0.1","path":"storage/partition_1/tpch/LineItem/2/LineItem"},{"ip":"127.0.0.1","path":"storage/partition_2/tpch/LineItem/2/LineItem"},{"ip":"127.0.0.1","path":"storage/partition_3/tpch/LineItem/2/LineItem"}]} \ No newline at end of file http://git-wip-us.apache.org/repos/asf/asterixdb/blob/f9e6bae9/asterixdb/asterix-app/src/test/resources/runtimets/results/rebalance/single_dataverse/single_dataverse.12.adm ---------------------------------------------------------------------- diff --git a/asterixdb/asterix-app/src/test/resources/runtimets/results/rebalance/single_dataverse/single_dataverse.12.adm b/asterixdb/asterix-app/src/test/resources/runtimets/results/rebalance/single_dataverse/single_dataverse.12.adm index 5a549ef..f9cd003 100644 --- a/asterixdb/asterix-app/src/test/resources/runtimets/results/rebalance/single_dataverse/single_dataverse.12.adm +++ b/asterixdb/asterix-app/src/test/resources/runtimets/results/rebalance/single_dataverse/single_dataverse.12.adm @@ -1 +1 @@ -{"keys":"o_orderkey","type":{"type":"org.apache.asterix.om.types.ARecordType","name":"OrderType","open":false,"fields":[{"o_orderkey":{"type":"AInt64"}},{"o_custkey":{"type":"AInt64"}},{"o_orderstatus":{"type":"AString"}},{"o_totalprice":{"type":"ADouble"}},{"o_orderdate":{"type":"AString"}},{"o_orderpriority":{"type":"AString"}},{"o_clerk":{"type":"AString"}},{"o_shippriority":{"type":"AInt64"}},{"o_comment":{"type":"AString"}}]},"splits":[{"ip":"127.0.0.1","path":"storage/partition_0/tpch/2/Orders_idx_Orders"},{"ip":"127.0.0.1","path":"storage/partition_1/tpch/2/Orders_idx_Orders"},{"ip":"127.0.0.1","path":"storage/partition_2/tpch/2/Orders_idx_Orders"},{"ip":"127.0.0.1","path":"storage/partition_3/tpch/2/Orders_idx_Orders"}]} \ No newline at end of file +{"keys":"o_orderkey","type":{"type":"org.apache.asterix.om.types.ARecordType","name":"OrderType","open":false,"fields":[{"o_orderkey":{"type":"AInt64"}},{"o_custkey":{"type":"AInt64"}},{"o_orderstatus":{"type":"AString"}},{"o_totalprice":{"type":"ADouble"}},{"o_orderdate":{"type":"AString"}},{"o_orderpriority":{"type":"AString"}},{"o_clerk":{"type":"AString"}},{"o_shippriority":{"type":"AInt64"}},{"o_comment":{"type":"AString"}}]},"splits":[{"ip":"127.0.0.1","path":"storage/partition_0/tpch/Orders/2/Orders"},{"ip":"127.0.0.1","path":"storage/partition_1/tpch/Orders/2/Orders"},{"ip":"127.0.0.1","path":"storage/partition_2/tpch/Orders/2/Orders"},{"ip":"127.0.0.1","path":"storage/partition_3/tpch/Orders/2/Orders"}]} \ No newline at end of file http://git-wip-us.apache.org/repos/asf/asterixdb/blob/f9e6bae9/asterixdb/asterix-app/src/test/resources/runtimets/results/rebalance/single_dataverse/single_dataverse.5.adm ---------------------------------------------------------------------- diff --git a/asterixdb/asterix-app/src/test/resources/runtimets/results/rebalance/single_dataverse/single_dataverse.5.adm b/asterixdb/asterix-app/src/test/resources/runtimets/results/rebalance/single_dataverse/single_dataverse.5.adm index 8ff99de..374e1af 100644 --- a/asterixdb/asterix-app/src/test/resources/runtimets/results/rebalance/single_dataverse/single_dataverse.5.adm +++ b/asterixdb/asterix-app/src/test/resources/runtimets/results/rebalance/single_dataverse/single_dataverse.5.adm @@ -1 +1 @@ -{"keys":"l_orderkey,l_linenumber","type":{"type":"org.apache.asterix.om.types.ARecordType","name":"LineItemType","open":false,"fields":[{"l_orderkey":{"type":"AInt64"}},{"l_partkey":{"type":"AInt64"}},{"l_suppkey":{"type":"AInt64"}},{"l_linenumber":{"type":"AInt64"}},{"l_quantity":{"type":"ADouble"}},{"l_extendedprice":{"type":"ADouble"}},{"l_discount":{"type":"ADouble"}},{"l_tax":{"type":"ADouble"}},{"l_returnflag":{"type":"AString"}},{"l_linestatus":{"type":"AString"}},{"l_shipdate":{"type":"AString"}},{"l_commitdate":{"type":"AString"}},{"l_receiptdate":{"type":"AString"}},{"l_shipinstruct":{"type":"AString"}},{"l_shipmode":{"type":"AString"}},{"l_comment":{"type":"AString"}}]},"splits":[{"ip":"127.0.0.1","path":"storage/partition_0/tpch/1/LineItem_idx_LineItem"},{"ip":"127.0.0.1","path":"storage/partition_1/tpch/1/LineItem_idx_LineItem"}]} +{"keys":"l_orderkey,l_linenumber","type":{"type":"org.apache.asterix.om.types.ARecordType","name":"LineItemType","open":false,"fields":[{"l_orderkey":{"type":"AInt64"}},{"l_partkey":{"type":"AInt64"}},{"l_suppkey":{"type":"AInt64"}},{"l_linenumber":{"type":"AInt64"}},{"l_quantity":{"type":"ADouble"}},{"l_extendedprice":{"type":"ADouble"}},{"l_discount":{"type":"ADouble"}},{"l_tax":{"type":"ADouble"}},{"l_returnflag":{"type":"AString"}},{"l_linestatus":{"type":"AString"}},{"l_shipdate":{"type":"AString"}},{"l_commitdate":{"type":"AString"}},{"l_receiptdate":{"type":"AString"}},{"l_shipinstruct":{"type":"AString"}},{"l_shipmode":{"type":"AString"}},{"l_comment":{"type":"AString"}}]},"splits":[{"ip":"127.0.0.1","path":"storage/partition_0/tpch/LineItem/1/LineItem"},{"ip":"127.0.0.1","path":"storage/partition_1/tpch/LineItem/1/LineItem"}]} http://git-wip-us.apache.org/repos/asf/asterixdb/blob/f9e6bae9/asterixdb/asterix-app/src/test/resources/runtimets/results/rebalance/single_dataverse/single_dataverse.6.adm ---------------------------------------------------------------------- diff --git a/asterixdb/asterix-app/src/test/resources/runtimets/results/rebalance/single_dataverse/single_dataverse.6.adm b/asterixdb/asterix-app/src/test/resources/runtimets/results/rebalance/single_dataverse/single_dataverse.6.adm index 6889a70..bca061b 100644 --- a/asterixdb/asterix-app/src/test/resources/runtimets/results/rebalance/single_dataverse/single_dataverse.6.adm +++ b/asterixdb/asterix-app/src/test/resources/runtimets/results/rebalance/single_dataverse/single_dataverse.6.adm @@ -1 +1 @@ -{"keys":"o_orderkey","type":{"type":"org.apache.asterix.om.types.ARecordType","name":"OrderType","open":false,"fields":[{"o_orderkey":{"type":"AInt64"}},{"o_custkey":{"type":"AInt64"}},{"o_orderstatus":{"type":"AString"}},{"o_totalprice":{"type":"ADouble"}},{"o_orderdate":{"type":"AString"}},{"o_orderpriority":{"type":"AString"}},{"o_clerk":{"type":"AString"}},{"o_shippriority":{"type":"AInt64"}},{"o_comment":{"type":"AString"}}]},"splits":[{"ip":"127.0.0.1","path":"storage/partition_0/tpch/1/Orders_idx_Orders"},{"ip":"127.0.0.1","path":"storage/partition_1/tpch/1/Orders_idx_Orders"}]} \ No newline at end of file +{"keys":"o_orderkey","type":{"type":"org.apache.asterix.om.types.ARecordType","name":"OrderType","open":false,"fields":[{"o_orderkey":{"type":"AInt64"}},{"o_custkey":{"type":"AInt64"}},{"o_orderstatus":{"type":"AString"}},{"o_totalprice":{"type":"ADouble"}},{"o_orderdate":{"type":"AString"}},{"o_orderpriority":{"type":"AString"}},{"o_clerk":{"type":"AString"}},{"o_shippriority":{"type":"AInt64"}},{"o_comment":{"type":"AString"}}]},"splits":[{"ip":"127.0.0.1","path":"storage/partition_0/tpch/Orders/1/Orders"},{"ip":"127.0.0.1","path":"storage/partition_1/tpch/Orders/1/Orders"}]} \ No newline at end of file http://git-wip-us.apache.org/repos/asf/asterixdb/blob/f9e6bae9/asterixdb/asterix-common/src/main/java/org/apache/asterix/common/dataflow/DatasetLocalResource.java ---------------------------------------------------------------------- diff --git a/asterixdb/asterix-common/src/main/java/org/apache/asterix/common/dataflow/DatasetLocalResource.java b/asterixdb/asterix-common/src/main/java/org/apache/asterix/common/dataflow/DatasetLocalResource.java index 78b5cb2..48bbf00 100644 --- a/asterixdb/asterix-common/src/main/java/org/apache/asterix/common/dataflow/DatasetLocalResource.java +++ b/asterixdb/asterix-common/src/main/java/org/apache/asterix/common/dataflow/DatasetLocalResource.java @@ -59,6 +59,11 @@ public class DatasetLocalResource implements IResource { } @Override + public void setPath(String path) { + resource.setPath(path); + } + + @Override public IIndex createInstance(INCServiceContext ncServiceCtx) throws HyracksDataException { return resource.createInstance(ncServiceCtx); } http://git-wip-us.apache.org/repos/asf/asterixdb/blob/f9e6bae9/asterixdb/asterix-common/src/main/java/org/apache/asterix/common/replication/IReplicaResourcesManager.java ---------------------------------------------------------------------- diff --git a/asterixdb/asterix-common/src/main/java/org/apache/asterix/common/replication/IReplicaResourcesManager.java b/asterixdb/asterix-common/src/main/java/org/apache/asterix/common/replication/IReplicaResourcesManager.java index 6ffa095..1c3f030 100644 --- a/asterixdb/asterix-common/src/main/java/org/apache/asterix/common/replication/IReplicaResourcesManager.java +++ b/asterixdb/asterix-common/src/main/java/org/apache/asterix/common/replication/IReplicaResourcesManager.java @@ -20,11 +20,14 @@ package org.apache.asterix.common.replication; import java.util.Set; +import org.apache.hyracks.api.exceptions.HyracksDataException; + public interface IReplicaResourcesManager { /** * @param partitions * @return the minimum LSN of all indexes that belong to {@code partitions}. + * @throws HyracksDataException */ - public long getPartitionsMinLSN(Set<Integer> partitions); + long getPartitionsMinLSN(Set<Integer> partitions) throws HyracksDataException; } http://git-wip-us.apache.org/repos/asf/asterixdb/blob/f9e6bae9/asterixdb/asterix-common/src/main/java/org/apache/asterix/common/storage/DatasetResourceReference.java ---------------------------------------------------------------------- diff --git a/asterixdb/asterix-common/src/main/java/org/apache/asterix/common/storage/DatasetResourceReference.java b/asterixdb/asterix-common/src/main/java/org/apache/asterix/common/storage/DatasetResourceReference.java new file mode 100644 index 0000000..d05321e --- /dev/null +++ b/asterixdb/asterix-common/src/main/java/org/apache/asterix/common/storage/DatasetResourceReference.java @@ -0,0 +1,77 @@ +/* + * 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 + * + * http://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.asterix.common.storage; + +import java.nio.file.Paths; + +import org.apache.asterix.common.dataflow.DatasetLocalResource; +import org.apache.asterix.common.utils.StorageConstants; +import org.apache.hyracks.storage.common.LocalResource; + +public class DatasetResourceReference extends ResourceReference { + + private int datasetId; + private int partitionId; + + private DatasetResourceReference() { + super(); + } + + public static DatasetResourceReference of(LocalResource localResource) { + return of(localResource, StorageConstants.VERSION); + } + + public static DatasetResourceReference of(LocalResource localResource, int version) { + if (version < StorageConstants.REBALANCE_STORAGE_VERSION) { + // to support legacy storage migration + return parseLegacyPath(localResource); + } + return parse(localResource); + } + + public int getDatasetId() { + return datasetId; + } + + public int getPartitionId() { + return partitionId; + } + + private static DatasetResourceReference parse(LocalResource localResource) { + final DatasetResourceReference datasetResourceReference = new DatasetResourceReference(); + final String filePath = Paths.get(localResource.getPath(), StorageConstants.METADATA_FILE_NAME).toString(); + parse(datasetResourceReference, filePath); + assignIds(localResource, datasetResourceReference); + return datasetResourceReference; + } + + private static DatasetResourceReference parseLegacyPath(LocalResource localResource) { + final DatasetResourceReference datasetResourceReference = new DatasetResourceReference(); + final String filePath = Paths.get(localResource.getPath(), StorageConstants.METADATA_FILE_NAME).toString(); + parseLegacyPath(datasetResourceReference, filePath); + assignIds(localResource, datasetResourceReference); + return datasetResourceReference; + } + + private static void assignIds(LocalResource localResource, DatasetResourceReference lrr) { + final DatasetLocalResource dsResource = (DatasetLocalResource) localResource.getResource(); + lrr.datasetId = dsResource.getDatasetId(); + lrr.partitionId = dsResource.getPartition(); + } +} http://git-wip-us.apache.org/repos/asf/asterixdb/blob/f9e6bae9/asterixdb/asterix-common/src/main/java/org/apache/asterix/common/storage/IndexFileProperties.java ---------------------------------------------------------------------- diff --git a/asterixdb/asterix-common/src/main/java/org/apache/asterix/common/storage/IndexFileProperties.java b/asterixdb/asterix-common/src/main/java/org/apache/asterix/common/storage/IndexFileProperties.java deleted file mode 100644 index ca6968f..0000000 --- a/asterixdb/asterix-common/src/main/java/org/apache/asterix/common/storage/IndexFileProperties.java +++ /dev/null @@ -1,74 +0,0 @@ -/* - * 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 - * - * http://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.asterix.common.storage; - -import java.io.File; - -import org.apache.asterix.common.utils.StoragePathUtil; - -/** - * A holder class for an index file properties. - */ -public class IndexFileProperties { - - private final String fileName; - private final String idxName; - private final String dataverseName; - private final int partitionId; - private final int datasetId; - - public IndexFileProperties(int partitionId, String dataverseName, String idxName, String fileName, int datasetId) { - this.partitionId = partitionId; - this.dataverseName = dataverseName; - this.idxName = idxName; - this.fileName = fileName; - this.datasetId = datasetId; - } - - public String getFileName() { - return fileName; - } - - public String getIdxName() { - return idxName; - } - - public String getDataverseName() { - return dataverseName; - } - - public int getPartitionId() { - return partitionId; - } - - public int getDatasetId() { - return datasetId; - } - - @Override - public String toString() { - StringBuilder sb = new StringBuilder(); - sb.append(StoragePathUtil.PARTITION_DIR_PREFIX + partitionId + File.separator); - sb.append(dataverseName + File.separator); - sb.append(idxName + File.separator); - sb.append(fileName); - sb.append(" [Dataset ID: " + datasetId + "]"); - return sb.toString(); - } -} \ No newline at end of file http://git-wip-us.apache.org/repos/asf/asterixdb/blob/f9e6bae9/asterixdb/asterix-common/src/main/java/org/apache/asterix/common/storage/IndexPathElements.java ---------------------------------------------------------------------- diff --git a/asterixdb/asterix-common/src/main/java/org/apache/asterix/common/storage/IndexPathElements.java b/asterixdb/asterix-common/src/main/java/org/apache/asterix/common/storage/IndexPathElements.java new file mode 100644 index 0000000..4d0f3dd --- /dev/null +++ b/asterixdb/asterix-common/src/main/java/org/apache/asterix/common/storage/IndexPathElements.java @@ -0,0 +1,44 @@ +/* + * 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 + * + * http://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.asterix.common.storage; + +public class IndexPathElements { + + private final String datasetName; + private final String indexName; + private final String rebalanceCount; + + public IndexPathElements(String datasetName, String indexName, String rebalanceCount) { + this.datasetName = datasetName; + this.indexName = indexName; + this.rebalanceCount = rebalanceCount; + } + + public String getDatasetName() { + return datasetName; + } + + public String getIndexName() { + return indexName; + } + + public String getRebalanceCount() { + return rebalanceCount; + } +} http://git-wip-us.apache.org/repos/asf/asterixdb/blob/f9e6bae9/asterixdb/asterix-common/src/main/java/org/apache/asterix/common/storage/ResourceReference.java ---------------------------------------------------------------------- diff --git a/asterixdb/asterix-common/src/main/java/org/apache/asterix/common/storage/ResourceReference.java b/asterixdb/asterix-common/src/main/java/org/apache/asterix/common/storage/ResourceReference.java new file mode 100644 index 0000000..0d65067 --- /dev/null +++ b/asterixdb/asterix-common/src/main/java/org/apache/asterix/common/storage/ResourceReference.java @@ -0,0 +1,110 @@ +/* + * 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 + * + * http://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.asterix.common.storage; + +import java.io.File; +import java.nio.file.Path; +import java.nio.file.Paths; + +import org.apache.asterix.common.utils.StoragePathUtil; + +public class ResourceReference { + + protected String root; + protected String partition; + protected String dataverse; + protected String dataset; + protected String rebalance; + protected String index; + protected String name; + + protected ResourceReference() { + } + + public static ResourceReference of(String localResourcePath) { + ResourceReference lrr = new ResourceReference(); + parse(lrr, localResourcePath); + return lrr; + } + + public String getPartition() { + return partition; + } + + public String getDataverse() { + return dataverse; + } + + public String getDataset() { + return dataset; + } + + public String getRebalance() { + return rebalance; + } + + public String getIndex() { + return index; + } + + public String getName() { + return name; + } + + public Path getRelativePath() { + return Paths.get(root, partition, dataverse, dataset, rebalance, index); + } + + protected static void parse(ResourceReference ref, String path) { + // format: root/partition/dataverse/dataset/rebalanceCount/index/fileName + final String[] tokens = path.split(File.separator); + if (tokens.length < 6) { + throw new IllegalStateException("Unrecognized path structure: " + path); + } + int offset = tokens.length; + ref.name = tokens[--offset]; + ref.index = tokens[--offset]; + ref.rebalance = tokens[--offset]; + ref.dataset = tokens[--offset]; + ref.dataverse = tokens[--offset]; + ref.partition = tokens[--offset]; + ref.root = tokens[--offset]; + } + + protected static void parseLegacyPath(ResourceReference ref, String path) { + // old format: root/partition/dataverse/datasetName_idx_IndexName/fileName + final String[] tokens = path.split(File.separator); + if (tokens.length < 4) { + throw new IllegalStateException("Unrecognized legacy path structure: " + path); + } + int offset = tokens.length; + ref.name = tokens[--offset]; + // split combined dataset/index name + final String[] indexTokens = tokens[--offset].split(StoragePathUtil.DATASET_INDEX_NAME_SEPARATOR); + if (indexTokens.length != 2) { + throw new IllegalStateException("Unrecognized legacy path structure: " + path); + } + ref.dataset = indexTokens[0]; + ref.index = indexTokens[1]; + ref.dataverse = tokens[--offset]; + ref.partition = tokens[--offset]; + ref.root = tokens[--offset]; + ref.rebalance = String.valueOf(0); + } +} http://git-wip-us.apache.org/repos/asf/asterixdb/blob/f9e6bae9/asterixdb/asterix-common/src/main/java/org/apache/asterix/common/utils/StorageConstants.java ---------------------------------------------------------------------- diff --git a/asterixdb/asterix-common/src/main/java/org/apache/asterix/common/utils/StorageConstants.java b/asterixdb/asterix-common/src/main/java/org/apache/asterix/common/utils/StorageConstants.java index 49d64d6..48769d4 100644 --- a/asterixdb/asterix-common/src/main/java/org/apache/asterix/common/utils/StorageConstants.java +++ b/asterixdb/asterix-common/src/main/java/org/apache/asterix/common/utils/StorageConstants.java @@ -24,13 +24,25 @@ import org.apache.hyracks.storage.am.common.api.ITreeIndexFrame; * A static class that stores storage constants */ public class StorageConstants { + public static final String METADATA_ROOT = "root_metadata"; - /** The storage version of AsterixDB related artifacts (e.g. log files, checkpoint files, etc..). */ - private static final int LOCAL_STORAGE_VERSION = 1; + public static final String METADATA_FILE_NAME = ".metadata"; + + /** + * The storage version of AsterixDB related artifacts (e.g. log files, checkpoint files, etc..). + */ + private static final int LOCAL_STORAGE_VERSION = 2; - /** The storage version of AsterixDB stack. */ + /** + * The storage version of AsterixDB stack. + */ public static final int VERSION = LOCAL_STORAGE_VERSION + ITreeIndexFrame.Constants.VERSION; + /** + * The storage version in which the rebalance storage structure was introduced + */ + public static final int REBALANCE_STORAGE_VERSION = 8; + private StorageConstants() { } } \ No newline at end of file