def parse_status(self, inp: BinaryIO): by_txn = read_txn_id(inp) read_time = ReadHybridTime.load(inp) txn_id = read_txn_id(inp) commit_time = HybridTime.load(inp) reason = CommitTimeReason(inp.read_uint8()) status_time = HybridTime.load(inp) safe_time = HybridTime.load(inp) txn = self.get_transaction(txn_id) txn.status_log.append(StatusLogEntry(read_time, by_txn, commit_time, reason)) txn.add_log( read_time.read, "status check by", by_txn, commit_time, reason, status_time, safe_time) self.get_transaction(by_txn).add_log( read_time.read, "see status", txn_id, commit_time, reason, status_time, safe_time)
def __init__(self, txn_id: UUID): self.id = txn_id self.involved_tablets = None self.commit_time = HybridTime() self.status_log: List[StatusLogEntry] = [] self.aborted = False self.log: List[TxnLogEntry] = []
def load_transaction_conflict_data(inp: BinaryIO) -> Optional[TransactionConflictData]: txn_id = read_txn_id(inp) if txn_id is None: return None status = TransactionStatus(inp.read_uint32()) inp.read_uint32() commit_time = HybridTime.load(inp) priority = inp.read_uint64() failed = inp.read_uint64() != 0 return TransactionConflictData(txn_id, status, commit_time, priority, failed)
def parse_commit(self, inp: BinaryIO): txn_id = read_txn_id(inp) commit_time = HybridTime.load(inp) txn = self.get_transaction(txn_id) tablets = inp.read_uint32() if txn.commit_time.valid(): if txn.commit_time != commit_time: raise Exception('Wrong commit time {} vs {}'.format(commit_time, txn)) else: txn.commit_time = commit_time txn.involved_tablets = tablets
def parse_conflicts(self, inp: BinaryIO): txn_id = read_txn_id(inp) hybrid_time = HybridTime.load(inp) txn = self.get_transaction(txn_id) if not hybrid_time.valid(): txn.aborted = True while True: txn_data = load_transaction_conflict_data(inp) if txn_data is None: break txn.add_log(hybrid_time, "see conflict", txn_data) self.get_transaction(txn_data.id).add_log( hybrid_time, "conflict check by", txn_id, txn_data)
def parse_apply(self, inp: BinaryIO): tablet = inp.read(32).decode('utf-8') txn = read_txn_id(inp) log_ht = HybridTime.load(inp) inp.read_int64() # Sequence no count = inp.read_int32() for i in range(0, count): cmd = WriteBatchEntryType(inp.read_int8()) if cmd == WriteBatchEntryType.kTypeValue: key = SubDocKey.decode(inp.read_varbytes(), True) value = decode_value(inp.read_varbytes()) self.analyzer.apply_row(tablet, txn, key, value, log_ht) else: raise Exception('Not supported write batch entry type: {}'.format(cmd))
class TransactionConflictData(NamedTuple): id: UUID = UUID(int=0) status: TransactionStatus = TransactionStatus.UNKNOWN commit_time: HybridTime = HybridTime() priority: int = 0 failed: bool = False
def parse_remove(self, inp: BinaryIO): tablet = inp.read(32).decode('utf-8') txn_id = read_txn_id(inp) hybrid_time = HybridTime.load(inp) reason = RemoveReason(inp.read_uint8()) self.get_transaction(txn_id).add_log(hybrid_time, "remove", reason)
def parse_applied(self, inp: BinaryIO): txn_id = read_txn_id(inp) hybrid_time = HybridTime.load(inp) self.get_transaction(txn_id).add_log(hybrid_time, "applied")