<?xml version="1.0" encoding="utf-8" standalone="yes"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom">
  <channel>
    <title>HA Cluster on pgcli</title>
    <link>https://pgcli.pages.dev/docs/ha-cluster/</link>
    <description>Recent content in HA Cluster on pgcli</description>
    <generator>Hugo</generator>
    <language>en-US</language>
    
    
    
      <lastBuildDate>Fri, 25 Sep 2026 11:29:56 +0800</lastBuildDate>
    
    
      <atom:link href="https://pgcli.pages.dev/docs/ha-cluster/index.xml" rel="self" type="application/rss+xml" />
    
    <item>
        <title>Patroni HA</title>
        <link>https://pgcli.pages.dev/docs/ha-cluster/ha/</link>
        <pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate>
        
        <guid>https://pgcli.pages.dev/docs/ha-cluster/ha/</guid>
        <description>&lt;p&gt;&lt;a href=&#34;https://patroni.readthedocs.io&#34;&gt;Patroni&lt;/a&gt; is the de-facto standard for&#xA;PostgreSQL high availability: it manages each postmaster&amp;rsquo;s lifecycle, streams&#xA;replication between members, and performs &lt;strong&gt;automatic failover&lt;/strong&gt; when the&#xA;leader is lost. pgcli exposes Patroni as a distinct mode — &lt;code&gt;pg ha&lt;/code&gt; — rather than&#xA;folding it into the plain &lt;code&gt;pg&lt;/code&gt; instance path.&lt;/p&gt;&#xA;&lt;blockquote&gt;&#xA;&lt;p&gt;&lt;strong&gt;This is a separate mode, not an addon subcommand.&lt;/strong&gt; Patroni (not pgcli) owns&#xA;the PostgreSQL process. &lt;code&gt;pg ha&lt;/code&gt; members do &lt;strong&gt;not&lt;/strong&gt; appear in &lt;code&gt;cfg.Instances&lt;/code&gt;,&#xA;share no instance lifecycle code, and are not created by &lt;code&gt;pg create&lt;/code&gt;. The one&#xA;thing it borrows from the addon system is the &lt;a href=&#34;https://pgcli.pages.dev/docs/addon/etcd/&#34;&gt;etcd&lt;/a&gt; DCS.&lt;/p&gt;</description>
      </item>
    <item>
        <title>Patroni Dynamic Configuration</title>
        <link>https://pgcli.pages.dev/docs/ha-cluster/ha-dynamic/</link>
        <pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate>
        
        <guid>https://pgcli.pages.dev/docs/ha-cluster/ha-dynamic/</guid>
        <description>&lt;p&gt;These parameters are stored in the DCS (etcd) under &lt;code&gt;/service/&amp;lt;scope&amp;gt;/config&lt;/code&gt; and&#xA;applied to &lt;strong&gt;every&lt;/strong&gt; member of the cluster. Modify them with &lt;code&gt;pg ha edit-config&lt;/code&gt;:&lt;/p&gt;&#xA;&lt;div class=&#34;td-code td-code--untitled&#34; id=&#34;td-code-36d98529-fence-0&#34; data-td-code data-td-code-auto-id&#xA;     data-td-language=&#34;bash&#34; data-td-line-count=&#34;3&#34;&gt;&#xA;  &lt;div class=&#34;td-code__viewport&#34; id=&#34;td-code-36d98529-fence-0-viewport&#34; data-td-code-viewport&gt;&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-bash&#34; data-lang=&#34;bash&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;pg ha edit-config app -- -s &lt;span class=&#34;nv&#34;&gt;loop_wait&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;m&#34;&gt;5&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;pg ha edit-config app -- -s &lt;span class=&#34;s1&#34;&gt;&amp;#39;postgresql.parameters.max_connections=200&amp;#39;&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;pg ha edit-config app --show          &lt;span class=&#34;c1&#34;&gt;# view current config&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;&#xA;&lt;/div&gt;&#xA;&lt;blockquote&gt;&#xA;&lt;p&gt;Reference: &lt;a href=&#34;https://patroni.readthedocs.io/en/latest/dynamic_configuration.html&#34;&gt;Patroni official docs&lt;/a&gt;,&#xA;&lt;a href=&#34;https://pigsty.cc/docs/patroni/config/dynamic/&#34;&gt;Pigsty dynamic config&lt;/a&gt;.&lt;/p&gt;&#xA;&lt;/blockquote&gt;&#xA;&lt;blockquote&gt;&#xA;&lt;p&gt;&lt;strong&gt;&lt;code&gt;bootstrap.dcs&lt;/code&gt; is one-time.&lt;/strong&gt; The &lt;code&gt;bootstrap.dcs&lt;/code&gt; block in &lt;code&gt;patroni.yml&lt;/code&gt;&#xA;only takes effect when the &lt;strong&gt;first&lt;/strong&gt; member of a scope bootstraps the cluster.&#xA;Once Patroni writes the config into the DCS, subsequent changes to&#xA;&lt;code&gt;bootstrap.dcs&lt;/code&gt; in the YAML file are &lt;strong&gt;completely ignored&lt;/strong&gt; — even on&#xA;re-install (&lt;code&gt;pg ha create&lt;/code&gt;). Re-running &lt;code&gt;pg ha create&lt;/code&gt; does &lt;strong&gt;not&lt;/strong&gt; re-read&#xA;&lt;code&gt;bootstrap.dcs&lt;/code&gt; — Patroni sees the existing &lt;code&gt;config&lt;/code&gt; key in the DCS and uses&#xA;it directly.&lt;/p&gt;</description>
      </item>
    <item>
        <title>Patroni REST API</title>
        <link>https://pgcli.pages.dev/docs/ha-cluster/ha-rest-api/</link>
        <pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate>
        
        <guid>https://pgcli.pages.dev/docs/ha-cluster/ha-rest-api/</guid>
        <description>&lt;p&gt;Patroni exposes an HTTP REST API on each member, providing health check endpoints&#xA;(for load balancers and Kubernetes probes), monitoring data (including Prometheus&#xA;metrics), and cluster management operations.&lt;/p&gt;&#xA;&lt;blockquote&gt;&#xA;&lt;p&gt;Reference: &lt;a href=&#34;https://patroni.readthedocs.io/en/latest/rest_api.html&#34;&gt;Patroni official docs&lt;/a&gt;,&#xA;&lt;a href=&#34;https://pigsty.cc/docs/patroni/rest_api/&#34;&gt;Pigsty REST API&lt;/a&gt;.&lt;/p&gt;&#xA;&lt;/blockquote&gt;&#xA;&lt;h2 id=&#34;finding-the-rest-api&#34;&gt;Finding the REST API&#xA;&lt;/h2&gt;&#xA;&lt;p&gt;Each member&amp;rsquo;s REST API port is assigned automatically by pgcli and stored in&#xA;&lt;code&gt;pg.yaml&lt;/code&gt; under &lt;code&gt;addons.patroni.&amp;lt;scope&amp;gt;.members.&amp;lt;name&amp;gt;.restapi_port&lt;/code&gt;. The port&#xA;is also embedded in the rendered &lt;code&gt;patroni.yml&lt;/code&gt; as &lt;code&gt;restapi.connect_address&lt;/code&gt;.&lt;/p&gt;&#xA;&lt;div class=&#34;td-code td-code--untitled&#34; id=&#34;td-code-fb544c01-fence-0&#34; data-td-code data-td-code-auto-id&#xA;     data-td-language=&#34;bash&#34; data-td-line-count=&#34;2&#34;&gt;&#xA;  &lt;div class=&#34;td-code__viewport&#34; id=&#34;td-code-fb544c01-fence-0-viewport&#34; data-td-code-viewport&gt;&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-bash&#34; data-lang=&#34;bash&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;c1&#34;&gt;# Find REST API ports&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;pg ha status app          &lt;span class=&#34;c1&#34;&gt;# shows pg= and rest= ports for each member&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;&#xA;&lt;/div&gt;&#xA;&lt;h3 id=&#34;authentication&#34;&gt;Authentication&#xA;&lt;/h3&gt;&#xA;&lt;p&gt;pgcli enables basic-auth on the REST API (username &lt;code&gt;postgres&lt;/code&gt;, auto-generated&#xA;password). But authentication is &lt;strong&gt;method-based&lt;/strong&gt;, not blanket:&lt;/p&gt;</description>
      </item>
    <item>
        <title>Extensions in HA Clusters</title>
        <link>https://pgcli.pages.dev/docs/ha-cluster/ha-extensions/</link>
        <pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate>
        
        <guid>https://pgcli.pages.dev/docs/ha-cluster/ha-extensions/</guid>
        <description>&lt;p&gt;Installing PostgreSQL extensions in a Patroni-managed HA cluster is&#xA;fundamentally different from a single-node instance. This page explains why,&#xA;and walks through the &lt;code&gt;pg ha extension&lt;/code&gt; command subtree that handles it.&lt;/p&gt;&#xA;&lt;h2 id=&#34;why-not-pg-extension-install&#34;&gt;Why not &lt;code&gt;pg extension install&lt;/code&gt;?&#xA;&lt;/h2&gt;&#xA;&lt;p&gt;The single-node flow (&lt;code&gt;pg extension install &amp;lt;instance&amp;gt; &amp;lt;ext&amp;gt;&lt;/code&gt;) works by:&lt;/p&gt;&#xA;&lt;ol&gt;&#xA;&lt;li&gt;Building a &lt;code&gt;-ext&lt;/code&gt; derived image with Pigsty packages&lt;/li&gt;&#xA;&lt;li&gt;Stopping and recreating the container from the new image&lt;/li&gt;&#xA;&lt;li&gt;Editing &lt;code&gt;postgresql.conf&lt;/code&gt; to set &lt;code&gt;shared_preload_libraries&lt;/code&gt;&lt;/li&gt;&#xA;&lt;li&gt;Running &lt;code&gt;CREATE EXTENSION&lt;/code&gt; inside the container&lt;/li&gt;&#xA;&lt;/ol&gt;&#xA;&lt;p&gt;In a Patroni cluster, &lt;strong&gt;steps 2-4 all break&lt;/strong&gt;:&lt;/p&gt;</description>
      </item>
    <item>
        <title>Patroni Cluster Backup</title>
        <link>https://pgcli.pages.dev/docs/ha-cluster/ha-backup/</link>
        <pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate>
        
        <guid>https://pgcli.pages.dev/docs/ha-cluster/ha-backup/</guid>
        <description>&lt;p&gt;This page walks the &lt;strong&gt;complete procedure for backing up a Patroni HA cluster&lt;/strong&gt;:&#xA;getting the backup infrastructure up with &lt;code&gt;pg backup setup&lt;/code&gt;, taking&#xA;full/incr/diff backups with &lt;code&gt;pg ha snapshot&lt;/code&gt;, and one operational pitfall — when a&#xA;replica&amp;rsquo;s &lt;code&gt;Replay LSN&lt;/code&gt; stalls and &lt;code&gt;pg ha status&lt;/code&gt; shows members disagreeing on LSN,&#xA;how to pull it back with &lt;code&gt;patronictl reinit&lt;/code&gt;. Command and mechanism details live in&#xA;&lt;a href=&#34;../ha/#backing-up-a-cross-host-leader&#34;&gt;Patroni HA&lt;/a&gt; and &lt;a href=&#34;../../backup/#s3-object-storage-repository&#34;&gt;Backup&lt;/a&gt;;&#xA;this page strings them into a path you can run end to end.&lt;/p&gt;</description>
      </item>
    <item>
        <title>Patroni Cluster Restore</title>
        <link>https://pgcli.pages.dev/docs/ha-cluster/ha-restore/</link>
        <pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate>
        
        <guid>https://pgcli.pages.dev/docs/ha-cluster/ha-restore/</guid>
        <description>&lt;p&gt;This page is the &lt;strong&gt;restore-side companion to &lt;a href=&#34;../ha-backup/&#34;&gt;Patroni Cluster Backup&lt;/a&gt;&lt;/strong&gt;.&#xA;Once a cluster has a stanza with WAL archiving (&lt;code&gt;pg backup setup&lt;/code&gt; + &lt;code&gt;pg ha snapshot&lt;/code&gt;),&#xA;&lt;code&gt;pg ha restore&lt;/code&gt; brings the whole cluster back to a point in time — the Patroni&#xA;counterpart of the single-instance &lt;a href=&#34;../../restore/&#34;&gt;&lt;code&gt;pg restore&lt;/code&gt;&lt;/a&gt;. It walks the&#xA;mechanism (why a cluster PITR is not just &lt;code&gt;pgbackrest restore&lt;/code&gt;), the safety&#xA;pre-check on where the leader lives, an end-to-end runbook, and the re-baseline&#xA;steps that must follow. Command/flag details also live in&#xA;&lt;a href=&#34;../../restore/#patroni-cluster&#34;&gt;Restore → Patroni cluster&lt;/a&gt;; this page strings them&#xA;into a procedure you can run.&lt;/p&gt;</description>
      </item>
    <item>
        <title>HA Exec / psql</title>
        <link>https://pgcli.pages.dev/docs/ha-cluster/ha-exec/</link>
        <pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate>
        
        <guid>https://pgcli.pages.dev/docs/ha-cluster/ha-exec/</guid>
        <description>&lt;p&gt;&lt;code&gt;pg ha exec&lt;/code&gt; and &lt;code&gt;pg ha psql&lt;/code&gt; are the direct way to run SQL against a Patroni&#xA;cluster. They are the cluster-side twins of the single-instance&#xA;&lt;a href=&#34;../../exec-psql/&#34;&gt;&lt;code&gt;pg exec&lt;/code&gt;&lt;/a&gt; and &lt;a href=&#34;../../exec-psql/&#34;&gt;&lt;code&gt;pg psql&lt;/code&gt;&lt;/a&gt;: you name&#xA;a scope, they resolve the target and connect. No &lt;code&gt;--dsn&lt;/code&gt; to hand-assemble, no&#xA;member container to &lt;code&gt;podman exec&lt;/code&gt; into, and — because the connection is plain TCP&#xA;— a leader or replica on &lt;strong&gt;another host&lt;/strong&gt; is just as reachable as a local one.&lt;/p&gt;</description>
      </item>
    <item>
        <title>Example: HA Cluster with a Self-CA MinIO</title>
        <link>https://pgcli.pages.dev/docs/ha-cluster/ha-example-minio/</link>
        <pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate>
        
        <guid>https://pgcli.pages.dev/docs/ha-cluster/ha-example-minio/</guid>
        <description>&lt;p&gt;This page is a &lt;strong&gt;worked example&lt;/strong&gt;, run end to end and verified: create a Patroni&#xA;HA cluster, stand up a MinIO addon that serves a &lt;strong&gt;bring-your-own domain&#xA;certificate&lt;/strong&gt; (a self-signed CA of our own making — the same shape as a&#xA;public-CA or corporate-CA cert, just without buying one), and point the cluster&amp;rsquo;s&#xA;pgBackRest backups and WAL archiving at it. Every command below is a real one&#xA;from the run; only hostnames, ports, passwords, and the certificate material are&#xA;genericized.&lt;/p&gt;</description>
      </item>
    <item>
        <title>Generating a Certificate — pg cert</title>
        <link>https://pgcli.pages.dev/docs/ha-cluster/ha-cert/</link>
        <pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate>
        
        <guid>https://pgcli.pages.dev/docs/ha-cluster/ha-cert/</guid>
        <description>&lt;p&gt;&lt;code&gt;pg cert&lt;/code&gt; mints a &lt;strong&gt;self-signed certificate&lt;/strong&gt; — its SubjectAltNames covering any&#xA;mix of DNS names and IP addresses you ask for — for any place you need TLS&#xA;without going through a CA: a dev or test server, an internal endpoint, a&#xA;service whose clients you control. The certificate it writes is a normal TLS&#xA;server leaf, usable anywhere.&lt;/p&gt;&#xA;&lt;p&gt;The use this docs tree exercises is pgBackRest&amp;rsquo;s S3 path: a Patroni cluster&amp;rsquo;s&#xA;backups push to an S3 store (MinIO or silo, typically) that must serve&#xA;&lt;strong&gt;TLS&lt;/strong&gt; — pgBackRest refuses plaintext S3 — and pgcli&amp;rsquo;s MinIO/silo addons can&#xA;serve a &lt;strong&gt;bring-your-own certificate&lt;/strong&gt; (&lt;code&gt;pg addon install minio --tls-cert ... --tls-key ...&lt;/code&gt;). The quickest way to get a cert to try that with is &lt;code&gt;pg cert&lt;/code&gt;:&lt;/p&gt;</description>
      </item>
    <item>
        <title>S3 Storage High Availability</title>
        <link>https://pgcli.pages.dev/docs/ha-cluster/ha-s3-storage/</link>
        <pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate>
        
        <guid>https://pgcli.pages.dev/docs/ha-cluster/ha-s3-storage/</guid>
        <description>&lt;p&gt;A Patroni cluster survives a node loss; the S3 repository its WAL and backups&#xA;stream into must survive one too, or &amp;ldquo;high availability&amp;rdquo; quietly ends at the&#xA;backup path. The store is a &lt;a href=&#34;https://pgcli.pages.dev/docs/addon/minio/&#34;&gt;MinIO&lt;/a&gt; or&#xA;&lt;a href=&#34;https://pgcli.pages.dev/docs/addon/silo/&#34;&gt;silo&lt;/a&gt; addon (the two are interchangeable — silo is Pigsty&amp;rsquo;s&#xA;MinIO fork with the same feature surface). Two fault domains matter, and they&#xA;are &lt;strong&gt;orthogonal&lt;/strong&gt;:&lt;/p&gt;&#xA;&lt;div class=&#34;td-table-scroll td-table-scroll--static&#34;&gt;&#xA;&lt;table&gt;&#xA;  &lt;thead&gt;&#xA;    &lt;tr&gt;&#xA;      &lt;th scope=&#34;col&#34;&gt;Fault&lt;/th&gt;&#xA;      &lt;th scope=&#34;col&#34;&gt;Who absorbs it&lt;/th&gt;&#xA;    &lt;/tr&gt;&#xA;  &lt;/thead&gt;&#xA;  &lt;tbody&gt;&#xA;    &lt;tr&gt;&#xA;      &lt;td&gt;A &lt;strong&gt;disk&lt;/strong&gt; dies inside a node&lt;/td&gt;&#xA;      &lt;td&gt;the drive-level EC under SNMD/MNMD, or the storage layer under MinIO&amp;rsquo;s data directory (ZFS)&lt;/td&gt;&#xA;    &lt;/tr&gt;&#xA;    &lt;tr&gt;&#xA;      &lt;td&gt;A &lt;strong&gt;node&lt;/strong&gt; dies entirely&lt;/td&gt;&#xA;      &lt;td&gt;MinIO&amp;rsquo;s own erasure coding (EC) across hosts&lt;/td&gt;&#xA;    &lt;/tr&gt;&#xA;  &lt;/tbody&gt;&#xA;&lt;/table&gt;&#xA;&lt;/div&gt;&#xA;&#xA;&lt;p&gt;This page records the shapes pgcli supports for combining the two, and how to&#xA;pick among them.&lt;/p&gt;</description>
      </item>
    
  </channel>
</rss>
