Overview

Pigsty

Pigsty is a Me-Better Open-Source RDS Alternative with:

Free RDS for PostgreSQL! check for details.

  • Battery-Included PostgreSQL Distribution, with , TimescaleDB, , PGVector, etc…
  • Incredible observability powered by & Grafana stack. Public .
  • Self-healing HA PGSQL cluster, powered by patroni, , etcd
  • Auto-Configured PITR, powered by and optional MinIO cluster
  • Declarative API, Database-as-Code implemented with playbooks.
  • Versatile Scenarios, run Docker apps, build demos, visualize data with .
  • Handy Toolbox, provision IaaS with Terraform, and try with local sandbox.

Prepare a new node with Linux x86_64 EL compatible OS, then run as a sudo-able user:

Then you will have a pigsty singleton node ready, with Web Services on port 80 and Postgres on port 5432.

Check Installation for details.

Download Directly

You can also download pigsty source and packages with git or curl directly:

  1. # get from GitHub
  2. bash -c "$(curl -fsSL https://raw.githubusercontent.com/Vonng/pigsty/master/bin/get)"
  3. # or download tarball directly with curl
  4. curl -L https://github.com/Vonng/pigsty/releases/download/v2.0.2/pigsty-v2.0.2.tgz -o ~/pigsty.tgz # SRC
  5. curl -L https://github.com/Vonng/pigsty/releases/download/v2.0.2/pigsty-pkg-v2.0.2.el9.x86_64.tgz -o /tmp/pkg.tgz # EL9
  6. curl -L https://github.com/Vonng/pigsty/releases/download/v2.0.2/pigsty-pkg-v2.0.2.el8.x86_64.tgz -o /tmp/pkg.tgz # EL8
  7. curl -L https://github.com/Vonng/pigsty/releases/download/v2.0.2/pigsty-pkg-v2.0.2.el7.x86_64.tgz -o /tmp/pkg.tgz # EL7
  8. # or using git if curl not available
  9. git clone https://github.com/Vonng/pigsty; cd pigsty; git checkout v2.0.2
  • INFRA: Local yum repo, Nginx, DNS, and entire Prometheus & Grafana observability stack.
  • : Init node name, repo, pkg, NTP, ssh, admin, tune, expose services, collect logs & metrics.
  • ETCD: Init etcd cluster for HA Postgres DCS or Kubernetes, used as distributed config store.
  • : Autonomous self-healing PostgreSQL cluster powered by Patroni, Pgbouncer, PgBackrest & HAProxy
  • REDIS: Deploy Redis servers in standalone master-replica, sentinel, and native cluster mode, optional.
  • : S3-compatible object storage service used as an optional central backup server for PGSQL.

You can compose them freely in a declarative manner. If you want host monitoring, INFRA & NODE will suffice. ETCD and PGSQL are used for HA PG clusters, install them on multiple nodes will automatically form a HA cluster. You can also reuse pigsty infra and develop your own modules, KAFKA, MYSQL, GPSQL, and more will come.

The default install.yml playbook in will install INFRA, NODE, ETCD & PGSQL on the current node. which gives you a battery-included PostgreSQL singleton instance (admin_ip:5432) with everything ready. This node can be used as an admin center & infra provider to manage, deploy & monitor more nodes & clusters.

Check Architecture for details.

To deploy a 3-node HA Postgres Cluster with streaming replication, define a new cluster on all.children.pg-test of :

  1. pg-test:
  2. hosts:
  3. 10.10.10.11: { pg_seq: 1, pg_role: primary }
  4. 10.10.10.12: { pg_seq: 2, pg_role: replica }
  5. 10.10.10.13: { pg_seq: 3, pg_role: offline }
  6. vars: { pg_cluster: pg-test }

Then create it with built-in playbooks:

You can deploy different kinds of instance roles, such as primary, replica, offline, delayed, sync standby, and different kinds of clusters, such as standby clusters, Citus clusters, and even Redis/MinIO/Etcd clusters.

Example: Complex Postgres Customize

  1. pg-meta:
  2. hosts: { 10.10.10.10: { pg_seq: 1, pg_role: primary , pg_offline_query: true } }
  3. vars:
  4. pg_cluster: pg-meta
  5. pg_databases: # define business databases on this cluster, array of database definition
  6. - name: meta # REQUIRED, `name` is the only mandatory field of a database definition
  7. baseline: cmdb.sql # optional, database sql baseline path, (relative path among ansible search path, e.g files/)
  8. pgbouncer: true # optional, add this database to pgbouncer database list? true by default
  9. schemas: [pigsty] # optional, additional schemas to be created, array of schema names
  10. extensions: # optional, additional extensions to be installed: array of `{name[,schema]}`
  11. - { name: postgis , schema: public }
  12. comment: pigsty meta database # optional, comment string for this database
  13. template: template1 # optional, which template to use, template1 by default
  14. encoding: UTF8 # optional, database encoding, UTF8 by default. (MUST same as template database)
  15. locale: C # optional, database locale, C by default. (MUST same as template database)
  16. lc_collate: C # optional, database collate, C by default. (MUST same as template database)
  17. lc_ctype: C # optional, database ctype, C by default. (MUST same as template database)
  18. tablespace: pg_default # optional, default tablespace, 'pg_default' by default.
  19. allowconn: true # optional, allow connection, true by default. false will disable connect at all
  20. revokeconn: false # optional, revoke public connection privilege. false by default. (leave connect with grant option to owner)
  21. register_datasource: true # optional, register this database to grafana datasources? true by default
  22. connlimit: -1 # optional, database connection limit, default -1 disable limit
  23. pool_auth_user: dbuser_meta # optional, all connection to this pgbouncer database will be authenticated by this user
  24. pool_mode: transaction # optional, pgbouncer pool mode at database level, default transaction
  25. pool_size: 64 # optional, pgbouncer pool size at database level, default 64
  26. pool_size_reserve: 32 # optional, pgbouncer pool size reserve at database level, default 32
  27. pool_size_min: 0 # optional, pgbouncer pool size min at database level, default 0
  28. pool_max_db_conn: 100 # optional, max database connections at database level, default 100
  29. - { name: grafana ,owner: dbuser_grafana ,revokeconn: true ,comment: grafana primary database }
  30. - { name: bytebase ,owner: dbuser_bytebase ,revokeconn: true ,comment: bytebase primary database }
  31. - { name: kong ,owner: dbuser_kong ,revokeconn: true ,comment: kong the api gateway database }
  32. - { name: gitea ,owner: dbuser_gitea ,revokeconn: true ,comment: gitea meta database }
  33. - { name: wiki ,owner: dbuser_wiki ,revokeconn: true ,comment: wiki meta database }
  34. pg_users: # define business users/roles on this cluster, array of user definition
  35. - name: dbuser_meta # REQUIRED, `name` is the only mandatory field of a user definition
  36. password: DBUser.Meta # optional, password, can be a scram-sha-256 hash string or plain text
  37. login: true # optional, can log in, true by default (new biz ROLE should be false)
  38. superuser: false # optional, is superuser? false by default
  39. createdb: false # optional, can create database? false by default
  40. createrole: false # optional, can create role? false by default
  41. inherit: true # optional, can this role use inherited privileges? true by default
  42. replication: false # optional, can this role do replication? false by default
  43. bypassrls: false # optional, can this role bypass row level security? false by default
  44. pgbouncer: true # optional, add this user to pgbouncer user-list? false by default (production user should be true explicitly)
  45. connlimit: -1 # optional, user connection limit, default -1 disable limit
  46. expire_in: 3650 # optional, now + n days when this role is expired (OVERWRITE expire_at)
  47. expire_at: '2030-12-31' # optional, YYYY-MM-DD 'timestamp' when this role is expired (OVERWRITTEN by expire_in)
  48. comment: pigsty admin user # optional, comment string for this user/role
  49. roles: [dbrole_admin] # optional, belonged roles. default roles are: dbrole_{admin,readonly,readwrite,offline}
  50. parameters: {} # optional, role level parameters with `ALTER ROLE SET`
  51. pool_mode: transaction # optional, pgbouncer pool mode at user level, transaction by default
  52. pool_connlimit: -1 # optional, max database connections at user level, default -1 disable limit
  53. - {name: dbuser_view ,password: DBUser.Viewer ,pgbouncer: true ,roles: [dbrole_readonly], comment: read-only viewer for meta database}
  54. - {name: dbuser_grafana ,password: DBUser.Grafana ,pgbouncer: true ,roles: [dbrole_admin] ,comment: admin user for grafana database }
  55. - {name: dbuser_bytebase ,password: DBUser.Bytebase ,pgbouncer: true ,roles: [dbrole_admin] ,comment: admin user for bytebase database }
  56. - {name: dbuser_kong ,password: DBUser.Kong ,pgbouncer: true ,roles: [dbrole_admin] ,comment: admin user for kong api gateway }
  57. - {name: dbuser_gitea ,password: DBUser.Gitea ,pgbouncer: true ,roles: [dbrole_admin] ,comment: admin user for gitea service }
  58. - {name: dbuser_wiki ,password: DBUser.Wiki ,pgbouncer: true ,roles: [dbrole_admin] ,comment: admin user for wiki.js service }
  59. # standby service will route {ip|name}:5435 to sync replica's pgbouncer (5435->6432 standby)
  60. port: 5435 # required, service exposed port (work as kubernetes service node port mode)
  61. ip: "*" # optional, service bind ip address, `*` for all ip by default
  62. selector: "[]" # required, service member selector, use JMESPath to filter inventory
  63. dest: default # optional, destination port, default|postgres|pgbouncer|<port_number>, 'default' by default
  64. check: /sync # optional, health check url path, / by default
  65. backup: "[? pg_role == `primary`]" # backup server selector
  66. maxconn: 3000 # optional, max allowed front-end connection
  67. balance: roundrobin # optional, haproxy load balance algorithm (roundrobin by default, other: leastconn)
  68. options: 'inter 3s fastinter 1s downinter 5s rise 3 fall 3 on-marked-down shutdown-sessions slowstart 30s maxconn 3000 maxqueue 128 weight 100'
  69. pg_hba_rules:
  70. - {user: dbuser_view , db: all ,addr: infra ,auth: pwd ,title: 'allow grafana dashboard access cmdb from infra nodes'}
  71. pg_vip_enabled: true
  72. pg_vip_address: 10.10.10.2/24
  73. pg_vip_interface: eth1
  74. node_crontab: # make a full backup 1 am everyday
  75. - '00 01 * * * postgres /pg/bin/pg-backup full'
  76. ``` Example: Security Enhanced PG Cluster with Delayed Replica

pg-meta: # 3 instance postgres cluster pg-meta hosts: 10.10.10.10: { pg_seq: 1, pg_role: primary } 10.10.10.11: { pg_seq: 2, pg_role: replica } 10.10.10.12: { pg_seq: 3, pg_role: replica , pg_offline_query: true } vars: pg_cluster: pg-meta pg_conf: crit.yml pg_users:

  1. - { name: dbuser_meta , password: DBUser.Meta , pgbouncer: true , roles: [ dbrole_admin ] , comment: pigsty admin user }
  2. - { name: dbuser_view , password: DBUser.Viewer , pgbouncer: true , roles: [ dbrole_readonly ] , comment: read-only viewer for meta database }
  3. pg_databases:
  4. - {name: meta ,baseline: cmdb.sql ,comment: pigsty meta database ,schemas: [pigsty] ,extensions: [{name: postgis, schema: public}, {name: timescaledb}]}
  5. pg_services:
  6. - { name: standby ,src_ip: "*" ,port: 5435 , dest: default ,selector: "[]" , backup: "[? pg_role == `primary`]" }
  7. pg_vip_enabled: true
  8. pg_vip_address: 10.10.10.2/24
  9. pg_vip_interface: eth1

OPTIONAL delayed cluster for pg-meta

pg-meta-delay: # delayed instance for pg-meta (1 hour ago) hosts: { 10.10.10.13: { pg_seq: 1, pg_role: primary, pg_upstream: 10.10.10.10, pg_delay: 1h } } vars: { pg_cluster: pg-meta-delay } ``` Example: Citus Distributed Cluster: 5 Nodes

redis-ms: # redis classic primary & replica hosts: { 10.10.10.10: { redis_node: 1 , redis_instances: { 6501: { }, 6502: { replica_of: ‘10.10.10.10 6501’ } } } } vars: { redis_cluster: redis-ms ,redis_password: ‘redis.ms’ ,redis_max_memory: 64MB }

redis-meta: # redis sentinel x 3 hosts: { 10.10.10.11: { redis_node: 1 , redis_instances: { 6001: { } ,6002: { } , 6003: { } } } } vars: { redis_cluster: redis-meta ,redis_password: ‘redis.meta’ ,redis_mode: sentinel ,redis_max_memory: 16MB }

redis-test: # redis native cluster: 3m x 3s hosts: 10.10.10.12: { redis_node: 1 ,redis_instances: { 6501: { } ,6502: { } ,6503: { } } } 10.10.10.13: { redis_node: 2 ,redis_instances: { 6501: { } ,6502: { } ,6503: { } } } vars: { redis_cluster: redis-test ,redis_password: ‘redis.test’ ,redis_mode: cluster, redis_max_memory: 32MB } ``` Example: ETCD 3 Node Cluster

  1. etcd: # dcs service for postgres/patroni ha consensus
  2. hosts: # 1 node for testing, 3 or 5 for production
  3. 10.10.10.10: { etcd_seq: 1 } # etcd_seq required
  4. 10.10.10.11: { etcd_seq: 2 } # assign from 1 ~ n
  5. 10.10.10.12: { etcd_seq: 3 } # odd number please
  6. vars: # cluster level parameter override roles/etcd
  7. etcd_cluster: etcd # mark etcd cluster name etcd
  8. etcd_safeguard: false # safeguard against purging
  9. etcd_clean: true # purge etcd during init process
  10. ``` Example: Minio 3 Node Deployment
  1. - name: minio # [REQUIRED] service name, unique
  2. port: 9002 # [REQUIRED] service port, unique
  3. options:
  4. - option httpchk
  5. - option http-keep-alive
  6. - http-check send meth OPTIONS uri /minio/health/live
  7. - http-check expect status 200
  8. servers:
  9. - { name: minio-1 ,ip: 10.10.10.10 , port: 9000 , options: 'check-ssl ca-file /etc/pki/ca.crt check port 9000' }
  10. - { name: minio-2 ,ip: 10.10.10.11 , port: 9000 , options: 'check-ssl ca-file /etc/pki/ca.crt check port 9000' }

```

Check for details.

Docs:

Wiki: https://github.com/Vonng/pigsty/wiki

Website: | https://pigsty.cc/zh/

WeChat: Search to join the WeChat group.

Telegram:

Discord: https://discord.gg/wDzt5VyWEzr

Author: (rh@vonng.com)

License:

Copyright 2018-2023 rh@vonng.com