<!-- CANARY: REQ=REQ-DOCS-001; FEATURE="Docs"; ASPECT=Documentation; STATUS=TESTED; OWNER=docs; UPDATED=2026-01-28 --> <h2 id="upgrade-procedures" class="position-relative d-flex align-items-center group"> <span>Upgrade 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="upgrade-procedures" aria-haspopup="dialog" aria-label="Share link: Upgrade 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> </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>This guide covers safe upgrade procedures for Geode, including pre-upgrade planning, various upgrade strategies, and rollback procedures.</p> <blockquote> <p><strong>Release-line note (2026-03-30)</strong></p> <ul> <li>Current stable release: <code>v0.2.18</code></li> <li><code>main</code> already contains post-<code>v0.2.18</code> storage persistence and pager-encryption fixes</li> <li>Upgrades from older <code>v0.1.x</code> builds must account for the March 2026 storage transition: monolithic persistence -&gt; per-graph storage -&gt; graph-storage-backed persistence</li> </ul> </blockquote> <h3 id="overview" class="position-relative d-flex align-items-center group"> <span>Overview</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="overview" aria-haspopup="dialog" aria-label="Share link: Overview"> <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><p>Geode supports multiple upgrade strategies:</p> <table> <thead> <tr> <th>Strategy</th> <th>Downtime</th> <th>Complexity</th> <th>Use Case</th> </tr> </thead> <tbody> <tr> <td>In-place</td> <td>Minutes</td> <td>Low</td> <td>Development, small production</td> </tr> <tr> <td>Rolling</td> <td>Zero</td> <td>Medium</td> <td>Distributed clusters</td> </tr> <tr> <td>Blue-green</td> <td>Zero</td> <td>High</td> <td>Critical production</td> </tr> <tr> <td>Canary</td> <td>Zero</td> <td>High</td> <td>Large-scale deployments</td> </tr> </tbody> </table> <h3 id="pre-upgrade-planning" class="position-relative d-flex align-items-center group"> <span>Pre-Upgrade 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="pre-upgrade-planning" aria-haspopup="dialog" aria-label="Share link: Pre-Upgrade 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> </h3> <h4 id="compatibility-matrix" class="position-relative d-flex align-items-center group"> <span>Compatibility Matrix</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="compatibility-matrix" aria-haspopup="dialog" aria-label="Share link: Compatibility Matrix"> <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><table> <thead> <tr> <th>From Version</th> <th>To Version</th> <th>Upgrade Path</th> <th>Notes</th> </tr> </thead> <tbody> <tr> <td>0.2.14</td> <td><strong>0.2.18</strong></td> <td>Direct</td> <td>Stable patch upgrade</td> </tr> <tr> <td>0.2.0-0.2.13</td> <td><strong>0.2.18</strong></td> <td>Direct</td> <td>Review DSN graph binding and auth/TLS flags</td> </tr> <tr> <td>0.1.28-0.1.39</td> <td><strong>0.2.18</strong></td> <td>Direct with backup validation</td> <td>Per-graph storage already present; validate restart and graph binding behavior</td> </tr> <tr> <td>0.1.3-0.1.27</td> <td><strong>0.2.18</strong></td> <td>Staged / restore-tested</td> <td>Storage layout changed significantly across March 2026</td> </tr> </tbody> </table> <h4 id="pre-upgrade-checklist" class="position-relative d-flex align-items-center group"> <span>Pre-Upgrade Checklist</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="pre-upgrade-checklist" aria-haspopup="dialog" aria-label="Share link: Pre-Upgrade Checklist"> <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"># 1. Check current version</span> </span></span><span class="line"><span class="cl">geode --version </span></span><span class="line"><span class="cl"> </span></span><span class="line"><span class="cl"><span class="c1"># 2. Review release notes for target version</span> </span></span><span class="line"><span class="cl"><span class="c1"># https://geodedb.com/docs/releases/</span> </span></span><span class="line"><span class="cl"><span class="c1"># https://geodedb.com/docs/reference/changelog/</span> </span></span><span class="line"><span class="cl"> </span></span><span class="line"><span class="cl"><span class="c1"># 3. Check system requirements</span> </span></span><span class="line"><span class="cl"><span class="c1"># - Zig version compatibility</span> </span></span><span class="line"><span class="cl"><span class="c1"># - OS version compatibility</span> </span></span><span class="line"><span class="cl"><span class="c1"># - Hardware requirements</span> </span></span><span class="line"><span class="cl"> </span></span><span class="line"><span class="cl"><span class="c1"># 4. Verify backup status</span> </span></span><span class="line"><span class="cl">geode backup --dest s3://bucket/backups --list </span></span><span class="line"><span class="cl"> </span></span><span class="line"><span class="cl"><span class="c1"># 5. Create pre-upgrade backup</span> </span></span><span class="line"><span class="cl">geode backup <span class="se">\ </span></span></span><span class="line"><span class="cl"><span class="se"></span> --dest s3://bucket/backups <span class="se">\ </span></span></span><span class="line"><span class="cl"><span class="se"></span> --mode full <span class="se">\ </span></span></span><span class="line"><span class="cl"><span class="se"></span> --label <span class="s2">&#34;pre-upgrade-</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"># 6. Test upgrade in staging</span> </span></span><span class="line"><span class="cl"><span class="c1"># - Deploy to staging environment first</span> </span></span><span class="line"><span class="cl"><span class="c1"># - Run full test suite</span> </span></span><span class="line"><span class="cl"><span class="c1"># - Verify application compatibility</span> </span></span><span class="line"><span class="cl"><span class="c1"># - Verify graph counts and restart persistence after first boot</span> </span></span><span class="line"><span class="cl"><span class="c1"># - Verify DSN graph binding if clients use /graph in connection strings</span> </span></span><span class="line"><span class="cl"> </span></span><span class="line"><span class="cl"><span class="c1"># 7. Document current configuration</span> </span></span><span class="line"><span class="cl">cp /etc/geode/geode.yaml /etc/geode/geode.yaml.backup </span></span><span class="line"><span class="cl">geode config show &gt; config-dump.yaml </span></span><span class="line"><span class="cl"> </span></span><span class="line"><span class="cl"><span class="c1"># 8. Plan maintenance window (if required)</span> </span></span><span class="line"><span class="cl"><span class="c1"># - Notify stakeholders</span> </span></span><span class="line"><span class="cl"><span class="c1"># - Schedule window</span> </span></span><span class="line"><span class="cl"><span class="c1"># - Prepare rollback plan</span> </span></span></code></pre></div> <h4 id="breaking-changes-review" class="position-relative d-flex align-items-center group"> <span>Breaking Changes Review</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="breaking-changes-review" aria-haspopup="dialog" aria-label="Share link: Breaking Changes Review"> <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>Review breaking changes for each version:</p> <div class="highlight"><pre tabindex="0" class="chroma"><code class="language-yaml" data-lang="yaml"><span class="line"><span class="cl"><span class="c"># v0.1.x -&gt; v0.1.x Breaking Changes</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">authentication</span><span class="p">:</span><span class="w"> </span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="c"># Was: optional (auth_enabled: false by default)</span><span class="w"> </span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="c"># Now: required (auth_enabled: true by default)</span><span class="w"> </span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="nt">action</span><span class="p">:</span><span class="w"> </span><span class="l">Configure authentication or explicitly disable</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">tls</span><span class="p">:</span><span class="w"> </span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="c"># Was: auto_generate: true</span><span class="w"> </span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="c"># Now: auto_generate: false (secure by default)</span><span class="w"> </span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="nt">action</span><span class="p">:</span><span class="w"> </span><span class="l">Provide valid TLS certificates</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">hardcoded_credentials</span><span class="p">:</span><span class="w"> </span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="c"># Was: Default admin/admin credentials</span><span class="w"> </span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="c"># Now: Removed, must use environment variables</span><span class="w"> </span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="nt">action</span><span class="p">:</span><span class="w"> </span><span class="l">Set GEODE_ADMIN_USERNAME and GEODE_DEFAULT_PASSWORD</span><span class="w"> </span></span></span></code></pre></div> <h3 id="in-place-upgrade" class="position-relative d-flex align-items-center group"> <span>In-Place Upgrade</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="in-place-upgrade" aria-haspopup="dialog" aria-label="Share link: In-Place Upgrade"> <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><p>For single-node deployments or development environments.</p> <h4 id="procedure" class="position-relative d-flex align-items-center group"> <span>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="procedure" aria-haspopup="dialog" aria-label="Share link: 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><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"># in-place-upgrade.sh</span> </span></span><span class="line"><span class="cl"> </span></span><span class="line"><span class="cl"><span class="nb">set</span> -euo pipefail </span></span><span class="line"><span class="cl"> </span></span><span class="line"><span class="cl"><span class="nv">NEW_VERSION</span><span class="o">=</span><span class="s2">&#34;0.2.18&#34;</span> </span></span><span class="line"><span class="cl"><span class="nv">BACKUP_DIR</span><span class="o">=</span><span class="s2">&#34;/var/lib/geode/upgrade-backup-</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="nb">echo</span> <span class="s2">&#34;=== In-Place Upgrade to </span><span class="nv">$NEW_VERSION</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"># 1. Pre-flight checks</span> </span></span><span class="line"><span class="cl"><span class="nb">echo</span> <span class="s2">&#34;Running pre-flight checks...&#34;</span> </span></span><span class="line"><span class="cl">geode admin status </span></span><span class="line"><span class="cl">geode backup --dest s3://bucket/backups --list <span class="p">|</span> head -5 </span></span><span class="line"><span class="cl"> </span></span><span class="line"><span class="cl"><span class="c1"># 2. Create backup</span> </span></span><span class="line"><span class="cl"><span class="nb">echo</span> <span class="s2">&#34;Creating pre-upgrade backup...&#34;</span> </span></span><span class="line"><span class="cl">geode backup <span class="se">\ </span></span></span><span class="line"><span class="cl"><span class="se"></span> --dest s3://bucket/backups <span class="se">\ </span></span></span><span class="line"><span class="cl"><span class="se"></span> --mode full <span class="se">\ </span></span></span><span class="line"><span class="cl"><span class="se"></span> --label <span class="s2">&#34;pre-upgrade-</span><span class="nv">$NEW_VERSION</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"># 3. Stop server gracefully</span> </span></span><span class="line"><span class="cl"><span class="nb">echo</span> <span class="s2">&#34;Stopping Geode server...&#34;</span> </span></span><span class="line"><span class="cl">sudo systemctl stop geode </span></span><span class="line"><span class="cl"> </span></span><span class="line"><span class="cl"><span class="c1"># Wait for clean shutdown</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"># 4. Backup binaries and config</span> </span></span><span class="line"><span class="cl"><span class="nb">echo</span> <span class="s2">&#34;Backing up current installation...&#34;</span> </span></span><span class="line"><span class="cl">mkdir -p <span class="s2">&#34;</span><span class="nv">$BACKUP_DIR</span><span class="s2">&#34;</span> </span></span><span class="line"><span class="cl">cp /usr/local/bin/geode <span class="s2">&#34;</span><span class="nv">$BACKUP_DIR</span><span class="s2">/&#34;</span> </span></span><span class="line"><span class="cl">cp /etc/geode/geode.yaml <span class="s2">&#34;</span><span class="nv">$BACKUP_DIR</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"># 5. Install new version</span> </span></span><span class="line"><span class="cl"><span class="nb">echo</span> <span class="s2">&#34;Installing new version...&#34;</span> </span></span><span class="line"><span class="cl"><span class="c1"># Option A: From release binary</span> </span></span><span class="line"><span class="cl">curl -L <span class="s2">&#34;https://github.com/codeprosorg/geode/releases/download/v</span><span class="nv">$NEW_VERSION</span><span class="s2">/geode-linux-amd64&#34;</span> <span class="se">\ </span></span></span><span class="line"><span class="cl"><span class="se"></span> -o /usr/local/bin/geode </span></span><span class="line"><span class="cl">chmod +x /usr/local/bin/geode </span></span><span class="line"><span class="cl"> </span></span><span class="line"><span class="cl"><span class="c1"># Option B: Build from source</span> </span></span><span class="line"><span class="cl"><span class="c1"># git clone --branch &#34;v$NEW_VERSION&#34; https://github.com/codeprosorg/geode /tmp/geode</span> </span></span><span class="line"><span class="cl"><span class="c1"># cd /tmp/geode &amp;&amp; make release</span> </span></span><span class="line"><span class="cl"><span class="c1"># cp ./zig-out/bin/geode /usr/local/bin/geode</span> </span></span><span class="line"><span class="cl"> </span></span><span class="line"><span class="cl"><span class="c1"># 6. Verify new version</span> </span></span><span class="line"><span class="cl"><span class="nb">echo</span> <span class="s2">&#34;Verifying installation...&#34;</span> </span></span><span class="line"><span class="cl">geode --version </span></span><span class="line"><span class="cl"> </span></span><span class="line"><span class="cl"><span class="c1"># 7. Update configuration (if needed)</span> </span></span><span class="line"><span class="cl"><span class="nb">echo</span> <span class="s2">&#34;Updating configuration...&#34;</span> </span></span><span class="line"><span class="cl"><span class="c1"># Apply any required config changes for new version</span> </span></span><span class="line"><span class="cl"><span class="c1"># For v0.1.x -&gt; v0.2.x, validate storage and DSN behavior in staging first</span> </span></span><span class="line"><span class="cl"> </span></span><span class="line"><span class="cl"><span class="c1"># 8. Start server</span> </span></span><span class="line"><span class="cl"><span class="nb">echo</span> <span class="s2">&#34;Starting Geode server...&#34;</span> </span></span><span class="line"><span class="cl">sudo systemctl start geode </span></span><span class="line"><span class="cl"> </span></span><span class="line"><span class="cl"><span class="c1"># 9. Wait for startup</span> </span></span><span class="line"><span class="cl"><span class="nb">echo</span> <span class="s2">&#34;Waiting for server to start...&#34;</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"># 10. Verify health</span> </span></span><span class="line"><span class="cl"><span class="nb">echo</span> <span class="s2">&#34;Verifying server health...&#34;</span> </span></span><span class="line"><span class="cl">geode admin status </span></span><span class="line"><span class="cl">geode query <span class="s2">&#34;RETURN 1 AS health_check&#34;</span> </span></span><span class="line"><span class="cl"> </span></span><span class="line"><span class="cl"><span class="c1"># 11. Run smoke tests</span> </span></span><span class="line"><span class="cl"><span class="nb">echo</span> <span class="s2">&#34;Running smoke tests...&#34;</span> </span></span><span class="line"><span class="cl"><span class="c1"># Add application-specific tests here</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;=== Upgrade Complete ===&#34;</span> </span></span></code></pre></div> <h4 id="rollback-procedure" class="position-relative d-flex align-items-center group"> <span>Rollback 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="rollback-procedure" aria-haspopup="dialog" aria-label="Share link: Rollback 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><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"># in-place-rollback.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;/var/lib/geode/upgrade-backup-20260128&#34;</span> <span class="c1"># Adjust date</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;=== Rolling Back Upgrade ===&#34;</span> </span></span><span class="line"><span class="cl"> </span></span><span class="line"><span class="cl"><span class="c1"># 1. Stop server</span> </span></span><span class="line"><span class="cl">sudo systemctl stop geode </span></span><span class="line"><span class="cl"> </span></span><span class="line"><span class="cl"><span class="c1"># 2. Restore binary</span> </span></span><span class="line"><span class="cl">cp <span class="s2">&#34;</span><span class="nv">$BACKUP_DIR</span><span class="s2">/geode&#34;</span> /usr/local/bin/geode </span></span><span class="line"><span class="cl"> </span></span><span class="line"><span class="cl"><span class="c1"># 3. Restore configuration</span> </span></span><span class="line"><span class="cl">cp <span class="s2">&#34;</span><span class="nv">$BACKUP_DIR</span><span class="s2">/geode.yaml&#34;</span> /etc/geode/geode.yaml </span></span><span class="line"><span class="cl"> </span></span><span class="line"><span class="cl"><span class="c1"># 4. Start server</span> </span></span><span class="line"><span class="cl">sudo systemctl start geode </span></span><span class="line"><span class="cl"> </span></span><span class="line"><span class="cl"><span class="c1"># 5. Verify</span> </span></span><span class="line"><span class="cl">geode --version </span></span><span class="line"><span class="cl">geode admin status </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;=== Rollback Complete ===&#34;</span> </span></span></code></pre></div> <h3 id="rolling-upgrade" class="position-relative d-flex align-items-center group"> <span>Rolling Upgrade</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="rolling-upgrade" aria-haspopup="dialog" aria-label="Share link: Rolling Upgrade"> <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><p>For distributed clusters with zero downtime.</p> <h4 id="prerequisites" class="position-relative d-flex align-items-center group"> <span>Prerequisites</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="prerequisites" aria-haspopup="dialog" aria-label="Share link: Prerequisites"> <i class="fa-sharp-duotone fa-solid fa-share-nodes" aria-hidden="true" style="font-size: 0.8em;"></i> <span class="visually-hidden">Share link</span> </button> </h4><ul> <li>At least 3 nodes in cluster</li> <li>Replication configured</li> <li>Health checks enabled</li> </ul> <h4 id="procedure-1" class="position-relative d-flex align-items-center group"> <span>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="procedure-1" aria-haspopup="dialog" aria-label="Share link: 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><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"># rolling-upgrade.sh</span> </span></span><span class="line"><span class="cl"> </span></span><span class="line"><span class="cl"><span class="nb">set</span> -euo pipefail </span></span><span class="line"><span class="cl"> </span></span><span class="line"><span class="cl"><span class="nv">NEW_VERSION</span><span class="o">=</span><span class="s2">&#34;0.2.18&#34;</span> </span></span><span class="line"><span class="cl"><span class="nv">NODES</span><span class="o">=(</span><span class="s2">&#34;geode-node1&#34;</span> <span class="s2">&#34;geode-node2&#34;</span> <span class="s2">&#34;geode-node3&#34;</span><span class="o">)</span> </span></span><span class="line"><span class="cl"><span class="nv">GEODE_BIN_URL</span><span class="o">=</span><span class="s2">&#34;https://releases.geodedb.com/v</span><span class="nv">$NEW_VERSION</span><span class="s2">/geode-linux-amd64&#34;</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;=== Rolling Upgrade to </span><span class="nv">$NEW_VERSION</span><span class="s2"> ===&#34;</span> </span></span><span class="line"><span class="cl"><span class="nb">echo</span> <span class="s2">&#34;Nodes: </span><span class="si">${</span><span class="nv">NODES</span><span class="p">[*]</span><span class="si">}</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"># Download new binary once</span> </span></span><span class="line"><span class="cl"><span class="nb">echo</span> <span class="s2">&#34;Downloading new binary...&#34;</span> </span></span><span class="line"><span class="cl">curl -L <span class="s2">&#34;</span><span class="nv">$GEODE_BIN_URL</span><span class="s2">&#34;</span> -o /tmp/geode-<span class="nv">$NEW_VERSION</span> </span></span><span class="line"><span class="cl">chmod +x /tmp/geode-<span class="nv">$NEW_VERSION</span> </span></span><span class="line"><span class="cl"> </span></span><span class="line"><span class="cl"><span class="c1"># Upgrade each node</span> </span></span><span class="line"><span class="cl"><span class="k">for</span> NODE in <span class="s2">&#34;</span><span class="si">${</span><span class="nv">NODES</span><span class="p">[@]</span><span class="si">}</span><span class="s2">&#34;</span><span class="p">;</span> <span class="k">do</span> </span></span><span class="line"><span class="cl"> <span class="nb">echo</span> <span class="s2">&#34;&#34;</span> </span></span><span class="line"><span class="cl"> <span class="nb">echo</span> <span class="s2">&#34;=== Upgrading </span><span class="nv">$NODE</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"># 1. Check node is healthy</span> </span></span><span class="line"><span class="cl"> <span class="nb">echo</span> <span class="s2">&#34;Checking node health...&#34;</span> </span></span><span class="line"><span class="cl"> ssh <span class="s2">&#34;</span><span class="nv">$NODE</span><span class="s2">&#34;</span> <span class="s2">&#34;geode admin status&#34;</span> </span></span><span class="line"><span class="cl"> </span></span><span class="line"><span class="cl"> <span class="c1"># 2. Check cluster has quorum without this node</span> </span></span><span class="line"><span class="cl"> <span class="nv">HEALTHY_NODES</span><span class="o">=</span><span class="k">$(</span>ssh <span class="s2">&#34;</span><span class="si">${</span><span class="nv">NODES</span><span class="p">[0]</span><span class="si">}</span><span class="s2">&#34;</span> <span class="s2">&#34;geode admin cluster-status --format json&#34;</span> <span class="p">|</span> <span class="se">\ </span></span></span><span class="line"><span class="cl"><span class="se"></span> jq <span class="s1">&#39;[.nodes[] | select(.status == &#34;healthy&#34;)] | length&#39;</span><span class="k">)</span> </span></span><span class="line"><span class="cl"> </span></span><span class="line"><span class="cl"> <span class="k">if</span> <span class="o">[</span> <span class="s2">&#34;</span><span class="nv">$HEALTHY_NODES</span><span class="s2">&#34;</span> -lt <span class="m">2</span> <span class="o">]</span><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;ERROR: Not enough healthy nodes. Aborting.&#34;</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"># 3. Drain connections from node</span> </span></span><span class="line"><span class="cl"> <span class="nb">echo</span> <span class="s2">&#34;Draining connections...&#34;</span> </span></span><span class="line"><span class="cl"> ssh <span class="s2">&#34;</span><span class="nv">$NODE</span><span class="s2">&#34;</span> <span class="s2">&#34;geode admin drain --timeout 60s&#34;</span> </span></span><span class="line"><span class="cl"> </span></span><span class="line"><span class="cl"> <span class="c1"># 4. Stop node</span> </span></span><span class="line"><span class="cl"> <span class="nb">echo</span> <span class="s2">&#34;Stopping node...&#34;</span> </span></span><span class="line"><span class="cl"> ssh <span class="s2">&#34;</span><span class="nv">$NODE</span><span class="s2">&#34;</span> <span class="s2">&#34;sudo systemctl stop geode&#34;</span> </span></span><span class="line"><span class="cl"> </span></span><span class="line"><span class="cl"> <span class="c1"># 5. Copy new binary</span> </span></span><span class="line"><span class="cl"> <span class="nb">echo</span> <span class="s2">&#34;Installing new version...&#34;</span> </span></span><span class="line"><span class="cl"> scp /tmp/geode-<span class="nv">$NEW_VERSION</span> <span class="s2">&#34;</span><span class="nv">$NODE</span><span class="s2">:/tmp/geode&#34;</span> </span></span><span class="line"><span class="cl"> ssh <span class="s2">&#34;</span><span class="nv">$NODE</span><span class="s2">&#34;</span> <span class="s2">&#34;sudo cp /tmp/geode /usr/local/bin/geode&#34;</span> </span></span><span class="line"><span class="cl"> </span></span><span class="line"><span class="cl"> <span class="c1"># 6. Update configuration if needed</span> </span></span><span class="line"><span class="cl"> <span class="c1"># ssh &#34;$NODE&#34; &#34;geode config migrate --from 0.17.x --to 0.18.x&#34;</span> </span></span><span class="line"><span class="cl"> </span></span><span class="line"><span class="cl"> <span class="c1"># 7. Start node</span> </span></span><span class="line"><span class="cl"> <span class="nb">echo</span> <span class="s2">&#34;Starting node...&#34;</span> </span></span><span class="line"><span class="cl"> ssh <span class="s2">&#34;</span><span class="nv">$NODE</span><span class="s2">&#34;</span> <span class="s2">&#34;sudo systemctl start geode&#34;</span> </span></span><span class="line"><span class="cl"> </span></span><span class="line"><span class="cl"> <span class="c1"># 8. Wait for node to rejoin cluster</span> </span></span><span class="line"><span class="cl"> <span class="nb">echo</span> <span class="s2">&#34;Waiting for node to rejoin...&#34;</span> </span></span><span class="line"><span class="cl"> <span class="k">for</span> i in <span class="o">{</span>1..30<span class="o">}</span><span class="p">;</span> <span class="k">do</span> </span></span><span class="line"><span class="cl"> <span class="nv">STATUS</span><span class="o">=</span><span class="k">$(</span>ssh <span class="s2">&#34;</span><span class="nv">$NODE</span><span class="s2">&#34;</span> <span class="s2">&#34;geode admin status --format json 2&gt;/dev/null&#34;</span> <span class="p">|</span> <span class="se">\ </span></span></span><span class="line"><span class="cl"><span class="se"></span> jq -r <span class="s1">&#39;.status&#39;</span> 2&gt;/dev/null <span class="o">||</span> <span class="nb">echo</span> <span class="s2">&#34;starting&#34;</span><span class="k">)</span> </span></span><span class="line"><span class="cl"> <span class="k">if</span> <span class="o">[</span> <span class="s2">&#34;</span><span class="nv">$STATUS</span><span class="s2">&#34;</span> <span class="o">==</span> <span class="s2">&#34;healthy&#34;</span> <span class="o">]</span><span class="p">;</span> <span class="k">then</span> </span></span><span class="line"><span class="cl"> <span class="nb">break</span> </span></span><span class="line"><span class="cl"> <span class="k">fi</span> </span></span><span class="line"><span class="cl"> <span class="nb">echo</span> <span class="s2">&#34; Waiting... (</span><span class="nv">$i</span><span class="s2">/30)&#34;</span> </span></span><span class="line"><span class="cl"> sleep <span class="m">10</span> </span></span><span class="line"><span class="cl"> <span class="k">done</span> </span></span><span class="line"><span class="cl"> </span></span><span class="line"><span class="cl"> <span class="c1"># 9. Verify node is healthy</span> </span></span><span class="line"><span class="cl"> <span class="nb">echo</span> <span class="s2">&#34;Verifying node health...&#34;</span> </span></span><span class="line"><span class="cl"> ssh <span class="s2">&#34;</span><span class="nv">$NODE</span><span class="s2">&#34;</span> <span class="s2">&#34;geode --version&#34;</span> </span></span><span class="line"><span class="cl"> ssh <span class="s2">&#34;</span><span class="nv">$NODE</span><span class="s2">&#34;</span> <span class="s2">&#34;geode admin status&#34;</span> </span></span><span class="line"><span class="cl"> </span></span><span class="line"><span class="cl"> <span class="c1"># 10. Verify cluster health</span> </span></span><span class="line"><span class="cl"> <span class="nb">echo</span> <span class="s2">&#34;Verifying cluster health...&#34;</span> </span></span><span class="line"><span class="cl"> ssh <span class="s2">&#34;</span><span class="si">${</span><span class="nv">NODES</span><span class="p">[0]</span><span class="si">}</span><span class="s2">&#34;</span> <span class="s2">&#34;geode admin cluster-status&#34;</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;=== </span><span class="nv">$NODE</span><span class="s2"> upgraded successfully ===&#34;</span> </span></span><span class="line"><span class="cl"> </span></span><span class="line"><span class="cl"> <span class="c1"># Wait before next node (allow stabilization)</span> </span></span><span class="line"><span class="cl"> <span class="k">if</span> <span class="o">[</span> <span class="s2">&#34;</span><span class="nv">$NODE</span><span class="s2">&#34;</span> !<span class="o">=</span> <span class="s2">&#34;</span><span class="si">${</span><span class="nv">NODES</span><span class="p">[-1]</span><span class="si">}</span><span class="s2">&#34;</span> <span class="o">]</span><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;Waiting 60s before next node...&#34;</span> </span></span><span class="line"><span class="cl"> sleep <span class="m">60</span> </span></span><span class="line"><span class="cl"> <span class="k">fi</span> </span></span><span class="line"><span class="cl"><span class="k">done</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;&#34;</span> </span></span><span class="line"><span class="cl"><span class="nb">echo</span> <span class="s2">&#34;=== Rolling Upgrade Complete ===&#34;</span> </span></span><span class="line"><span class="cl"><span class="nb">echo</span> <span class="s2">&#34;All nodes running version </span><span class="nv">$NEW_VERSION</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"># Final verification</span> </span></span><span class="line"><span class="cl"><span class="k">for</span> NODE in <span class="s2">&#34;</span><span class="si">${</span><span class="nv">NODES</span><span class="p">[@]</span><span class="si">}</span><span class="s2">&#34;</span><span class="p">;</span> <span class="k">do</span> </span></span><span class="line"><span class="cl"> <span class="nv">VERSION</span><span class="o">=</span><span class="k">$(</span>ssh <span class="s2">&#34;</span><span class="nv">$NODE</span><span class="s2">&#34;</span> <span class="s2">&#34;geode --version&#34;</span> <span class="p">|</span> head -1<span class="k">)</span> </span></span><span class="line"><span class="cl"> <span class="nb">echo</span> <span class="s2">&#34;</span><span class="nv">$NODE</span><span class="s2">: </span><span class="nv">$VERSION</span><span class="s2">&#34;</span> </span></span><span class="line"><span class="cl"><span class="k">done</span> </span></span></code></pre></div> <h4 id="rollback-rolling" class="position-relative d-flex align-items-center group"> <span>Rollback (Rolling)</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="rollback-rolling" aria-haspopup="dialog" aria-label="Share link: Rollback (Rolling)"> <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="cp">#!/bin/bash </span></span></span><span class="line"><span class="cl"><span class="cp"></span><span class="c1"># rolling-rollback.sh</span> </span></span><span class="line"><span class="cl"> </span></span><span class="line"><span class="cl"><span class="c1"># Same process as upgrade, but with previous version</span> </span></span><span class="line"><span class="cl"><span class="c1"># Keep previous binary available for quick rollback</span> </span></span><span class="line"><span class="cl"> </span></span><span class="line"><span class="cl"><span class="nv">OLD_VERSION</span><span class="o">=</span><span class="s2">&#34;0.1.2&#34;</span> </span></span><span class="line"><span class="cl"><span class="c1"># ... follow same rolling procedure with old version</span> </span></span></code></pre></div> <h3 id="blue-green-deployment" class="position-relative d-flex align-items-center group"> <span>Blue-Green Deployment</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="blue-green-deployment" aria-haspopup="dialog" aria-label="Share link: Blue-Green Deployment"> <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><p>For critical production with instant rollback capability.</p> <h4 id="architecture" class="position-relative d-flex align-items-center group"> <span>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="architecture" aria-haspopup="dialog" aria-label="Share link: 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><div class="highlight"><pre tabindex="0" class="chroma"><code class="language-fallback" data-lang="fallback"><span class="line"><span class="cl"> ┌─────────────────┐ </span></span><span class="line"><span class="cl"> │ Load Balancer │ </span></span><span class="line"><span class="cl"> │ (Weighted) │ </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"> │ 100% │ 0% │ </span></span><span class="line"><span class="cl"> ┌────▼────┐ ┌────▼────┐ </span></span><span class="line"><span class="cl"> │ Blue │ │ Green │ </span></span><span class="line"><span class="cl"> │ v0.1.x │ │ v0.1.x │ </span></span><span class="line"><span class="cl"> │(Active) │ │(Standby)│ </span></span><span class="line"><span class="cl"> └─────────┘ └─────────┘ </span></span></code></pre></div> <h4 id="procedure-2" class="position-relative d-flex align-items-center group"> <span>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="procedure-2" aria-haspopup="dialog" aria-label="Share link: 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><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"># blue-green-upgrade.sh</span> </span></span><span class="line"><span class="cl"> </span></span><span class="line"><span class="cl"><span class="nb">set</span> -euo pipefail </span></span><span class="line"><span class="cl"> </span></span><span class="line"><span class="cl"><span class="nv">NEW_VERSION</span><span class="o">=</span><span class="s2">&#34;0.2.18&#34;</span> </span></span><span class="line"><span class="cl"><span class="nv">BLUE_CLUSTER</span><span class="o">=</span><span class="s2">&#34;geode-blue&#34;</span> </span></span><span class="line"><span class="cl"><span class="nv">GREEN_CLUSTER</span><span class="o">=</span><span class="s2">&#34;geode-green&#34;</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;=== Blue-Green Upgrade to </span><span class="nv">$NEW_VERSION</span><span class="s2"> ===&#34;</span> </span></span><span class="line"><span class="cl"><span class="nb">echo</span> <span class="s2">&#34;Blue (current): </span><span class="nv">$BLUE_CLUSTER</span><span class="s2">&#34;</span> </span></span><span class="line"><span class="cl"><span class="nb">echo</span> <span class="s2">&#34;Green (new): </span><span class="nv">$GREEN_CLUSTER</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"># Phase 1: Prepare Green Environment</span> </span></span><span class="line"><span class="cl"><span class="nb">echo</span> <span class="s2">&#34;&#34;</span> </span></span><span class="line"><span class="cl"><span class="nb">echo</span> <span class="s2">&#34;=== Phase 1: Prepare Green Environment ===&#34;</span> </span></span><span class="line"><span class="cl"> </span></span><span class="line"><span class="cl"><span class="c1"># Deploy new version to green</span> </span></span><span class="line"><span class="cl"><span class="nb">echo</span> <span class="s2">&#34;Deploying </span><span class="nv">$NEW_VERSION</span><span class="s2"> to green cluster...&#34;</span> </span></span><span class="line"><span class="cl">./deploy-cluster.sh <span class="s2">&#34;</span><span class="nv">$GREEN_CLUSTER</span><span class="s2">&#34;</span> <span class="s2">&#34;</span><span class="nv">$NEW_VERSION</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"># Wait for green to be ready</span> </span></span><span class="line"><span class="cl"><span class="nb">echo</span> <span class="s2">&#34;Waiting for green cluster to be ready...&#34;</span> </span></span><span class="line"><span class="cl">./wait-for-cluster.sh <span class="s2">&#34;</span><span class="nv">$GREEN_CLUSTER</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"># Phase 2: Sync Data</span> </span></span><span class="line"><span class="cl"><span class="nb">echo</span> <span class="s2">&#34;&#34;</span> </span></span><span class="line"><span class="cl"><span class="nb">echo</span> <span class="s2">&#34;=== Phase 2: Sync Data ===&#34;</span> </span></span><span class="line"><span class="cl"> </span></span><span class="line"><span class="cl"><span class="c1"># Set up replication from blue to green</span> </span></span><span class="line"><span class="cl"><span class="nb">echo</span> <span class="s2">&#34;Setting up replication...&#34;</span> </span></span><span class="line"><span class="cl">geode admin replicate <span class="se">\ </span></span></span><span class="line"><span class="cl"><span class="se"></span> --source <span class="s2">&#34;</span><span class="nv">$BLUE_CLUSTER</span><span class="s2">&#34;</span> <span class="se">\ </span></span></span><span class="line"><span class="cl"><span class="se"></span> --target <span class="s2">&#34;</span><span class="nv">$GREEN_CLUSTER</span><span class="s2">&#34;</span> <span class="se">\ </span></span></span><span class="line"><span class="cl"><span class="se"></span> --mode async </span></span><span class="line"><span class="cl"> </span></span><span class="line"><span class="cl"><span class="c1"># Wait for sync</span> </span></span><span class="line"><span class="cl"><span class="nb">echo</span> <span class="s2">&#34;Waiting for initial sync...&#34;</span> </span></span><span class="line"><span class="cl"><span class="k">while</span> true<span class="p">;</span> <span class="k">do</span> </span></span><span class="line"><span class="cl"> <span class="nv">LAG</span><span class="o">=</span><span class="k">$(</span>geode admin replication-lag --target <span class="s2">&#34;</span><span class="nv">$GREEN_CLUSTER</span><span class="s2">&#34;</span><span class="k">)</span> </span></span><span class="line"><span class="cl"> <span class="nb">echo</span> <span class="s2">&#34;Replication lag: </span><span class="nv">$LAG</span><span class="s2">&#34;</span> </span></span><span class="line"><span class="cl"> <span class="o">[</span> <span class="s2">&#34;</span><span class="nv">$LAG</span><span class="s2">&#34;</span> -lt <span class="m">10</span> <span class="o">]</span> <span class="o">&amp;&amp;</span> <span class="nb">break</span> </span></span><span class="line"><span class="cl"> sleep <span class="m">10</span> </span></span><span class="line"><span class="cl"><span class="k">done</span> </span></span><span class="line"><span class="cl"> </span></span><span class="line"><span class="cl"><span class="c1"># Phase 3: Test Green</span> </span></span><span class="line"><span class="cl"><span class="nb">echo</span> <span class="s2">&#34;&#34;</span> </span></span><span class="line"><span class="cl"><span class="nb">echo</span> <span class="s2">&#34;=== Phase 3: Test Green Environment ===&#34;</span> </span></span><span class="line"><span class="cl"> </span></span><span class="line"><span class="cl"><span class="c1"># Run smoke tests against green</span> </span></span><span class="line"><span class="cl"><span class="nb">echo</span> <span class="s2">&#34;Running smoke tests...&#34;</span> </span></span><span class="line"><span class="cl">./smoke-tests.sh <span class="s2">&#34;</span><span class="nv">$GREEN_CLUSTER</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"># Run integration tests</span> </span></span><span class="line"><span class="cl"><span class="nb">echo</span> <span class="s2">&#34;Running integration tests...&#34;</span> </span></span><span class="line"><span class="cl">./integration-tests.sh <span class="s2">&#34;</span><span class="nv">$GREEN_CLUSTER</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"># Phase 4: Switch Traffic</span> </span></span><span class="line"><span class="cl"><span class="nb">echo</span> <span class="s2">&#34;&#34;</span> </span></span><span class="line"><span class="cl"><span class="nb">echo</span> <span class="s2">&#34;=== Phase 4: Switch Traffic ===&#34;</span> </span></span><span class="line"><span class="cl"> </span></span><span class="line"><span class="cl"><span class="nb">read</span> -p <span class="s2">&#34;Ready to switch traffic to green? (yes/no): &#34;</span> CONFIRM </span></span><span class="line"><span class="cl"><span class="o">[</span> <span class="s2">&#34;</span><span class="nv">$CONFIRM</span><span class="s2">&#34;</span> !<span class="o">=</span> <span class="s2">&#34;yes&#34;</span> <span class="o">]</span> <span class="o">&amp;&amp;</span> <span class="nb">exit</span> <span class="m">1</span> </span></span><span class="line"><span class="cl"> </span></span><span class="line"><span class="cl"><span class="c1"># Gradual traffic shift</span> </span></span><span class="line"><span class="cl"><span class="nb">echo</span> <span class="s2">&#34;Shifting 10% traffic to green...&#34;</span> </span></span><span class="line"><span class="cl">./update-lb-weights.sh <span class="nv">blue</span><span class="o">=</span><span class="m">90</span> <span class="nv">green</span><span class="o">=</span><span class="m">10</span> </span></span><span class="line"><span class="cl">sleep <span class="m">60</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;Shifting 50% traffic to green...&#34;</span> </span></span><span class="line"><span class="cl">./update-lb-weights.sh <span class="nv">blue</span><span class="o">=</span><span class="m">50</span> <span class="nv">green</span><span class="o">=</span><span class="m">50</span> </span></span><span class="line"><span class="cl">sleep <span class="m">60</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;Shifting 100% traffic to green...&#34;</span> </span></span><span class="line"><span class="cl">./update-lb-weights.sh <span class="nv">blue</span><span class="o">=</span><span class="m">0</span> <span class="nv">green</span><span class="o">=</span><span class="m">100</span> </span></span><span class="line"><span class="cl"> </span></span><span class="line"><span class="cl"><span class="c1"># Phase 5: Verify and Cleanup</span> </span></span><span class="line"><span class="cl"><span class="nb">echo</span> <span class="s2">&#34;&#34;</span> </span></span><span class="line"><span class="cl"><span class="nb">echo</span> <span class="s2">&#34;=== Phase 5: Verify and Cleanup ===&#34;</span> </span></span><span class="line"><span class="cl"> </span></span><span class="line"><span class="cl"><span class="c1"># Monitor for issues</span> </span></span><span class="line"><span class="cl"><span class="nb">echo</span> <span class="s2">&#34;Monitoring for 5 minutes...&#34;</span> </span></span><span class="line"><span class="cl">sleep <span class="m">300</span> </span></span><span class="line"><span class="cl"> </span></span><span class="line"><span class="cl"><span class="c1"># Check error rates</span> </span></span><span class="line"><span class="cl"><span class="nv">ERROR_RATE</span><span class="o">=</span><span class="k">$(</span>./get-error-rate.sh<span class="k">)</span> </span></span><span class="line"><span class="cl"><span class="k">if</span> <span class="o">[</span> <span class="s2">&#34;</span><span class="k">$(</span><span class="nb">echo</span> <span class="s2">&#34;</span><span class="nv">$ERROR_RATE</span><span class="s2"> &gt; 0.01&#34;</span> <span class="p">|</span> bc<span class="k">)</span><span class="s2">&#34;</span> -eq <span class="m">1</span> <span class="o">]</span><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;ERROR: High error rate detected. Rolling back...&#34;</span> </span></span><span class="line"><span class="cl"> ./update-lb-weights.sh <span class="nv">blue</span><span class="o">=</span><span class="m">100</span> <span class="nv">green</span><span class="o">=</span><span class="m">0</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"># Keep blue running for quick rollback</span> </span></span><span class="line"><span class="cl"><span class="nb">echo</span> <span class="s2">&#34;Blue cluster retained for rollback capability&#34;</span> </span></span><span class="line"><span class="cl"><span class="nb">echo</span> <span class="s2">&#34;Run &#39;./cleanup-blue.sh&#39; after validation period&#34;</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;&#34;</span> </span></span><span class="line"><span class="cl"><span class="nb">echo</span> <span class="s2">&#34;=== Blue-Green Upgrade Complete ===&#34;</span> </span></span></code></pre></div> <h4 id="instant-rollback" class="position-relative d-flex align-items-center group"> <span>Instant Rollback</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="instant-rollback" aria-haspopup="dialog" aria-label="Share link: Instant Rollback"> <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="cp">#!/bin/bash </span></span></span><span class="line"><span class="cl"><span class="cp"></span><span class="c1"># blue-green-rollback.sh</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;=== Instant Rollback to Blue ===&#34;</span> </span></span><span class="line"><span class="cl"> </span></span><span class="line"><span class="cl"><span class="c1"># Switch all traffic back to blue</span> </span></span><span class="line"><span class="cl">./update-lb-weights.sh <span class="nv">blue</span><span class="o">=</span><span class="m">100</span> <span class="nv">green</span><span class="o">=</span><span class="m">0</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;Traffic switched to blue&#34;</span> </span></span><span class="line"><span class="cl"><span class="nb">echo</span> <span class="s2">&#34;Green cluster retained for investigation&#34;</span> </span></span></code></pre></div> <h3 id="canary-deployment" class="position-relative d-flex align-items-center group"> <span>Canary Deployment</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="canary-deployment" aria-haspopup="dialog" aria-label="Share link: Canary Deployment"> <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><p>For gradual rollout with monitoring.</p> <h4 id="procedure-3" class="position-relative d-flex align-items-center group"> <span>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="procedure-3" aria-haspopup="dialog" aria-label="Share link: 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><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"># canary-upgrade.sh</span> </span></span><span class="line"><span class="cl"> </span></span><span class="line"><span class="cl"><span class="nb">set</span> -euo pipefail </span></span><span class="line"><span class="cl"> </span></span><span class="line"><span class="cl"><span class="nv">NEW_VERSION</span><span class="o">=</span><span class="s2">&#34;0.2.18&#34;</span> </span></span><span class="line"><span class="cl"><span class="nv">CANARY_PERCENTAGE</span><span class="o">=</span><span class="m">5</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;=== Canary Deployment to </span><span class="nv">$NEW_VERSION</span><span class="s2"> ===&#34;</span> </span></span><span class="line"><span class="cl"><span class="nb">echo</span> <span class="s2">&#34;Initial canary: </span><span class="nv">$CANARY_PERCENTAGE</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"># Deploy canary instance</span> </span></span><span class="line"><span class="cl"><span class="nb">echo</span> <span class="s2">&#34;Deploying canary instance...&#34;</span> </span></span><span class="line"><span class="cl">./deploy-canary.sh <span class="s2">&#34;</span><span class="nv">$NEW_VERSION</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"># Route small percentage to canary</span> </span></span><span class="line"><span class="cl"><span class="nb">echo</span> <span class="s2">&#34;Routing </span><span class="si">${</span><span class="nv">CANARY_PERCENTAGE</span><span class="si">}</span><span class="s2">% to canary...&#34;</span> </span></span><span class="line"><span class="cl">./update-routing.sh <span class="nv">canary</span><span class="o">=</span><span class="nv">$CANARY_PERCENTAGE</span> </span></span><span class="line"><span class="cl"> </span></span><span class="line"><span class="cl"><span class="c1"># Monitor canary</span> </span></span><span class="line"><span class="cl"><span class="nb">echo</span> <span class="s2">&#34;Monitoring canary for 30 minutes...&#34;</span> </span></span><span class="line"><span class="cl">./monitor-canary.sh --duration 30m --threshold-error-rate 0.01 </span></span><span class="line"><span class="cl"> </span></span><span class="line"><span class="cl"><span class="k">if</span> <span class="o">[</span> <span class="nv">$?</span> -ne <span class="m">0</span> <span class="o">]</span><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;Canary failed. Rolling back...&#34;</span> </span></span><span class="line"><span class="cl"> ./update-routing.sh <span class="nv">canary</span><span class="o">=</span><span class="m">0</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"># Gradually increase canary</span> </span></span><span class="line"><span class="cl"><span class="k">for</span> PCT in <span class="m">10</span> <span class="m">25</span> <span class="m">50</span> <span class="m">75</span> 100<span class="p">;</span> <span class="k">do</span> </span></span><span class="line"><span class="cl"> <span class="nb">echo</span> <span class="s2">&#34;Increasing canary to </span><span class="si">${</span><span class="nv">PCT</span><span class="si">}</span><span class="s2">%...&#34;</span> </span></span><span class="line"><span class="cl"> ./update-routing.sh <span class="nv">canary</span><span class="o">=</span><span class="nv">$PCT</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;Monitoring for 15 minutes...&#34;</span> </span></span><span class="line"><span class="cl"> ./monitor-canary.sh --duration 15m --threshold-error-rate 0.01 </span></span><span class="line"><span class="cl"> </span></span><span class="line"><span class="cl"> <span class="k">if</span> <span class="o">[</span> <span class="nv">$?</span> -ne <span class="m">0</span> <span class="o">]</span><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;Canary failed at </span><span class="si">${</span><span class="nv">PCT</span><span class="si">}</span><span class="s2">%. Rolling back...&#34;</span> </span></span><span class="line"><span class="cl"> ./update-routing.sh <span class="nv">canary</span><span class="o">=</span><span class="m">0</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 class="k">done</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;=== Canary Deployment Complete ===&#34;</span> </span></span></code></pre></div> <h3 id="configuration-migration" class="position-relative d-flex align-items-center group"> <span>Configuration Migration</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="configuration-migration" aria-haspopup="dialog" aria-label="Share link: Configuration Migration"> <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="automatic-migration" class="position-relative d-flex align-items-center group"> <span>Automatic Migration</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="automatic-migration" aria-haspopup="dialog" aria-label="Share link: Automatic Migration"> <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"># Migrate configuration between versions</span> </span></span><span class="line"><span class="cl">geode config migrate <span class="se">\ </span></span></span><span class="line"><span class="cl"><span class="se"></span> --from-version 0.17.x <span class="se">\ </span></span></span><span class="line"><span class="cl"><span class="se"></span> --to-version 0.18.x <span class="se">\ </span></span></span><span class="line"><span class="cl"><span class="se"></span> --config /etc/geode/geode.yaml <span class="se">\ </span></span></span><span class="line"><span class="cl"><span class="se"></span> --output /etc/geode/geode.yaml.new </span></span><span class="line"><span class="cl"> </span></span><span class="line"><span class="cl"><span class="c1"># Review changes</span> </span></span><span class="line"><span class="cl">diff /etc/geode/geode.yaml /etc/geode/geode.yaml.new </span></span><span class="line"><span class="cl"> </span></span><span class="line"><span class="cl"><span class="c1"># Apply changes</span> </span></span><span class="line"><span class="cl">mv /etc/geode/geode.yaml.new /etc/geode/geode.yaml </span></span></code></pre></div> <h4 id="manual-migration-examples" class="position-relative d-flex align-items-center group"> <span>Manual Migration Examples</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="manual-migration-examples" aria-haspopup="dialog" aria-label="Share link: Manual Migration Examples"> <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>v0.1.x to v0.1.x</strong>:</p> <div class="highlight"><pre tabindex="0" class="chroma"><code class="language-yaml" data-lang="yaml"><span class="line"><span class="cl"><span class="c"># Old (v0.1.x)</span><span class="w"> </span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="nt">server</span><span class="p">:</span><span class="w"> </span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="nt">listen</span><span class="p">:</span><span class="w"> </span><span class="s1">&#39;0.0.0.0:3141&#39;</span><span class="w"> </span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="nt">auth_enabled</span><span class="p">:</span><span class="w"> </span><span class="kc">false</span><span class="w"> </span><span class="c"># Optional auth</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">tls</span><span class="p">:</span><span class="w"> </span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="nt">auto_generate</span><span class="p">:</span><span class="w"> </span><span class="kc">true</span><span class="w"> </span><span class="c"># Auto-generate certs</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="c"># New (v0.1.x)</span><span class="w"> </span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="nt">server</span><span class="p">:</span><span class="w"> </span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="nt">listen</span><span class="p">:</span><span class="w"> </span><span class="s1">&#39;0.0.0.0:3141&#39;</span><span class="w"> </span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="c"># auth_enabled removed, now always true</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">security</span><span class="p">:</span><span class="w"> </span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="nt">authentication</span><span class="p">:</span><span class="w"> </span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="nt">enabled</span><span class="p">:</span><span class="w"> </span><span class="kc">true</span><span class="w"> </span><span class="c"># Explicit enable</span><span class="w"> </span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="nt">default_user</span><span class="p">:</span><span class="w"> </span><span class="l">${GEODE_ADMIN_USERNAME}</span><span class="w"> </span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="nt">default_password</span><span class="p">:</span><span class="w"> </span><span class="l">${GEODE_DEFAULT_PASSWORD}</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">tls</span><span class="p">:</span><span class="w"> </span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="nt">auto_generate</span><span class="p">:</span><span class="w"> </span><span class="kc">false</span><span class="w"> </span><span class="c"># Must provide certs</span><span class="w"> </span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="nt">cert</span><span class="p">:</span><span class="w"> </span><span class="l">/etc/geode/certs/server.crt</span><span class="w"> </span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="nt">key</span><span class="p">:</span><span class="w"> </span><span class="l">/etc/geode/certs/server.key</span><span class="w"> </span></span></span></code></pre></div> <h3 id="post-upgrade-validation" class="position-relative d-flex align-items-center group"> <span>Post-Upgrade 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="post-upgrade-validation" aria-haspopup="dialog" aria-label="Share link: Post-Upgrade 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="validation-script" class="position-relative d-flex align-items-center group"> <span>Validation Script</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="validation-script" aria-haspopup="dialog" aria-label="Share link: Validation Script"> <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="cp">#!/bin/bash </span></span></span><span class="line"><span class="cl"><span class="cp"></span><span class="c1"># post-upgrade-validation.sh</span> </span></span><span class="line"><span class="cl"> </span></span><span class="line"><span class="cl"><span class="nb">set</span> -euo pipefail </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;=== Post-Upgrade Validation ===&#34;</span> </span></span><span class="line"><span class="cl"> </span></span><span class="line"><span class="cl"><span class="c1"># 1. Version check</span> </span></span><span class="line"><span class="cl"><span class="nb">echo</span> <span class="s2">&#34;1. Checking version...&#34;</span> </span></span><span class="line"><span class="cl"><span class="nv">ACTUAL_VERSION</span><span class="o">=</span><span class="k">$(</span>geode --version <span class="p">|</span> grep -oP <span class="s1">&#39;\d+\.\d+\.\d+&#39;</span><span class="k">)</span> </span></span><span class="line"><span class="cl"><span class="nb">echo</span> <span class="s2">&#34; Version: </span><span class="nv">$ACTUAL_VERSION</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"># 2. Health check</span> </span></span><span class="line"><span class="cl"><span class="nb">echo</span> <span class="s2">&#34;2. Checking server health...&#34;</span> </span></span><span class="line"><span class="cl">geode admin status </span></span><span class="line"><span class="cl"> </span></span><span class="line"><span class="cl"><span class="c1"># 3. Query test</span> </span></span><span class="line"><span class="cl"><span class="nb">echo</span> <span class="s2">&#34;3. Running query test...&#34;</span> </span></span><span class="line"><span class="cl">geode query <span class="s2">&#34;MATCH (n) RETURN count(n) AS count&#34;</span> </span></span><span class="line"><span class="cl"> </span></span><span class="line"><span class="cl"><span class="c1"># 4. Write test</span> </span></span><span class="line"><span class="cl"><span class="nb">echo</span> <span class="s2">&#34;4. Running write test...&#34;</span> </span></span><span class="line"><span class="cl">geode query <span class="s2">&#34;CREATE (t:Test {timestamp: datetime()}) RETURN t&#34;</span> </span></span><span class="line"><span class="cl">geode query <span class="s2">&#34;MATCH (t:Test) DELETE t&#34;</span> </span></span><span class="line"><span class="cl"> </span></span><span class="line"><span class="cl"><span class="c1"># 5. Performance test</span> </span></span><span class="line"><span class="cl"><span class="nb">echo</span> <span class="s2">&#34;5. Running performance test...&#34;</span> </span></span><span class="line"><span class="cl"><span class="nv">START</span><span class="o">=</span><span class="k">$(</span>date +%s%N<span class="k">)</span> </span></span><span class="line"><span class="cl"><span class="k">for</span> i in <span class="o">{</span>1..100<span class="o">}</span><span class="p">;</span> <span class="k">do</span> </span></span><span class="line"><span class="cl"> geode query <span class="s2">&#34;MATCH (n) RETURN n LIMIT 10&#34;</span> &gt; /dev/null </span></span><span class="line"><span class="cl"><span class="k">done</span> </span></span><span class="line"><span class="cl"><span class="nv">END</span><span class="o">=</span><span class="k">$(</span>date +%s%N<span class="k">)</span> </span></span><span class="line"><span class="cl"><span class="nv">DURATION_MS</span><span class="o">=</span><span class="k">$((</span> <span class="o">(</span>END <span class="o">-</span> START<span class="o">)</span> <span class="o">/</span> <span class="m">1000000</span> <span class="k">))</span> </span></span><span class="line"><span class="cl"><span class="nv">AVG_MS</span><span class="o">=</span><span class="k">$((</span> DURATION_MS <span class="o">/</span> <span class="m">100</span> <span class="k">))</span> </span></span><span class="line"><span class="cl"><span class="nb">echo</span> <span class="s2">&#34; 100 queries in </span><span class="si">${</span><span class="nv">DURATION_MS</span><span class="si">}</span><span class="s2">ms (avg: </span><span class="si">${</span><span class="nv">AVG_MS</span><span class="si">}</span><span class="s2">ms)&#34;</span> </span></span><span class="line"><span class="cl"> </span></span><span class="line"><span class="cl"><span class="c1"># 6. Backup test</span> </span></span><span class="line"><span class="cl"><span class="nb">echo</span> <span class="s2">&#34;6. Testing backup functionality...&#34;</span> </span></span><span class="line"><span class="cl">geode backup --dest /tmp/validation-backup --mode full --verify </span></span><span class="line"><span class="cl">rm -rf /tmp/validation-backup </span></span><span class="line"><span class="cl"> </span></span><span class="line"><span class="cl"><span class="c1"># 7. Application connectivity test</span> </span></span><span class="line"><span class="cl"><span class="nb">echo</span> <span class="s2">&#34;7. Testing application connectivity...&#34;</span> </span></span><span class="line"><span class="cl"><span class="c1"># Add application-specific tests</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;&#34;</span> </span></span><span class="line"><span class="cl"><span class="nb">echo</span> <span class="s2">&#34;=== Validation Complete ===&#34;</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="before-upgrade" class="position-relative d-flex align-items-center group"> <span>Before Upgrade</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="before-upgrade" aria-haspopup="dialog" aria-label="Share link: Before Upgrade"> <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>Read release notes</strong>: Understand changes and breaking changes</li> <li><strong>Test in staging</strong>: Full test cycle before production</li> <li><strong>Create backup</strong>: Always have a rollback point</li> <li><strong>Notify stakeholders</strong>: Communicate maintenance window</li> <li><strong>Prepare rollback plan</strong>: Know how to revert quickly</li> </ol> <h4 id="during-upgrade" class="position-relative d-flex align-items-center group"> <span>During Upgrade</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="during-upgrade" aria-haspopup="dialog" aria-label="Share link: During Upgrade"> <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 closely</strong>: Watch metrics and logs</li> <li><strong>Proceed incrementally</strong>: Don&rsquo;t rush</li> <li><strong>Verify each step</strong>: Don&rsquo;t assume success</li> <li><strong>Document issues</strong>: Note any problems encountered</li> <li><strong>Be ready to rollback</strong>: Have plan ready</li> </ol> <h4 id="after-upgrade" class="position-relative d-flex align-items-center group"> <span>After Upgrade</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="after-upgrade" aria-haspopup="dialog" aria-label="Share link: After Upgrade"> <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>Run validation</strong>: Complete test suite</li> <li><strong>Monitor for 24h</strong>: Watch for delayed issues</li> <li><strong>Update documentation</strong>: Note version in runbooks</li> <li><strong>Clean up</strong>: Remove old binaries, backup temp files</li> <li><strong>Conduct review</strong>: What went well, what to improve</li> </ol> <h3 id="troubleshooting" class="position-relative d-flex align-items-center group"> <span>Troubleshooting</span> <button type="button" class="h-share btn btn-link p-0 text-decoration-none link-secondary opacity-50 hover-opacity-100 transition-all ms-1" data-share-target="troubleshooting" aria-haspopup="dialog" aria-label="Share link: Troubleshooting"> <i class="fa-sharp-duotone fa-solid fa-share-nodes" aria-hidden="true" style="font-size: 0.8em;"></i> <span class="visually-hidden">Share link</span> </button> </h3> <h4 id="upgrade-fails-to-start" class="position-relative d-flex align-items-center group"> <span>Upgrade Fails to Start</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="upgrade-fails-to-start" aria-haspopup="dialog" aria-label="Share link: Upgrade Fails to Start"> <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"># Check logs</span> </span></span><span class="line"><span class="cl">journalctl -u geode -n <span class="m">100</span> </span></span><span class="line"><span class="cl"> </span></span><span class="line"><span class="cl"><span class="c1"># Common issues:</span> </span></span><span class="line"><span class="cl"><span class="c1"># - Config format changed -&gt; migrate config</span> </span></span><span class="line"><span class="cl"><span class="c1"># - Missing dependencies -&gt; check Zig version</span> </span></span><span class="line"><span class="cl"><span class="c1"># - Permission issues -&gt; check file ownership</span> </span></span></code></pre></div> <h4 id="data-incompatibility" class="position-relative d-flex align-items-center group"> <span>Data Incompatibility</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="data-incompatibility" aria-haspopup="dialog" aria-label="Share link: Data Incompatibility"> <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"># If data format changed between versions</span> </span></span><span class="line"><span class="cl">geode admin migrate-data --from-version 0.17.x </span></span><span class="line"><span class="cl"> </span></span><span class="line"><span class="cl"><span class="c1"># If migration fails, restore from backup</span> </span></span><span class="line"><span class="cl">geode restore --source s3://bucket/backups --backup-id &lt;pre-upgrade-id&gt; </span></span></code></pre></div> <h4 id="performance-regression" class="position-relative d-flex align-items-center group"> <span>Performance Regression</span> <button type="button" class="h-share btn btn-link p-0 text-decoration-none link-secondary opacity-50 hover-opacity-100 transition-all ms-1" data-share-target="performance-regression" aria-haspopup="dialog" aria-label="Share link: Performance Regression"> <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"># Compare query plans</span> </span></span><span class="line"><span class="cl">geode query <span class="s2">&#34;EXPLAIN MATCH (n) RETURN n LIMIT 100&#34;</span> </span></span><span class="line"><span class="cl"> </span></span><span class="line"><span class="cl"><span class="c1"># Check index status</span> </span></span><span class="line"><span class="cl">geode admin index-status </span></span><span class="line"><span class="cl"> </span></span><span class="line"><span class="cl"><span class="c1"># Review new configuration options</span> </span></span><span class="line"><span class="cl">geode config diff --from 0.17.x --to 0.18.x </span></span></code></pre></div> <h3 id="related-documentation" class="position-relative d-flex align-items-center group"> <span>Related Documentation</span> <button type="button" class="h-share btn btn-link p-0 text-decoration-none link-secondary opacity-50 hover-opacity-100 transition-all ms-1" data-share-target="related-documentation" aria-haspopup="dialog" aria-label="Share link: Related Documentation"> <i class="fa-sharp-duotone fa-solid fa-share-nodes" aria-hidden="true" style="font-size: 0.8em;"></i> <span class="visually-hidden">Share link</span> </button> </h3><ul> <li><strong><a href="/docs/guides/migration-guide/" >Migration Guide</a> </strong> - Data migration procedures</li> <li><strong><a href="/docs/operations/backup/" >Backup Procedures</a> </strong> - Backup before upgrade</li> <li><strong><a href="/docs/operations/disaster-recovery/" >Disaster Recovery</a> </strong> - Recovery procedures</li> <li><strong><a href="/docs/configuration/" >Configuration Reference</a> </strong> - Configuration options</li> </ul>