<!-- CANARY: REQ=REQ-DOCS-001; FEATURE="Docs"; ASPECT=Documentation; STATUS=TESTED; OWNER=docs; UPDATED=2026-01-15 --> <p>Documentation tagged with <strong>Multi-Version Concurrency Control (MVCC)</strong> in the Geode graph database. MVCC is a fundamental concurrency control mechanism that enables high-performance concurrent access to data while maintaining ACID transaction guarantees.</p> <h3 id="introduction-to-mvcc" class="position-relative d-flex align-items-center group"> <span>Introduction to MVCC</span> <button type="button" class="h-share btn btn-link p-0 text-decoration-none link-secondary opacity-50 hover-opacity-100 transition-all ms-1" data-share-target="introduction-to-mvcc" aria-haspopup="dialog" aria-label="Share link: Introduction to MVCC"> <i class="fa-sharp-duotone fa-solid fa-share-nodes" aria-hidden="true" style="font-size: 0.8em;"></i> <span class="visually-hidden">Share link</span> </button> </h3><div id="headingShareModal" class="heading-share-modal" role="dialog" aria-modal="true" aria-labelledby="headingShareTitle" hidden> <div class="hsm-dialog" role="document"> <div class="hsm-header"> <h2 id="headingShareTitle" class="h6 mb-0 fw-bold">Share this section</h2> <button type="button" class="hsm-close" aria-label="Close"> <i class="fa-solid fa-xmark"></i> </button> </div> <div class="hsm-body"> <label for="headingShareInput" class="form-label small text-muted mb-1 text-uppercase fw-bold" style="font-size: 0.7rem; letter-spacing: 0.5px;">Permalink</label> <div class="input-group mb-4 hsm-url-group"> <input id="headingShareInput" type="text" class="form-control font-monospace" readonly aria-readonly="true" style="font-size: 0.85rem;" /> <button class="btn btn-primary hsm-copy" type="button" aria-label="Copy" title="Copy"> <i class="fa-duotone fa-clipboard" aria-hidden="true"></i> </button> </div> <div class="small fw-bold mb-2 text-muted text-uppercase" style="font-size: 0.7rem; letter-spacing: 0.5px;">Share via</div> <div class="hsm-share-grid"> <a id="share-twitter" class="btn btn-outline-secondary w-100" target="_blank" rel="noopener noreferrer"> <i class="fa-brands fa-twitter me-2"></i>Twitter </a> <a id="share-linkedin" class="btn btn-outline-secondary w-100" target="_blank" rel="noopener noreferrer"> <i class="fa-brands fa-linkedin me-2"></i>LinkedIn </a> <a id="share-facebook" class="btn btn-outline-secondary w-100" target="_blank" rel="noopener noreferrer"> <i class="fa-brands fa-facebook me-2"></i>Facebook </a> </div> </div> </div> </div> <style> .heading-share-modal { position: fixed; inset: 0; display: flex; justify-content: center; align-items: center; background: rgba(0, 0, 0, 0.6); z-index: 1050; padding: 1rem; backdrop-filter: blur(4px); -webkit-backdrop-filter: blur(4px); } .heading-share-modal[hidden] { display: none !important; } .hsm-dialog { max-width: 420px; width: 100%; background: var(--bs-body-bg, #fff); color: var(--bs-body-color, #212529); border: 1px solid var(--bs-border-color, rgba(0,0,0,0.1)); border-radius: 1rem; box-shadow: 0 25px 50px -12px rgba(0, 0, 0, 0.25); overflow: hidden; animation: hsm-fade-in 0.2s ease-out; } @keyframes hsm-fade-in { from { opacity: 0; transform: scale(0.95); } to { opacity: 1; transform: scale(1); } } [data-bs-theme="dark"] .hsm-dialog { background: #1e293b; border-color: rgba(255,255,255,0.1); color: #f8f9fa; } .hsm-header { display: flex; justify-content: space-between; align-items: center; padding: 1rem 1.5rem; border-bottom: 1px solid var(--bs-border-color, rgba(0,0,0,0.1)); background: rgba(0,0,0,0.02); } [data-bs-theme="dark"] .hsm-header { background: rgba(255,255,255,0.02); border-color: rgba(255,255,255,0.1); } .hsm-close { background: transparent; border: none; color: inherit; opacity: 0.5; padding: 0.25rem 0.5rem; border-radius: 0.25rem; font-size: 1.2rem; line-height: 1; transition: opacity 0.2s; } .hsm-close:hover { opacity: 1; } .hsm-body { padding: 1.5rem; } .hsm-url-group { display: flex !important; align-items: stretch; } .hsm-url-group .form-control { flex: 1; min-width: 0; margin: 0; background: var(--bs-secondary-bg, #f8f9fa); border-color: var(--bs-border-color, #dee2e6); border-top-right-radius: 0; border-bottom-right-radius: 0; height: 42px; } .hsm-url-group .btn { flex: 0 0 auto; margin: 0; margin-left: -1px; border-top-left-radius: 0; border-bottom-left-radius: 0; height: 42px; display: flex; align-items: center; justify-content: center; padding: 0 1.25rem; z-index: 2; } [data-bs-theme="dark"] .hsm-url-group .form-control { background: #0f172a; border-color: #334155; color: #e2e8f0; } .hsm-share-grid { display: flex; flex-direction: column; gap: 0.5rem; } .hsm-share-grid .btn { display: flex; align-items: center; justify-content: center; font-size: 0.9rem; padding: 0.6rem; border-color: var(--bs-border-color); width: 100%; } [data-bs-theme="dark"] .hsm-share-grid .btn { color: #e2e8f0; border-color: #475569; } [data-bs-theme="dark"] .hsm-share-grid .btn:hover { background: #334155; border-color: #cbd5e1; } </style> <script> (function(){ const modal = document.getElementById('headingShareModal'); if(!modal) return; const input = modal.querySelector('#headingShareInput'); const copyBtn = modal.querySelector('.hsm-copy'); const twitter = modal.querySelector('#share-twitter'); const linkedin = modal.querySelector('#share-linkedin'); const facebook = modal.querySelector('#share-facebook'); const closeBtn = modal.querySelector('.hsm-close'); let lastFocus=null; let trapBound=false; function buildUrl(id){ return window.location.origin + window.location.pathname + '#' + id; } function isOpen(){ return !modal.hasAttribute('hidden'); } function hydrate(id){ const url=buildUrl(id); input.value=url; const enc=encodeURIComponent(url); const text=encodeURIComponent(document.title); if(twitter) twitter.href=`https://twitter.com/intent/tweet?url=${enc}&text=${text}`; if(linkedin) linkedin.href=`https://www.linkedin.com/sharing/share-offsite/?url=${enc}`; if(facebook) facebook.href=`https://www.facebook.com/sharer/sharer.php?u=${enc}`; } function openModal(id){ lastFocus=document.activeElement; hydrate(id); if(!isOpen()){ modal.removeAttribute('hidden'); } requestAnimationFrame(()=>{ input.focus(); }); trapFocus(); } function closeModal(){ if(!isOpen()) return; modal.setAttribute('hidden',''); if(lastFocus && typeof lastFocus.focus==='function') lastFocus.focus(); } function copyCurrent(){ try{ navigator.clipboard.writeText(input.value).then(()=>feedback(true),()=>fallback()); } catch(e){ fallback(); } } function fallback(){ input.select(); try{ document.execCommand('copy'); feedback(true);}catch(e){ feedback(false);} } function feedback(ok){ if(!copyBtn) return; const icon=copyBtn.querySelector('i'); if(!icon) return; const prev=copyBtn.getAttribute('data-prev')||icon.className; if(!copyBtn.getAttribute('data-prev')) copyBtn.setAttribute('data-prev',prev); icon.className= ok ? 'fa-duotone fa-clipboard-check':'fa-duotone fa-circle-exclamation'; setTimeout(()=>{ icon.className=prev; },1800); } function handleShareClick(e){ e.preventDefault(); const btn=e.currentTarget; const id=btn.getAttribute('data-share-target'); if(id) openModal(id); } function bindShareButtons(){ document.querySelectorAll('.h-share').forEach(btn=>{ if(!btn.dataset.hShareBound){ btn.addEventListener('click', handleShareClick); btn.dataset.hShareBound='1'; } }); } bindShareButtons(); if(document.readyState==='loading'){ document.addEventListener('DOMContentLoaded', bindShareButtons); } else { requestAnimationFrame(bindShareButtons); } document.addEventListener('click', function(e){ const shareBtn=e.target.closest && e.target.closest('.h-share'); if(shareBtn && !shareBtn.dataset.hShareBound){ handleShareClick.call(shareBtn, e); } }, true); document.addEventListener('click', e=>{ if(e.target===modal) closeModal(); if(e.target.closest && e.target.closest('.hsm-close')){ e.preventDefault(); closeModal(); } if(copyBtn && (e.target===copyBtn || (e.target.closest && e.target.closest('.hsm-copy')))) { e.preventDefault(); copyCurrent(); } }); document.addEventListener('keydown', e=>{ if(e.key==='Escape' && isOpen()) closeModal(); }); function trapFocus(){ if(trapBound) return; trapBound=true; modal.addEventListener('keydown', f=>{ if(f.key==='Tab' && isOpen()){ const focusable=[...modal.querySelectorAll('a[href],button,input,textarea,select,[tabindex]:not([tabindex="-1"])')].filter(el=>!el.hasAttribute('disabled')); if(!focusable.length) return; const first=focusable[0]; const last=focusable[focusable.length-1]; if(f.shiftKey && document.activeElement===first){ f.preventDefault(); last.focus(); } else if(!f.shiftKey && document.activeElement===last){ f.preventDefault(); first.focus(); } } }); } if(closeBtn) closeBtn.addEventListener('click', e=>{ e.preventDefault(); closeModal(); }); })(); </script><p>Multi-Version Concurrency Control (MVCC) is a sophisticated concurrency control method that allows multiple transactions to access the same data simultaneously without blocking each other. Unlike traditional locking mechanisms that force readers and writers to wait for each other, MVCC creates multiple versions of data items, allowing readers to access consistent snapshots while writers create new versions.</p> <p>MVCC has become the de facto standard for modern database systems because it solves the fundamental trade-off between consistency and concurrency. Traditional two-phase locking provides strong consistency but suffers from contention—readers block writers and writers block readers. MVCC breaks this deadlock by maintaining multiple timestamped versions of each data item.</p> <p>In Geode&rsquo;s implementation, MVCC enables true snapshot isolation and serializable snapshot isolation (SSI), ensuring that transactions see consistent views of the database while allowing maximum concurrency. This is critical for graph databases where complex traversal queries might read thousands of nodes and relationships—blocking those reads would cripple performance.</p> <h3 id="core-mvcc-concepts" class="position-relative d-flex align-items-center group"> <span>Core MVCC Concepts</span> <button type="button" class="h-share btn btn-link p-0 text-decoration-none link-secondary opacity-50 hover-opacity-100 transition-all ms-1" data-share-target="core-mvcc-concepts" aria-haspopup="dialog" aria-label="Share link: Core MVCC Concepts"> <i class="fa-sharp-duotone fa-solid fa-share-nodes" aria-hidden="true" style="font-size: 0.8em;"></i> <span class="visually-hidden">Share link</span> </button> </h3> <h4 id="version-chains" class="position-relative d-flex align-items-center group"> <span>Version Chains</span> <button type="button" class="h-share btn btn-link p-0 text-decoration-none link-secondary opacity-50 hover-opacity-100 transition-all ms-1" data-share-target="version-chains" aria-haspopup="dialog" aria-label="Share link: Version Chains"> <i class="fa-sharp-duotone fa-solid fa-share-nodes" aria-hidden="true" style="font-size: 0.8em;"></i> <span class="visually-hidden">Share link</span> </button> </h4><p>Every data item (node, relationship, or property) in Geode exists as a version chain—a linked list of versions ordered by transaction timestamp. Each version contains:</p> <ul> <li><strong>Transaction ID (TxID)</strong>: The transaction that created this version</li> <li><strong>Begin timestamp</strong>: When this version became visible</li> <li><strong>End timestamp</strong>: When this version was superseded (NULL if current)</li> <li><strong>Data payload</strong>: The actual node/relationship/property value</li> <li><strong>Visibility metadata</strong>: Information for determining version visibility</li> </ul> <p>When a transaction reads data, MVCC walks the version chain to find the appropriate version based on the transaction&rsquo;s snapshot timestamp.</p> <h4 id="snapshot-isolation" class="position-relative d-flex align-items-center group"> <span>Snapshot Isolation</span> <button type="button" class="h-share btn btn-link p-0 text-decoration-none link-secondary opacity-50 hover-opacity-100 transition-all ms-1" data-share-target="snapshot-isolation" aria-haspopup="dialog" aria-label="Share link: Snapshot Isolation"> <i class="fa-sharp-duotone fa-solid fa-share-nodes" aria-hidden="true" style="font-size: 0.8em;"></i> <span class="visually-hidden">Share link</span> </button> </h4><p>Each transaction in Geode operates on a consistent snapshot of the database taken at transaction start time. This snapshot represents a point-in-time view where:</p> <ul> <li>All committed transactions up to the snapshot time are visible</li> <li>All uncommitted or future transactions are invisible</li> <li>The data remains consistent throughout the transaction</li> </ul> <p>Snapshot isolation eliminates many concurrency anomalies:</p> <ul> <li><strong>Dirty reads</strong>: Can&rsquo;t happen—uncommitted data is invisible</li> <li><strong>Non-repeatable reads</strong>: Can&rsquo;t happen—the snapshot is immutable</li> <li><strong>Phantom reads</strong>: Can&rsquo;t happen—new rows don&rsquo;t appear in snapshots</li> </ul> <h4 id="visibility-rules" class="position-relative d-flex align-items-center group"> <span>Visibility Rules</span> <button type="button" class="h-share btn btn-link p-0 text-decoration-none link-secondary opacity-50 hover-opacity-100 transition-all ms-1" data-share-target="visibility-rules" aria-haspopup="dialog" aria-label="Share link: Visibility Rules"> <i class="fa-sharp-duotone fa-solid fa-share-nodes" aria-hidden="true" style="font-size: 0.8em;"></i> <span class="visually-hidden">Share link</span> </button> </h4><p>MVCC determines version visibility using sophisticated rules:</p> <div class="highlight"><pre tabindex="0" class="chroma"><code class="language-fallback" data-lang="fallback"><span class="line"><span class="cl">A version V is visible to transaction T if: </span></span><span class="line"><span class="cl">1. V.begin_timestamp &lt;= T.snapshot_timestamp </span></span><span class="line"><span class="cl">2. V.end_timestamp &gt; T.snapshot_timestamp OR V.end_timestamp IS NULL </span></span><span class="line"><span class="cl">3. V.creating_transaction is committed at T.snapshot_timestamp </span></span><span class="line"><span class="cl">4. V.deleting_transaction is not committed at T.snapshot_timestamp </span></span></code></pre></div><p>These rules ensure transactions only see committed data that was valid at their snapshot time.</p> <h4 id="write-write-conflicts" class="position-relative d-flex align-items-center group"> <span>Write-Write Conflicts</span> <button type="button" class="h-share btn btn-link p-0 text-decoration-none link-secondary opacity-50 hover-opacity-100 transition-all ms-1" data-share-target="write-write-conflicts" aria-haspopup="dialog" aria-label="Share link: Write-Write Conflicts"> <i class="fa-sharp-duotone fa-solid fa-share-nodes" aria-hidden="true" style="font-size: 0.8em;"></i> <span class="visually-hidden">Share link</span> </button> </h4><p>While MVCC allows readers and writers to proceed concurrently, write-write conflicts still require coordination. When two transactions attempt to modify the same data:</p> <div class="highlight"><pre tabindex="0" class="chroma"><code class="language-gql" data-lang="gql"><span class="line"><span class="cl"><span class="err">--</span><span class="w"> </span><span class="py">Transaction</span><span class="w"> </span><span class="py">1</span><span class="w"> </span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="py">BEGIN</span><span class="err">;</span><span class="w"> </span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="py">MATCH</span><span class="w"> </span><span class="p">(</span><span class="py">p</span><span class="p">:</span><span class="nc">Person</span><span class="w"> </span><span class="p">{</span><span class="py">id</span><span class="p">:</span><span class="w"> </span><span class="nc">123</span><span class="p">})</span><span class="w"> </span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="py">SET</span><span class="w"> </span><span class="py">p</span><span class="err">.</span><span class="py">balance</span><span class="w"> </span><span class="p">=</span><span class="w"> </span><span class="py">p</span><span class="err">.</span><span class="py">balance</span><span class="w"> </span><span class="err">+</span><span class="w"> </span><span class="py">100</span><span class="err">;</span><span class="w"> </span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="err">--</span><span class="w"> </span><span class="py">Transaction</span><span class="w"> </span><span class="py">2</span><span class="w"> </span><span class="py">attempts</span><span class="w"> </span><span class="py">same</span><span class="w"> </span><span class="py">update</span><span class="w"> </span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="py">COMMIT</span><span class="err">;</span><span class="w"> </span><span class="err">--</span><span class="w"> </span><span class="py">One</span><span class="w"> </span><span class="py">transaction</span><span class="w"> </span><span class="py">succeeds</span><span class="p">,</span><span class="w"> </span><span class="py">other</span><span class="w"> </span><span class="py">aborts</span><span class="w"> </span><span class="py">with</span><span class="w"> </span><span class="py">conflict</span><span class="w"> </span><span class="py">error</span><span class="w"> </span></span></span></code></pre></div><p>Geode detects write-write conflicts and aborts one transaction, forcing retry. This preserves serializability while maximizing concurrency.</p> <h3 id="how-mvcc-works-in-geode" class="position-relative d-flex align-items-center group"> <span>How MVCC Works in Geode</span> <button type="button" class="h-share btn btn-link p-0 text-decoration-none link-secondary opacity-50 hover-opacity-100 transition-all ms-1" data-share-target="how-mvcc-works-in-geode" aria-haspopup="dialog" aria-label="Share link: How MVCC Works in Geode"> <i class="fa-sharp-duotone fa-solid fa-share-nodes" aria-hidden="true" style="font-size: 0.8em;"></i> <span class="visually-hidden">Share link</span> </button> </h3> <h4 id="transaction-lifecycle" class="position-relative d-flex align-items-center group"> <span>Transaction Lifecycle</span> <button type="button" class="h-share btn btn-link p-0 text-decoration-none link-secondary opacity-50 hover-opacity-100 transition-all ms-1" data-share-target="transaction-lifecycle" aria-haspopup="dialog" aria-label="Share link: Transaction Lifecycle"> <i class="fa-sharp-duotone fa-solid fa-share-nodes" aria-hidden="true" style="font-size: 0.8em;"></i> <span class="visually-hidden">Share link</span> </button> </h4><ol> <li><strong>BEGIN</strong>: Allocate transaction ID, capture snapshot timestamp</li> <li><strong>READ</strong>: Walk version chains to find visible versions</li> <li><strong>WRITE</strong>: Create new versions with current transaction ID</li> <li><strong>COMMIT</strong>: Mark all created versions as committed, update timestamps</li> <li><strong>ROLLBACK</strong>: Mark all created versions as aborted</li> </ol> <h4 id="version-storage" class="position-relative d-flex align-items-center group"> <span>Version Storage</span> <button type="button" class="h-share btn btn-link p-0 text-decoration-none link-secondary opacity-50 hover-opacity-100 transition-all ms-1" data-share-target="version-storage" aria-haspopup="dialog" aria-label="Share link: Version Storage"> <i class="fa-sharp-duotone fa-solid fa-share-nodes" aria-hidden="true" style="font-size: 0.8em;"></i> <span class="visually-hidden">Share link</span> </button> </h4><p>Geode stores versions using a highly optimized layout:</p> <ul> <li><strong>In-Memory Version Table</strong>: Hot versions kept in memory for fast access</li> <li><strong>Versioned B-Tree</strong>: Persistent storage with efficient range scans</li> <li><strong>Version Compression</strong>: Delta encoding for similar versions</li> <li><strong>Garbage Collection</strong>: Background cleanup of obsolete versions</li> </ul> <h4 id="garbage-collection" class="position-relative d-flex align-items-center group"> <span>Garbage Collection</span> <button type="button" class="h-share btn btn-link p-0 text-decoration-none link-secondary opacity-50 hover-opacity-100 transition-all ms-1" data-share-target="garbage-collection" aria-haspopup="dialog" aria-label="Share link: Garbage Collection"> <i class="fa-sharp-duotone fa-solid fa-share-nodes" aria-hidden="true" style="font-size: 0.8em;"></i> <span class="visually-hidden">Share link</span> </button> </h4><p>Over time, old versions accumulate. Geode&rsquo;s MVCC garbage collector reclaims space:</p> <div class="highlight"><pre tabindex="0" class="chroma"><code class="language-fallback" data-lang="fallback"><span class="line"><span class="cl">A version V can be garbage collected if: </span></span><span class="line"><span class="cl">1. V is not the current version </span></span><span class="line"><span class="cl">2. No active transaction has a snapshot_timestamp that could see V </span></span><span class="line"><span class="cl">3. V has been superseded for longer than the retention period </span></span></code></pre></div><p>The GC runs continuously in the background, using a generational approach similar to modern memory managers.</p> <h4 id="integration-with-wal" class="position-relative d-flex align-items-center group"> <span>Integration with WAL</span> <button type="button" class="h-share btn btn-link p-0 text-decoration-none link-secondary opacity-50 hover-opacity-100 transition-all ms-1" data-share-target="integration-with-wal" aria-haspopup="dialog" aria-label="Share link: Integration with WAL"> <i class="fa-sharp-duotone fa-solid fa-share-nodes" aria-hidden="true" style="font-size: 0.8em;"></i> <span class="visually-hidden">Share link</span> </button> </h4><p>MVCC works hand-in-hand with Write-Ahead Logging (WAL):</p> <ul> <li><strong>Before Image</strong>: WAL records contain old version data</li> <li><strong>After Image</strong>: WAL records contain new version data</li> <li><strong>Recovery</strong>: Replay WAL to reconstruct version chains</li> <li><strong>Point-in-Time Recovery</strong>: Use version timestamps to recover to specific moments</li> </ul> <h3 id="use-cases-and-benefits" class="position-relative d-flex align-items-center group"> <span>Use Cases and Benefits</span> <button type="button" class="h-share btn btn-link p-0 text-decoration-none link-secondary opacity-50 hover-opacity-100 transition-all ms-1" data-share-target="use-cases-and-benefits" aria-haspopup="dialog" aria-label="Share link: Use Cases and Benefits"> <i class="fa-sharp-duotone fa-solid fa-share-nodes" aria-hidden="true" style="font-size: 0.8em;"></i> <span class="visually-hidden">Share link</span> </button> </h3> <h4 id="high-concurrency-read-workloads" class="position-relative d-flex align-items-center group"> <span>High-Concurrency Read Workloads</span> <button type="button" class="h-share btn btn-link p-0 text-decoration-none link-secondary opacity-50 hover-opacity-100 transition-all ms-1" data-share-target="high-concurrency-read-workloads" aria-haspopup="dialog" aria-label="Share link: High-Concurrency Read Workloads"> <i class="fa-sharp-duotone fa-solid fa-share-nodes" aria-hidden="true" style="font-size: 0.8em;"></i> <span class="visually-hidden">Share link</span> </button> </h4><p>MVCC shines in read-heavy workloads:</p> <div class="highlight"><pre tabindex="0" class="chroma"><code class="language-gql" data-lang="gql"><span class="line"><span class="cl"><span class="err">--</span><span class="w"> </span><span class="py">Thousands</span><span class="w"> </span><span class="py">of</span><span class="w"> </span><span class="py">concurrent</span><span class="w"> </span><span class="py">read</span><span class="w"> </span><span class="py">transactions</span><span class="w"> </span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="py">MATCH</span><span class="w"> </span><span class="p">(</span><span class="py">p</span><span class="p">:</span><span class="nc">Person</span><span class="p">)</span><span class="err">-</span><span class="p">[:</span><span class="nc">KNOWS</span><span class="err">*</span><span class="py">1</span><span class="err">.</span><span class="mf">.3</span><span class="p">]</span><span class="err">-&gt;</span><span class="p">(</span><span class="py">friend</span><span class="p">)</span><span class="w"> </span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="py">WHERE</span><span class="w"> </span><span class="py">p</span><span class="err">.</span><span class="py">id</span><span class="w"> </span><span class="p">=</span><span class="w"> </span><span class="nv">$userId</span><span class="w"> </span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="py">RETURN</span><span class="w"> </span><span class="py">friend</span><span class="err">.</span><span class="py">name</span><span class="p">,</span><span class="w"> </span><span class="py">friend</span><span class="err">.</span><span class="py">interests</span><span class="w"> </span></span></span></code></pre></div><p>These queries never block each other or block writes, enabling linear scaling of read throughput.</p> <h4 id="long-running-analytics" class="position-relative d-flex align-items-center group"> <span>Long-Running Analytics</span> <button type="button" class="h-share btn btn-link p-0 text-decoration-none link-secondary opacity-50 hover-opacity-100 transition-all ms-1" data-share-target="long-running-analytics" aria-haspopup="dialog" aria-label="Share link: Long-Running Analytics"> <i class="fa-sharp-duotone fa-solid fa-share-nodes" aria-hidden="true" style="font-size: 0.8em;"></i> <span class="visually-hidden">Share link</span> </button> </h4><p>Complex graph analytics can run without locking:</p> <div class="highlight"><pre tabindex="0" class="chroma"><code class="language-gql" data-lang="gql"><span class="line"><span class="cl"><span class="err">--</span><span class="w"> </span><span class="py">Multi</span><span class="err">-</span><span class="py">minute</span><span class="w"> </span><span class="py">PageRank</span><span class="w"> </span><span class="py">computation</span><span class="w"> </span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="py">MATCH</span><span class="w"> </span><span class="p">(</span><span class="py">n</span><span class="p">:</span><span class="nc">Page</span><span class="p">)</span><span class="w"> </span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="py">RETURN</span><span class="w"> </span><span class="py">n</span><span class="err">.</span><span class="py">id</span><span class="p">,</span><span class="w"> </span><span class="py">pageRank</span><span class="p">(</span><span class="py">n</span><span class="p">)</span><span class="w"> </span><span class="py">AS</span><span class="w"> </span><span class="py">rank</span><span class="w"> </span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="py">ORDER</span><span class="w"> </span><span class="py">BY</span><span class="w"> </span><span class="py">rank</span><span class="w"> </span><span class="py">DESC</span><span class="w"> </span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="py">LIMIT</span><span class="w"> </span><span class="py">100</span><span class="w"> </span></span></span></code></pre></div><p>The transaction operates on a consistent snapshot, unaffected by concurrent updates.</p> <h4 id="time-travel-queries" class="position-relative d-flex align-items-center group"> <span>Time-Travel Queries</span> <button type="button" class="h-share btn btn-link p-0 text-decoration-none link-secondary opacity-50 hover-opacity-100 transition-all ms-1" data-share-target="time-travel-queries" aria-haspopup="dialog" aria-label="Share link: Time-Travel Queries"> <i class="fa-sharp-duotone fa-solid fa-share-nodes" aria-hidden="true" style="font-size: 0.8em;"></i> <span class="visually-hidden">Share link</span> </button> </h4><p>MVCC enables querying historical data:</p> <div class="highlight"><pre tabindex="0" class="chroma"><code class="language-gql" data-lang="gql"><span class="line"><span class="cl"><span class="err">--</span><span class="w"> </span><span class="py">See</span><span class="w"> </span><span class="py">data</span><span class="w"> </span><span class="py">as</span><span class="w"> </span><span class="py">it</span><span class="w"> </span><span class="py">existed</span><span class="w"> </span><span class="py">at</span><span class="w"> </span><span class="py">specific</span><span class="w"> </span><span class="py">time</span><span class="w"> </span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="py">SET</span><span class="w"> </span><span class="py">TRANSACTION</span><span class="w"> </span><span class="py">SNAPSHOT</span><span class="w"> </span><span class="py">AT</span><span class="w"> </span><span class="err">&#39;</span><span class="py">2025</span><span class="err">-</span><span class="py">01</span><span class="err">-</span><span class="py">01T00</span><span class="p">:</span><span class="nc">00</span><span class="p">:</span><span class="nc">00Z</span><span class="err">&#39;;</span><span class="w"> </span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="py">MATCH</span><span class="w"> </span><span class="p">(</span><span class="py">account</span><span class="p">:</span><span class="nc">Account</span><span class="w"> </span><span class="p">{</span><span class="py">id</span><span class="p">:</span><span class="w"> </span><span class="nv">$accountId</span><span class="p">})</span><span class="w"> </span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="nc">RETURN</span><span class="w"> </span><span class="py">account</span><span class="err">.</span><span class="py">balance</span><span class="w"> </span><span class="err">--</span><span class="w"> </span><span class="py">Balance</span><span class="w"> </span><span class="kd">on</span><span class="w"> </span><span class="py">Jan</span><span class="w"> </span><span class="py">1</span><span class="p">,</span><span class="w"> </span><span class="py">2025</span><span class="w"> </span></span></span></code></pre></div><p>This is invaluable for auditing, debugging, and historical analysis.</p> <h4 id="optimistic-concurrency" class="position-relative d-flex align-items-center group"> <span>Optimistic Concurrency</span> <button type="button" class="h-share btn btn-link p-0 text-decoration-none link-secondary opacity-50 hover-opacity-100 transition-all ms-1" data-share-target="optimistic-concurrency" aria-haspopup="dialog" aria-label="Share link: Optimistic Concurrency"> <i class="fa-sharp-duotone fa-solid fa-share-nodes" aria-hidden="true" style="font-size: 0.8em;"></i> <span class="visually-hidden">Share link</span> </button> </h4><p>MVCC supports optimistic locking patterns:</p> <div class="highlight"><pre tabindex="0" class="chroma"><code class="language-gql" data-lang="gql"><span class="line"><span class="cl"><span class="err">--</span><span class="w"> </span><span class="py">Optimistic</span><span class="w"> </span><span class="py">update</span><span class="w"> </span><span class="py">with</span><span class="w"> </span><span class="py">version</span><span class="w"> </span><span class="py">check</span><span class="w"> </span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="py">MATCH</span><span class="w"> </span><span class="p">(</span><span class="py">product</span><span class="p">:</span><span class="nc">Product</span><span class="w"> </span><span class="p">{</span><span class="py">sku</span><span class="p">:</span><span class="w"> </span><span class="nv">$sku</span><span class="p">})</span><span class="w"> </span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="nc">WHERE</span><span class="w"> </span><span class="py">product</span><span class="err">.</span><span class="py">version</span><span class="w"> </span><span class="p">=</span><span class="w"> </span><span class="nv">$expectedVersion</span><span class="w"> </span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="py">SET</span><span class="w"> </span><span class="py">product</span><span class="err">.</span><span class="py">quantity</span><span class="w"> </span><span class="p">=</span><span class="w"> </span><span class="py">product</span><span class="err">.</span><span class="py">quantity</span><span class="w"> </span><span class="err">-</span><span class="w"> </span><span class="nv">$amount</span><span class="p">,</span><span class="w"> </span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="py">product</span><span class="err">.</span><span class="py">version</span><span class="w"> </span><span class="p">=</span><span class="w"> </span><span class="py">product</span><span class="err">.</span><span class="py">version</span><span class="w"> </span><span class="err">+</span><span class="w"> </span><span class="py">1</span><span class="w"> </span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="py">RETURN</span><span class="w"> </span><span class="py">product</span><span class="err">.</span><span class="py">version</span><span class="w"> </span></span></span></code></pre></div><p>If the version changed, the WHERE clause fails, signaling a conflict.</p> <h3 id="best-practices" class="position-relative d-flex align-items-center group"> <span>Best Practices</span> <button type="button" class="h-share btn btn-link p-0 text-decoration-none link-secondary opacity-50 hover-opacity-100 transition-all ms-1" data-share-target="best-practices" aria-haspopup="dialog" aria-label="Share link: Best Practices"> <i class="fa-sharp-duotone fa-solid fa-share-nodes" aria-hidden="true" style="font-size: 0.8em;"></i> <span class="visually-hidden">Share link</span> </button> </h3> <h4 id="transaction-management" class="position-relative d-flex align-items-center group"> <span>Transaction Management</span> <button type="button" class="h-share btn btn-link p-0 text-decoration-none link-secondary opacity-50 hover-opacity-100 transition-all ms-1" data-share-target="transaction-management" aria-haspopup="dialog" aria-label="Share link: Transaction Management"> <i class="fa-sharp-duotone fa-solid fa-share-nodes" aria-hidden="true" style="font-size: 0.8em;"></i> <span class="visually-hidden">Share link</span> </button> </h4><ol> <li> <p><strong>Keep transactions short</strong>: Long transactions hold snapshots, preventing garbage collection</p> <div class="highlight"><pre tabindex="0" class="chroma"><code class="language-gql" data-lang="gql"><span class="line"><span class="cl"><span class="err">--</span><span class="w"> </span><span class="py">Good</span><span class="p">:</span><span class="w"> </span><span class="nc">Short</span><span class="w"> </span><span class="py">transaction</span><span class="w"> </span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="py">BEGIN</span><span class="err">;</span><span class="w"> </span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="py">MATCH</span><span class="w"> </span><span class="p">(</span><span class="py">p</span><span class="p">:</span><span class="nc">Person</span><span class="w"> </span><span class="p">{</span><span class="py">id</span><span class="p">:</span><span class="w"> </span><span class="nv">$id</span><span class="p">})</span><span class="w"> </span><span class="nc">SET</span><span class="w"> </span><span class="py">p</span><span class="err">.</span><span class="py">last_login</span><span class="w"> </span><span class="p">=</span><span class="w"> </span><span class="py">now</span><span class="p">()</span><span class="err">;</span><span class="w"> </span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="py">COMMIT</span><span class="err">;</span><span class="w"> </span></span></span><span class="line"><span class="cl"><span class="w"> </span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="err">--</span><span class="w"> </span><span class="py">Bad</span><span class="p">:</span><span class="w"> </span><span class="nc">Long</span><span class="err">-</span><span class="py">running</span><span class="w"> </span><span class="py">transaction</span><span class="w"> </span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="py">BEGIN</span><span class="err">;</span><span class="w"> </span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="err">--</span><span class="w"> </span><span class="py">Complex</span><span class="w"> </span><span class="py">processing</span><span class="kd">...</span><span class="w"> </span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="err">--</span><span class="w"> </span><span class="py">Hours</span><span class="w"> </span><span class="py">later</span><span class="kd">...</span><span class="w"> </span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="py">COMMIT</span><span class="err">;</span><span class="w"> </span></span></span></code></pre></div></li> <li> <p><strong>Use appropriate isolation levels</strong>: Choose between snapshot isolation and serializable snapshot isolation based on requirements</p> </li> <li> <p><strong>Handle conflicts gracefully</strong>: Implement retry logic for write-write conflicts</p> <div class="highlight"><pre tabindex="0" class="chroma"><code class="language-python" data-lang="python"><span class="line"><span class="cl"><span class="k">for</span> <span class="n">attempt</span> <span class="ow">in</span> <span class="nb">range</span><span class="p">(</span><span class="n">max_retries</span><span class="p">):</span> </span></span><span class="line"><span class="cl"> <span class="k">try</span><span class="p">:</span> </span></span><span class="line"><span class="cl"> <span class="k">with</span> <span class="n">db</span><span class="o">.</span><span class="n">transaction</span><span class="p">():</span> </span></span><span class="line"><span class="cl"> <span class="c1"># Perform updates</span> </span></span><span class="line"><span class="cl"> <span class="k">break</span> </span></span><span class="line"><span class="cl"> <span class="k">except</span> <span class="n">ConflictError</span><span class="p">:</span> </span></span><span class="line"><span class="cl"> <span class="k">if</span> <span class="n">attempt</span> <span class="o">==</span> <span class="n">max_retries</span> <span class="o">-</span> <span class="mi">1</span><span class="p">:</span> </span></span><span class="line"><span class="cl"> <span class="k">raise</span> </span></span><span class="line"><span class="cl"> <span class="n">time</span><span class="o">.</span><span class="n">sleep</span><span class="p">(</span><span class="n">backoff_delay</span><span class="p">)</span> </span></span></code></pre></div></li> </ol> <h4 id="performance-optimization" class="position-relative d-flex align-items-center group"> <span>Performance Optimization</span> <button type="button" class="h-share btn btn-link p-0 text-decoration-none link-secondary opacity-50 hover-opacity-100 transition-all ms-1" data-share-target="performance-optimization" aria-haspopup="dialog" aria-label="Share link: Performance Optimization"> <i class="fa-sharp-duotone fa-solid fa-share-nodes" aria-hidden="true" style="font-size: 0.8em;"></i> <span class="visually-hidden">Share link</span> </button> </h4><ol> <li><strong>Monitor version chain length</strong>: Long chains indicate hot spots</li> <li><strong>Tune garbage collection</strong>: Balance retention needs with storage efficiency</li> <li><strong>Use bulk operations</strong>: Reduce transaction overhead for batch updates</li> <li><strong>Partition hot data</strong>: Distribute high-contention data across nodes</li> </ol> <h4 id="debugging-and-monitoring" class="position-relative d-flex align-items-center group"> <span>Debugging and Monitoring</span> <button type="button" class="h-share btn btn-link p-0 text-decoration-none link-secondary opacity-50 hover-opacity-100 transition-all ms-1" data-share-target="debugging-and-monitoring" aria-haspopup="dialog" aria-label="Share link: Debugging and Monitoring"> <i class="fa-sharp-duotone fa-solid fa-share-nodes" aria-hidden="true" style="font-size: 0.8em;"></i> <span class="visually-hidden">Share link</span> </button> </h4><p>Track MVCC metrics:</p> <ul> <li><strong>Active transactions</strong>: Number of concurrent transactions</li> <li><strong>Version chain depth</strong>: Average and max version count per item</li> <li><strong>GC throughput</strong>: Versions reclaimed per second</li> <li><strong>Conflict rate</strong>: Write-write conflicts per second</li> <li><strong>Snapshot age</strong>: Age of oldest active snapshot</li> </ul> <div class="highlight"><pre tabindex="0" class="chroma"><code class="language-gql" data-lang="gql"><span class="line"><span class="cl"><span class="err">--</span><span class="w"> </span><span class="py">Query</span><span class="w"> </span><span class="py">MVCC</span><span class="w"> </span><span class="py">statistics</span><span class="w"> </span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="py">CALL</span><span class="w"> </span><span class="py">dbms</span><span class="err">.</span><span class="py">monitor</span><span class="err">.</span><span class="py">mvcc</span><span class="err">.</span><span class="py">stats</span><span class="p">()</span><span class="w"> </span><span class="py">YIELD</span><span class="w"> </span><span class="py">metric</span><span class="p">,</span><span class="w"> </span><span class="py">value</span><span class="w"> </span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="py">RETURN</span><span class="w"> </span><span class="py">metric</span><span class="p">,</span><span class="w"> </span><span class="py">value</span><span class="w"> </span></span></span></code></pre></div> <h3 id="troubleshooting" class="position-relative d-flex align-items-center group"> <span>Troubleshooting</span> <button type="button" class="h-share btn btn-link p-0 text-decoration-none link-secondary opacity-50 hover-opacity-100 transition-all ms-1" data-share-target="troubleshooting" aria-haspopup="dialog" aria-label="Share link: Troubleshooting"> <i class="fa-sharp-duotone fa-solid fa-share-nodes" aria-hidden="true" style="font-size: 0.8em;"></i> <span class="visually-hidden">Share link</span> </button> </h3> <h4 id="long-version-chains" class="position-relative d-flex align-items-center group"> <span>Long Version Chains</span> <button type="button" class="h-share btn btn-link p-0 text-decoration-none link-secondary opacity-50 hover-opacity-100 transition-all ms-1" data-share-target="long-version-chains" aria-haspopup="dialog" aria-label="Share link: Long Version Chains"> <i class="fa-sharp-duotone fa-solid fa-share-nodes" aria-hidden="true" style="font-size: 0.8em;"></i> <span class="visually-hidden">Share link</span> </button> </h4><p><strong>Symptom</strong>: Queries slow down over time <strong>Cause</strong>: Hot-spot data with frequent updates <strong>Solution</strong>: Partition data, increase GC frequency, or redesign schema</p> <h4 id="garbage-collection-stalls" class="position-relative d-flex align-items-center group"> <span>Garbage Collection Stalls</span> <button type="button" class="h-share btn btn-link p-0 text-decoration-none link-secondary opacity-50 hover-opacity-100 transition-all ms-1" data-share-target="garbage-collection-stalls" aria-haspopup="dialog" aria-label="Share link: Garbage Collection Stalls"> <i class="fa-sharp-duotone fa-solid fa-share-nodes" aria-hidden="true" style="font-size: 0.8em;"></i> <span class="visually-hidden">Share link</span> </button> </h4><p><strong>Symptom</strong>: Storage keeps growing <strong>Cause</strong>: Long-running transactions preventing GC <strong>Solution</strong>: Identify and terminate long transactions, tune retention policy</p> <h4 id="high-conflict-rates" class="position-relative d-flex align-items-center group"> <span>High Conflict Rates</span> <button type="button" class="h-share btn btn-link p-0 text-decoration-none link-secondary opacity-50 hover-opacity-100 transition-all ms-1" data-share-target="high-conflict-rates" aria-haspopup="dialog" aria-label="Share link: High Conflict Rates"> <i class="fa-sharp-duotone fa-solid fa-share-nodes" aria-hidden="true" style="font-size: 0.8em;"></i> <span class="visually-hidden">Share link</span> </button> </h4><p><strong>Symptom</strong>: Many transaction aborts <strong>Cause</strong>: Write-write conflicts on shared data <strong>Solution</strong>: Redesign to reduce contention, use application-level sharding</p> <h3 id="related-topics" class="position-relative d-flex align-items-center group"> <span>Related Topics</span> <button type="button" class="h-share btn btn-link p-0 text-decoration-none link-secondary opacity-50 hover-opacity-100 transition-all ms-1" data-share-target="related-topics" aria-haspopup="dialog" aria-label="Share link: Related Topics"> <i class="fa-sharp-duotone fa-solid fa-share-nodes" aria-hidden="true" style="font-size: 0.8em;"></i> <span class="visually-hidden">Share link</span> </button> </h3><ul> <li><a href="/tags/ssi/" >Serializable Snapshot Isolation (SSI)</a> - Advanced isolation level built on MVCC</li> <li><a href="/tags/wal/" >Write-Ahead Logging (WAL)</a> - Durability mechanism integrated with MVCC</li> <li><a href="/tags/acid/" >ACID Transactions</a> - Transaction guarantees enabled by MVCC</li> <li><a href="/tags/concurrency/" >Concurrency Control</a> - Broader concurrency mechanisms</li> <li><a href="/tags/isolation/" >Isolation Levels</a> - Transaction isolation guarantees</li> <li><a href="/tags/performance/" >Performance</a> - MVCC performance characteristics</li> <li><a href="/tags/transactions/" >Transactions</a> - Transaction management</li> </ul> <h3 id="further-reading" class="position-relative d-flex align-items-center group"> <span>Further Reading</span> <button type="button" class="h-share btn btn-link p-0 text-decoration-none link-secondary opacity-50 hover-opacity-100 transition-all ms-1" data-share-target="further-reading" aria-haspopup="dialog" aria-label="Share link: Further Reading"> <i class="fa-sharp-duotone fa-solid fa-share-nodes" aria-hidden="true" style="font-size: 0.8em;"></i> <span class="visually-hidden">Share link</span> </button> </h3> <h4 id="documentation" class="position-relative d-flex align-items-center group"> <span>Documentation</span> <button type="button" class="h-share btn btn-link p-0 text-decoration-none link-secondary opacity-50 hover-opacity-100 transition-all ms-1" data-share-target="documentation" aria-haspopup="dialog" aria-label="Share link: Documentation"> <i class="fa-sharp-duotone fa-solid fa-share-nodes" aria-hidden="true" style="font-size: 0.8em;"></i> <span class="visually-hidden">Share link</span> </button> </h4><ul> <li><a href="/docs/transactions/" >Transaction Guide</a> - Complete transaction documentation</li> <li><a href="/tags/concurrency/" >Concurrency Control</a> - Detailed concurrency mechanisms</li> <li><a href="/docs/query/performance-tuning/" >Performance Tuning</a> - MVCC optimization techniques</li> </ul> <h4 id="implementation-details" class="position-relative d-flex align-items-center group"> <span>Implementation Details</span> <button type="button" class="h-share btn btn-link p-0 text-decoration-none link-secondary opacity-50 hover-opacity-100 transition-all ms-1" data-share-target="implementation-details" aria-haspopup="dialog" aria-label="Share link: Implementation Details"> <i class="fa-sharp-duotone fa-solid fa-share-nodes" aria-hidden="true" style="font-size: 0.8em;"></i> <span class="visually-hidden">Share link</span> </button> </h4><ul> <li><a href="/docs/architecture/" >Architecture Overview</a> - System architecture including MVCC</li> <li><a href="/tags/storage/" >Storage Engine</a> - Version storage and indexing</li> <li><a href="/docs/recovery/" >Recovery and Durability</a> - WAL integration with MVCC</li> </ul> <h4 id="advanced-topics" class="position-relative d-flex align-items-center group"> <span>Advanced Topics</span> <button type="button" class="h-share btn btn-link p-0 text-decoration-none link-secondary opacity-50 hover-opacity-100 transition-all ms-1" data-share-target="advanced-topics" aria-haspopup="dialog" aria-label="Share link: Advanced Topics"> <i class="fa-sharp-duotone fa-solid fa-share-nodes" aria-hidden="true" style="font-size: 0.8em;"></i> <span class="visually-hidden">Share link</span> </button> </h4><ul> <li><a href="/tags/distributed/" >Distributed MVCC</a> - MVCC in distributed environments</li> <li><a href="/tags/performance/" >Garbage Collection</a> - Version cleanup strategies</li> <li><a href="/tags/temporal/" >Temporal Queries</a> - Historical query capabilities</li> </ul> <h3 id="mvcc-implementation-deep-dive" class="position-relative d-flex align-items-center group"> <span>MVCC Implementation Deep Dive</span> <button type="button" class="h-share btn btn-link p-0 text-decoration-none link-secondary opacity-50 hover-opacity-100 transition-all ms-1" data-share-target="mvcc-implementation-deep-dive" aria-haspopup="dialog" aria-label="Share link: MVCC Implementation Deep Dive"> <i class="fa-sharp-duotone fa-solid fa-share-nodes" aria-hidden="true" style="font-size: 0.8em;"></i> <span class="visually-hidden">Share link</span> </button> </h3> <h4 id="version-storage-architecture" class="position-relative d-flex align-items-center group"> <span>Version Storage Architecture</span> <button type="button" class="h-share btn btn-link p-0 text-decoration-none link-secondary opacity-50 hover-opacity-100 transition-all ms-1" data-share-target="version-storage-architecture" aria-haspopup="dialog" aria-label="Share link: Version Storage Architecture"> <i class="fa-sharp-duotone fa-solid fa-share-nodes" aria-hidden="true" style="font-size: 0.8em;"></i> <span class="visually-hidden">Share link</span> </button> </h4><p>Geode stores versions using an optimized multi-tier approach:</p> <div class="highlight"><pre tabindex="0" class="chroma"><code class="language-fallback" data-lang="fallback"><span class="line"><span class="cl">Node Version Chain Example: </span></span><span class="line"><span class="cl">┌─────────────────────────────────────────────────────────┐ </span></span><span class="line"><span class="cl">│ Node ID: 42 (Person:Alice) │ </span></span><span class="line"><span class="cl">├─────────────────────────────────────────────────────────┤ </span></span><span class="line"><span class="cl">│ Current Version (TxID: 1005, committed) │ </span></span><span class="line"><span class="cl">│ age: 31 │ </span></span><span class="line"><span class="cl">│ email: &#34;[email protected]&#34; │ </span></span><span class="line"><span class="cl">│ ↓ │ </span></span><span class="line"><span class="cl">│ Previous Version (TxID: 1003, committed) │ </span></span><span class="line"><span class="cl">│ age: 31 │ </span></span><span class="line"><span class="cl">│ email: &#34;[email protected]&#34; │ </span></span><span class="line"><span class="cl">│ ↓ │ </span></span><span class="line"><span class="cl">│ Previous Version (TxID: 1001, committed) │ </span></span><span class="line"><span class="cl">│ age: 30 │ </span></span><span class="line"><span class="cl">│ email: &#34;[email protected]&#34; │ </span></span><span class="line"><span class="cl">│ ↓ │ </span></span><span class="line"><span class="cl">│ NULL (end of chain) │ </span></span><span class="line"><span class="cl">└─────────────────────────────────────────────────────────┘ </span></span></code></pre></div> <h4 id="version-visibility-algorithm" class="position-relative d-flex align-items-center group"> <span>Version Visibility Algorithm</span> <button type="button" class="h-share btn btn-link p-0 text-decoration-none link-secondary opacity-50 hover-opacity-100 transition-all ms-1" data-share-target="version-visibility-algorithm" aria-haspopup="dialog" aria-label="Share link: Version Visibility Algorithm"> <i class="fa-sharp-duotone fa-solid fa-share-nodes" aria-hidden="true" style="font-size: 0.8em;"></i> <span class="visually-hidden">Share link</span> </button> </h4><div class="highlight"><pre tabindex="0" class="chroma"><code class="language-zig" data-lang="zig"><span class="line"><span class="cl"><span class="c1">// geode/src/mvcc/visibility.zig </span></span></span><span class="line"><span class="cl"><span class="c1"></span><span class="w"> </span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="kr">pub</span><span class="w"> </span><span class="k">fn</span><span class="w"> </span><span class="n">isVersionVisible</span><span class="p">(</span><span class="w"> </span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="n">version</span><span class="o">:</span><span class="w"> </span><span class="o">*</span><span class="n">Version</span><span class="p">,</span><span class="w"> </span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="n">snapshot</span><span class="o">:</span><span class="w"> </span><span class="o">*</span><span class="n">Snapshot</span><span class="w"> </span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="p">)</span><span class="w"> </span><span class="kt">bool</span><span class="w"> </span><span class="p">{</span><span class="w"> </span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="c1">// Check version begin timestamp </span></span></span><span class="line"><span class="cl"><span class="c1"></span><span class="w"> </span><span class="k">if</span><span class="w"> </span><span class="p">(</span><span class="n">version</span><span class="p">.</span><span class="n">begin_timestamp</span><span class="w"> </span><span class="o">&gt;</span><span class="w"> </span><span class="n">snapshot</span><span class="p">.</span><span class="n">timestamp</span><span class="p">)</span><span class="w"> </span><span class="p">{</span><span class="w"> </span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="k">return</span><span class="w"> </span><span class="kc">false</span><span class="p">;</span><span class="w"> </span><span class="c1">// Created after snapshot </span></span></span><span class="line"><span class="cl"><span class="c1"></span><span class="w"> </span><span class="p">}</span><span class="w"> </span></span></span><span class="line"><span class="cl"><span class="w"> </span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="c1">// Check version end timestamp </span></span></span><span class="line"><span class="cl"><span class="c1"></span><span class="w"> </span><span class="k">if</span><span class="w"> </span><span class="p">(</span><span class="n">version</span><span class="p">.</span><span class="n">end_timestamp</span><span class="w"> </span><span class="o">!=</span><span class="w"> </span><span class="kc">null</span><span class="w"> </span><span class="k">and</span><span class="w"> </span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="n">version</span><span class="p">.</span><span class="n">end_timestamp</span><span class="p">.</span><span class="o">?</span><span class="w"> </span><span class="o">&lt;=</span><span class="w"> </span><span class="n">snapshot</span><span class="p">.</span><span class="n">timestamp</span><span class="p">)</span><span class="w"> </span><span class="p">{</span><span class="w"> </span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="k">return</span><span class="w"> </span><span class="kc">false</span><span class="p">;</span><span class="w"> </span><span class="c1">// Deleted before snapshot </span></span></span><span class="line"><span class="cl"><span class="c1"></span><span class="w"> </span><span class="p">}</span><span class="w"> </span></span></span><span class="line"><span class="cl"><span class="w"> </span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="c1">// Check creating transaction status </span></span></span><span class="line"><span class="cl"><span class="c1"></span><span class="w"> </span><span class="k">if</span><span class="w"> </span><span class="p">(</span><span class="o">!</span><span class="n">isCommitted</span><span class="p">(</span><span class="n">version</span><span class="p">.</span><span class="n">creating_tx</span><span class="p">,</span><span class="w"> </span><span class="n">snapshot</span><span class="p">.</span><span class="n">timestamp</span><span class="p">))</span><span class="w"> </span><span class="p">{</span><span class="w"> </span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="k">return</span><span class="w"> </span><span class="kc">false</span><span class="p">;</span><span class="w"> </span><span class="c1">// Creating transaction not committed </span></span></span><span class="line"><span class="cl"><span class="c1"></span><span class="w"> </span><span class="p">}</span><span class="w"> </span></span></span><span class="line"><span class="cl"><span class="w"> </span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="c1">// Check deleting transaction status </span></span></span><span class="line"><span class="cl"><span class="c1"></span><span class="w"> </span><span class="k">if</span><span class="w"> </span><span class="p">(</span><span class="n">version</span><span class="p">.</span><span class="n">deleting_tx</span><span class="w"> </span><span class="o">!=</span><span class="w"> </span><span class="kc">null</span><span class="w"> </span><span class="k">and</span><span class="w"> </span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="n">isCommitted</span><span class="p">(</span><span class="n">version</span><span class="p">.</span><span class="n">deleting_tx</span><span class="p">.</span><span class="o">?</span><span class="p">,</span><span class="w"> </span><span class="n">snapshot</span><span class="p">.</span><span class="n">timestamp</span><span class="p">))</span><span class="w"> </span><span class="p">{</span><span class="w"> </span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="k">return</span><span class="w"> </span><span class="kc">false</span><span class="p">;</span><span class="w"> </span><span class="c1">// Deleting transaction committed </span></span></span><span class="line"><span class="cl"><span class="c1"></span><span class="w"> </span><span class="p">}</span><span class="w"> </span></span></span><span class="line"><span class="cl"><span class="w"> </span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="k">return</span><span class="w"> </span><span class="kc">true</span><span class="p">;</span><span class="w"> </span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="p">}</span><span class="w"> </span></span></span></code></pre></div> <h4 id="snapshot-isolation-example" class="position-relative d-flex align-items-center group"> <span>Snapshot Isolation Example</span> <button type="button" class="h-share btn btn-link p-0 text-decoration-none link-secondary opacity-50 hover-opacity-100 transition-all ms-1" data-share-target="snapshot-isolation-example" aria-haspopup="dialog" aria-label="Share link: Snapshot Isolation Example"> <i class="fa-sharp-duotone fa-solid fa-share-nodes" aria-hidden="true" style="font-size: 0.8em;"></i> <span class="visually-hidden">Share link</span> </button> </h4><div class="highlight"><pre tabindex="0" class="chroma"><code class="language-python" data-lang="python"><span class="line"><span class="cl"><span class="kn">from</span> <span class="nn">geode_client</span> <span class="kn">import</span> <span class="n">Client</span> </span></span><span class="line"><span class="cl"><span class="kn">import</span> <span class="nn">asyncio</span> </span></span><span class="line"><span class="cl"> </span></span><span class="line"><span class="cl"><span class="k">async</span> <span class="k">def</span> <span class="nf">demonstrate_snapshot_isolation</span><span class="p">():</span> </span></span><span class="line"><span class="cl"> <span class="n">client1</span> <span class="o">=</span> <span class="n">Client</span><span class="p">(</span><span class="s2">&#34;localhost&#34;</span><span class="p">,</span> <span class="mi">3141</span><span class="p">)</span> </span></span><span class="line"><span class="cl"> <span class="n">client2</span> <span class="o">=</span> <span class="n">Client</span><span class="p">(</span><span class="s2">&#34;localhost&#34;</span><span class="p">,</span> <span class="mi">3141</span><span class="p">)</span> </span></span><span class="line"><span class="cl"> </span></span><span class="line"><span class="cl"> <span class="c1"># Setup: Create test data</span> </span></span><span class="line"><span class="cl"> <span class="k">await</span> <span class="n">tx1</span><span class="o">.</span><span class="n">execute</span><span class="p">(</span><span class="s2">&#34;&#34;&#34; </span></span></span><span class="line"><span class="cl"><span class="s2"> CREATE (account:Account {id: &#39;acc_123&#39;, balance: 1000}) </span></span></span><span class="line"><span class="cl"><span class="s2"> &#34;&#34;&#34;</span><span class="p">)</span> </span></span><span class="line"><span class="cl"> </span></span><span class="line"><span class="cl"> <span class="c1"># Transaction 1: Long-running read</span> </span></span><span class="line"><span class="cl"> <span class="k">async</span> <span class="k">with</span> <span class="n">client1</span><span class="o">.</span><span class="n">connection</span><span class="p">()</span> <span class="k">as</span> <span class="n">tx1</span><span class="p">:</span> </span></span><span class="line"><span class="cl"> <span class="k">await</span> <span class="n">tx1</span><span class="o">.</span><span class="n">begin</span><span class="p">()</span> </span></span><span class="line"><span class="cl"> <span class="c1"># Take snapshot at t=1</span> </span></span><span class="line"><span class="cl"> <span class="n">result1</span> <span class="o">=</span> <span class="k">await</span> <span class="n">tx1</span><span class="o">.</span><span class="n">execute</span><span class="p">(</span><span class="s2">&#34;&#34;&#34; </span></span></span><span class="line"><span class="cl"><span class="s2"> MATCH (account:Account {id: &#39;acc_123&#39;}) </span></span></span><span class="line"><span class="cl"><span class="s2"> RETURN account.balance AS balance </span></span></span><span class="line"><span class="cl"><span class="s2"> &#34;&#34;&#34;</span><span class="p">)</span> </span></span><span class="line"><span class="cl"> <span class="n">balance_t1</span> <span class="o">=</span> <span class="p">(</span><span class="n">result1</span><span class="o">.</span><span class="n">rows</span><span class="p">[</span><span class="mi">0</span><span class="p">]</span> <span class="k">if</span> <span class="n">result1</span><span class="o">.</span><span class="n">rows</span> <span class="k">else</span> <span class="kc">None</span><span class="p">)[</span><span class="s1">&#39;balance&#39;</span><span class="p">]</span> </span></span><span class="line"><span class="cl"> <span class="nb">print</span><span class="p">(</span><span class="sa">f</span><span class="s2">&#34;T1 reads balance: </span><span class="si">{</span><span class="n">balance_t1</span><span class="si">}</span><span class="s2">&#34;</span><span class="p">)</span> <span class="c1"># 1000</span> </span></span><span class="line"><span class="cl"> </span></span><span class="line"><span class="cl"> <span class="c1"># Transaction 2: Concurrent update</span> </span></span><span class="line"><span class="cl"> <span class="k">async</span> <span class="k">with</span> <span class="n">client2</span><span class="o">.</span><span class="n">connection</span><span class="p">()</span> <span class="k">as</span> <span class="n">tx2</span><span class="p">:</span> </span></span><span class="line"><span class="cl"> <span class="k">await</span> <span class="n">tx2</span><span class="o">.</span><span class="n">begin</span><span class="p">()</span> </span></span><span class="line"><span class="cl"> <span class="k">await</span> <span class="n">tx2</span><span class="o">.</span><span class="n">execute</span><span class="p">(</span><span class="s2">&#34;&#34;&#34; </span></span></span><span class="line"><span class="cl"><span class="s2"> MATCH (account:Account {id: &#39;acc_123&#39;}) </span></span></span><span class="line"><span class="cl"><span class="s2"> SET account.balance = account.balance - 100 </span></span></span><span class="line"><span class="cl"><span class="s2"> &#34;&#34;&#34;</span><span class="p">)</span> </span></span><span class="line"><span class="cl"> <span class="c1"># T2 commits here</span> </span></span><span class="line"><span class="cl"> </span></span><span class="line"><span class="cl"> <span class="c1"># Sleep to ensure T2 commits</span> </span></span><span class="line"><span class="cl"> <span class="k">await</span> <span class="n">asyncio</span><span class="o">.</span><span class="n">sleep</span><span class="p">(</span><span class="mf">0.1</span><span class="p">)</span> </span></span><span class="line"><span class="cl"> </span></span><span class="line"><span class="cl"> <span class="c1"># T1 reads again from same snapshot</span> </span></span><span class="line"><span class="cl"> <span class="n">result2</span> <span class="o">=</span> <span class="k">await</span> <span class="n">tx1</span><span class="o">.</span><span class="n">execute</span><span class="p">(</span><span class="s2">&#34;&#34;&#34; </span></span></span><span class="line"><span class="cl"><span class="s2"> MATCH (account:Account {id: &#39;acc_123&#39;}) </span></span></span><span class="line"><span class="cl"><span class="s2"> RETURN account.balance AS balance </span></span></span><span class="line"><span class="cl"><span class="s2"> &#34;&#34;&#34;</span><span class="p">)</span> </span></span><span class="line"><span class="cl"> <span class="n">balance_t2</span> <span class="o">=</span> <span class="p">(</span><span class="n">result2</span><span class="o">.</span><span class="n">rows</span><span class="p">[</span><span class="mi">0</span><span class="p">]</span> <span class="k">if</span> <span class="n">result2</span><span class="o">.</span><span class="n">rows</span> <span class="k">else</span> <span class="kc">None</span><span class="p">)[</span><span class="s1">&#39;balance&#39;</span><span class="p">]</span> </span></span><span class="line"><span class="cl"> <span class="nb">print</span><span class="p">(</span><span class="sa">f</span><span class="s2">&#34;T1 reads balance again: </span><span class="si">{</span><span class="n">balance_t2</span><span class="si">}</span><span class="s2">&#34;</span><span class="p">)</span> <span class="c1"># Still 1000!</span> </span></span><span class="line"><span class="cl"> </span></span><span class="line"><span class="cl"> <span class="c1"># T1 sees consistent snapshot despite T2&#39;s committed change</span> </span></span><span class="line"><span class="cl"> </span></span><span class="line"><span class="cl"> <span class="c1"># After T1 commits, new snapshot sees T2&#39;s change</span> </span></span><span class="line"><span class="cl"> <span class="n">result3</span> <span class="o">=</span> <span class="k">await</span> <span class="n">tx1</span><span class="o">.</span><span class="n">execute</span><span class="p">(</span><span class="s2">&#34;&#34;&#34; </span></span></span><span class="line"><span class="cl"><span class="s2"> MATCH (account:Account {id: &#39;acc_123&#39;}) </span></span></span><span class="line"><span class="cl"><span class="s2"> RETURN account.balance AS balance </span></span></span><span class="line"><span class="cl"><span class="s2"> &#34;&#34;&#34;</span><span class="p">)</span> </span></span><span class="line"><span class="cl"> <span class="n">balance_final</span> <span class="o">=</span> <span class="p">(</span><span class="n">result3</span><span class="o">.</span><span class="n">rows</span><span class="p">[</span><span class="mi">0</span><span class="p">]</span> <span class="k">if</span> <span class="n">result3</span><span class="o">.</span><span class="n">rows</span> <span class="k">else</span> <span class="kc">None</span><span class="p">)[</span><span class="s1">&#39;balance&#39;</span><span class="p">]</span> </span></span><span class="line"><span class="cl"> <span class="nb">print</span><span class="p">(</span><span class="sa">f</span><span class="s2">&#34;New snapshot sees: </span><span class="si">{</span><span class="n">balance_final</span><span class="si">}</span><span class="s2">&#34;</span><span class="p">)</span> <span class="c1"># 900</span> </span></span><span class="line"><span class="cl"> </span></span><span class="line"><span class="cl"><span class="n">asyncio</span><span class="o">.</span><span class="n">run</span><span class="p">(</span><span class="n">demonstrate_snapshot_isolation</span><span class="p">())</span> </span></span></code></pre></div> <h3 id="advanced-mvcc-patterns" class="position-relative d-flex align-items-center group"> <span>Advanced MVCC Patterns</span> <button type="button" class="h-share btn btn-link p-0 text-decoration-none link-secondary opacity-50 hover-opacity-100 transition-all ms-1" data-share-target="advanced-mvcc-patterns" aria-haspopup="dialog" aria-label="Share link: Advanced MVCC Patterns"> <i class="fa-sharp-duotone fa-solid fa-share-nodes" aria-hidden="true" style="font-size: 0.8em;"></i> <span class="visually-hidden">Share link</span> </button> </h3> <h4 id="optimistic-concurrency-control" class="position-relative d-flex align-items-center group"> <span>Optimistic Concurrency Control</span> <button type="button" class="h-share btn btn-link p-0 text-decoration-none link-secondary opacity-50 hover-opacity-100 transition-all ms-1" data-share-target="optimistic-concurrency-control" aria-haspopup="dialog" aria-label="Share link: Optimistic Concurrency Control"> <i class="fa-sharp-duotone fa-solid fa-share-nodes" aria-hidden="true" style="font-size: 0.8em;"></i> <span class="visually-hidden">Share link</span> </button> </h4><div class="highlight"><pre tabindex="0" class="chroma"><code class="language-python" data-lang="python"><span class="line"><span class="cl"><span class="k">class</span> <span class="nc">OptimisticLock</span><span class="p">:</span> </span></span><span class="line"><span class="cl"> <span class="s2">&#34;&#34;&#34;Implement optimistic locking using MVCC.&#34;&#34;&#34;</span> </span></span><span class="line"><span class="cl"> </span></span><span class="line"><span class="cl"> <span class="k">def</span> <span class="fm">__init__</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">client</span><span class="p">):</span> </span></span><span class="line"><span class="cl"> <span class="bp">self</span><span class="o">.</span><span class="n">client</span> <span class="o">=</span> <span class="n">client</span> </span></span><span class="line"><span class="cl"> </span></span><span class="line"><span class="cl"> <span class="k">async</span> <span class="k">def</span> <span class="nf">read_with_version</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">entity_id</span><span class="p">):</span> </span></span><span class="line"><span class="cl"> <span class="s2">&#34;&#34;&#34;Read entity and its current version.&#34;&#34;&#34;</span> </span></span><span class="line"><span class="cl"> <span class="n">result</span><span class="p">,</span> <span class="n">_</span> <span class="o">=</span> <span class="k">await</span> <span class="bp">self</span><span class="o">.</span><span class="n">client</span><span class="o">.</span><span class="n">query</span><span class="p">(</span><span class="s2">&#34;&#34;&#34; </span></span></span><span class="line"><span class="cl"><span class="s2"> MATCH (e:Entity {id: $id}) </span></span></span><span class="line"><span class="cl"><span class="s2"> RETURN e, e.version AS version </span></span></span><span class="line"><span class="cl"><span class="s2"> &#34;&#34;&#34;</span><span class="p">,</span> <span class="p">{</span><span class="s1">&#39;id&#39;</span><span class="p">:</span> <span class="n">entity_id</span><span class="p">})</span> </span></span><span class="line"><span class="cl"> </span></span><span class="line"><span class="cl"> <span class="n">row</span> <span class="o">=</span> <span class="n">result</span><span class="o">.</span><span class="n">rows</span><span class="p">[</span><span class="mi">0</span><span class="p">]</span> <span class="k">if</span> <span class="n">result</span><span class="o">.</span><span class="n">rows</span> <span class="k">else</span> <span class="kc">None</span> </span></span><span class="line"><span class="cl"> <span class="k">return</span> <span class="n">row</span><span class="p">[</span><span class="s1">&#39;e&#39;</span><span class="p">],</span> <span class="n">row</span><span class="p">[</span><span class="s1">&#39;version&#39;</span><span class="p">]</span> </span></span><span class="line"><span class="cl"> </span></span><span class="line"><span class="cl"> <span class="k">async</span> <span class="k">def</span> <span class="nf">update_with_version_check</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">entity_id</span><span class="p">,</span> <span class="n">expected_version</span><span class="p">,</span> <span class="n">updates</span><span class="p">):</span> </span></span><span class="line"><span class="cl"> <span class="s2">&#34;&#34;&#34;Update entity only if version matches.&#34;&#34;&#34;</span> </span></span><span class="line"><span class="cl"> <span class="n">result</span><span class="p">,</span> <span class="n">_</span> <span class="o">=</span> <span class="k">await</span> <span class="bp">self</span><span class="o">.</span><span class="n">client</span><span class="o">.</span><span class="n">query</span><span class="p">(</span><span class="s2">&#34;&#34;&#34; </span></span></span><span class="line"><span class="cl"><span class="s2"> MATCH (e:Entity {id: $id}) </span></span></span><span class="line"><span class="cl"><span class="s2"> WHERE e.version = $expected_version </span></span></span><span class="line"><span class="cl"><span class="s2"> SET e += $updates, </span></span></span><span class="line"><span class="cl"><span class="s2"> e.version = e.version + 1 </span></span></span><span class="line"><span class="cl"><span class="s2"> RETURN e.version AS new_version </span></span></span><span class="line"><span class="cl"><span class="s2"> &#34;&#34;&#34;</span><span class="p">,</span> <span class="p">{</span> </span></span><span class="line"><span class="cl"> <span class="s1">&#39;id&#39;</span><span class="p">:</span> <span class="n">entity_id</span><span class="p">,</span> </span></span><span class="line"><span class="cl"> <span class="s1">&#39;expected_version&#39;</span><span class="p">:</span> <span class="n">expected_version</span><span class="p">,</span> </span></span><span class="line"><span class="cl"> <span class="s1">&#39;updates&#39;</span><span class="p">:</span> <span class="n">updates</span> </span></span><span class="line"><span class="cl"> <span class="p">})</span> </span></span><span class="line"><span class="cl"> </span></span><span class="line"><span class="cl"> <span class="n">row</span> <span class="o">=</span> <span class="n">result</span><span class="o">.</span><span class="n">rows</span><span class="p">[</span><span class="mi">0</span><span class="p">]</span> <span class="k">if</span> <span class="n">result</span><span class="o">.</span><span class="n">rows</span> <span class="k">else</span> <span class="kc">None</span> </span></span><span class="line"><span class="cl"> <span class="k">if</span> <span class="ow">not</span> <span class="n">row</span><span class="p">:</span> </span></span><span class="line"><span class="cl"> <span class="k">raise</span> <span class="n">OptimisticLockException</span><span class="p">(</span><span class="s2">&#34;Version mismatch - entity was modified&#34;</span><span class="p">)</span> </span></span><span class="line"><span class="cl"> </span></span><span class="line"><span class="cl"> <span class="k">return</span> <span class="n">row</span><span class="p">[</span><span class="s1">&#39;new_version&#39;</span><span class="p">]</span> </span></span><span class="line"><span class="cl"> </span></span><span class="line"><span class="cl"><span class="c1"># Usage</span> </span></span><span class="line"><span class="cl"><span class="k">async</span> <span class="k">def</span> <span class="nf">safe_concurrent_update</span><span class="p">():</span> </span></span><span class="line"><span class="cl"> <span class="n">lock</span> <span class="o">=</span> <span class="n">OptimisticLock</span><span class="p">(</span><span class="n">client</span><span class="p">)</span> </span></span><span class="line"><span class="cl"> </span></span><span class="line"><span class="cl"> <span class="c1"># Read current state</span> </span></span><span class="line"><span class="cl"> <span class="n">entity</span><span class="p">,</span> <span class="n">version</span> <span class="o">=</span> <span class="k">await</span> <span class="n">lock</span><span class="o">.</span><span class="n">read_with_version</span><span class="p">(</span><span class="n">entity_id</span><span class="o">=</span><span class="s2">&#34;entity_1&#34;</span><span class="p">)</span> </span></span><span class="line"><span class="cl"> </span></span><span class="line"><span class="cl"> <span class="c1"># Perform business logic</span> </span></span><span class="line"><span class="cl"> <span class="n">new_quantity</span> <span class="o">=</span> <span class="n">entity</span><span class="p">[</span><span class="s1">&#39;quantity&#39;</span><span class="p">]</span> <span class="o">-</span> <span class="mi">5</span> </span></span><span class="line"><span class="cl"> </span></span><span class="line"><span class="cl"> <span class="c1"># Attempt update with version check</span> </span></span><span class="line"><span class="cl"> <span class="k">try</span><span class="p">:</span> </span></span><span class="line"><span class="cl"> <span class="n">new_version</span> <span class="o">=</span> <span class="k">await</span> <span class="n">lock</span><span class="o">.</span><span class="n">update_with_version_check</span><span class="p">(</span> </span></span><span class="line"><span class="cl"> <span class="n">entity_id</span><span class="o">=</span><span class="s2">&#34;entity_1&#34;</span><span class="p">,</span> </span></span><span class="line"><span class="cl"> <span class="n">expected_version</span><span class="o">=</span><span class="n">version</span><span class="p">,</span> </span></span><span class="line"><span class="cl"> <span class="n">updates</span><span class="o">=</span><span class="p">{</span><span class="s1">&#39;quantity&#39;</span><span class="p">:</span> <span class="n">new_quantity</span><span class="p">}</span> </span></span><span class="line"><span class="cl"> <span class="p">)</span> </span></span><span class="line"><span class="cl"> <span class="nb">print</span><span class="p">(</span><span class="sa">f</span><span class="s2">&#34;Updated to version </span><span class="si">{</span><span class="n">new_version</span><span class="si">}</span><span class="s2">&#34;</span><span class="p">)</span> </span></span><span class="line"><span class="cl"> <span class="k">except</span> <span class="n">OptimisticLockException</span><span class="p">:</span> </span></span><span class="line"><span class="cl"> <span class="nb">print</span><span class="p">(</span><span class="s2">&#34;Concurrent modification detected - retry&#34;</span><span class="p">)</span> </span></span></code></pre></div> <h4 id="time-travel-queries-1" class="position-relative d-flex align-items-center group"> <span>Time-Travel Queries</span> <button type="button" class="h-share btn btn-link p-0 text-decoration-none link-secondary opacity-50 hover-opacity-100 transition-all ms-1" data-share-target="time-travel-queries-1" aria-haspopup="dialog" aria-label="Share link: Time-Travel Queries"> <i class="fa-sharp-duotone fa-solid fa-share-nodes" aria-hidden="true" style="font-size: 0.8em;"></i> <span class="visually-hidden">Share link</span> </button> </h4><p>MVCC enables querying historical database states:</p> <div class="highlight"><pre tabindex="0" class="chroma"><code class="language-gql" data-lang="gql"><span class="line"><span class="cl"><span class="err">--</span><span class="w"> </span><span class="py">Query</span><span class="w"> </span><span class="py">database</span><span class="w"> </span><span class="py">as</span><span class="w"> </span><span class="py">it</span><span class="w"> </span><span class="py">existed</span><span class="w"> </span><span class="py">at</span><span class="w"> </span><span class="py">specific</span><span class="w"> </span><span class="py">time</span><span class="w"> </span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="py">BEGIN</span><span class="w"> </span><span class="py">TRANSACTION</span><span class="w"> </span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="py">AS</span><span class="w"> </span><span class="py">OF</span><span class="w"> </span><span class="py">SYSTEM</span><span class="w"> </span><span class="py">TIME</span><span class="w"> </span><span class="err">&#39;</span><span class="py">2025</span><span class="err">-</span><span class="py">01</span><span class="err">-</span><span class="py">01T00</span><span class="p">:</span><span class="nc">00</span><span class="p">:</span><span class="nc">00Z</span><span class="err">&#39;;</span><span class="w"> </span></span></span><span class="line"><span class="cl"><span class="w"> </span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="py">MATCH</span><span class="w"> </span><span class="p">(</span><span class="py">account</span><span class="p">:</span><span class="nc">Account</span><span class="w"> </span><span class="p">{</span><span class="py">id</span><span class="p">:</span><span class="w"> </span><span class="err">&#39;</span><span class="nc">acc_123</span><span class="err">&#39;</span><span class="p">})</span><span class="w"> </span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="py">RETURN</span><span class="w"> </span><span class="py">account</span><span class="err">.</span><span class="py">balance</span><span class="w"> </span><span class="py">AS</span><span class="w"> </span><span class="py">balance_at_jan1</span><span class="err">;</span><span class="w"> </span></span></span><span class="line"><span class="cl"><span class="w"> </span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="py">COMMIT</span><span class="err">;</span><span class="w"> </span></span></span><span class="line"><span class="cl"><span class="w"> </span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="err">--</span><span class="w"> </span><span class="py">Query</span><span class="w"> </span><span class="py">multiple</span><span class="w"> </span><span class="py">historical</span><span class="w"> </span><span class="py">points</span><span class="w"> </span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="py">MATCH</span><span class="w"> </span><span class="p">(</span><span class="py">account</span><span class="p">:</span><span class="nc">Account</span><span class="w"> </span><span class="p">{</span><span class="py">id</span><span class="p">:</span><span class="w"> </span><span class="err">&#39;</span><span class="nc">acc_123</span><span class="err">&#39;</span><span class="p">})</span><span class="w"> </span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="py">WITH</span><span class="w"> </span><span class="py">account</span><span class="err">.</span><span class="py">id</span><span class="w"> </span><span class="py">AS</span><span class="w"> </span><span class="py">account_id</span><span class="w"> </span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="py">UNWIND</span><span class="w"> </span><span class="p">[</span><span class="w"> </span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="err">&#39;</span><span class="py">2025</span><span class="err">-</span><span class="py">01</span><span class="err">-</span><span class="py">01T00</span><span class="p">:</span><span class="nc">00</span><span class="p">:</span><span class="nc">00Z</span><span class="err">&#39;</span><span class="p">,</span><span class="w"> </span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="err">&#39;</span><span class="py">2025</span><span class="err">-</span><span class="py">02</span><span class="err">-</span><span class="py">01T00</span><span class="p">:</span><span class="nc">00</span><span class="p">:</span><span class="nc">00Z</span><span class="err">&#39;</span><span class="p">,</span><span class="w"> </span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="err">&#39;</span><span class="py">2025</span><span class="err">-</span><span class="py">03</span><span class="err">-</span><span class="py">01T00</span><span class="p">:</span><span class="nc">00</span><span class="p">:</span><span class="nc">00Z</span><span class="err">&#39;</span><span class="w"> </span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="p">]</span><span class="w"> </span><span class="py">AS</span><span class="w"> </span><span class="py">timestamp</span><span class="w"> </span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="py">WITH</span><span class="w"> </span><span class="py">account_id</span><span class="p">,</span><span class="w"> </span><span class="py">timestamp</span><span class="w"> </span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="py">CALL</span><span class="w"> </span><span class="p">{</span><span class="w"> </span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="py">BEGIN</span><span class="w"> </span><span class="py">TRANSACTION</span><span class="w"> </span><span class="py">AS</span><span class="w"> </span><span class="py">OF</span><span class="w"> </span><span class="py">SYSTEM</span><span class="w"> </span><span class="py">TIME</span><span class="w"> </span><span class="py">timestamp</span><span class="err">;</span><span class="w"> </span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="py">MATCH</span><span class="w"> </span><span class="p">(</span><span class="py">account</span><span class="p">:</span><span class="nc">Account</span><span class="w"> </span><span class="p">{</span><span class="py">id</span><span class="p">:</span><span class="w"> </span><span class="nc">account_id</span><span class="p">})</span><span class="w"> </span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="py">RETURN</span><span class="w"> </span><span class="py">account</span><span class="err">.</span><span class="py">balance</span><span class="w"> </span><span class="py">AS</span><span class="w"> </span><span class="py">balance</span><span class="err">;</span><span class="w"> </span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="py">COMMIT</span><span class="err">;</span><span class="w"> </span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="p">}</span><span class="w"> </span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="py">RETURN</span><span class="w"> </span><span class="py">timestamp</span><span class="p">,</span><span class="w"> </span><span class="py">balance</span><span class="w"> </span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="py">ORDER</span><span class="w"> </span><span class="py">BY</span><span class="w"> </span><span class="py">timestamp</span><span class="err">;</span><span class="w"> </span></span></span></code></pre></div><div class="highlight"><pre tabindex="0" class="chroma"><code class="language-python" data-lang="python"><span class="line"><span class="cl"><span class="k">async</span> <span class="k">def</span> <span class="nf">historical_balance_report</span><span class="p">(</span><span class="n">account_id</span><span class="p">,</span> <span class="n">start_date</span><span class="p">,</span> <span class="n">end_date</span><span class="p">):</span> </span></span><span class="line"><span class="cl"> <span class="s2">&#34;&#34;&#34;Generate historical balance report using time-travel.&#34;&#34;&#34;</span> </span></span><span class="line"><span class="cl"> </span></span><span class="line"><span class="cl"> <span class="c1"># Generate monthly timestamps</span> </span></span><span class="line"><span class="cl"> <span class="n">timestamps</span> <span class="o">=</span> <span class="n">generate_monthly_timestamps</span><span class="p">(</span><span class="n">start_date</span><span class="p">,</span> <span class="n">end_date</span><span class="p">)</span> </span></span><span class="line"><span class="cl"> </span></span><span class="line"><span class="cl"> <span class="n">balances</span> <span class="o">=</span> <span class="p">[]</span> </span></span><span class="line"><span class="cl"> <span class="k">for</span> <span class="n">ts</span> <span class="ow">in</span> <span class="n">timestamps</span><span class="p">:</span> </span></span><span class="line"><span class="cl"> <span class="n">result</span><span class="p">,</span> <span class="n">_</span> <span class="o">=</span> <span class="k">await</span> <span class="n">client</span><span class="o">.</span><span class="n">query</span><span class="p">(</span><span class="s2">&#34;&#34;&#34; </span></span></span><span class="line"><span class="cl"><span class="s2"> BEGIN TRANSACTION AS OF SYSTEM TIME $timestamp; </span></span></span><span class="line"><span class="cl"><span class="s2"> MATCH (account:Account {id: $account_id}) </span></span></span><span class="line"><span class="cl"><span class="s2"> RETURN account.balance AS balance; </span></span></span><span class="line"><span class="cl"><span class="s2"> COMMIT; </span></span></span><span class="line"><span class="cl"><span class="s2"> &#34;&#34;&#34;</span><span class="p">,</span> <span class="p">{</span><span class="s1">&#39;account_id&#39;</span><span class="p">:</span> <span class="n">account_id</span><span class="p">,</span> <span class="s1">&#39;timestamp&#39;</span><span class="p">:</span> <span class="n">ts</span><span class="p">})</span> </span></span><span class="line"><span class="cl"> </span></span><span class="line"><span class="cl"> <span class="n">row</span> <span class="o">=</span> <span class="n">result</span><span class="o">.</span><span class="n">rows</span><span class="p">[</span><span class="mi">0</span><span class="p">]</span> <span class="k">if</span> <span class="n">result</span><span class="o">.</span><span class="n">rows</span> <span class="k">else</span> <span class="kc">None</span> </span></span><span class="line"><span class="cl"> <span class="n">balances</span><span class="o">.</span><span class="n">append</span><span class="p">({</span> </span></span><span class="line"><span class="cl"> <span class="s1">&#39;timestamp&#39;</span><span class="p">:</span> <span class="n">ts</span><span class="p">,</span> </span></span><span class="line"><span class="cl"> <span class="s1">&#39;balance&#39;</span><span class="p">:</span> <span class="n">row</span><span class="p">[</span><span class="s1">&#39;balance&#39;</span><span class="p">]</span> <span class="k">if</span> <span class="n">row</span> <span class="k">else</span> <span class="kc">None</span> </span></span><span class="line"><span class="cl"> <span class="p">})</span> </span></span><span class="line"><span class="cl"> </span></span><span class="line"><span class="cl"> <span class="k">return</span> <span class="n">balances</span> </span></span></code></pre></div> <h3 id="garbage-collection-strategies" class="position-relative d-flex align-items-center group"> <span>Garbage Collection Strategies</span> <button type="button" class="h-share btn btn-link p-0 text-decoration-none link-secondary opacity-50 hover-opacity-100 transition-all ms-1" data-share-target="garbage-collection-strategies" aria-haspopup="dialog" aria-label="Share link: Garbage Collection Strategies"> <i class="fa-sharp-duotone fa-solid fa-share-nodes" aria-hidden="true" style="font-size: 0.8em;"></i> <span class="visually-hidden">Share link</span> </button> </h3> <h4 id="configurable-gc-policies" class="position-relative d-flex align-items-center group"> <span>Configurable GC Policies</span> <button type="button" class="h-share btn btn-link p-0 text-decoration-none link-secondary opacity-50 hover-opacity-100 transition-all ms-1" data-share-target="configurable-gc-policies" aria-haspopup="dialog" aria-label="Share link: Configurable GC Policies"> <i class="fa-sharp-duotone fa-solid fa-share-nodes" aria-hidden="true" style="font-size: 0.8em;"></i> <span class="visually-hidden">Share link</span> </button> </h4><div class="highlight"><pre tabindex="0" class="chroma"><code class="language-python" data-lang="python"><span class="line"><span class="cl"><span class="k">class</span> <span class="nc">MVCCGarbageCollector</span><span class="p">:</span> </span></span><span class="line"><span class="cl"> <span class="s2">&#34;&#34;&#34;Configure and manage MVCC garbage collection.&#34;&#34;&#34;</span> </span></span><span class="line"><span class="cl"> </span></span><span class="line"><span class="cl"> <span class="k">def</span> <span class="fm">__init__</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">client</span><span class="p">):</span> </span></span><span class="line"><span class="cl"> <span class="bp">self</span><span class="o">.</span><span class="n">client</span> <span class="o">=</span> <span class="n">client</span> </span></span><span class="line"><span class="cl"> </span></span><span class="line"><span class="cl"> <span class="k">async</span> <span class="k">def</span> <span class="nf">set_retention_policy</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">retention_hours</span><span class="p">):</span> </span></span><span class="line"><span class="cl"> <span class="s2">&#34;&#34;&#34;Set how long to retain old versions.&#34;&#34;&#34;</span> </span></span><span class="line"><span class="cl"> <span class="k">await</span> <span class="bp">self</span><span class="o">.</span><span class="n">client</span><span class="o">.</span><span class="n">execute</span><span class="p">(</span><span class="s2">&#34;&#34;&#34; </span></span></span><span class="line"><span class="cl"><span class="s2"> CALL dbms.mvcc.setRetentionPolicy($hours) </span></span></span><span class="line"><span class="cl"><span class="s2"> &#34;&#34;&#34;</span><span class="p">,</span> <span class="p">{</span><span class="s1">&#39;hours&#39;</span><span class="p">:</span> <span class="n">retention_hours</span><span class="p">})</span> </span></span><span class="line"><span class="cl"> </span></span><span class="line"><span class="cl"> <span class="k">async</span> <span class="k">def</span> <span class="nf">run_gc_manually</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span> </span></span><span class="line"><span class="cl"> <span class="s2">&#34;&#34;&#34;Trigger manual garbage collection.&#34;&#34;&#34;</span> </span></span><span class="line"><span class="cl"> <span class="n">result</span><span class="p">,</span> <span class="n">_</span> <span class="o">=</span> <span class="k">await</span> <span class="bp">self</span><span class="o">.</span><span class="n">client</span><span class="o">.</span><span class="n">query</span><span class="p">(</span><span class="s2">&#34;&#34;&#34; </span></span></span><span class="line"><span class="cl"><span class="s2"> CALL dbms.mvcc.garbageCollect() </span></span></span><span class="line"><span class="cl"><span class="s2"> YIELD versionsReclaimed, bytesFreed </span></span></span><span class="line"><span class="cl"><span class="s2"> RETURN versionsReclaimed, bytesFreed </span></span></span><span class="line"><span class="cl"><span class="s2"> &#34;&#34;&#34;</span><span class="p">)</span> </span></span><span class="line"><span class="cl"> </span></span><span class="line"><span class="cl"> <span class="n">stats</span> <span class="o">=</span> <span class="n">result</span><span class="o">.</span><span class="n">rows</span><span class="p">[</span><span class="mi">0</span><span class="p">]</span> <span class="k">if</span> <span class="n">result</span><span class="o">.</span><span class="n">rows</span> <span class="k">else</span> <span class="kc">None</span> </span></span><span class="line"><span class="cl"> <span class="k">return</span> <span class="n">stats</span> </span></span><span class="line"><span class="cl"> </span></span><span class="line"><span class="cl"> <span class="k">async</span> <span class="k">def</span> <span class="nf">get_gc_stats</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span> </span></span><span class="line"><span class="cl"> <span class="s2">&#34;&#34;&#34;Get garbage collection statistics.&#34;&#34;&#34;</span> </span></span><span class="line"><span class="cl"> <span class="n">result</span><span class="p">,</span> <span class="n">_</span> <span class="o">=</span> <span class="k">await</span> <span class="bp">self</span><span class="o">.</span><span class="n">client</span><span class="o">.</span><span class="n">query</span><span class="p">(</span><span class="s2">&#34;&#34;&#34; </span></span></span><span class="line"><span class="cl"><span class="s2"> CALL dbms.mvcc.stats() </span></span></span><span class="line"><span class="cl"><span class="s2"> YIELD metric, value </span></span></span><span class="line"><span class="cl"><span class="s2"> RETURN metric, value </span></span></span><span class="line"><span class="cl"><span class="s2"> &#34;&#34;&#34;</span><span class="p">)</span> </span></span><span class="line"><span class="cl"> </span></span><span class="line"><span class="cl"> <span class="k">return</span> <span class="p">{</span><span class="n">row</span><span class="p">[</span><span class="s1">&#39;metric&#39;</span><span class="p">]:</span> <span class="n">row</span><span class="p">[</span><span class="s1">&#39;value&#39;</span><span class="p">]</span> <span class="k">for</span> <span class="n">row</span> <span class="ow">in</span> <span class="n">result</span><span class="o">.</span><span class="n">rows</span><span class="p">}</span> </span></span><span class="line"><span class="cl"> </span></span><span class="line"><span class="cl"><span class="c1"># Usage</span> </span></span><span class="line"><span class="cl"><span class="k">async</span> <span class="k">def</span> <span class="nf">manage_storage</span><span class="p">():</span> </span></span><span class="line"><span class="cl"> <span class="n">gc</span> <span class="o">=</span> <span class="n">MVCCGarbageCollector</span><span class="p">(</span><span class="n">client</span><span class="p">)</span> </span></span><span class="line"><span class="cl"> </span></span><span class="line"><span class="cl"> <span class="c1"># Set 24-hour retention</span> </span></span><span class="line"><span class="cl"> <span class="k">await</span> <span class="n">gc</span><span class="o">.</span><span class="n">set_retention_policy</span><span class="p">(</span><span class="n">retention_hours</span><span class="o">=</span><span class="mi">24</span><span class="p">)</span> </span></span><span class="line"><span class="cl"> </span></span><span class="line"><span class="cl"> <span class="c1"># Run GC and get stats</span> </span></span><span class="line"><span class="cl"> <span class="n">stats</span> <span class="o">=</span> <span class="k">await</span> <span class="n">gc</span><span class="o">.</span><span class="n">run_gc_manually</span><span class="p">()</span> </span></span><span class="line"><span class="cl"> <span class="nb">print</span><span class="p">(</span><span class="sa">f</span><span class="s2">&#34;Reclaimed </span><span class="si">{</span><span class="n">stats</span><span class="p">[</span><span class="s1">&#39;versionsReclaimed&#39;</span><span class="p">]</span><span class="si">}</span><span class="s2"> versions&#34;</span><span class="p">)</span> </span></span><span class="line"><span class="cl"> <span class="nb">print</span><span class="p">(</span><span class="sa">f</span><span class="s2">&#34;Freed </span><span class="si">{</span><span class="n">stats</span><span class="p">[</span><span class="s1">&#39;bytesFreed&#39;</span><span class="p">]</span> <span class="o">/</span> <span class="mi">1024</span> <span class="o">/</span> <span class="mi">1024</span><span class="si">:</span><span class="s2">.2f</span><span class="si">}</span><span class="s2"> MB&#34;</span><span class="p">)</span> </span></span><span class="line"><span class="cl"> </span></span><span class="line"><span class="cl"> <span class="c1"># Monitor GC health</span> </span></span><span class="line"><span class="cl"> <span class="n">gc_stats</span> <span class="o">=</span> <span class="k">await</span> <span class="n">gc</span><span class="o">.</span><span class="n">get_gc_stats</span><span class="p">()</span> </span></span><span class="line"><span class="cl"> <span class="nb">print</span><span class="p">(</span><span class="sa">f</span><span class="s2">&#34;Average version chain length: </span><span class="si">{</span><span class="n">gc_stats</span><span class="p">[</span><span class="s1">&#39;avg_chain_length&#39;</span><span class="p">]</span><span class="si">}</span><span class="s2">&#34;</span><span class="p">)</span> </span></span><span class="line"><span class="cl"> <span class="nb">print</span><span class="p">(</span><span class="sa">f</span><span class="s2">&#34;Oldest active snapshot age: </span><span class="si">{</span><span class="n">gc_stats</span><span class="p">[</span><span class="s1">&#39;oldest_snapshot_age_seconds&#39;</span><span class="p">]</span><span class="si">}</span><span class="s2">s&#34;</span><span class="p">)</span> </span></span></code></pre></div> <h4 id="aggressive-vs-conservative-gc" class="position-relative d-flex align-items-center group"> <span>Aggressive vs. Conservative GC</span> <button type="button" class="h-share btn btn-link p-0 text-decoration-none link-secondary opacity-50 hover-opacity-100 transition-all ms-1" data-share-target="aggressive-vs-conservative-gc" aria-haspopup="dialog" aria-label="Share link: Aggressive vs. Conservative GC"> <i class="fa-sharp-duotone fa-solid fa-share-nodes" aria-hidden="true" style="font-size: 0.8em;"></i> <span class="visually-hidden">Share link</span> </button> </h4><div class="highlight"><pre tabindex="0" class="chroma"><code class="language-python" data-lang="python"><span class="line"><span class="cl"><span class="c1"># Conservative: Keep more history (better for time-travel)</span> </span></span><span class="line"><span class="cl"><span class="k">await</span> <span class="n">client</span><span class="o">.</span><span class="n">execute</span><span class="p">(</span><span class="s2">&#34;&#34;&#34; </span></span></span><span class="line"><span class="cl"><span class="s2"> CALL dbms.mvcc.configure({ </span></span></span><span class="line"><span class="cl"><span class="s2"> retention_hours: 168, // 1 week </span></span></span><span class="line"><span class="cl"><span class="s2"> gc_frequency_minutes: 60, </span></span></span><span class="line"><span class="cl"><span class="s2"> max_chain_length: 100 </span></span></span><span class="line"><span class="cl"><span class="s2"> }) </span></span></span><span class="line"><span class="cl"><span class="s2">&#34;&#34;&#34;</span><span class="p">)</span> </span></span><span class="line"><span class="cl"> </span></span><span class="line"><span class="cl"><span class="c1"># Aggressive: Minimize storage (faster queries)</span> </span></span><span class="line"><span class="cl"><span class="k">await</span> <span class="n">client</span><span class="o">.</span><span class="n">execute</span><span class="p">(</span><span class="s2">&#34;&#34;&#34; </span></span></span><span class="line"><span class="cl"><span class="s2"> CALL dbms.mvcc.configure({ </span></span></span><span class="line"><span class="cl"><span class="s2"> retention_hours: 1, </span></span></span><span class="line"><span class="cl"><span class="s2"> gc_frequency_minutes: 5, </span></span></span><span class="line"><span class="cl"><span class="s2"> max_chain_length: 10 </span></span></span><span class="line"><span class="cl"><span class="s2"> }) </span></span></span><span class="line"><span class="cl"><span class="s2">&#34;&#34;&#34;</span><span class="p">)</span> </span></span></code></pre></div> <h3 id="performance-monitoring" class="position-relative d-flex align-items-center group"> <span>Performance Monitoring</span> <button type="button" class="h-share btn btn-link p-0 text-decoration-none link-secondary opacity-50 hover-opacity-100 transition-all ms-1" data-share-target="performance-monitoring" aria-haspopup="dialog" aria-label="Share link: Performance Monitoring"> <i class="fa-sharp-duotone fa-solid fa-share-nodes" aria-hidden="true" style="font-size: 0.8em;"></i> <span class="visually-hidden">Share link</span> </button> </h3> <h4 id="mvcc-performance-metrics" class="position-relative d-flex align-items-center group"> <span>MVCC Performance Metrics</span> <button type="button" class="h-share btn btn-link p-0 text-decoration-none link-secondary opacity-50 hover-opacity-100 transition-all ms-1" data-share-target="mvcc-performance-metrics" aria-haspopup="dialog" aria-label="Share link: MVCC Performance Metrics"> <i class="fa-sharp-duotone fa-solid fa-share-nodes" aria-hidden="true" style="font-size: 0.8em;"></i> <span class="visually-hidden">Share link</span> </button> </h4><div class="highlight"><pre tabindex="0" class="chroma"><code class="language-python" data-lang="python"><span class="line"><span class="cl"><span class="kn">from</span> <span class="nn">prometheus_client</span> <span class="kn">import</span> <span class="n">Gauge</span><span class="p">,</span> <span class="n">Histogram</span> </span></span><span class="line"><span class="cl"> </span></span><span class="line"><span class="cl"><span class="c1"># Define metrics</span> </span></span><span class="line"><span class="cl"><span class="n">version_chain_length</span> <span class="o">=</span> <span class="n">Histogram</span><span class="p">(</span> </span></span><span class="line"><span class="cl"> <span class="s1">&#39;geode_mvcc_version_chain_length&#39;</span><span class="p">,</span> </span></span><span class="line"><span class="cl"> <span class="s1">&#39;Length of version chains&#39;</span><span class="p">,</span> </span></span><span class="line"><span class="cl"> <span class="n">buckets</span><span class="o">=</span><span class="p">[</span><span class="mi">1</span><span class="p">,</span> <span class="mi">5</span><span class="p">,</span> <span class="mi">10</span><span class="p">,</span> <span class="mi">25</span><span class="p">,</span> <span class="mi">50</span><span class="p">,</span> <span class="mi">100</span><span class="p">,</span> <span class="mi">250</span><span class="p">]</span> </span></span><span class="line"><span class="cl"><span class="p">)</span> </span></span><span class="line"><span class="cl"> </span></span><span class="line"><span class="cl"><span class="n">active_snapshots</span> <span class="o">=</span> <span class="n">Gauge</span><span class="p">(</span> </span></span><span class="line"><span class="cl"> <span class="s1">&#39;geode_mvcc_active_snapshots&#39;</span><span class="p">,</span> </span></span><span class="line"><span class="cl"> <span class="s1">&#39;Number of active snapshots&#39;</span> </span></span><span class="line"><span class="cl"><span class="p">)</span> </span></span><span class="line"><span class="cl"> </span></span><span class="line"><span class="cl"><span class="n">gc_reclaimed_versions</span> <span class="o">=</span> <span class="n">Counter</span><span class="p">(</span> </span></span><span class="line"><span class="cl"> <span class="s1">&#39;geode_mvcc_gc_reclaimed_versions_total&#39;</span><span class="p">,</span> </span></span><span class="line"><span class="cl"> <span class="s1">&#39;Total versions reclaimed by GC&#39;</span> </span></span><span class="line"><span class="cl"><span class="p">)</span> </span></span><span class="line"><span class="cl"> </span></span><span class="line"><span class="cl"><span class="k">async</span> <span class="k">def</span> <span class="nf">collect_mvcc_metrics</span><span class="p">():</span> </span></span><span class="line"><span class="cl"> <span class="s2">&#34;&#34;&#34;Collect and export MVCC metrics.&#34;&#34;&#34;</span> </span></span><span class="line"><span class="cl"> <span class="n">stats</span><span class="p">,</span> <span class="n">_</span> <span class="o">=</span> <span class="k">await</span> <span class="n">client</span><span class="o">.</span><span class="n">query</span><span class="p">(</span><span class="s2">&#34;&#34;&#34; </span></span></span><span class="line"><span class="cl"><span class="s2"> CALL dbms.mvcc.detailedStats() </span></span></span><span class="line"><span class="cl"><span class="s2"> YIELD metric, value </span></span></span><span class="line"><span class="cl"><span class="s2"> RETURN metric, value </span></span></span><span class="line"><span class="cl"><span class="s2"> &#34;&#34;&#34;</span><span class="p">)</span> </span></span><span class="line"><span class="cl"> </span></span><span class="line"><span class="cl"> <span class="k">for</span> <span class="n">row</span> <span class="ow">in</span> <span class="n">stats</span><span class="o">.</span><span class="n">rows</span><span class="p">:</span> </span></span><span class="line"><span class="cl"> <span class="n">metric</span> <span class="o">=</span> <span class="n">row</span><span class="p">[</span><span class="s1">&#39;metric&#39;</span><span class="p">]</span> </span></span><span class="line"><span class="cl"> <span class="n">value</span> <span class="o">=</span> <span class="n">row</span><span class="p">[</span><span class="s1">&#39;value&#39;</span><span class="p">]</span> </span></span><span class="line"><span class="cl"> </span></span><span class="line"><span class="cl"> <span class="k">if</span> <span class="n">metric</span> <span class="o">==</span> <span class="s1">&#39;avg_version_chain_length&#39;</span><span class="p">:</span> </span></span><span class="line"><span class="cl"> <span class="n">version_chain_length</span><span class="o">.</span><span class="n">observe</span><span class="p">(</span><span class="n">value</span><span class="p">)</span> </span></span><span class="line"><span class="cl"> <span class="k">elif</span> <span class="n">metric</span> <span class="o">==</span> <span class="s1">&#39;active_snapshots&#39;</span><span class="p">:</span> </span></span><span class="line"><span class="cl"> <span class="n">active_snapshots</span><span class="o">.</span><span class="n">set</span><span class="p">(</span><span class="n">value</span><span class="p">)</span> </span></span><span class="line"><span class="cl"> <span class="k">elif</span> <span class="n">metric</span> <span class="o">==</span> <span class="s1">&#39;gc_reclaimed_versions&#39;</span><span class="p">:</span> </span></span><span class="line"><span class="cl"> <span class="n">gc_reclaimed_versions</span><span class="o">.</span><span class="n">inc</span><span class="p">(</span><span class="n">value</span><span class="p">)</span> </span></span></code></pre></div> <h4 id="identifying-performance-bottlenecks" class="position-relative d-flex align-items-center group"> <span>Identifying Performance Bottlenecks</span> <button type="button" class="h-share btn btn-link p-0 text-decoration-none link-secondary opacity-50 hover-opacity-100 transition-all ms-1" data-share-target="identifying-performance-bottlenecks" aria-haspopup="dialog" aria-label="Share link: Identifying Performance Bottlenecks"> <i class="fa-sharp-duotone fa-solid fa-share-nodes" aria-hidden="true" style="font-size: 0.8em;"></i> <span class="visually-hidden">Share link</span> </button> </h4><div class="highlight"><pre tabindex="0" class="chroma"><code class="language-python" data-lang="python"><span class="line"><span class="cl"><span class="k">async</span> <span class="k">def</span> <span class="nf">diagnose_mvcc_issues</span><span class="p">():</span> </span></span><span class="line"><span class="cl"> <span class="s2">&#34;&#34;&#34;Diagnose MVCC-related performance issues.&#34;&#34;&#34;</span> </span></span><span class="line"><span class="cl"> </span></span><span class="line"><span class="cl"> <span class="c1"># Check for long version chains</span> </span></span><span class="line"><span class="cl"> <span class="n">result</span><span class="p">,</span> <span class="n">_</span> <span class="o">=</span> <span class="k">await</span> <span class="n">client</span><span class="o">.</span><span class="n">query</span><span class="p">(</span><span class="s2">&#34;&#34;&#34; </span></span></span><span class="line"><span class="cl"><span class="s2"> CALL dbms.mvcc.versionChainStats() </span></span></span><span class="line"><span class="cl"><span class="s2"> YIELD nodeId, chainLength </span></span></span><span class="line"><span class="cl"><span class="s2"> WHERE chainLength &gt; 50 </span></span></span><span class="line"><span class="cl"><span class="s2"> RETURN nodeId, chainLength </span></span></span><span class="line"><span class="cl"><span class="s2"> ORDER BY chainLength DESC </span></span></span><span class="line"><span class="cl"><span class="s2"> LIMIT 10 </span></span></span><span class="line"><span class="cl"><span class="s2"> &#34;&#34;&#34;</span><span class="p">)</span> </span></span><span class="line"><span class="cl"> </span></span><span class="line"><span class="cl"> <span class="n">long_chains</span> <span class="o">=</span> <span class="p">[</span><span class="n">row</span> <span class="k">for</span> <span class="n">row</span> <span class="ow">in</span> <span class="n">result</span><span class="o">.</span><span class="n">rows</span><span class="p">]</span> </span></span><span class="line"><span class="cl"> <span class="k">if</span> <span class="n">long_chains</span><span class="p">:</span> </span></span><span class="line"><span class="cl"> <span class="nb">print</span><span class="p">(</span><span class="s2">&#34;WARNING: Long version chains detected&#34;</span><span class="p">)</span> </span></span><span class="line"><span class="cl"> <span class="k">for</span> <span class="n">chain</span> <span class="ow">in</span> <span class="n">long_chains</span><span class="p">:</span> </span></span><span class="line"><span class="cl"> <span class="nb">print</span><span class="p">(</span><span class="sa">f</span><span class="s2">&#34; Node </span><span class="si">{</span><span class="n">chain</span><span class="p">[</span><span class="s1">&#39;nodeId&#39;</span><span class="p">]</span><span class="si">}</span><span class="s2">: </span><span class="si">{</span><span class="n">chain</span><span class="p">[</span><span class="s1">&#39;chainLength&#39;</span><span class="p">]</span><span class="si">}</span><span class="s2"> versions&#34;</span><span class="p">)</span> </span></span><span class="line"><span class="cl"> <span class="nb">print</span><span class="p">(</span><span class="s2">&#34;Recommendation: Increase GC frequency or reduce update rate&#34;</span><span class="p">)</span> </span></span><span class="line"><span class="cl"> </span></span><span class="line"><span class="cl"> <span class="c1"># Check for old snapshots blocking GC</span> </span></span><span class="line"><span class="cl"> <span class="n">result</span><span class="p">,</span> <span class="n">_</span> <span class="o">=</span> <span class="k">await</span> <span class="n">client</span><span class="o">.</span><span class="n">query</span><span class="p">(</span><span class="s2">&#34;&#34;&#34; </span></span></span><span class="line"><span class="cl"><span class="s2"> CALL dbms.transactions.list() </span></span></span><span class="line"><span class="cl"><span class="s2"> YIELD transactionId, startTime </span></span></span><span class="line"><span class="cl"><span class="s2"> WHERE duration.between(startTime, datetime()) &gt; duration(&#39;PT5M&#39;) </span></span></span><span class="line"><span class="cl"><span class="s2"> RETURN transactionId, startTime </span></span></span><span class="line"><span class="cl"><span class="s2"> &#34;&#34;&#34;</span><span class="p">)</span> </span></span><span class="line"><span class="cl"> </span></span><span class="line"><span class="cl"> <span class="n">old_txs</span> <span class="o">=</span> <span class="p">[</span><span class="n">row</span> <span class="k">for</span> <span class="n">row</span> <span class="ow">in</span> <span class="n">result</span><span class="o">.</span><span class="n">rows</span><span class="p">]</span> </span></span><span class="line"><span class="cl"> <span class="k">if</span> <span class="n">old_txs</span><span class="p">:</span> </span></span><span class="line"><span class="cl"> <span class="nb">print</span><span class="p">(</span><span class="s2">&#34;WARNING: Long-running transactions blocking GC&#34;</span><span class="p">)</span> </span></span><span class="line"><span class="cl"> <span class="k">for</span> <span class="n">tx</span> <span class="ow">in</span> <span class="n">old_txs</span><span class="p">:</span> </span></span><span class="line"><span class="cl"> <span class="nb">print</span><span class="p">(</span><span class="sa">f</span><span class="s2">&#34; Transaction </span><span class="si">{</span><span class="n">tx</span><span class="p">[</span><span class="s1">&#39;transactionId&#39;</span><span class="p">]</span><span class="si">}</span><span class="s2">&#34;</span><span class="p">)</span> </span></span><span class="line"><span class="cl"> <span class="nb">print</span><span class="p">(</span><span class="sa">f</span><span class="s2">&#34; Started: </span><span class="si">{</span><span class="n">tx</span><span class="p">[</span><span class="s1">&#39;startTime&#39;</span><span class="p">]</span><span class="si">}</span><span class="s2">&#34;</span><span class="p">)</span> </span></span><span class="line"><span class="cl"> <span class="nb">print</span><span class="p">(</span><span class="s2">&#34;Recommendation: Terminate or shorten these transactions&#34;</span><span class="p">)</span> </span></span></code></pre></div> <h3 id="distributed-mvcc" class="position-relative d-flex align-items-center group"> <span>Distributed MVCC</span> <button type="button" class="h-share btn btn-link p-0 text-decoration-none link-secondary opacity-50 hover-opacity-100 transition-all ms-1" data-share-target="distributed-mvcc" aria-haspopup="dialog" aria-label="Share link: Distributed MVCC"> <i class="fa-sharp-duotone fa-solid fa-share-nodes" aria-hidden="true" style="font-size: 0.8em;"></i> <span class="visually-hidden">Share link</span> </button> </h3> <h4 id="multi-node-version-coordination" class="position-relative d-flex align-items-center group"> <span>Multi-Node Version Coordination</span> <button type="button" class="h-share btn btn-link p-0 text-decoration-none link-secondary opacity-50 hover-opacity-100 transition-all ms-1" data-share-target="multi-node-version-coordination" aria-haspopup="dialog" aria-label="Share link: Multi-Node Version Coordination"> <i class="fa-sharp-duotone fa-solid fa-share-nodes" aria-hidden="true" style="font-size: 0.8em;"></i> <span class="visually-hidden">Share link</span> </button> </h4><div class="highlight"><pre tabindex="0" class="chroma"><code class="language-python" data-lang="python"><span class="line"><span class="cl"><span class="k">class</span> <span class="nc">DistributedMVCC</span><span class="p">:</span> </span></span><span class="line"><span class="cl"> <span class="s2">&#34;&#34;&#34;Coordinate MVCC across multiple nodes.&#34;&#34;&#34;</span> </span></span><span class="line"><span class="cl"> </span></span><span class="line"><span class="cl"> <span class="k">def</span> <span class="fm">__init__</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">nodes</span><span class="p">):</span> </span></span><span class="line"><span class="cl"> <span class="bp">self</span><span class="o">.</span><span class="n">nodes</span> <span class="o">=</span> <span class="n">nodes</span> </span></span><span class="line"><span class="cl"> <span class="bp">self</span><span class="o">.</span><span class="n">clock</span> <span class="o">=</span> <span class="n">HybridLogicalClock</span><span class="p">()</span> </span></span><span class="line"><span class="cl"> </span></span><span class="line"><span class="cl"> <span class="k">async</span> <span class="k">def</span> <span class="nf">begin_distributed_transaction</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span> </span></span><span class="line"><span class="cl"> <span class="s2">&#34;&#34;&#34;Start transaction across all nodes with synchronized snapshot.&#34;&#34;&#34;</span> </span></span><span class="line"><span class="cl"> </span></span><span class="line"><span class="cl"> <span class="c1"># Get synchronized timestamp from all nodes</span> </span></span><span class="line"><span class="cl"> <span class="n">timestamps</span> <span class="o">=</span> <span class="p">[]</span> </span></span><span class="line"><span class="cl"> <span class="k">for</span> <span class="n">node</span> <span class="ow">in</span> <span class="bp">self</span><span class="o">.</span><span class="n">nodes</span><span class="p">:</span> </span></span><span class="line"><span class="cl"> <span class="n">ts</span> <span class="o">=</span> <span class="k">await</span> <span class="n">node</span><span class="o">.</span><span class="n">get_current_timestamp</span><span class="p">()</span> </span></span><span class="line"><span class="cl"> <span class="n">timestamps</span><span class="o">.</span><span class="n">append</span><span class="p">(</span><span class="n">ts</span><span class="p">)</span> </span></span><span class="line"><span class="cl"> </span></span><span class="line"><span class="cl"> <span class="c1"># Use maximum timestamp to ensure consistent snapshot</span> </span></span><span class="line"><span class="cl"> <span class="n">snapshot_timestamp</span> <span class="o">=</span> <span class="nb">max</span><span class="p">(</span><span class="n">timestamps</span><span class="p">)</span> </span></span><span class="line"><span class="cl"> </span></span><span class="line"><span class="cl"> <span class="c1"># Begin transaction on all nodes with same snapshot</span> </span></span><span class="line"><span class="cl"> <span class="n">transactions</span> <span class="o">=</span> <span class="p">[]</span> </span></span><span class="line"><span class="cl"> <span class="k">for</span> <span class="n">node</span> <span class="ow">in</span> <span class="bp">self</span><span class="o">.</span><span class="n">nodes</span><span class="p">:</span> </span></span><span class="line"><span class="cl"> <span class="n">tx</span> <span class="o">=</span> <span class="k">await</span> <span class="n">node</span><span class="o">.</span><span class="n">begin</span><span class="p">(</span><span class="n">snapshot_timestamp</span><span class="p">)</span> </span></span><span class="line"><span class="cl"> <span class="n">transactions</span><span class="o">.</span><span class="n">append</span><span class="p">(</span><span class="n">tx</span><span class="p">)</span> </span></span><span class="line"><span class="cl"> </span></span><span class="line"><span class="cl"> <span class="k">return</span> <span class="n">DistributedTransaction</span><span class="p">(</span><span class="n">transactions</span><span class="p">,</span> <span class="n">snapshot_timestamp</span><span class="p">)</span> </span></span><span class="line"><span class="cl"> </span></span><span class="line"><span class="cl"><span class="k">class</span> <span class="nc">HybridLogicalClock</span><span class="p">:</span> </span></span><span class="line"><span class="cl"> <span class="s2">&#34;&#34;&#34;Hybrid logical clock for distributed timestamp coordination.&#34;&#34;&#34;</span> </span></span><span class="line"><span class="cl"> </span></span><span class="line"><span class="cl"> <span class="k">def</span> <span class="fm">__init__</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span> </span></span><span class="line"><span class="cl"> <span class="bp">self</span><span class="o">.</span><span class="n">logical_time</span> <span class="o">=</span> <span class="mi">0</span> </span></span><span class="line"><span class="cl"> <span class="bp">self</span><span class="o">.</span><span class="n">physical_time</span> <span class="o">=</span> <span class="mi">0</span> </span></span><span class="line"><span class="cl"> </span></span><span class="line"><span class="cl"> <span class="k">def</span> <span class="nf">now</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span> </span></span><span class="line"><span class="cl"> <span class="s2">&#34;&#34;&#34;Get current HLC timestamp.&#34;&#34;&#34;</span> </span></span><span class="line"><span class="cl"> <span class="n">current_physical</span> <span class="o">=</span> <span class="n">time</span><span class="o">.</span><span class="n">time_ns</span><span class="p">()</span> </span></span><span class="line"><span class="cl"> </span></span><span class="line"><span class="cl"> <span class="k">if</span> <span class="n">current_physical</span> <span class="o">&gt;</span> <span class="bp">self</span><span class="o">.</span><span class="n">physical_time</span><span class="p">:</span> </span></span><span class="line"><span class="cl"> <span class="bp">self</span><span class="o">.</span><span class="n">physical_time</span> <span class="o">=</span> <span class="n">current_physical</span> </span></span><span class="line"><span class="cl"> <span class="bp">self</span><span class="o">.</span><span class="n">logical_time</span> <span class="o">=</span> <span class="mi">0</span> </span></span><span class="line"><span class="cl"> <span class="k">else</span><span class="p">:</span> </span></span><span class="line"><span class="cl"> <span class="bp">self</span><span class="o">.</span><span class="n">logical_time</span> <span class="o">+=</span> <span class="mi">1</span> </span></span><span class="line"><span class="cl"> </span></span><span class="line"><span class="cl"> <span class="k">return</span> <span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">physical_time</span><span class="p">,</span> <span class="bp">self</span><span class="o">.</span><span class="n">logical_time</span><span class="p">)</span> </span></span><span class="line"><span class="cl"> </span></span><span class="line"><span class="cl"> <span class="k">def</span> <span class="nf">update</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">remote_timestamp</span><span class="p">):</span> </span></span><span class="line"><span class="cl"> <span class="s2">&#34;&#34;&#34;Update clock based on received timestamp.&#34;&#34;&#34;</span> </span></span><span class="line"><span class="cl"> <span class="n">remote_physical</span><span class="p">,</span> <span class="n">remote_logical</span> <span class="o">=</span> <span class="n">remote_timestamp</span> </span></span><span class="line"><span class="cl"> <span class="n">current_physical</span> <span class="o">=</span> <span class="n">time</span><span class="o">.</span><span class="n">time_ns</span><span class="p">()</span> </span></span><span class="line"><span class="cl"> </span></span><span class="line"><span class="cl"> <span class="bp">self</span><span class="o">.</span><span class="n">physical_time</span> <span class="o">=</span> <span class="nb">max</span><span class="p">(</span><span class="n">current_physical</span><span class="p">,</span> <span class="n">remote_physical</span><span class="p">,</span> <span class="bp">self</span><span class="o">.</span><span class="n">physical_time</span><span class="p">)</span> </span></span><span class="line"><span class="cl"> </span></span><span class="line"><span class="cl"> <span class="k">if</span> <span class="bp">self</span><span class="o">.</span><span class="n">physical_time</span> <span class="o">==</span> <span class="n">remote_physical</span><span class="p">:</span> </span></span><span class="line"><span class="cl"> <span class="bp">self</span><span class="o">.</span><span class="n">logical_time</span> <span class="o">=</span> <span class="nb">max</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">logical_time</span><span class="p">,</span> <span class="n">remote_logical</span><span class="p">)</span> <span class="o">+</span> <span class="mi">1</span> </span></span><span class="line"><span class="cl"> <span class="k">elif</span> <span class="bp">self</span><span class="o">.</span><span class="n">physical_time</span> <span class="o">==</span> <span class="n">current_physical</span><span class="p">:</span> </span></span><span class="line"><span class="cl"> <span class="bp">self</span><span class="o">.</span><span class="n">logical_time</span> <span class="o">+=</span> <span class="mi">1</span> </span></span><span class="line"><span class="cl"> <span class="k">else</span><span class="p">:</span> </span></span><span class="line"><span class="cl"> <span class="bp">self</span><span class="o">.</span><span class="n">logical_time</span> <span class="o">=</span> <span class="mi">0</span> </span></span><span class="line"><span class="cl"> </span></span><span class="line"><span class="cl"> <span class="k">return</span> <span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">physical_time</span><span class="p">,</span> <span class="bp">self</span><span class="o">.</span><span class="n">logical_time</span><span class="p">)</span> </span></span></code></pre></div> <h3 id="troubleshooting-mvcc-issues" class="position-relative d-flex align-items-center group"> <span>Troubleshooting MVCC Issues</span> <button type="button" class="h-share btn btn-link p-0 text-decoration-none link-secondary opacity-50 hover-opacity-100 transition-all ms-1" data-share-target="troubleshooting-mvcc-issues" aria-haspopup="dialog" aria-label="Share link: Troubleshooting MVCC Issues"> <i class="fa-sharp-duotone fa-solid fa-share-nodes" aria-hidden="true" style="font-size: 0.8em;"></i> <span class="visually-hidden">Share link</span> </button> </h3> <h4 id="issue-version-chain-bloat" class="position-relative d-flex align-items-center group"> <span>Issue: Version Chain Bloat</span> <button type="button" class="h-share btn btn-link p-0 text-decoration-none link-secondary opacity-50 hover-opacity-100 transition-all ms-1" data-share-target="issue-version-chain-bloat" aria-haspopup="dialog" aria-label="Share link: Issue: Version Chain Bloat"> <i class="fa-sharp-duotone fa-solid fa-share-nodes" aria-hidden="true" style="font-size: 0.8em;"></i> <span class="visually-hidden">Share link</span> </button> </h4><p><strong>Symptom</strong>: Queries slow down over time on frequently updated entities</p> <p><strong>Diagnosis</strong>:</p> <div class="highlight"><pre tabindex="0" class="chroma"><code class="language-python" data-lang="python"><span class="line"><span class="cl"><span class="k">async</span> <span class="k">def</span> <span class="nf">find_bloated_chains</span><span class="p">():</span> </span></span><span class="line"><span class="cl"> <span class="n">result</span><span class="p">,</span> <span class="n">_</span> <span class="o">=</span> <span class="k">await</span> <span class="n">client</span><span class="o">.</span><span class="n">query</span><span class="p">(</span><span class="s2">&#34;&#34;&#34; </span></span></span><span class="line"><span class="cl"><span class="s2"> CALL dbms.mvcc.analyzeChains() </span></span></span><span class="line"><span class="cl"><span class="s2"> YIELD entityId, entityType, chainLength, storageBytes </span></span></span><span class="line"><span class="cl"><span class="s2"> WHERE chainLength &gt; 100 </span></span></span><span class="line"><span class="cl"><span class="s2"> RETURN entityId, entityType, chainLength, storageBytes </span></span></span><span class="line"><span class="cl"><span class="s2"> ORDER BY chainLength DESC </span></span></span><span class="line"><span class="cl"><span class="s2"> &#34;&#34;&#34;</span><span class="p">)</span> </span></span><span class="line"><span class="cl"> </span></span><span class="line"><span class="cl"> <span class="k">return</span> <span class="p">[</span><span class="n">row</span> <span class="k">for</span> <span class="n">row</span> <span class="ow">in</span> <span class="n">result</span><span class="o">.</span><span class="n">rows</span><span class="p">]</span> </span></span></code></pre></div><p><strong>Solutions</strong>:</p> <ol> <li>Increase GC frequency</li> <li>Reduce retention period</li> <li>Redesign to batch updates</li> <li>Consider partitioning hot entities</li> </ol> <h4 id="issue-gc-starvation" class="position-relative d-flex align-items-center group"> <span>Issue: GC Starvation</span> <button type="button" class="h-share btn btn-link p-0 text-decoration-none link-secondary opacity-50 hover-opacity-100 transition-all ms-1" data-share-target="issue-gc-starvation" aria-haspopup="dialog" aria-label="Share link: Issue: GC Starvation"> <i class="fa-sharp-duotone fa-solid fa-share-nodes" aria-hidden="true" style="font-size: 0.8em;"></i> <span class="visually-hidden">Share link</span> </button> </h4><p><strong>Symptom</strong>: Storage grows continuously, GC not reclaiming space</p> <p><strong>Diagnosis</strong>:</p> <div class="highlight"><pre tabindex="0" class="chroma"><code class="language-python" data-lang="python"><span class="line"><span class="cl"><span class="k">async</span> <span class="k">def</span> <span class="nf">check_gc_health</span><span class="p">():</span> </span></span><span class="line"><span class="cl"> <span class="n">result</span><span class="p">,</span> <span class="n">_</span> <span class="o">=</span> <span class="k">await</span> <span class="n">client</span><span class="o">.</span><span class="n">query</span><span class="p">(</span><span class="s2">&#34;&#34;&#34; </span></span></span><span class="line"><span class="cl"><span class="s2"> CALL dbms.mvcc.gcHealth() </span></span></span><span class="line"><span class="cl"><span class="s2"> YIELD lastRunTime, versionsEligible, versionsReclaimed </span></span></span><span class="line"><span class="cl"><span class="s2"> RETURN lastRunTime, versionsEligible, versionsReclaimed </span></span></span><span class="line"><span class="cl"><span class="s2"> &#34;&#34;&#34;</span><span class="p">)</span> </span></span><span class="line"><span class="cl"> </span></span><span class="line"><span class="cl"> <span class="n">health</span> <span class="o">=</span> <span class="n">result</span><span class="o">.</span><span class="n">rows</span><span class="p">[</span><span class="mi">0</span><span class="p">]</span> <span class="k">if</span> <span class="n">result</span><span class="o">.</span><span class="n">rows</span> <span class="k">else</span> <span class="kc">None</span> </span></span><span class="line"><span class="cl"> </span></span><span class="line"><span class="cl"> <span class="k">if</span> <span class="n">health</span><span class="p">[</span><span class="s1">&#39;versionsEligible&#39;</span><span class="p">]</span> <span class="o">&gt;</span> <span class="mi">0</span> <span class="ow">and</span> <span class="n">health</span><span class="p">[</span><span class="s1">&#39;versionsReclaimed&#39;</span><span class="p">]</span> <span class="o">==</span> <span class="mi">0</span><span class="p">:</span> </span></span><span class="line"><span class="cl"> <span class="c1"># GC unable to run - find why</span> </span></span><span class="line"><span class="cl"> <span class="n">blocked_by</span><span class="p">,</span> <span class="n">_</span> <span class="o">=</span> <span class="k">await</span> <span class="n">client</span><span class="o">.</span><span class="n">query</span><span class="p">(</span><span class="s2">&#34;&#34;&#34; </span></span></span><span class="line"><span class="cl"><span class="s2"> CALL dbms.transactions.blocking() </span></span></span><span class="line"><span class="cl"><span class="s2"> YIELD transactionId, blockedBy </span></span></span><span class="line"><span class="cl"><span class="s2"> RETURN transactionId, blockedBy </span></span></span><span class="line"><span class="cl"><span class="s2"> &#34;&#34;&#34;</span><span class="p">)</span> </span></span><span class="line"><span class="cl"> </span></span><span class="line"><span class="cl"> <span class="k">return</span> <span class="n">blocked_by</span><span class="o">.</span><span class="n">rows</span> </span></span></code></pre></div><p><strong>Solutions</strong>:</p> <ol> <li>Identify and terminate long-running transactions</li> <li>Ensure no snapshots held indefinitely</li> <li>Check for GC configuration issues</li> </ol> <p>Geode&rsquo;s MVCC implementation provides the foundation for high-concurrency, consistent graph queries. By maintaining multiple versions and using snapshot isolation, Geode achieves both strong consistency guarantees and excellent concurrent performance—essential for production graph workloads.</p>

Related Articles