如果SLOG丢失,如何使ZFS与ZIL SLOG保持一致?

如果SLOG丢失,如何使ZFS与ZIL SLOG保持一致?

我的 HDD 上有 ZFS,SSD 上有 ZIL SLOG。

如果相关的话,我在 SSD 上还有一个 LARC 缓存。

如何重新配置​​它以确保 SSD 故障不会导致数据不一致(不符合 POSIX 文件系统调用结果规则,例如write()在单个线程中混合两个操作的内容,一个接一个地执行)?

如果我在不恢复 SSD 的情况下恢复 HDD 的备份快照,我想确保 ZFS 上的 PosgreSQL DB 不会变得不一致。 (我确实采取了同步 PostgreSQL 的措施(假设 Postgre 没有错误)POSIX 正确的文件系统保证数据库不会变得不一致。)

答案1

ZIL 仅假定包含短期内对稳定磁盘的未提交写入。如果您同时发生电源故障和 SSD 故障,这可能会成为问题。但是,如果 SSD 在其他方面正常的情况下出现故障,则 zfs 应该从相当于 raid 写回的模式转换为 raid 直写模式。性能可能会下降,但不会立即损坏任何内容。

ZIL 的要点是将更改快速写入非易失性存储,以便可以快速告诉应用程序继续。如果在将这些数据写入稳定存储(磁盘)之前断电,则在通电后下次安装 zfs 卷时,它们将从 ZIL 复制到稳定存储。

文件系统快照的全部意义在于,您可以复制未主动写入的文件系统的稳定版本。这与 ZIL 无关,因为快照不应该是可写的,因此 ZIL 不会有任何挂起的写入操作。

话虽如此,postgreSQL 可能并不乐意恢复文件系统快照。除非 postgreSQL 也被告知在 ZFS 快照之前进行快照或暂停,否则 zfs 快照可能包含一些部分 postgreSQL 写入,这可能是一个问题。您可能想问一个关于如何正确备份 postgreSQL 数据库的单独问题。 (......除非其他人想在这里介绍这一点。)

答案2

SLOG 可以被认为是独立于数据集的。这意味着一旦你的 pg 数据被刷新到磁盘,数据集就可以被快照和备份,并且快照可以被恢复(到同一个池和/或到不同的池),无论它有日志设备与否。

如果您打算从池中物理删除log(SLOG) 或cache(L2ARC) 设备,您当然应该首先从逻辑上删除它:

zpool remove [poolname] [logdevice|cachedevice]

(看man zpool-remove

如果未正确删除 SLOG,池可能无法在下次重新启动时导入。从中恢复可能相当容易(如果 SLOG 中没有未刷新的数据),或者在不接受数据损坏的情况下很难/不可能做到。通常建议添加两个 SLOG 设备作为镜像对,这是有原因的,这就是为了避免这个问题 - 即避免出现能够损坏池的单点故障。


我仍然会定期进行pg_dump备份(到另一个具有自己的快照和备份计划的数据集),因为我认为文本转储比二进制文件更可靠 - 特别是如果二进制快照是在 postgresql 服务器仍在运行时创建的(服务器可能拍摄快照时,尚未将内存中的所有内容写入磁盘...但关闭服务器将使其写入以相同状态重新启动所需的所有内容)。还因为对于重要数据来说,备份越多越好。

顺便说一句,我几年前写了一个简单的 postgresql 备份脚本,它转储所有内容,然后是 pg 全局变量(角色等),然后是每个数据库和表的模式,然后是数据(如 COPY ... FROM),然后是数据再次作为列插入。我已经使用它的变体大约 20 年了。我在 ServerFault 上发布了它的一个版本:自动备份 PostgreSQL 数据库的最佳方法是什么?时间回到2009年。

该版本可能需要一些小的调整(尤其是DBS=( $($PSQL --list --tuples-only ...) )获取数据库列表的行。如果备份目录是具有自己的快照计划的 zfs 数据集,则不需要 YMD 子目录或find ... -mtime +30 ...删除另外,您不需要通过管道pg_dumppg_dumpall进入gzip,只需对备份数据集使用压缩即可。

相关内容