MCPcopy Create free account
hub / github.com/ClickHouse/ClickHouse / rollback

Method rollback

src/Interpreters/MergeTreeTransaction.cpp:315–384  ·  view source on GitHub ↗

Source from the content-addressed store, hash-verified

313}
314
315bool MergeTreeTransaction::rollback() noexcept
316{
317 auto blocker = CannotAllocateThreadFaultInjector::blockFaultInjections();
318 LockMemoryExceptionInThread memory_tracker_lock(VariableContext::Global);
319 CSN expected = Tx::UnknownCSN;
320 bool need_rollback = csn.compare_exchange_strong(expected, Tx::RolledBackCSN);
321
322 /// Check that it was not rolled back concurrently
323 if (!need_rollback)
324 return false;
325
326 /// It's not a problem if server crash at this point
327 /// because on startup we will see that TID is not committed and will simply discard these changes.
328
329 RunningMutationsList mutations_to_kill;
330 DataPartsVector parts_to_remove;
331 DataPartsVector parts_to_activate;
332
333 {
334 std::lock_guard lock{mutex};
335 mutations_to_kill = mutations;
336 parts_to_remove = creating_parts;
337 parts_to_activate = removing_parts;
338 }
339
340 /// Forcefully stop related mutations if any
341 for (const auto & table_and_mutation : mutations_to_kill)
342 table_and_mutation.first->killMutation(table_and_mutation.second);
343
344 /// Discard changes in active parts set
345 /// Remove parts that were created, restore parts that were removed (except parts that were created by this transaction too)
346
347 /// Kind of optimization: cleanup thread can remove these parts immediately
348 for (const auto & part : parts_to_remove)
349 {
350 /// Write special RolledBackCSN, so we will be able to cleanup transaction log
351 part->version->setAndStoreCreationCSN(Tx::RolledBackCSN);
352 }
353
354 for (const auto & part : parts_to_remove)
355 {
356 /// NOTE It's possible that part is already removed from working set in the same transaction
357 /// (or, even worse, in a separate non-transactional query with NonTransactionalTID),
358 /// but it's not a problem: removePartsFromWorkingSet(...) will do nothing in this case.
359 const_cast<MergeTreeData &>(part->storage).removePartsFromWorkingSet(NO_TRANSACTION_RAW, {part}, true);
360 }
361
362 for (const auto & part : parts_to_activate)
363 if (part->version->getInfo().creation_tid != tid)
364 const_cast<MergeTreeData &>(part->storage).restoreAndActivatePart(part);
365
366 for (const auto & part : parts_to_activate)
367 {
368 /// Clear removal_tid from version metadata file, so we will not need to distinguish TIDs that were not committed
369 /// and TIDs that were committed long time ago and were removed from the log on log cleanup.
370 part->version->setAndStoreRemovalTID(Tx::EmptyTID);
371 part->version->unlockRemovalTID(tid, TransactionInfoContext{part->storage.getStorageID(), part->name});
372 }

Callers 3

completeMethod · 0.45
rollbackTransactionMethod · 0.45

Calls 8

setAndStoreRemovalTIDMethod · 0.80
unlockRemovalTIDMethod · 0.80
killMutationMethod · 0.45
getInfoMethod · 0.45
getStorageIDMethod · 0.45

Tested by

no test coverage detected