Zum Inhalt

Datenbankbenutzer

Tenax sichert jede Datenbank mit einem Benutzer, tenax, dessen Passwort in einem Secret namens tenax-* neben der Datenbank liegt. Ein Administratorkonto verwendet es nie. Den Benutzer anzulegen kostet zwei Befehle, plus eine Zeile Serverkonfiguration für die Wiederherstellung auf jede Sekunde.

NS=team-a                         # the database's namespace
PASSWORD=$(openssl rand -hex 24)  # hex: no quoting surprises

# 1. The Secret Tenax reads
kubectl -n $NS create secret generic tenax-postgres \
  --from-literal=username=tenax --from-file=password=<(printf %s "$PASSWORD")

# 2. The user, as a superuser, through the database's pod (deploy/…, sts/… or a pod)
kubectl -n $NS exec -i deploy/postgres -- psql -U postgres -v ON_ERROR_STOP=1 <<SQL
\set tenax_password '$PASSWORD'
SELECT 'CREATE ROLE tenax LOGIN REPLICATION' WHERE NOT EXISTS (SELECT 1 FROM pg_roles WHERE rolname = 'tenax') \gexec
ALTER ROLE tenax WITH LOGIN REPLICATION PASSWORD :'tenax_password';
GRANT pg_read_all_data, pg_monitor TO tenax;
ALTER SYSTEM SET max_slot_wal_keep_size = '2GB';
SELECT pg_reload_conf();
SQL

3. Für die Wiederherstellung auf jede Sekunde erlauben Sie dem Benutzer die Replikation: Fügen Sie diese Zeile zu pg_hba.conf hinzu und laden Sie die Konfiguration neu (kein Neustart).

host  replication  tenax  all  scram-sha-256

Wird Postgres von einem Operator oder Helm-Chart verwaltet, fügen Sie die Zeile dort hinzu, wo pg_hba konfiguriert wird (zum Beispiel spec.postgresql.pg_hba in CloudNativePG oder der Wert pgHbaConfiguration des Charts).

Dasselbe SQL als Datei, mit Kommentaren (docs/sql/postgres-users.sql)
docs/sql/postgres-users.sql
-- Tenax's database user for PostgreSQL 15/16/17 (run once as a superuser, e.g. with psql):
--
--   psql -v tenax_password="$TENAX_PASSWORD" -f postgres-users.sql
--
-- One user, `tenax`, does everything (ADR 0016): inventory queries, logical dumps (pg_dump), exports and checks
-- with pg_read_all_data + pg_monitor; physical base backups (pg_basebackup) and the WAL stream with REPLICATION.
--
-- For physical backups and point-in-time restore pg_hba.conf must also allow it to replicate, then reload:
--     host replication tenax all scram-sha-256
-- Without that rule Tenax still works: it takes logical backups and tells you the rule to add.
-- Also needed: wal_level = replica (the default) and max_wal_senders >= 2 (default 10).
\set ON_ERROR_STOP on

SELECT format('CREATE ROLE tenax LOGIN REPLICATION PASSWORD %L', :'tenax_password')
WHERE NOT EXISTS (SELECT 1 FROM pg_roles WHERE rolname = 'tenax') \gexec
ALTER ROLE tenax WITH LOGIN REPLICATION NOSUPERUSER NOCREATEDB NOCREATEROLE PASSWORD :'tenax_password';
GRANT pg_read_all_data, pg_monitor TO tenax;
-- Keep backup sessions bounded.
ALTER ROLE tenax SET idle_in_transaction_session_timeout = '10min';

-- A stopped streamer must never fill the database disk: cap WAL retained by replication slots (no restart needed).
ALTER SYSTEM SET max_slot_wal_keep_size = '2GB';
SELECT pg_reload_conf();
NS=team-a
PASSWORD=$(openssl rand -hex 24)

# 1. The Secret Tenax reads
kubectl -n $NS create secret generic tenax-mysql \
  --from-literal=username=tenax --from-file=password=<(printf %s "$PASSWORD")

# 2. The user, as root (the official image has the root password in MYSQL_ROOT_PASSWORD)
kubectl -n $NS exec -i deploy/mysql -- sh -c 'MYSQL_PWD="$MYSQL_ROOT_PASSWORD" mysql -uroot' <<SQL
CREATE USER IF NOT EXISTS 'tenax'@'%' IDENTIFIED BY '$PASSWORD';
GRANT SELECT, SHOW VIEW, TRIGGER, EVENT, LOCK TABLES, PROCESS, RELOAD, SHOW_ROUTINE,
      REPLICATION SLAVE, REPLICATION CLIENT ON *.* TO 'tenax'@'%';
SQL

3. Die Wiederherstellung auf jede Sekunde braucht ein eingeschaltetes Binlog im Row-Format: Beides ist in MySQL 8 Standard. select @@log_bin, @@binlog_format zeigt 1, ROW.

Dasselbe SQL als Datei, mit Kommentaren (docs/sql/mysql-users.sql)
docs/sql/mysql-users.sql
-- Tenax's database user for MySQL 8.4 (run once as root, replace the password):
--
--   mysql -uroot -p < mysql-users.sql
--
-- One user, `tenax`, does everything (ADR 0016): consistent logical dumps (mysqldump --single-transaction
-- --source-data=2), inventory and checks, and the binlog stream (mysqlbinlog --read-from-remote-server).
-- Without REPLICATION SLAVE / REPLICATION CLIENT Tenax still takes dumps, but without point-in-time restore.
--
-- Server settings (all MySQL 8 defaults except GTIDs): log_bin=ON, binlog_format=ROW, a unique server_id;
-- gtid_mode=ON with enforce_gtid_consistency=ON is recommended; binlog_expire_logs_seconds long enough for the
-- streamer to catch up after an outage (default 30 days).
CREATE USER IF NOT EXISTS 'tenax'@'%' IDENTIFIED BY 'CHANGE_ME_PASSWORD';
GRANT SELECT, SHOW VIEW, TRIGGER, EVENT, LOCK TABLES, PROCESS, RELOAD, SHOW_ROUTINE,
      REPLICATION SLAVE, REPLICATION CLIENT ON *.* TO 'tenax'@'%';
FLUSH PRIVILEGES;

Das war's. Verweisen Sie das Ziel auf das Secret:

spec:
  credentials:
    secretRef: { name: tenax-postgres }

Ohne Schritt 3

Nichts schlägt fehl. Tenax versucht, mit dem Benutzer zu replizieren, und wenn die Datenbank ablehnt:

  • sind Vollsicherungen logisch, nach dem Zeitplan der Policy;
  • sagen die Condition Replication des Ziels, die Konsole und die Warnungen jedes Backups genau, was hinzuzufügen ist;
  • prüft Tenax alle paar Minuten erneut und beginnt von selbst zu streamen, sobald Sie es hinzugefügt haben.
Der Benutzer darf Das bringt Ihnen Berechtigungen
Alles lesen logische Backups, Inventare, Exporte, Checks Postgres pg_read_all_data + pg_monitor; MySQL SELECT, SHOW VIEW, TRIGGER, EVENT, LOCK TABLES, PROCESS, RELOAD, SHOW_ROUTINE
Replizieren physische Backups (Postgres) und den Änderungsstrom: Wiederherstellung auf jede Sekunde Postgres REPLICATION plus die Regel in pg_hba.conf; MySQL REPLICATION SLAVE, REPLICATION CLIENT

Replikations-Slots

Der Postgres-Stream hält WAL in einem Replikations-Slot zurück, bis Tenax es gespeichert hat. Das SQL begrenzt, was ein angehaltener Streamer zurückhalten kann, auf 2 GB (max_slot_wal_keep_size), Tenax alarmiert mit TenaxSlotWALRetentionHigh lange vorher, und es entfernt den Slot, wenn das Ziel gelöscht oder die Point-in-Time-Wiederherstellung ausgeschaltet wird.

Für Fortgeschrittene: den Benutzer automatisch synchron halten, für GitOps-Setups, in denen Passwörter rotieren und Datenbanken neu aufgebaut werden.