Esempio n. 1
0
        internal void AddOperation(OperationLogRecord record)
        {
            Utility.Assert(record.Transaction.IsValidTransaction, "record.Transaction.IsValidTransaction == true");

            if (record.Transaction.IsAtomicOperation)
            {
                record.IsEnlistedTransaction = true;
            }
            else
            {
                lock (this.txmapLock)
                {
                    if (this.latestRecords.ContainsKey(record.Transaction.Id))
                    {
                        record.IsEnlistedTransaction   = this.latestRecords[record.Transaction.Id].IsEnlistedTransaction;
                        record.ParentTransactionRecord = this.latestRecords[record.Transaction.Id];
                        record.ParentTransactionRecord.ChildTransactionRecord = record;
                        this.latestRecords[record.Transaction.Id]             = record;
                        return;
                    }

                    this.latestRecords[record.Transaction.Id] = record;
                }

                Utility.Assert(record.IsEnlistedTransaction == false, "record.IsEnlistedTransaction == false");
            }

            record.ParentTransactionRecord = null;
        }
Esempio n. 2
0
        internal OperationLogRecord FindOperation(OperationLogRecord record)
        {
            Utility.Assert(record.Transaction.IsValidTransaction, "record.Transaction.IsValidTransaction == true");
            Utility.Assert(record.IsOperationContextPresent == false, "record.IsOperationContextPresent == false");

            if (record.Transaction.IsAtomicOperation)
            {
                Utility.Assert(record.ParentTransactionRecord == null, "record.ParentTransactionRecord == null");
            }
            else
            {
                Utility.Assert(
                    LogRecord.IsInvalidRecord(record.ParentTransactionRecord),
                    "LogRecord.IsInvalidRecord(record.ParentTransactionRecord) == true");
                lock (this.txmapLock)
                {
                    Utility.Assert(
                        this.latestRecords.ContainsKey(record.Transaction.Id),
                        "Could not find operation in latest records");
                    return((OperationLogRecord)this.latestRecords[record.Transaction.Id]);
                }
            }

            return(record);
        }
Esempio n. 3
0
        internal OperationLogRecord RedactOperation(OperationLogRecord record)
        {
            Utility.Assert(record.Transaction.IsValidTransaction, "record.Transaction.IsValidTransaction == true");
            Utility.Assert(record.IsOperationContextPresent == false, "record.IsOperationContextPresent == false");

            if (record.Transaction.IsAtomicOperation)
            {
                Utility.Assert(record.ParentTransactionRecord == null, "record.ParentTransactionRecord == null");
            }
            else
            {
                Utility.Assert(
                    LogRecord.IsInvalidRecord(record.ParentTransactionRecord),
                    "LogRecord.IsInvalidRecord(record.ParentTransactionRecord) == true");
                lock (this.txmapLock)
                {
                    Utility.Assert(
                        this.latestRecords.ContainsKey(record.Transaction.Id),
                        "latestRecords_.ContainsKey(record.Transaction.Id)");

                    record = (OperationLogRecord)this.latestRecords[record.Transaction.Id];
                    this.latestRecords[record.Transaction.Id]             = record.ParentTransactionRecord;
                    record.ParentTransactionRecord.ChildTransactionRecord =
                        TransactionLogRecord.InvalidTransactionLogRecord;
                    return(record);
                }
            }

            return(record);
        }
        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);
            }
        }
Esempio n. 5
0
        private static LogRecord ReadFromOperationData(OperationData operationData)
        {
            LogRecord     record;
            long          lsn;
            const ulong   RecordPosition = InvalidRecordPosition;
            LogRecordType recordType;
            var           index = -1;

            using (var reader = new BinaryReader(IncrementIndexAndGetMemoryStreamAt(operationData, ref index)))
            {
                // Logical metadata section.
                var startingPosition = reader.BaseStream.Position;
                var sizeOfSection    = reader.ReadInt32();
                var endPosition      = startingPosition + sizeOfSection;

                // Logical metadata read.
                recordType = (LogRecordType)reader.ReadUInt32();
                lsn        = reader.ReadInt64();

                // Jump to the end of the section ignoring fields that are not understood.
                Utility.Assert(endPosition >= reader.BaseStream.Position, "Could not have read more than section size.");
                reader.BaseStream.Position = endPosition;
            }

            switch (recordType)
            {
            case LogRecordType.BeginTransaction:
                record = new BeginTransactionOperationLogRecord(recordType, RecordPosition, lsn);
                break;

            case LogRecordType.Operation:
                record = new OperationLogRecord(recordType, RecordPosition, lsn);
                break;

            case LogRecordType.EndTransaction:
                record = new EndTransactionLogRecord(recordType, RecordPosition, lsn);
                break;

            case LogRecordType.Barrier:
                record = new BarrierLogRecord(recordType, RecordPosition, lsn);
                break;

            case LogRecordType.UpdateEpoch:
                record = new UpdateEpochLogRecord(recordType, RecordPosition, lsn);
                break;

            case LogRecordType.Backup:
                record = new BackupLogRecord(recordType, RecordPosition, lsn);
                break;

            default:
                Utility.CodingError(
                    "Unexpected record type received during replication/copy processing {0}",
                    recordType);
                return(null);
            }

            record.ReadLogical(operationData, ref index);
            return(record);
        }
        protected override void ReadLogical(OperationData operationData, ref int index)
        {
            base.ReadLogical(operationData, ref index);

            using (var br = new BinaryReader(IncrementIndexAndGetMemoryStreamAt(operationData, ref index)))
            {
                // Read metadata section
                var startingPosition = br.BaseStream.Position;
                var sizeOfSection    = br.ReadInt32();
                var endPosition      = startingPosition + sizeOfSection;

                // Read metadata fields
                this.isSingleOperationTransaction = br.ReadBoolean();

                // Jump to the end of the section ignoring fields that are not understood.
                Utility.Assert(endPosition >= br.BaseStream.Position, "Could not have read more than section size.");
                br.BaseStream.Position = endPosition;
            }

            this.metaData = OperationLogRecord.ReadOperationData(operationData, ref index);
            this.redo     = OperationLogRecord.ReadOperationData(operationData, ref index);
            this.undo     = OperationLogRecord.ReadOperationData(operationData, ref index);

            this.UpdateApproximateDiskSize();
        }
Esempio n. 7
0
        internal static void Assert(bool condition, string format, OperationLogRecord param1, BeginCheckpointLogRecord param2)
        {
            if (condition == false)
            {
                var failFastMessage = string.Format(System.Globalization.CultureInfo.InvariantCulture, format, param1, param2);
                FailFast(failFastMessage);

                // AMW - Force break into debugger for ease of debugging
                Debugger.Break();
            }
        }
Esempio n. 8
0
        public void AddOperation(
            Transaction transaction,
            OperationData metaData,
            OperationData undo,
            OperationData redo,
            object operationContext)
        {
            var record = new OperationLogRecord(transaction, metaData, undo, redo, operationContext);

            this.ProcessLogicalRecordOnPrimary(record);
        }
Esempio n. 9
0
        public async Task <long> AddOperationAsync(
            AtomicRedoOperation atomicRedoOperation,
            OperationData metaData,
            OperationData redo,
            object operationContext)
        {
            var record = new OperationLogRecord(atomicRedoOperation, metaData, redo, operationContext);

            await this.ProcessLogicalRecordOnPrimaryAsync(record).ConfigureAwait(false);

            return(record.Lsn.LSN);
        }
Esempio n. 10
0
        /// <summary>
        /// Process the operation transaction log record.
        /// </summary>
        /// <param name="operationLogRecord">The operation transaction record to be processed.</param>
        /// <param name="isRecoverableRecord">Is this a recoverable record.</param>
        private void ProcessLogRecord(OperationLogRecord operationLogRecord, out bool isRecoverableRecord)
        {
            isRecoverableRecord = true;

            this.LastLogicalSequenceNumber++;
            Utility.Assert(
                operationLogRecord.Lsn == this.LastLogicalSequenceNumber,
                "operationRecord.LastLogicalSequenceNumber == lsn");
            this.TransactionsMap.AddOperation(operationLogRecord);

            if (Mode.Recovery == this.mode)
            {
                Utility.Assert(
                    (operationLogRecord.IsEnlistedTransaction == true) ||
                    (operationLogRecord.RecordPosition
                     < this.recoveredLastCompletedBeginCheckpointRecord.RecordPosition),
                    "(operationLogRecord.IsEnlistedTransaction == true) || (operationLogRecord.RecordPosition < this.recoveredLastCompletedBeginCheckpointRecord.RecordPosition). " +
                    "OperationLogRecord: {0}, this.recoveredLastCompletedBeginCheckpointRecord: {1}",
                    operationLogRecord, this.recoveredLastCompletedBeginCheckpointRecord);
            }
            else
            {
                Utility.Assert(
                    LogRecord.InvalidRecordPosition == operationLogRecord.RecordPosition,
                    "LogRecord.INVALID_RECORD_POSITION == operationLogRecord.RecordPosition. OperationLogRecord: {0}",
                    operationLogRecord);
            }

            isRecoverableRecord = operationLogRecord.IsEnlistedTransaction == true;

            if (operationLogRecord.IsRedoOnly)
            {
                this.LastRecoveredAtomicRedoOperationLsn = operationLogRecord.Lsn.LSN;

                var message = string.Format(
                    CultureInfo.InvariantCulture,
                    "RedoOnly Operation Epoch: <{0}, {1}>",
                    this.ProgressVector.LastProgressVectorEntry.Epoch.DataLossNumber,
                    this.ProgressVector.LastProgressVectorEntry.Epoch.ConfigurationNumber);

                FabricEvents.Events.LogRecordsMap(
                    this.tracer.Type,
                    operationLogRecord.RecordType.ToString(),
                    this.LastRecoveredAtomicRedoOperationLsn,
                    message);
            }
        }
        protected override void Read(BinaryReader br, bool isPhysicalRead)
        {
            // IF THIS METHOD CHANGES, READLOGICAL MUST CHANGE ACCORDINGLY AS WE ARE ADDING MULTIPLE ARRAYSEGMENTS HERE
            // THIS IS TRUE FOR ANY REDO+UNDO TYPE RECORDS
            base.Read(br, isPhysicalRead);

            // Metadata section.
            var startingPosition = br.BaseStream.Position;
            var sizeOfSection    = br.ReadInt32();
            var endPosition      = startingPosition + sizeOfSection;

            // Read single operation optimiation flag.
            this.isSingleOperationTransaction = br.ReadBoolean();

            // Jump to the end of the section ignoring fields that are not understood.
            Utility.Assert(endPosition >= br.BaseStream.Position, "Could not have read more than section size.");
            br.BaseStream.Position = endPosition;

            this.metaData = OperationLogRecord.ReadOperationData(br);
            this.redo     = OperationLogRecord.ReadOperationData(br);
            this.undo     = OperationLogRecord.ReadOperationData(br);

            this.UpdateApproximateDiskSize();
        }
Esempio n. 12
0
        private static LogRecord ReadRecord(BinaryReader br, ulong recordPosition, bool isPhysicalRead)
        {
            LogRecord     record;
            var           lsn = LogicalSequenceNumber.InvalidLsn.LSN;
            LogRecordType recordType;

            // Metadata section.
            var startingPosition = br.BaseStream.Position;
            var sizeOfSection    = br.ReadInt32();
            var endPosition      = startingPosition + sizeOfSection;

            // Read Logical Metadata
            recordType = (LogRecordType)br.ReadUInt32();

            switch (recordType)
            {
            case LogRecordType.BeginTransaction:
                record = new BeginTransactionOperationLogRecord(recordType, recordPosition, lsn);
                break;

            case LogRecordType.Operation:
                record = new OperationLogRecord(recordType, recordPosition, lsn);
                break;

            case LogRecordType.EndTransaction:
                record = new EndTransactionLogRecord(recordType, recordPosition, lsn);
                break;

            case LogRecordType.Barrier:
                record = new BarrierLogRecord(recordType, recordPosition, lsn);
                break;

            case LogRecordType.UpdateEpoch:
                record = new UpdateEpochLogRecord(recordType, recordPosition, lsn);
                break;

            case LogRecordType.Backup:
                record = new BackupLogRecord(recordType, recordPosition, lsn);
                break;

            case LogRecordType.BeginCheckpoint:
                record = new BeginCheckpointLogRecord(recordType, recordPosition, lsn);
                break;

            case LogRecordType.EndCheckpoint:
                record = new EndCheckpointLogRecord(recordType, recordPosition, lsn);
                break;

            case LogRecordType.Indexing:
                record = new IndexingLogRecord(recordType, recordPosition, lsn);
                break;

            case LogRecordType.TruncateHead:
                record = new TruncateHeadLogRecord(recordType, recordPosition, lsn);
                break;

            case LogRecordType.TruncateTail:
                record = new TruncateTailLogRecord(recordType, recordPosition, lsn);
                break;

            case LogRecordType.Information:
                record = new InformationLogRecord(recordType, recordPosition, lsn);
                break;

            case LogRecordType.CompleteCheckpoint:
                record = new CompleteCheckpointLogRecord(recordType, recordPosition, lsn);
                break;

            default:
                Utility.CodingError("Unexpected record type {0}", recordType);
                return(null);
            }

            record.lsn = new LogicalSequenceNumber(br.ReadInt64());

            // Jump to the end of the section ignoring fields that are not understood.
            Utility.Assert(endPosition >= br.BaseStream.Position, "Could not have read more than section size.");
            br.BaseStream.Position = endPosition;

            record.Read(br, isPhysicalRead);

            return(record);
        }