ConceptioArchivearXiv CS
arXiv CSopen access

RCC: Speculative Write Versioning with Redo Logs

Unknown · 2026 · arxiv_cs
arXiv CS · Papers · License: Open Access · 2026
Open Source ↗Direct PDF ↓
databasesdatamanagementsqlstorage
databases, sql, data management, storage

RCC: Speculative Write Versioning with Redo Logs Hyejin Yoo∗

Seongjae Moon∗

Sang-Won Lee

Jonghyeok Park

Seoul National University [email protected]

Seoul National University [email protected]

Seoul National University [email protected]

Korea University [email protected]

arXiv:2607.19697v1 [cs.DB] 22 Jul 2026

Modern OLTP engines rely on multi-versioning to eliminate read-write conflicts, yet their concurrency is severely limited for write-write conflicts. The conventional wisdom of updating records in place and immediately causes only one transaction to update a record at a time, and other update-conflicting transactions to wait for the former to commit or abort. Thus, conflicting transactions are serialized. We propose RCC, which leverages redo logs to resolve conflicting writes. A transaction updates a record out of place by creating a speculative write version using the redo log. With multiple speculative versions, RCC allows concurrent transactions to be pipelined after the update-conflicting point. Each update made by a transaction is installed to its record upon commit. This lazy update policy enables lightweight rollback: a transaction aborts simply by discarding its speculative versions. To fully realize the performance potential of its speculative versioning, RCC also proposes two novel techniques: commit-time deadlock detection and columnar RCC (RCC-C). The former detects cycles only once lazily at commit time and the latter eliminates record-level false WW conflicts by leveraging columngranule redo logs. RCC guarantees serializability using lock-based access-time conflict ordering and dependency graph tracking. We implement RCC on MySQL and PostgreSQL, seamlessly integrating the concurrency control mechanism with their buffer managers, lock managers, and recovery modules. RCC improves TPC-C’s transaction throughput and latency over Vanilla versions by an order of magnitude when running 64 concurrent threads on a machine with 128 cores. RCC-C further boosts throughput and latency by avoiding false conflict-induced deadlocks and unnecessary aborts. For a high-contention YCSB benchmark, commit-time deadlock detection enables RCC to scale to 128 clients while competing schemes do not scale beyond 32 threads.

CCS CONCEPTS • Information systems → Database transaction processing.

KEYWORDS Concurrency Control, Redo log, MVCC, OLTP

1

INTRODUCTION

Concurrency control is a fundamental component of OLTP systems, as it determines how concurrent transactions interleave with each other for consistency and concurrency. In traditional singleversion concurrency control schemes, such as two-phase locking (2PL), the database maintains only the most recent version of each object. To prevent anomalies including dirty reads, non-repeatable reads, and lost updates, single-version systems enforce pessimistic ∗ Both authors contributed equally.

Throughput (TPS)

ABSTRACT

20K

Vanilla MySQL RCC-W 12.7x RCC-D RCC RCC-C 8.2x

10K

3.9x

30K

4.7x

12.9x 10.4x

8.4x 3.6x

4.7x

4.7x 1.8x 2.0x

0

Read-Committed

Repeatable-Read

Serializable

Figure 1: TPC-C Throughput (1 WH, 64 Clients): RCC pipelines WW-conflicting transactions via speculative versioning, while Vanilla MySQL serializes them. Commit-time deadlock detection enables RCC to far outperform woundwait (RCC-W) and eager detection (RCC-D). Columnar RCC (RCC-C) further eliminates false conflicts among transactions accessing disjoint columns. locking on the current version [39]. Thus, read-write (RW), writeread (WR), and write-write (WW) conflicts cause transactions to be blocked. In particular, any transaction updating an object must hold an exclusive lock on the current version until commit, forcing WW-conflicting transactions to be strictly serialized and limiting concurrency severely. Multi-version concurrency control (MVCC) was introduced to alleviate this limitation. By maintaining multiple committed versions of an object as well as its current version, MVCC allows reads and updates to proceed concurrently without blocking each other [42], thus resolving RW and WR conflicts and significantly improving concurrency compared to single-version systems. In particular, many MVCC systems, including MySQL and Oracle, reconstruct past committed versions on demand using undo logs, which were originally designed for recovery [4]. Although existing MVCC systems eliminate RW and WR conflicts using committed past versions and the current version of an object, they still handle WW conflicts pessimistically. That is, they allow only one transaction to update the current version of an object at a time by holding the write lock until its commit or abort, thereby blocking other conflicting transactions from updating the same object. To quantify this limitation, we run TPC-C on MySQL and PostgreSQL with up to 128 clients. As we detail in Section 2, transaction throughput quickly plateaus and CPU utilization remains low on servers equipped with 128 physical CPU cores. These results suggest that WW conflicts are the primary bottleneck preventing production DBMSs from scaling on modern many-core servers. Meanwhile, many OLTP workloads exhibit a characteristic that makes WW blocking avoidable: most transactions commit successfully and update conflict-causing records early in their execution, typically at most once (Section 2). Under these conditions, exposing uncommitted writes to subsequent transactions and pipelining their execution is unlikely to cause anomalies. Yet existing MVCC systems forgo this opportunity because the trade-off between early

Hyejin Yoo, Seongjae Moon, Sang-Won Lee, and Jonghyeok Park

write visibility and correctness has long been resolved in favor of pessimism. The prevailing practice of updating records in place and immediately causes only one transaction to update a record at a time, forcing conflicting transactions to be serialized. We argue that this in-place update convention is the root cause of pessimistic WW handling [13]. Anomalies such as dirty reads and non-repeatable reads do not stem from exposing uncommitted updates, but from overwriting a shared current version. If active transactions’ updates on the same record are maintained as separate versions and ordered by lock acquisition time, they can proceed concurrently without compromising correctness. Based on this observation, we propose RCC, which resolves WW conflicts by leveraging redo logs as speculative write versions. When updating a record, rather than immediately overwriting the current version in the data page, a transaction creates a speculative write version using its redo log entry, leaving the current version intact until commit. After the update, the transaction immediately releases the lock, allowing other transactions to access the record without waiting. Upon commit, the speculative version is installed into the data page. This lazy update policy of RCC makes rollback lightweight: a transaction aborts simply by discarding its speculative versions, since no changes have yet been installed to the data page. By maintaining separate speculative versions per active transaction, RCC enables transactions conflicting on the same record to be pipelined concurrently, each proceeding on the latest speculative version without waiting for predecessors to commit. RCC creates speculative versions in lock acquisition order and maintains a dependency graph to enforce commit ordering and cascade aborts among conflicting transactions. By adjusting the scope of dependency tracking in this graph, RCC supports all standard isolation levels. Under Read Committed and Repeatable Read, RCC tracks only WW dependencies from speculative writes. Under Serializable, RCC additionally tracks RW anti-dependencies [7, 38] and detects cycles in the dependency graph to prevent anomalies such as write skew [3]. While speculative versioning enables transactions to be pipelined, realizing its full potential requires two novel mechanisms. First, we propose optimistic commit-time deadlock detection, a novel deadlock handling scheme designed for speculative versioning, assuming that true deadlocks are not frequent in practice [14]. Although RCC eliminates lock-induced blocking, deadlock handling remains critical for both correctness and performance. Existing speculative versioning systems rely on wound-wait [15], which requires a deadlock prevention action on every lock acquisition and may cause false aborts [66]. In contrast, RCC allows each transaction to execute to completion without interruption, performing cycle detection only once at commit time. Only upon a true deadlock does RCC abort the involved transactions. This eliminates both false aborts and per-conflict detection overhead from the execution path, significantly reducing transaction latency and improving overall throughput. Commit-time deadlock detection is the key mechanism that enables RCC to outperform existing deadlock prevention schemes and scale up to 128 CPU cores and threads, whereas competing schemes suffer significant throughput degradation beyond 32 concurrent threads (Section 6). Second, we propose Columnar RCC (RCC-C), enabled by RCC’s redo log-based design. In record-level RCC, false WW conflicts arise

when transactions update different columns of the same record, forcing short pre-committed transactions to wait for long ones and, even worse, causing false deadlocks and aborts. By tracking modifications at column granularity as redo log deltas, RCC-C eliminates false WW conflicts, further improving transaction throughput and latency. The main contributions of this paper are summarized as follows: • We identify that OLTP workloads present opportunities for speculative write visibility, including low abort ratio, rare re-updates, and early conflict points, yet existing MVCC systems fail to exploit this opportunity due to the in-place update convention. • We propose a new concurrency control scheme, RCC, which addresses WW conflicts. Its key idea is to repurpose redo logs as speculative write versions and thus to enable update-conflicting transactions to be pipelined. • We present two techniques that realize the full potential of speculative write versioning: commit-time deadlock detection, which eliminates false aborts from wound-wait by deferring cycle detection to the commit phase, and columnar dependency tracking, which leverages physiological redo logs to eliminate false WW conflicts between transactions modifying disjoint columns. • We implement RCC on both MySQL and PostgreSQL with approximately 2K and 1K lines of code changes, respectively. RCC seamlessly integrates with the recovery module of each production DBMS. Under TPC-C, RCC outperforms Vanilla MySQL by about an order of magnitude under both Repeatable Read and Serializable isolation. Evaluation on YCSB using a machine with 128 cores confirms that RCC scales to 128 clients, while competing schemes do not beyond 32 threads. Our implementation of RCC passes BenchmarkSQL’s built-in consistency checker [2].

2

BACKGROUND AND MOTIVATION

In this section, we review how modern OLTP engines resolve RW and WR conflicts using MVCC while still suffering from WW ones. We then identify opportunities for early write lock release in OLTP workloads. Finally, we attribute pessimistic write locking to in-place updates, motivating RCC’s speculative versioning.

2.1

Multi-Version Concurrency Control

Multi-version concurrency control (MVCC) improves concurrency by maintaining multiple physical versions of a single logical data item, allowing read and write operations to proceed without blocking each other [33, 34, 51, 61]. The key idea of MVCC lies in allowing read operations to access an appropriate version, while write operations create new versions without blocking concurrent readers. In the past decade, a variety of strategies have been proposed for integrating MV with concurrency control, including timestamp ordering (MVTO), optimistic concurrency control (MVOCC), and two-phase locking (MV2PL) [61]. Version Construction To access an appropriate version, MVCC systems must construct a version that is visible to the reader. Existing MVCC Systems [33, 51] organize version chains for physical data in an append-only manner, but they differ in the ordering of versions. MySQL adopts Newest-to-Oldest ordering, where the current committed version resides in the primary data page, and past versions are chained backward through undo log entries [19, 21, 32].

4K

MySQL PostgreSQL

3K

Avg. Latency (ms)

Throughput (TPS)

RCC: Speculative Write Versioning with Redo Logs

2K 1K 0 1

8

16

32

64

Number of Threads

(a) Throughput

128

Execution New-Order

Wait (T) Wait (F) Payment 190 91 42 18

100

10

4

3 1

7

4

4

4

4

16

32

64

128

0.7

1

8

Number of Threads

(b) Latency Breakdown

Figure 2: WW Conflicts Limit Concurrency (TPC-C, 1 WH) PostgreSQL adopts Oldest-to-Newest ordering, where each version is stored as a separate physical tuple and newer versions are appended to the tail of the chain [21, 49]. Eliminating RW and WR Blocking. By maintaining multiple versions, MVCC allows readers and writers to operate independently without blocking each other. In N2O systems, when a reader requires a version that is currently being modified, it does not block on the writer’s lock. Instead, the system reconstructs a past committed version by traversing the undo log chain, allowing the readers to proceed immediately. Writers modify the current version in place without waiting for readers, since any concurrent reader can always reconstruct an appropriate past version from the undo log. In O2N systems, readers and writers operate on physically separate tuples. A reader traverses the version chain and selects a tuple whose xmin and xmax indicate visibility to its snapshot, regardless of whether a concurrent writer is appending a new version [49]. Writers simply append new tuples to the chain without modifying existing ones, leaving past versions intact for concurrent readers. WW Blocking Limits Concurrency. While MVCC eliminates RW and WR blocking, WW conflicts remain unresolved. When concurrent transactions attempt to update the same record, they must be serialized regardless of the version storage organization. In N2O systems, a writer must acquire an exclusive lock on the current version and hold it until commit. Any subsequent writer attempting to update the same record is blocked until the first writer commits and releases the lock. This blocking is unavoidable because N2O systems perform in-place updates on the current version, and allowing concurrent modifications would result in lost updates [3]. WW conflicts also persist in O2N systems. Before appending a new version, a writer must check if another transaction is updating the same record. In that case, the second writer must wait for the first to complete. While MVCC decouples readers and writers, no such mechanism exists for concurrent writers, so WW conflicts limit concurrency and scalability. To quantify the impact of WW conflicts on concurrency, we measured transactions per second (TPS) while running the TPCC benchmark on two representative open-source databases that support MVCC: MySQL 8.4.5 [26] under Repeatable Read and PostgreSQL 16.2 [50] under Read Committed, each with its default isolation level. The workload executes New-Order and Payment transactions in a 1:1 ratio, capturing the update-intensive behavior typical of OLTP workloads. All experiments were conducted on a dedicated server equipped with an AMD EPYC 9754 CPU (128 cores at 2.25GHz) and 256GB DRAM, running Ubuntu 22.04. Figure 2a shows the resulting transaction throughput. Despite abundant CPU resources, as the number of concurrent connections exceeds eight, TPS plateaus and the CPU utilization remains very

Table 1: Concurrency Characteristics in OLTP Workloads

Benchmark TPC-C [24] Wikipedia [58] YCSB-A (𝜃 =0.9) [9] AuctionMark [1] TATP [27] Epinions [25]

WW Wait (% of time)

Abort (% of txns)

Re-update (% of txns)

93.9 51.9 50.6 ∼0 ∼0 0.04

1.6 1.0 0 4.5 4.2 ∼0

0.05 0.09 0 0 0 0

WW Wait: ratio of total TX execution time blocked due to WW conflicts. Abort: transaction abort ratio; Re-update: re-updating transaction ratio

low (i.e., at most 1.7% with 128 concurrent clients), indicating that the system is not compute-bound but limited by synchronization overhead. To identify the source of this scalability bottleneck, we analyze transaction latency and its components in MySQL. Figure 2b breaks down the average latency of each transaction type into execution time and WW lock wait. We further separate WW lock wait into true conflicts on the same column and false conflicts on different columns of the same record. Note that WW lock wait measures the total elapsed time during write lock acquisition, which includes system-level overheads such as thread scheduling, context switching, and lock manager contention. While the execution time remains largely unchanged across different concurrency levels, the time spent waiting for write locks grows substantially with the number of concurrent connections per warehouse. As Figure 2b shows, while New-Order latency remains stable, Payment latency grows sharply with concurrency because every Payment transaction updates the same warehouse record. Each Payment must wait for the preceding one to commit before acquiring the write lock, forming a serial chain of WW blocking. In addition, record-level locking creates false conflicts between Payment and New-Order transactions that update disjoint columns of district records, unnecessarily serializing them and increasing the lock holding time. As a result, true and false WW conflicts prolong Payment latency from 0.7 ms to 190 ms at 128 clients.

2.2

Opportunity for Speculative Write Visibility

A promising solution to WW conflicts is speculative write visibility [10], which exposes uncommitted writes to subsequent transactions. Although prior speculative versioning systems [15, 41, 60, 62] have shown significant throughput gains over conventional locking under high contention, two questions remain unexplored: how much execution time WW conflicts actually consume, and what characteristics of OLTP workloads make speculative write visibility effective. To answer these questions, we run six OLTP benchmarks on MySQL 8.4.5 [26] under repeatable read isolation level with 128 clients and a scale factor of 1 for 30 minutes. Table 1 summarizes the results. Our analysis reveals that OLTP transactions exhibit three characteristics that enable speculative write visibility. First, most OLTP transactions are expected to commit successfully. Speculative write visibility introduces the risk of cascading aborts [10]: if a transaction aborts after exposing its uncommitted writes, all dependent transactions abort cascadingly. However, as shown in Table 1, abort rates remain low across all benchmarks. In

Hyejin Yoo, Seongjae Moon, Sang-Won Lee, and Jonghyeok Park

many OLTP workloads, transactions are typically designed to commit successfully, and application-level aborts are rare [14]. Thus, conservative blocking or abort-heavy designs miss opportunities to improve concurrency. Second, transactions typically update each record only once. In Table 1, re-update rates remain below 0.1% across all benchmarks. However, when a transaction re-updates a record, any transaction that has read its prior speculative version observes a stale value and must be aborted. Thus, the occasional cascading abort from a reupdate is a worthwhile trade-off, as exposing speculative versions to concurrent transactions significantly improves concurrency while preserving serializability, provided commit order is enforced. Third, in most OLTP workloads, update-conflicting operations occur in the early phase of transactions, causing transactions to hold locks longer and block subsequent transactions for longer. Transactions typically place update-conflicting operations early for reasons such as application logic, unique ID acquisition, and deadlock avoidance [16, 62, 63]. For this reason, WW conflicts account for a large fraction of total transaction execution time. For instance, as shown in Table 1, three benchmarks (TPC-C, Wikipedia, YCSB-A) exhibit WW wait times exceeding 50% of total execution time. One way to free subsequent transactions from prolonged blocking is to allow them to access uncommitted writes so that their executions can be pipelined. Taken together, these characteristics reveal a clear opportunity to improve scalability in OLTP workloads through speculative write visibility. By leveraging them, update-conflicting transactions can proceed concurrently, as cascading aborts are rare. RCC capitalizes on this opportunity to improve concurrency under WW conflicts.

2.3

In-Place Updates as the Culprit

However, most existing concurrency schemes fail to exploit this ample opportunity for speculative write visibility. As the main culprit, we pinpoint the prevailing convention that all active transactions must apply their updates immediately and in place to the current version of a data object [17]. When a transaction is to update a data record, it must first acquire an exclusive write lock, then capture the redo log and modify the current record version immediately [3, 39]. The transaction then should hold the lock until commit so as to avoid isolation anomalies such as lost updates, dirty reads, and non-repeatable reads [3]. This convention causes several concurrency-related limitations. First, updating the current version in place implies that a transaction that updates a record must hold the write lock until commit, making the updated value invisible to other transactions, although the transaction is highly likely to commit. As a result, WW conflicts serialize update-conflicting transactions. Second, immediate modification of the current version means that the database can expose only the most recently written value, making it impossible to preserve multiple concurrent update states for the same record. Lastly, when multiple active transactions share and overwrite the current version, even speculative concurrency becomes unsafe: aborting a blocked transaction can trigger cascading rollbacks, and a transaction that rereads a record after updating it may observe another transaction’s update, violating read-after-write consistency or repeatable-read semantics [3]. As a result, short early conflicts are amplified into

long blocking periods, and transactions that could otherwise proceed are serialized. In summary, pessimistic write locking is not an intrinsic requirement for correctness, but rather an artifact of the update-in-place convention. This convention constitutes a fundamental obstacle to scalable concurrency [13], motivating a different approach: resolving WW conflicts early by allowing subsequent transactions to proceed speculatively.

3

DESIGN OF RCC

The analysis in Section 2 shows that OLTP transactions encounter WW conflicts early and are highly likely to commit, yet existing systems serialize them through in-place updates and exclusive locks held until commit. RCC eliminates this serialization by materializing out-of-place speculative write versions from redo logs at record access time, deferring installation to commit, and enforcing correctness through dependency tracking. This enables pipelined execution of contending transactions while preserving isolation guarantees.

3.1

Key Idea: Redo Logs as Versions

Modern DBMSs already maintain three logical timelines: the current version accessed by transactions, the undo logs keeping past committed versions, and the redo logs which record intended future updates. While the undo log is leveraged as version storage to resolve RW and WR conflicts in existing MVCC schemes, redo logs have been used solely to guarantee durability by recording transactional updates to be persisted at commit and replaying them upon recovery. However, redo logs naturally encode a transaction’s update intention and can be safely ignored if the transaction aborts. This motivates a key question: Can redo logs be reinterpreted as write versions for concurrency control? To answer this question, RCC extends the role of redo logs by treating redo-log-backed updates as speculative write versions to address WW conflicts. A speculative write version represents an uncommitted and abortable version of a record, which is materialized by an active transaction. For brevity, we refer to speculative write versions just as speculative versions hereafter. When updating a record, a transaction reads the speculative version from its predecessor or the current version from the data page, appends a redo log entry, and creates a new speculative version by applying this redo log. When multiple transactions are updating the same record, each active transaction thus maintains its own speculative version of the record, enabling multiple active transactions to update the same record instead of overwriting the single current state. The speculative versions of an active transaction are installed to their corresponding current versions in data pages lazily at commit time. Treating active transactions’ redo logs for a record as speculative versions and thus decoupling them from the record’s current version enables a fundamentally different approach to concurrency control. First, dirty reads are avoided: if a transaction observes a speculative version produced by another transaction, commit ordering ensures that the observer can commit only after the producer commits. Second, repeatable reads are preserved because each transaction retains its own speculative version even if other

RCC: Speculative Write Versioning with Redo Logs

WAL Buffer

LSN #2 𝑹∗ → 𝑹"

T1 Time

LSN #1 𝑹 → 𝑹∗

Transaction Log Area (TLA)

Update (R)

T2 Update (R)

𝑹′

LSN #3 𝑹" → 𝑹′′

Read (R)

LSN #4 𝑹"" → 𝑹′′′

Commit

T4

Update (R)

𝑹′′ Pre-Commit

Each TX’s Local Speculative Version

T3

𝑹′′′

Commit

Commit

Commit

Access-Time Controlled Speculative Write Visibility

Record R's Dependency 𝑪𝒐𝒍 𝑨: 𝑻𝟑 → 𝑻𝟐 → 𝑻𝟏

Update (R)

𝑹∗

Pre-Commit

Lock Table (Commit Dependency)

Repeatable Read

𝑪𝒐𝒍 𝑩: 𝑻𝟒

Buffer Cache Page Pi

Record R 𝑹 → 𝑹∗ → 𝑹" → 𝑹"" → 𝑹′′′ Deferred Update at Commit

Figure 3: RCC Overview: The shaded regions in each speculative version indicate the modified columns. 𝑇1 − 𝑇3 and 𝑇4 modify disjoint columns of the same record. active transactions are updating the same object. Lastly, lost updates are avoided because speculative versions from concurrent writers are strictly ordered and applied sequentially at commit. In addition, redo logs offer an opportunity for finer-grained concurrency control. Each redo log entry naturally captures which columns of a record a transaction modifies [33, 34]. RCC exploits this property to refine dependency tracking from the record level to the column level: when two transactions modify disjoint columns of the same record, RCC does not create a dependency edge between them, eliminating false WW conflicts that record-level schemes cannot avoid. We elaborate on this in Section 3.4.

3.2

Design Objectives and Architecture

3.2.1 Design Objectives. RCC repurposes redo logs designed for recovery to also support concurrency control. The goal of RCC is to resolve WW conflicts efficiently while remaining well-aligned with existing DBMS architectures. Rather than redesigning the storage engine or recovery mechanisms, RCC extends existing components in modern systems with minimal architectural changes. The design objectives of RCC are as follows. • High Concurrency with Strong Isolation. RCC maximizes concurrency through speculative unlock, which allows conflicting transactions to proceed under dependency tracking, while maintaining strict lock-based conflict ordering, as in two-phase locking. Although speculative unlock introduces cascading abort and commit dependency management overhead, RCC addresses these efficiently through transaction-level redo-based versioning, lightweight dependency management, and commit-time deadlock detection, which avoids the false aborts of wound-wait. • Seamless Integration. To demonstrate that speculative versioning can be realized by extending full-fledged DBMSs with minimal modifications, RCC leverages existing recovery mechanisms without altering them, while maintaining full ACID guarantees. • Compatibility. RCC supports multiple isolation levels, including Read Committed, Repeatable Read, Snapshot Isolation, and Serializable. For transactions without WW conflicts, RCC operates identically to vanilla MVCC systems. 3.2.2 Architecture. In this section, we focus on extending N2O MVCC systems, such as MySQL, to simplify the discussion. Since RCC maintains speculative versions out-of-place independent of

the underlying MVCC architecture, O2N MVCC systems such as PostgreSQL can also be naturally extended with RCC, as discussed in Appendix A. We explain the overall architecture and key concepts of RCC using Figure 3. To realize the full potential of redo log as a version, RCC introduces several novel concepts, as discussed below. Constructing Speculative Versions with Redo Logs. As illustrated in Figure 3, when a transaction updates a data record (i.e., the current version of the record having the last committed value), it acquires an exclusive lock on the record, captures the corresponding redo log, and creates a speculative version using the redo log (e.g., the blue dashed rectangles in Figure 3). The speculative version provides repeatable reads to the transaction, even when other transactions have also updated the same record. In that each active transaction maintains its own speculative version, RCC is similar to optimistic concurrency control [23], which maintains local data copies for each transaction. Transaction Log Area. RCC resolves WW conflicts by repurposing redo logs for dual purposes: recovery and concurrency control. Rather than introducing a separate version store, RCC leverages redo logs as an active version store. Relying solely on the WAL for version construction is inefficient, since the log is maintained at the transaction level rather than the page level. Constructing speculative versions of each data record in this manner requires scanning the entire WAL to extract relevant modifications, which can incur significant overhead, especially when log records must be retrieved from disk. To mitigate the overhead, RCC introduces Transaction Log Area (TLA), a per-transaction memory heap where each transaction stores redo logs for recovery and a speculative version to enable fast access without repeatedly applying redo logs. Although speculative versions can be reconstructed by applying redo logs, storing them separately in the TLA eliminates lock contention and version traversal overhead. The space requirement of the TLA depends on the number of active transactions and the number and length of records being updated. For instance, when running 128 concurrent threads of New-Order and Payment transactions in TPC-C, the maximum TLA capacity is about 8KB. This amount of additional TLA space, though not negligible, can be easily justified by the improved concurrency. Lazy Update Installation When a transaction updates a record, RCC does not update the record’s current version in place but instead materializes the active transaction’s updates to data records

Hyejin Yoo, Seongjae Moon, Sang-Won Lee, and Jonghyeok Park

on their speculative versions. Later, when the transaction commits, the newly committed value is lazily installed from the speculative version to the current version. Note that the overhead of installing the current record lazily is the same as that of immediately updating the record in place. As a result, current record versions in data pages always retain the most recently committed value while their uncommitted values reside only in the TLA. Cascading Abort and Lightweight Rollback. While RCC improves concurrency by exposing uncommitted updates by one transaction to another, it must perform cascading aborts when a predecessor transaction aborts or re-updates its speculative value. In Figure 3, for instance, if T2 reads the speculative version 𝑅 ′ written by T1 and T1 subsequently aborts, the dependent transaction T2 must also abort. For another example, if T1 re-updates the record 𝑅 after T2 had already read its speculative version (𝑅 ′ ), RCC prevents stale reads by aborting T2 that has read the first update. Therefore, it is crucial to reduce the overhead of cascading aborts in RCC. In this regard, deferred update installation provides a side benefit: lightweight and recoverable cascading rollback [4]. Since active transactions do not install any updates to the current version, RCC can abort uncommitted transactions simply by discarding their speculative versions in the TLA, without reverting current versions. Access-Time Ordering for Conflicting Transactions. In RCC, each transaction acquires an exclusive lock prior to updating a data record using the same mechanism in existing DBMSs such as a lock table, as illustrated in Figure 3. However, RCC introduces speculative unlock, which allows a transaction to release its lock immediately after creating a speculative version of the data, rather than holding the lock until commit. Unlike a conventional lock release, speculative unlock retains the lock table entry for dependency tracking while allowing subsequent transactions to proceed without waiting. This also enables RCC to detect re-updates and cascade-abort dependent transactions through the lock table. When another transaction is to update the same record, it must acquire the exclusive lock for the record and then create another speculative version. For example, T2 acquires the exclusive lock prior to updating the record 𝑅 using the lock table, and then creates its speculative version 𝑅 ′′ using the version 𝑅 ′ of transaction T1. In this regard, RCC strictly enforces commits to follow lock acquisition order, thereby guaranteeing conflict-serializable schedules [39]. Specifically, RCC enforces commit order consistency [40]. Once the update order is determined, allowing subsequent transactions to proceed speculatively does not compromise correctness, as long as the commit order respects that update order. Compared to OCC, both schemes aim to maximize update concurrency. However, RCC enforces strict ordering when concurrent transactions access the same data object, whereas OCC does not control concurrent accesses at access time. Under high contention, this causes OCC to suffer frequent aborts at validation, while RCC allows conflicting transactions to commit. Dependency Chain and Pre-Commit. When a transaction accesses the speculative version of another transaction, the former transaction is said to depend on the latter one. The former and the latter are called a dependent and preceding transaction, respectively. Active transactions accessing the same record constitute a dependency chain [10, 12], which is managed in the lock table.

Even if a transaction reaches the commit point, it cannot commit when it depends on other transactions. We refer to transactions in this state as pre-committed. A pre-committed transaction will commit once all its preceding transactions commit, and abort if any of the preceding transactions aborts or re-updates its speculative version. For instance, transaction T2 in Figure 3 must abort if T1 re-updates its version 𝑅 ′ after T2 creates its version 𝑅 ′′ . Otherwise, T2 experiences a dirty read anomaly. When the leading transaction in a dependency chain — one with no remaining uncommitted predecessors — commits, it is removed from the chain. This releases the pre-commit wait of its immediate successors, triggering their commits in turn and propagating sequential commits along the chain. Optimistic Commit-Time Deadlock Detection. While RCC reduces lock-induced blocking during execution, its dependency chain remains susceptible to deadlocks, shifting the bottleneck from lock waiting to deadlock handling. Conventional approaches employ deadlock avoidance (e.g., wound-wait) or synchronous deadlock detection, both rooted in a pessimistic assumption that deadlocks are frequent and must be prevented or detected immediately. These conservative strategies require synchronous intervention on every lock acquisition, placing deadlock handling logic directly on the latency-critical execution path. This leads to two major drawbacks: (1) high execution-time overhead due to frequent cycle checks [15], and (2) a high rate of false aborts [66] in the case of wound-wait, where transactions are preemptively killed before an actual deadlock is confirmed. Consequently, these methods prevent speculative write versioning from fully realizing its potential for seamless pipelining, as transactions are constantly interrupted by deadlock handling during execution. To maximize the benefits of speculative write versioning, RCC adopts an optimistic approach to deadlock handling: rather than preventing or eagerly detecting deadlocks during execution, it defers their resolution entirely to the commit phase. This design, which we term commit-time deadlock detection, ensures that transactions proceed through the execution pipeline without any interruption from deadlock resolution logic. The cycle detection is triggered once per transaction at commit time: each transaction traverses its local dependency chain to check for cycles, requiring no per-conflict synchronization on the execution path. As a result, transactions not involved in a deadlock cycle complete execution and commit without incurring any deadlock-related latency overhead, significantly reducing their end-to-end transaction latency. Once a deadlock is detected, all involved transactions are aborted. Although this involves aborting multiple transactions, the performance impact is minimized by RCC’s lightweight abort mechanism. One might question whether deferring deadlock detection to commit time wastes CPU cycles when deadlocks actually occur, and whether a synchronous eager approach would be more efficient under high deadlock rates. We opt for commit-time detection for two reasons. First, true deadlocks are inherently rare in practice [14, 29, 54]; pessimistic schemes such as wound-retire [15] could trigger false aborts excessively without an actual cycle [66], so wasted work from false aborts far exceeds that from true deadlocks. Second, RCC invokes cycle detection only once per transaction at commit time, whereas synchronous schemes pay per-conflict overhead on every

RCC: Speculative Write Versioning with Redo Logs

lock acquisition. Under wound-wait, an older transaction blocks until the wounded younger transaction completes rollback, paying this cost regardless of whether a deadlock exists. As shown in Section 6, RCC outperforms RCC-D by about 2.1× on TPC-C.

3.3

Database Operations in RCC

With the added functions and data structures described in Section 3, RCC performs normal database operations such as update, read, commit, and abort differently from traditional DBMSs. This section describes how RCC redefines when and how these operations interact to enable speculative write versioning with early lock release. While explaining how each database operation works in RCC, we also discuss the challenges and our solutions. 3.3.1 Update. Conventional RDBMSs serialize concurrent writes by holding the exclusive lock on a record’s current version until commit. RCC breaks this serialization through speculative unlock. Consider T1, T2, and T3 sequentially updating record 𝑅 in Figure 3. T1 acquires the exclusive lock on 𝑅, applies its modification, and stores the resulting speculative version 𝑅 ′ together with its redo log entry in its own TLA. When T2 subsequently acquires the lock, it waits only for T1 to complete its update rather than for T1’s commit. T2 reads 𝑅 ′ from T1’s TLA, produces 𝑅 ′′ in its own TLA, and releases the lock immediately. RCC records a dependency edge T2→T1, enforcing that T2 cannot commit before T1 and must abort if T1 aborts. T3 proceeds analogously for 𝑅 ′′ , yielding the dependency chain T3→T2→T1. If T1 re-updates 𝑅 after T2 has read 𝑅 ′ , RCC cascade-aborts T2 and its successors (T3) to invalidate their stale reads. The current version in the data page remains unchanged throughout this sequence. Lock Management. RCC extends the existing lock table with transaction dependency tracking while preserving the standard lock structure. Locks are enqueued in their acquisition order, forming a linear sequence where each holder becomes the predecessor of the next, thereby tracking commit dependencies while maintaining full compatibility with existing lock-based protocols. Insertion and Deletion. RCC applies speculative versioning only to update operations. Insertions create new records with no prior version, so WW conflicts do not arise. Deletions are handled by setting a delete flag on the record [30, 48], allowing RCC to treat them in the same manner as updates. Index Management. RCC requires no modification of index structures. Primary key values should be chosen to be rarely or never changed [44], so primary index entries remain valid throughout speculative versioning. For secondary indexes, entries point to the current version in the data page, not to speculative versions. When a transaction reads a secondary index, it copies the speculative version from the preceding transaction without traversing the dependency chain. Secondary index maintenance occurs only at commit time when speculative versions are installed into the data page, following the same procedure as conventional systems. 3.3.2 Commit. When T3 commits in Figure 3, it must wait for all its predecessors (T1, T2) to commit. Otherwise, if any predecessor aborts after T3 commits and makes its update durable, T3’s effects become irrecoverable [39]. For recoverability, RCC introduces a precommit protocol: even after completing its execution, a transaction

waits in the pre-commit state until all its predecessors commit, then proceeds to commit. Upon commit, a transaction flushes its commit log record to storage and then installs its speculative versions from the TLA into the corresponding data records in data pages. In Figure 3, when T1 commits, T2 and T3 commit sequentially, advancing the current version of 𝑅 from 𝑅 ′ through 𝑅 ′′ to 𝑅 ′′′ . 3.3.3 Abort. Unlike conventional systems where the abort operation must undo in-place updates, RCC simply discards the TLA of each aborted transaction without page-level rollback, because of the lazy update installation. While improving concurrency by allowing transactions to read speculative versions, RCC must cascade abort for all successors in the dependency chain when a predecessor aborts. For example, in Figure 3, if T1 aborts, T2 must also abort because T2 has read T1’s uncommitted update. Any transaction attempting to access a record under an active cascading abort must wait until the abort completes. In practice, long cascade chains are rare because abort rates remain below 5% in OLTP benchmarks (Table 1). 3.3.4 Read. RCC supports two read modes. A plain SELECT follows the conventional MVCC snapshot read protocol, returning a committed version consistent with the transaction’s snapshot timestamp by traversing the version chain without acquiring locks or creating dependency edges [32, 49]. Speculative versions are invisible to snapshot reads. A SELECT FOR UPDATE [20, 28, 36, 59] acquires an exclusive lock and reads the latest speculative version from the predecessor’s TLA, or the committed version if no active predecessor exists. This creates a dependency edge from the reader to the predecessor, as described in Section 3.3.1. All read-modifywrite operations in RCC require SELECT FOR UPDATE to ensure updates are based on the most recent state in the dependency chain. A transaction that mixes both modes on records updated by the same predecessor observes values from different points in time. The snapshot read returns the committed version, while the speculative read returns the uncommitted version. This is consistent with Vanilla MySQL under Repeatable Read, where a plain SELECT and a SELECT FOR UPDATE within the same transaction can return different versions of the same record [28]. The choice between the two read modes determines how RCC tracks dependencies and what isolation guarantees it provides, as described next. Isolation Levels. Under Repeatable Read, RCC tracks only WW dependencies from speculative writes. Snapshot reads and read-only transactions behave identically to vanilla MVCC systems. Thus, if a transaction uses plain SELECT, RCC is also susceptible to write skews [7], as in conventional vanilla MySQL. Under Serializable, RCC additionally tracks RW anti-dependencies to prevent write skews [3]. To this end, plain SELECT statements are treated as SELECT FOR UPDATE, acquiring locks and performing speculative reads [28] to detect potential RW conflicts with concurrent transactions. For example, in Figure 3, consider a transaction T5 that starts before T1 commits and accesses record R. If T5 is read-only, it reads the committed version R from the data page, as speculative versions remain invisible to snapshot reads. If T5 performs SELECT FOR UPDATE on R, it reads the latest speculative version 𝑅 ′′′ from T3’s TLA, and RCC records a dependency edge T5→T3. Under Serializable, if T3 subsequently modifies a record that T5 has

Hyejin Yoo, Seongjae Moon, Sang-Won Lee, and Jonghyeok Park

speculatively read, the resulting RW anti-dependency edge (T3 → T5) creates a cycle in the speculative dependency graph, and RCC aborts both transactions to prevent write skew [3].

3.4

Columnar RCC (RCC-C)

RCC resolves WW conflicts by allowing update-conflicting transactions to be pipelined through speculative versioning with commit ordering. However, dependency tracking in RCC operates at the record level. Even when two transactions update different columns of the same record, RCC creates a dependency edge between them, treating them as conflicting. For example, in TPC-C [24], New-Order updates d_next_o_id of a District record, while Payment updates d_ytd of the same record [67]. Since RCC defers deadlock detection to commit time, false WW conflicts between New-Order and Payment — which are independent at the column level — proliferate significantly under concurrent execution, becoming the dominant source of unnecessary overhead in TPC-C. Such false conflicts, which are inherent to record-level dependency tracking in any concurrency control scheme, lead to two performance problems that are particularly pronounced in RCC due to its speculative pipelining and commit-time deadlock detection. First, short transactions (e.g., Payment) in pre-commit state must wait idle for long transactions (e.g., New-Order) to commit, prolonging commit wait time and thus transaction latency. Second, and more importantly, false conflicts at the record level can form false dependency cycles, causing unnecessary aborts and thus severely degrading both transaction latency and throughput. Existing approaches to column-level concurrency control, such as column-level locking [37], column-level static analysis [60], and static timestamp splitting [18], either impose prohibitive overhead or require prior knowledge of workload access patterns, making them impractical for production systems. Prior speculative versioning schemes [15, 66] also cannot support column-level concurrency control, as they maintain full-tuple snapshots as local copies, making column-disjoint install order-dependent and requiring serialization even for non-conflicting column updates. RCC maintains redo logs as speculative versions in the TLA. Since these redo logs employ physiological logging [33, 34], each entry naturally captures which columns a transaction modifies as (offset, length, value) deltas, requiring no static workload analysis. RCC exploits this to refine WW dependency tracking to the column level: when two transactions modify disjoint columns of the same record, RCC does not create a dependency edge between them. At commit time, each transaction installs its redo log deltas directly into the original data page at the corresponding column offsets, updating only the modified columns in place. Since column-level deltas on disjoint offsets are independent of each other, their installation order does not affect the final record state, allowing these transactions to commit in parallel without violating correctness. We call this columnar RCC as RCC-C. As illustrated in Figure 3, T1–T3 sequentially update colA of record 𝑅, forming a dependency chain T3→T2→ T1. When T4 updates 𝑅’s colB, its delta does not overlap with those of T1–T3, so RCC-C creates no dependency edge between T4 and T1–T3. T4 reads the current version of 𝑅 from the data page (since no speculative version of colB exists in any TLA), stores its own delta as

a speculative version (𝑅 ∗ ) in its TLA, and commits independently without waiting for T1–T3. If T4 were to read colA speculatively, RCC would create a dependency edge T4 → T3 as in base RCC. When the modified columns of two transactions overlap, RCC-C falls back to record-level dependency tracking, preserving the same correctness guarantees as base RCC. RCC’s redo log-based design enables column-level fine-grained concurrency control without the prohibitive overhead of per-column lock management [37] or the static workload analysis [18, 60]. By eliminating false WW dependencies between transactions accessing disjoint columns, RCC-C avoids unnecessary pre-commit waits, false deadlocks, and the resulting aborts, improving both transaction latency and throughput over base RCC.

3.5

Recovery

Like conventional MVCC systems, RCC employs ARIES-style recovery with redo and undo logs to ensure atomicity and durability. In MySQL, RCC defers log materialization until all predecessor transactions have committed. Once dependencies are resolved, RCC copies redo logs from the TLA to the global WAL buffer, assigns LSNs and applies changes to data pages. Since the TLA is volatile, crash recovery relies solely on persisted WAL records, following the same ARIES recovery. In PostgreSQL, speculative versions are stored as separate tuples rather than TLA entries. However, the same WAL protocol applies, as tuple creation and visibility metadata follow the same vanilla logging scheme [31, 39, 47]. RCC also reduces I/O overhead as a side benefit of its design. First, eliminating WW conflicts shortens transaction lifetimes. In vanilla systems, a transaction waiting for a write lock remains active for longer. During this period, its previously modified pages can be flushed to disk through checkpointing or buffer eviction, and each such flush requires WAL writes including full page images. RCC removes this blocking period, so transactions complete faster and fewer page flushes occur during transaction execution. Second, RCC’s deferred update policy keeps data pages clean from uncommitted modifications. Vanilla systems apply updates in place immediately, so flushing a page with uncommitted modifications requires persisting redo logs, undo logs, and associated page images. RCC stores speculative versions only in the TLA and installs them at commit. These pages remain unmodified, which reduces page write traffic and the associated WAL overhead.

4

CORRECTNESS

Definitions. Let 𝑥 = (𝑟, Γ) denote a conflict unit, where 𝑟 is a record and Γ is a subset of columns of 𝑟 . Two conflict units (𝑟, Γ𝑖 ) and (𝑟, Γ𝑗 ) conflict iff Γ𝑖 ∩ Γ𝑗 ≠ ∅. A write is speculative (denoted 𝑆𝑊𝑖 [𝑥]) if 𝑇𝑖 stores the update in its TLA and releases the lock before commit; the update is installed to 𝑟 only when 𝑇𝑖 commits. A read 𝑅𝑖 [𝑟 ] is speculative (denoted 𝑆𝑅𝑖 [𝑟 ]) if 𝑇𝑖 issues SELECT FOR UPDATE and reads an uncommitted value written by another transaction 𝑇 𝑗 . A plain SELECT returns the version visible under 𝑇𝑖 ’s snapshot and does not include any speculative dependency. Speculative Dependency Graph. The speculative dependency graph 𝑆𝐺 (𝐻 ) of a history 𝐻 contains a directed edge from 𝑇 𝑗 to 𝑇𝑖

RCC: Speculative Write Versioning with Redo Logs

(denoting 𝐶𝑖 must precede 𝐶 𝑗 ) in two cases: (i) WW dependency: 𝑇𝑖 performs 𝑆𝑊𝑖 [𝑥𝑖 ], and 𝑇 𝑗 subsequently performs 𝑆𝑊 𝑗 [𝑥 𝑗 ] or 𝑆𝑅 𝑗 [𝑟 ], where 𝑥𝑖 and 𝑥 𝑗 conflict. (ii) RW anti dependency: 𝑇𝑖 has performed 𝑆𝑅𝑖 [𝑟 ] and 𝑇 𝑗 subsequently performs 𝑆𝑊 𝑗 [𝑥 𝑗 ] on the same record 𝑟 . Commit Protocol. RCC enforces two invariants on every speculative history 𝐻 . First, for every WW dependency edge 𝑇 𝑗 → 𝑇𝑖 , 𝐶𝑖 must precede 𝐶 𝑗 . If 𝑇𝑖 aborts, 𝑇 𝑗 must also abort. Second, a transaction commits only after all its predecessors in 𝑆𝐺 (𝐻 ) have committed. Theorem 1. Speculative histories are recoverable. Proof. Assume 𝐻 is not recoverable: 𝑇 𝑗 reads an uncommitted value written by 𝑇𝑖 and 𝐶 𝑗 occurs before 𝐶𝑖 . Since only speculative operations can access uncommitted values, the commit protocol requires 𝐶𝑖 to precede 𝐶 𝑗 , a contradiction. □ Theorem 2. If 𝑆𝐺 (𝐻 ) is acyclic, speculative histories 𝐻 guarantee commit ordering. Proof. Let 𝑆𝐺 (𝐻 ) contain a cycle: 𝑇𝑖 → 𝑇 𝑗 → 𝑇𝑘 → 𝑇𝑖 . By the commit protocol, 𝐶 𝑗 must precede 𝐶𝑖 , 𝐶𝑘 must precede 𝐶 𝑗 , and 𝐶𝑖 must precede 𝐶𝑘 , which is a contradiction. Therefore, if 𝑆𝐺 (𝐻 ) contains a cycle, 𝐻 cannot satisfy commit ordering. □ A speculative history 𝐻 that satisfies commit ordering is serializable [40]. To corroborate these guarantees, all TPC-C runs passed BenchmarkSQL’s built-in consistency checker [2].

5

IMPLEMENTATION

We implemented RCC on MySQL (v8.4) and PostgreSQL (v16.2), representing N2O and O2N MVCC architectures, respectively. RCC leverages redo log as speculative version storage in N2O and materializes speculative versions as tuples in the version chain in O2N. Both implementations modify only the lock manager and transaction management modules, with approximately 2K and 1K lines for MySQL and PostgreSQL, respectively. Due to the space constraints, we focus on MySQL implementation in this section and present the PostgreSQL implementation details in Appendix A. Dependency Management. RCC needs to track dependencies among transactions to govern commit, aborts, and deadlocks and thus to guarantee serializability. In our implementation, a transaction enqueues a lock request, identifying the immediate lock holder preceding it in the lock table (lock_sys->rec_hash) as its predecessor. This dependency — represented as a pointer to the predecessor and its conflicting lock object — is then recorded in the transaction’s private memory region (i.e., TLA). For columnar dependency tracking, RCC adds a column_bitmap field to lock_t. A dependency edge is created only when the bitmaps of two conflicting locks overlap [37]. Speculative Version Construction. RCC maintains speculative versions as redo-log entries to store uncommitted updates in the TLA. When a transaction updates a record, it first copies the predecessor’s speculative version to its own TLA, performs its update, and stores the redo log in its TLA. RCC initially allocates 4KB of heap memory for each transaction’s TLA and dynamically allocates additional memory as needed. In our TPC-C experiments,

each speculative version consumes about 300 bytes on average, comparable to the corresponding record size. Commit. Every dependent transaction must wait in the precommit state until all its predecessors have committed. While in this state, cycle detection is performed on the dependency graph; RCC leverages the built-in background deadlock detection thread to asynchronously monitor cycles among waiting client threads. Once the commit is permitted, redo logs accumulated in the TLA are parsed using Vanilla MySQL’s recovery function. Following the WAL protocol, RCC writes undo logs, applies redo logs for speculative versions in the TLA to data pages, and finally appends redo logs to the WAL buffer. Finally, RCC removes dependency edges while releasing locks. Abort. When a transaction aborts, all its dependents must also abort to prevent dirty reads [3]. Although the cascading aborts are inevitable in speculative write versioning, RCC can minimize its overhead because it does not update the current version in place. For cascading aborts, RCC traverses the lock table starting from the aborting transaction and identifies dependent transactions that read the uncommitted update and marks them for abort. Once a cascading abort begins, it becomes visible through the lock table, and any transaction attempting to acquire a lock should wait until the cascading abort completes.

6

PERFORMANCE EVALUATION

This section evaluates the performance of RCC using synthetic, TPC-C, and YCSB benchmarks. RCC is effective in reducing wait time due to WW conflict in both N2O and O2N multi-versioning DBMSs (§6.2, §6.3). We evaluate the effectiveness of commit-time deadlock detection and columnar RCC on TPC-C (§6.4), and further analyze the scalability of existing protocols on DBx-1000 and RCC variants under high contention on YCSB (§6.5).

6.1

Experimental Setup

We conduct all experiments on a Linux machine equipped with an AMD EPYC 9754 CPU (128 cores at 2.25GHz) and 256GB DRAM, running Ubuntu 22.04. For storage, we use two SK hynix PS1010 4TB NVMe SSDs: one for the data device and one for the log device. To isolate WW conflicts from I/O overhead [63], we set the buffer large enough to keep the database entirely in memory except for one experiment (§6.3). Unless otherwise specified, the isolation level is Repeatable Read. Each experiment runs for 1 minute after a 1 minute warm-up.

6.2

Performance on Synthetic Benchmark

We analyze the potential benefits of RCC in an ideal setting with a single hotspot where all concurrent transactions have the same execution time. The synthetic benchmark performs one readmodify-write (𝑅𝑀𝑊 ) on a hotspot record and multiple random reads within a single table. All threads contend on a single hotspot record but access separate partitions for random reads, eliminating table locks and page-latch contention, thereby isolating the impact of write–write conflicts. Since MySQL and PostgreSQL exhibit similar performance trends, we present results from one DBMS per experiment for brevity.

40 0 1

8

16

32

64 128

Number of Threads

(a) Varying Transaction Length

RCC VAN

4K 2K

Up to 70.6x 0 0

0.25

0.5

0.75

10K

5K

7.6x 0

1

1

Distance

(b) Varying Hotspot Position

RCC VAN

8

16

32

64 128

Number of Threads

(a) Varying Client Threads

Throughput (TPS)

Len=64 Len=128 Len=256

80

Throughput (TPS)

Throughput(TPS)

Speedup

Hyejin Yoo, Seongjae Moon, Sang-Won Lee, and Jonghyeok Park

40K

RCC VAN

20K

0 1

2

4

8

Number of Warehouses

(b) Varying Warehouse Count

Figure 4: Synthetic Benchmark: RCC vs. Vanilla

Figure 5: TPC-C Throughput: RCC vs. Vanilla

Varying Transaction Length. To evaluate the effect of transaction length on RCC’s performance in PostgreSQL, we design a synthetic workload where each transaction performs one hotspot update at the beginning, followed by 𝐿𝑒𝑛 random reads. We vary the number of threads from 1 to 128 and 𝐿𝑒𝑛 from 64 to 256. Figure 4a shows that the speedup of RCC over Vanilla PostgreSQL grows as 𝐿𝑒𝑛 increases, reaching up to 59×. In Vanilla, since the write lock on the hotspot is held until commit, longer transactions lead to longer WW blocking. In contrast, RCC allows subsequent transactions to access the speculative version immediately after each update, without waiting for the preceding transaction to commit. For this reason, as shown in Figure 4a, RCC’s speedup over Vanilla scales as the number of threads increases up to 64. In the case of shorter transactions (𝐿𝑒𝑛=64, 128), the speedup decreases at higher contention (e.g., 128 threads) due to lock thrashing problem in 2PL [15, 56]. Varying Hotspot Position. To assess the effect of hotspot position on RCC’s performance in MySQL, we design a synthetic workload where each transaction performs one hotspot update and 256 random reads. 𝐷𝑖𝑠𝑡𝑎𝑛𝑐𝑒 denotes the fraction of reads placed before the hotspot. We vary 𝐷𝑖𝑠𝑡𝑎𝑛𝑐𝑒 from 0 (hotspot at the beginning) to 1 (at the end) with 128 concurrent threads. As shown in Figure 4b, although increasing distance shortens the lock holding time, Vanilla improves throughput only at 𝐷𝑖𝑠𝑡𝑎𝑛𝑐𝑒=1. At all other positions (𝐷𝑖𝑠𝑡𝑎𝑛𝑐𝑒 < 1), lock thrashing [56] prevents Vanilla from benefiting from the reduced lock duration. In contrast, RCC sustains throughput irrespective of the hotspot position, as speculative unlock releases the lock immediately after updating the hotspot.

blocking on the Warehouse and District tables. Since each warehouse has a single Warehouse row and ten District rows, concurrent updates on these records are serialized. In contrast, RCC scales up to 64 client threads, achieving up to 7.6× higher throughput than Vanilla (8.4× on MySQL). Since RCC allows subsequent transactions to access the speculative version immediately after the preceding transaction completes its update, WW-conflicting transactions are pipelined. Beyond 64 clients, RCC exhibits a modest throughput decline, as contention concentrates on a single Warehouse record, amplifying the lock thrashing problem in 2PL [15, 56]. Varying Warehouse Count. To evaluate whether RCC scales with database size, we vary the number of warehouses from 1 to 8 while fixing the number of concurrent clients per warehouse at 16. To isolate WW conflicts from page latch contention, we partition Warehouse and District tables according to Warehouse ID for both RCC and Vanilla. Figure 5b shows that RCC consistently outperforms Vanilla by up to 3.1× (3.3× on PostgreSQL) across all scale factors. The speedup remains stable because each warehouse introduces the same contention pattern, and thus RCC eliminates WW blocking at each warehouse independently. Buffer Size. The results presented so far assume that the entire database fits in memory. To evaluate the effect of RCC under the I/O-heavy configuration, we measure the transaction throughput while running the TPC-C benchmark with 1 warehouse and 64 clients. We set the buffer pool size to 30%, 20%, and 10% of the initial data size (i.e., 250MB). RCC outperforms Vanilla MySQL by 4.1× to 5.9× and Vanilla PostgreSQL by 3.8× to 4.1× across the three buffer configurations. These results indicate that the performance benefit of RCC still holds under I/O-bound conditions, although the gain slightly decreases as the buffer size shrinks and accordingly the I/O time becomes more dominant.

6.3

Performance on TPC-C Benchmark

To measure the performance of RCC on the TPC-C benchmark, we use tpcc-mysql [36] for MySQL and sysbench-tpcc [35] for PostgreSQL. In both benchmark settings, each read-modify-write sequence is configured to issue SELECT FOR UPDATE prior to UPDATE, as is standard practice for read-modify-write operations [28, 55]. We run New-Order and Payment transactions in a 1:1 ratio and report throughput in transactions per second (TPS). Since both MySQL and PostgreSQL exhibit similar performance trends, we present results from one DBMS per experiment for brevity. Varying Client Threads. To evaluate the scalability of RCC, we measure throughput while increasing the number of concurrent client threads from 1 to 128 with a single warehouse. Figure 5a shows the results for PostgreSQL. As the number of clients increases, throughput in Vanilla quickly plateaus at eight threads due to WW

6.4

Effects of Deadlock Detection and RCC-C

To measure the effects of optimistic commit-time deadlock detection in RCC and Columnar RCC, we run the TPC-C benchmark with 1 warehouse under Repeatable Read and Serializable isolation levels, using five different configurations for deadlock handling and RCC-C: • Vanilla: MySQL’s exclusive write locking until commit. • RCC: Commit-time deadlock detection. • RCC-W: Wound-wait for deadlock prevention [15]. • RCC-D: Deadlock detection on every lock acquisition. • RCC-C: RCC with column-level conflict detection (§3.4). To isolate the effect of RCC’s commit-time deadlock detection, we additionally implement RCC’s two variants in terms of deadlock

20K 10K

RCC-C RCC RCC-D RCC-W VAN

20K

10K

0

0 1

8 16 32 64 Number of Threads

128

1

(a) Repeatable Read

8 16 32 64 Number of Threads

128

25

Execution RCC-W RCC

20

10 5 0

1

50

0 1

8 16 32 64 Number of Threads

128

16

32

64

128

(a) Runtime Breakdown

RCC RCC-D RCC-W VAN

20K 10K 0

1

𝑎𝑣𝑔

𝑝99

𝑎𝑣𝑔 𝑝99

Baseline

2.2

3.2

0.5

VAN RCC RCC-C

25.2 5.3 3.9

45.3 12.1 7.8

43.1 54.8 5.4 12.1 1.2 3.0

1.0

(b) Latency at 64 clients (ms)

Figure 7: TPC-C under Serializable

Throughput (TPS)

Abort Rate (%)

Throughput (TPS)

0

Wound-Wait Bamboo TicToc Silo

100

8

Number of Threads

(b) Serializable

Wound-Wait Bamboo TicToc Silo

New-Order Payment

Wasted

15

Figure 6: TPC-C Throughput: RCC Variants

1M

Wait RCC-D RCC-C

Abort Rate (%)

RCC-C RCC RCC-D RCC-W VAN

Amortized Runtime (ms)

30K

Throughput (TPS)

Throughput (TPS)

RCC: Speculative Write Versioning with Redo Logs

8 16 32 64 128 Number of Threads

50

0 1

(a) Competing Schemes on DBx1000 Do Not Scale (due to Aborts)

RCC RCC-D RCC-W VAN

100

8 16 32 64 Number of Threads

128

1

8 16 32 64 128 Number of Threads

(b) RCC on MySQL Scales to 128 Threads

Figure 8: YCSB Performance: Varying Client Threads (𝑟𝑒𝑎𝑑_𝑟𝑎𝑡𝑖𝑜 = 0.5, 𝜃 = 0.99, 128 Cores) prevention: RCC-W, which avoids deadlocks via wound-wait [15], and RCC-D, which detects deadlock synchronously upon every lock acquisition. Deadlock Detection. To evaluate the impact of deadlock handling on speculative write versioning, we compare RCC-W, RCC-D, and RCC under both isolation levels. Under Repeatable Read (Figure 6a), RCC-W outperforms Vanilla MySQL by up to 7× through speculative write versioning, comparable to the gains reported by Bamboo [15]. However, its wound-wait preemptively aborts younger transactions on every lock conflict, causing false aborts even in the absence of actual deadlock cycles. In MySQL, each rollback synchronously blocks subsequent transactions accessing the same record until it completes. RCC-D achieves up to 4.2× speedup but degrades beyond 32 threads due to latch contention on the centralized lock table, as eager deadlock detection requires frequent cycle checks. RCC outperforms RCC-W by 1.6× by avoiding these false aborts, and RCC-D by 2.1× by eliminating per-conflict detection overhead. Under Serializable (Figure 6b), since RCC must track RW and WR conflicts as well as WW conflicts, increasing the overhead of wound-wait and eager detection relative to committime detection, RCC’s gain over RCC-W and RCC-D increases to 2.7× and 2.3×, respectively. By avoiding preemptive aborts and eliminating per-conflict cycle checks, RCC reduces wasted time by 8.8× over RCC-W and wait time by 7.3× over RCC-D (Figure 7a, 64 clients). Columnar RCC (RCC-C). To assess columnar RCC, we compare RCC and RCC-C under Serializable. Figure 6b shows that RCC-C improves throughput by up to 2.3× over RCC. Figure 7b presents the average (𝑎𝑣𝑔) and 99th percentile (𝑝99) latencies at 64 clients against a Baseline of a single transaction. While RCC improves the average Payment latency (denoted as 𝑎𝑣𝑔) by 8× over Vanilla MySQL, the latencies of New-Order and Payment converge. This is due to record-level dependency tracking, which creates false dependencies between transactions modifying disjoint columns. For example, a Payment updating d_ytd must wait for the commit

of a long-running New-Order updating d_next_o_id on the same District record. Under Serializable, RW and WR conflicts across other tables such as Warehouse and Customer further exacerbate these false dependencies, forming cycles that trigger unnecessary aborts. Thus, when moving from Repeatable Read to Serializable, all schemes except for RCC-C in Figure 6b experience considerable throughput degradation. In contrast, RCC-C exhibits significantly less throughput degradation than the other schemes, as columnlevel dependency tracking avoids the false dependencies that would otherwise form cycles and trigger unnecessary aborts. In addition, as shown in the last row of Figure 7b, RCC-C can significantly reduce the transaction latency.

6.5

Performance on YCSB Benchmark

To evaluate RCC’s performance on workloads beyond the synthetic and TPC-C experiments, and in particular to demonstrate its scalability advantage over competing concurrency control schemes under high contention, we run YCSB [9] on MySQL and DBx1000 [64] with a single table of 10 million records. Each record has a primary key and 10 columns of 100 bytes each. Each transaction accesses 16 records drawn from a Zipfian distribution (𝜃 = 0.99, 𝑟𝑒𝑎𝑑_𝑟𝑎𝑡𝑖𝑜 = 0.5) under Serializable isolation. DBx-1000. To investigate how existing concurrency control protocols behave under high contention, we compare four protocols on DBx1000 [64]: Wound-Wait [5], Silo [57], TicToc [65], Bamboo [15].1 As Figure 8a shows, all four protocols degrade beyond 32 threads, each limited by a different bottleneck. Wound-Wait suffers from prolonged lock holding that serializes concurrent writers. Silo and TicToc avoid lock waits entirely, but validation fails for nearly every transaction, with abort rates close to 100%. Bamboo retires locks early but inherits wound-wait’s preemptive aborts, which cascade frequently under high contention [66]. These results confirm that per-conflict runtime overhead, preemptive aborts, or 1 Rebirth-Retire [66] is excluded because its release implementation [11] did not produce

stable results in our environment.

Hyejin Yoo, Seongjae Moon, Sang-Won Lee, and Jonghyeok Park

synchronous deadlock handling limits the scalability of existing concurrency protocols, as the number of concurrent threads goes beyond 32. MySQL. We evaluate RCC and its variants on MySQL using the same YCSB workload. RCC-W and RCC-D exhibit performance degradation beyond 16 threads, which is consistent with the TPC-C results in Section 6.4. In contrast, RCC aborts transactions only upon true deadlocks at commit time, keeping the abort rate low and scaling to 128 threads. This demonstrates that commit-time deadlock detection works well across different high contention workloads. Unlike TPC-C where all threads contend on a single Warehouse row, YCSB distributes contention across multiple hot records of the Zipfian distribution (𝜃 = 0.99). This mitigates the lock thrashing observed in TPC-C at high thread counts, allowing RCC to scale to 128 threads.

7

RELATED WORK

Optimistic Concurrency Control. Assuming that conflicts are rare, optimistic concurrency control (OCC) [23] allows transactions to execute without blocking, validating against committed versions only at commit time. Silo [57] optimizes OCC for multicore systems by decentralizing the validation phase. TicToc [65] improves scalability through data-driven timestamps. Like OCC and its variants, RCC maintains transaction-private versions during execution and wastes work on aborted transactions. Unlike optimistic schemes, however, RCC minimizes aborts through lockbased access-time conflict ordering, avoiding the excessive abort rates that they suffer under high contention [16, 60], as illustrated in Figure 8a. Relaxed Pessimistic Concurrency Control. Pessimistic concurrency control (PCC) schemes, such as strict two-phase locking (S2PL) protocol [39], guarantee serializability but limit the concurrency due to the strict locking protocol. Numerous techniques have been proposed to improve concurrency in PCC by relaxing the conservative locking protocol duration, while preserving the correctness guarantee. Based on the observation that pre-committed transactions can safely expose their updates while waiting for log flush [45], early lock release (ELR) [22] and controlled lock violation (CLV) [12] allow transactions to release locks before commit. However, since ongoing updates remain hidden, conflicting transactions are still serialized. In contrast, in RCC, each transaction speculatively releases its lock immediately after updating a record, pipelining subsequent transactions on the record. Early Visibility via Transaction Analysis and Chopping. To further improve concurrency by advancing the write visibility prior to transaction commit, several techniques decompose transactions into smaller pieces to avoid conflicts [10, 43, 60, 62]. Transaction Chopping [43] decomposes transactions into sub-transactions to enable early update visibility, but requires static analysis of transaction access patterns. Runtime Pipelining [62] and IC3 [60] relax chopping’s SC-cycle constraints through runtime enforcement, allowing transactions to read uncommitted data at the risk of cascading aborts. PWV [10] avoids cascading aborts via early commit points and deterministic execution, while requiring transaction decomposition. In contrast, RCC does not require static analysis or transaction decomposition.

Bamboo [15] is the closest work to RCC, as it allows transactions to retire locks after their final writes to a record, enabling subsequent transactions to read uncommitted data speculatively. Like RCC, it also supports lazy update installation, dependency tracking among conflicting transactions, and lightweight cascading aborts. However, RCC differs from Bamboo in three ways: First, for deadlock handling, RCC adopts commit-time deadlock detection while Bamboo relies on the wound-retire protocol. Unlike Bamboo which triggers a high rate of false aborts caused by wound-wait’s conservative nature [66], RCC defers detection entirely to commit time and aborts transactions only upon true deadlocks. Thus, RCC achieves a lower abort rate and higher throughput than Bamboo. In particular, as illustrated in Figure 8a, this leads to a dramatic difference in scalability: RCC scales to 128 cores and threads whereas Bamboo degrades beyond 32. Second, RCC naturally supports column-level concurrency control by leveraging redo log deltas, whereas Bamboo cannot, as it maintains full-tuple snapshots as local copies, making column-disjoint install order-dependent. Lastly, while Bamboo is implemented only on DBx1000 [64], a research prototype, RCC is fully integrated into two production DBMSs, MySQL and PostgreSQL, passing BenchmarkSQL’s consistency checker. This demonstrates that RCC’s redo log-based design generalizes across different DBMS architectures. Multi-Version Concurrency Control. MVCC systems maintain multiple versions of the same logical object to increase concurrency [6, 8, 61]. Depending on the version storage architecture, MVCC implementations adopt either Newest-to-Oldest (N2O) or Oldest-to-Newest (O2N) ordering for the version chain. MySQL adopts N2O ordering with undo logs for past version reconstruction, while PostgreSQL uses O2N with a tuple-level version chain. Both architectures manage past committed versions but still block on WW conflicts for the current version. RCC extends these architectures by introducing redo logs as speculative version storage, enabling concurrent updates while guaranteeing that serialization order follows lock acquisition order.

8

CONCLUSION

In this paper, we observe that write–write conflicts limit concurrency severely, and argue that the long-standing practice of in-place updates to records is the primary culprit. We then proposed RCC, which is, to our best knowledge, the first approach to leverage redo logs as speculative versions. RCC aims to improve transaction latency and throughput by pipelining conflicting transactions, not serializing them, while simultaneously achieving serializability through lock-based access-time ordering and dependency management. To harness the full potential of speculative versioning, RCC proposed two novel techniques: commit-time deadlock detection and columnar concurrency control. Both are critical for improving transaction latency, throughput, and scalability. We show that RCC can integrate naturally with both N2O and O2N MVCC schemes, and experimental results confirm that RCC improves concurrency significantly and scales up to 128 concurrent threads.

REFERENCES [1] V. Angkanawaraphan and Andrew Pavlo. 2022. AuctionMark: A Benchmark for High-Performance OLTP Systems. http://hstore.cs.brown.edu/projects/ auctionmark.

RCC: Speculative Write Versioning with Redo Logs

[2] BenchmarkSQL. 2021. BenchmarkSQL Checker. https://github.com/wieck/ benchmarksql/blob/master/src/main/resources/checks/checks.sql. [3] Hal Berenson, Phil Bernstein, Jim Gray, Jim Melton, Elizabeth O’Neil, and Patrick O’Neil. 1995. A critique of ANSI SQL isolation levels. SIGMOD Record 24, 2 (May 1995). [4] Philip Bernstein, Vassos Hadzilacos, and Nathan Goodman. 1987. Concurrency Control and Recovery in Database Systems. Addison-Wesley. [5] Philip A. Bernstein and Nathan Goodman. 1981. Concurrency Control in Distributed Database Systems. ACM Comput. Surv. 13, 2 (June 1981), 185–221. https://doi.org/10.1145/356842.356846 [6] Paul M. Bober and Michael J. Carey. 1992. Multiversion Query Locking. In Proceedings of the 18th International Conference on Very Large Data Bases (VLDB ’92). [7] Michael J. Cahill, Uwe Röhm, and Alan D. Fekete. 2009. Serializable isolation for snapshot databases. ACM Transactions on Database Systems 34, 4, Article 20 (Dec. 2009). [8] Arvola Chan, Stephen Fox, Wen-Te K. Lin, Anil Nori, and Daniel R. Ries. 1982. The implementation of an integrated concurrency control and recovery scheme. In Proceedings of the 1982 ACM International Conference on Management of Data (SIGMOD ’82). 184–191. [9] Brian F Cooper, Adam Silberstein, Erwin Tam, Raghu Ramakrishnan, and Russell Sears. 2010. Benchmarking cloud serving systems with YCSB. In Proceedings of the 1st ACM symposium on Cloud computing. [10] Jose M. Faleiro, Daniel J. Abadi, and Joseph M. Hellerstein. 2017. High performance transactions via early write visibility. Proceedings of the VLDB Endowment 10, 5 (Jan. 2017), 613–624. DBx1000 Rebirth-Retire. https://github.com/gitzhqian/ [11] Github. 2026. RebirthRetire. [12] Goetz Graefe, Mark Lillibridge, Harumi Kuno, Joseph Tucek, and Alistair Veitch. 2013. Controlled Lock Violation. In Proceedings of the 2013 ACM International Conference on Management of Data (SIGMOD ’13). 85–96. [13] Jim Gray. 1981. The Transaction Concept: Virtues and Limitations. In Proceedings of the VLDB Endowment. [14] Jim Gray and Andreas Reuter. 1993. Transaction Processing: Concepts and Techniques (Section 13.4.4). Morgan Kaufmann. [15] Zhihan Guo, Kan Wu, Cong Yan, and Xiangyao Yu. 2021. Releasing Locks As Early As You Can: Reducing Contention of Hotspots by Violating Two-Phase Locking. In Proceedings of the 2021 ACM International Conference on Management of Data (SIGMOD ’21). 658–670. [16] Farzad Habibi, Juncheng Fang, Tania Lorido-Botran, and Faisal Nawab. 2026. Brook-2PL: Tolerating High Contention Workloads with A Deadlock-Free TwoPhase Locking Protocol. In Proceedings of the 2026 ACM International Conference on Management of Data (SIGMOD ’26). [17] Pat Helland. 2024. Scalable OLTP in the Cloud: What’s the BIG DEAL?. In 14th Conference on Innovative Data Systems Research (CIDR ’24). [18] Yihe Huang, William Qian, Eddie Kohler, Barbara Liskov, and Liuba Shrira. 2020. Opportunities for optimism in contended main-memory multicore transactions. 13, 5 (Jan. 2020), 629–642. https://doi.org/10.14778/3377369.3377373 [19] Ken Jacobs. 1995. Concurrency Control, Transaction Isolation and Serializability in SQL92 and Oracle7. Oracle White Paper. [20] Bas Ketsman, Christoph Koch, Frank Neven, and Brecht Vandevoort. 2022. Deciding Robustness for Lower SQL Isolation Levels. ACM Trans. Database Syst. 47, 4, Article 13 (Nov. 2022), 41 pages. https://doi.org/10.1145/3561049 [21] Jongbin Kim, Jaeseon Yu, Jaechan Ahn, Sooyong Kang, and Hyungsoo Jung. 2022. Diva: Making MVCC Systems HTAP-Friendly. In Proceedings of the 2022 International Conference on Management of Data (SIGMOD ’22). 49–64. [22] Hideaki Kimura, Goetz Graefe, and Harumi A Kuno. 2012. Efficient locking techniques for databases on modern hardware. In ADMS@ VLDB. [23] H. T. Kung and John T. Robinson. 1981. On optimistic methods for concurrency control. ACM Transactions on Database Systems 6, 2 (June 1981), 213–226. [24] Scott T. Leutenegger and Daniel Dias. 1993. A Modeling Study of the TPC-C Benchmark. In Proceedings of the 1993 ACM International Conference on Management of Data (SIGMOD ’93). 22–31. [25] Paolo Massa and Paolo Avesani. 2005. Controversial users demand local trust metrics: an experimental study on Epinions.com community. In AAAI, Vol. 1. 121–126. [26] MySQL Team (Oracle Corp.). 2025. MySQL Server (GitHub repository). https: //github.com/mysql/mysql-server/releases/tag/mysql-8.4.5. [27] Simo Neuvonen, Antoni Wolski, Markku Manner, and Vilho Raatikka. 2009. TATP Benchmark Description (Version 1.0). http://tatpbenchmark.sourceforge.net. [28] Oracle. 2025. 17.7.2.4 Locking Reads. https://dev.mysql.com/doc/refman/8.4/en/ innodb-locking-reads.html. [29] Oracle. 2025. 17.7.5 Deadlocks in InnoDB. https://dev.mysql.com/doc/refman/8. 4/en/innodb-deadlocks.html. [30] Oracle. 2025. 17.8.9. Purge Configuration. https://dev.mysql.com/doc/refman/8. 0/en/innodb-purge-configuration.html. [31] Oracle. 2025. Chapter 9 Backup and Recovery. https://dev.mysql.com/doc/ refman/9.6/en/backup-and-recovery.html.

[32] Oracle. 2025. InnoDB Multi-Versioning. https://dev.mysql.com/doc/refman/8.4/ en/innodb-multi-versioning.html. [33] Oracle. 2025. MySQL. https://www.mysql.com/. [34] Oracle. 2025. Oracle | Cloud Applications and Cloud Platform. https://www. oracle.com/. [35] Percona. 2018. sysbench-tpcc. https://github.com/Percona-Lab/sysbench-tpcc. [36] Percona. 2018. tpcc-mysql. https://github.com/Percona-Lab/tpcc-mysql. [37] N. Ponnekanti. 2001. Pseudo column level locking. In Proceedings 17th International Conference on Data Engineering. 545–550. https://doi.org/10.1109/ICDE. 2001.914868 [38] Dan R. K. Ports and Kevin Grittner. 2012. Serializable snapshot isolation in PostgreSQL. Proc. VLDB Endow. 5, 12 (Aug. 2012), 1850–1861. https://doi.org/10. 14778/2367502.2367523 [39] Raghu Ramakrishnan and Johannes Gehrke. 2002. Database Management Systems (3rd ed.). McGraw-Hill, Inc., USA. [40] Yoav Raz. 1993. Extended commitment ordering, or guaranteeing global serializability by applying commitment order selectively to global transactions. In Proceedings of the Twelfth ACM SIGACT-SIGMOD-SIGART Symposium on Principles of Database Systems (PODS ’93). [41] P Krishna Reddy and Masaru Kitsuregawa. 2004. Speculative locking protocols to improve performance for distributed database systems. IEEE Transactions on Knowledge and Data Engineering 16, 2 (2004). [42] David Reed. 1983. Implementing Atomic Actions on Decentralized Data. ACM Transactions on Computer Systems 1 (1983). [43] Dennis Shasha, Francois Llirbat, Eric Simon, and Patrick Valduriez. 1995. Transaction chopping: algorithms and performance studies. ACM Transactions on Database Systems 20, 3 (Sept. 1995). [44] Abraham Silberschatz, Henry F Korth, Shashank Sudarshan, et al. 2010. Database system concepts - 6th edition. Vol. 6. Mcgraw-hill New York. [45] Eljas Soisalon-Soininen and Tatu Ylönen. 1995. Partial Strictness in Two-Phase Locking. In Proceedings of the 5th International Conference on Database Theory (ICDT ’95). [46] Michael Stonebraker. 1987. The Design of the POSTGRES Storage System. In Proceedings of 13th International Conference on Very Large Data Bases (VLDB ’87). [47] Michael Stonebraker and Lawrence A. Rowe. 1986. The design of POSTGRES. In Proceedings of the 1986 ACM International Conference on Management of Data (SIGMOD ’86). [48] The PostgreSQL Global Development Group. 2025. 24.1. Routine Vacuuming. https://www.postgresql.org/docs/current/routine-vacuuming.html. [49] The PostgreSQL Global Development Group. 2025. Chapter 9. Multi-Version Concurrency Control. https://www.postgresql.org/docs/7.1/mvcc.html. [50] The PostgreSQL Global Development Group. 2025. postgres (GitHub repository). https://github.com/postgres/postgres/releases/tag/REL_16_2. [51] The PostgreSQL Global Development Group. 2025. PostgreSQL: The World’s Most Advanced Open Source Relational Database. https://www.postgresql.org/. [52] The PostgreSQL Global Development Group. 2025. README on The Locking tuples. https://github.com/postgres/postgres/blob/master/src/backend/access/ heap/README.tuplock. [53] The PostgreSQL Global Development Group. 2025. README on The Transaction System. https://github.com/postgres/postgres/blob/master/src/backend/access/ transam/README. [54] The PostgreSQL Global Development Group. 2026. 19.12. Lock Management. https://www.postgresql.org/docs/current/runtime-config-locks.html. [55] The PostgreSQL Global Development Group. 2026. SELECT. https://www. postgresql.org/docs/current/sql-select.html. [56] Alexander Thomasian. 1993. Two-phase locking performance and its thrashing behavior. ACM Transactions on Database Systems 18, 4 (Dec. 1993), 579–625. [57] Stephen Tu, Wenting Zheng, Eddie Kohler, Barbara Liskov, and Samuel Madden. 2013. Speedy transactions in multicore in-memory databases. In Proceedings of the 24th ACM Symposium on Operating Systems Principles (SOSP ’13). 18–32. [58] Guido Urdaneta, Guillaume Pierre, and Maarten Van Steen. 2009. Wikipedia workload analysis for decentralized hosting. Computer Networks 53, 11 (2009), 1830–1845. [59] Brecht Vandevoort, Bas Ketsman, Christoph Koch, and Frank Neven. 2021. Robustness against read committed for transaction templates. 14, 11 (July 2021), 2141–2153. https://doi.org/10.14778/3476249.3476268 [60] Zhaoguo Wang, Shuai Mu, Yang Cui, Han Yi, Haibo Chen, and Jinyang Li. 2016. Scaling Multicore Databases via Constrained Parallel Execution. In Proceedings of the 2016 International Conference on Management of Data (SIGMOD ’16). [61] Yingjun Wu, Joy Arulraj, Jiexi Lin, Ran Xian, and Andrew Pavlo. 2017. An Empirical Evaluation of In-Memory Multi-Version Concurrency Control. Proceedings of the VLDB Endowment 10, 7 (mar 2017), 781–792. [62] Chao Xie, Chunzhi Su, Cody Littley, Lorenzo Alvisi, Manos Kapritsos, and Yang Wang. 2015. High-performance ACID via modular concurrency control. In Proceedings of the 25th Symposium on Operating Systems Principles (SOSP ’15). [63] Cong Yan and Alvin Cheung. 2016. Leveraging lock contention to improve OLTP application performance. Proceedings of the VLDB Endowment 9, 5 (Jan. 2016).

Hyejin Yoo, Seongjae Moon, Sang-Won Lee, and Jonghyeok Park

[64] Xiangyao Yu, George Bezerra, Andrew Pavlo, Srinivas Devadas, and Michael Stonebraker. 2014. Staring into the abyss: an evaluation of concurrency control with one thousand cores. Proceedings of the VLDB Endowment 8, 3 (Nov. 2014), 209–220. [65] Xiangyao Yu, Andrew Pavlo, Daniel Sanchez, and Srinivas Devadas. 2016. TicToc: Time Traveling Optimistic Concurrency Control. In Proceedings of the 2016 ACM International Conference on Management of Data (SIGMOD ’16). 1629–1642. [66] Qian Zhang, Yiwen Xiang, Jianhao Wei, Yang Yang, Yifan Li, Xueqing Gong, and Wanggen Liu. 2025. Rebirth-Retire: A Concurrency Control Protocol Adaptable to Different Levels of Contention. Proceedings of the VLDB Endowment 18, 9 (May 2025), 3162–3174. [67] Xiaodong Zhang and Jing Zhou. 2022. High-Performance Transaction Processing for Web Applications Using Column-Level Locking. In Web Information Systems Engineering – WISE 2022, Richard Chbeir, Helen Huang, Fabrizio Silvestri, Yannis Manolopoulos, and Yanchun Zhang (Eds.). Springer International Publishing, Cham, 186–193.

A

APPENDIX

We implemented RCC on MySQL (v8.4) and PostgreSQL (v16.2), which represent two prevalent MVCC architectures: newest-tooldest (N2O) and oldest-to-newest (O2N), respectively. While RCC leverages redo logs as speculative version storage in N2O systems, the same design principle applies to O2N systems by materializing speculative versions directly as tuples in the version chain. Our implementations of RCC for both N2O and O2N require moderate changes only to the lock manager and transaction management modules: MySQL (about 2K lines) and PostgreSQL (about 1K lines). As such, we believe that RCC can be readily integrated into commercial DBMSs, such as Oracle and Microsoft SQL Server.

A.1

Speculative Version Construction

RCC needs to store uncommitted updates as speculative versions. Its MySQL implementation maintains speculative versions as redo-log entries in a dedicated memory region (i.e., TLA), while its PostgreSQL implementation materializes them as new speculative tuple versions directly in the heap pages themselves (i.e., in the MVCC version chain). PostgreSQL. RCC creates speculative tuples following the same procedure as Vanilla PostgreSQL. To read the speculative version and create a new speculative tuple version, RCC utilizes three existing fields in the tuple header: xmin, xmax, and t_ctid, which stores the pointer to the next version in the chain. RCC identifies the latest speculative version by checking the status of xmin and xmax via pg_xact (transaction status log) [53], where xmin is in progress, and xmax is invalid or t_ctid points to itself.

A.2

Dependency Management

RCC needs to track dependencies between transactions to guarantee a serializable schedule equivalent to the strict two-phase locking protocol and to handle cascading aborts. When transaction 𝑇 𝑗 accesses a speculative version created by an active transaction 𝑇𝑖, RCC records a dependency edge from 𝑇 𝑗 to 𝑇𝑖. PostgreSQL. Unlike MySQL, where lock acquisition order in the central lock table serves as a dependency graph, PostgreSQL stores row locks in tuple headers [52], providing no such structure. To track commit dependencies, RCC extends PostgreSQL’s transaction manager with a bidirectional dependency graph. RCC maintains the pred_list in each transaction’s local memory and the dep_list in shared memory using a partitioned hash table to reduce mutex overhead. Both lists store transaction IDs, and their sizes scale with the number of predecessors and dependents, respectively. When a transaction creates a speculative version, RCC extracts the predecessor ID from the tuple’s xmin, adds it to its pred_list, and inserts itself into the predecessor’s dep_list. Note that RCC does not support columnar dependency detection on PostgreSQL, because both its heap pages and WAL store full tuples rather than column-level deltas.

A.3

Commit

When a transaction commits in RCC, it waits until all predecessors commit to guarantee serializability. When a transaction enters pre-commit, it performs cycle detection on the dependency graph.

RCC: Speculative Write Versioning with Redo Logs

To implement this, RCC extends the existing commit protocol in both MySQL and PostgreSQL. PostgreSQL. RCC checks the status of all predecessors in the pred_list and detects deadlocks by performing the depth-first search on the dep_list. Since WAL records are already written when speculative versions are stored in heap pages, no additional operations are required at commit.

A.4

Abort

When a transaction aborts, all its dependents must also abort to prevent dirty reads [3]. Although the cascading abort is inevitable

in speculative write versioning, RCC can minimize its overhead because it does not update the current version in place. PostgreSQL. When a transaction aborts, Vanilla PostgreSQL marks it as aborted in pg_xact, making those tuples invisible until vacuum reclaims them [46]. RCC leverages this mechanism. In the case of a cascading abort, each transaction detects a predecessor abort by checking pg_xact and aborts itself. Although cascading aborts can increase dead tuples, our separate TPC-C experiment shows that RCC incurs only 1.7% additional storage overhead due to dead tuples [48] from speculative versions of aborted transactions, as the vacuum process continuously reclaims them in the background.

Related documents

Record · ID 394506 · SHA-256 cd253ddb8f996d5d
Retrieved via Conceptio — every document is proof-bundled with source, license, and retrieval metadata.