Search in sources :

Example 1 with DIRECT_TO_TARGET_NEW_DIRECTORY

use of io.trino.plugin.hive.LocationHandle.WriteMode.DIRECT_TO_TARGET_NEW_DIRECTORY in project trino by trinodb.

the class SemiTransactionalHiveMetastore method rollbackShared.

@GuardedBy("this")
private void rollbackShared() {
    checkHoldsLock();
    for (DeclaredIntentionToWrite declaredIntentionToWrite : declaredIntentionsToWrite) {
        switch(declaredIntentionToWrite.getMode()) {
            case STAGE_AND_MOVE_TO_TARGET_DIRECTORY:
            case DIRECT_TO_TARGET_NEW_DIRECTORY:
                // it will only be written to during the commit call and the commit call cleans up after failures.
                if ((declaredIntentionToWrite.getMode() == DIRECT_TO_TARGET_NEW_DIRECTORY) && skipTargetCleanupOnRollback) {
                    break;
                }
                Path rootPath = declaredIntentionToWrite.getRootPath();
                // In the case of DIRECT_TO_TARGET_NEW_DIRECTORY, if the directory is not guaranteed to be unique
                // for the query, it is possible that another query or compute engine may see the directory, wrote
                // data to it, and exported it through metastore. Therefore it may be argued that cleanup of staging
                // directories must be carried out conservatively. To be safe, we only delete files that start or
                // end with the query IDs in this transaction.
                recursiveDeleteFilesAndLog(declaredIntentionToWrite.getHdfsContext(), rootPath, ImmutableSet.of(declaredIntentionToWrite.getQueryId()), true, format("staging/target_new directory rollback for table %s", declaredIntentionToWrite.getSchemaTableName()));
                break;
            case DIRECT_TO_TARGET_EXISTING_DIRECTORY:
                Set<Path> pathsToClean = new HashSet<>();
                // Check the base directory of the declared intention
                // * existing partition may also be in this directory
                // * this is where new partitions are created
                Path baseDirectory = declaredIntentionToWrite.getRootPath();
                pathsToClean.add(baseDirectory);
                SchemaTableName schemaTableName = declaredIntentionToWrite.getSchemaTableName();
                Optional<Table> table = delegate.getTable(schemaTableName.getSchemaName(), schemaTableName.getTableName());
                if (table.isPresent()) {
                    // check every existing partition that is outside for the base directory
                    List<Column> partitionColumns = table.get().getPartitionColumns();
                    if (!partitionColumns.isEmpty()) {
                        List<String> partitionColumnNames = partitionColumns.stream().map(Column::getName).collect(toImmutableList());
                        List<String> partitionNames = delegate.getPartitionNamesByFilter(schemaTableName.getSchemaName(), schemaTableName.getTableName(), partitionColumnNames, TupleDomain.all()).orElse(ImmutableList.of());
                        for (List<String> partitionNameBatch : Iterables.partition(partitionNames, 10)) {
                            Collection<Optional<Partition>> partitions = delegate.getPartitionsByNames(schemaTableName.getSchemaName(), schemaTableName.getTableName(), partitionNameBatch).values();
                            partitions.stream().filter(Optional::isPresent).map(Optional::get).map(partition -> partition.getStorage().getLocation()).map(Path::new).filter(path -> !isSameOrParent(baseDirectory, path)).forEach(pathsToClean::add);
                        }
                    }
                } else {
                    logCleanupFailure("Error rolling back write to table %s.%s. Data directory may contain temporary data. Table was dropped in another transaction.", schemaTableName.getSchemaName(), schemaTableName.getTableName());
                }
                // delete any file that starts or ends with the query ID
                for (Path path : pathsToClean) {
                    // TODO: It is a known deficiency that some empty directory does not get cleaned up in S3.
                    // We cannot delete any of the directories here since we do not know who created them.
                    recursiveDeleteFilesAndLog(declaredIntentionToWrite.getHdfsContext(), path, ImmutableSet.of(declaredIntentionToWrite.getQueryId()), false, format("target_existing directory rollback for table %s", schemaTableName));
                }
                break;
            default:
                throw new UnsupportedOperationException("Unknown write mode");
        }
    }
}
Also used : Path(org.apache.hadoop.fs.Path) TableInvalidationCallback(io.trino.plugin.hive.TableInvalidationCallback) HiveUpdateProcessor(io.trino.plugin.hive.HiveUpdateProcessor) FileSystem(org.apache.hadoop.fs.FileSystem) USER(io.trino.spi.security.PrincipalType.USER) MetastoreConf.getTimeVar(org.apache.hadoop.hive.metastore.conf.MetastoreConf.getTimeVar) NO_ACID_TRANSACTION(io.trino.plugin.hive.acid.AcidTransaction.NO_ACID_TRANSACTION) FileStatus(org.apache.hadoop.fs.FileStatus) ColumnStatisticType(io.trino.spi.statistics.ColumnStatisticType) NOT_SUPPORTED(io.trino.spi.StandardErrorCode.NOT_SUPPORTED) TableNotFoundException(io.trino.spi.connector.TableNotFoundException) Configuration(org.apache.hadoop.conf.Configuration) Map(java.util.Map) HIVE_CORRUPTED_COLUMN_STATISTICS(io.trino.plugin.hive.HiveErrorCode.HIVE_CORRUPTED_COLUMN_STATISTICS) PRESTO_QUERY_ID_NAME(io.trino.plugin.hive.HiveMetadata.PRESTO_QUERY_ID_NAME) AcidTransaction(io.trino.plugin.hive.acid.AcidTransaction) HdfsEnvironment(io.trino.plugin.hive.HdfsEnvironment) ImmutableList.toImmutableList(com.google.common.collect.ImmutableList.toImmutableList) Set(java.util.Set) MILLISECONDS(java.util.concurrent.TimeUnit.MILLISECONDS) GuardedBy(javax.annotation.concurrent.GuardedBy) HiveWriteUtils.pathExists(io.trino.plugin.hive.util.HiveWriteUtils.pathExists) MANAGED_TABLE(org.apache.hadoop.hive.metastore.TableType.MANAGED_TABLE) SchemaTableName(io.trino.spi.connector.SchemaTableName) ImmutableMap.toImmutableMap(com.google.common.collect.ImmutableMap.toImmutableMap) OWNERSHIP(io.trino.plugin.hive.metastore.HivePrivilegeInfo.HivePrivilege.OWNERSHIP) SqlStandardAccessControlMetadataMetastore(io.trino.plugin.hive.security.SqlStandardAccessControlMetadataMetastore) RemoteIterator(org.apache.hadoop.fs.RemoteIterator) Joiner(com.google.common.base.Joiner) MoreObjects.toStringHelper(com.google.common.base.MoreObjects.toStringHelper) HIVE_TABLE_DROPPED_DURING_QUERY(io.trino.plugin.hive.HiveErrorCode.HIVE_TABLE_DROPPED_DURING_QUERY) PartitionStatistics(io.trino.plugin.hive.PartitionStatistics) Iterables(com.google.common.collect.Iterables) PartitionNotFoundException(io.trino.plugin.hive.PartitionNotFoundException) Supplier(java.util.function.Supplier) ArrayList(java.util.ArrayList) DataOperationType(org.apache.hadoop.hive.metastore.api.DataOperationType) HiveType(io.trino.plugin.hive.HiveType) OptionalLong(java.util.OptionalLong) Lists(com.google.common.collect.Lists) HiveTableHandle(io.trino.plugin.hive.HiveTableHandle) FormatMethod(com.google.errorprone.annotations.FormatMethod) ScheduledExecutorService(java.util.concurrent.ScheduledExecutorService) ImmutableSet.toImmutableSet(com.google.common.collect.ImmutableSet.toImmutableSet) LinkedHashSet(java.util.LinkedHashSet) PartitionAndStatementId(io.trino.plugin.hive.PartitionAndStatementId) ViewReaderUtil.isPrestoView(io.trino.plugin.hive.ViewReaderUtil.isPrestoView) Executor(java.util.concurrent.Executor) FileUtils.makePartName(org.apache.hadoop.hive.common.FileUtils.makePartName) PrincipalType(io.trino.spi.security.PrincipalType) TRANSACTION_CONFLICT(io.trino.spi.StandardErrorCode.TRANSACTION_CONFLICT) IOException(java.io.IOException) ConnectorSession(io.trino.spi.connector.ConnectorSession) MoreFutures.getFutureValue(io.airlift.concurrent.MoreFutures.getFutureValue) RoleGrant(io.trino.spi.security.RoleGrant) HiveMetastoreClosure(io.trino.plugin.hive.HiveMetastoreClosure) ValidTxnWriteIdList(org.apache.hadoop.hive.common.ValidTxnWriteIdList) HivePrivilege(io.trino.plugin.hive.metastore.HivePrivilegeInfo.HivePrivilege) NUM_ROWS(io.trino.plugin.hive.metastore.thrift.ThriftMetastoreUtil.NUM_ROWS) ScheduledFuture(java.util.concurrent.ScheduledFuture) HiveUtil.toPartitionValues(io.trino.plugin.hive.util.HiveUtil.toPartitionValues) AcidOperation(io.trino.plugin.hive.acid.AcidOperation) SchemaNotFoundException(io.trino.spi.connector.SchemaNotFoundException) Duration(io.airlift.units.Duration) Statistics.merge(io.trino.plugin.hive.util.Statistics.merge) Preconditions.checkArgument(com.google.common.base.Preconditions.checkArgument) ALREADY_EXISTS(io.trino.spi.StandardErrorCode.ALREADY_EXISTS) Path(org.apache.hadoop.fs.Path) HIVE_FILESYSTEM_ERROR(io.trino.plugin.hive.HiveErrorCode.HIVE_FILESYSTEM_ERROR) Statistics.reduce(io.trino.plugin.hive.util.Statistics.reduce) HiveBasicStatistics(io.trino.plugin.hive.HiveBasicStatistics) ImmutableSet(com.google.common.collect.ImmutableSet) ImmutableMap(com.google.common.collect.ImmutableMap) Collection(java.util.Collection) LocatedFileStatus(org.apache.hadoop.fs.LocatedFileStatus) TableAlreadyExistsException(io.trino.plugin.hive.TableAlreadyExistsException) TrinoException(io.trino.spi.TrinoException) HIVE_PATH_ALREADY_EXISTS(io.trino.plugin.hive.HiveErrorCode.HIVE_PATH_ALREADY_EXISTS) Collectors(java.util.stream.Collectors) FileNotFoundException(java.io.FileNotFoundException) String.format(java.lang.String.format) Preconditions.checkState(com.google.common.base.Preconditions.checkState) HdfsContext(io.trino.plugin.hive.HdfsEnvironment.HdfsContext) List(java.util.List) MetastoreUtil.buildInitialPrivilegeSet(io.trino.plugin.hive.metastore.MetastoreUtil.buildInitialPrivilegeSet) Optional(java.util.Optional) Pattern(java.util.regex.Pattern) WriteMode(io.trino.plugin.hive.LocationHandle.WriteMode) AcidUtils(org.apache.hadoop.hive.ql.io.AcidUtils) DIRECT_TO_TARGET_NEW_DIRECTORY(io.trino.plugin.hive.LocationHandle.WriteMode.DIRECT_TO_TARGET_NEW_DIRECTORY) Logger(io.airlift.log.Logger) Type(io.trino.spi.type.Type) AtomicBoolean(java.util.concurrent.atomic.AtomicBoolean) HashMap(java.util.HashMap) CompletableFuture(java.util.concurrent.CompletableFuture) Function(java.util.function.Function) HashSet(java.util.HashSet) ImmutableList(com.google.common.collect.ImmutableList) Verify.verify(com.google.common.base.Verify.verify) HIVE_METASTORE_ERROR(io.trino.plugin.hive.HiveErrorCode.HIVE_METASTORE_ERROR) Objects.requireNonNull(java.util.Objects.requireNonNull) LinkedList(java.util.LinkedList) Iterator(java.util.Iterator) HiveWriteUtils.isFileCreatedByQuery(io.trino.plugin.hive.util.HiveWriteUtils.isFileCreatedByQuery) TupleDomain(io.trino.spi.predicate.TupleDomain) HiveWriteUtils.createDirectory(io.trino.plugin.hive.util.HiveWriteUtils.createDirectory) SUBTRACT(io.trino.plugin.hive.util.Statistics.ReduceOperator.SUBTRACT) TXN_TIMEOUT(org.apache.hadoop.hive.metastore.conf.MetastoreConf.ConfVars.TXN_TIMEOUT) VisibleForTesting(com.google.common.annotations.VisibleForTesting) Optional(java.util.Optional) SchemaTableName(io.trino.spi.connector.SchemaTableName) LinkedHashSet(java.util.LinkedHashSet) HashSet(java.util.HashSet) GuardedBy(javax.annotation.concurrent.GuardedBy)

Aggregations

VisibleForTesting (com.google.common.annotations.VisibleForTesting)1 Joiner (com.google.common.base.Joiner)1 MoreObjects.toStringHelper (com.google.common.base.MoreObjects.toStringHelper)1 Preconditions.checkArgument (com.google.common.base.Preconditions.checkArgument)1 Preconditions.checkState (com.google.common.base.Preconditions.checkState)1 Verify.verify (com.google.common.base.Verify.verify)1 ImmutableList (com.google.common.collect.ImmutableList)1 ImmutableList.toImmutableList (com.google.common.collect.ImmutableList.toImmutableList)1 ImmutableMap (com.google.common.collect.ImmutableMap)1 ImmutableMap.toImmutableMap (com.google.common.collect.ImmutableMap.toImmutableMap)1 ImmutableSet (com.google.common.collect.ImmutableSet)1 ImmutableSet.toImmutableSet (com.google.common.collect.ImmutableSet.toImmutableSet)1 Iterables (com.google.common.collect.Iterables)1 Lists (com.google.common.collect.Lists)1 FormatMethod (com.google.errorprone.annotations.FormatMethod)1 MoreFutures.getFutureValue (io.airlift.concurrent.MoreFutures.getFutureValue)1 Logger (io.airlift.log.Logger)1 Duration (io.airlift.units.Duration)1 HdfsEnvironment (io.trino.plugin.hive.HdfsEnvironment)1 HdfsContext (io.trino.plugin.hive.HdfsEnvironment.HdfsContext)1