Download index.html from getreadystack/pg14-upgrade-blocker-lint: direct link, hf CLI and curl.
- Browser
- Download file 42.6 kB
-
https://huggingface.co/spaces/getreadystack/pg14-upgrade-blocker-lint/resolve/main/index.html
- Command line
-
hf download hf://spaces/getreadystack/pg14-upgrade-blocker-lint/index.html
-
curl -L -o index.html https://huggingface.co/spaces/getreadystack/pg14-upgrade-blocker-lint/resolve/main/index.html
42.6 kB
| <html lang="en"> | |
| <head> | |
| <meta charset="utf-8"> | |
| <meta name="viewport" content="width=device-width,initial-scale=1"> | |
| <title>PostgreSQL 14 Upgrade check — check your upgrade files free</title> | |
| <meta name="description" content="Find SQL and configuration lines removed or renamed in PostgreSQL 15, 16, or 17 before an Aurora or RDS PostgreSQL 14 upgrade."> | |
| <style> | |
| :root{color-scheme:light}body{margin:0;font:15px/1.55 system-ui,-apple-system,"Segoe UI",sans-serif;background:#faf9f5;color:#1a1512} | |
| .wrap{max-width:960px;margin:0 auto;padding:28px 18px 60px}h1{font-size:26px;margin:0 0 6px}.lede{color:#4a403a;margin:0 0 16px} | |
| textarea{width:100%;min-height:260px;font:13px/1.45 ui-monospace,Menlo,Consolas,monospace;padding:12px;border:1px solid #d9d0c4;border-radius:8px;box-sizing:border-box} | |
| .bar{display:flex;gap:10px;align-items:center;margin:12px 0}button{font:600 15px system-ui;padding:10px 18px;border:0;border-radius:8px;background:#1a1512;color:#fff;cursor:pointer} | |
| input[type=date]{font:14px system-ui;padding:8px;border:1px solid #d9d0c4;border-radius:6px} | |
| table{border-collapse:collapse;width:100%;font-size:14px;margin-top:10px}th,td{text-align:left;padding:8px 10px;border-bottom:1px solid #eee;vertical-align:top}th{font-size:12px;letter-spacing:.06em;text-transform:uppercase;color:#7a6e65} | |
| .sev.error{color:#a8551f;font-weight:700}.sev.warn,.sev.warning{color:#96691f}.ok{color:#2a6446;font-weight:600}.sum{font-weight:600} | |
| .note{font-size:13px;color:#7a6e65;margin-top:18px}#paid{margin-top:22px;padding:14px 16px;border:1px solid #e2d8cb;border-radius:10px;background:#fffdfa} | |
| </style> | |
| <script data-grow-initializer="">!(function(){window.growMe||((window.growMe=function(e){window.growMe._.push(e);}),(window.growMe._=[]));var e=document.createElement("script");(e.type="text/javascript"),(e.src="https://faves.grow.me/main.js"),(e.defer=!0),e.setAttribute("data-grow-faves-site-id","U2l0ZTphZjljMzgyMC0yMmU5LTRhYjgtYTIxNS03OTRhMGY1N2ExYzM=");var t=document.getElementsByTagName("script")[0];t.parentNode.insertBefore(e,t);})();</script> | |
| <!--yj-canon-s101--><link rel="canonical" href="https://getreadystack.com/tools/pg14-upgrade-blocker-lint"></head> | |
| <body> | |
| <div class="wrap"> | |
| <h1>PostgreSQL 14 Upgrade check — check your upgrade files free</h1> | |
| <p class="lede">Flags SQL and config lines that PostgreSQL 15, 16 or 17 removed or renamed, so an Aurora/RDS PostgreSQL 14 upgrade does not break before standard support ends on 28 February 2027. Runs entirely in your browser — nothing is uploaded.</p> | |
| <textarea id="src" spellcheck="false">-- ops/backup_and_monitoring.sql : helpers still written for PostgreSQL 14 | |
| SELECT pg_start_backup('nightly', true); | |
| SELECT pg_stop_backup(); | |
| CREATE EXTENSION IF NOT EXISTS adminpack; | |
| CREATE FUNCTION slugify(t text) RETURNS text AS $$ | |
| return t.lower().replace(' ', '-') | |
| $$ LANGUAGE plpythonu; | |
| CREATE VIEW checkpoint_health AS | |
| SELECT checkpoints_timed, now() AS sampled_at FROM pg_stat_bgwriter; | |
| ALTER SYSTEM SET vacuum_defer_cleanup_age = 10000;</textarea> | |
| <div class="bar"><button id="go">Check</button><label>as of <input type="date" id="today"></label></div> | |
| <div id="out" aria-live="polite"></div> | |
| <div id="paid"><strong>Free here:</strong> Lint the open .sql, .conf or .tf file against PostgreSQL 15, 16 and 17 removals, with the fix on every line. <strong>In the editor:</strong> Scan every migration in the workspace at once and export one upgrade-blocker report (Markdown + CSV) to attach to the upgrade ticket. — $29 once · one licence key per person or team seat. <a href="https://getreadystack.com/api/buy/cl/polar_cl_s5avrba8KowKm6k2clM21lHLbLMEFg3UCrkFv41dVza">Get the full version — $29</a></div> | |
| <p class="note">Same engine as the VS Code extension, byte for byte.</p> | |
| </div> | |
| <script>var PGU_RULES = [ | |
| {"id":"PG15-START-BACKUP","v":15,"sev":"error","re":"\\bpg_start_backup\\s*\\(","msg":"pg_start_backup() was renamed in PostgreSQL 15 (exclusive backup mode removed)","fix":"call pg_backup_start(label, fast) in the same session as pg_backup_stop()"}, | |
| {"id":"PG15-STOP-BACKUP","v":15,"sev":"error","re":"\\bpg_stop_backup\\s*\\(","msg":"pg_stop_backup() was renamed in PostgreSQL 15","fix":"call pg_backup_stop() in the session that ran pg_backup_start()"}, | |
| {"id":"PG15-BACKUP-START-TIME","v":15,"sev":"error","re":"\\bpg_backup_start_time\\s*\\(","msg":"pg_backup_start_time() was removed in PostgreSQL 15","fix":"drop the call; track the start time in your backup tool"}, | |
| {"id":"PG15-IS-IN-BACKUP","v":15,"sev":"error","re":"\\bpg_is_in_backup\\s*\\(","msg":"pg_is_in_backup() was removed in PostgreSQL 15","fix":"drop the call; only non-exclusive backups exist from 15 on"}, | |
| {"id":"PG15-PLPYTHON2","v":15,"sev":"error","re":"\\bplpython2?u\\b","msg":"plpython2u / plpythonu were removed in PostgreSQL 15 (Python 2 no longer supported)","fix":"port the function to Python 3 and use LANGUAGE plpython3u"}, | |
| {"id":"PG15-STATS-TEMP-DIR","v":15,"sev":"error","re":"\\bstats_temp_directory\\b","msg":"server variable stats_temp_directory was removed in PostgreSQL 15","fix":"delete the setting (statistics now live in shared memory)"}, | |
| {"id":"PG15-DUMP-NO-SYNC-SNAP","v":15,"sev":"warn","re":"--no-synchronized-snapshots\\b","msg":"pg_dump --no-synchronized-snapshots was removed in PostgreSQL 15","fix":"remove the option"}, | |
| {"id":"PG16-FORCE-PARALLEL","v":16,"sev":"error","re":"\\bforce_parallel_mode\\b","msg":"force_parallel_mode was renamed in PostgreSQL 16","fix":"use debug_parallel_query"}, | |
| {"id":"PG16-PROMOTE-TRIGGER","v":16,"sev":"error","re":"\\bpromote_trigger_file\\b","msg":"server variable promote_trigger_file was removed in PostgreSQL 16","fix":"promote with pg_ctl promote or SELECT pg_promote()"}, | |
| {"id":"PG16-VACUUM-DEFER","v":16,"sev":"error","re":"\\bvacuum_defer_cleanup_age\\b","msg":"server variable vacuum_defer_cleanup_age was removed in PostgreSQL 16","fix":"use hot_standby_feedback or a replication slot"}, | |
| {"id":"PG16-LC-VARS","v":16,"sev":"error","re":"(current_setting\\s*\\(\\s*'lc_(collate|ctype)'|\\bSHOW\\s+lc_(collate|ctype)\\b)","msg":"read-only server variables lc_collate and lc_ctype were removed in PostgreSQL 16","fix":"read datcollate / datctype from pg_database"}, | |
| {"id":"PG16-WAL-TILL-END","v":16,"sev":"error","re":"\\bpg_get_wal_(records_info|stats)_till_end_of_wal\\b","msg":"pg_walinspect *_till_end_of_wal() functions were removed in PostgreSQL 16","fix":"call pg_get_wal_records_info() / pg_get_wal_stats() with an end LSN"}, | |
| {"id":"PG16-SELECT-RULE-VIEW","v":16,"sev":"error","re":"\\bCREATE\\s+(OR\\s+REPLACE\\s+)?RULE\\s+\"?_RETURN\"?","msg":"creating views manually with ON SELECT rules was removed in PostgreSQL 16","fix":"use CREATE VIEW"}, | |
| {"id":"PG17-OLD-SNAPSHOT","v":17,"sev":"error","re":"\\bold_snapshot_threshold\\b","msg":"server variable old_snapshot_threshold was removed in PostgreSQL 17","fix":"delete the setting; bound long transactions with idle_in_transaction_session_timeout"}, | |
| {"id":"PG17-DB-USER-NS","v":17,"sev":"error","re":"\\bdb_user_namespace\\b","msg":"db_user_namespace (per-database users) was removed in PostgreSQL 17","fix":"create ordinary roles and restrict them with CONNECT privileges"}, | |
| {"id":"PG17-ADMINPACK","v":17,"sev":"error","re":"\\badminpack\\b","msg":"the adminpack contrib extension was removed in PostgreSQL 17","fix":"DROP EXTENSION adminpack before the upgrade"}, | |
| {"id":"PG17-TRACE-RECOVERY","v":17,"sev":"error","re":"\\btrace_recovery_messages\\b","msg":"server variable trace_recovery_messages was removed in PostgreSQL 17","fix":"delete the setting"}, | |
| {"id":"PG17-PGSS-BLK-TIME","v":17,"sev":"error","re":"\\bblk_(read|write)_time\\b","msg":"pg_stat_statements blk_read_time / blk_write_time were renamed in PostgreSQL 17","fix":"use shared_blk_read_time / shared_blk_write_time"}, | |
| {"id":"PG17-BGWRITER-CHECKPOINT","v":17,"sev":"error","re":"\\b(checkpoints_timed|checkpoints_req|checkpoint_write_time|checkpoint_sync_time|buffers_checkpoint)\\b","msg":"checkpoint columns were removed from pg_stat_bgwriter in PostgreSQL 17","fix":"read them from the new view pg_stat_checkpointer"}, | |
| {"id":"PG17-BUFFERS-BACKEND","v":17,"sev":"error","re":"\\bbuffers_backend(_fsync)?\\b","msg":"buffers_backend / buffers_backend_fsync were removed from pg_stat_bgwriter in PostgreSQL 17","fix":"use pg_stat_io"}, | |
| {"id":"PG17-ICU-LOCALE-COL","v":17,"sev":"error","re":"\\b(colliculocale|daticulocale)\\b","msg":"pg_collation.colliculocale / pg_database.daticulocale were renamed in PostgreSQL 17","fix":"use colllocale / datlocale"} | |
| ] | |
| ;</script> | |
| <script>// PostgreSQL 14 upgrade-blocker engine: flags lines that PostgreSQL 15, 16 or 17 removed or renamed. | |
| // Sources: postgresql.org release notes 15.0 / 16.0 / 17.0 ("Migration to Version N") and the | |
| // AWS Aurora/RDS PostgreSQL release calendars (14: end of standard support 28 February 2027). | |
| (function () { | |
| var RULES = (typeof module !== 'undefined') ? require('./rules.json') : window.PGU_RULES; | |
| var COMPILED = RULES.map(function (r) { return { r: r, re: new RegExp(r.re, 'i') }; }); | |
| var CLIFF = { | |
| version: 14, end_standard: '2027-02-28', es_year1: '2027-03-01', es_year3: '2029-03-01', es_end: '2030-02-28', | |
| rate_y1: 0.100, rate_y3: 0.200, region: 'US East (Ohio)' | |
| }; | |
| // Extended Support per year for N vCPUs, running 8,760 hours (rate per vCPU-hour from the AWS pricing page). | |
| function extendedSupportPerYear(vcpus, year3) { | |
| return Math.round((+vcpus || 0) * (year3 ? CLIFF.rate_y3 : CLIFF.rate_y1) * 8760 * 100) / 100; | |
| } | |
| function stripComment(line) { | |
| var t = line.trim(); | |
| if (t.charAt(0) === '#' || t.indexOf('//') === 0) return ''; | |
| var out = '', q = false; | |
| for (var i = 0; i < line.length; i++) { | |
| var c = line.charAt(i); | |
| if (c === "'") q = !q; | |
| if (!q && c === '-' && line.charAt(i + 1) === '-' && !/[A-Za-z0-9]/.test(line.charAt(i + 2) || '')) break; | |
| if (!q && c === '#' && /^\s*$/.test(line.slice(0, i)) ) break; | |
| out += c; | |
| } | |
| return out; | |
| } | |
| function check(text, opts) { | |
| opts = opts || {}; | |
| var target = +opts.target || 17; | |
| var lines = String(text || '').split(/\r?\n/); | |
| var findings = []; | |
| for (var n = 0; n < lines.length; n++) { | |
| var code = stripComment(lines[n]); | |
| if (!code.trim()) continue; | |
| for (var k = 0; k < COMPILED.length; k++) { | |
| var c = COMPILED[k]; | |
| if (c.r.v > target) continue; | |
| if (c.re.test(code)) { | |
| findings.push({ check: c.r.id, sev: c.r.sev, line: n + 1, removed_in: c.r.v, | |
| msg: c.r.msg + ' — fix: ' + c.r.fix + '. Blocks the 14 → ' + target + ' upgrade (Aurora/RDS PostgreSQL 14 standard support ends 28 February 2027).' }); | |
| } | |
| } | |
| } | |
| var res = { findings: findings, target: target, cliff: CLIFF }; | |
| if (opts.vcpus) res.extended_support_usd_per_year = extendedSupportPerYear(opts.vcpus, false); | |
| return res; | |
| } | |
| var api = { engine: { check: check, extendedSupportPerYear: extendedSupportPerYear }, RULES: RULES, RULE_COUNT: RULES.length, CLIFF: CLIFF }; | |
| if (typeof module !== 'undefined') module.exports = api; | |
| if (typeof window !== 'undefined') window.PGUENGINE = api; | |
| })(); | |
| </script> | |
| <script>// ⛔뼈대 — kit/scaffold.py 가 찍는다 (s143). findings [{check,sev,msg,line?}] → 글/HTML. 같은 파일이 Node 와 브라우저에서 산다. | |
| ; | |
| function escapeHtml(s) { return String(s == null ? '' : s).replace(/&/g, '&').replace(/</g, '<').replace(/>/g, '>').replace(/"/g, '"'); } | |
| function summaryLine(res) { | |
| const f = (res && res.findings) || []; const e = f.filter(function (x) { return String(x.sev || 'error').toLowerCase().startsWith('err'); }).length; | |
| return f.length ? (f.length + ' finding' + (f.length === 1 ? '' : 's') + ' (' + e + ' error' + (e === 1 ? '' : 's') + ')') : 'Clean — no findings.'; | |
| } | |
| function toText(res, label) { | |
| const f = (res && res.findings) || []; | |
| const lines = ['== ' + (label || '') + ' — ' + summaryLine(res)]; | |
| f.forEach(function (x) { lines.push(' ' + String(x.sev || 'error').toUpperCase().slice(0, 4) + ' ' + (x.line ? 'L' + x.line + ' ' : '') + (x.check || x.id || '') + ' ' + (x.msg || x.message || '')); }); | |
| return lines.join('\n'); | |
| } | |
| function toHtml(res) { | |
| const f = (res && res.findings) || []; | |
| if (!f.length) return '<p class="ok">' + escapeHtml(summaryLine(res)) + '</p>'; | |
| const rows = f.map(function (x) { return '<tr><td class="sev ' + escapeHtml(String(x.sev || 'error')) + '">' + escapeHtml(String(x.sev || 'error')) + '</td><td>' + (x.line ? 'L' + escapeHtml(x.line) : '') + '</td><td><code>' + escapeHtml(x.check || x.id || '') + '</code></td><td>' + escapeHtml(x.msg || x.message || '') + '</td></tr>'; }).join(''); | |
| return '<p class="sum">' + escapeHtml(summaryLine(res)) + '</p><table><thead><tr><th>Level</th><th>Line</th><th>Check</th><th>What</th></tr></thead><tbody>' + rows + '</tbody></table>'; | |
| } | |
| var PGUREPORT = { escapeHtml: escapeHtml, summaryLine: summaryLine, toText: toText, toHtml: toHtml }; | |
| if (typeof module !== 'undefined' && module.exports) module.exports = PGUREPORT; | |
| else window.PGUREPORT = PGUREPORT; | |
| </script> | |
| <script> | |
| (function(){ | |
| var src=document.getElementById('src'), out=document.getElementById('out'), go=document.getElementById('go'), today=document.getElementById('today'); | |
| today.value=new Date().toISOString().slice(0,10); | |
| function run(){ try { var res=window.PGUENGINE.engine.check(src.value,{today:today.value}); out.innerHTML=window.PGUREPORT.toHtml(res); } catch(e){ out.innerHTML='<p class="sev error">Could not run: '+String(e.message||e)+'</p>'; } } | |
| go.onclick=run; if (src.value.trim()) run(); | |
| })(); | |
| </script> | |
| <section data-yj-install="free" style="margin:2rem auto 1rem;max-width:46rem;padding:1.25rem 1.25rem;border:1px solid #cfe3d6;border-radius:12px;background:#f6fbf8;font:16px/1.6 system-ui,-apple-system,Segoe UI,sans-serif"><h2 style="margin:0 0 .4rem;font-size:1.2rem">Install free</h2><p style="margin:0 0 .8rem;color:#41505f">Free for the file open in your editor - no key, no limit. The workspace sweep and the report ask for a key.</p><a href="https://marketplace.visualstudio.com/items?itemName=ReadyStack.pg14-upgrade-blocker-lint" rel="noopener" data-yj-install-door="mp" onclick="try{navigator.sendBeacon('/api/ev',new Blob([JSON.stringify({t:'install',slug:'pg14-upgrade-blocker-lint',src:'mp',path:location.pathname})],{type:'application/json'}))}catch(e){}" style="display:inline-block;margin:0 .5rem .5rem 0;padding:.6rem 1rem;border-radius:8px;background:#0f7b3f;color:#fff;text-decoration:none;font-weight:600">VS Code Marketplace</a><a href="https://open-vsx.org/extension/readystack/pg14-upgrade-blocker-lint" rel="noopener" data-yj-install-door="ovsx" onclick="try{navigator.sendBeacon('/api/ev',new Blob([JSON.stringify({t:'install',slug:'pg14-upgrade-blocker-lint',src:'ovsx',path:location.pathname})],{type:'application/json'}))}catch(e){}" style="display:inline-block;margin:0 .5rem .5rem 0;padding:.6rem 1rem;border-radius:8px;background:#0f7b3f;color:#fff;text-decoration:none;font-weight:600">Open VSX (Cursor, VSCodium)</a><a href="https://www.npmjs.com/package/@readystack/pg14-upgrade-blocker-lint" rel="noopener" data-yj-install-door="npm" onclick="try{navigator.sendBeacon('/api/ev',new Blob([JSON.stringify({t:'install',slug:'pg14-upgrade-blocker-lint',src:'npm',path:location.pathname})],{type:'application/json'}))}catch(e){}" style="display:inline-block;margin:0 .5rem .5rem 0;padding:.6rem 1rem;border-radius:8px;background:#0f7b3f;color:#fff;text-decoration:none;font-weight:600">npm</a><a href="https://hub.docker.com/r/getreadystack/pg14-upgrade-blocker-lint" rel="noopener" data-yj-install-door="docker" onclick="try{navigator.sendBeacon('/api/ev',new Blob([JSON.stringify({t:'install',slug:'pg14-upgrade-blocker-lint',src:'docker',path:location.pathname})],{type:'application/json'}))}catch(e){}" style="display:inline-block;margin:0 .5rem .5rem 0;padding:.6rem 1rem;border-radius:8px;background:#0f7b3f;color:#fff;text-decoration:none;font-weight:600">Docker Hub</a><pre style="margin:.5rem 0 0;padding:.6rem .8rem;background:#f3f5f8;border-radius:8px;font-size:.9rem;overflow:auto">ext install ReadyStack.pg14-upgrade-blocker-lint | |
| npx @readystack/pg14-upgrade-blocker-lint <file> | |
| docker run --rm -v "$PWD:/w" getreadystack/pg14-upgrade-blocker-lint /w</pre><p style="margin:.6rem 0 0;font-size:.92rem;color:#41505f"><a href="https://getreadystack.com/api/buy/team" rel="nofollow" style="color:#0f7b3f;text-decoration:underline">Team? One key for every ReadyStack linter, 5 seats, $149 once</a></p></section> | |
| <section data-yj-alert="rule" style="margin:1rem auto 1.5rem;max-width:46rem;padding:1.1rem 1.25rem;border:1px solid #d9dee6;border-radius:12px;background:#fbfcfd;font:15px/1.55 system-ui,-apple-system,Segoe UI,sans-serif"><b style="font-size:1.05rem">Get the full rule table as a PDF</b><div style="opacity:.78;margin:.35rem 0 .8rem">All 21 rules PostgreSQL 14 Upgrade Lint (Aurora/RDS 2027) checks, each with its source and date, on printable pages you can hand to your team or auditor. We email it now, and once more only if a rule changes. No newsletter.</div><div style="display:flex;gap:8px;flex-wrap:wrap"><input id="yjae" type="email" placeholder="you@example.com" style="flex:1;min-width:210px;padding:11px 13px;border:1px solid rgba(140,150,165,.34);border-radius:8px;background:#fff;color:inherit"><button id="yjab" style="padding:11px 18px;border-radius:8px;border:0;cursor:pointer;background:#0f7b3f;color:#fff;font:600 15px system-ui,sans-serif">Email me the PDF</button></div><div id="yjao" hidden style="margin-top:.6rem;color:#0f7b3f">Sent. It arrives within the hour - check spam too.</div><script>(function(){var b=document.getElementById("yjab"),e=document.getElementById("yjae");if(!b||!e)return;b.addEventListener("click",function(){var v=e.value.trim();if(!/.+@.+\..+/.test(v))return;try{localStorage.setItem("yj_em","1");}catch(_){}fetch(location.origin+"/api/subscribe",{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({email:v,slug:"pg14-upgrade-blocker-lint",lang:"en",source:"rule_table"+((b.closest&&b.closest("section")&&b.closest("section").getAttribute("data-yj-moved"))?"_at_result":"")})}).then(function(r){var o=document.getElementById("yjao");o.hidden=false;if(!r.ok){o.textContent="Could not save - please try again.";}}).catch(function(){var o=document.getElementById("yjao");o.hidden=false;o.textContent="Could not save - please try again.";});});})();</script><script>(function(){var e=document.getElementById("yjae"),s=e&&e.closest?e.closest("section"):null,o=document.getElementById("out");if(!s||!o)return;var d=false;function mv(ev){if(d)return;if(ev&&ev.target&&s.contains(ev.target))return;d=true;var b=o;while(b.parentNode&&b.parentNode!==document.body&&b.parentNode.tagName!=="MAIN"&&b.parentNode.tagName!=="ARTICLE")b=b.parentNode;if(!b.parentNode||b===s||b.contains(s))return;try{b.parentNode.insertBefore(s,b.nextSibling);s.setAttribute("data-yj-moved","1");}catch(_){}}document.addEventListener("input",mv,true);document.addEventListener("change",mv,true);})();</script></section> | |
| <section data-yj-cta="paid" style="margin:3rem auto;max-width:46rem;padding:1.5rem 1.25rem;border:1px solid #d8dee9;border-radius:12px;background:#fbfcfe;font:16px/1.6 system-ui,-apple-system,Segoe UI,sans-serif"><h2 style="margin:0 0 .5rem;font-size:1.25rem">Get the complete version <span class="yj-price">$29</span></h2><p style="margin:.25rem 0 1rem;color:#41505f">This page is the working piece. The full pack has everything below.</p><p style="margin:0 0 1rem;color:#41505f">PostgreSQL upgrade 14 → 17: finds the SQL and config lines that PostgreSQL 15, 16 and 17 removed, with the fix on each line</p><p style="margin:0 0 1rem;color:#5b6b7c;font-size:.94rem">AWS bills Extended Support for Aurora/RDS PostgreSQL 14 from 1 March 2027 at $0.100 per vCPU-hour (US East Ohio): $7,008 a year for one 8-vCPU instance running 8,760 hours.</p><a href="https://getreadystack.com/api/buy/cl/polar_cl_s5avrba8KowKm6k2clM21lHLbLMEFg3UCrkFv41dVza" rel="nofollow" style="display:inline-block;padding:.7rem 1.3rem;border-radius:8px;background:#1b64f2;color:#fff;text-decoration:none;font-weight:600">Buy the full version — $29</a></section> | |
| <!--yj-share-s101--><div style="margin:28px 0 8px;text-align:center"><button id="yjcp" type="button" style="font:inherit;padding:10px 18px;border:1px solid #8884;border-radius:10px;background:transparent;cursor:pointer">Copy link</button><button id="yjimg" type="button" style="font:inherit;padding:10px 18px;margin-left:8px;border:1px solid #8884;border-radius:10px;background:transparent;cursor:pointer">Save result as image</button></div><script>(function(){var b=document.getElementById("yjimg");if(!b)return;b.addEventListener("click",function(){var o=document.getElementById("out");var txt=(o&&(o.innerText||o.textContent)||"").trim();if(!txt){b.textContent="(no result yet)";setTimeout(function(){b.textContent="Save result as image";},1500);return;}var lines=txt.split(String.fromCharCode(10)).filter(function(x){return x.trim();}).slice(0,10);var W=1200,P=56,c=document.createElement("canvas");c.width=W;var lh=38,H=P*2+70+lines.length*lh+60;c.height=H;var x=c.getContext("2d");x.fillStyle="#1a1512";x.fillRect(0,0,W,H);x.fillStyle="#f3e9d2";x.font="600 34px system-ui,Segoe UI,Arial";var t=(document.title||"").split("|")[0].trim();x.fillText(t.slice(0,54),P,P+34);x.font="22px ui-monospace,Menlo,Consolas,monospace";x.fillStyle="#e8dcc4";for(var i=0;i<lines.length;i++){x.fillText(lines[i].slice(0,88),P,P+70+i*lh+22);}x.font="600 22px system-ui,Segoe UI,Arial";x.fillStyle="#c9a227";var d=location.hostname.replace("www.","");x.fillText(d,W-P-x.measureText(d).width,H-P+6);c.toBlob(function(bl){var u=URL.createObjectURL(bl),a=document.createElement("a");a.href=u;a.download=(t||"result").replace(/[^a-z0-9]+/gi,"-").toLowerCase()+"-"+d+".png";document.body.appendChild(a);a.click();setTimeout(function(){URL.revokeObjectURL(u);a.remove();},2000);},"image/png");});})();</script><script>(function(){var b=document.getElementById("yjcp");if(!b)return;var t=b.textContent;b.addEventListener("click",function(){var u=location.href.split("#")[0];function d(){b.textContent="Link copied";setTimeout(function(){b.textContent=t;},1800);}if(navigator.clipboard&&navigator.clipboard.writeText){navigator.clipboard.writeText(u).then(d,function(){prompt("",u);});}else{prompt("",u);}});})();</script> | |
| <script data-yj="yj-view-beacon">(function(){try{var p=location.pathname;var k='yjv:'+p;if(sessionStorage.getItem(k))return;sessionStorage.setItem(k,'1');fetch('/api/ev',{method:'POST',keepalive:true,headers:{'Content-Type':'application/json'},body:JSON.stringify({path:p,lang:"en",ref:(document.referrer||''),src:(function(){try{return (new URLSearchParams(location.search).get('ref')||'').replace(/[^a-z_]/g,'').slice(0,12)}catch(e){return ''}})()})}).catch(function(){});}catch(e){}})();</script> | |
| <script data-yj="yj-use-beacon">(function(){try{var o=document.getElementById('out');if(!o)return;var p=location.pathname,k='yju:'+p,sent=false;function fire(){if(sent||sessionStorage.getItem(k))return;if(!(o.textContent||'').replace(/\s+/g,'').length)return;sent=true;sessionStorage.setItem(k,'1');fetch('/api/ev',{method:'POST',keepalive:true,headers:{'Content-Type':'application/json'},body:JSON.stringify({path:p,lang:"en",t:'use',src:(function(){try{return (new URLSearchParams(location.search).get('ref')||'').replace(/[^a-z_]/g,'').slice(0,12)}catch(e){return ''}})()})}).catch(function(){});}var mo=new MutationObserver(function(){fire();if(sent)mo.disconnect();});mo.observe(o,{childList:true,characterData:true,subtree:true});}catch(e){}})();</script><div class="yj-home-find"><div class="yj-lgbar"><a href="/" class="yj-lg on">EN</a><a href="/de/" class="yj-lg">DE</a><a href="/ja/" class="yj-lg">JA</a><a href="/es/" class="yj-lg">ES</a><a href="/pt/" class="yj-lg">PT</a></div><section class="yj-find"><h2>Find a tool</h2><input id="yjq" type="search" autocomplete="off" placeholder="Type a product name, format or task"><div id="yjr"></div></section><style>.yj-lgbar{position:absolute;top:14px;right:18px;display:flex;gap:6px;z-index:60}.yj-lg{font:600 12px/1 system-ui,sans-serif;padding:6px 9px;border-radius:4px;text-decoration:none;color:#8b96a3;border:1px solid rgba(140,150,165,.28)}.yj-lg:hover{color:#e8eaed;border-color:rgba(160,175,195,.6)}.yj-lg.on{color:#0e1116;background:#cfd6de;border-color:#cfd6de}.yj-find{max-width:760px;margin:34px auto 8px;padding:0 20px}.yj-find h2{font:600 20px/1.3 system-ui,sans-serif;margin:0 0 10px}#yjq{width:100%;box-sizing:border-box;padding:13px 15px;font:400 15.5px system-ui,sans-serif;border:1px solid rgba(140,150,165,.34);border-radius:8px;background:rgba(255,255,255,.04);color:inherit}#yjq:focus{outline:none;border-color:#7FD1C4}#yjr{margin-top:10px;display:flex;flex-direction:column;gap:6px}#yjr a{display:flex;justify-content:space-between;gap:12px;padding:11px 14px;border:1px solid rgba(140,150,165,.22);border-radius:6px;text-decoration:none;font:400 14.5px/1.4 system-ui,sans-serif;color:inherit}#yjr a:hover{border-color:#7FD1C4}#yjr .pr{font:600 13px system-ui,sans-serif;color:#5fbf9a;white-space:nowrap}</style><script>(function(){var q=document.getElementById("yjq"),r=document.getElementById("yjr"),D=null;function load(){if(D)return Promise.resolve(D);return fetch("/search-index.json").then(function(x){return x.json();}).then(function(j){D=j;return j;}).catch(function(){D=[];return D;});}function esc(t){return String(t).replace(/[&<>"]/g,function(c){return {"&":"&","<":"<",">":">",'"':"""}[c];});}function run(){var v=q.value.trim().toLowerCase();if(v.length<2){r.innerHTML="";return;}load().then(function(j){var w=v.split(/\s+/),o=[];for(var i=0;i<j.length&&o.length<12;i++){var t=j[i].t.toLowerCase();var ok=true;for(var k=0;k<w.length;k++){if(t.indexOf(w[k])<0){ok=false;break;}}if(ok)o.push(j[i]);}r.innerHTML=o.length?o.map(function(x){return "<a href=\""+esc(x.u)+"\">"+"<span>"+esc(x.t)+"</span>"+(x.p?"<span class=\"pr\">$"+x.p+"</span>":"")+"</a>";}).join(""):"";});}q.addEventListener("input",run);q.addEventListener("focus",load);})();</script></div><section data-yj="yj-facts-v1" style="max-width:920px;margin:48px auto 0;padding:0 20px;font-family:system-ui,sans-serif"><style>.yj-article p{font:400 15.5px/1.7 system-ui,sans-serif;color:#26313b;margin:0 0 12px;max-width:72ch}.yj-article h2,.yj-article h3,.yj-article h4{font:600 17px/1.35 system-ui,sans-serif;color:#1b1f24;margin:22px 0 8px}.yj-article table{border-collapse:collapse;margin:10px 0 16px;font:14px/1.45 system-ui,sans-serif}.yj-article th,.yj-article td{border:1px solid #e2e6ea;padding:6px 10px;text-align:left}.yj-article th{background:#f4f6f8}.yj-article pre{background:#0f1720;color:#e6edf3;padding:12px 14px;border-radius:8px;overflow:auto;font:13px/1.5 ui-monospace,Menlo,monospace}.yj-article code{font:13px ui-monospace,Menlo,monospace;background:#f1f3f5;padding:1px 4px;border-radius:3px}.yj-article pre code{background:none;padding:0}.yj-article ul,.yj-article ol{font:15px/1.6 system-ui,sans-serif;color:#26313b}</style><p style="font:400 13px/1.5 system-ui,sans-serif;color:#6b7680;margin:0 0 14px"><time datetime="2026-09-27">Updated 2026-09-27</time> · ReadyStack</p><script type="application/ld+json">{"@context":"https://schema.org","@type":"WebPage","dateModified":"2026-09-27","author":{"@type":"Organization","name":"ReadyStack"}}</script><h2 style="font:600 21px/1.3 system-ui,sans-serif;margin:0 0 6px;color:#1b1f24">Worked example</h2><p style="font:400 14.5px/1.5 system-ui,sans-serif;margin:0 0 16px;color:#5b6570">Real numbers from this tool, line by line.</p><div class="yj-article"><p><img src="https://getreadystack.com/img/promo/sku325988_result_card.jpg" alt="PostgreSQL 14 Upgrade Lint (Aurora/RDS 2027)" loading="lazy" style="max-width:100%;border-radius:6px"></p> | |
| <p>Six lines in one sample SQL file break a PostgreSQL 14 to 17 upgrade, and backend teams on Amazon Aurora PostgreSQL 14 or RDS for PostgreSQL 14 have until 28 February 2027 to find lines like them before AWS starts billing Extended Support.</p> | |
| <p>The dates come from the AWS release calendars. For PostgreSQL 14 on both Aurora and RDS, standard support ends on 28 February 2027. Extended Support year 1 pricing starts on 1 March 2027, year 3 pricing on 1 March 2029, and Extended Support itself ends on 28 February 2030. In US East (Ohio) the charge is $0.100 per vCPU-hour in years 1 and 2 and $0.200 in year 3. One 8-vCPU instance running 8,760 hours a year works out at 8 x $0.100 x 8,760 = $7,008 a year, before you pay for the instance.</p> | |
| <p>So the upgrade is the cheaper path. The trouble is that the upgrade checks look at the wrong place. pg_upgrade --check and the Aurora pre-upgrade check read the catalog of the running cluster. They do not read the backup scripts, monitoring views, ALTER SYSTEM files and migrations that live in your Git repository. A function body that calls pg_start_backup() upgrades without a complaint and then fails the first time the nightly job runs.</p> | |
| <p>Here is the sample file that ships with the extension, and what PostgreSQL 14 Upgrade Lint says about it:</p> | |
| <p>SELECT pg_start_backup('nightly', true); -- renamed in 15: pg_backup_start() SELECT pg_stop_backup(); -- renamed in 15: pg_backup_stop() CREATE EXTENSION IF NOT EXISTS adminpack; -- removed in 17 ... LANGUAGE plpythonu; -- removed in 15: plpython3u SELECT checkpoints_timed ... FROM pg_stat_bgwriter; -- moved in 17: pg_stat_checkpointer ALTER SYSTEM SET vacuum_defer_cleanup_age = 10000; -- removed in 16</p> | |
| <p>Each of the six is a line that was fine on 14. Three were removed or renamed in PostgreSQL 15, one in 16 and two in 17. The fixed version of the same file, also bundled, returns zero findings.</p> | |
| <p>The extension carries 21 rules, all taken from the "Migration to Version 15", "16" and "17" sections of the PostgreSQL release notes. They cover the backup functions that lost exclusive mode, Python 2 languages, server variables such as stats_temp_directory, promote_trigger_file, old_snapshot_threshold and db_user_namespace, the adminpack extension, the pg_stat_statements columns blk_read_time and blk_write_time that became shared_blk_read_time and shared_blk_write_time, the checkpoint columns that left pg_stat_bgwriter, and the ICU locale columns colliculocale and daticulocale. Lines inside -- comments and # config comments are skipped, so a note about what you already removed does not count against you.</p> | |
| <p>Why not ask a chatbot? Most public examples of backup scripts and monitoring queries were written for PostgreSQL 14 and earlier, and assistants still produce pg_start_backup() and checkpoints_timed. A rule list read from the release notes does not drift.</p> | |
| <p>The free part is complete on its own. Open any .sql, .conf or .tf file in VS Code, or paste it into the web page, and every blocker appears with its line number, the version that removed it and the line to write instead. No key, no account, nothing uploaded.</p> | |
| <p>The next job is the upgrade ticket itself: a list of every blocker across every migration folder. That is the paid part, a one-time licence that scans the whole workspace at once and exports one report as Markdown and CSV.</p> | |
| <p>Start with the file you trust least, usually the backup script or the Grafana query nobody has touched since 2021.</p></div><h2 style="font:600 19px/1.3 system-ui,sans-serif;margin:30px 0 10px;color:#1b1f24">15 seconds — what it actually does</h2><video controls muted playsinline preload="none" poster="/img/promo/sku325988_result_card.jpg" style="width:100%;max-width:360px;border-radius:10px;display:block;margin:0 auto"><source src="/media/sku325988_short.mp4" type="video/mp4"></video><h2 style="font:600 21px/1.3 system-ui,sans-serif;margin:34px 0 6px;color:#1b1f24">Questions people ask</h2><details style="border-bottom:1px solid #e6e9ed;padding:10px 0"><summary style="cursor:pointer;font:600 15px/1.4 system-ui,sans-serif;color:#1b1f24">What does PostgreSQL 14 Upgrade Lint check?</summary><p style="margin:8px 0 2px;font:400 14.5px/1.6 system-ui,sans-serif;color:#33404b">It reads .sql, .conf and .tf files line by line and flags 21 functions, server variables, languages and catalog columns that PostgreSQL 15, 16 or 17 removed or renamed, such as pg_start_backup(), plpythonu, vacuum_defer_cleanup_age, adminpack and the checkpoint columns of pg_stat_bgwriter. Every finding names the version that removed it and the replacement to write instead.</p></details><details style="border-bottom:1px solid #e6e9ed;padding:10px 0"><summary style="cursor:pointer;font:600 15px/1.4 system-ui,sans-serif;color:#1b1f24">Who is PostgreSQL 14 Upgrade Lint for?</summary><p style="margin:8px 0 2px;font:400 14.5px/1.6 system-ui,sans-serif;color:#33404b">Backend developers, DBAs and platform teams running Amazon Aurora PostgreSQL 14 or RDS for PostgreSQL 14 who must move to 16 or 17 before standard support ends on 28 February 2027. It also fits anyone upgrading a self-managed PostgreSQL 14 cluster who keeps backup scripts, monitoring queries and migrations in a Git repository.</p></details><details style="border-bottom:1px solid #e6e9ed;padding:10px 0"><summary style="cursor:pointer;font:600 15px/1.4 system-ui,sans-serif;color:#1b1f24">Why not rely on pg_upgrade --check or a chatbot?</summary><p style="margin:8px 0 2px;font:400 14.5px/1.6 system-ui,sans-serif;color:#33404b">pg_upgrade --check and the Aurora pre-upgrade check read the catalog of the running cluster, not the .sql files, monitoring queries and ALTER SYSTEM scripts in your repository. A function body that calls pg_start_backup() still upgrades and then fails at run time. Chatbots trained on PostgreSQL 14 era examples still suggest the removed names.</p></details><details style="border-bottom:1px solid #e6e9ed;padding:10px 0"><summary style="cursor:pointer;font:600 15px/1.4 system-ui,sans-serif;color:#1b1f24">What is free and what does the $29 licence add?</summary><p style="margin:8px 0 2px;font:400 14.5px/1.6 system-ui,sans-serif;color:#33404b">Free, with no key: lint the open .sql, .conf or .tf file in VS Code or paste it into the web page, and get every blocker with its line number and fix. The $29 one-time licence scans every migration in the workspace at once and exports one upgrade-blocker report as Markdown and CSV for the upgrade ticket.</p></details><details style="border-bottom:1px solid #e6e9ed;padding:10px 0"><summary style="cursor:pointer;font:600 15px/1.4 system-ui,sans-serif;color:#1b1f24">What does staying on PostgreSQL 14 cost on AWS?</summary><p style="margin:8px 0 2px;font:400 14.5px/1.6 system-ui,sans-serif;color:#33404b">From 1 March 2027 AWS bills Extended Support for Aurora and RDS PostgreSQL 14 at $0.100 per vCPU-hour in US East (Ohio), rising to $0.200 from 1 March 2029. One 8-vCPU instance running 8,760 hours a year costs 8 x $0.100 x 8,760 = $7,008 a year on top of the instance price.</p></details><details style="border-bottom:1px solid #e6e9ed;padding:10px 0"><summary style="cursor:pointer;font:600 15px/1.4 system-ui,sans-serif;color:#1b1f24">Why not just ask ChatGPT or another AI chat?</summary><p style="margin:8px 0 2px;font:400 14.5px/1.6 system-ui,sans-serif;color:#33404b">A general AI chat answers from training data with a cutoff date, cannot read your repository and names no rule version. PostgreSQL 14 Upgrade Lint (Aurora/RDS 2027) checks the file you open against 21 rules from a rule set dated 2026-09-27, and points at the exact line with the fix. For a filing, an audit or a client you need that dated result on your own files.</p></details><script type="application/ld+json" data-yj="yj-faq-ld">{"@context": "https://schema.org", "@type": "FAQPage", "mainEntity": [{"@type": "Question", "name": "What does PostgreSQL 14 Upgrade Lint check?", "acceptedAnswer": {"@type": "Answer", "text": "It reads .sql, .conf and .tf files line by line and flags 21 functions, server variables, languages and catalog columns that PostgreSQL 15, 16 or 17 removed or renamed, such as pg_start_backup(), plpythonu, vacuum_defer_cleanup_age, adminpack and the checkpoint columns of pg_stat_bgwriter. Every finding names the version that removed it and the replacement to write instead."}}, {"@type": "Question", "name": "Who is PostgreSQL 14 Upgrade Lint for?", "acceptedAnswer": {"@type": "Answer", "text": "Backend developers, DBAs and platform teams running Amazon Aurora PostgreSQL 14 or RDS for PostgreSQL 14 who must move to 16 or 17 before standard support ends on 28 February 2027. It also fits anyone upgrading a self-managed PostgreSQL 14 cluster who keeps backup scripts, monitoring queries and migrations in a Git repository."}}, {"@type": "Question", "name": "Why not rely on pg_upgrade --check or a chatbot?", "acceptedAnswer": {"@type": "Answer", "text": "pg_upgrade --check and the Aurora pre-upgrade check read the catalog of the running cluster, not the .sql files, monitoring queries and ALTER SYSTEM scripts in your repository. A function body that calls pg_start_backup() still upgrades and then fails at run time. Chatbots trained on PostgreSQL 14 era examples still suggest the removed names."}}, {"@type": "Question", "name": "What is free and what does the $29 licence add?", "acceptedAnswer": {"@type": "Answer", "text": "Free, with no key: lint the open .sql, .conf or .tf file in VS Code or paste it into the web page, and get every blocker with its line number and fix. The $29 one-time licence scans every migration in the workspace at once and exports one upgrade-blocker report as Markdown and CSV for the upgrade ticket."}}, {"@type": "Question", "name": "What does staying on PostgreSQL 14 cost on AWS?", "acceptedAnswer": {"@type": "Answer", "text": "From 1 March 2027 AWS bills Extended Support for Aurora and RDS PostgreSQL 14 at $0.100 per vCPU-hour in US East (Ohio), rising to $0.200 from 1 March 2029. One 8-vCPU instance running 8,760 hours a year costs 8 x $0.100 x 8,760 = $7,008 a year on top of the instance price."}}, {"@type": "Question", "name": "Why not just ask ChatGPT or another AI chat?", "acceptedAnswer": {"@type": "Answer", "text": "A general AI chat answers from training data with a cutoff date, cannot read your repository and names no rule version. PostgreSQL 14 Upgrade Lint (Aurora/RDS 2027) checks the file you open against 21 rules from a rule set dated 2026-09-27, and points at the exact line with the fix. For a filing, an audit or a client you need that dated result on your own files."}}]}</script><div id="yj-ask" style="margin:36px 0 0;padding:18px 18px 16px;border:1px solid #e2e6ea;border-radius:10px;background:#fbfbfc"><h2 style="font:600 19px/1.3 system-ui,sans-serif;margin:0 0 4px;color:#1b1f24">Ask about this tool</h2><p style="font:400 13.5px/1.5 system-ui,sans-serif;margin:0 0 12px;color:#5b6570">One question, answered by the person who built it. Your email only if you want the answer sent.</p><form onsubmit="return yjAsk(event)" style="display:grid;gap:8px"><textarea name="question" required minlength="10" maxlength="2000" rows="3" placeholder="Your question" style="font:14px/1.5 system-ui,sans-serif;padding:10px;border:1px solid #cfd6dd;border-radius:6px"></textarea><div style="display:flex;gap:8px;flex-wrap:wrap"><input type="email" name="email" placeholder="Email (optional)" style="flex:1;min-width:200px;font:14px system-ui,sans-serif;padding:9px 10px;border:1px solid #cfd6dd;border-radius:6px"><button type="submit" style="font:600 14px system-ui,sans-serif;padding:9px 18px;border:0;border-radius:6px;background:#1b1f24;color:#fff;cursor:pointer">Send</button></div><p id="yj-ask-msg" style="font:13px system-ui,sans-serif;margin:2px 0 0;color:#0a6238;min-height:1em"></p></form><script>function yjAsk(e){e.preventDefault();var f=e.target,m=document.getElementById("yj-ask-msg");m.style.color="#0a6238";fetch(location.origin+"/api/ask",{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({sku:325988,slug:"pg14-upgrade-blocker-lint",lang:"en",question:f.question.value,email:f.email.value,page:location.pathname})}).then(function(r){if(!r.ok)throw 0;m.textContent="Thanks \u2014 noted. Answers land on this page and, if you left an email, in your inbox.";f.question.value="";}).catch(function(){m.style.color="#a8551f";m.textContent="Could not send. Please try again in a minute.";});return false;}</script></div></section><section class="yj-related" style="max-width:920px;margin:56px auto 40px;padding:0 20px"><h2 style="font:600 21px/1.3 system-ui,sans-serif;margin:0 0 6px;color:#1b1f24">Same job, next tool</h2><p style="font:400 14.5px/1.5 system-ui,sans-serif;margin:0 0 20px;color:#5b6570">Free in the browser. The full version is a one-time licence.</p><div style="display:grid;grid-template-columns:repeat(auto-fill,minmax(250px,1fr));gap:14px"><a class="yj-rel-c" href="https://getreadystack.com/tools/angular-removed-api-lint"><span class="yj-rel-t">Angular Removed-API Lint</span><span class="yj-rel-p">$29</span></a><a class="yj-rel-c" href="https://getreadystack.com/tools/jdk25-upgrade-blocker-lint"><span class="yj-rel-t">JDK 25 Upgrade Blocker Lint</span><span class="yj-rel-p">$29</span></a><a class="yj-rel-c" href="https://getreadystack.com/tools/livewire3-upgrade-blocker-lint"><span class="yj-rel-t">Livewire 3 Upgrade Blocker Lint</span><span class="yj-rel-p">$29</span></a><a class="yj-rel-c" href="https://getreadystack.com/tools/python-upgrade-removed-api-lint"><span class="yj-rel-t">Python Upgrade Lint: Removed Stdlib 3.12-3.14</span><span class="yj-rel-p">$29</span></a><a class="yj-rel-c" href="https://getreadystack.com/tools/tailwind-v4-upgrade-blocker-lint"><span class="yj-rel-t">Tailwind v4 Upgrade Blocker Lint</span><span class="yj-rel-p">$29</span></a><a class="yj-rel-c" href="https://getreadystack.com/tools/config-dsl-lint-snippet-pack"><span class="yj-rel-t">Config & DSL Lint + Snippets — 9 Sets</span><span class="yj-rel-p">$29</span></a></div><style>.yj-rel-c{display:flex;flex-direction:column;gap:8px;padding:15px 16px;border:1px solid #e2e6ea;border-radius:6px;text-decoration:none;background:#fff}.yj-rel-c:hover{border-color:#b9c2cb;background:#fafbfc}.yj-rel-t{font:500 14.5px/1.42 system-ui,sans-serif;color:#1b1f24}.yj-rel-p{font:600 13px system-ui,sans-serif;color:#0a6238}</style></section></body> | |
| </html> | |