GithubHelp home page GithubHelp logo

vonng / pigsty Goto Github PK

View Code? Open in Web Editor NEW
2.7K 46.0 231.0 26.71 MB

Battery-Included PostgreSQL Distro as a Free RDS Alternative

Home Page: https://doc.pigsty.cc/

License: GNU Affero General Public License v3.0

Makefile 4.63% Shell 28.03% Python 8.05% PLpgSQL 26.12% Jinja 25.95% HCL 2.84% Ruby 2.31% Perl 1.67% TypeScript 0.40%
postgres graphics infra service toolbox yours

pigsty's Introduction

Pigsty

"PostgreSQL In Great STYle": Postgres, Infras, Graphics, Service, Toolbox, it's all Yours.

—— Battery-Included, Local-First PostgreSQL Distribution as an Open-Source RDS Alternative

Website | Demo | Blog | Discuss | Discord | Roadmap | 站点 | 博客

Get Started with the latest v2.6.0 release: curl -fsSL https://get.pigsty.cc/latest


Features

Pigsty is your postgres, infra, grafana service toolbox, check Feature | 特性 and Demo for details.

pigsty-desc


Get Started

Setup everything with one command! Check Get Started | 快速上手 for details.

Prepare a fresh Linux x86_64 node that runs compatible OS distros:

# run as the admin user with no password ssh & sudo capability
curl -fsSL https://get.pigsty.cc/latest | bash
cd ~/pigsty; ./bootstrap; ./configure; ./install.yml;

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

Download with Get
$ curl -fsSL https://get.pigsty.cc/latest | bash
...
[Checking] ===========================================
[ OK ] SOURCE from CDN due to GFW
FROM CDN    : bash -c "$(curl -fsSL https://get.pigsty.cc/latest)"
FROM GITHUB : bash -c "$(curl -fsSL https://raw.githubusercontent.com/Vonng/pigsty/master/bin/latest)"
[Downloading] ===========================================
[ OK ] download pigsty source code from CDN
[ OK ] $ curl -SL https://get.pigsty.cc/v2.6.0/pigsty-v2.6.0.tgz
...
MD5: xxxxxx.......xxxxxxxxxx  /tmp/pigsty-v2.6.0.tgz
[Extracting] ===========================================
[ OK ] extract '/tmp/pigsty-v2.6.0.tgz' to '/home/vagrant/pigsty'
[ OK ] $ tar -xf /tmp/pigsty-v2.6.0.tgz -C ~;
[Reference] ===========================================
Official Site:   https://pigsty.cc
Get Started:     https://pigsty.io/docs/setup/install/
Documentation:   https://doc.pigsty.cc
Github Repo:     https://github.com/Vonng/pigsty
Public Demo:     https://demo.pigsty.cc
[Proceeding] ===========================================
cd ~/pigsty      # entering pigsty home directory before proceeding
./bootstrap      # install ansible & download the optional offline packages
./configure      # preflight-check and generate config according to your env
./install.yml    # install pigsty on this node and init it as the admin node
[ OK ] ~/pigsty is ready to go now!
Download with Git

You can also download pigsty source with git, don't forget to use a specific version tag.

git clone https://github.com/Vonng/pigsty;
cd pigsty; git checkout v2.6.0
Download Directly

You can also download pigsty source & offline packages directly from GitHub release page.

# get from GitHub
bash -c "$(curl -fsSL https://raw.githubusercontent.com/Vonng/pigsty/master/bin/latest)"

# or download tarball directly with curl
curl -L https://github.com/Vonng/pigsty/releases/download/v2.6.0/pigsty-v2.6.0.tgz -o ~/pigsty.tgz                      # Pigsty Source
curl -L https://github.com/Vonng/pigsty/releases/download/v2.6.0/pigsty-pkg-v2.6.0.el9.x86_64.tgz      -o /tmp/pkg.tgz  # Rocky 9.3 (EL9)
curl -L https://github.com/Vonng/pigsty/releases/download/v2.6.0/pigsty-pkg-v2.6.0.el8.x86_64.tgz      -o /tmp/pkg.tgz  # Rocky 8.9 (EL8)
curl -L https://github.com/Vonng/pigsty/releases/download/v2.6.0/pigsty-pkg-v2.6.0.ubuntu22.x86_64.tgz -o /tmp/pkg.tgz  # Ubuntu 22.04

# alternative CDN in china 
curl -L https://get.pigsty.cc/v2.6.0/pigsty-v2.6.0.tgz -o ~/pigsty.tgz
curl -L https://get.pigsty.cc/v2.6.0/pigsty-pkg-v2.6.0.el8.x86_64.tgz -o /tmp/pkg.tgz       # EL8: Rocky 8.9 ...

asciicast


Architecture

Pigsty uses a modular design. There are six default modules available:

  • INFRA: Local yum repo, Nginx, DNS, and entire Prometheus & Grafana observability stack.
  • NODE: 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.
  • PGSQL: 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.
  • MINIO: S3-compatible object storage service used as an optional central backup server for PGSQL, optional.

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 Get Started 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.

pigsty-arch.jpg


More Clusters

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

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

Then create it with built-in playbooks:

bin/pgsql-add pg-test   # init pg-test cluster 

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
pg-meta:
  hosts: { 10.10.10.10: { pg_seq: 1, pg_role: primary , pg_offline_query: true } }
  vars:
    pg_cluster: pg-meta
    pg_databases:                       # define business databases on this cluster, array of database definition
      - name: meta                      # REQUIRED, `name` is the only mandatory field of a database definition
        baseline: cmdb.sql              # optional, database sql baseline path, (relative path among ansible search path, e.g files/)
        pgbouncer: true                 # optional, add this database to pgbouncer database list? true by default
        schemas: [pigsty]               # optional, additional schemas to be created, array of schema names
        extensions:                     # optional, additional extensions to be installed: array of `{name[,schema]}`
          - { name: postgis , schema: public }
          - { name: timescaledb }
        comment: pigsty meta database   # optional, comment string for this database
        owner: postgres                # optional, database owner, postgres by default
        template: template1            # optional, which template to use, template1 by default
        encoding: UTF8                 # optional, database encoding, UTF8 by default. (MUST same as template database)
        locale: C                      # optional, database locale, C by default.  (MUST same as template database)
        lc_collate: C                  # optional, database collate, C by default. (MUST same as template database)
        lc_ctype: C                    # optional, database ctype, C by default.   (MUST same as template database)
        tablespace: pg_default         # optional, default tablespace, 'pg_default' by default.
        allowconn: true                # optional, allow connection, true by default. false will disable connect at all
        revokeconn: false              # optional, revoke public connection privilege. false by default. (leave connect with grant option to owner)
        register_datasource: true      # optional, register this database to grafana datasources? true by default
        connlimit: -1                  # optional, database connection limit, default -1 disable limit
        pool_auth_user: dbuser_meta    # optional, all connection to this pgbouncer database will be authenticated by this user
        pool_mode: transaction         # optional, pgbouncer pool mode at database level, default transaction
        pool_size: 64                  # optional, pgbouncer pool size at database level, default 64
        pool_size_reserve: 32          # optional, pgbouncer pool size reserve at database level, default 32
        pool_size_min: 0               # optional, pgbouncer pool size min at database level, default 0
        pool_max_db_conn: 100          # optional, max database connections at database level, default 100
      - { name: grafana  ,owner: dbuser_grafana  ,revokeconn: true ,comment: grafana primary database }
      - { name: bytebase ,owner: dbuser_bytebase ,revokeconn: true ,comment: bytebase primary database }
      - { name: kong     ,owner: dbuser_kong     ,revokeconn: true ,comment: kong the api gateway database }
      - { name: gitea    ,owner: dbuser_gitea    ,revokeconn: true ,comment: gitea meta database }
      - { name: wiki     ,owner: dbuser_wiki     ,revokeconn: true ,comment: wiki meta database }
    pg_users:                           # define business users/roles on this cluster, array of user definition
      - name: dbuser_meta               # REQUIRED, `name` is the only mandatory field of a user definition
        password: DBUser.Meta           # optional, password, can be a scram-sha-256 hash string or plain text
        login: true                     # optional, can log in, true by default  (new biz ROLE should be false)
        superuser: false                # optional, is superuser? false by default
        createdb: false                 # optional, can create database? false by default
        createrole: false               # optional, can create role? false by default
        inherit: true                   # optional, can this role use inherited privileges? true by default
        replication: false              # optional, can this role do replication? false by default
        bypassrls: false                # optional, can this role bypass row level security? false by default
        pgbouncer: true                 # optional, add this user to pgbouncer user-list? false by default (production user should be true explicitly)
        connlimit: -1                   # optional, user connection limit, default -1 disable limit
        expire_in: 3650                 # optional, now + n days when this role is expired (OVERWRITE expire_at)
        expire_at: '2030-12-31'         # optional, YYYY-MM-DD 'timestamp' when this role is expired  (OVERWRITTEN by expire_in)
        comment: pigsty admin user      # optional, comment string for this user/role
        roles: [dbrole_admin]           # optional, belonged roles. default roles are: dbrole_{admin,readonly,readwrite,offline}
        parameters: {}                  # optional, role level parameters with `ALTER ROLE SET`
        pool_mode: transaction          # optional, pgbouncer pool mode at user level, transaction by default
        pool_connlimit: -1              # optional, max database connections at user level, default -1 disable limit
      - {name: dbuser_view     ,password: DBUser.Viewer   ,pgbouncer: true ,roles: [dbrole_readonly], comment: read-only viewer for meta database}
      - {name: dbuser_grafana  ,password: DBUser.Grafana  ,pgbouncer: true ,roles: [dbrole_admin]    ,comment: admin user for grafana database   }
      - {name: dbuser_bytebase ,password: DBUser.Bytebase ,pgbouncer: true ,roles: [dbrole_admin]    ,comment: admin user for bytebase database  }
      - {name: dbuser_kong     ,password: DBUser.Kong     ,pgbouncer: true ,roles: [dbrole_admin]    ,comment: admin user for kong api gateway   }
      - {name: dbuser_gitea    ,password: DBUser.Gitea    ,pgbouncer: true ,roles: [dbrole_admin]    ,comment: admin user for gitea service      }
      - {name: dbuser_wiki     ,password: DBUser.Wiki     ,pgbouncer: true ,roles: [dbrole_admin]    ,comment: admin user for wiki.js service    }
    pg_services:                        # extra services in addition to pg_default_services, array of service definition
      # standby service will route {ip|name}:5435 to sync replica's pgbouncer (5435->6432 standby)
      - name: standby                   # required, service name, the actual svc name will be prefixed with `pg_cluster`, e.g: pg-meta-standby
        port: 5435                      # required, service exposed port (work as kubernetes service node port mode)
        ip: "*"                         # optional, service bind ip address, `*` for all ip by default
        selector: "[]"                  # required, service member selector, use JMESPath to filter inventory
        dest: default                   # optional, destination port, default|postgres|pgbouncer|<port_number>, 'default' by default
        check: /sync                    # optional, health check url path, / by default
        backup: "[? pg_role == `primary`]"  # backup server selector
        maxconn: 3000                   # optional, max allowed front-end connection
        balance: roundrobin             # optional, haproxy load balance algorithm (roundrobin by default, other: leastconn)
        options: 'inter 3s fastinter 1s downinter 5s rise 3 fall 3 on-marked-down shutdown-sessions slowstart 30s maxconn 3000 maxqueue 128 weight 100'
    pg_hba_rules:
      - {user: dbuser_view , db: all ,addr: infra ,auth: pwd ,title: 'allow grafana dashboard access cmdb from infra nodes'}
    pg_vip_enabled: true
    pg_vip_address: 10.10.10.2/24
    pg_vip_interface: eth1
    node_crontab:  # make a full backup 1 am everyday
      - '00 01 * * * postgres /pg/bin/pg-backup full'
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:
      - { name: dbuser_meta , password: DBUser.Meta   , pgbouncer: true , roles: [ dbrole_admin ] , comment: pigsty admin user }
      - { name: dbuser_view , password: DBUser.Viewer , pgbouncer: true , roles: [ dbrole_readonly ] , comment: read-only viewer for meta database }
    pg_databases:
      - {name: meta ,baseline: cmdb.sql ,comment: pigsty meta database ,schemas: [pigsty] ,extensions: [{name: postgis, schema: public}, {name: timescaledb}]}
    pg_default_service_dest: postgres
    pg_services:
      - { name: standby ,src_ip: "*" ,port: 5435 , dest: default ,selector: "[]" , backup: "[? pg_role == `primary`]" }
    pg_vip_enabled: true
    pg_vip_address: 10.10.10.2/24
    pg_vip_interface: eth1
    pg_listen: '${ip},${vip},${lo}'
    patroni_ssl_enabled: true
    pgbouncer_sslmode: require
    pgbackrest_method: minio
    pg_libs: 'timescaledb, $libdir/passwordcheck, pg_stat_statements, auto_explain' # add passwordcheck extension to enforce strong password
    pg_default_roles:                 # default roles and users in postgres cluster
      - { name: dbrole_readonly  ,login: false ,comment: role for global read-only access     }
      - { name: dbrole_offline   ,login: false ,comment: role for restricted read-only access }
      - { name: dbrole_readwrite ,login: false ,roles: [dbrole_readonly]               ,comment: role for global read-write access }
      - { name: dbrole_admin     ,login: false ,roles: [pg_monitor, dbrole_readwrite]  ,comment: role for object creation }
      - { name: postgres     ,superuser: true  ,expire_in: 7300                        ,comment: system superuser }
      - { name: replicator ,replication: true  ,expire_in: 7300 ,roles: [pg_monitor, dbrole_readonly]   ,comment: system replicator }
      - { name: dbuser_dba   ,superuser: true  ,expire_in: 7300 ,roles: [dbrole_admin]  ,pgbouncer: true ,pool_mode: session, pool_connlimit: 16 , comment: pgsql admin user }
      - { name: dbuser_monitor ,roles: [pg_monitor] ,expire_in: 7300 ,pgbouncer: true ,parameters: {log_min_duration_statement: 1000 } ,pool_mode: session ,pool_connlimit: 8 ,comment: pgsql monitor user }
    pg_default_hba_rules:             # postgres host-based auth rules by default
      - {user: '${dbsu}'    ,db: all         ,addr: local     ,auth: ident ,title: 'dbsu access via local os user ident'  }
      - {user: '${dbsu}'    ,db: replication ,addr: local     ,auth: ident ,title: 'dbsu replication from local os ident' }
      - {user: '${repl}'    ,db: replication ,addr: localhost ,auth: ssl   ,title: 'replicator replication from localhost'}
      - {user: '${repl}'    ,db: replication ,addr: intra     ,auth: ssl   ,title: 'replicator replication from intranet' }
      - {user: '${repl}'    ,db: postgres    ,addr: intra     ,auth: ssl   ,title: 'replicator postgres db from intranet' }
      - {user: '${monitor}' ,db: all         ,addr: localhost ,auth: pwd   ,title: 'monitor from localhost with password' }
      - {user: '${monitor}' ,db: all         ,addr: infra     ,auth: ssl   ,title: 'monitor from infra host with password'}
      - {user: '${admin}'   ,db: all         ,addr: infra     ,auth: ssl   ,title: 'admin @ infra nodes with pwd & ssl'   }
      - {user: '${admin}'   ,db: all         ,addr: world     ,auth: cert  ,title: 'admin @ everywhere with ssl & cert'   }
      - {user: '+dbrole_readonly',db: all    ,addr: localhost ,auth: ssl   ,title: 'pgbouncer read/write via local socket'}
      - {user: '+dbrole_readonly',db: all    ,addr: intra     ,auth: ssl   ,title: 'read/write biz user via password'     }
      - {user: '+dbrole_offline' ,db: all    ,addr: intra     ,auth: ssl   ,title: 'allow etl offline tasks from intranet'}
    pgb_default_hba_rules:            # pgbouncer host-based authentication rules
      - {user: '${dbsu}'    ,db: pgbouncer   ,addr: local     ,auth: peer  ,title: 'dbsu local admin access with os ident'}
      - {user: 'all'        ,db: all         ,addr: localhost ,auth: pwd   ,title: 'allow all user local access with pwd' }
      - {user: '${monitor}' ,db: pgbouncer   ,addr: intra     ,auth: ssl   ,title: 'monitor access via intranet with pwd' }
      - {user: '${monitor}' ,db: all         ,addr: world     ,auth: deny  ,title: 'reject all other monitor access addr' }
      - {user: '${admin}'   ,db: all         ,addr: intra     ,auth: ssl   ,title: 'admin access via intranet with pwd'   }
      - {user: '${admin}'   ,db: all         ,addr: world     ,auth: deny  ,title: 'reject all other admin access addr'   }
      - {user: 'all'        ,db: all         ,addr: intra     ,auth: ssl   ,title: 'allow all user intra access with pwd' }

# 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
all:
  children:
    pg-citus0: # citus coordinator, pg_group = 0
      hosts: { 10.10.10.10: { pg_seq: 1, pg_role: primary } }
      vars: { pg_cluster: pg-citus0 , pg_group: 0 }
    pg-citus1: # citus data node 1
      hosts: { 10.10.10.11: { pg_seq: 1, pg_role: primary } }
      vars: { pg_cluster: pg-citus1 , pg_group: 1 }
    pg-citus2: # citus data node 2
      hosts: { 10.10.10.12: { pg_seq: 1, pg_role: primary } }
      vars: { pg_cluster: pg-citus2 , pg_group: 2 }
    pg-citus3: # citus data node 3, with an extra replica
      hosts:
        10.10.10.13: { pg_seq: 1, pg_role: primary }
        10.10.10.14: { pg_seq: 2, pg_role: replica }
      vars: { pg_cluster: pg-citus3 , pg_group: 3 }
  vars:                               # global parameters for all citus clusters
    pg_mode: citus                    # pgsql cluster mode: citus
    pg_shard: pg-citus                # citus shard name: pg-citus
    patroni_citus_db: meta            # citus distributed database name
    pg_dbsu_password: DBUser.Postgres # all dbsu password access for citus cluster
    pg_libs: 'citus, timescaledb, pg_stat_statements, auto_explain' # citus will be added by patroni automatically
    pg_extensions:
      - postgis34_${ pg_version }* timescaledb-2-postgresql-${ pg_version }* pgvector_${ pg_version }* citus_${ pg_version }*
    pg_users: [ { name: dbuser_meta ,password: DBUser.Meta ,pgbouncer: true ,roles: [ dbrole_admin ] } ]
    pg_databases: [ { name: meta ,extensions: [ { name: citus }, { name: postgis }, { name: timescaledb } ] } ]
    pg_hba_rules:
      - { user: 'all' ,db: all  ,addr: 127.0.0.1/32 ,auth: ssl ,title: 'all user ssl access from localhost' }
      - { user: 'all' ,db: all  ,addr: intra        ,auth: ssl ,title: 'all user ssl access from intranet'  }
Example: Redis Cluster/Sentinel/Standalone
redis-ms: # redis classic primary & replica
  hosts: { 10.10.10.10: { redis_node: 1 , redis_instances: { 6379: { }, 6380: { replica_of: '10.10.10.10 6379' } } } }
  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: { 26379: { } ,26380: { } ,26381: { } } } }
  vars:
    redis_cluster: redis-meta
    redis_password: 'redis.meta'
    redis_mode: sentinel
    redis_max_memory: 16MB
    redis_sentinel_monitor: # primary list for redis sentinel, use cls as name, primary ip:port
      - { name: redis-ms, host: 10.10.10.10, port: 6379 ,password: redis.ms, quorum: 2 }

redis-test: # redis native cluster: 3m x 3s
  hosts:
    10.10.10.12: { redis_node: 1 ,redis_instances: { 6379: { } ,6380: { } ,6381: { } } }
    10.10.10.13: { redis_node: 2 ,redis_instances: { 6379: { } ,6380: { } ,6381: { } } }
  vars: { redis_cluster: redis-test ,redis_password: 'redis.test' ,redis_mode: cluster, redis_max_memory: 32MB }
Example: ETCD 3 Node Cluster
etcd: # dcs service for postgres/patroni ha consensus
  hosts:  # 1 node for testing, 3 or 5 for production
    10.10.10.10: { etcd_seq: 1 }  # etcd_seq required
    10.10.10.11: { etcd_seq: 2 }  # assign from 1 ~ n
    10.10.10.12: { etcd_seq: 3 }  # odd number please
  vars: # cluster level parameter override roles/etcd
    etcd_cluster: etcd  # mark etcd cluster name etcd
    etcd_safeguard: false # safeguard against purging
    etcd_clean: true # purge etcd during init process
Example: Minio 3 Node Deployment
minio:
  hosts:
    10.10.10.10: { minio_seq: 1 }
    10.10.10.11: { minio_seq: 2 }
    10.10.10.12: { minio_seq: 3 }
  vars:
    minio_cluster: minio
    minio_data: '/data{1...2}'        # use two disk per node
    minio_node: '${minio_cluster}-${minio_seq}.pigsty' # minio node name pattern
    haproxy_services:
      - name: minio                     # [REQUIRED] service name, unique
        port: 9002                      # [REQUIRED] service port, unique
        options:
          - option httpchk
          - option http-keep-alive
          - http-check send meth OPTIONS uri /minio/health/live
          - http-check expect status 200
        servers:
          - { name: minio-1 ,ip: 10.10.10.10 , port: 9000 , options: 'check-ssl ca-file /etc/pki/ca.crt check port 9000' }
          - { name: minio-2 ,ip: 10.10.10.11 , port: 9000 , options: 'check-ssl ca-file /etc/pki/ca.crt check port 9000' }
          - { name: minio-3 ,ip: 10.10.10.12 , port: 9000 , options: 'check-ssl ca-file /etc/pki/ca.crt check port 9000' }
Example: Install Pigsty 4-Node Sandbox

asciicast

Check Configuration & PGSQL Conf for details.


About

Docs: https://pigsty.io/

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

WeChat: Search pigsty-cc to join the WeChat group.

Telegram: https://t.me/joinchat/gV9zfZraNPM3YjFh

Discord: https://discord.gg/D92HzV2s

Author: Vonng ([email protected])

License: AGPL-3.0

Copyright: 2018-2024 [email protected]

pigsty's People

Contributors

alemacci avatar mgramin avatar moond4rk avatar nerosong avatar pmextra avatar superzhu0818 avatar takakawa avatar vonng avatar woblidog avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

pigsty's Issues

Create extension with schema typo

A missing space in pg-init-business.sql.j2 prevent extension being created in correct schema.

{% if 'extensions' in database %}{% for extension in database.extensions %}
CREATE EXTENSION IF NOT EXISTS "{{ extension.name }}"{% if 'schema' in extension %}WITH SCHEMA "{{ extension.schema }}"{% endif %};
{% endfor %}{% endif %}

Pgbadger Intergration

pgbadger is an useful tools for log analyzing.
We can introduce semi-realtime log summary with pgbadger.

Can not connect to some nodes from meta node

172.16.121.232 元节点
172.16.121.233 pg节点1 primary
172.16.121.234 pg节点2 从
172.16.121.235 pg节点3 从
172.16.121.236 源节点vip
172.16.121.237 pg cluster vip
集群初始化完成后(all), 发现 元节点 无法ping通 primary pg节点3
image
image

Pigsty CMDB and dynamic inventory

Make default pgsql database on meta as part of the infrastructure.

Use it as dynamic inventory for cluster management.

for example, ansible could retrieve inventory information from cmdb via

#!/bin/bash
psql service=meta -AXtwc 'SELECT text FROM pigsty.inventory;'

PostgreSQL 14 metrics support for pg_exporter

PostgreSQL 14 alpha is released. and first beta will be released on 5/20.
Add support for new metrics of PostgreSQL 14

pg_stat_wal

pg_stat_activity.command

pg_stat_replication_slots

pg_stat_statements

pg_stat_database

Integration with Aliyun MyBase for PostgreSQL

Pigsty could be use as pure monitoring system without provisioning part.
So it could monitoring Postgres that are created by other provisioning solutions, such as Aliyun MyBase.

I've received request for supporting MyBase PostgreSQL
It will be tested and added in next release.

Add create database playbook

Scenario

Database creation after cluster bootstrap is tricky.
It is not a good practice to use init playbook pgsql.yml for that purpose.

Proposal

add a pgsql-createdb.yml playbook for that purpose

It may requires a cli arg -e pg_database = <your new database in inventory> to work

Add create user playbook

Scenario

User creation after cluster bootstrap is tricky.
It is not a good practice to use init playbook pgsql.yml for that purpose.

Proposal

add a pgsql-createuser.yml playbook for that purpose

It may requires a cli arg -e pg_user = <your new user in inventory> to work.

pg_hba reset on patroni restart (patroni 2.0)

After patroni restart, pg_hba rules will be overwrite by patroni.

Which means any modification to hba related variables should be applied to patroni.yml to take permanent effect.

This issue could be solved by templating patroni.yml hba section (working on it)

HAProxy admin page access via nginx

Scenario

HAProxy provides a handy admin web UI. And we already have a nginx server on meta node.
So why don't we build an index page for all haproxy instance and make nginx proxy for them?

Proposal

  • Add a new domain name h.pigsty for haproxy index pages
  • Add new default entry in nginx_upstream
    - { name: haproxy,       host: h.pigsty, url: "127.0.0.1:9091" }
  • Setup upstream and proxy in /etc/nginx/conf.d/haproxy.conf
# haproxy instance definition
upstream pg-meta-1 {
    server 10.10.10.10:9101 max_fails=0;
}
upstream pg-test-1 {
    server 10.10.10.11:9101 max_fails=0;
}
upstream pg-test-2 {
    server 10.10.10.12:9101 max_fails=0;
}
upstream pg-test-3 {
    server 10.10.10.13:9101 max_fails=0;
}


# nginx proxy for haproxy admin
server {
    listen       80;
    server_name  h.pigsty;

    location ^~/pg-meta-1/ {
        proxy_pass http://pg-meta-1;
        proxy_connect_timeout 2;
    }
    location ^~/pg-test-1/ {
        proxy_pass http://pg-test-1;
        proxy_connect_timeout 2;
    }
    location ^~/pg-test-2/ {
        proxy_pass http://pg-test-2;
        proxy_connect_timeout 2;
    }
    location ^~/pg-test-3/ {
        proxy_pass http://pg-test-3;
        proxy_connect_timeout 2;
    }

    location / {
        root        //www/;
        index       haproxy.html;
    }
}
  • Add index page for all haproxy pages: haproxy.html
  • Add auth for haproxy admin web UI: haproxy_admin_auth_enabled

Binary install mode for node_exporter and pg_exporter

Scenario

Sometimes you may want ADD pigsty monitoring system to existing database cluster instead of provisioning a new one.
In that case. It is much convenient to install node_exporter & pg_exporter via copy binaries. (Directly from meta node instead of setup infra, download and install rpm, blahblah)

Proposal

Add a exporter_binary_install option. If set, node_exporter and pg_exporter are copied to /usr/bin/ directly.
But you'll have to put those two binary files in files directory.

Upgrade to PG 13.2

Update default software packages to PG 13.2

PG 13.2 will be added in next minor release (v0.6)

working on it

Service provision

Currently service is achieved by haproxy node port.
In case of integration with other LoadB lancer provider. We need extract the service abstraction from it.

for example:

pg_services:
  # default service will route {ip|name}:5436 to primary postgres (5436->5432) (example service)
  - name: default           # service's actual name is {{ pg_cluster }}-{{ service.name }}
    src_ip: "*"             # service bind ip address, * for all, vip for cluster virtual ip address
    src_port: 5436          # bind port, mandatory
    dst_port: postgres      # target port: postgres|pgbouncer|port_number , pgbouncer(6432) by default
    check_method: http      # health check method: only http is available for now
    check_port: patroni     # health check port:  patroni|pg_exporter|port_number , patroni by default
    check_url: /primary     # health check url path, / as default
    check_code: 200         # health check http code, 200 as default
    selector: "[]"          # instance selector
    haproxy:                # haproxy specific fields
      maxconn: 3000         # default front-end connection
      balance: roundrobin   # load balance algorithm (roundrobin by default)
      default_server_options: 'inter 3s fastinter 1s downinter 5s rise 3 fall 3 on-marked-down shutdown-sessions slowstart 30s maxconn 3000 maxqueue 128 weight 100'

Add QPS panels for tables and indexes

Add Table/Index QPS panel

Table QPS can be roughly calculated from pg_table_idx_scan and pg_table_seq_scan. (Which is actually Scan per Seconds)
It's very useful to have a QPS metrics for tables and indexes.

有些指标数据没有收集

QPS,TPS并没有数据,检查了一下发现并没有收集pg:ins:qps和pg:ins:tps指标。是开源版不开放这个功能吗?

RPM Installation

RPM packages has 3 major advantage.

  • Installation & Uninstall made easy
  • Explicitly limit the execution environment to CentOS 7 x86_64
  • Better version control mechanism

Decouple consul

Scenario

Currently pigsty rely on consul for three purpose

  • DCS for HA Agent
  • Monitoring target discovery
  • Cluster status admin and report

While consul is really good. I'd like to provide more options and possibility.
For example, user who are familiar with etcd would not like the idea of learning a new kind of database.

Proposal

  • Refactor Patroni template to enabling etcd support
  • Add configuration entry to designate where to register services
  • Add configuration entry to designate where to discover services

Delayed Role Implementation

Delayed instance is a special kind of offline instance which

  • restore from archived WAL
  • have a recovery_min_apply_delay

Refactor monitor roles with monitor only mode

Scenario

Add monitor-only mode support for role monitor

Proposal

  • Add export_repo_url (http address) in case of skipping node_repo_urls setup.
  • Add exporter_create_user (boolean) to trying create monitor user in target database.

Pigsty CLI Tools

Provide yet another cli wrapper to seal ansible primitives. for example:

NAME
    pigsty -- Pigsty Command-Line Interface v0.8

SYNOPSIS

    meta               setup meta nodes            init|fetch|repo|cache|ansible
    node               setup database nodes        init|tune|dcs|remove|ping|bash|ssh|admin
    pgsql              setup postgres clusters     init|node|dcs|postgres|template|business|monitor|service|monly|remove
    infra              setup infrastructure        init|ca|dns|prometheus|grafana|loki|haproxy|target
    clean              clean pgsql clusters        all|service|monitor|postgres|dcs
    config             mange pigsty config file    init|edit|info|dump|path
    serve              run pigsty API server       init|start|stop|restart|reload|status
    demo               setup local demo            init|up|new|clean|start|dns
    log                watch system log            query|postgres|patroni|pgbouncer|message
    pg                 pg operational tasks        user|db|svc|hba|log|psql|deploy|backup|restore|vacuum|repack


EXAMPLES

    1. infra summary
        pigsty infra

    2. pgsql clusters summary
        pigsty pgsql

    3. pigsty nodes summary
        pigsty node

    4. create pgsql cluster 'pg-test'
        pigsty pgsql init -l pg-test

    5. add new instance 10.10.10.13 of cluster 'pg-test'
        pigsty pgsql init -l 10.10.10.13

    6. remove cluster 'pg-test'
        pigsty clean -l pg-test

    7. create user dbuser_vonng on cluster 'pg-test'
        pigsty pg user dbuser_vonng -l pg-test

    8. create database test2 on cluster 'pg-test'
        pigsty pg db test -l pg-test

Usage:
  pigsty [command]

Available Commands:
  clean       remove pgsql cluster/instance
  help        Help about any command
  infra       setup infrastructure
  meta        setup meta node
  node        setup database node
  pgsql       setup pgsql clusters
  serve       Launch pigsty API server

Flags:
  -h, --help               help for pigsty
  -i, --inventory string   inventory file (default "./pigsty.yml")
  -l, --limit string       limit execution hosts
  -t, --tags strings       limit execution tasks

grafana首页 HAproxy连接问题

小白刚刚初始化完成pigsty集群 在首页
image 这个lian'jie链接不应该是 h.pigsty 么, 目前的超链接好像是 pigsty:9101
image

其他几个链接都是正常的, 还请指教

Offline access control

Scenario

In real world production environment, It is common requirements that running some ETL process / Interactive Queries / SAGA on OLTP databases.

It is highly recommended to run that shit on dedicate instance (which may named offline) to avoid undesired side-effect on entire cluster.

Thus, we need a mechanism to MARK a specific instance for that purpose. and a new default role to MARK users with that sort of needs.

Proposal

We may introduce a new default role dbrole_offline which have same privilege as dbrole_readonly but is not a member of dbrole_readonly. It will be granted to ETL/SAGA/Interactive users.

And members of dbrole_offline will only be allowed by hba on instances with pg_role = offline or variable pg_offline_query = true.

Database provisioning interface enhancement

Upgrade database creation interface to support complete features.

Current interface:

pg_databases:                       # create a business database 'meta'
  - name: meta
    schemas: [meta]                 # create extra schema named 'meta'
    extensions: [{name: postgis}]   # create extra extension postgis
    parameters:                     # overwrite database meta's default search_path
      search_path: public, monitor

Proposed interface

Which include complete customizable options for postgres database.

pg_databases:
  - name: meta                      # name is the only required field for a database
    owner: postgres                 # optional, database owner
    template: template1             # optional, template1 by default
    encoding: UTF8                  # optional, UTF8 by default
    locale: C                       # optional, C by default
    allowconn: true                 # optional, true by default, false disable connect at all
    revokeconn: false               # optional, false by default, true revoke connect from public # (only default user and owner have connect privilege on database)
    tablespace: pg_default          # optional, 'pg_default' is the default tablespace
    connlimit: -1                   # optional, connection limit, -1 or none disable limit (default)
    extensions:                     # optional, extension name and where to create
      - {name: postgis, schema: public}
    parameters:                     # optional, extra parameters with ALTER DATABASE
      enable_partitionwise_join: true
    pgbouncer: true                 # optional, add this database to pgbouncer list? true by default
    comment: pigsty meta database   # optional, comment string for database

Remove svc and role label in monitoring system

svc and role are tagged to all metrics in pigsty.

Usually it works well. role of instance will be auto-adjusted by patroni callback and routine tasks.

While it do have two down-sides:

  • When failover occurs. It create NEW time series. which my disturb monitoring display
  • It cost more space and attention. Which may affect how analysis goes.

To avoid it. Here I propose to eliminate svc and role label from pigsty. (Along with any old service level metrics implementation)

Split monolith static monitor target file into per-cluster conf

Currently. If you are using static prometheus target discovery.

The target file is a monolith lies in /etc/prometheus/targets/all.yml.

It's good to split that monolith file into small files, for example, one yml file per cluster.

Besides, for people who are using per-cluster style inventory, this could work, too.

The targets files would be:

/etc/prometheus/targets/pg-test.yml
/etc/prometheus/targets/pg-meta.yml
/etc/prometheus/targets/pg-other-cluster.yml

Safeguard for purge functionality

Scenario

It is very dangerous to set dcs_exists_action = clean and pg_exists_action = clean, Which are safeguard variables to avoid accidentally removing any running databases or dcs instances.

It is always better to achieve that by an explicit playbook execution pgsql-rm.yml rather than change a variable.
In some case you just want to erase that possibility.

Proposal

Add two safeguard variables pg_disable_purge and dcs_disable_purge. If set to true, corresponding variable pg_exists_action and dcs_exists_action will be forced to abort to avoid purge.

Readonly traffic fallback on primary if all replicas down

Scenario

If all replica instances are down. Current setup will NOT route those traffic to the only primary. which means readonly service are not available.

It nice to have an additional option to configure that in case of all replicas failure:

  • Leave primary be, so at least readwrite service will survival the avalanche case
  • Route readonly traffic to primary so the service still intact.

Proposal

Add an option haproxy_weight_fallback which controls this behaviro

  • When set to 0, it is same as before, primary will not take any read-only traffic
  • When set to a value larger than 0, It will be used as relative weight for primary instance in replica services group.

In normal situation, the primary will take a very little portion of read-only traffic. In case of all replica down. It will become the only available backend in replica service. And takeover all read-only traffics.

Prometheus static targets mode support

Scenario

Currently, postgres instance identity is managed by Consul Service Registration.
Which is implemented as local consul service configuration file in /etc/consul.d/svc-***.json
It is a distributed approach that allows instances themselves to 'report' their identity.
It do have some potential security issues such as wrong identity because of malicious or accidentally configured.

Some may prefer a centralized approach. E.g manage all identity in the meta-node.
Since we already have those information in inventory

Proposal

Take prometheus for example.
We can provide an alternative option to use static target identity file rather than service discovery.
Which may reduce the hazard of operating and reloading consul.

We can generate prometheus configuration with inventory and label all instance properly.
It also makes it much easier to integrate with other provisioning systems.

when i make upload,always error.then vm enter aborted status

# make upload
ssh -t meta "sudo rm -rf /tmp/pkg.tgz"
Connection to 127.0.0.1 closed.
scp -r files/pkg.tgz meta:/tmp/pkg.tgz
pkg.tgz                                                                                                                 100% 1029MB  10.9MB/s   01:34    
ssh -t meta "sudo mkdir -p /www/pigsty/; sudo rm -rf /www/pigsty/*; sudo tar -xf /tmp/pkg.tgz --strip-component=1 -C /www/pigsty/"
Connection to 127.0.0.1 closed by remote host.
Connection to 127.0.0.1 closed.
make: *** [upload] 错误 255

# make status
cd vagrant && vagrant status
Current machine states:

meta                      aborted (virtualbox)
node-1                    running (virtualbox)
node-2                    running (virtualbox)
node-3                    running (virtualbox)

This environment represents multiple VMs. The VMs are all listed
above with their current state. For more information about a specific
VM, run `vagrant status NAME`.

# make resume
cd vagrant && vagrant resume
==> meta: Waiting for machine to boot. This may take a few minutes...
The guest machine entered an invalid state while waiting for it
to boot. Valid states are 'restoring, running'. The machine is in the
'aborted' state. Please verify everything is configured
properly and try again.

If the provider you're using has a GUI that comes with it,
it is often helpful to open that and watch the machine, since the
GUI often has more helpful error messages than Vagrant can retrieve.
For example, if you're using VirtualBox, run `vagrant up` while the
VirtualBox GUI is open.

The primary issue for this error is that the provider you're using
is not properly configured. This is very rarely a Vagrant issue.
make: *** [resume] 错误 1

Default pigsty config does not have exec func priv for dbrole_offline

Case

Default configuration entry pg_default_privileges for pigsty has a mis-config

    pg_default_privilegs:                         # object created by dbsu and admin will have their privileges properly set
      - GRANT USAGE                         ON SCHEMAS   TO dbrole_readonly
      - GRANT SELECT                        ON TABLES    TO dbrole_readonly
      - GRANT SELECT                        ON SEQUENCES TO dbrole_readonly
      - GRANT EXECUTE                       ON FUNCTIONS TO dbrole_readonly
      - GRANT USAGE                         ON SCHEMAS   TO dbrole_offline
      - GRANT SELECT                        ON TABLES    TO dbrole_offline
      - GRANT SELECT                        ON SEQUENCES TO dbrole_offline
      - GRANT EXECUTE                       ON FUNCTIONS TO dbrole_readonly
      - GRANT INSERT, UPDATE, DELETE        ON TABLES    TO dbrole_readwrite
      - GRANT USAGE,  UPDATE                ON SEQUENCES TO dbrole_readwrite
      - GRANT TRUNCATE, REFERENCES, TRIGGER ON TABLES    TO dbrole_admin
      - GRANT CREATE                        ON SCHEMAS   TO dbrole_admin
      - GRANT USAGE                         ON TYPES     TO dbrole_admin

The line:

- GRANT EXECUTE                       ON FUNCTIONS TO dbrole_readonly

should be

- GRANT EXECUTE                       ON FUNCTIONS TO dbrole_offline

Solution

Update pigsty.yml configuration file.

ClientIP Issue when using Haproxy

When using haproxy, ClientIP will be shadowed. So it will be always 127.0.0.1 in PostgreSQL logs. which could be annoying.

Candidate Solutions

  • Use smart clients and connect to pgbouncer directly (e.g via consul DNS, services discovery, blahblah)
  • Change pgbouncer source code to extract clientIP from haproxy and use set application to pass it to postgres.
  • Use L4 VIP instead of haproxy with toa module which could solve this issue.
  • I don't care about client IP, just go with it.

User provisioning interface enhancement

Upgrade user creation interface to support complete features.

Current interface:

pg_users:
  - username: test                  # example production user have read-write access
    password: test                  # example user's password
    options: LOGIN                  # extra options
    groups: [ dbrole_readwrite ]    # dborole_admin|dbrole_readwrite|dbrole_readonly
    comment: default test user for production usage
    pgbouncer: true                 # add to pgbouncer

Proposed interface

Which include complete customizable options for postgres user/role.

pg_users:
  # complete example of user/role definition for production user
  - name: dbuser_meta               # example production user have read-write access
    password: DBUser.Meta           # example user's password, can be encrypted
    login: true                     # can login, true by default (should be false for role)
    superuser: false                # is superuser? false by default
    createdb: false                 # can create database? false by default
    createrole: false               # can create role? false by default
    inherit: true                   # can this role use inherited privileges?
    replication: false              # can this role do replication? false by default
    bypassrls: false                # can this role bypass row level security? false by default
    connlimit: -1                   # connection limit, -1 disable limit
    expire_at: '2030-12-31'         # 'timestamp' when this role is expired
    expire_in: 365                  # now + n days when this role is expired (OVERWRITE expire_at)
    roles: [dbrole_readwrite]       # dborole_admin|dbrole_readwrite|dbrole_readonly
    pgbouncer: true                 # add this user to pgbouncer? false by default (true for production user)
    parameters:                     # user's default search path
      search_path: public
    comment: test user

Use single node as default deployment

The standard deployment use to have 4 node.
Which may be a threshold for use.

Switch to single node deployment by default will simplify installation procedure. and enabling other possibilities such as take pigsty as data-analysis environment.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.