pg_resetwal — 重置一个 PostgreSQL 数据库集群的预写式日志和其他控制信息
pg_resetwal [ -f | --force ] [ -n | --dry-run ] [option...] [ -D | --pgdata ]datadir
pg_resetwal 会清除预写式日志(WAL),并可选地重置存储在 pg_control 文件中的一些其他控制信息。当这些文件已损坏时,有时会需要这个功能。它只应作为最后手段使用,即当服务器因这种损坏而无法启动时。
某些选项(例如 --wal-segsize,见下文)也可以用来修改数据库集群的某些全局设置,而无需重新运行 initdb。在一个其他方面健全的数据库集群上,只要不使用下文提到的任何危险模式,就可以安全地这样做。
如果在一个服务器已被干净地关闭且控制文件健全的数据目录上使用 pg_resetwal,那么它对数据库系统的内容不会产生任何影响,只是不再使用的 WAL 文件会被清除掉。任何其他用法都有潜在危险,必须非常小心地进行。在一个处于非干净关闭状态或控制文件已损坏的数据目录上工作之前,pg_resetwal 会要求指定 -f(强制)选项。
在一个具有损坏 WAL 或损坏控制文件的数据目录上运行过这个命令之后,应该可以启动服务器,但请记住,由于存在部分提交的事务,数据库中可能包含不一致的数据。你应该立即转储你的数据,运行 initdb,然后恢复。恢复之后,检查是否存在不一致之处,并根据需要进行修复。
如果 pg_resetwal 抱怨它无法为 pg_control 确定有效数据,你可以通过指定 -f(强制)选项来强制它继续进行。在这种情况下,将会用看似合理的值来替代缺失的数据。大多数字段可以预期是匹配的,但下一个 OID、下一个事务 ID 和纪元、下一个多事务 ID 和偏移量以及 WAL 起始位置等字段可能需要手工辅助。这些字段可以使用下文讨论的选项来设置。如果你无法为所有这些字段确定正确的值,仍然可以使用 -f,但对恢复出来的数据库必须比平时更加怀疑:立即进行一次转储和恢复是必不可少的。不要在转储之前在数据库中执行任何修改数据的操作,因为任何这样的动作都可能使损坏更加严重。
这个工具只能由安装服务器的用户运行,因为它需要对数据目录的读/写访问权限。
datadir-D datadir--pgdata=datadir 指定数据库目录的位置。出于安全原因,你必须在命令行上指定数据目录。pg_resetwal 不使用环境变量 PGDATA。
-f--force 强制 pg_resetwal 继续进行,即使处于上文解释过的可能有危险的情形中。具体来说,如果服务器没有被干净地关闭,或者 pg_resetwal 无法为 pg_control 确定有效数据,就必须使用这个选项才能继续。
-n--dry-run -n/--dry-run 选项指示 pg_resetwal 打印从 pg_control 重构出的值以及即将被修改的值,然后不修改任何内容就退出。这主要是一个调试工具,但在允许 pg_resetwal 真正继续进行之前,它也可以作为一种合理性检查。
-V--version显示版本信息,然后退出。
-?--help显示帮助,然后退出。
只有当 pg_resetwal 无法通过读取 pg_control 确定合适的值时,才需要下列选项。安全值可以按照下文描述的方法来确定。对于取数字参数的值,可以使用前缀 0x 来指定十六进制值。注意,这些说明只适用于 8 kB 的标准块大小。
-c xid,xid--commit-timestamp-ids=xid,xid手工设置可以检索其提交时间的最老和最新事务 ID。
可以通过在数据目录下的 pg_commit_ts 目录中寻找数值上最小的文件名,来确定可以检索其提交时间的最老事务 ID(第一部分)的安全值。反过来,可以通过在同一个目录中寻找数值上最大的文件名,来确定可以检索其提交时间的最新事务 ID(第二部分)的安全值。文件名是十六进制的。
-e xid_epoch--epoch=xid_epoch手工设置下一个事务 ID 的纪元。
除了被 pg_resetwal 设置的那个字段之外,事务 ID 纪元实际上并没有存储在数据库中的任何地方,因此就数据库本身而言任何值都可以工作。你可能需要调整这个值,以确保像 Slony-I 和 Skytools 这样的复制系统能够正确工作 — 如果是这样,应该可以从下游被复制数据库的状态中得到一个合适的值。
-l walfile--next-wal-file=walfile通过指定下一个 WAL 段文件的名称来手工设置 WAL 起始位置。
下一个 WAL 段文件的名称应该大于数据目录下 pg_wal 目录中当前存在的任何 WAL 段文件名。这些名称也是十六进制的,并且由三个部分组成。第一部分是“时间线 ID”,通常应保持不变。例如,如果 00000001000000320000004A 是 pg_wal 中最大的条目,则使用 -l 00000001000000320000004B 或更大的值。
注意,当使用非默认的 WAL 段大小时,WAL 文件名中的数字与系统函数和系统视图所报告的 LSN 不同。这个选项接受一个 WAL 文件名,而不是一个 LSN。
pg_resetwal 本身会查看 pg_wal 中的文件,并选择一个超出最后一个现有文件名的默认 -l 设置。因此,手工调整 -l 应当只在以下情况下才需要:你知道有一些当前不在 pg_wal 中的 WAL 段文件(例如离线归档中的条目);或者 pg_wal 的内容已完全丢失。
-m mxid,mxid--multixact-ids=mxid,mxid手工设置下一个和最老的多事务 ID。
下一个多事务 ID(第一部分)的安全值可以这样确定:在数据目录下的 pg_multixact/offsets 目录中寻找数值上最大的文件名,加 1,然后乘以 65536(0x10000)。反过来,最老多事务 ID(-m 的第二部分)的安全值可以这样确定:在同一个目录中寻找数值上最小的文件名,然后乘以 65536。文件名是十六进制的,因此最简单的做法是以十六进制指定选项值并追加四个零。
-o oid--next-oid=oid手工设置下一个 OID。
没有同样简单的方法可以确定一个超出数据库中最大 OID 的下一个 OID,但幸运的是,把下一个 OID 的设置弄对并不关键。
-O mxoff--multixact-offset=mxoff手工设置下一个多事务偏移量。
安全值可以这样确定:在数据目录下的 pg_multixact/members 目录中寻找数值上最大的文件名,加 1,然后乘以 52352(0xCC80)。文件名是十六进制的。没有像其他选项那样追加零的简单方法。
-u xid--oldest-transaction-id=xid手工设置最老的未冻结事务 ID。
安全值可以这样确定:在数据目录下的 pg_xact 目录中寻找数值上最小的文件名,然后乘以 1048576(0x100000)。注意,文件名是十六进制的。通常,以十六进制指定选项值也同样是最简单的方式。例如,如果 0007 是 pg_xact 中最小的条目,那么 -u 0x700000 就可以工作(五个尾部零提供了合适的乘数)。
-x xid--next-transaction-id=xid手工设置下一个事务 ID。
安全值可以这样确定:在数据目录下的 pg_xact 目录中寻找数值上最大的文件名,加 1,然后乘以 1048576(0x100000)。注意,文件名是十六进制的。通常,以十六进制指定选项值也同样是最简单的方式。例如,如果 0011 是 pg_xact 中最大的条目,那么 -x 0x1200000 就可以工作(五个尾部零提供了合适的乘数)。
--char-signedness=option 手工设置默认的 char 符号性。可能的值是 signed 和 unsigned。
对于由 pg_upgrade 从 18 之前的 PostgreSQL 版本升级而来的数据库集群,安全值应该是在该升级之前运行该集群的平台的默认 char 符号性。对于所有其他集群,signed 就是安全值。不过,这个选项专供 pg_upgrade 使用,通常不应手工使用。
--wal-segsize=wal_segment_size设置新的 WAL 段大小,以兆字节为单位。该值必须被设置为介于 1 和 1024(兆字节)之间的 2 的幂。更多信息请参见 initdb 的相同选项。
这个选项也可以用来更改一个现有数据库集群的 WAL 段大小,从而避免重新运行 initdb。
虽然 pg_resetwal 会把 WAL 起始地址设置在最新的现有 WAL 段文件之后,但某些段大小的更改可能会导致之前的 WAL 文件名被重用。如果 WAL 文件名重叠会给你的归档策略带来问题,建议将 -l 与这个选项一起使用,以手工设置 WAL 起始地址。
PG_COLOR 指定是否在诊断消息中使用颜色。可能的值是 always、auto 和 never。
在服务器运行时不得使用这个命令。如果在数据目录中发现了服务器锁文件,pg_resetwal 将拒绝启动。如果服务器崩溃了,可能会留下一个锁文件;在这种情况下,你可以移除该锁文件以允许 pg_resetwal 运行。但在这样做之前,请再三确认没有仍然存活的服务器进程。
pg_resetwal 只能用于相同大版本的服务器。