当前位置: 首页 > news >正文

pg_hardstorage 入门

`pg_hardstorage`是一款基于 PostgreSQL **复制协议的持续 WAL 流式**传输备份工具。在生产环境中,需要并行运行两个进程:一个进程`wal stream` 持续接收来自 PostgreSQL 的 WAL 日志,并将每个已完成的 16 MiB 数据段提交到存储库;`backup`另一个进程则按计划(例如每晚)创建基础备份,后续的 WAL 流式传输会以此为基础进行滚动。每日备份 + 持续运行的 WAL 流式传输 = PITR(基于数据段的备份恢复)至任何数据段对齐点。

它通过物理复制协议备份您自己运行的 PostgreSQL 数据库(裸机、虚拟机、容器、Patroni 集群以及 CloudNativePG 等运维工具),对内容寻址数据块进行去重和加密,并使用 PITR 进行恢复。支持 PG 15+ 和 Apache 2.0。

以下从零开始搭建pg_hardstorage备份。

------

## 1. 安装

### Pre-built binary

发布版本以静态文件`linux/{amd64,arm64}`和tar 包的形式提供(Windows 仅支持命令行界面)。从[github.com/cybertec-postgresql/pg_hardstorage/releases](https://github.com/cybertec-postgresql/pg_hardstorage/releases)`darwin/arm64` 获取匹配的版本 ,验证签名,然后将二进制文件放到您的目录中:`$PATH`

```
VERSION=1.0.4 # latest release: https://github.com/cybertec-postgresql/pg_hardstorage/releases/latest
curl -LO "https://github.com/cybertec-postgresql/pg_hardstorage/releases/download/v${VERSION}/pg_hardstorage_${VERSION}_linux_amd64.tar.gz"
tar xzf "pg_hardstorage_${VERSION}_linux_amd64.tar.gz"
sudo install -m 0755 pg_hardstorage /usr/local/bin/
pg_hardstorage version
```

### `.deb`(Debian / Ubuntu)

```
VERSION=1.0.4 # the release you downloaded
sudo dpkg -i "pg-hardstorage_${VERSION}_amd64.deb"
```

该软件包在 处安装二进制文件`/usr/bin/pg_hardstorage`,在 处放置一个 systemd 单元`/lib/systemd/system/pg_hardstorage.service`,并创建`/etc/pg_hardstorage/`,,其模式为 0750 `/var/lib/pg_hardstorage/`, `/var/log/pg_hardstorage/`所有者为`pg-hardstorage`。

### `.rpm`(Fedora / RHEL / Rocky / Alma)

```
VERSION=1.0.4 # the release you downloaded
sudo rpm -i "pg-hardstorage-${VERSION}-1.x86_64.rpm"
```

### Container image

```
VERSION=1.0.4 # latest release tag
docker pull "ghcr.io/cybertec-postgresql/pg_hardstorage:v${VERSION}"
docker run --rm "ghcr.io/cybertec-postgresql/pg_hardstorage:v${VERSION}" version
```

该镜像不包含发行版。请在指定位置挂载一个配置目录`/etc/pg_hardstorage` ,并在指定位置挂载一个状态目录`/var/lib/pg_hardstorage`;这两个目录都必须对用户 ID 65532 具有写入权限。

### From source

```
git clone https://github.com/cybertec-postgresql/pg_hardstorage
cd pg_hardstorage
make # produces bin/pg_hardstorage
sudo install -m 0755 bin/pg_hardstorage /usr/local/bin/
```

需要 Go 1.26+.`make test`在竞争检测器下运行完整的单元测试套件;`make test-integration`通过 testcontainers-go 测试真正的 PostgreSQL 17 容器(需要 Docker)。

$ pg_hardstorage version
pg_hardstorage 1.0.4 (6bf20a6, built 2026-06-24T20:10:58Z)

------

## 2. 五分钟快速入门

### 2.1 在 PostgreSQL 上配置复制用户

```
CREATE ROLE pgbackup REPLICATION LOGIN PASSWORD 'pgbackup';
```

添加一行`pg_hba.conf`代码,允许代理主机以该角色进行复制:

```
host replication pgbackup 192.192.103.117/32 scram-sha-256
或者
host replication pgbackup 0.0.0.0/0 scram-sha-256
```

重新加载 PG(`SELECT pg_reload_conf()`)。

### 2.2 创建存储库

```
pg_hardstorage repo init file:///postgresql/backup/
```

#提前创建本地目录 /postgresql/backup,postgres用户需要赋予目录读写权限,chmod 700

仓库是一个目录(或 S3 对象存储),其中包含代码块、清单和 WAL。一个仓库可以包含多个部署。该命令`repo init`对 URL 是幂等的——针对现有仓库重新运行命令会返回 `conflict.repo_exists`(exit 7)。

S3 的工作原理相同:

```
pg_hardstorage repo init 's3://acme-backups/?region=eu-central-1'
```

其他后端使用相同的格式——选择与存储相匹配的 URL 方案:

| 后端 | 示例网址 |
| ---------------------------- | --------------------------------------------------- |
| 本地文件系统 | `file:///postgresql/backup` |
| AWS S3 / MinIO / R2 / B2 | `s3://acme-backups/?region=eu-central-1` |
| Google Cloud Storage | `gcs://acme-backups/` |
| Azure Blob | `azblob://account.blob.core.windows.net/container/` |
| 通过 SSH(SFTP)远程主机 | `sftp://backup@nas.example.com/srv/backups` |
| 通过 SSH (ssh-exec) 远程主机 | `scp://backup@nas.example.com/srv/backups` |

`sftp://`两者`scp://`都使用 SSH;`sftp://`默认情况下选择 SSH,`scp://`当远程服务器禁用 SFTP 子系统时选择 SSH。有关身份验证/已知主机/额外映射设置的相关信息,请参阅 [“添加 SFTP 存储库”](https://github.com/cybertec-postgresql/pg_hardstorage/blob/main/docs/how-to/adding/repository-sftp.md) 和[“添加 SCP 存储库”](https://github.com/cybertec-postgresql/pg_hardstorage/blob/main/docs/how-to/adding/repository-scp.md) 。

### 2.3 验证 PG 是否已准备好进行备份恢复(一次性预检)

`wal stream`每次启动时都会自动运行预检程序,但您可以先单独运行它,以确认源 PostgreSQL 满足复制要求,然后再配置 systemd:

```
pg_hardstorage wal pg_hardstorage wal preflight db1 --pg-connection \ 'postgres://pgbackup:pgbackup@192.192.103.117:5432/postgres'
输出如下:
{
"deployment": "db1",
"role": "pgbackup",
"pg_version_num": 180003,
"findings": [
{
"severity": "info",
"code": "max_slot_wal_keep_size.unbounded",
"message": "max_slot_wal_keep_size = -1 (PG default); the slot will retain WAL until the streamer reconnects, even if pg_wal/ fills the partition",
"suggestion": "pair with a disk-free alert on the partition holding pg_wal/ AND a streamer-lag alert; or set max_slot_wal_keep_size to bound the slot — see docs/how-to/operating/slot-disk-safety.md for the full trade-off",
"observed": "-1"
},
{
"severity": "info",
"code": "wal_keep_size",
"message": "wal_keep_size = 0 (informational; the slot is the primary retention guarantee)",
"observed": "0"
}
]
}
```

致命错误(`wal_level.too_low`,,,)会导致命令以非零值退出,并且每个错误都会阻塞程序。警告(, 在 PG 17 及以上级别)会显示出来`max_replication_slots.full`, 但不会阻塞程序。`max_wal_senders.saturated``role.no_replication``suggestion:``max_slot_wal_keep_size.set``idle_replication_slot_timeout.set`

### 2.4 启动 WAL 流式传输(这是始终开启的核心)

完成预检清理后,启动 WAL 流。这是其主要功能,`pg_hardstorage`也是需要 24*7 全天候运行的进程:

```
pg_hardstorage wal stream db1 \
--pg-connection 'postgres://pgbackup:pgbackup@192.192.103.117:5432/postgres' \
--repo file:///postgresql/backup
输出如下:
08:26:18 [INFO ] wal.preflight.max_slot_wal_keep_size.unbounded
body: {
"message": "max_slot_wal_keep_size = -1 (PG default); the slot will retain WAL until the streamer reconnects, even if pg_wal/ fills the partition",
"observed": "-1",
"required": "",
"suggestion": "pair with a disk-free alert on the partition holding pg_wal/ AND a streamer-lag alert; or set max_slot_wal_keep_size to bound the slot — see docs/how-to/operating/slot-disk-safety.md for the full trade-off"
}
08:26:18 [INFO ] wal.preflight.wal_keep_size
body: {
"message": "wal_keep_size = 0 (informational; the slot is the primary retention guarantee)",
"observed": "0",
"required": "",
"suggestion": ""
}
08:26:19 [INFO ] wal.stream.starting deployment=db1 timeline=1
body: {
"attempt": 1,
"compression": "",
"encryption": false,
"resume_strategy": "fresh-slot-restart-lsn",
"slot": "pg_hardstorage_db1",
"start_lsn": "0/85000000",
"status_interval": "10s",
"system_id": "7639282777750685031"
}

08:43:04 [WARNING] wal.stream.reconnecting
body: {
"attempt": 1,
"backoff": "1s",
"error": "streaming: inactivity timeout (no message from server) (after 5m0s)",
"reason": "stream_break",
"synced_lsn": "0/87000000"
}
08:43:05 [INFO ] wal.stream.starting deployment=db1 timeline=1
body: {
"attempt": 2,
"compression": "",
"encryption": false,
"last_lsn_in_repo": "0/87000000",
"resume_strategy": "resume-from-repo",
"slot": "pg_hardstorage_db1",
"start_lsn": "0/87000000",
"status_interval": "10s",
"system_id": "7639282777750685031"
}
08:48:05 [WARNING] wal.stream.reconnecting
body: {
"attempt": 2,
"backoff": "1s",
"error": "streaming: inactivity timeout (no message from server) (after 5m0s)",
"reason": "stream_break",
"synced_lsn": "0/0"
}
08:48:06 [INFO ] wal.stream.starting deployment=db1 timeline=1
body: {
"attempt": 3,
"compression": "",
"encryption": false,
"last_lsn_in_repo": "0/87000000",
"resume_strategy": "resume-from-repo",
"slot": "pg_hardstorage_db1",
"start_lsn": "0/87000000",
"status_interval": "10s",
"system_id": "7639282777750685031"
}
...................

当前该进程是前台运行,如果终止则服务停止,可以转为后台运行,如下:
方法1:使用nohup(临时/轻量级)
nohup pg_hardstorage wal stream db1 \
--pg-connection 'postgres://pgbackup:pgbackup@192.192.103.117:5432/postgres' \
--repo file:///postgresql/backup \
>> /postgresql/backup/wal_stream.log 2>&1 &

方法2:创建systemd服务(生产环境最佳实践)
1. 创建服务文件
使用 root 用户或 sudo 权限创建 /etc/systemd/system/pg_hardstorage-wal.service:
[Unit]
Description=PostgreSQL Hardstorage WAL Stream for db1
After=network.target postgresql.service

[Service]
Type=simple
User=postgres
Group=postgres
ExecStart=/usr/bin/pg_hardstorage wal stream db1 \
--pg-connection 'postgres://pgbackup:pgbackup@192.192.103.117:5432/postgres' \
--repo file:///postgresql/backup
Restart=always
RestartSec=5
# 限制日志输出,防止占满系统盘
StandardOutput=journal
StandardError=journal
[Install]
WantedBy=multi-user.target

2. 启动并启用服务
# 重新加载 systemd 配置
sudo systemctl daemon-reload

# 启动服务
sudo systemctl start pg_hardstorage-wal

# 设置开机自启
sudo systemctl enable pg_hardstorage-wal
3. 查看日志与状态
# 查看运行状态
sudo systemctl status pg_hardstorage-wal

# 实时查看流传输日志
journalctl -u pg_hardstorage-wal -f
```

`CREATE_REPLICATION_SLOT pg_hardstorage_db1 PHYSICAL RESERVE_WAL`如果槽位不存在,代理会发出请求——在创建时立即`RESERVE_WAL`锁定槽位`restart_lsn`,因此 PG 从那时起就保留 WAL 日志。然后它会 `START_REPLICATION SLOT pg_hardstorage_db1 PHYSICAL`针对该槽位发出请求。代理重启后,数据流不会中断。可以使用 systemd或容器调度器来监控它。

`--skip-preflight`如果已经审核过 PG,则此方法是显式覆盖;`--no-slot`对于仅用于归档的部署,此方法是显式逃生舱口,它通过另一种机制保证 WAL 保留(两者都会发出响亮的警告——使用其中任何一种都是有意为之)。

让它继续运行。剩余步骤将在另一个终端或单独的调度程序下运行。

### 2.5 采取第一次基础备份

在streamer进程并发运行的情况下,进行基础备份。这两个进程共享存储库 URL,但除此之外没有其他协调——`backup streamer进程`BASE_BACKUP`通过自身的复制连接传输数据,同时`wal stream`继续发送 WAL 日志。

向导程序会探测 PG,生成签名密钥对和 KEK,写入数据 `pg_hardstorage.yaml`,并(默认情况下)进行第一次备份:

```
pg_hardstorage init \
--pg-connection 'postgres://pgbackup:pgbackup@192.192.103.117:5432/postgres' \
--repo file:///postgresql/backup \
--deployment db1 \
--yes
输出内容如下:
08:30:38 [INFO ] init.probe.starting
body: {
"deployment": "db1"
}
08:30:38 [NOTICE] init.probe.ok
body: {
"pg_version": 18,
"system_id": "7639282777750685031",
"timeline": 1
}
08:30:38 [NOTICE] init.repo.ready
body: {
"repo_id": "9bc618d1f252be3ba8f3c6422d3c3c55",
"url": "file:///postgresql/backup"
}
08:30:39 [NOTICE] init.kek.ready
body: {
"generated": true,
"path": "/home/postgres/.config/pg_hardstorage/keyring/kek.bin"
}
08:30:39 [NOTICE] init.config.written
body: {
"deployment": "db1"
}
08:30:39 [INFO ] init.backup.starting
body: {
"deployment": "db1"
}
08:43:58 [NOTICE] init.backup.ok
body: {
"backup_id": "db1.full.20260625T083040Z.68ac",
"duration_ms": 799160
}
✓ pg_hardstorage initialized
Deployment: db1
PostgreSQL: 18
Cluster ID: 7639282777750685031
Timeline: 1
Repository: file:///postgresql/backup
Config: /home/postgres/.config/pg_hardstorage/pg_hardstorage.yaml
Keyring: /home/postgres/.config/pg_hardstorage/keyring
Encryption: AES-256-GCM (KEK generated at /home/postgres/.config/pg_hardstorage/keyring/kek.bin)

First backup: db1.full.20260625T083040Z.68ac
logical: 1.3 GiB
duration: 799160ms

Next steps:
1. Start the agent (drives scheduled backups + retention):
pg_hardstorage agent
2. Continuously archive WAL for PITR:
pg_hardstorage wal stream db1 --pg-connection ... --repo file:///postgresql/backup
3. Inspect deployment health:
pg_hardstorage doctor db1
```

要稍后进行备份而无需通过向导(这是调度程序每晚运行的命令):

```
pg_hardstorage backup db1 \
--pg-connection 'postgres://pgbackup:pgbackup@192.192.103.117:5432/postgres' \
--repo file:///postgresql/backup
输出内容如下:
08:48:41 [INFO ] backup.dedup_hints_loaded deployment=db1
body: {
"hint_chunks": 20698
}
08:48:42 [INFO ] backup.pg_probed
body: {
"pg_version": 18,
"raw": "18.3"
}
08:48:42 [INFO ] backup.identified
body: {
"system_id": "7639282777750685031",
"timeline": 1,
"xlogpos": "0/870001A0"
}
08:48:42 [INFO ] backup.started tenant=default deployment=db1 backup_id=db1.full.20260625T084842Z.2dd5
08:48:57 [INFO ] backup.stream_complete
body: {
"bytes_received": 1422521710,
"messages": 46080,
"tablespaces": 1
}
08:49:03 [WARNING] backup.essential_files_unchecked deployment=db1 backup_id=db1.full.20260625T084842Z.2dd5
body: {
"error": "backup: probe config locations: pg: read data_directory: ERROR: permission denied to examine \"data_directory\" (SQLSTATE 42501)",
"hint": "could not query data_directory / config_file from source PG; skipping the pre-commit essential-files check"
}
08:49:05 [INFO ] backup.committed tenant=default deployment=db1 backup_id=db1.full.20260625T084842Z.2dd5 timeline=1 lsn=0/88000158
body: {
"chunks_deduped": 21160,
"chunks_written": 2,
"dedup_hit_rate": 0.9999054909743881,
"duration_ms": 24044,
"file_count": 1782,
"logical_bytes": 1421272834,
"primary_key": "manifests/db1/backups/db1.full.20260625T084842Z.2dd5/manifest.json",
"total_chunk_refs": 21162,
"unique_chunk_bytes": 1409386943,
"unique_chunk_count": 20698
}
✓ Backup committed
ID: db1.full.20260625T084842Z.2dd5
Deployment: db1
PostgreSQL: 18
Cluster ID: 7639282777750685031
Stop LSN / TLI: 0/88000158 / 1
Files: 1782 in 1 tablespace(s)
Logical bytes: 1.3 GiB
Unique chunks: 20698 (1.3 GiB after dedup)
Dedup ratio: 1.01x
Duration: 24044 ms
Encryption: AES-256-GCM (per-backup DEK, wrapped under local KEK)
Manifest: manifests/db1/backups/db1.full.20260625T084842Z.2dd5/manifest.json
```

生产环境中:调度`backup`(cron / systemd 定时器 / Kubernetes CronJob),监控`wal stream`(systemd / Kubernetes Deployment)。基础备份是周期性锚点;流式传输器确保 PITR 在锚点之间达到字节级精确同步。

### 2.6 恢复

```
pg_hardstorage restore db1 latest \
--target /postgresql/restored \
--repo file:///postgresql/backup
输出内容如下:
08:50:18 [INFO ] restore.manifest_loaded tenant=default deployment=db1 backup_id=db1.full.20260625T084842Z.2dd5 timeline=1 lsn=0/88000158
body: {
"file_count": 1782,
"pg_version": 18,
"tablespaces": 1
}
08:50:18 [INFO ] restore.started deployment=db1 backup_id=db1.full.20260625T084842Z.2dd5
body: {
"resumed": false,
"target": "/postgresql/restored"
}
09:00:47 [INFO ] restore.verifybackup_ok deployment=db1 backup_id=db1.full.20260625T084842Z.2dd5
body: {
"algorithm": "CRC32C",
"bytes_hashed": 1421273066,
"files_checked": 1783
}
09:00:49 [INFO ] restore.auto_recovery_armed deployment=db1 backup_id=db1.full.20260625T084842Z.2dd5
body: {
"recovery_target": "immediate",
"restore_command": "wired",
"signal": "standby.signal"
}
```

PITR 通过自然语言时间:

--恢复预览:

[postgres@pg117 ~]$ pg_hardstorage restore db1 latest --target /postgresql/restored --repo file:///postgresql/backup --to "5 minutes ago" --preview

Restore plan (preview only — no files written)
Backup: db1.full.20260626T071735Z.b2be
Deployment: db1
Target: /postgresql/restored
PostgreSQL: 18
Cluster ID: 7639282777750685031
Backup stop LSN: 0/A2000158 (TLI 1)
Recovery target: time 2026-06-29T07:40:33.510854269Z (inclusive=true)
On target reached: pause
Recovery TLI: latest
Files: 1787
Total bytes: 1.3 GiB
Chunk refs: 21166 (20702 unique, 1.3 GiB after dedup)
backup_label: 232 bytes
Estimated RTO: 13554 ms (assuming 100.0 MiB/s)
Pre-flight: ✗ 1 issue(s)

--开始恢复:

pg_hardstorage restore db1 latest \
--target /postgresql/restored5 \
--repo file:///postgresql/backup \
--to "5 minutes ago
输出内容如下:
09:03:36 [INFO ] restore.manifest_loaded tenant=default deployment=db1 backup_id=db1.full.20260625T084842Z.2dd5 timeline=1 lsn=0/88000158
body: {
"file_count": 1782,
"pg_version": 18,
"tablespaces": 1
}
09:03:36 [INFO ] restore.started deployment=db1 backup_id=db1.full.20260625T084842Z.2dd5
body: {
"resumed": false,
"target": "/postgresql/restored5"
}
09:14:19 [INFO ] restore.verifybackup_ok deployment=db1 backup_id=db1.full.20260625T084842Z.2dd5
body: {
"algorithm": "CRC32C",
"bytes_hashed": 1421273066,
"files_checked": 1783
}
09:14:20 [INFO ] restore.recovery_armed deployment=db1 backup_id=db1.full.20260625T084842Z.2dd5
body: {
"action": "pause",
"inclusive": true,
"target_lsn": "",
"target_name": "",
"target_time": "2026-06-25T08:58:36Z",
"timeline": "latest"
}

或者恢复到特定的 LSN:。`--to-lsn 0/3000028`或者恢复到指定的还原点:`--to-name pre_release`。

恢复操作会写入一个托管块`recovery.signal`,并在 `postgresql.auto.conf`其中`restore_command`调用 `pg_hardstorage wal fetch <deployment> %f %p --repo ...`。启动 PG;恢复过程继续进行。

`pg_verifybackup`在恢复操作声明成功之前,会先对数据目录进行检查。只有在您清楚自己在做什么的情况下才跳过此检查——`--verify=skip`退出代码,表示验证程序判定为“否”。

### 2.7 备份状态查看

[postgres@pg117 ~]$ pg_hardstorage status db1

DEPLOYMENT BACKUPS HEALTH LATEST AGE STOP LSN TLI STREAMS

db1 5 ✓ db1.full.20260626T071735Z.b2be 3d 0/A2000158 1 -

Audit anchor: ⚠ none (6 event(s) un-anchored — run `pg_hardstorage audit anchor`)
Pending approvals: 0

[postgres@pg117 ~]$ pg_hardstorage list db1

Backups for db1 (5):
BACKUP ID TYPE WHEN FILES SIZE DEDUP DURATION

db1.full.20260626T071735Z.b2be full 2026-06-26 07:17 1787 1.3 GiB 1.01x 10805ms db1.full.20260625T094450Z.9826 full 2026-06-25 09:45 1785 1.3 GiB 1.01x 18790ms db1.full.20260625T092448Z.25f6 full 2026-06-25 09:25 1782 1.3 GiB 1.01x 13424ms db1.full.20260625T084842Z.2dd5 full 2026-06-25 08:48 1782 1.3 GiB 1.01x 15683ms db1.full.20260625T083040Z.68ac full 2026-06-25 08:31 1782 1.3 GiB 1.01x 27398ms

[postgres@pg117 ~]$ pg_hardstorage show db1 db1.full.20260625T084842Z.2dd5
Backup db1.full.20260625T084842Z.2dd5 Deployment db1
Type full
PostgreSQL 18
Cluster ID 7639282777750685031
Start LSN 0/88000028
Stop LSN 0/88000158
Timeline 1
Started 2026-06-25 08:48:42 UTC
Stopped 2026-06-25 08:48:57 UTC
Duration 15683 ms
Compression zstd
Tablespaces 1
oid=0
Files 1782
Logical bytes 1.3 GiB
Unique chunks 20698 (1.3 GiB)
Dedup ratio 1.01x
backup_label 232 bytes
Signature ed25519 / fingerprint 25aeb62195860b7b

`status`返回 RPO(当前时间 - 最近一次备份完成时间)、WAL 延迟和下次计划运行时间。`show`转储完整清单,包括 LSN 范围、时间线、去重率、加密信封详细信息以及已写入的验证记录。

### 2.8 留存率

默认策略:

deployments:
db1:
retention:
policy: gfs
keep_daily: 7
keep_weekly: 4
keep_monthly: 12
keep_yearly: 5

[postgres@pg117 ~]$ pg_hardstorage rotate db1

Rotation plan (dry-run — no manifests soft-deleted)

Policy: gfs

db1
keep: 2
delete: 3
[keep] db1.full.20260626T071735Z.b2be @ 2026-06-26T07:17:46Z (daily-1,weekly-1,monthly-1,yearly-1)

​ [keep] db1.full.20260625T094450Z.9826 @ 2026-06-25T09:45:08Z (daily-2)

​ [del ] db1.full.20260625T092448Z.25f6 @ 2026-06-25T09:25:02Z

​ [del ] db1.full.20260625T084842Z.2dd5 @ 2026-06-25T08:48:57Z

​ [del ] db1.full.20260625T083040Z.68ac @ 2026-06-25T08:31:07Z

------

## 3. 验证安装

`doctor`是单命令,检查“是否存在任何问题”:

$ pg_hardstorage doctor
Mode: user

PATHS
Config /home/postgres/.config/pg_hardstorage [xdg] exists drwx------
drop-in /home/postgres/.config/pg_hardstorage/conf.d [derived] missing
deployments /home/postgres/.config/pg_hardstorage/deployments [derived] missing
sinks /home/postgres/.config/pg_hardstorage/sinks [derived] missing
skills /home/postgres/.config/pg_hardstorage/skills [derived] missing
keyring /home/postgres/.config/pg_hardstorage/keyring [derived] exists drwx------
State /home/postgres/.local/share/pg_hardstorage [xdg] missing
bookkeeping /home/postgres/.local/share/pg_hardstorage/bookkeeping [derived] missing
inflight /home/postgres/.local/share/pg_hardstorage/inflight [derived] missing
crashes /home/postgres/.local/share/pg_hardstorage/crashes [derived] missing
Cache /home/postgres/.cache/pg_hardstorage [xdg] missing
Logs /home/postgres/.local/state/pg_hardstorage [xdg] missing
Runtime /run/user/1001/pg_hardstorage [xdg] missing
Shared data /home/postgres/.local/share/pg_hardstorage/share [xdg] missing

CONFIG
Status: configured
Schema: pg_hardstorage.config.v1
Deployments: 1 (db1)
db1 class: internal
Sinks: 0
Source files:
[loaded ] /home/postgres/.config/pg_hardstorage/pg_hardstorage.yaml

KEYSTORE
Dir: /home/postgres/.config/pg_hardstorage/keyring
Signing key: ✓ present
KEK: ✓ present (encryption ON by default for new backups)

AIRGAP
Mode: off

REPOS
file:///postgresql/backup — reachable
audit chain: 6 event(s)
anchor: ✗ NONE (chain has events, no transparency anchor)

ISSUES
[WARNING] audit.anchor_missing: doctor: 6 audit event(s) at file:///postgresql/backup but no transparency-log anchor; run `pg_hardstorage audit anchor`
hint: run `pg_hardstorage audit anchor --repo <url>` (or wire periodic anchoring via the agent's audit_anchor schedule)

任何一行`✗`都是一个需要修正的建议。运行 `pg_hardstorage doctor -o json`生成机器可读格式。

`doctor`正常时退出代码为 0,`--exit-on-issues`发现问题时退出代码为 10 — 如果想要一个硬性失败信号,可将其连接到警报系统中。

http://www.cnnetsun.cn/news/3105506.html

相关文章:

  • ai_hot_news_20260701
  • 2026年零基础转型大模型行业的实操指南
  • Photon光影包终极指南:如何为你的Minecraft打造电影级画面
  • 多维聚合数据操作:维度对齐、度量校准与空值策略实战
  • STM32与TPS65263实现高效嵌入式电源管理方案
  • Claude归零层解析:语义保真度校验环的工程消除与落地实践
  • HyperFlex 架构(1):介绍与设计摘要
  • IMU传感器与MCU实现6DoF运动追踪技术解析
  • Sqribble深度解析:模板驱动的云原生文档操作系统
  • PDF 翻译按页收费还是按字收费,正式文档怎么选
  • 模板驱动型文档自动化:结构化填空替代AI生成
  • Sqribble文档自动化系统:模板驱动的PDF生成原理与工程实践
  • 硕博论文怕双降毁盲审?2026 实测:智谱文思深度适配高难论文,AI 率能压到 2%
  • 企业官网开发进入AI时代:从需求到上线全流程解析
  • FanControl终极指南:掌握Windows风扇控制的专业技巧
  • 6DoF IMU应用开发:BMI270与PIC18F4550实战指南
  • TPS65263三路降压转换器与PIC18F86K90的嵌入式电源管理方案
  • 论文焦虑终结者!6款AI论文平台,一键极速生成超长篇幅!
  • ICG-Dextran/Mannose,Dextran-ICG,吲哚菁绿-甘露糖/葡聚糖的组成
  • 构建智能家居操作系统:Home Assistant OS深度解析与实践指南
  • Agent 运行时革命:Session 作为事件日志的工程实践
  • STM32驱动WS2812智能灯带:硬件选型与底层实现
  • 深度解析:探索Python与Cadence Virtuoso的无缝集成革命——SkillBridge实战指南
  • DSPE-Azo-PEG-Cy5/Heparin/OH,肝素修饰DSPE-偶氮苯-PEG的设计思路
  • 在Windows上轻松处理PDF的终极方案:Poppler预编译包完整指南
  • PCF8591与PIC18F26K40的模数转换应用指南
  • 模型关系幻觉(数据集构建)
  • 有了ai,是不是都没人问了
  • PIC18F4680与74HC32构建高效2x2键盘管理系统
  • Agent Runtime 三层架构:Session、Harness 与 Sandbox 的工程本质