This commit introduces a hugepages configuration for postgres via a rhizome lib+bin. At the moment, it uses the default huge page size (2M), and calculates the number of huge pages as 25% of the total available memory. The setup adjusts the shared_buffers accordingly to fit the shared memory within the allocated number of hugepages. The configuration happens as an `ExecStartPre` script added to the existing systemd unit managed by pg_ctlcluster. To keep the semantics of the `start` command unchanged, the hugepages script *does not* stop an existing cluster to configure hugepages, and only does it when the cluster is not running. In a subsequent change, we can consider adding the boot parameters to setup 1G hugepages for larger instances (possibly standard-30+), where they are most useful. [1]: https://www.postgresql.org/docs/current/kernel-resources.html#LINUX-HUGE-PAGES
139 lines
5.3 KiB
Ruby
Executable File
139 lines
5.3 KiB
Ruby
Executable File
#!/bin/env ruby
|
|
# frozen_string_literal: true
|
|
|
|
require "json"
|
|
require_relative "../../common/lib/util"
|
|
require_relative "../lib/pgbouncer_setup"
|
|
|
|
if ARGV.count != 1
|
|
fail "Wrong number of arguments. Expected 1, Given #{ARGV.count}"
|
|
end
|
|
|
|
v = ARGV[0]
|
|
configure_hash = JSON.parse($stdin.read)
|
|
|
|
# Update /etc/hosts
|
|
hosts = <<-HOSTS
|
|
127.0.0.1 localhost
|
|
::1 ip6-localhost ip6-loopback
|
|
fe00::0 ip6-localnet
|
|
ff00::0 ip6-mcastprefix
|
|
ff02::1 ip6-allnodes
|
|
ff02::2 ip6-allrouters
|
|
ff02::3 ip6-allhosts
|
|
#{configure_hash["hosts"]}
|
|
HOSTS
|
|
safe_write_to_file("/etc/hosts", hosts)
|
|
|
|
# Update postgresql.conf
|
|
configs = configure_hash["configs"].map { |k, v| "#{k} = #{v}" }.join("\n")
|
|
safe_write_to_file("/etc/postgresql/#{v}/main/conf.d/001-service.conf", configs)
|
|
|
|
# Update pg_hba.conf
|
|
private_subnets = configure_hash["private_subnets"].flat_map {
|
|
[
|
|
"host all all #{_1["net4"]} scram-sha-256",
|
|
"host all all #{_1["net6"]} scram-sha-256"
|
|
]
|
|
}.join("\n")
|
|
|
|
pg_hba_entries = <<-PG_HBA
|
|
# PostgreSQL Client Authentication Configuration File
|
|
# ===================================================
|
|
#
|
|
# Refer to the "Client Authentication" section in the PostgreSQL
|
|
# documentation for a complete description of this file.
|
|
|
|
# TYPE DATABASE USER ADDRESS METHOD
|
|
# Database administrative login by Unix domain socket
|
|
local all postgres peer map=system2postgres
|
|
local all pgbouncer peer map=system2pgbouncer
|
|
|
|
# Allow connections from localhost with ubi_monitoring OS user as
|
|
# ubi_monitoring database user. This will be used by postgres_exporter
|
|
# to scrape metrics and expose them to prometheus.
|
|
local all ubi_monitoring peer
|
|
|
|
# "local" is for Unix domain socket connections only
|
|
# Use SCRAM authentication for all local connections to allow pgbouncer
|
|
# passthrough to work for all non-unix users
|
|
local all all scram-sha-256
|
|
# IPv4 local connections:
|
|
host all all 127.0.0.1/32 scram-sha-256
|
|
# IPv6 local connections:
|
|
host all all ::1/128 scram-sha-256
|
|
|
|
# Allow replication connections from localhost, by a user with the
|
|
# replication privilege.
|
|
local replication all peer
|
|
host replication all 127.0.0.1/32 scram-sha-256
|
|
host replication all ::1/128 scram-sha-256
|
|
|
|
# Allow connections from private subnet with SCRAM authentication
|
|
#{private_subnets}
|
|
|
|
# Allow replication connection using special replication user for
|
|
# HA standbys
|
|
hostssl replication ubi_replication all cert map=standby2replication
|
|
|
|
# Allow connections from public internet with md5 authentication
|
|
# Note that if the password is encrypted as scram-sha-256, PostgreSQL
|
|
# still uses scram-sha-256 for authentication.
|
|
host all all all md5
|
|
PG_HBA
|
|
safe_write_to_file("/etc/postgresql/#{v}/main/pg_hba.conf", pg_hba_entries)
|
|
|
|
identity = configure_hash["identity"]
|
|
pg_ident_entries = <<-PG_IDENT
|
|
# PostgreSQL User Name Maps
|
|
# =========================
|
|
#
|
|
# Refer to the PostgreSQL documentation, chapter "Client
|
|
# Authentication" for a complete description.
|
|
# MAPNAME SYSTEM-USERNAME PG-USERNAME
|
|
system2postgres postgres postgres
|
|
system2pgbouncer postgres pgbouncer
|
|
system2postgres ubi postgres
|
|
standby2replication #{identity} ubi_replication
|
|
PG_IDENT
|
|
safe_write_to_file("/etc/postgresql/#{v}/main/pg_ident.conf", pg_ident_entries)
|
|
|
|
# Configure system hugepages
|
|
meminfo = File.read("/proc/meminfo")
|
|
hugepage_size_kib = Integer(meminfo[/^Hugepagesize:\s*(\d+)\s*kB/, 1], 10)
|
|
memory_total_kib = Integer(meminfo[/^MemTotal:\s*(\d+)\s*kB/, 1], 10)
|
|
|
|
target_hugepages_size_kib = memory_total_kib / 4
|
|
target_hugepages = target_hugepages_size_kib / hugepage_size_kib
|
|
|
|
r "echo 'vm.nr_hugepages = #{target_hugepages}' | sudo tee /etc/sysctl.d/10-hugepages.conf"
|
|
r "sync"
|
|
r "echo 3 | sudo tee /proc/sys/vm/drop_caches"
|
|
r "echo 1 | sudo tee /proc/sys/vm/compact_memory"
|
|
r "sudo sysctl --system"
|
|
|
|
meminfo = File.read("/proc/meminfo")
|
|
allocated_hugepages = Integer(meminfo[/^HugePages_Total:\s*(\d+)/, 1], 10)
|
|
|
|
if allocated_hugepages < target_hugepages
|
|
puts "Failed to allocate #{target_hugepages} hugepages. Only #{allocated_hugepages} were allocated."
|
|
exit 1
|
|
else
|
|
puts "Successfully allocated #{allocated_hugepages} hugepages."
|
|
end
|
|
|
|
# Create drop-in directory for postgresql@.service to override
|
|
# the default systemd service file with a custom ExecStartPre to configure hugepages.
|
|
r "mkdir -p /etc/systemd/system/postgresql@.service.d"
|
|
execstartpre_hugepages_conf = <<-HUGEPAGES_CONF
|
|
[Service]
|
|
ExecStartPre=/home/ubi/postgres/bin/configure-hugepages %i
|
|
HUGEPAGES_CONF
|
|
safe_write_to_file("/etc/systemd/system/postgresql@.service.d/hugepages.conf", execstartpre_hugepages_conf)
|
|
|
|
# Reload the postmaster to apply changes
|
|
r "pg_ctlcluster #{v} main reload || pg_ctlcluster #{v} main restart"
|
|
|
|
pgbouncer_setup = PgBouncerSetup.new(v, configure_hash["configs"]["max_connections"], configure_hash["pgbouncer_instances"])
|
|
pgbouncer_setup.setup
|