データベースユーザー¶
Tenax は各データベースを ひとつのユーザー tenax でバックアップします。そのパスワードは、データベースと同じ Namespace の
tenax-* という名前の Secret に保存します。管理者アカウントは決して使いません。ユーザーの作成はコマンド 2 つで済み、
任意の 1 秒への復元にはさらにサーバー設定が 1 行必要です。
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. 任意の 1 秒への復元を行うには、ユーザーにレプリケーションを許可します。pg_hba.conf に次の行を追加して
リロードします (再起動は不要です)。
Postgres をオペレーターや Helm チャートで管理している場合は、pg_hba を設定している場所にこの行を追加します
(たとえば CloudNativePG の spec.postgresql.pg_hba、またはチャートの pgHbaConfiguration 値)。
同じ 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. 任意の 1 秒への復元には、行形式の binlog が有効である必要があります。どちらも MySQL 8 のデフォルトです。
select @@log_bin, @@binlog_format で 1, ROW と表示されれば問題ありません。
同じ 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 を指定します。
手順 3 を行わない場合¶
何も失敗しません。Tenax はそのユーザーでレプリケーションを試み、データベースが拒否した場合は次のようになります。
- フルバックアップはポリシーのスケジュールに従って論理バックアップになります。
- ターゲットの
Replicationコンディション、コンソール、各バックアップの警告に、追加すべき内容が正確に表示されます。 - Tenax は数分ごとに再確認し、設定が追加されると自動でストリーミングを開始します。
| ユーザーに許可すること | 得られるもの | 権限 |
|---|---|---|
| すべてを読む | 論理バックアップ、インベントリ、エクスポート、チェック | Postgres pg_read_all_data + pg_monitor。MySQL SELECT、SHOW VIEW、TRIGGER、EVENT、LOCK TABLES、PROCESS、RELOAD、SHOW_ROUTINE |
| レプリケーション | 物理バックアップ (Postgres) と変更ストリーム: 任意の 1 秒への復元 | Postgres REPLICATION と pg_hba.conf のルール。MySQL REPLICATION SLAVE、REPLICATION CLIENT |
レプリケーションスロット
Postgres のストリームは、Tenax が保存するまで WAL をレプリケーションスロットに保持します。上記の SQL は、停止した
ストリーマーが保持できる量を 2 GB に制限し (max_slot_wal_keep_size)、Tenax はその手前で TenaxSlotWALRetentionHigh
のアラートを出します。ターゲットが削除されるか、ポイントインタイム復元が無効にされると、スロットは削除されます。
上級: パスワードがローテーションされ、データベースが再構築される GitOps 構成向けに、ユーザーを自動的に同期させる。