-{ pkgs, config, hostName, ... }:
+{ pkgs, config, hostName, host, ... }:
let
inherit (config.networking) domain;
inherit (config.services) postgresql;
package = pkgs.postgresql_12;
#enableTCPIP = true;
settings = {
- # ZFS is Copy on Write (CoW). As a result, it’s not possible
- # to have a torn page because a page can’t be partially written
- # without reverting to the previous copy.
- full_page_writes = false;
log_connections = true;
log_disconnections = true;
log_hostname = false;
- max_connections = 25;
max_locks_per_transaction = 1024;
password_encryption = "scram-sha-256"; # requires postfix >= 11
ssl = false;
ssl_cert_file = "/var/lib/acme/${domain}/fullchain.pem";
ssl_key_file = "/var/lib/acme/${domain}/key.pem";
unix_socket_permissions = "0770";
+
+ # ZFS is Copy on Write (CoW). As a result, it’s not possible
+ # to have a torn page because a page can’t be partially written
+ # without reverting to the previous copy.
+ full_page_writes = false;
+ # Avoid zero-filling of new files used for Postgres’s Write Ahead Log.
+ # The reasoning here is that since ZFS overwrites these anyway,
+ # you might as well get yourself a new inode.
+ wal_init_zero = false;
+ wal_recycle = false;
+
+ max_connections = 50;
+ # The proper size for the POSTGRESQL shared buffer cache is the largest
+ # useful size that does not adversely affect other activity.
+ # Ideally we should limit ZFS's ARC's max size
+ # to a percentage of physical memory
+ # minus the shared_buffer cache for PostgreSQL
+ # minus the kernel's memory overhead.
+ shared_buffers = "1GB";
+ # Used by the optimizer to estimate the size of the kernel's disk buffer cache.
+ effective_cache_size = "3GB";
+ # Setting a large value helps in tasks like
+ # VACUUM, RESTORE, CREATE INDEX, ADD FOREIGN KEY and ALTER TABLE.
+ maintenance_work_mem = "256MB";
+ # Bigger value for wal_buffers in case of lot of concurrent connection gives better performance.
+ wal_buffers = "16MB";
+ min_wal_size = "1GB";
+ max_wal_size = "4GB";
+ default_statistics_target = 100;
+ random_page_cost = "1.1";
+ effective_io_concurrency = 200;
+ work_mem = "20971kB";
+ huge_pages = false;
+ max_worker_processes = host.CPUs;
+ max_parallel_workers_per_gather = host.CPUs / 2;
+ max_parallel_workers = host.CPUs;
+ max_parallel_maintenance_workers = host.CPUs / 2;
};
# If one record is chosen and the auth fails,
# subsequent records are not considered.
#user /^(.*)$ \1
'';
};
- fileSystems."/var/lib/postgresql" = {
- device = "${hostName}/var/postgresql";
- fsType = "zfs"; # with sync=always,
- # though loading OpenConcerto's initial SQL
- # takes 1m40s instead of 40s :\
- };
/*
services.syncoid.commands = {
"${hostName}/var/postgresql" = {
};
*/
services.sanoid.datasets = {
- "${hostName}/var/postgresql" = {
+ "${hostName}/var/lib/postgresql" = {
use_template = [ "snap" ];
daily = 31;
+ hourly = 0;
+ recursive = true;
};
};
systemd.services.postgresql = {
local template=''${template:-template1}
$PSQL -tAc "SELECT 1 FROM pg_catalog.pg_database WHERE datname = '$db'" | grep -q 1 || {
$PSQL -d "$template" -AqtX --set ON_ERROR_STOP=1 -f - <<EOF
- CREATE ROLE "$owner" NOSUPERUSER NOCREATEDB NOCREATEROLE NOINHERIT ''${pass:+LOGIN PASSWORD '$pass'};
+ CREATE ROLE "$owner" NOSUPERUSER NOCREATEDB NOCREATEROLE NOINHERIT LOGIN ''${pass:+PASSWORD '$pass'};
CREATE DATABASE "$db" WITH OWNER="$owner"
''${encoding:+ENCODING='$encoding'}
''${lc_collate:+LC_COLLATE='$lc_collate'}
local user=$2
$PSQL -tAc "SELECT 1 FROM pg_catalog.pg_roles WHERE rolname='$user'" | grep -q 1 ||
$PSQL -d "$db" -AqtX --set ON_ERROR_STOP=1 -f - <<EOF
- CREATE ROLE "$user" NOSUPERUSER NOCREATEDB NOCREATEROLE NOINHERIT ''${pass:+LOGIN ENCRYPTED PASSWORD '$pass'};
+ CREATE ROLE "$user" NOSUPERUSER NOCREATEDB NOCREATEROLE NOINHERIT LOGIN ''${pass:+ENCRYPTED PASSWORD '$pass'};
GRANT USAGE ON SCHEMA public TO "$user";
GRANT CONNECT,TEMPORARY ON DATABASE "$db" TO "$user";
EOF