/// <summary> /// Create a new <see cref="BackupMetadataFile"/> and write it to the given file. /// </summary> /// <returns>Task that represents the asynchronous operation.</returns> public static async Task <BackupMetadataFile> CreateAsync( string fileName, BackupOption backupOption, Guid parentBackupId, Guid backupId, Guid partitionId, long replicaId, Epoch startingEpoch, long startingLsn, Epoch backupEpoch, long backupLsn, CancellationToken cancellationToken) { // Create the file with asynchronous flag and 4096 cache size (C# default). // MCoskun: Default IoPriorityHint is used. // Reason: Backup is a user operation. using (var filestream = FabricFile.Open( fileName, FileMode.CreateNew, FileAccess.Write, FileShare.Read, 4096, FileOptions.Asynchronous)) { Utility.SetIoPriorityHint(filestream.SafeFileHandle, Kernel32Types.PRIORITY_HINT.IoPriorityHintLow); var backupMetadataFile = new BackupMetadataFile(fileName); backupMetadataFile.properties = new BackupMetadataFileProperties() { BackupOption = backupOption, ParentBackupId = parentBackupId, BackupId = backupId, PartitionId = partitionId, ReplicaId = replicaId, StartingEpoch = startingEpoch, StartingLsn = startingLsn, BackupEpoch = backupEpoch, BackupLsn = backupLsn, }; // Write the properties. var propertiesHandle = await FileBlock.WriteBlockAsync(filestream, writer => backupMetadataFile.properties.Write(writer)).ConfigureAwait(false); cancellationToken.ThrowIfCancellationRequested(); // Write the footer. backupMetadataFile.footer = new FileFooter(propertiesHandle, Version); await FileBlock.WriteBlockAsync(filestream, writer => backupMetadataFile.footer.Write(writer)).ConfigureAwait(false); cancellationToken.ThrowIfCancellationRequested(); // Flush to underlying stream. await filestream.FlushAsync(cancellationToken).ConfigureAwait(false); return(backupMetadataFile); } }
/// <summary> /// Create a new <see cref="StateManagerFile"/> and write it to the given file. /// </summary> /// <param name="filePath">Path to the checkpoint file.</param> /// <param name="partitionId">Service partition Id.</param> /// <param name="replicaId">Service replica Id.</param> /// <param name="metadataList">The state providers' metadata.</param> /// <param name="allowPrepareCheckpointLSNToBeInvalid"> /// Allow the prepare checkpoint LSN to be invalid. If it is invalid, do not write it. /// </param> /// <param name="prepareCheckpointLSN">The PrepareCheckpointLSN.</param> /// <param name="cancellationToken">Token used to signal cancellation.</param> /// <returns>The new <see cref="BackupLogFile"/>.</returns> public static async Task <StateManagerFile> CreateAsync( string filePath, Guid partitionId, long replicaId, List <SerializableMetadata> metadataList, bool allowPrepareCheckpointLSNToBeInvalid, long prepareCheckpointLSN, CancellationToken cancellationToken) { // #12249219: Without the "allowPrepareCheckpointLSNToBeInvalid" being set to true in the backup code path, // It is possible for all backups before the first checkpoint after the upgrade to fail. // If the code has the PrepareCheckpointLSN property, it must be larger than or equal to ZeroLSN(0). Utility.Assert( allowPrepareCheckpointLSNToBeInvalid || prepareCheckpointLSN >= StateManagerConstants.ZeroLSN, "{0}:{1} CreateAsync: In the write path, prepareCheckpointLSN must be larger or equal to 0. PrepareCheckpointLSN: {2}.", partitionId, replicaId, prepareCheckpointLSN); // Create the file with asynchronous flag and 4096 cache size (C# default). // MCoskun: Default IoPriorityHint is used. // Reason: Used during backup and checkpoint (user operation and life-cycle operation respectively). using (var filestream = FabricFile.Open( filePath, FileMode.Create, FileAccess.Write, FileShare.Write, 4096, FileOptions.Asynchronous)) { var stateManagerFile = new StateManagerFile(filePath); stateManagerFile.StateProviderMetadata = metadataList; bool shouldNotWritePrepareCheckpointLSN = prepareCheckpointLSN == StateManagerConstants.InvalidLSN ? true : false; stateManagerFile.properties = new StateManagerFileProperties(shouldNotWritePrepareCheckpointLSN); stateManagerFile.properties.PartitionId = partitionId; stateManagerFile.properties.ReplicaId = replicaId; if (shouldNotWritePrepareCheckpointLSN == false) { stateManagerFile.properties.PrepareCheckpointLSN = prepareCheckpointLSN; } // Write the state provider metadata. var blocks = await stateManagerFile.WriteMetadataAsync(filestream, metadataList, cancellationToken).ConfigureAwait(false); stateManagerFile.properties.MetadataHandle = new BlockHandle(offset: 0, size: filestream.Position); cancellationToken.ThrowIfCancellationRequested(); // Write the blocks and update the properties. stateManagerFile.properties.BlocksHandle = await FileBlock.WriteBlockAsync(filestream, (sectionWriter) => blocks.Write(sectionWriter)).ConfigureAwait(false); cancellationToken.ThrowIfCancellationRequested(); // Write the properties. var propertiesHandle = await FileBlock.WriteBlockAsync(filestream, writer => stateManagerFile.properties.Write(writer)).ConfigureAwait(false); cancellationToken.ThrowIfCancellationRequested(); // Write the footer. stateManagerFile.footer = new FileFooter(propertiesHandle, Version); await FileBlock.WriteBlockAsync(filestream, writer => stateManagerFile.footer.Write(writer)).ConfigureAwait(false); cancellationToken.ThrowIfCancellationRequested(); // Ensure we fully flush the data to disk before returning. await filestream.FlushAsync().ConfigureAwait(false); stateManagerFile.FileSize = filestream.Length; return(stateManagerFile); } }
/// <summary> /// Create a new <see cref="BackupLogFile"/> and write it to the given file. /// </summary> /// <param name="fileName">Name of the backup file.</param> /// <param name="logRecords">The log records.</param> /// <param name="lastBackupLogRecord"></param> /// <param name="cancellationToken">Token used to signal cancellation.</param> /// <returns>The new <see cref="BackupLogFile"/>.</returns> public static async Task <BackupLogFile> CreateAsync( string fileName, IAsyncEnumerator <LogRecord> logRecords, BackupLogRecord lastBackupLogRecord, CancellationToken cancellationToken) { var stopwatch = new Stopwatch(); stopwatch.Start(); var backupLogFile = new BackupLogFile(fileName); backupLogFile.properties = new BackupLogFileProperties(); // Create the file with asynchronous flag and 4096 cache size (C# default). using (var filestream = FabricFile.Open( fileName, FileMode.CreateNew, FileAccess.Write, FileShare.Write, 4096, FileOptions.Asynchronous)) { Utility.SetIoPriorityHint(filestream.SafeFileHandle, Kernel32Types.PRIORITY_HINT.IoPriorityHintLow); var incrementalBackupRecords = logRecords as IncrementalBackupLogRecordAsyncEnumerator; if (incrementalBackupRecords == null) { await backupLogFile.WriteLogRecordsAsync(filestream, logRecords, cancellationToken).ConfigureAwait(false); } else { await backupLogFile.WriteLogRecordsAsync(filestream, incrementalBackupRecords, cancellationToken).ConfigureAwait(false); await incrementalBackupRecords.VerifyDrainedAsync().ConfigureAwait(false); Utility.Assert(backupLogFile.Count == incrementalBackupRecords.Count, "Unexpected count"); backupLogFile.properties.IndexingRecordEpoch = incrementalBackupRecords.StartingEpoch; backupLogFile.properties.IndexingRecordLsn = incrementalBackupRecords.StartingLsn; if (incrementalBackupRecords.HighestBackedupEpoch == LoggingReplicator.InvalidEpoch) { backupLogFile.properties.LastBackedUpEpoch = lastBackupLogRecord.HighestBackedUpEpoch; } else { backupLogFile.properties.LastBackedUpEpoch = incrementalBackupRecords.HighestBackedupEpoch; } backupLogFile.properties.LastBackedUpLsn = incrementalBackupRecords.HighestBackedupLsn; } // Write the log records. backupLogFile.properties.RecordsHandle = new BlockHandle(offset: 0, size: filestream.Position); cancellationToken.ThrowIfCancellationRequested(); // Write the properties. var propertiesHandle = await FileBlock.WriteBlockAsync(filestream, writer => backupLogFile.properties.Write(writer)).ConfigureAwait(false); cancellationToken.ThrowIfCancellationRequested(); // Write the footer. backupLogFile.footer = new FileFooter(propertiesHandle, Version); await FileBlock.WriteBlockAsync(filestream, writer => backupLogFile.footer.Write(writer)).ConfigureAwait(false); cancellationToken.ThrowIfCancellationRequested(); // Store the size. backupLogFile.Size = filestream.Length; } stopwatch.Stop(); backupLogFile.WriteTimeInMilliseconds = stopwatch.ElapsedMilliseconds; return(backupLogFile); }