跳轉到

資料庫使用者

Tenax 使用一個使用者 tenax 備份每個資料庫,其密碼儲存在資料庫旁邊一個名為 tenax-* 的 Secret 中。 它從不使用管理員帳號。建立該使用者只需兩條命令;如需還原到任意一秒,再加一行伺服器設定。

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. 如需還原到任意一秒,請允許該使用者進行複製:把下面這行加到 pg_hba.conf 並重新載入設定(無需重啟)。

host  replication  tenax  all  scram-sha-256

如果 Postgres 由 Operator 或 Helm Chart 管理,請在它設定 pg_hba 的地方新增這一行(例如 CloudNativePG 中的 spec.postgresql.pg_hba,或 Chart 的 pgHbaConfiguration 值)。

同樣的 SQL,帶註解的檔案版(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. 還原到任意一秒需要開啟 binlog 並使用列格式:兩者都是 MySQL 8 的預設設定。 select @@log_bin, @@binlog_format 會顯示 1, ROW。

同樣的 SQL,帶註解的檔案版(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;

就這麼簡單。讓目標指向這個 Secret:

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

不做第 3 步

不會有任何失敗。Tenax 會嘗試用該使用者進行複製,如果資料庫拒絕:

  • 完整備份為邏輯備份,依策略的排程執行;
  • 目標的 Replication 狀態條件、控制台以及每個備份的警告都會準確說明需要新增什麼;
  • Tenax 每隔幾分鐘重新檢查一次,一旦你新增完成,就會自動開始串流傳輸。
使用者可以 你將獲得 權限
讀取全部資料 邏輯備份、清單、匯出、檢查 Postgres pg_read_all_data + pg_monitor;MySQL SELECT、SHOW VIEW、TRIGGER、EVENT、LOCK TABLES、PROCESS、RELOAD、SHOW_ROUTINE
複製 實體備份(Postgres)和變更串流:還原到任意一秒 Postgres REPLICATION 加上 pg_hba.conf 規則;MySQL REPLICATION SLAVE、REPLICATION CLIENT

複製槽

Postgres 串流會把 WAL 保留在複製槽中,直到 Tenax 將其儲存完畢。上面的 SQL 把已停止的串流傳輸程式最多能保留的量 限制為 2 GB(max_slot_wal_keep_size),Tenax 會在遠未達到該值之前就發出 TenaxSlotWALRetentionHigh 警示, 並在目標被刪除或關閉時間點還原時刪除該複製槽。

進階:自動保持使用者同步,適用於密碼會輪替、資料庫會重建的 GitOps 環境。