protected override void Write(BinaryWriter bw, OperationData operationData, bool isPhysicalWrite, bool forceRecomputeOffsets) { base.Write(bw, operationData, isPhysicalWrite, forceRecomputeOffsets); if (this.replicatedData.Array == null) { var startingPos = bw.BaseStream.Position; // Leave room for size bw.BaseStream.Position += sizeof(int); // Note that if you change this part, begin checkpoint log record also must be changed. bw.Write(this.backupId.ToByteArray()); bw.Write(this.highestBackedUpEpoch.DataLossNumber); bw.Write(this.highestBackedUpEpoch.ConfigurationNumber); bw.Write(this.highestBackedUpLsn.LSN); bw.Write(this.backupLogRecordCount); bw.Write(this.BackupLogSizeInKB); var endPosition = bw.BaseStream.Position; var sizeOfSection = checked ((int)(endPosition - startingPos)); bw.BaseStream.Position = startingPos; bw.Write(sizeOfSection); bw.BaseStream.Position = endPosition; this.replicatedData = CreateArraySegment(startingPos, bw); } operationData.Add(this.replicatedData); }
protected override void Write(BinaryWriter bw, OperationData operationData, bool isPhysicalWrite, bool forceRecomputeOffsets) { base.Write(bw, operationData, isPhysicalWrite, forceRecomputeOffsets); if (this.replicatedData.Array == null) { var startingPos = bw.BaseStream.Position; // Leave room for size bw.BaseStream.Position += sizeof(int); bw.Write(this.lastStableLsn.LSN); // Write size at the beginning. var endPosition = bw.BaseStream.Position; var sizeOfSection = checked ((int)(endPosition - startingPos)); bw.BaseStream.Position = startingPos; bw.Write(sizeOfSection); bw.BaseStream.Position = endPosition; this.replicatedData = CreateArraySegment(startingPos, bw); } operationData.Add(this.replicatedData); }
protected override void Write(BinaryWriter bw, OperationData operationData, bool isPhysicalWrite, bool forceRecomputeOffsets) { base.Write(bw, operationData, isPhysicalWrite, forceRecomputeOffsets); if (this.replicatedData == null) { this.replicatedData = new List <ArraySegment <byte> >(); // Metadata section. var startingPos = bw.BaseStream.Position; bw.BaseStream.Position += sizeof(int); // Metadata fields. bw.Write(this.isSingleOperationTransaction); // End Metadata section var endPosition = bw.BaseStream.Position; var sizeOfSection = checked ((int)(endPosition - startingPos)); bw.BaseStream.Position = startingPos; bw.Write(sizeOfSection); bw.BaseStream.Position = endPosition; this.replicatedData.Add(CreateArraySegment(startingPos, bw)); OperationLogRecord.WriteOperationData(this.metaData, bw, ref this.replicatedData); OperationLogRecord.WriteOperationData(this.redo, bw, ref this.replicatedData); OperationLogRecord.WriteOperationData(this.undo, bw, ref this.replicatedData); } foreach (var segment in this.replicatedData) { operationData.Add(segment); } }
protected override void Write(BinaryWriter bw, OperationData operationData, bool isPhysicalWrite, bool forceRecomputeOffsets) { base.Write(bw, operationData, isPhysicalWrite, forceRecomputeOffsets); var startingPos = bw.BaseStream.Position; bw.BaseStream.Position += sizeof(int); bw.Write(this.lastStableLsn.LSN); if (isPhysicalWrite == true) { if (this.lastCompletedBeginCheckpointRecordOffset == InvalidPhysicalRecordOffset || forceRecomputeOffsets == true) { Utility.Assert( this.lastCompletedBeginCheckpointRecord != null || forceRecomputeOffsets, "(this.lastCompletedBeginCheckpointRecord != null)={0} || forceRecomputeOffsets={1}", this.lastCompletedBeginCheckpointRecord != null, forceRecomputeOffsets); if (this.lastCompletedBeginCheckpointRecord != null) { if (this.lastCompletedBeginCheckpointRecord.RecordPosition != InvalidRecordPosition) { Utility.Assert( this.RecordPosition != InvalidPhysicalRecordOffset, "this.RecordPosition != LogRecord.INVALID_RECORD_POSITION"); this.lastCompletedBeginCheckpointRecordOffset = this.RecordPosition - this.lastCompletedBeginCheckpointRecord .RecordPosition; } else { this.lastCompletedBeginCheckpointRecordOffset = InvalidPhysicalRecordOffset; } } } bw.Write(this.lastCompletedBeginCheckpointRecordOffset); } var endPosition = bw.BaseStream.Position; var sizeOfSection = checked ((int)(endPosition - startingPos)); bw.BaseStream.Position = startingPos; bw.Write(sizeOfSection); bw.BaseStream.Position = endPosition; operationData.Add(CreateArraySegment(startingPos, bw)); }
/// <summary> /// Returns the metadata for the copied state. /// </summary> /// <returns></returns> /// <remarks> /// Contains /// - Version of the copy metadata state. /// - Progress ProgressVectorEntry of the copied checkpoint. /// - Copied Checkpoints Epoch /// - Sequence number of the first operation in the log to be copied. /// - Sequence number of the copied checkpoints sequence number. /// - UptoSequence number for the copy provided by the volatile replicator. /// - Highest possible the state providers could have copied. /// </remarks> private OperationData GetCopyStateMetadata() { var expectedSize = this.beginCheckpointRecord.ProgressVector.ByteCount; expectedSize += CopyStateMetadataByteSizeNotIncludingProgressVector; OperationData result; using (var stream = new MemoryStream(expectedSize)) { using (var bw = new BinaryWriter(stream)) { // First 4 bytes are reserved for the version of the metadata. bw.Write(CopyStateMetadataVersion); // TODO: Ask for the size to avoid expanding the memoryStream. this.beginCheckpointRecord.ProgressVector.Write(bw); var startingEpoch = this.beginCheckpointRecord.Epoch; bw.Write(startingEpoch.DataLossNumber); bw.Write(startingEpoch.ConfigurationNumber); bw.Write(this.sourceStartingLsn.LSN); bw.Write(this.beginCheckpointRecord.Lsn.LSN); bw.Write(this.uptoLsn.LSN); bw.Write(this.replicatedLogManager.CurrentLogTailLsn.LSN); Utility.Assert( expectedSize == stream.Position, "Position mismatch. Expected {0} Position {1}", expectedSize, stream.Position); result = new OperationData(new ArraySegment <byte>(stream.GetBuffer(), 0, (int)stream.Position)); result.Add(CopyProgressVectorOperation); } } var trace = "Copying Log Preamble. SourceStartingLSN: " + this.sourceStartingLsn.LSN + " BeginCheckpointLSN: " + this.beginCheckpointRecord.Lsn.LSN + " StateRecordsCoipied: " + this.copiedRecordNumber + " CurrentTailSequenceNumber: " + this.replicatedLogManager.CurrentLogTailLsn.LSN; FabricEvents.Events.CopyStreamGetNext(tracer.Type, trace); return(result); }
internal static OperationData WriteRecord( LogRecord record, BinaryWriter bw, bool isPhysicalWrite = true, bool setRecordLength = true, bool forceRecomputeOffsets = false) { // NOTE:- The binary writer is not where the real data is written // It is only passed in to avoid each log record from creating its own writer // The real data of the log record is returned in the operation data // As a result, reset the position of the writer before starting to write bw.BaseStream.Position = 0; var operationData = new OperationData(); record.Write(bw, operationData, isPhysicalWrite, forceRecomputeOffsets); uint recordLength = 0; foreach (var data in operationData) { recordLength += (uint)data.Count; } if (setRecordLength) { record.RecordLength = recordLength; } var mm = bw.BaseStream as MemoryStream; var startingPosition = bw.BaseStream.Position; bw.Write(recordLength); var arraySegment = new ArraySegment <byte>( mm.GetBuffer(), (int)startingPosition, (int)mm.Position - (int)startingPosition); // Append and prepend record length in a fixed encoding of sizeof(int) bytes operationData.Add(arraySegment); operationData.Insert(0, arraySegment); return(operationData); }
internal static OperationData ReadOperationData(BinaryReader br) { var count = br.ReadInt32(); if (count == NullOperationDataCode) { return(null); } var operationData = new OperationData(); for (var i = 0; i < count; i++) { operationData.Add(ReadBytes(br)); } return(operationData); }
protected override void Write(BinaryWriter bw, OperationData operationData, bool isPhysicalWrite, bool forceRecomputeOffsets) { base.Write(bw, operationData, isPhysicalWrite, forceRecomputeOffsets); var startingPos = bw.BaseStream.Position; bw.BaseStream.Position += sizeof(int); bw.Write((int)this.informationEvent); var endPosition = bw.BaseStream.Position; var sizeOfSection = checked ((int)(endPosition - startingPos)); bw.BaseStream.Position = startingPos; bw.Write(sizeOfSection); bw.BaseStream.Position = endPosition; operationData.Add(CreateArraySegment(startingPos, bw)); }
protected override void Write(BinaryWriter bw, OperationData operationData, bool isPhysicalWrite, bool forceRecomputeOffsets) { base.Write(bw, operationData, isPhysicalWrite, forceRecomputeOffsets); var startingPosition = bw.BaseStream.Position; bw.BaseStream.Position += sizeof(int); if (this.linkedPhysicalRecordOffset == InvalidPhysicalRecordOffset || forceRecomputeOffsets == true) { Utility.Assert( this.linkedPhysicalRecord != null || forceRecomputeOffsets == true, "(this.linkedPhysicalRecord != null)={0}, forceRecomputeOffsets={1}", this.linkedPhysicalRecord != null, forceRecomputeOffsets); if (this.linkedPhysicalRecord == null) { this.linkedPhysicalRecordOffset = 0; } else { Utility.Assert( this.linkedPhysicalRecord.RecordPosition != InvalidRecordPosition, "this.linkedPhysicalRecord.RecordPosition != LogRecord.INVALID_RECORD_POSITION"); Utility.Assert( this.RecordPosition != InvalidRecordPosition, "this.RecordPosition != LogRecord.INVALID_RECORD_POSITION"); this.linkedPhysicalRecordOffset = this.RecordPosition - this.linkedPhysicalRecord.RecordPosition; } } bw.Write(this.linkedPhysicalRecordOffset); var endPosition = bw.BaseStream.Position; var sizeOfSection = checked ((int)(endPosition - startingPosition)); bw.BaseStream.Position = startingPosition; bw.Write(sizeOfSection); bw.BaseStream.Position = endPosition; operationData.Add(CreateArraySegment(startingPosition, bw)); return; }
protected override void Write(BinaryWriter bw, OperationData operationData, bool isPhysicalWrite, bool forceRecomputeOffsets) { base.Write(bw, operationData, isPhysicalWrite, forceRecomputeOffsets); var startingPosition = bw.BaseStream.Position; bw.BaseStream.Position += sizeof(int); bw.Write(this.isStable); bw.Write(this.periodicTruncationTimeTicks); var endPosition = bw.BaseStream.Position; var sizeOfSection = checked ((int)(endPosition - startingPosition)); bw.BaseStream.Position = startingPosition; bw.Write(sizeOfSection); bw.BaseStream.Position = endPosition; operationData.Add(CreateArraySegment(startingPosition, bw)); }
protected override void Write(BinaryWriter bw, OperationData operationData, bool isPhysicalWrite, bool forceRecomputeOffsets) { base.Write(bw, operationData, isPhysicalWrite, forceRecomputeOffsets); var startingPosition = bw.BaseStream.Position; // Metadata Size bw.BaseStream.Position += sizeof(int); // Future fields // End of metadata. var endPosition = bw.BaseStream.Position; var sizeOfSection = checked ((int)(endPosition - startingPosition)); bw.BaseStream.Position = startingPosition; bw.Write(sizeOfSection); bw.BaseStream.Position = endPosition; operationData.Add(CreateArraySegment(startingPosition, bw)); }
protected override void Write(BinaryWriter bw, OperationData operationData, bool isPhysicalWrite, bool forceRecomputeOffsets) { base.Write(bw, operationData, isPhysicalWrite, forceRecomputeOffsets); var startingPos = bw.BaseStream.Position; bw.BaseStream.Position += sizeof(int); bw.Write(this.logHeadEpoch.DataLossNumber); bw.Write(this.logHeadEpoch.ConfigurationNumber); bw.Write(this.logHeadLsn.LSN); bw.Write(this.logHeadPsn.PSN); if (isPhysicalWrite == true) { if (this.logHeadRecordOffset == InvalidPhysicalRecordOffset || forceRecomputeOffsets == true) { Utility.Assert( this.logHeadRecord != null, "this.logHeadRecord != null"); Utility.Assert( this.logHeadRecord.RecordPosition != InvalidRecordPosition, "this.logHeadRecord.RecordPosition != LogRecord.INVALID_RECORD_POSITION"); Utility.Assert( this.RecordPosition != InvalidRecordPosition, "this.RecordPosition != LogRecord.INVALID_RECORD_POSITION"); this.logHeadRecordOffset = this.RecordPosition - this.logHeadRecord.RecordPosition; } bw.Write(this.logHeadRecordOffset); } var endPosition = bw.BaseStream.Position; var sizeOfSection = checked ((int)(endPosition - startingPos)); bw.BaseStream.Position = startingPos; bw.Write(sizeOfSection); bw.BaseStream.Position = endPosition; operationData.Add(CreateArraySegment(startingPos, bw)); return; }
internal static OperationData ReadOperationData(OperationData operationData, ref int index) { int count; using (var br = new BinaryReader(IncrementIndexAndGetMemoryStreamAt(operationData, ref index))) { count = br.ReadInt32(); } if (count == NullOperationDataCode) { return(null); } var operationData2 = new OperationData(); for (var i = 0; i < count; i++) { operationData2.Add(ReadBytes(operationData, ref index)); } return(operationData2); }
protected override void Write(BinaryWriter bw, OperationData operationData, bool isPhysicalWrite, bool forceRecomputeOffsets) { base.Write(bw, operationData, isPhysicalWrite, forceRecomputeOffsets); var startingPosition = bw.BaseStream.Position; bw.BaseStream.Position += sizeof(int); bw.Write(this.epoch.DataLossNumber); bw.Write(this.epoch.ConfigurationNumber); bw.Write(this.primaryReplicaId); bw.Write(this.timestamp.ToBinary()); var endPosition = bw.BaseStream.Position; var sizeOfSection = checked ((int)(endPosition - startingPosition)); bw.BaseStream.Position = startingPosition; bw.Write(sizeOfSection); bw.BaseStream.Position = endPosition; operationData.Add(CreateArraySegment(startingPosition, bw)); return; }
private async Task <OperationData> GetNextAsyncSafe(CancellationToken cancellationToken) { OperationData data; if (this.copyStage == CopyStage.CopyMetadata) { data = await this.copyContext.GetNextAsync(CancellationToken.None).ConfigureAwait(false); Utility.Assert(data.Count == 1, "data.Count == 1"); var bytes = data[0].Array; using (var br = new BinaryReader(new MemoryStream(bytes, data[0].Offset, data[0].Count))) { this.targetReplicaId = br.ReadInt64(); this.targetProgressVector = new ProgressVector(); this.targetProgressVector.Read(br, false); var targetLogHeadDatalossNumber = br.ReadInt64(); var targetLogHeadConfigurationNumber = br.ReadInt64(); this.targetLogHeadEpoch = new Epoch(targetLogHeadDatalossNumber, targetLogHeadConfigurationNumber); this.targetLogHeadLsn = new LogicalSequenceNumber(br.ReadInt64()); this.currentTargetLsn = new LogicalSequenceNumber(br.ReadInt64()); this.latestRecoveredAtomicRedoOperationLsn = br.ReadInt64(); } var message = string.Format( CultureInfo.InvariantCulture, "Target Replica Copy Context: {0}" + Environment.NewLine + " TargetLogHeadEpoch: {1},{2} TargetLogHeadLsn: {3} TargetLogTailEpoch: {4},{5} TargetLogTailLSN: {6}" + Environment.NewLine + " SourceLogHeadEpoch: {7},{8} SourceLogHeadLsn: {9} SourceLogTailEpoch: {10},{11} SourceLogTailLSN: {12}" + Environment.NewLine + " Target ProgressVector: {13}" + Environment.NewLine + " Source ProgressVector: {14}" + Environment.NewLine + " LastRecoveredAtomicRedoOperationLsn: {15}", this.targetReplicaId, this.targetLogHeadEpoch.DataLossNumber, this.targetLogHeadEpoch.ConfigurationNumber, this.targetLogHeadLsn.LSN, this.targetProgressVector.LastProgressVectorEntry.Epoch.DataLossNumber, this.targetProgressVector.LastProgressVectorEntry.Epoch.ConfigurationNumber, this.currentTargetLsn.LSN, this.replicatedLogManager.CurrentLogHeadRecord.CurrentEpoch.DataLossNumber, this.replicatedLogManager.CurrentLogHeadRecord.CurrentEpoch.ConfigurationNumber, this.replicatedLogManager.CurrentLogHeadRecord.Lsn.LSN, this.replicatedLogManager.CurrentLogTailEpoch.DataLossNumber, this.replicatedLogManager.CurrentLogTailEpoch.ConfigurationNumber, this.replicatedLogManager.CurrentLogTailLsn.LSN, this.targetProgressVector.ToString(Constants.ProgressVectorMaxStringSizeInKb / 2), this.replicatedLogManager.ProgressVector.ToString(Constants.ProgressVectorMaxStringSizeInKb / 2), this.latestRecoveredAtomicRedoOperationLsn); FabricEvents.Events.CopyStreamMetadata(tracer.Type, message); await this.waitForLogFlushUptoLsn(this.uptoLsn).ConfigureAwait(false); CopyMode copyMode; await this.checkpointManager.AcquireBackupAndCopyConsistencyLockAsync("Copy").ConfigureAwait(false); try { copyMode = this.checkpointManager.GetLogRecordsToCopy( this.targetProgressVector, this.targetLogHeadEpoch, this.targetLogHeadLsn, this.currentTargetLsn, this.latestRecoveredAtomicRedoOperationLsn, this.targetReplicaId, out this.sourceStartingLsn, out this.targetStartingLsn, out this.logRecordsToCopy, out this.beginCheckpointRecord); } finally { this.checkpointManager.ReleaseBackupAndCopyConsistencyLock("Copy"); } CopyStage copyStageToWrite; if (copyMode == CopyMode.None) { this.copyStage = CopyStage.CopyNone; copyStageToWrite = CopyStage.CopyNone; } else if (copyMode == CopyMode.Full) { this.copyStage = CopyStage.CopyState; copyStageToWrite = CopyStage.CopyState; this.copyStateStream = this.stateManager.GetCurrentState(); } else if ((copyMode & CopyMode.FalseProgress) != 0) { Utility.Assert( this.sourceStartingLsn <= this.targetStartingLsn, "this.sourceStartingLsn ({0}) <= this.targetStartingLsn ({1})", this.sourceStartingLsn, this.targetStartingLsn); this.copyStage = CopyStage.CopyFalseProgress; copyStageToWrite = CopyStage.CopyFalseProgress; } else { this.copyStage = CopyStage.CopyScanToStartingLsn; copyStageToWrite = CopyStage.CopyLog; } return(this.GetCopyMetadata(copyStageToWrite)); } if (this.copyStage == CopyStage.CopyState) { data = await this.copyStateStream.GetNextAsync(cancellationToken).ConfigureAwait(false); if (data != null) { data.Add(CopyStateOperation); FabricEvents.Events.CopyStreamGetNextNoise( tracer.Type, "Copying State Operation: " + this.copiedRecordNumber); ++this.copiedRecordNumber; return(data); } var disposableCopyStateStream = this.copyStateStream as IDisposable; if (disposableCopyStateStream != null) { disposableCopyStateStream.Dispose(); } if (this.uptoLsn < beginCheckpointRecord.LastStableLsn) { // Ensure we copy records up to the stable LSN of the begin checkpoint record as part of the copy stream // so that the idle can initiate a checkpoint and apply it as part of the copy pump itself // Not doing the above will mean that the idle can get promoted to active even before the checkpoint is completed // uptolsn is inclusive LSN // BUG: RDBug #9269022:Replicator must rename copy log before changing role to active secondary during full builds this.uptoLsn = beginCheckpointRecord.LastStableLsn; var trace = "FullCopy: Copying Logs from " + this.sourceStartingLsn.LSN + " to BC.LastStableLsn: " + beginCheckpointRecord.LastStableLsn.LSN + " as the upto lsn: " + this.uptoLsn + " was smaller than the checkpoint stable lsn"; FabricEvents.Events.CopyStreamGetNext(tracer.Type, trace); } data = this.GetCopyStateMetadata(); this.copyStage = CopyStage.CopyLog; this.copiedRecordNumber = 0; return(data); } if (this.copyStage == CopyStage.CopyFalseProgress) { this.copyStage = CopyStage.CopyScanToStartingLsn; this.bw.BaseStream.Position = 0; this.bw.Write(this.sourceStartingLsn.LSN); var stream = this.bw.BaseStream as MemoryStream; data = new OperationData(new ArraySegment <byte>(stream.GetBuffer(), 0, (int)stream.Position)); data.Add(CopyFalseProgressOperation); var trace = "Copying False Progress. SourceStartingLSN: " + this.sourceStartingLsn.LSN + " TargetStartingLSN: " + this.targetStartingLsn.LSN; FabricEvents.Events.CopyStreamGetNext(tracer.Type, trace); return(data); } LogRecord record; if (this.copyStage == CopyStage.CopyScanToStartingLsn) { var startingLsn = (this.sourceStartingLsn < this.targetStartingLsn) ? this.sourceStartingLsn : this.targetStartingLsn; do { var hasMoved = await this.logRecordsToCopy.MoveNextAsync(cancellationToken).ConfigureAwait(false); if (hasMoved == false) { goto Finish; } record = this.logRecordsToCopy.Current; Utility.Assert(record.Lsn <= startingLsn, "record.Lsn <= startingLsn"); } while (record.Lsn < startingLsn); // The log stream is positioned at the end of startingLsn at this point. The enumerator Current is pointing to the "startingLsn" this.copyStage = CopyStage.CopyLog; } if (this.copyStage == CopyStage.CopyLog) { do { // This will start copying after the startingLsn record as expected var hasMoved = await this.logRecordsToCopy.MoveNextAsync(cancellationToken).ConfigureAwait(false); if (hasMoved == false) { goto Finish; } record = this.logRecordsToCopy.Current; } while (record is PhysicalLogRecord); if (record.Lsn > this.uptoLsn) { goto Finish; } var logicalLogRecord = record as LogicalLogRecord; Utility.Assert(logicalLogRecord != null, "Must be a logical log record"); data = logicalLogRecord.ToOperationData(this.bw); data.Add(CopyLogOperation); var trace = "Copying log record. LogRecordNumber: " + this.copiedRecordNumber + "Record Type: " + record.RecordType + " LSN: " + record.Lsn.LSN; FabricEvents.Events.CopyStreamGetNextNoise(tracer.Type, trace); ++this.copiedRecordNumber; return(data); } Finish: if (this.logRecordsToCopy != null) { this.logRecordsToCopy.Dispose(); } FabricEvents.Events.CopyStreamFinished(tracer.Type, this.copiedRecordNumber); return(null); }
protected override void Write(BinaryWriter bw, OperationData operationData, bool isPhysicalWrite, bool forceRecomputeOffsets) { base.Write(bw, operationData, isPhysicalWrite, forceRecomputeOffsets); var startingPos = bw.BaseStream.Position; // Leave room for size bw.BaseStream.Position += sizeof(int); // By now, all the log records before this begin checkpoint must have been serialized if (this.earliestPendingTransactionOffset == LogicalLogRecord.InvalidLogicalRecordOffset || forceRecomputeOffsets == true) { Utility.Assert( this.earliestPendingTransaction != BeginTransactionOperationLogRecord.InvalidBeginTransactionLogRecord, "Earliest pending transaction is not expected to be invalid"); if (this.earliestPendingTransaction == null) { this.earliestPendingTransactionOffset = 0; } else { this.earliestPendingTransactionOffset = this.RecordPosition - this.earliestPendingTransaction.RecordPosition; } } Utility.Assert(this.progressVector != null, "this.progressVector != null"); this.progressVector.Write(bw); bw.Write(this.earliestPendingTransactionOffset); Utility.Assert( this.epoch != LogicalSequenceNumber.InvalidEpoch, "this.copyEpoch != LogicalSequenceNumber.InvalidEpoch"); bw.Write(this.epoch.DataLossNumber); bw.Write(this.epoch.ConfigurationNumber); // Write the backup information. // Note that if you change this part, backup log record also must be changed. Utility.Assert( this.highestBackedUpEpoch.DataLossNumber != LogicalSequenceNumber.InvalidLsn.LSN, "this.backupLogSize != uint.MaxValue"); Utility.Assert( this.highestBackedUpEpoch.ConfigurationNumber != LogicalSequenceNumber.InvalidLsn.LSN, "this.backupLogSize != uint.MaxValue"); Utility.Assert( this.highestBackedUpLsn != LogicalSequenceNumber.InvalidLsn, "this.backupLogSize != uint.MaxValue"); Utility.Assert(this.backupLogRecordCount != uint.MaxValue, "this.backupLogSize != uint.MaxValue"); Utility.Assert(this.backupLogSize != uint.MaxValue, "this.backupLogSize != uint.MaxValue"); bw.Write(this.backupId.ToByteArray()); bw.Write(this.highestBackedUpEpoch.DataLossNumber); bw.Write(this.highestBackedUpEpoch.ConfigurationNumber); bw.Write(this.highestBackedUpLsn.LSN); bw.Write(this.backupLogRecordCount); bw.Write(this.backupLogSize); bw.Write(this.lastPeriodicCheckpointTimeTicks); bw.Write(this.lastPeriodicTruncationTimeTicks); var endPosition = bw.BaseStream.Position; var sizeOfSection = checked ((int)(endPosition - startingPos)); bw.BaseStream.Position = startingPos; bw.Write(sizeOfSection); bw.BaseStream.Position = endPosition; operationData.Add(CreateArraySegment(startingPos, bw)); }
protected virtual void Write(BinaryWriter bw, OperationData operationData, bool isPhysicalWrite, bool forceRecomputeOffsets) { // NOTE - LogicalData optimization is NOT done here unlike other log records because the lsn is not yet assigned at this point. // Logical Metadata section. var logicalStartingPosition = bw.BaseStream.Position; bw.BaseStream.Position += sizeof(int); // Logical Metadata fields bw.Write((uint)this.recordType); bw.Write(this.lsn.LSN); // End Logical Metadata section var logicalEndPosition = bw.BaseStream.Position; var logicalSizeOfSection = checked ((int)(logicalEndPosition - logicalStartingPosition)); bw.BaseStream.Position = logicalStartingPosition; bw.Write(logicalSizeOfSection); bw.BaseStream.Position = logicalEndPosition; operationData.Add(CreateArraySegment(logicalStartingPosition, bw)); if (isPhysicalWrite) { // Physical Metadata section. var physicalStartPosition = bw.BaseStream.Position; bw.BaseStream.Position += sizeof(int); bw.Write(this.psn.PSN); Utility.Assert( this.recordPosition != InvalidRecordPosition, "this.recordPosition != LogRecord.INVALID_RECORD_POSITION"); if (this.previousPhysicalRecordOffset == InvalidPhysicalRecordOffset) { Utility.Assert( this.previousPhysicalRecord != PhysicalLogRecord.InvalidPhysicalLogRecord, "this.previousPhysicalRecord != PhysicalLogRecord.InvalidPhysicalLogRecord"); if (this.previousPhysicalRecord == null) { this.previousPhysicalRecordOffset = 0; } else { Utility.Assert( this.previousPhysicalRecord.recordPosition != InvalidRecordPosition, "this.previousPhysicalRecord.recordPosition != LogRecord.INVALID_RECORD_POSITION"); Utility.Assert( this.recordPosition != InvalidRecordPosition, "this.recordPosition != LogRecord.INVALID_RECORD_POSITION"); this.previousPhysicalRecordOffset = this.recordPosition - this.previousPhysicalRecord.recordPosition; } } else { Utility.CodingError( "Record written twice. Record Type:{0} RecordPosition={1}", this.recordType, this.recordPosition); } bw.Write(this.previousPhysicalRecordOffset); // End Logical Metadata section var physicalEndPosition = bw.BaseStream.Position; var physicalSizeOfSection = checked ((int)(physicalEndPosition - physicalStartPosition)); bw.BaseStream.Position = physicalStartPosition; bw.Write(physicalSizeOfSection); bw.BaseStream.Position = physicalEndPosition; operationData.Add(CreateArraySegment(physicalStartPosition, bw)); } return; }
protected override void Write(BinaryWriter bw, OperationData operationData, bool isPhysicalWrite, bool forceRecomputeOffsets) { base.Write(bw, operationData, isPhysicalWrite, forceRecomputeOffsets); var startingPosition = bw.BaseStream.Position; if (this.replicatedData.Array == null) { bw.BaseStream.Position += sizeof(int); bw.Write(this.transaction.Id); var endPosition = bw.BaseStream.Position; var sizeOfSection = checked ((int)(endPosition - startingPosition)); bw.BaseStream.Position = startingPosition; bw.Write(sizeOfSection); bw.BaseStream.Position = endPosition; this.replicatedData = CreateArraySegment(startingPosition, bw); } operationData.Add(this.replicatedData); if (isPhysicalWrite) { // Physical Metadata section. var physicalStartPosition = bw.BaseStream.Position; bw.BaseStream.Position += sizeof(int); startingPosition = bw.BaseStream.Position; if (this.parentTransactionRecordOffset == InvalidLogicalRecordOffset || forceRecomputeOffsets == true) { Utility.Assert( this.parentTransactionRecord != InvalidLogicalLogRecord || forceRecomputeOffsets == true, "(this.parentTransactionRecord != LogicalLogRecord.InvalidLogicalLogRecord)={0}, forceRecomputeOffsets={1}", this.parentTransactionRecord != InvalidLogicalLogRecord, forceRecomputeOffsets); if (this.parentTransactionRecord == null) { this.parentTransactionRecordOffset = 0; } else { Utility.Assert( this.parentTransactionRecord.RecordPosition != InvalidRecordPosition, "his.parentTransactionRecord.RecordPosition != LogRecord.INVALID_RECORD_POSITION"); Utility.Assert( this.RecordPosition != InvalidRecordPosition, "this.RecordPosition != LogRecord.INVALID_RECORD_POSITION"); this.parentTransactionRecordOffset = this.RecordPosition - this.parentTransactionRecord.RecordPosition; } } bw.Write(this.parentTransactionRecordOffset); // End Physical Metadata section var physicalEndPosition = bw.BaseStream.Position; var physicalSizeOfSection = checked ((int)(physicalEndPosition - physicalStartPosition)); bw.BaseStream.Position = physicalStartPosition; bw.Write(physicalSizeOfSection); bw.BaseStream.Position = physicalEndPosition; operationData.Add(CreateArraySegment(physicalStartPosition, bw)); } return; }