<!-- CANARY: REQ=REQ-DOCS-001; FEATURE="Docs"; ASPECT=Documentation; STATUS=TESTED; OWNER=docs; UPDATED=2026-01-28 --> <h2 id="backup-and-recovery-in-geode" class="position-relative d-flex align-items-center group"> <span>Backup and Recovery 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="backup-and-recovery-in-geode" aria-haspopup="dialog" aria-label="Share link: Backup and Recovery 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> </h2><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>Data is the lifeblood of modern applications. Robust backup and recovery capabilities protect against hardware failures, software bugs, human errors, and disasters. Geode provides comprehensive backup and recovery features including continuous archiving, point-in-time recovery, and automated disaster recovery procedures.</p> <p>This guide covers backup strategies, recovery procedures, and best practices for ensuring data resilience in Geode deployments.</p> <h3 id="understanding-backup-and-recovery" class="position-relative d-flex align-items-center group"> <span>Understanding Backup and Recovery</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="understanding-backup-and-recovery" aria-haspopup="dialog" aria-label="Share link: Understanding Backup and Recovery"> <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="recovery-objectives" class="position-relative d-flex align-items-center group"> <span>Recovery Objectives</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="recovery-objectives" aria-haspopup="dialog" aria-label="Share link: Recovery Objectives"> <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>RPO (Recovery Point Objective)</strong>: Maximum acceptable data loss</p> <ul> <li>RPO = 0: No data loss (synchronous replication)</li> <li>RPO = 1 minute: Lose at most 1 minute of data</li> <li>RPO = 1 hour: Daily backups acceptable for non-critical data</li> </ul> <p><strong>RTO (Recovery Time Objective)</strong>: Maximum acceptable downtime</p> <ul> <li>RTO = seconds: Requires hot standby with automatic failover</li> <li>RTO = minutes: Requires warm standby or fast restore</li> <li>RTO = hours: Cold backup restoration acceptable</li> </ul> <h4 id="backup-types" class="position-relative d-flex align-items-center group"> <span>Backup Types</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="backup-types" aria-haspopup="dialog" aria-label="Share link: Backup Types"> <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>Full Backup</strong>: Complete copy of all data</p> <ul> <li>Largest storage requirement</li> <li>Fastest restore (single operation)</li> <li>Slowest to create</li> </ul> <p><strong>Incremental Backup</strong>: Changes since last backup</p> <ul> <li>Smallest storage requirement</li> <li>Requires full + all incrementals to restore</li> <li>Fastest to create</li> </ul> <p><strong>Differential Backup</strong>: Changes since last full backup</p> <ul> <li>Medium storage requirement</li> <li>Requires full + latest differential to restore</li> <li>Medium creation speed</li> </ul> <p><strong>Continuous Archiving (WAL)</strong>: Stream write-ahead log</p> <ul> <li>Enables point-in-time recovery</li> <li>Minimal additional storage overhead</li> <li>Near-zero RPO</li> </ul> <h3 id="backup-configuration" class="position-relative d-flex align-items-center group"> <span>Backup Configuration</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="backup-configuration" aria-haspopup="dialog" aria-label="Share link: Backup Configuration"> <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="full-database-backup" class="position-relative d-flex align-items-center group"> <span>Full Database Backup</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="full-database-backup" aria-haspopup="dialog" aria-label="Share link: Full Database Backup"> <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>Create a complete backup of the database:</p> <div class="highlight"><pre tabindex="0" class="chroma"><code class="language-bash" data-lang="bash"><span class="line"><span class="cl"><span class="c1"># Create full backup</span> </span></span><span class="line"><span class="cl">./geode backup create <span class="se">\ </span></span></span><span class="line"><span class="cl"><span class="se"></span> --output /backups/geode/full-<span class="k">$(</span>date +%Y%m%d<span class="k">)</span> <span class="se">\ </span></span></span><span class="line"><span class="cl"><span class="se"></span> --type full <span class="se">\ </span></span></span><span class="line"><span class="cl"><span class="se"></span> --compress gzip <span class="se">\ </span></span></span><span class="line"><span class="cl"><span class="se"></span> --parallel <span class="m">4</span> </span></span><span class="line"><span class="cl"> </span></span><span class="line"><span class="cl"><span class="c1"># Backup with encryption</span> </span></span><span class="line"><span class="cl">./geode backup create <span class="se">\ </span></span></span><span class="line"><span class="cl"><span class="se"></span> --output /backups/geode/full-<span class="k">$(</span>date +%Y%m%d<span class="k">)</span> <span class="se">\ </span></span></span><span class="line"><span class="cl"><span class="se"></span> --type full <span class="se">\ </span></span></span><span class="line"><span class="cl"><span class="se"></span> --encrypt <span class="se">\ </span></span></span><span class="line"><span class="cl"><span class="se"></span> --encryption-key-file /etc/geode/backup.key </span></span></code></pre></div><p><strong>Configuration</strong>:</p> <div class="highlight"><pre tabindex="0" class="chroma"><code class="language-toml" data-lang="toml"><span class="line"><span class="cl"><span class="c"># geode.toml - Backup configuration</span> </span></span><span class="line"><span class="cl"><span class="p">[</span><span class="nx">backup</span><span class="p">]</span> </span></span><span class="line"><span class="cl"><span class="nx">enabled</span> <span class="p">=</span> <span class="kc">true</span> </span></span><span class="line"><span class="cl"><span class="nx">directory</span> <span class="p">=</span> <span class="s2">&#34;/var/lib/geode/backups&#34;</span> </span></span><span class="line"><span class="cl"> </span></span><span class="line"><span class="cl"><span class="p">[</span><span class="nx">backup</span><span class="p">.</span><span class="nx">full</span><span class="p">]</span> </span></span><span class="line"><span class="cl"><span class="c"># Schedule full backups</span> </span></span><span class="line"><span class="cl"><span class="nx">schedule</span> <span class="p">=</span> <span class="s2">&#34;0 2 * * 0&#34;</span> <span class="c"># Weekly at 2 AM Sunday</span> </span></span><span class="line"><span class="cl"><span class="nx">retention_days</span> <span class="p">=</span> <span class="mi">30</span> </span></span><span class="line"><span class="cl"><span class="nx">compression</span> <span class="p">=</span> <span class="s2">&#34;gzip&#34;</span> </span></span><span class="line"><span class="cl"><span class="nx">parallel_workers</span> <span class="p">=</span> <span class="mi">4</span> </span></span><span class="line"><span class="cl"> </span></span><span class="line"><span class="cl"><span class="p">[</span><span class="nx">backup</span><span class="p">.</span><span class="nx">incremental</span><span class="p">]</span> </span></span><span class="line"><span class="cl"><span class="c"># Schedule incremental backups</span> </span></span><span class="line"><span class="cl"><span class="nx">schedule</span> <span class="p">=</span> <span class="s2">&#34;0 2 * * 1-6&#34;</span> <span class="c"># Daily at 2 AM Mon-Sat</span> </span></span><span class="line"><span class="cl"><span class="nx">retention_days</span> <span class="p">=</span> <span class="mi">7</span> </span></span><span class="line"><span class="cl"><span class="nx">base_backup</span> <span class="p">=</span> <span class="s2">&#34;latest_full&#34;</span> </span></span></code></pre></div> <h4 id="incremental-backups" class="position-relative d-flex align-items-center group"> <span>Incremental Backups</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="incremental-backups" aria-haspopup="dialog" aria-label="Share link: Incremental Backups"> <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>Capture only changes since the last backup:</p> <div class="highlight"><pre tabindex="0" class="chroma"><code class="language-bash" data-lang="bash"><span class="line"><span class="cl"><span class="c1"># Create incremental backup</span> </span></span><span class="line"><span class="cl">./geode backup create <span class="se">\ </span></span></span><span class="line"><span class="cl"><span class="se"></span> --output /backups/geode/incr-<span class="k">$(</span>date +%Y%m%d-%H%M<span class="k">)</span> <span class="se">\ </span></span></span><span class="line"><span class="cl"><span class="se"></span> --type incremental <span class="se">\ </span></span></span><span class="line"><span class="cl"><span class="se"></span> --base-backup /backups/geode/full-20260125 </span></span><span class="line"><span class="cl"> </span></span><span class="line"><span class="cl"><span class="c1"># List backup chain</span> </span></span><span class="line"><span class="cl">./geode backup list --chain /backups/geode/full-20260125 </span></span></code></pre></div><p><strong>Output</strong>:</p> <div class="highlight"><pre tabindex="0" class="chroma"><code class="language-fallback" data-lang="fallback"><span class="line"><span class="cl">Backup Chain for full-20260125: </span></span><span class="line"><span class="cl"> 1. full-20260125 (12.4 GB, 2026-01-25 02:00:00) </span></span><span class="line"><span class="cl"> 2. incr-20260126-0200 (234 MB, 2026-01-26 02:00:00) </span></span><span class="line"><span class="cl"> 3. incr-20260127-0200 (189 MB, 2026-01-27 02:00:00) </span></span><span class="line"><span class="cl"> 4. incr-20260128-0200 (312 MB, 2026-01-28 02:00:00) </span></span><span class="line"><span class="cl"> </span></span><span class="line"><span class="cl">Total size: 13.1 GB </span></span><span class="line"><span class="cl">Restore point: 2026-01-28 02:00:00 </span></span></code></pre></div> <h4 id="wal-archiving-for-point-in-time-recovery" class="position-relative d-flex align-items-center group"> <span>WAL Archiving for Point-in-Time Recovery</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="wal-archiving-for-point-in-time-recovery" aria-haspopup="dialog" aria-label="Share link: WAL Archiving for Point-in-Time Recovery"> <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>Enable continuous WAL archiving for near-zero RPO:</p> <div class="highlight"><pre tabindex="0" class="chroma"><code class="language-toml" data-lang="toml"><span class="line"><span class="cl"><span class="c"># geode.toml - WAL archiving</span> </span></span><span class="line"><span class="cl"><span class="p">[</span><span class="nx">wal</span><span class="p">]</span> </span></span><span class="line"><span class="cl"><span class="nx">enabled</span> <span class="p">=</span> <span class="kc">true</span> </span></span><span class="line"><span class="cl"><span class="nx">directory</span> <span class="p">=</span> <span class="s2">&#34;/var/lib/geode/wal&#34;</span> </span></span><span class="line"><span class="cl"><span class="nx">max_size_mb</span> <span class="p">=</span> <span class="mi">1024</span> </span></span><span class="line"><span class="cl"><span class="nx">sync_mode</span> <span class="p">=</span> <span class="s2">&#34;fsync&#34;</span> </span></span><span class="line"><span class="cl"> </span></span><span class="line"><span class="cl"><span class="p">[</span><span class="nx">wal</span><span class="p">.</span><span class="nx">archiving</span><span class="p">]</span> </span></span><span class="line"><span class="cl"><span class="nx">enabled</span> <span class="p">=</span> <span class="kc">true</span> </span></span><span class="line"><span class="cl"><span class="nx">destination</span> <span class="p">=</span> <span class="s2">&#34;/backups/geode/wal&#34;</span> </span></span><span class="line"><span class="cl"><span class="nx">compression</span> <span class="p">=</span> <span class="s2">&#34;lz4&#34;</span> </span></span><span class="line"><span class="cl"> </span></span><span class="line"><span class="cl"><span class="c"># Ship WAL to remote storage</span> </span></span><span class="line"><span class="cl"><span class="p">[</span><span class="nx">wal</span><span class="p">.</span><span class="nx">archiving</span><span class="p">.</span><span class="nx">remote</span><span class="p">]</span> </span></span><span class="line"><span class="cl"><span class="nx">enabled</span> <span class="p">=</span> <span class="kc">true</span> </span></span><span class="line"><span class="cl"><span class="nx">type</span> <span class="p">=</span> <span class="s2">&#34;s3&#34;</span> </span></span><span class="line"><span class="cl"><span class="nx">bucket</span> <span class="p">=</span> <span class="s2">&#34;geode-wal-archive&#34;</span> </span></span><span class="line"><span class="cl"><span class="nx">prefix</span> <span class="p">=</span> <span class="s2">&#34;production/wal&#34;</span> </span></span><span class="line"><span class="cl"><span class="nx">upload_interval_seconds</span> <span class="p">=</span> <span class="mi">60</span> </span></span></code></pre></div><p><strong>Monitor WAL archiving</strong>:</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">Check</span><span class="w"> </span><span class="py">WAL</span><span class="w"> </span><span class="py">archiving</span><span class="w"> </span><span class="py">status</span><span class="w"> </span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="py">SELECT</span><span class="w"> </span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="py">current_wal_file</span><span class="p">,</span><span class="w"> </span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="py">last_archived_file</span><span class="p">,</span><span class="w"> </span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="py">archive_lag_bytes</span><span class="p">,</span><span class="w"> </span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="py">archive_lag_seconds</span><span class="p">,</span><span class="w"> </span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="py">failed_archive_count</span><span class="w"> </span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="py">FROM</span><span class="w"> </span><span class="py">system</span><span class="err">.</span><span class="py">wal_archiving_status</span><span class="err">;</span><span class="w"> </span></span></span></code></pre></div> <h4 id="cloud-storage-integration" class="position-relative d-flex align-items-center group"> <span>Cloud Storage Integration</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="cloud-storage-integration" aria-haspopup="dialog" aria-label="Share link: Cloud Storage Integration"> <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>Amazon S3</strong>:</p> <div class="highlight"><pre tabindex="0" class="chroma"><code class="language-toml" data-lang="toml"><span class="line"><span class="cl"><span class="p">[</span><span class="nx">backup</span><span class="p">.</span><span class="nx">storage</span><span class="p">]</span> </span></span><span class="line"><span class="cl"><span class="nx">type</span> <span class="p">=</span> <span class="s2">&#34;s3&#34;</span> </span></span><span class="line"><span class="cl"><span class="nx">bucket</span> <span class="p">=</span> <span class="s2">&#34;mycompany-geode-backups&#34;</span> </span></span><span class="line"><span class="cl"><span class="nx">prefix</span> <span class="p">=</span> <span class="s2">&#34;production&#34;</span> </span></span><span class="line"><span class="cl"><span class="nx">region</span> <span class="p">=</span> <span class="s2">&#34;us-east-1&#34;</span> </span></span><span class="line"><span class="cl"><span class="nx">storage_class</span> <span class="p">=</span> <span class="s2">&#34;STANDARD_IA&#34;</span> </span></span><span class="line"><span class="cl"> </span></span><span class="line"><span class="cl"><span class="p">[</span><span class="nx">backup</span><span class="p">.</span><span class="nx">storage</span><span class="p">.</span><span class="nx">credentials</span><span class="p">]</span> </span></span><span class="line"><span class="cl"><span class="c"># Use IAM role or explicit credentials</span> </span></span><span class="line"><span class="cl"><span class="nx">use_instance_role</span> <span class="p">=</span> <span class="kc">true</span> </span></span><span class="line"><span class="cl"><span class="c"># Or:</span> </span></span><span class="line"><span class="cl"><span class="c"># access_key_id = &#34;...&#34;</span> </span></span><span class="line"><span class="cl"><span class="c"># secret_access_key = &#34;...&#34;</span> </span></span></code></pre></div><p><strong>Google Cloud Storage</strong>:</p> <div class="highlight"><pre tabindex="0" class="chroma"><code class="language-toml" data-lang="toml"><span class="line"><span class="cl"><span class="p">[</span><span class="nx">backup</span><span class="p">.</span><span class="nx">storage</span><span class="p">]</span> </span></span><span class="line"><span class="cl"><span class="nx">type</span> <span class="p">=</span> <span class="s2">&#34;gcs&#34;</span> </span></span><span class="line"><span class="cl"><span class="nx">bucket</span> <span class="p">=</span> <span class="s2">&#34;mycompany-geode-backups&#34;</span> </span></span><span class="line"><span class="cl"><span class="nx">prefix</span> <span class="p">=</span> <span class="s2">&#34;production&#34;</span> </span></span><span class="line"><span class="cl"><span class="nx">credentials_file</span> <span class="p">=</span> <span class="s2">&#34;/etc/geode/gcs-credentials.json&#34;</span> </span></span></code></pre></div><p><strong>Azure Blob Storage</strong>:</p> <div class="highlight"><pre tabindex="0" class="chroma"><code class="language-toml" data-lang="toml"><span class="line"><span class="cl"><span class="p">[</span><span class="nx">backup</span><span class="p">.</span><span class="nx">storage</span><span class="p">]</span> </span></span><span class="line"><span class="cl"><span class="nx">type</span> <span class="p">=</span> <span class="s2">&#34;azure&#34;</span> </span></span><span class="line"><span class="cl"><span class="nx">container</span> <span class="p">=</span> <span class="s2">&#34;geode-backups&#34;</span> </span></span><span class="line"><span class="cl"><span class="nx">prefix</span> <span class="p">=</span> <span class="s2">&#34;production&#34;</span> </span></span><span class="line"><span class="cl"><span class="nx">account</span> <span class="p">=</span> <span class="s2">&#34;mycompanybackups&#34;</span> </span></span><span class="line"><span class="cl"><span class="c"># Uses managed identity or connection string</span> </span></span></code></pre></div> <h3 id="recovery-procedures" class="position-relative d-flex align-items-center group"> <span>Recovery Procedures</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="recovery-procedures" aria-haspopup="dialog" aria-label="Share link: Recovery Procedures"> <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="full-restore" class="position-relative d-flex align-items-center group"> <span>Full Restore</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="full-restore" aria-haspopup="dialog" aria-label="Share link: Full Restore"> <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>Restore from a full backup:</p> <div class="highlight"><pre tabindex="0" class="chroma"><code class="language-bash" data-lang="bash"><span class="line"><span class="cl"><span class="c1"># Stop Geode server</span> </span></span><span class="line"><span class="cl">systemctl stop geode </span></span><span class="line"><span class="cl"> </span></span><span class="line"><span class="cl"><span class="c1"># Clear existing data (if any)</span> </span></span><span class="line"><span class="cl">rm -rf /var/lib/geode/data/* </span></span><span class="line"><span class="cl"> </span></span><span class="line"><span class="cl"><span class="c1"># Restore from backup</span> </span></span><span class="line"><span class="cl">./geode backup restore <span class="se">\ </span></span></span><span class="line"><span class="cl"><span class="se"></span> --input /backups/geode/full-20260125 <span class="se">\ </span></span></span><span class="line"><span class="cl"><span class="se"></span> --data-dir /var/lib/geode/data <span class="se">\ </span></span></span><span class="line"><span class="cl"><span class="se"></span> --parallel <span class="m">4</span> </span></span><span class="line"><span class="cl"> </span></span><span class="line"><span class="cl"><span class="c1"># Start Geode server</span> </span></span><span class="line"><span class="cl">systemctl start geode </span></span><span class="line"><span class="cl"> </span></span><span class="line"><span class="cl"><span class="c1"># Verify restoration</span> </span></span><span class="line"><span class="cl">./geode shell -c <span class="s2">&#34;MATCH (n) RETURN count(n) as node_count&#34;</span> </span></span></code></pre></div> <h4 id="incremental-restore" class="position-relative d-flex align-items-center group"> <span>Incremental Restore</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="incremental-restore" aria-haspopup="dialog" aria-label="Share link: Incremental Restore"> <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>Restore full backup plus incrementals:</p> <div class="highlight"><pre tabindex="0" class="chroma"><code class="language-bash" data-lang="bash"><span class="line"><span class="cl"><span class="c1"># Restore full backup first</span> </span></span><span class="line"><span class="cl">./geode backup restore <span class="se">\ </span></span></span><span class="line"><span class="cl"><span class="se"></span> --input /backups/geode/full-20260125 <span class="se">\ </span></span></span><span class="line"><span class="cl"><span class="se"></span> --data-dir /var/lib/geode/data </span></span><span class="line"><span class="cl"> </span></span><span class="line"><span class="cl"><span class="c1"># Apply incremental backups in order</span> </span></span><span class="line"><span class="cl">./geode backup restore <span class="se">\ </span></span></span><span class="line"><span class="cl"><span class="se"></span> --input /backups/geode/incr-20260126-0200 <span class="se">\ </span></span></span><span class="line"><span class="cl"><span class="se"></span> --data-dir /var/lib/geode/data <span class="se">\ </span></span></span><span class="line"><span class="cl"><span class="se"></span> --incremental </span></span><span class="line"><span class="cl"> </span></span><span class="line"><span class="cl">./geode backup restore <span class="se">\ </span></span></span><span class="line"><span class="cl"><span class="se"></span> --input /backups/geode/incr-20260127-0200 <span class="se">\ </span></span></span><span class="line"><span class="cl"><span class="se"></span> --data-dir /var/lib/geode/data <span class="se">\ </span></span></span><span class="line"><span class="cl"><span class="se"></span> --incremental </span></span><span class="line"><span class="cl"> </span></span><span class="line"><span class="cl"><span class="c1"># Or restore entire chain automatically</span> </span></span><span class="line"><span class="cl">./geode backup restore <span class="se">\ </span></span></span><span class="line"><span class="cl"><span class="se"></span> --input /backups/geode/incr-20260127-0200 <span class="se">\ </span></span></span><span class="line"><span class="cl"><span class="se"></span> --data-dir /var/lib/geode/data <span class="se">\ </span></span></span><span class="line"><span class="cl"><span class="se"></span> --restore-chain </span></span></code></pre></div> <h4 id="point-in-time-recovery-pitr" class="position-relative d-flex align-items-center group"> <span>Point-in-Time Recovery (PITR)</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="point-in-time-recovery-pitr" aria-haspopup="dialog" aria-label="Share link: Point-in-Time Recovery (PITR)"> <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>Recover to a specific moment in time:</p> <div class="highlight"><pre tabindex="0" class="chroma"><code class="language-bash" data-lang="bash"><span class="line"><span class="cl"><span class="c1"># Restore to specific timestamp</span> </span></span><span class="line"><span class="cl">./geode backup restore <span class="se">\ </span></span></span><span class="line"><span class="cl"><span class="se"></span> --input /backups/geode/full-20260125 <span class="se">\ </span></span></span><span class="line"><span class="cl"><span class="se"></span> --wal-archive /backups/geode/wal <span class="se">\ </span></span></span><span class="line"><span class="cl"><span class="se"></span> --data-dir /var/lib/geode/data <span class="se">\ </span></span></span><span class="line"><span class="cl"><span class="se"></span> --target-time <span class="s2">&#34;2026-01-27 14:30:00 UTC&#34;</span> </span></span><span class="line"><span class="cl"> </span></span><span class="line"><span class="cl"><span class="c1"># Restore to specific transaction</span> </span></span><span class="line"><span class="cl">./geode backup restore <span class="se">\ </span></span></span><span class="line"><span class="cl"><span class="se"></span> --input /backups/geode/full-20260125 <span class="se">\ </span></span></span><span class="line"><span class="cl"><span class="se"></span> --wal-archive /backups/geode/wal <span class="se">\ </span></span></span><span class="line"><span class="cl"><span class="se"></span> --data-dir /var/lib/geode/data <span class="se">\ </span></span></span><span class="line"><span class="cl"><span class="se"></span> --target-xid <span class="m">12847293</span> </span></span><span class="line"><span class="cl"> </span></span><span class="line"><span class="cl"><span class="c1"># Restore to named recovery point</span> </span></span><span class="line"><span class="cl">./geode backup restore <span class="se">\ </span></span></span><span class="line"><span class="cl"><span class="se"></span> --input /backups/geode/full-20260125 <span class="se">\ </span></span></span><span class="line"><span class="cl"><span class="se"></span> --wal-archive /backups/geode/wal <span class="se">\ </span></span></span><span class="line"><span class="cl"><span class="se"></span> --data-dir /var/lib/geode/data <span class="se">\ </span></span></span><span class="line"><span class="cl"><span class="se"></span> --target-name <span class="s2">&#34;pre-migration-checkpoint&#34;</span> </span></span></code></pre></div><p><strong>Create named recovery points</strong>:</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">Create</span><span class="w"> </span><span class="py">a</span><span class="w"> </span><span class="py">named</span><span class="w"> </span><span class="py">checkpoint</span><span class="w"> </span><span class="py">for</span><span class="w"> </span><span class="py">easy</span><span class="w"> </span><span class="py">PITR</span><span class="w"> </span><span class="py">targeting</span><span class="w"> </span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="py">CREATE</span><span class="w"> </span><span class="py">CHECKPOINT</span><span class="w"> </span><span class="err">&#39;</span><span class="py">pre</span><span class="err">-</span><span class="py">migration</span><span class="err">-</span><span class="py">checkpoint</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="err">--</span><span class="w"> </span><span class="py">List</span><span class="w"> </span><span class="py">available</span><span class="w"> </span><span class="py">checkpoints</span><span class="w"> </span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="py">SELECT</span><span class="w"> </span><span class="py">name</span><span class="p">,</span><span class="w"> </span><span class="py">timestamp</span><span class="p">,</span><span class="w"> </span><span class="py">wal_position</span><span class="w"> </span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="py">FROM</span><span class="w"> </span><span class="py">system</span><span class="err">.</span><span class="py">checkpoints</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="w"> </span><span class="py">DESC</span><span class="err">;</span><span class="w"> </span></span></span></code></pre></div> <h4 id="selective-recovery" class="position-relative d-flex align-items-center group"> <span>Selective Recovery</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="selective-recovery" aria-haspopup="dialog" aria-label="Share link: Selective Recovery"> <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>Restore specific graphs or data:</p> <div class="highlight"><pre tabindex="0" class="chroma"><code class="language-bash" data-lang="bash"><span class="line"><span class="cl"><span class="c1"># Restore single graph</span> </span></span><span class="line"><span class="cl">./geode backup restore <span class="se">\ </span></span></span><span class="line"><span class="cl"><span class="se"></span> --input /backups/geode/full-20260125 <span class="se">\ </span></span></span><span class="line"><span class="cl"><span class="se"></span> --data-dir /var/lib/geode/data <span class="se">\ </span></span></span><span class="line"><span class="cl"><span class="se"></span> --include-graphs <span class="s2">&#34;social_network,analytics&#34;</span> </span></span><span class="line"><span class="cl"> </span></span><span class="line"><span class="cl"><span class="c1"># Exclude specific graphs</span> </span></span><span class="line"><span class="cl">./geode backup restore <span class="se">\ </span></span></span><span class="line"><span class="cl"><span class="se"></span> --input /backups/geode/full-20260125 <span class="se">\ </span></span></span><span class="line"><span class="cl"><span class="se"></span> --data-dir /var/lib/geode/data <span class="se">\ </span></span></span><span class="line"><span class="cl"><span class="se"></span> --exclude-graphs <span class="s2">&#34;temp_data,staging&#34;</span> </span></span></code></pre></div> <h3 id="disaster-recovery" class="position-relative d-flex align-items-center group"> <span>Disaster Recovery</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="disaster-recovery" aria-haspopup="dialog" aria-label="Share link: Disaster Recovery"> <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="dr-architecture" class="position-relative d-flex align-items-center group"> <span>DR 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="dr-architecture" aria-haspopup="dialog" aria-label="Share link: DR 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>Design for disaster resilience:</p> <div class="highlight"><pre tabindex="0" class="chroma"><code class="language-fallback" data-lang="fallback"><span class="line"><span class="cl">Primary Site (us-east-1) DR Site (us-west-2) </span></span><span class="line"><span class="cl">┌─────────────────────┐ ┌─────────────────────┐ </span></span><span class="line"><span class="cl">│ Geode Cluster │ │ Geode Standby │ </span></span><span class="line"><span class="cl">│ (3 nodes) │──WAL──────│ (3 nodes) │ </span></span><span class="line"><span class="cl">│ │ Stream │ (read-only) │ </span></span><span class="line"><span class="cl">└─────────────────────┘ └─────────────────────┘ </span></span><span class="line"><span class="cl"> │ │ </span></span><span class="line"><span class="cl"> ▼ ▼ </span></span><span class="line"><span class="cl">┌─────────────────────┐ ┌─────────────────────┐ </span></span><span class="line"><span class="cl">│ S3 Backup Bucket │───Repl────│ S3 Backup Bucket │ </span></span><span class="line"><span class="cl">│ (us-east-1) │ │ (us-west-2) │ </span></span><span class="line"><span class="cl">└─────────────────────┘ └─────────────────────┘ </span></span></code></pre></div><p><strong>Configuration for DR standby</strong>:</p> <div class="highlight"><pre tabindex="0" class="chroma"><code class="language-toml" data-lang="toml"><span class="line"><span class="cl"><span class="c"># geode.toml - DR standby site</span> </span></span><span class="line"><span class="cl"><span class="p">[</span><span class="nx">server</span><span class="p">]</span> </span></span><span class="line"><span class="cl"><span class="nx">mode</span> <span class="p">=</span> <span class="s2">&#34;standby&#34;</span> </span></span><span class="line"><span class="cl"><span class="nx">read_only</span> <span class="p">=</span> <span class="kc">true</span> </span></span><span class="line"><span class="cl"> </span></span><span class="line"><span class="cl"><span class="p">[</span><span class="nx">replication</span><span class="p">.</span><span class="nx">streaming</span><span class="p">]</span> </span></span><span class="line"><span class="cl"><span class="nx">enabled</span> <span class="p">=</span> <span class="kc">true</span> </span></span><span class="line"><span class="cl"><span class="nx">primary_host</span> <span class="p">=</span> <span class="s2">&#34;primary.geode.internal&#34;</span> </span></span><span class="line"><span class="cl"><span class="nx">primary_port</span> <span class="p">=</span> <span class="mi">7687</span> </span></span><span class="line"><span class="cl"> </span></span><span class="line"><span class="cl"><span class="p">[</span><span class="nx">replication</span><span class="p">.</span><span class="nx">wal</span><span class="p">]</span> </span></span><span class="line"><span class="cl"><span class="c"># Receive WAL from primary</span> </span></span><span class="line"><span class="cl"><span class="nx">receive_directory</span> <span class="p">=</span> <span class="s2">&#34;/var/lib/geode/wal_receive&#34;</span> </span></span><span class="line"><span class="cl"><span class="nx">apply_delay_seconds</span> <span class="p">=</span> <span class="mi">0</span> <span class="c"># Real-time, or delay for protection</span> </span></span><span class="line"><span class="cl"> </span></span><span class="line"><span class="cl"><span class="p">[</span><span class="nx">failover</span><span class="p">]</span> </span></span><span class="line"><span class="cl"><span class="c"># Manual failover only for DR</span> </span></span><span class="line"><span class="cl"><span class="nx">auto_promote</span> <span class="p">=</span> <span class="kc">false</span> </span></span><span class="line"><span class="cl"><span class="nx">promotion_command</span> <span class="p">=</span> <span class="s2">&#34;/etc/geode/promote-to-primary.sh&#34;</span> </span></span></code></pre></div> <h4 id="dr-failover-procedure" class="position-relative d-flex align-items-center group"> <span>DR Failover Procedure</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="dr-failover-procedure" aria-haspopup="dialog" aria-label="Share link: DR Failover Procedure"> <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>Planned Failover</strong> (maintenance):</p> <div class="highlight"><pre tabindex="0" class="chroma"><code class="language-bash" data-lang="bash"><span class="line"><span class="cl"><span class="c1"># On primary site</span> </span></span><span class="line"><span class="cl"><span class="c1"># 1. Stop accepting writes</span> </span></span><span class="line"><span class="cl">./geode admin set-read-only <span class="nb">true</span> </span></span><span class="line"><span class="cl"> </span></span><span class="line"><span class="cl"><span class="c1"># 2. Wait for replication to catch up</span> </span></span><span class="line"><span class="cl">./geode admin wait-for-sync --target dr-site </span></span><span class="line"><span class="cl"> </span></span><span class="line"><span class="cl"><span class="c1"># 3. Create final checkpoint</span> </span></span><span class="line"><span class="cl">./geode admin checkpoint --name <span class="s2">&#34;failover-</span><span class="k">$(</span>date +%Y%m%d<span class="k">)</span><span class="s2">&#34;</span> </span></span><span class="line"><span class="cl"> </span></span><span class="line"><span class="cl"><span class="c1"># On DR site</span> </span></span><span class="line"><span class="cl"><span class="c1"># 4. Promote standby to primary</span> </span></span><span class="line"><span class="cl">./geode admin promote --accept-writes </span></span><span class="line"><span class="cl"> </span></span><span class="line"><span class="cl"><span class="c1"># 5. Update DNS/load balancer</span> </span></span><span class="line"><span class="cl"><span class="c1"># 6. Verify applications reconnect</span> </span></span></code></pre></div><p><strong>Unplanned Failover</strong> (disaster):</p> <div class="highlight"><pre tabindex="0" class="chroma"><code class="language-bash" data-lang="bash"><span class="line"><span class="cl"><span class="c1"># On DR site</span> </span></span><span class="line"><span class="cl"><span class="c1"># 1. Check last received WAL position</span> </span></span><span class="line"><span class="cl">./geode admin wal-status </span></span><span class="line"><span class="cl"> </span></span><span class="line"><span class="cl"><span class="c1"># 2. Decide on data loss acceptance</span> </span></span><span class="line"><span class="cl"><span class="c1"># 3. Promote to primary</span> </span></span><span class="line"><span class="cl">./geode admin promote --force --accept-data-loss </span></span><span class="line"><span class="cl"> </span></span><span class="line"><span class="cl"><span class="c1"># 4. Update DNS/load balancer</span> </span></span><span class="line"><span class="cl"><span class="c1"># 5. Notify stakeholders of potential data loss</span> </span></span><span class="line"><span class="cl"><span class="c1"># 6. Begin incident response</span> </span></span></code></pre></div> <h4 id="dr-testing" class="position-relative d-flex align-items-center group"> <span>DR Testing</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="dr-testing" aria-haspopup="dialog" aria-label="Share link: DR Testing"> <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>Regular DR drills ensure readiness:</p> <div class="highlight"><pre tabindex="0" class="chroma"><code class="language-python" data-lang="python"><span class="line"><span class="cl"><span class="ch">#!/usr/bin/env python3</span> </span></span><span class="line"><span class="cl"><span class="s2">&#34;&#34;&#34;Automated DR test script&#34;&#34;&#34;</span> </span></span><span class="line"><span class="cl"> </span></span><span class="line"><span class="cl"><span class="kn">import</span> <span class="nn">subprocess</span> </span></span><span class="line"><span class="cl"><span class="kn">import</span> <span class="nn">time</span> </span></span><span class="line"><span class="cl"><span class="kn">from</span> <span class="nn">datetime</span> <span class="kn">import</span> <span class="n">datetime</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">run_dr_test</span><span class="p">():</span> </span></span><span class="line"><span class="cl"> <span class="s2">&#34;&#34;&#34;Execute DR failover test&#34;&#34;&#34;</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;Starting DR test at </span><span class="si">{</span><span class="n">datetime</span><span class="o">.</span><span class="n">now</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></span><span class="line"><span class="cl"> <span class="c1"># 1. Record current state</span> </span></span><span class="line"><span class="cl"> <span class="n">primary_count</span> <span class="o">=</span> <span class="n">get_node_count</span><span class="p">(</span><span class="s2">&#34;primary.geode.internal&#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;Primary node count: </span><span class="si">{</span><span class="n">primary_count</span><span class="si">}</span><span class="s2">&#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"># 2. Create test data</span> </span></span><span class="line"><span class="cl"> <span class="n">create_test_nodes</span><span class="p">(</span><span class="s2">&#34;primary.geode.internal&#34;</span><span class="p">,</span> <span class="mi">1000</span><span class="p">)</span> </span></span><span class="line"><span class="cl"> </span></span><span class="line"><span class="cl"> <span class="c1"># 3. Wait for replication</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="mi">30</span><span class="p">)</span> </span></span><span class="line"><span class="cl"> <span class="n">dr_count</span> <span class="o">=</span> <span class="n">get_node_count</span><span class="p">(</span><span class="s2">&#34;dr.geode.internal&#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;DR node count: </span><span class="si">{</span><span class="n">dr_count</span><span class="si">}</span><span class="s2">&#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"># 4. Simulate primary failure</span> </span></span><span class="line"><span class="cl"> <span class="nb">print</span><span class="p">(</span><span class="s2">&#34;Simulating primary failure...&#34;</span><span class="p">)</span> </span></span><span class="line"><span class="cl"> <span class="n">subprocess</span><span class="o">.</span><span class="n">run</span><span class="p">([</span><span class="s2">&#34;ssh&#34;</span><span class="p">,</span> <span class="s2">&#34;primary&#34;</span><span class="p">,</span> <span class="s2">&#34;systemctl&#34;</span><span class="p">,</span> <span class="s2">&#34;stop&#34;</span><span class="p">,</span> <span class="s2">&#34;geode&#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"># 5. Promote DR</span> </span></span><span class="line"><span class="cl"> <span class="nb">print</span><span class="p">(</span><span class="s2">&#34;Promoting DR site...&#34;</span><span class="p">)</span> </span></span><span class="line"><span class="cl"> <span class="n">subprocess</span><span class="o">.</span><span class="n">run</span><span class="p">([</span><span class="s2">&#34;ssh&#34;</span><span class="p">,</span> <span class="s2">&#34;dr&#34;</span><span class="p">,</span> <span class="s2">&#34;./geode&#34;</span><span class="p">,</span> <span class="s2">&#34;admin&#34;</span><span class="p">,</span> <span class="s2">&#34;promote&#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"># 6. Verify DR is operational</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="mi">10</span><span class="p">)</span> </span></span><span class="line"><span class="cl"> <span class="n">dr_count_after</span> <span class="o">=</span> <span class="n">get_node_count</span><span class="p">(</span><span class="s2">&#34;dr.geode.internal&#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;DR node count after promotion: </span><span class="si">{</span><span class="n">dr_count_after</span><span class="si">}</span><span class="s2">&#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"># 7. Run test queries</span> </span></span><span class="line"><span class="cl"> <span class="n">verify_queries</span><span class="p">(</span><span class="s2">&#34;dr.geode.internal&#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"># 8. Restore primary (cleanup)</span> </span></span><span class="line"><span class="cl"> <span class="nb">print</span><span class="p">(</span><span class="s2">&#34;Restoring primary...&#34;</span><span class="p">)</span> </span></span><span class="line"><span class="cl"> <span class="n">subprocess</span><span class="o">.</span><span class="n">run</span><span class="p">([</span><span class="s2">&#34;ssh&#34;</span><span class="p">,</span> <span class="s2">&#34;primary&#34;</span><span class="p">,</span> <span class="s2">&#34;systemctl&#34;</span><span class="p">,</span> <span class="s2">&#34;start&#34;</span><span class="p">,</span> <span class="s2">&#34;geode&#34;</span><span class="p">])</span> </span></span><span class="line"><span class="cl"> <span class="n">subprocess</span><span class="o">.</span><span class="n">run</span><span class="p">([</span><span class="s2">&#34;ssh&#34;</span><span class="p">,</span> <span class="s2">&#34;dr&#34;</span><span class="p">,</span> <span class="s2">&#34;./geode&#34;</span><span class="p">,</span> <span class="s2">&#34;admin&#34;</span><span class="p">,</span> <span class="s2">&#34;demote&#34;</span><span class="p">])</span> </span></span><span class="line"><span class="cl"> </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;DR test completed at </span><span class="si">{</span><span class="n">datetime</span><span class="o">.</span><span class="n">now</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></span><span class="line"><span class="cl"><span class="k">def</span> <span class="nf">get_node_count</span><span class="p">(</span><span class="n">host</span><span class="p">):</span> </span></span><span class="line"><span class="cl"> <span class="n">result</span> <span class="o">=</span> <span class="n">subprocess</span><span class="o">.</span><span class="n">run</span><span class="p">(</span> </span></span><span class="line"><span class="cl"> <span class="p">[</span><span class="s2">&#34;./geode&#34;</span><span class="p">,</span> <span class="s2">&#34;shell&#34;</span><span class="p">,</span> <span class="s2">&#34;--host&#34;</span><span class="p">,</span> <span class="n">host</span><span class="p">,</span> <span class="s2">&#34;-c&#34;</span><span class="p">,</span> </span></span><span class="line"><span class="cl"> <span class="s2">&#34;MATCH (n) RETURN count(n) as cnt&#34;</span><span class="p">],</span> </span></span><span class="line"><span class="cl"> <span class="n">capture_output</span><span class="o">=</span><span class="kc">True</span><span class="p">,</span> <span class="n">text</span><span class="o">=</span><span class="kc">True</span> </span></span><span class="line"><span class="cl"> <span class="p">)</span> </span></span><span class="line"><span class="cl"> <span class="c1"># Parse count from output</span> </span></span><span class="line"><span class="cl"> <span class="k">return</span> <span class="nb">int</span><span class="p">(</span><span class="n">result</span><span class="o">.</span><span class="n">stdout</span><span class="o">.</span><span class="n">strip</span><span class="p">()</span><span class="o">.</span><span class="n">split</span><span class="p">()[</span><span class="o">-</span><span class="mi">1</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">create_test_nodes</span><span class="p">(</span><span class="n">host</span><span class="p">,</span> <span class="n">count</span><span class="p">):</span> </span></span><span class="line"><span class="cl"> <span class="n">subprocess</span><span class="o">.</span><span class="n">run</span><span class="p">([</span> </span></span><span class="line"><span class="cl"> <span class="s2">&#34;./geode&#34;</span><span class="p">,</span> <span class="s2">&#34;shell&#34;</span><span class="p">,</span> <span class="s2">&#34;--host&#34;</span><span class="p">,</span> <span class="n">host</span><span class="p">,</span> <span class="s2">&#34;-c&#34;</span><span class="p">,</span> </span></span><span class="line"><span class="cl"> <span class="sa">f</span><span class="s2">&#34;UNWIND range(1, </span><span class="si">{</span><span class="n">count</span><span class="si">}</span><span class="s2">) AS i CREATE (:DRTest </span><span class="se">{{</span><span class="s2">id: i, ts: datetime()</span><span class="se">}}</span><span class="s2">)&#34;</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">def</span> <span class="nf">verify_queries</span><span class="p">(</span><span class="n">host</span><span class="p">):</span> </span></span><span class="line"><span class="cl"> <span class="n">queries</span> <span class="o">=</span> <span class="p">[</span> </span></span><span class="line"><span class="cl"> <span class="s2">&#34;MATCH (n:DRTest) RETURN count(n)&#34;</span><span class="p">,</span> </span></span><span class="line"><span class="cl"> <span class="s2">&#34;MATCH (n) RETURN labels(n), count(*) GROUP BY labels(n)&#34;</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="k">for</span> <span class="n">query</span> <span class="ow">in</span> <span class="n">queries</span><span class="p">:</span> </span></span><span class="line"><span class="cl"> <span class="n">subprocess</span><span class="o">.</span><span class="n">run</span><span class="p">([</span><span class="s2">&#34;./geode&#34;</span><span class="p">,</span> <span class="s2">&#34;shell&#34;</span><span class="p">,</span> <span class="s2">&#34;--host&#34;</span><span class="p">,</span> <span class="n">host</span><span class="p">,</span> <span class="s2">&#34;-c&#34;</span><span class="p">,</span> <span class="n">query</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="vm">__name__</span> <span class="o">==</span> <span class="s2">&#34;__main__&#34;</span><span class="p">:</span> </span></span><span class="line"><span class="cl"> <span class="n">run_dr_test</span><span class="p">()</span> </span></span></code></pre></div> <h3 id="backup-monitoring" class="position-relative d-flex align-items-center group"> <span>Backup 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="backup-monitoring" aria-haspopup="dialog" aria-label="Share link: Backup 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="backup-status-metrics" class="position-relative d-flex align-items-center group"> <span>Backup Status 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="backup-status-metrics" aria-haspopup="dialog" aria-label="Share link: Backup Status 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-bash" data-lang="bash"><span class="line"><span class="cl"><span class="c1"># Prometheus metrics</span> </span></span><span class="line"><span class="cl">curl http://localhost:3141/metrics <span class="p">|</span> grep backup </span></span><span class="line"><span class="cl"> </span></span><span class="line"><span class="cl"><span class="c1"># Example metrics</span> </span></span><span class="line"><span class="cl">geode_backup_last_full_timestamp <span class="m">1706140800</span> </span></span><span class="line"><span class="cl">geode_backup_last_full_duration_seconds <span class="m">847</span> </span></span><span class="line"><span class="cl">geode_backup_last_full_size_bytes <span class="m">13421772800</span> </span></span><span class="line"><span class="cl">geode_backup_last_incremental_timestamp <span class="m">1706227200</span> </span></span><span class="line"><span class="cl">geode_backup_last_incremental_size_bytes <span class="m">245366784</span> </span></span><span class="line"><span class="cl">geode_backup_wal_archive_lag_bytes <span class="m">0</span> </span></span><span class="line"><span class="cl">geode_backup_wal_archive_lag_seconds <span class="m">12</span> </span></span></code></pre></div> <h4 id="backup-health-checks" class="position-relative d-flex align-items-center group"> <span>Backup Health Checks</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="backup-health-checks" aria-haspopup="dialog" aria-label="Share link: Backup Health Checks"> <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-gql" data-lang="gql"><span class="line"><span class="cl"><span class="err">--</span><span class="w"> </span><span class="py">Check</span><span class="w"> </span><span class="py">backup</span><span class="w"> </span><span class="py">status</span><span class="w"> </span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="py">SELECT</span><span class="w"> </span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="py">backup_type</span><span class="p">,</span><span class="w"> </span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="py">last_backup_time</span><span class="p">,</span><span class="w"> </span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="py">last_backup_size_mb</span><span class="p">,</span><span class="w"> </span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="py">last_backup_duration_seconds</span><span class="p">,</span><span class="w"> </span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="py">backup_count_24h</span><span class="p">,</span><span class="w"> </span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="py">oldest_backup_time</span><span class="w"> </span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="py">FROM</span><span class="w"> </span><span class="py">system</span><span class="err">.</span><span class="py">backup_status</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">Check</span><span class="w"> </span><span class="py">WAL</span><span class="w"> </span><span class="py">archiving</span><span class="w"> </span><span class="py">health</span><span class="w"> </span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="py">SELECT</span><span class="w"> </span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="py">current_wal_file</span><span class="p">,</span><span class="w"> </span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="py">last_archived_file</span><span class="p">,</span><span class="w"> </span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="py">archive_lag_bytes</span><span class="p">,</span><span class="w"> </span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="py">archive_lag_seconds</span><span class="p">,</span><span class="w"> </span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="py">archive_failures_24h</span><span class="w"> </span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="py">FROM</span><span class="w"> </span><span class="py">system</span><span class="err">.</span><span class="py">wal_archiving_status</span><span class="err">;</span><span class="w"> </span></span></span></code></pre></div> <h4 id="alerting-rules" class="position-relative d-flex align-items-center group"> <span>Alerting 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="alerting-rules" aria-haspopup="dialog" aria-label="Share link: Alerting 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><div class="highlight"><pre tabindex="0" class="chroma"><code class="language-yaml" data-lang="yaml"><span class="line"><span class="cl"><span class="c"># Prometheus alerting rules for backups</span><span class="w"> </span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="nt">groups</span><span class="p">:</span><span class="w"> </span></span></span><span class="line"><span class="cl"><span class="w"> </span>- <span class="nt">name</span><span class="p">:</span><span class="w"> </span><span class="l">geode_backup_alerts</span><span class="w"> </span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="nt">rules</span><span class="p">:</span><span class="w"> </span></span></span><span class="line"><span class="cl"><span class="w"> </span>- <span class="nt">alert</span><span class="p">:</span><span class="w"> </span><span class="l">BackupOverdue</span><span class="w"> </span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="nt">expr</span><span class="p">:</span><span class="w"> </span><span class="l">time() - geode_backup_last_full_timestamp &gt; 86400 * 8</span><span class="w"> </span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="nt">for</span><span class="p">:</span><span class="w"> </span><span class="l">1h</span><span class="w"> </span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="nt">labels</span><span class="p">:</span><span class="w"> </span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="nt">severity</span><span class="p">:</span><span class="w"> </span><span class="l">warning</span><span class="w"> </span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="nt">annotations</span><span class="p">:</span><span class="w"> </span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="nt">summary</span><span class="p">:</span><span class="w"> </span><span class="s2">&#34;Full backup overdue&#34;</span><span class="w"> </span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="nt">description</span><span class="p">:</span><span class="w"> </span><span class="s2">&#34;Last full backup was {{ $value | humanizeDuration }} ago&#34;</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="nt">alert</span><span class="p">:</span><span class="w"> </span><span class="l">BackupFailed</span><span class="w"> </span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="nt">expr</span><span class="p">:</span><span class="w"> </span><span class="l">geode_backup_last_status != 1</span><span class="w"> </span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="nt">for</span><span class="p">:</span><span class="w"> </span><span class="l">5m</span><span class="w"> </span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="nt">labels</span><span class="p">:</span><span class="w"> </span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="nt">severity</span><span class="p">:</span><span class="w"> </span><span class="l">critical</span><span class="w"> </span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="nt">annotations</span><span class="p">:</span><span class="w"> </span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="nt">summary</span><span class="p">:</span><span class="w"> </span><span class="s2">&#34;Backup failed&#34;</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="nt">alert</span><span class="p">:</span><span class="w"> </span><span class="l">WALArchiveLagHigh</span><span class="w"> </span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="nt">expr</span><span class="p">:</span><span class="w"> </span><span class="l">geode_backup_wal_archive_lag_seconds &gt; 300</span><span class="w"> </span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="nt">for</span><span class="p">:</span><span class="w"> </span><span class="l">5m</span><span class="w"> </span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="nt">labels</span><span class="p">:</span><span class="w"> </span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="nt">severity</span><span class="p">:</span><span class="w"> </span><span class="l">warning</span><span class="w"> </span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="nt">annotations</span><span class="p">:</span><span class="w"> </span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="nt">summary</span><span class="p">:</span><span class="w"> </span><span class="s2">&#34;WAL archive lag is high&#34;</span><span class="w"> </span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="nt">description</span><span class="p">:</span><span class="w"> </span><span class="s2">&#34;WAL archiving is {{ $value }}s behind&#34;</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="nt">alert</span><span class="p">:</span><span class="w"> </span><span class="l">WALArchiveFailed</span><span class="w"> </span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="nt">expr</span><span class="p">:</span><span class="w"> </span><span class="l">increase(geode_backup_wal_archive_failures_total[1h]) &gt; 0</span><span class="w"> </span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="nt">for</span><span class="p">:</span><span class="w"> </span><span class="l">5m</span><span class="w"> </span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="nt">labels</span><span class="p">:</span><span class="w"> </span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="nt">severity</span><span class="p">:</span><span class="w"> </span><span class="l">critical</span><span class="w"> </span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="nt">annotations</span><span class="p">:</span><span class="w"> </span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="nt">summary</span><span class="p">:</span><span class="w"> </span><span class="s2">&#34;WAL archiving failed&#34;</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="nt">alert</span><span class="p">:</span><span class="w"> </span><span class="l">BackupStorageLow</span><span class="w"> </span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="nt">expr</span><span class="p">:</span><span class="w"> </span><span class="l">geode_backup_storage_free_bytes / geode_backup_storage_total_bytes &lt; 0.1</span><span class="w"> </span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="nt">for</span><span class="p">:</span><span class="w"> </span><span class="l">1h</span><span class="w"> </span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="nt">labels</span><span class="p">:</span><span class="w"> </span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="nt">severity</span><span class="p">:</span><span class="w"> </span><span class="l">warning</span><span class="w"> </span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="nt">annotations</span><span class="p">:</span><span class="w"> </span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="nt">summary</span><span class="p">:</span><span class="w"> </span><span class="s2">&#34;Backup storage below 10%&#34;</span><span class="w"> </span></span></span></code></pre></div> <h3 id="backup-validation" class="position-relative d-flex align-items-center group"> <span>Backup Validation</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="backup-validation" aria-haspopup="dialog" aria-label="Share link: Backup Validation"> <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="automated-backup-testing" class="position-relative d-flex align-items-center group"> <span>Automated Backup Testing</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="automated-backup-testing" aria-haspopup="dialog" aria-label="Share link: Automated Backup Testing"> <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>Regularly verify backup integrity:</p> <div class="highlight"><pre tabindex="0" class="chroma"><code class="language-bash" data-lang="bash"><span class="line"><span class="cl"><span class="c1"># Verify backup integrity</span> </span></span><span class="line"><span class="cl">./geode backup verify <span class="se">\ </span></span></span><span class="line"><span class="cl"><span class="se"></span> --input /backups/geode/full-20260125 <span class="se">\ </span></span></span><span class="line"><span class="cl"><span class="se"></span> --check-checksums <span class="se">\ </span></span></span><span class="line"><span class="cl"><span class="se"></span> --check-consistency </span></span><span class="line"><span class="cl"> </span></span><span class="line"><span class="cl"><span class="c1"># Test restore to temporary location</span> </span></span><span class="line"><span class="cl">./geode backup test-restore <span class="se">\ </span></span></span><span class="line"><span class="cl"><span class="se"></span> --input /backups/geode/full-20260125 <span class="se">\ </span></span></span><span class="line"><span class="cl"><span class="se"></span> --temp-dir /tmp/geode-restore-test <span class="se">\ </span></span></span><span class="line"><span class="cl"><span class="se"></span> --run-queries <span class="s2">&#34;MATCH (n) RETURN count(n)&#34;</span> </span></span></code></pre></div><p><strong>Automated validation script</strong>:</p> <div class="highlight"><pre tabindex="0" class="chroma"><code class="language-bash" data-lang="bash"><span class="line"><span class="cl"><span class="cp">#!/bin/bash </span></span></span><span class="line"><span class="cl"><span class="cp"></span><span class="c1"># /etc/geode/scripts/validate-backup.sh</span> </span></span><span class="line"><span class="cl"> </span></span><span class="line"><span class="cl"><span class="nv">BACKUP_DIR</span><span class="o">=</span><span class="s2">&#34;/backups/geode&#34;</span> </span></span><span class="line"><span class="cl"><span class="nv">TEST_DIR</span><span class="o">=</span><span class="s2">&#34;/tmp/geode-backup-test&#34;</span> </span></span><span class="line"><span class="cl"><span class="nv">ALERT_EMAIL</span><span class="o">=</span><span class="s2">&#34;[email protected]&#34;</span> </span></span><span class="line"><span class="cl"> </span></span><span class="line"><span class="cl"><span class="c1"># Find latest full backup</span> </span></span><span class="line"><span class="cl"><span class="nv">LATEST_FULL</span><span class="o">=</span><span class="k">$(</span>ls -t <span class="nv">$BACKUP_DIR</span>/full-* <span class="p">|</span> head -1<span class="k">)</span> </span></span><span class="line"><span class="cl"> </span></span><span class="line"><span class="cl"><span class="nb">echo</span> <span class="s2">&#34;Validating backup: </span><span class="nv">$LATEST_FULL</span><span class="s2">&#34;</span> </span></span><span class="line"><span class="cl"> </span></span><span class="line"><span class="cl"><span class="c1"># Verify checksums</span> </span></span><span class="line"><span class="cl"><span class="k">if</span> ! ./geode backup verify --input <span class="s2">&#34;</span><span class="nv">$LATEST_FULL</span><span class="s2">&#34;</span> --check-checksums<span class="p">;</span> <span class="k">then</span> </span></span><span class="line"><span class="cl"> <span class="nb">echo</span> <span class="s2">&#34;CRITICAL: Backup checksum verification failed!&#34;</span> <span class="p">|</span> mail -s <span class="s2">&#34;Backup Alert&#34;</span> <span class="nv">$ALERT_EMAIL</span> </span></span><span class="line"><span class="cl"> <span class="nb">exit</span> <span class="m">1</span> </span></span><span class="line"><span class="cl"><span class="k">fi</span> </span></span><span class="line"><span class="cl"> </span></span><span class="line"><span class="cl"><span class="c1"># Test restore</span> </span></span><span class="line"><span class="cl">rm -rf <span class="nv">$TEST_DIR</span> </span></span><span class="line"><span class="cl">mkdir -p <span class="nv">$TEST_DIR</span> </span></span><span class="line"><span class="cl"> </span></span><span class="line"><span class="cl"><span class="k">if</span> ! ./geode backup restore --input <span class="s2">&#34;</span><span class="nv">$LATEST_FULL</span><span class="s2">&#34;</span> --data-dir <span class="s2">&#34;</span><span class="nv">$TEST_DIR</span><span class="s2">&#34;</span> 2&gt;/dev/null<span class="p">;</span> <span class="k">then</span> </span></span><span class="line"><span class="cl"> <span class="nb">echo</span> <span class="s2">&#34;CRITICAL: Backup restore test failed!&#34;</span> <span class="p">|</span> mail -s <span class="s2">&#34;Backup Alert&#34;</span> <span class="nv">$ALERT_EMAIL</span> </span></span><span class="line"><span class="cl"> <span class="nb">exit</span> <span class="m">1</span> </span></span><span class="line"><span class="cl"><span class="k">fi</span> </span></span><span class="line"><span class="cl"> </span></span><span class="line"><span class="cl"><span class="c1"># Start temporary instance and verify</span> </span></span><span class="line"><span class="cl">./geode serve --data-dir <span class="s2">&#34;</span><span class="nv">$TEST_DIR</span><span class="s2">&#34;</span> --listen 127.0.0.1:13141 <span class="p">&amp;</span> </span></span><span class="line"><span class="cl"><span class="nv">TEMP_PID</span><span class="o">=</span><span class="nv">$!</span> </span></span><span class="line"><span class="cl">sleep <span class="m">10</span> </span></span><span class="line"><span class="cl"> </span></span><span class="line"><span class="cl"><span class="c1"># Run verification queries</span> </span></span><span class="line"><span class="cl"><span class="nv">NODE_COUNT</span><span class="o">=</span><span class="k">$(</span>./geode shell --host 127.0.0.1:13141 -c <span class="s2">&#34;MATCH (n) RETURN count(n)&#34;</span> 2&gt;/dev/null<span class="k">)</span> </span></span><span class="line"><span class="cl"> </span></span><span class="line"><span class="cl"><span class="c1"># Cleanup</span> </span></span><span class="line"><span class="cl"><span class="nb">kill</span> <span class="nv">$TEMP_PID</span> 2&gt;/dev/null </span></span><span class="line"><span class="cl">rm -rf <span class="nv">$TEST_DIR</span> </span></span><span class="line"><span class="cl"> </span></span><span class="line"><span class="cl"><span class="nb">echo</span> <span class="s2">&#34;Backup validation successful. Node count: </span><span class="nv">$NODE_COUNT</span><span class="s2">&#34;</span> </span></span></code></pre></div> <h4 id="retention-management" class="position-relative d-flex align-items-center group"> <span>Retention 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="retention-management" aria-haspopup="dialog" aria-label="Share link: Retention 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><p>Configure backup retention policies:</p> <div class="highlight"><pre tabindex="0" class="chroma"><code class="language-toml" data-lang="toml"><span class="line"><span class="cl"><span class="p">[</span><span class="nx">backup</span><span class="p">.</span><span class="nx">retention</span><span class="p">]</span> </span></span><span class="line"><span class="cl"><span class="c"># Keep full backups for 30 days</span> </span></span><span class="line"><span class="cl"><span class="nx">full_retention_days</span> <span class="p">=</span> <span class="mi">30</span> </span></span><span class="line"><span class="cl"><span class="nx">full_min_count</span> <span class="p">=</span> <span class="mi">4</span> <span class="c"># Keep at least 4 full backups</span> </span></span><span class="line"><span class="cl"> </span></span><span class="line"><span class="cl"><span class="c"># Keep incremental backups for 7 days</span> </span></span><span class="line"><span class="cl"><span class="nx">incremental_retention_days</span> <span class="p">=</span> <span class="mi">7</span> </span></span><span class="line"><span class="cl"> </span></span><span class="line"><span class="cl"><span class="c"># Keep WAL archives for 14 days</span> </span></span><span class="line"><span class="cl"><span class="nx">wal_retention_days</span> <span class="p">=</span> <span class="mi">14</span> </span></span><span class="line"><span class="cl"> </span></span><span class="line"><span class="cl"><span class="c"># Automatic cleanup</span> </span></span><span class="line"><span class="cl"><span class="nx">auto_cleanup</span> <span class="p">=</span> <span class="kc">true</span> </span></span><span class="line"><span class="cl"><span class="nx">cleanup_schedule</span> <span class="p">=</span> <span class="s2">&#34;0 4 * * *&#34;</span> <span class="c"># 4 AM daily</span> </span></span></code></pre></div><div class="highlight"><pre tabindex="0" class="chroma"><code class="language-bash" data-lang="bash"><span class="line"><span class="cl"><span class="c1"># Manual cleanup</span> </span></span><span class="line"><span class="cl">./geode backup cleanup <span class="se">\ </span></span></span><span class="line"><span class="cl"><span class="se"></span> --older-than 30d <span class="se">\ </span></span></span><span class="line"><span class="cl"><span class="se"></span> --keep-min <span class="m">4</span> <span class="se">\ </span></span></span><span class="line"><span class="cl"><span class="se"></span> --dry-run <span class="c1"># Preview what will be deleted</span> </span></span><span class="line"><span class="cl"> </span></span><span class="line"><span class="cl"><span class="c1"># Actually delete</span> </span></span><span class="line"><span class="cl">./geode backup cleanup <span class="se">\ </span></span></span><span class="line"><span class="cl"><span class="se"></span> --older-than 30d <span class="se">\ </span></span></span><span class="line"><span class="cl"><span class="se"></span> --keep-min <span class="m">4</span> </span></span></code></pre></div> <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="backup-strategy" class="position-relative d-flex align-items-center group"> <span>Backup Strategy</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="backup-strategy" aria-haspopup="dialog" aria-label="Share link: Backup Strategy"> <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>Follow 3-2-1 rule</strong>: 3 copies, 2 different media, 1 offsite</li> <li><strong>Automate backups</strong>: Never rely on manual processes</li> <li><strong>Encrypt sensitive data</strong>: Protect backups at rest</li> <li><strong>Test restores regularly</strong>: Untested backups may not work</li> <li><strong>Document procedures</strong>: Clear runbooks for emergencies</li> </ol> <h4 id="recovery-planning" class="position-relative d-flex align-items-center group"> <span>Recovery Planning</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="recovery-planning" aria-haspopup="dialog" aria-label="Share link: Recovery Planning"> <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>Define RTO/RPO</strong>: Based on business requirements</li> <li><strong>Choose appropriate strategy</strong>: Balance cost vs. recovery speed</li> <li><strong>Plan for different scenarios</strong>: Hardware failure, data corruption, disaster</li> <li><strong>Train team members</strong>: Everyone should know recovery procedures</li> <li><strong>Conduct regular drills</strong>: Practice makes perfect</li> </ol> <h4 id="monitoring-and-alerting" class="position-relative d-flex align-items-center group"> <span>Monitoring and Alerting</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="monitoring-and-alerting" aria-haspopup="dialog" aria-label="Share link: Monitoring and Alerting"> <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 backup success</strong>: Alert on failures immediately</li> <li><strong>Track backup duration</strong>: Detect performance degradation</li> <li><strong>Monitor storage capacity</strong>: Plan ahead for growth</li> <li><strong>Check WAL archiving</strong>: Ensure continuous protection</li> <li><strong>Validate backups</strong>: Automated integrity checks</li> </ol> <h4 id="security" class="position-relative d-flex align-items-center group"> <span>Security</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="security" aria-haspopup="dialog" aria-label="Share link: Security"> <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>Encrypt backups</strong>: Use strong encryption (AES-256)</li> <li><strong>Secure backup storage</strong>: Restrict access to backup locations</li> <li><strong>Audit backup access</strong>: Log who accesses backups</li> <li><strong>Rotate encryption keys</strong>: Regular key rotation policy</li> <li><strong>Test decryption</strong>: Verify you can decrypt backups</li> </ol> <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/high-availability/" >High Availability</a> - HA configuration and failover</li> <li><a href="/tags/backup/" >Backup</a> - Backup creation and management</li> <li><a href="/tags/replication/" >Replication</a> - Data replication strategies</li> <li><a href="/tags/distributed-systems/" >Distributed Systems</a> - Distributed architecture</li> <li><a href="/tags/operations/" >Operations</a> - Operational procedures</li> <li><a href="/tags/security/" >Security</a> - Data protection and encryption</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><ul> <li>Backup and Recovery Best Practices Guide</li> <li>Disaster Recovery Planning Handbook</li> <li>Point-in-Time Recovery Tutorial</li> <li>Backup Encryption Guide</li> <li>DR Testing Procedures</li> <li>Compliance and Backup Retention</li> </ul>

Related Articles