>From Ali Alsuliman <[email protected]>: Ali Alsuliman has submitted this change. ( https://asterix-gerrit.ics.uci.edu/c/asterixdb/+/17841 )
Change subject: [ASTERIXDB-3259][MTD] Prepare steps for dropping database artifacts ...................................................................... [ASTERIXDB-3259][MTD] Prepare steps for dropping database artifacts - user model changes: no - storage format changes: no - interface changes: yes Details: The drop jobs will be changed to operate at the database level. Change-Id: Iec9b559b6de09fa191d7b54a759c05a874d15913 Reviewed-on: https://asterix-gerrit.ics.uci.edu/c/asterixdb/+/17841 Integration-Tests: Jenkins <[email protected]> Tested-by: Jenkins <[email protected]> Reviewed-by: Ali Alsuliman <[email protected]> Reviewed-by: Murtadha Hubail <[email protected]> --- M asterixdb/asterix-metadata/src/main/java/org/apache/asterix/metadata/utils/SplitsAndConstraintsUtil.java M asterixdb/asterix-app/src/main/java/org/apache/asterix/app/translator/QueryTranslator.java M asterixdb/asterix-metadata/src/main/java/org/apache/asterix/metadata/MetadataManager.java M asterixdb/asterix-app/src/main/java/org/apache/asterix/utils/DataverseUtil.java M asterixdb/asterix-metadata/src/main/java/org/apache/asterix/metadata/MetadataNode.java M asterixdb/asterix-metadata/src/main/java/org/apache/asterix/metadata/utils/DataPartitioningProvider.java M asterixdb/asterix-metadata/src/main/java/org/apache/asterix/metadata/api/IMetadataManager.java M asterixdb/asterix-metadata/src/main/java/org/apache/asterix/metadata/utils/StaticDataPartitioningProvider.java M asterixdb/asterix-metadata/src/main/java/org/apache/asterix/metadata/utils/DynamicDataPartitioningProvider.java M asterixdb/asterix-metadata/src/main/java/org/apache/asterix/metadata/api/IMetadataNode.java M asterixdb/asterix-metadata/src/main/java/org/apache/asterix/metadata/declared/MetadataProvider.java 11 files changed, 175 insertions(+), 15 deletions(-) Approvals: Murtadha Hubail: Looks good to me, approved Ali Alsuliman: Looks good to me, but someone else must approve Jenkins: Verified; Verified diff --git a/asterixdb/asterix-app/src/main/java/org/apache/asterix/app/translator/QueryTranslator.java b/asterixdb/asterix-app/src/main/java/org/apache/asterix/app/translator/QueryTranslator.java index 024cb17..89161b9 100644 --- a/asterixdb/asterix-app/src/main/java/org/apache/asterix/app/translator/QueryTranslator.java +++ b/asterixdb/asterix-app/src/main/java/org/apache/asterix/app/translator/QueryTranslator.java @@ -1927,6 +1927,7 @@ metadataProvider.setMetadataTxnContext(mdTxnCtx); List<FeedEventsListener> feedsToStop = new ArrayList<>(); List<JobSpecification> jobsToExecute = new ArrayList<>(); + //TODO(DB): resolve database directory try { Database database = MetadataManager.INSTANCE.getDatabase(mdTxnCtx, databaseName); if (database == null) { @@ -1941,16 +1942,49 @@ validateDatabaseStateBeforeDrop(metadataProvider, database, sourceLoc); // #. prepare jobs which will drop corresponding feed storage - //TODO(DB): + ActiveNotificationHandler activeEventHandler = + (ActiveNotificationHandler) appCtx.getActiveNotificationHandler(); + IActiveEntityEventsListener[] activeListeners = activeEventHandler.getEventListeners(); + for (IActiveEntityEventsListener listener : activeListeners) { + EntityId activeEntityId = listener.getEntityId(); + if (activeEntityId.getExtensionName().equals(Feed.EXTENSION_NAME) + && activeEntityId.getDatabaseName().equals(databaseName)) { + FeedEventsListener feedListener = (FeedEventsListener) listener; + feedsToStop.add(feedListener); + jobsToExecute + .add(FeedOperations.buildRemoveFeedStorageJob(metadataProvider, feedListener.getFeed())); + } + } // #. prepare jobs which will drop corresponding datasets with indexes - //TODO(DB): + List<Dataset> datasets = MetadataManager.INSTANCE.getDatabaseDatasets(mdTxnCtx, databaseName); + for (Dataset dataset : datasets) { + String datasetName = dataset.getDatasetName(); + DatasetType dsType = dataset.getDatasetType(); + switch (dsType) { + case INTERNAL: + List<Index> indexes = MetadataManager.INSTANCE.getDatasetIndexes(mdTxnCtx, databaseName, + dataset.getDataverseName(), datasetName); + for (Index index : indexes) { + jobsToExecute + .add(IndexUtil.buildDropIndexJobSpec(index, metadataProvider, dataset, sourceLoc)); + } + break; + case EXTERNAL: + case VIEW: + break; + } + } // #. prepare jobs which will drop corresponding libraries - //TODO(DB): + List<Library> libraries = MetadataManager.INSTANCE.getDatabaseLibraries(mdTxnCtx, databaseName); + for (Library library : libraries) { + jobsToExecute.add(ExternalLibraryJobUtils.buildDropLibraryJobSpec(library.getDataverseName(), + library.getName(), metadataProvider)); + } // #. prepare jobs which will drop the database - //TODO(DB): + jobsToExecute.add(DataverseUtil.dropDatabaseJobSpec(databaseName, metadataProvider)); // #. mark PendingDropOp on the database record by // first, deleting the database record from the 'Database' collection @@ -1983,11 +2017,20 @@ MetadataManager.INSTANCE.dropDatabase(mdTxnCtx, databaseName); // drop all node groups that no longer needed - //TODO(DB): + for (Dataset dataset : datasets) { + String nodeGroup = dataset.getNodeGroupName(); + lockManager.acquireNodeGroupWriteLock(metadataProvider.getLocks(), nodeGroup); + if (MetadataManager.INSTANCE.getNodegroup(mdTxnCtx, nodeGroup) != null) { + MetadataManager.INSTANCE.dropNodegroup(mdTxnCtx, nodeGroup, true); + } + } //TODO(DB): switch active database to the DEFAULT if the dropped database is the currently active one + if (activeDataverse.getDatabaseName().equals(databaseName)) { + activeDataverse = MetadataBuiltinEntities.DEFAULT_DATAVERSE; + } - //TODO(DB): validateDatabaseDatasetsStateAfterDrop + validateDatasetsStateAfterNamespaceDrop(metadataProvider, mdTxnCtx, datasets); MetadataManager.INSTANCE.commitTransaction(mdTxnCtx); return true; @@ -1997,7 +2040,9 @@ } if (progress == ProgressState.ADDED_PENDINGOP_RECORD_TO_METADATA) { - //TODO(DB): switch active database to the DEFAULT if the dropped database is the currently active one + if (activeDataverse.getDatabaseName().equals(databaseName)) { + activeDataverse = MetadataBuiltinEntities.DEFAULT_DATAVERSE; + } // #. execute compensation operations // remove the all artifacts in NC @@ -2018,7 +2063,7 @@ } catch (Exception e2) { e.addSuppressed(e2); abort(e, e2, mdTxnCtx); - throw new IllegalStateException("System is inconsistent state: pending dataverse(" + databaseName + throw new IllegalStateException("System is inconsistent state: pending database(" + databaseName + ") couldn't be removed from the metadata", e); } } @@ -2165,7 +2210,7 @@ activeDataverse = MetadataBuiltinEntities.DEFAULT_DATAVERSE; } - validateDataverseDatasetsStateAfterDrop(metadataProvider, mdTxnCtx, datasets); + validateDatasetsStateAfterNamespaceDrop(metadataProvider, mdTxnCtx, datasets); MetadataManager.INSTANCE.commitTransaction(mdTxnCtx); return true; } catch (Exception e) { @@ -2220,9 +2265,9 @@ // may be overridden by product extensions for additional checks before dropping the dataverse } - protected void validateDataverseDatasetsStateAfterDrop(MetadataProvider metadataProvider, + protected void validateDatasetsStateAfterNamespaceDrop(MetadataProvider metadataProvider, MetadataTransactionContext mdTxnCtx, List<Dataset> datasets) throws AlgebricksException { - // may be overridden by product extensions for additional checks after dropping the dataverse + // may be overridden by product extensions for additional checks after dropping a database/dataverse } public void handleDatasetDropStatement(MetadataProvider metadataProvider, Statement stmt, diff --git a/asterixdb/asterix-app/src/main/java/org/apache/asterix/utils/DataverseUtil.java b/asterixdb/asterix-app/src/main/java/org/apache/asterix/utils/DataverseUtil.java index 61b526c..3b7cb00 100644 --- a/asterixdb/asterix-app/src/main/java/org/apache/asterix/utils/DataverseUtil.java +++ b/asterixdb/asterix-app/src/main/java/org/apache/asterix/utils/DataverseUtil.java @@ -41,4 +41,15 @@ jobSpec.addRoot(frod); return jobSpec; } + + public static JobSpecification dropDatabaseJobSpec(String database, MetadataProvider metadata) { + JobSpecification jobSpec = RuntimeUtils.createJobSpecification(metadata.getApplicationContext()); + PartitioningProperties partitioningProperties = metadata.splitAndConstraints(database); + FileRemoveOperatorDescriptor frod = new FileRemoveOperatorDescriptor(jobSpec, + partitioningProperties.getSplitsProvider(), false, partitioningProperties.getComputeStorageMap()); + AlgebricksPartitionConstraintHelper.setPartitionConstraintInJobSpec(jobSpec, frod, + partitioningProperties.getConstraints()); + jobSpec.addRoot(frod); + return jobSpec; + } } diff --git a/asterixdb/asterix-metadata/src/main/java/org/apache/asterix/metadata/MetadataManager.java b/asterixdb/asterix-metadata/src/main/java/org/apache/asterix/metadata/MetadataManager.java index 040b489..ed3474d 100644 --- a/asterixdb/asterix-metadata/src/main/java/org/apache/asterix/metadata/MetadataManager.java +++ b/asterixdb/asterix-metadata/src/main/java/org/apache/asterix/metadata/MetadataManager.java @@ -301,6 +301,21 @@ } @Override + public List<Dataset> getDatabaseDatasets(MetadataTransactionContext ctx, String database) + throws AlgebricksException { + List<Dataset> databaseDatasets; + try { + Objects.requireNonNull(database); + // assuming that the transaction can read its own writes on the metadata node + databaseDatasets = metadataNode.getDatabaseDatasets(ctx.getTxnId(), database); + } catch (RemoteException e) { + throw new MetadataException(ErrorCode.REMOTE_EXCEPTION_WHEN_CALLING_METADATA_NODE, e); + } + // don't update the cache to avoid checking against the transaction's uncommitted datasets + return databaseDatasets; + } + + @Override public List<Dataset> getDataverseDatasets(MetadataTransactionContext ctx, String database, DataverseName dataverseName) throws AlgebricksException { List<Dataset> dataverseDatasets; @@ -903,6 +918,21 @@ } @Override + public List<Library> getDatabaseLibraries(MetadataTransactionContext ctx, String database) + throws AlgebricksException { + List<Library> databaseLibraries; + try { + // assuming that the transaction can read its own writes on the metadata node + Objects.requireNonNull(database); + databaseLibraries = metadataNode.getDatabaseLibraries(ctx.getTxnId(), database); + } catch (RemoteException e) { + throw new MetadataException(ErrorCode.REMOTE_EXCEPTION_WHEN_CALLING_METADATA_NODE, e); + } + // don't update the cache to avoid checking against the transaction's uncommitted functions + return databaseLibraries; + } + + @Override public List<Library> getDataverseLibraries(MetadataTransactionContext ctx, String database, DataverseName dataverseName) throws AlgebricksException { List<Library> dataverseLibaries; diff --git a/asterixdb/asterix-metadata/src/main/java/org/apache/asterix/metadata/MetadataNode.java b/asterixdb/asterix-metadata/src/main/java/org/apache/asterix/metadata/MetadataNode.java index 3871ffb..cc1251b 100644 --- a/asterixdb/asterix-metadata/src/main/java/org/apache/asterix/metadata/MetadataNode.java +++ b/asterixdb/asterix-metadata/src/main/java/org/apache/asterix/metadata/MetadataNode.java @@ -1183,7 +1183,8 @@ } } - private List<Dataset> getDatabaseDatasets(TxnId txnId, String database) throws AlgebricksException { + @Override + public List<Dataset> getDatabaseDatasets(TxnId txnId, String database) throws AlgebricksException { try { ITupleReference searchKey = createTuple(database); DatasetTupleTranslator tupleReaderWriter = tupleTranslatorProvider.getDatasetTupleTranslator(false); @@ -1239,7 +1240,8 @@ } } - private List<Library> getDatabaseLibraries(TxnId txnId, String database) throws AlgebricksException { + @Override + public List<Library> getDatabaseLibraries(TxnId txnId, String database) throws AlgebricksException { try { ITupleReference searchKey = createTuple(database); LibraryTupleTranslator tupleReaderWriter = tupleTranslatorProvider.getLibraryTupleTranslator(false); diff --git a/asterixdb/asterix-metadata/src/main/java/org/apache/asterix/metadata/api/IMetadataManager.java b/asterixdb/asterix-metadata/src/main/java/org/apache/asterix/metadata/api/IMetadataManager.java index 226dd70..f3cc811 100644 --- a/asterixdb/asterix-metadata/src/main/java/org/apache/asterix/metadata/api/IMetadataManager.java +++ b/asterixdb/asterix-metadata/src/main/java/org/apache/asterix/metadata/api/IMetadataManager.java @@ -132,6 +132,8 @@ Dataverse getDataverse(MetadataTransactionContext ctx, String database, DataverseName dataverseName) throws AlgebricksException; + List<Dataset> getDatabaseDatasets(MetadataTransactionContext ctx, String database) throws AlgebricksException; + /** * Retrieves all datasets belonging to the given dataverse. * @@ -671,6 +673,8 @@ Library getLibrary(MetadataTransactionContext ctx, String database, DataverseName dataverseName, String libraryName) throws AlgebricksException, RemoteException; + List<Library> getDatabaseLibraries(MetadataTransactionContext ctx, String database) throws AlgebricksException; + /** * Retireve libraries installed in a given dataverse. * diff --git a/asterixdb/asterix-metadata/src/main/java/org/apache/asterix/metadata/api/IMetadataNode.java b/asterixdb/asterix-metadata/src/main/java/org/apache/asterix/metadata/api/IMetadataNode.java index b738533..a4f2ca7 100644 --- a/asterixdb/asterix-metadata/src/main/java/org/apache/asterix/metadata/api/IMetadataNode.java +++ b/asterixdb/asterix-metadata/src/main/java/org/apache/asterix/metadata/api/IMetadataNode.java @@ -143,6 +143,8 @@ */ List<Dataverse> getDataverses(TxnId txnId) throws AlgebricksException, RemoteException; + List<Dataset> getDatabaseDatasets(TxnId txnId, String database) throws AlgebricksException, RemoteException; + /** * Retrieves all datasets belonging to the given dataverse, acquiring local * locks on behalf of the given transaction id. @@ -714,6 +716,8 @@ Library getLibrary(TxnId txnId, String database, DataverseName dataverseName, String libraryName) throws AlgebricksException, RemoteException; + List<Library> getDatabaseLibraries(TxnId txnId, String database) throws AlgebricksException, RemoteException; + /** * Retireve libraries installed in a given dataverse. * diff --git a/asterixdb/asterix-metadata/src/main/java/org/apache/asterix/metadata/declared/MetadataProvider.java b/asterixdb/asterix-metadata/src/main/java/org/apache/asterix/metadata/declared/MetadataProvider.java index f2dcde4..0ecef7d 100644 --- a/asterixdb/asterix-metadata/src/main/java/org/apache/asterix/metadata/declared/MetadataProvider.java +++ b/asterixdb/asterix-metadata/src/main/java/org/apache/asterix/metadata/declared/MetadataProvider.java @@ -955,6 +955,10 @@ numKeyFields / 2); } + public PartitioningProperties splitAndConstraints(String databaseName) { + return dataPartitioningProvider.getPartitioningProperties(databaseName); + } + public PartitioningProperties splitAndConstraints(DataverseName dataverseName) { return dataPartitioningProvider.getPartitioningProperties(dataverseName); } diff --git a/asterixdb/asterix-metadata/src/main/java/org/apache/asterix/metadata/utils/DataPartitioningProvider.java b/asterixdb/asterix-metadata/src/main/java/org/apache/asterix/metadata/utils/DataPartitioningProvider.java index d763430..d99aa13 100644 --- a/asterixdb/asterix-metadata/src/main/java/org/apache/asterix/metadata/utils/DataPartitioningProvider.java +++ b/asterixdb/asterix-metadata/src/main/java/org/apache/asterix/metadata/utils/DataPartitioningProvider.java @@ -68,6 +68,8 @@ } } + public abstract PartitioningProperties getPartitioningProperties(String databaseName); + public abstract PartitioningProperties getPartitioningProperties(DataverseName dataverseName); public abstract PartitioningProperties getPartitioningProperties(MetadataTransactionContext mdTxnCtx, Dataset ds, diff --git a/asterixdb/asterix-metadata/src/main/java/org/apache/asterix/metadata/utils/DynamicDataPartitioningProvider.java b/asterixdb/asterix-metadata/src/main/java/org/apache/asterix/metadata/utils/DynamicDataPartitioningProvider.java index 95dae4a..803a53b 100644 --- a/asterixdb/asterix-metadata/src/main/java/org/apache/asterix/metadata/utils/DynamicDataPartitioningProvider.java +++ b/asterixdb/asterix-metadata/src/main/java/org/apache/asterix/metadata/utils/DynamicDataPartitioningProvider.java @@ -37,6 +37,14 @@ } @Override + public PartitioningProperties getPartitioningProperties(String databaseName) { + Pair<IFileSplitProvider, AlgebricksPartitionConstraint> splitsAndConstraints = SplitsAndConstraintsUtil + .getDatabaseSplitProviderAndConstraints(appCtx.getClusterStateManager(), databaseName); + int[][] partitionsMap = getOneToOnePartitionsMap(getLocationsCount(splitsAndConstraints.second)); + return PartitioningProperties.of(splitsAndConstraints.first, splitsAndConstraints.second, partitionsMap); + } + + @Override public PartitioningProperties getPartitioningProperties(DataverseName dataverseName) { Pair<IFileSplitProvider, AlgebricksPartitionConstraint> splitsAndConstraints = SplitsAndConstraintsUtil .getDataverseSplitProviderAndConstraints(appCtx.getClusterStateManager(), dataverseName); diff --git a/asterixdb/asterix-metadata/src/main/java/org/apache/asterix/metadata/utils/SplitsAndConstraintsUtil.java b/asterixdb/asterix-metadata/src/main/java/org/apache/asterix/metadata/utils/SplitsAndConstraintsUtil.java index a83b8dc..2abb4f6 100644 --- a/asterixdb/asterix-metadata/src/main/java/org/apache/asterix/metadata/utils/SplitsAndConstraintsUtil.java +++ b/asterixdb/asterix-metadata/src/main/java/org/apache/asterix/metadata/utils/SplitsAndConstraintsUtil.java @@ -45,6 +45,17 @@ private SplitsAndConstraintsUtil() { } + private static FileSplit[] getDatabaseSplits(IClusterStateManager clusterStateManager, String databaseName) { + List<FileSplit> splits = new ArrayList<>(); + // get all partitions + for (ClusterPartition clusterPartition : clusterStateManager.getClusterPartitons()) { + File f = new File(StoragePathUtil.prepareStoragePartitionPath(clusterPartition.getPartitionId()), + databaseName); + splits.add(StoragePathUtil.getFileSplitForClusterPartition(clusterPartition, f.getPath())); + } + return splits.toArray(new FileSplit[] {}); + } + private static FileSplit[] getDataverseSplits(IClusterStateManager clusterStateManager, DataverseName dataverseName) { List<FileSplit> splits = new ArrayList<>(); @@ -84,6 +95,12 @@ return splits.toArray(new FileSplit[] {}); } + public static Pair<IFileSplitProvider, AlgebricksPartitionConstraint> getDatabaseSplitProviderAndConstraints( + IClusterStateManager clusterStateManager, String databaseName) { + FileSplit[] splits = getDatabaseSplits(clusterStateManager, databaseName); + return StoragePathUtil.splitProviderAndPartitionConstraints(splits); + } + public static Pair<IFileSplitProvider, AlgebricksPartitionConstraint> getDataverseSplitProviderAndConstraints( IClusterStateManager clusterStateManager, DataverseName dataverseName) { FileSplit[] splits = getDataverseSplits(clusterStateManager, dataverseName); diff --git a/asterixdb/asterix-metadata/src/main/java/org/apache/asterix/metadata/utils/StaticDataPartitioningProvider.java b/asterixdb/asterix-metadata/src/main/java/org/apache/asterix/metadata/utils/StaticDataPartitioningProvider.java index ffcdc57..f8f967a 100644 --- a/asterixdb/asterix-metadata/src/main/java/org/apache/asterix/metadata/utils/StaticDataPartitioningProvider.java +++ b/asterixdb/asterix-metadata/src/main/java/org/apache/asterix/metadata/utils/StaticDataPartitioningProvider.java @@ -49,6 +49,15 @@ } @Override + public PartitioningProperties getPartitioningProperties(String databaseName) { + SplitComputeLocations dataverseSplits = getSplits(databaseName); + StorageComputePartitionsMap partitionMap = clusterStateManager.getStorageComputeMap(); + int[][] partitionsMap = partitionMap.getComputeToStorageMap(false); + return PartitioningProperties.of(dataverseSplits.getSplitsProvider(), dataverseSplits.getConstraints(), + partitionsMap); + } + + @Override public PartitioningProperties getPartitioningProperties(DataverseName dataverseName) { SplitComputeLocations dataverseSplits = getDataverseSplits(dataverseName); StorageComputePartitionsMap partitionMap = clusterStateManager.getStorageComputeMap(); @@ -69,13 +78,16 @@ } private SplitComputeLocations getDataverseSplits(DataverseName dataverseName) { + return getSplits(StoragePathUtil.prepareDataverseName(dataverseName)); + } + + private SplitComputeLocations getSplits(String subPath) { List<FileSplit> splits = new ArrayList<>(); List<String> locations = new ArrayList<>(); Set<Integer> uniqueLocations = new HashSet<>(); StorageComputePartitionsMap partitionMap = clusterStateManager.getStorageComputeMap(); for (int i = 0; i < storagePartitionsCounts; i++) { - File f = new File(StoragePathUtil.prepareStoragePartitionPath(i), - StoragePathUtil.prepareDataverseName(dataverseName)); + File f = new File(StoragePathUtil.prepareStoragePartitionPath(i), subPath); ComputePartition computePartition = partitionMap.getComputePartition(i); splits.add(new MappedFileSplit(computePartition.getNodeId(), f.getPath(), 0)); if (!uniqueLocations.contains(computePartition.getId())) { -- To view, visit https://asterix-gerrit.ics.uci.edu/c/asterixdb/+/17841 To unsubscribe, or for help writing mail filters, visit https://asterix-gerrit.ics.uci.edu/settings Gerrit-Project: asterixdb Gerrit-Branch: master Gerrit-Change-Id: Iec9b559b6de09fa191d7b54a759c05a874d15913 Gerrit-Change-Number: 17841 Gerrit-PatchSet: 2 Gerrit-Owner: Ali Alsuliman <[email protected]> Gerrit-Reviewer: Ali Alsuliman <[email protected]> Gerrit-Reviewer: Jenkins <[email protected]> Gerrit-Reviewer: Michael Blow <[email protected]> Gerrit-Reviewer: Murtadha Hubail <[email protected]> Gerrit-CC: Till Westmann <[email protected]> Gerrit-MessageType: merged
