diff options
author | snaury <snaury@ydb.tech> | 2023-04-05 18:46:24 +0300 |
---|---|---|
committer | snaury <snaury@ydb.tech> | 2023-04-05 18:46:24 +0300 |
commit | fd86d9a7713285bdfb8f09300f04bac908f451e5 (patch) | |
tree | 75ac22abea6024ad2748746c083fb50df426562a | |
parent | 2eb21fc7d5f358ba19d86ed2bab01f64219814aa (diff) | |
download | ydb-fd86d9a7713285bdfb8f09300f04bac908f451e5.tar.gz |
Support different element sizes in persisted tx artifacts
-rw-r--r-- | ydb/core/tx/datashard/datashard_active_transaction.cpp | 11 | ||||
-rw-r--r-- | ydb/core/tx/datashard/datashard_impl.h | 2 | ||||
-rw-r--r-- | ydb/core/tx/datashard/datashard_trans_queue.cpp | 30 |
3 files changed, 36 insertions, 7 deletions
diff --git a/ydb/core/tx/datashard/datashard_active_transaction.cpp b/ydb/core/tx/datashard/datashard_active_transaction.cpp index 8f334f8b1ff..6f72f6d367d 100644 --- a/ydb/core/tx/datashard/datashard_active_transaction.cpp +++ b/ydb/core/tx/datashard/datashard_active_transaction.cpp @@ -582,12 +582,19 @@ void TActiveTransaction::DbStoreLocksAccessLog(TDataShard * self, using Schema = TDataShard::Schema; NIceDb::TNiceDb db(txc.DB); - TVector<TSysTables::TLocksTable::TPersistentLock> vec; + + using TLocksVector = TVector<TSysTables::TLocksTable::TPersistentLock>; + TLocksVector vec; vec.reserve(LocksAccessLog().Locks.size()); for (auto &pr : LocksAccessLog().Locks) vec.emplace_back(pr.second); + + // Historically C++ column type was TVector<TLock> + const char* vecDataStart = reinterpret_cast<const char*>(vec.data()); + size_t vecDataSize = vec.size() * sizeof(TLocksVector::value_type); + TStringBuf vecData(vecDataStart, vecDataSize); db.Table<Schema::TxArtifacts>().Key(GetTxId()) - .Update(NIceDb::TUpdate<Schema::TxArtifacts::Locks>(vec)); + .Update(NIceDb::TUpdate<Schema::TxArtifacts::Locks>(vecData)); LOG_TRACE_S(ctx, NKikimrServices::TX_DATASHARD, "Storing " << vec.size() << " locks for txid=" << GetTxId() diff --git a/ydb/core/tx/datashard/datashard_impl.h b/ydb/core/tx/datashard/datashard_impl.h index 39a24478c6c..04124acae01 100644 --- a/ydb/core/tx/datashard/datashard_impl.h +++ b/ydb/core/tx/datashard/datashard_impl.h @@ -642,7 +642,7 @@ class TDataShard // Specify which tx artifacts have been stored to local DB and can be // reused on tx replay. See TActiveTransaction::EArtifactFlags. struct Flags : Column<2, NScheme::NTypeIds::Uint64> {}; - struct Locks : Column<3, NScheme::NTypeIds::String> { using Type = TVector<TSysTables::TLocksTable::TPersistentLock>; }; + struct Locks : Column<3, NScheme::NTypeIds::String> { using Type = TStringBuf; }; using TKey = TableKey<TxId>; using TColumns = TableColumns<TxId, Flags, Locks>; diff --git a/ydb/core/tx/datashard/datashard_trans_queue.cpp b/ydb/core/tx/datashard/datashard_trans_queue.cpp index 4e529eb25d7..a23b9fcbb81 100644 --- a/ydb/core/tx/datashard/datashard_trans_queue.cpp +++ b/ydb/core/tx/datashard/datashard_trans_queue.cpp @@ -360,11 +360,33 @@ bool TTransQueue::LoadTxDetails(NIceDb::TNiceDb &db, artifactFlags = 0; if (!artifactsRow.EndOfSet()) { artifactFlags = artifactsRow.GetValue<Schema::TxArtifacts::Flags>(); - auto persistentLocks = artifactsRow.GetValueOrDefault<Schema::TxArtifacts::Locks>({}); locks.clear(); - locks.reserve(persistentLocks.size()); - for (const auto& persistentLock : persistentLocks) { - locks.push_back(TSysTables::TLocksTable::TLock::FromPersistent(persistentLock)); + + // Deserialize persisted locks from database + // Unfortunately there was a bad version briefly deployed to clusters + // that had an additional field in the locks structure, so we have to + // guess an element data size. Luckily there's always either 0 or 1 + // locks in the column, so guessing is not really ambiguous. + TStringBuf data = artifactsRow.GetValueOrDefault<Schema::TxArtifacts::Locks>({}); + if (!data.empty()) { + size_t elementSize = sizeof(TSysTables::TLocksTable::TPersistentLock); + if ((data.size() % elementSize) != 0) { + size_t badElementSize = elementSize + 8; + Y_VERIFY_S((data.size() % badElementSize) == 0, + "Unexpected Schema::TxArtifacts::Locks column size " << data.size() + << " (expected divisible by " << elementSize << " or " << badElementSize << ")"); + elementSize = badElementSize; + } + + const char* p = data.data(); + size_t count = data.size() / elementSize; + locks.reserve(count); + + for (size_t i = 0; i < count; ++i) { + locks.push_back(TSysTables::TLocksTable::TLock::FromPersistent( + ReadUnaligned<TSysTables::TLocksTable::TPersistentLock>(p))); + p += elementSize; + } } } |