从零开始学PostgreSQL (六): 备份和恢复

2024-09-06 19:18:31 浏览数 (3)

概述

PostgreSQL 提供了多种备份和恢复策略,旨在满足不同规模和需求的数据库环境。以下是 PostgreSQL 备份和恢复的主要方法概览:

1. SQL 转储

SQL 转储 是一种逻辑备份方法,使用 pg_dump 和 pg_dumpall 工具将数据库或整个集群的状态导出为 SQL 语句流。这种方法非常适合小型到中型数据库,易于迁移和恢复。

1.1. 恢复转储

使用 pg_restore 命令可以从 SQL 转储文件中恢复数据库,可以选择性地恢复特定的表、模式或数据序列。

1.2. 使用 pg_dumpall

pg_dumpall 用于备份 PostgreSQL 集群的全局信息,如用户账户、角色、数据库列表等,通常与 pg_dump 结合使用以实现整个集群的备份。

1.3. 处理大型数据库

对于大型数据库,SQL 转储可能耗时且占用大量磁盘空间。此时,可以采用以下两种物理备份方法之一。

2. 文件系统级备份

文件系统级备份 是一种物理备份技术,涉及在数据库停止服务时(或在某些情况下,使用 pg_start_backup 和 pg_stop_backup 命令在 PostgreSQL 运行时)直接复制数据目录。这种方法适用于数据库大小超出 SQL 转储能力的情况,但要求在备份期间数据库不可用。

3. 连续存档和时间点恢复(PITR)

连续存档 和 时间点恢复 (PITR) 提供了更高级别的数据保护和恢复灵活性。这种方法通过归档写前日志 (WAL) 来实现,允许数据库恢复到故障发生前的任意时间点。

3.1. 设置 WAL 归档

要启用 PITR,必须配置 PostgreSQL 以归档 WAL 文件。这通常涉及设置 archive_mode 和 archive_command 参数,并确保有足够的存储空间来保存 WAL 文件。

3.2. 进行基础备份

在启用连续归档后,需要创建一个基础备份,这是数据库在某个时间点的完整快照。基础备份可以使用 pg_basebackup 工具创建。

3.3. 使用低级 API 进行基础备份

除了使用 pg_basebackup,还可以通过调用 pg_start_backup 和 pg_stop_backup 函数来创建基础备份,这提供了更多的控制和灵活性。

3.4. 使用连续归档备份进行恢复

恢复时,将基础备份恢复到一个新的数据目录,并应用自备份时刻以来归档的 WAL 文件,以恢复到所需的点。

3.5. 时间线

PostgreSQL 使用时间线来追踪数据库的历史状态,这在 PITR 中特别重要,因为每个时间点恢复都可能创建一个新的时间线分支。

3.6. 提示和示例

在实施 PITR 时,有几个关键点需要注意,例如正确配置归档存储位置、确保 WAL 文件的完整性以及理解时间线的概念。

3.7. 注意事项

使用 PITR 时,需要考虑数据一致性和事务的隔离级别,以避免潜在的数据不一致。

1. SQL 转储

以下是pg_dump的一些关键特性和用法:

1、基本用法:

代码语言:javascript复制
pg_dump -U postgres -h 127.0.0.1 -p 5432 -W -d mydb >dumpfile

是最简单的用法,其中dbname是要备份的数据库名,dumpfile是生成的转储文件。

2、输出格式:

  • 默认情况下,pg_dump生成的是文本格式的转储文件,但也可以生成其他格式,如定制的二进制格式,后者在恢复时速度更快且占用空间更小。

3、远程备份:

  • pg_dump可以从任何有权限访问目标数据库的远程主机执行备份。

4、权限需求:

  • 通常需要以数据库超级用户的身份运行pg_dump来备份整个数据库,因为超级用户对所有表都有读取权限。对于部分数据库的备份,可以根据权限使用特定的选项。

5、连接参数:

  • 可以通过-h host和-p port选项指定数据库服务器的主机名和端口号,以及通过-U username选项指定连接的用户名。

6、跨版本和架构兼容性:

  • pg_dump的输出通常可以用于恢复到较新版本的PostgreSQL,也适用于不同计算机架构之间的迁移。

7、一致性保证:

  • 转储过程中,pg_dump会捕捉数据库的一致状态,即使在数据库运行时也能生成一致的转储文件,除了某些需要独占锁的操作。

8、高级选项:

  • pg_dump还提供了多种选项,如选择特定的模式或表进行备份,以及控制数据和模式的分离等。

1.1 恢复转储

恢复pg_dump创建的数据库转储通常涉及以下步骤和注意事项:

1、恢复命令:

  • 文本转储文件通常通过psql命令读入,其基本形式为:
代码语言:javascript复制
psql -U postgres -h 127.0.0.1 -p 5432 -W --set ON_ERROR_STOP=on mydb < dumpfile

非文本格式的转储文件(如tar或directory格式)需要使用pg_restore命令进行恢复。

2、数据库先决条件:

  • 在执行psql命令前,目标数据库dbname必须已经存在。你可以使用createdb命令创建数据库,特别是使用template0作为模板,以确保干净的状态:
代码语言:javascript复制
createdb -T template0 dbname

3、用户权限:

  • 所有在转储数据库中拥有对象或被授予对象权限的用户都必须存在于目标系统上,否则恢复过程会失败。

4、错误处理:

  • 默认情况下,psql在遇到SQL错误时会继续执行脚本,但你可以通过设置ON_ERROR_STOP变量为on,使psql在第一个错误出现时就停止执行并退出,退出状态码为3。
代码语言:javascript复制
psql -U postgres -h 127.0.0.1 -p 5432 -W --set ON_ERROR_STOP=on mydb <dumpfile

5、事务模式:

  • 可以将整个转储恢复视为一个事务,这样要么全部成功要么全部回滚。这可以通过psql的--single-transaction选项实现。但要注意,任何错误都会导致整个恢复操作回滚。

6、跨服务器转储:

  • pg_dump和psql支持管道操作,允许你直接从一个服务器转储到另一个服务器,无需保存中间文件。
代码语言:javascript复制
pg_dump -U postgres -h 127.0.0.1 -p 5432 -W -d mydb | psql -U postgres -h 127.0.0.1 -p 5432 -W --set ON_ERROR_STOP=on mydb

7、转储上下文:

  • pg_dump生成的转储是相对于template0数据库的,这意味着所有依赖项,如语言和函数,也会被转储。在恢复时,如果使用自定义template1,那么需要从template0创建新数据库以保持一致性。

8、分析统计信息:

  • 完成恢复后,运行ANALYZE命令以更新查询优化器的统计信息,这对于性能至关重要。

9、批量数据加载:

  • 对于大量数据的加载,可以参考PostgreSQL文档中关于高效数据加载的章节,以获取最佳实践和技巧。

1.2. 使用 pg_dumpall

pg_dumpall是一个用于备份整个PostgreSQL数据库集群的工具,包括所有数据库以及集群范围内的信息,如角色和表空间定义。下面是使用pg_dumpall进行备份和恢复的主要要点:

1、备份整个集群:

  • 使用pg_dumpall命令可以备份整个数据库集群的内容,包括每个数据库及其集群级的配置信息。
  • 基本的备份命令是:
代码语言:javascript复制
pg_dumpall -U postgres -h 127.0.0.1 -p 5432 -W >dumpfile

2、恢复集群:

  • 要恢复pg_dumpall生成的转储文件,可以使用psql命令,指定转储文件和超级用户权限的数据库(通常是postgres数据库):
代码语言:javascript复制
psql -U postgres -h 127.0.0.1 -p 5432 -W -f dumpfile postgres

3、超级用户权限:

  • 在恢复pg_dumpall转储时,必须使用具有超级用户权限的连接,这是因为角色和表空间信息的恢复需要这种级别的访问权限。

4、表空间路径:

  • 如果你的数据库集群使用了表空间,确保在新环境中转储文件中的表空间路径是适用的。可能需要调整路径以适应新的硬件布局。

5、工作原理:

  • pg_dumpall通过发出用于重新创建角色、表空间和空数据库的命令,然后对每个数据库调用pg_dump来工作。这意味着,尽管每个数据库在内部是一致的,但不同数据库之间的快照可能不会完全同步。

6、仅备份集群范围数据:

  • 使用--globals-only选项,pg_dumpall可以仅备份集群范围的数据,不会备份每个单独数据库中的表结构、数据、索引、视图、存储过程等数据库级别的对象 。这对于在已有数据库上执行完整集群备份时非常有用。
代码语言:javascript复制
pg_dumpall --globals-only -U postgres -h 127.0.0.1 -p 5432 -W  > dumpfile

1.3. 处理大型数据库

处理大型数据库备份时,确实会遇到操作系统文件大小限制的问题,特别是当数据库规模庞大到单个文件无法容纳整个备份的情况下。以下是处理大型数据库备份的一些策略:

1、使用压缩转储:

  • 使用pg_dump导出数据到标准输出,然后通过管道将其传递给gzip进行压缩。
代码语言:javascript复制
pg_dump -U postgres -h 127.0.0.1 -p 5432 -W -d mydb | gzip > filename.gz
代码语言:javascript复制
gunzip -c filename.gz | psql -U postgres -h 127.0.0.1 -p 5432 -W -d mydb

2、使用拆分:

  • 利用split命令将大文件分割成多个小文件,避免文件大小限制。
代码语言:javascript复制
pg_dump -U postgres -h 127.0.0.1 -p 5432 -W -d mydb | split -b 2G - filename
代码语言:javascript复制
pg_dump -U postgres -h 127.0.0.1 -p 5432 -W -d mydb | split -b 2G --filter='gzip > $FILE.gz'
代码语言:javascript复制
cat filename* |psql -U postgres -h 127.0.0.1 -p 5432 -W -d mydb

3、使用自定义转储格式(Custom Dump Format):

  • pg_dump支持自定义格式,它会在写入输出文件时进行压缩。
代码语言:javascript复制
pg_dump -U postgres -h 127.0.0.1 -p 5432 -W  -Fc mydb > filename
代码语言:javascript复制
pg_restore -U postgres -h 127.0.0.1 -p 5432 -W -d mydb filename

4、使用并行转储和恢复:

  • 对于非常大的数据库,pg_dump提供了并行转储的功能,可以显著加速转储过程。
代码语言:javascript复制
pg_dump -U postgres -h 127.0.0.1 -p 5432 -W -j 3 -F d -f pgsqlbackup-dir mydb

2. 文件系统级备份

文件系统级备份是一种直接复制PostgreSQL数据库存储数据的文件的方法,这种方法虽然直观,但存在一些重要的局限性:

1、服务器停机需求:

  • 必须停止数据库服务器以获得一致的备份,因为文件系统备份不能在数据库活动时提供原子快照。
  • 服务器内部的缓存机制和事务状态使得在服务器运行时的备份不完整或不一致。

2、整体备份限制:

  • 备份整个数据库集群而不是单个数据库或表,因为表数据依赖于事务日志文件中的提交状态。
  • 单独恢复一个表会导致数据库集群中的其他表变得无效。
代码语言:javascript复制
tar -cf backup.tar /usr/local/pgsql/data

3、一致快照:

  • 如果文件系统支持一致快照,可以创建数据库卷的冻结快照,然后复制数据目录到备份设备。
  • 这种方式创建的备份会在重启时触发WAL日志回放,因为服务器会认为发生了崩溃。
  • 在快照前执行CHECKPOINT可以减少恢复时间。

4、多文件系统限制:

  • 如果数据库分布在多个文件系统上,可能无法同时创建所有卷的一致快照,需要特别注意快照的同步性。
  • 可能需要短暂关闭数据库服务器来确保所有快照的同步,或者采用连续归档基础备份方法。

5、使用rsync进行备份:

  • 使用rsync可以实现在服务器运行时的初步备份,然后在服务器短暂停止后进行最终一致性检查。
  • 这种方法可以最小化停机时间,最终结果将是服务器关闭瞬间的一致状态。

6、文件系统备份与SQL转储比较:

  • 文件系统备份通常比SQL转储大,因为它们包含了所有数据文件,而pg_dump只转储创建对象的SQL语句和必要的数据。

3. 连续存档和时间点恢复 (PITR)

PostgreSQL 使用预写日志(WAL)来记录所有对数据库数据文件的更改,这不仅对于崩溃后的恢复至关重要,还允许了一种被称为连续存档(或在线备份)的高级备份策略。以下是这种备份方法的关键特点和步骤:

1、WAL 日志:

  • PostgreSQL 在数据目录的子目录中维护 WAL 文件,记录每次更改。
  • WAL 日志用于恢复数据库一致性,即使在系统崩溃后也能通过重放日志恢复数据。

2、结合文件系统备份与 WAL 备份:

  • 这种策略使用文件系统级别的备份作为起点,然后结合备份的 WAL 文件进行重放,以达到最新状态。
  • 这种方法不要求备份在创建时完全一致,因为任何内部不一致可通过日志重放修正。

3、连续备份与时间点恢复:

  • 通过持续存档 WAL 文件,可以实现连续备份,尤其适用于大型数据库。
  • 时间点恢复(Point-in-time Recovery, PITR)允许将数据库恢复到特定的时间点。

4、暖备用系统:

  • 如果连续地将 WAL 文件传输给另一台具有相同基本备份的机器,就形成了一个暖备用系统,能够快速切换到近实时的数据副本。

5、限制与要求:

  • 这种备份方法不支持单独恢复数据库的子集,只支持整个集群的恢复。
  • 需要大量的存储空间来保存基本备份和WAL文件。
  • 要求在第一次基础备份前设置并测试WAL文件的归档过程。

6、工具与兼容性:

  • pg_dump 和 pg_dumpall 是逻辑备份工具,不能用于连续存档方案,因为它们不包含WAL重放所需的所有信息。

为了有效利用连续存档策略,必须确保WAL文件的归档流程可靠,以便在需要时能够进行完整的数据库恢复。这种方法虽然管理上更复杂,但在需要高可用性和灾难恢复能力的场景中非常有价值。

3.1. 设置 WAL 归档

在PostgreSQL中设置WAL(Write-Ahead Logging)归档涉及以下几个关键步骤和注意事项:

1、配置参数:

  • 设置wal_level为replica或更高,以启用WAL归档所需的日志级别。
  • 启用archive_mode以激活WAL归档。
  • 指定archive_command,这是一个shell命令,用于在WAL段文件完成后将其复制到归档位置。
  • 或者,指定archive_library,使用自定义的C语言编写的库来处理归档。
代码语言:javascript复制
将/var/lib/pgsql/16/data/pg_wal目录下的文件cp到/var/lib/pgsql/16/archivedir/目录中
archive_mode = on
wal_level = replica
archive_command = 'test ! -f /var/lib/pgsql/16/archivedir/%f && cp %p /var/lib/pgsql/16/archivedir/%f'

新建目录记得授权  
chmod 700 ./archivedir/
chown -R postgres:postgres ./archivedir/

2、档案命令:

  • 使用如cp或copy命令将WAL段文件复制到指定的归档目录。
  • 命令应该包含%p和%f占位符,分别代表文件的完整路径和文件名。
  • 命令应当防止覆盖已存在的文件,确保数据的安全性和完整性。

3、安全和权限:

  • 归档的数据应存储在具有适当权限的目录中,以防止未经授权的访问。

4、错误处理和监控:

  • 归档命令应返回零退出状态以表明成功,否则PostgreSQL将重试归档。
  • 监控归档过程,确保其能够跟上WAL数据的生成速度,避免磁盘空间耗尽。

5、自定义归档模块:

  • 使用archive_library可以实现更高效的归档处理和访问服务器资源的能力。

6、配置文件的备份:

  • 注意WAL归档不包括对postgresql.conf等配置文件的更改,需要单独备份。

7、WAL段切换和优化:

  • 可以通过设置archive_timeout来控制WAL段的切换频率,减少未归档数据的量。
  • 手动使用pg_switch_wal函数立即触发WAL段切换。

8、SQL命令的WAL优化:

  • 某些SQL命令可能被优化以减少或消除WAL日志记录,这可能影响归档恢复的信息完整性。
  1. 动态配置更改:
  • 对于wal_level和archive_command等参数,需要在服务器启动时设置,但可以通过重新加载配置文件来应用更改。

3.2. 进行基础备份

在PostgreSQL中,pg_basebackup工具用于创建基础备份,这是数据库恢复的基础。以下是使用pg_basebackup进行基础备份的关键点:

1、创建备份:

  • pg_basebackup可以创建两种类型的备份:文件系统备份或tar存档。
  • 它可以创建包含数据库集群所有必要数据文件的完整快照。

2、备份模式与性能:

  • 在进行备份时,PostgreSQL进入备份模式,这可能会影响性能,特别是当服务器在高负载下运行时。
  • full_page_writes配置参数可能在备份过程中被启用,以确保页面级别的恢复一致性。

3、WAL归档:

  • 为了能够恢复到某个时间点,必须保存在备份期间生成的所有WAL(Write-Ahead Log)段文件。
  • 基础备份会创建一个备份历史记录文件,这个文件会被存档,包含了备份开始和结束时的WAL段信息。

4、备份历史记录:

  • 备份历史记录文件是一个小的文本文件,记录了备份的元数据,如标签、开始和结束时间及WAL段。
  • 这个文件对于确定要恢复的WAL文件至关重要。

5、WAL文件保留:

  • 必须保留从上次基础备份以来的所有WAL文件,以便能够进行恢复。
  • 备份间隔应考虑到存储空间和恢复时间,因为WAL文件占用空间,且恢复时需要重播这些文件。

6、多备份集:

  • 保留多个备份集是明智的,这样即使某一个备份损坏或不完整,你也有其他备份可用。

3.3 使用低级 API 进行基础备份

使用PostgreSQL的低级API进行基础备份是一种更精细控制备份流程的方法,虽然比使用pg_basebackup复杂,但它提供了更多的定制选项。以下是使用低级API进行基础备份的主要步骤:

1、开启备份:

  • 作为具有适当权限的用户(通常是超级用户),连接到PostgreSQL服务器。
  • 发出pg_backup_start命令,提供一个标签字符串以唯一标识此次备份操作,以及是否需要立即进行检查点(fast参数)。
代码语言:javascript复制
postgres=# SELECT pg_backup_start(label => 'label', fast => false);

2、执行文件系统备份:

  • 使用如tar或cpio等文件系统备份工具进行实际的数据文件备份。
  • 数据库在备份过程中可以继续正常运行,无需中断。

3、终止备份:

  • 通过pg_backup_stop命令结束备份模式,这也会触发WAL段的自动切换(在主节点上)。
代码语言:javascript复制
postgres=# SELECT * FROM pg_backup_stop(wait_for_archive => true);

4、记录备份元数据:

  • pg_backup_stop返回的信息中,backup_label应写入备份目录中的一个文件,而tablespace_map(如果存在)应写入另一个文件。
  • 这些元数据文件对备份的完整性至关重要,必须准确无误地保存。

5、WAL段归档:

  • 确保在备份过程中产生的所有WAL段文件都被归档。
  • pg_backup_stop的wait_for_archive参数控制是否等待所有WAL段归档完成再返回。

6、监控归档过程:

  • 监控归档系统以确保所有必要的WAL段文件都及时归档,避免备份无效。

3.3.1 备份数据目录

在进行PostgreSQL数据库备份时,重要的是要确保备份策略能够有效地捕获所有必要的数据,同时避免不必要的元素。以下是从提供的文档中总结的关键点:

1、备份数据目录:确保备份包含数据库集群目录下的所有文件。如果使用了外部表空间,记得也备份它们,并确保备份工具能正确处理符号链接。

2、排除特定文件:从备份中排除以下文件和目录:

  • postmaster.pid 和 postmaster.opts,因为它们记录的是运行中postmaster的信息,而恢复后的新环境可能不同。
  • pg_wal 目录,除非你想保留WAL文件用于归档或恢复。
  • pg_replslot 目录,以避免影响备用数据库上的WAL文件保留策略和热备用反馈机制。
  • pg_dynshmem, pg_notify, pg_serial, pg_snapshots, pg_stat_tmp, 和 pg_subtrans 目录,因为它们在postmaster启动时会被初始化。
  • 以pgsql_tmp开头的文件或目录,因为它们会在postmaster启动时被清理和重建。
  • pg_internal.init文件,这些文件包含在恢复时会被重新生成的关系缓存数据。

3、备份标签和表空间映射:备份标签文件包含了关于备份会话的重要元数据,如标签字符串、运行时间和起始WAL文件名。表空间映射文件记录了表空间符号链接的信息,这对于恢复过程至关重要。

4、在服务器停止时备份:虽然推荐在服务器运行时进行备份以利用PostgreSQL的流复制和热备份特性,但在服务器停止时进行备份也是可能的。在这种情况下,你需要手动跟踪每个备份及其相关联的WAL文件位置。

5、备份工具兼容性:使用如rsync或GNU tar等文件系统备份工具时,注意它们如何处理文件更改的情况。某些版本的这些工具可以配置以忽略文件更改的警告,或者区分更改文件和致命错误的退出代码。

3.4 使用连续归档备份进行恢复

当你需要使用连续归档备份(Continuous Archiving Backup)来恢复PostgreSQL数据库时,以下是详细的恢复步骤:

停止运行中的数据库服务器,以确保数据的一致性。

备份当前数据目录,如果空间允许,将整个数据目录和表空间复制到一个安全的地方。如果空间不足,至少备份pg_wal目录,以保留未归档的WAL文件。

清空数据目录,删除数据目录下的所有文件和子目录,包括所有表空间目录。

从备份恢复数据,使用文件系统备份恢复数据文件至数据目录,确保文件的所有权和权限正确。

处理WAL目录,清空pg_wal目录,如果之前保存了未归档的WAL文件,将其复制回pg_wal目录。

配置恢复参数,在postgresql.conf中设置恢复配置,包括restore_command来定义如何检索归档的WAL文件。在数据目录下创建recovery.signal文件,表明即将进行恢复。

代码语言:javascript复制
restore_command = 'cp /var/lib/pgsql/16/archivedir/%f %p'

修改访问控制,可能需要临时修改pg_hba.conf以限制用户访问,直到确认恢复成功。

启动服务器,服务器将自动进入恢复模式,读取并应用归档的WAL文件。如果恢复中断,重启服务器可以继续恢复。

监控恢复过程,一旦恢复完成,服务器会删除recovery.signal文件,然后开始正常运行。检查数据库内容,确保数据恢复无误。

调整访问权限,确认恢复成功后,调整pg_hba.conf以允许用户正常连接。

关键配置点是restore_command,它告诉PostgreSQL如何从归档中恢复WAL文件。如果要恢复到特定的时间点或事务状态,需要设置相应的恢复目标。恢复目标必须在基本备份结束时间之后,以保证数据一致性。

如果在恢复过程中遇到损坏的WAL数据,恢复会停止,这时需要重新开始恢复流程,可能需要指定一个在损坏点之前的恢复目标。如果恢复因外部原因失败,可以重新启动恢复,从失败点继续。

3.5 时间线

在PostgreSQL中,时间线(Timeline)概念是用来处理数据库的时间点恢复(Point-in-Time Recovery, PITR)的复杂性。当你需要将数据库恢复到过去某个时刻的状态时,例如因为你意外删除了一个关键表,你可能需要使用备份的数据并结合写前日志(WAL, Write-Ahead Logging)文件来还原数据库。

当你从WAL归档中恢复数据时,PostgreSQL会在恢复完成后创建一个新的时间线。这个新时间线生成的WAL记录会被标记,以区别于原始历史记录中的记录。这是因为如果在恢复后继续操作数据库,可能会覆盖掉原本可能需要的WAL段文件,从而阻止你再次恢复到更早的状态。

WAL文件名中包含了时间线ID,这是为了确保新时间线的WAL数据不会覆盖旧时间线的数据。时间线ID在文件名中是以十六进制形式出现的,而在日志和其他输出中则常以十进制形式出现。

在处理不确定恢复时间点的情况下,你可能需要多次尝试不同的时间点恢复,这时多个时间线就显得非常有用。你可以保存多个时间线的历史,这样即使你之前放弃了某个时间线,你仍然可以从它的状态恢复。

每次创建新时间线时,PostgreSQL还会创建一个时间线历史记录文件,记录新时间线是从哪个时间线分支出来的,以及分支的时间。这些历史记录文件对于从包含多个时间线的归档中恢复数据时选择正确的WAL段文件至关重要。尽管这些文件很小,但是它们非常重要,应该被妥善保存。

在恢复过程中,PostgreSQL默认会选择归档中最新的时间线进行恢复。如果你想恢复到基本备份时的时间线或其后代时间线,你需要在recovery_target_timeline 参数中指定目标时间线ID。然而,你不能恢复到早于基本备份创建的时间线。

代码语言:javascript复制
恢复目标设置
# 仅在执行有针对性的恢复时设置这些选项。#recovery_target = ''           # 设置为 'immediate' 可以在达到一致状态后立即结束恢复(更改需重启)
#recovery_target_name = ''      # 恢复到指定的命名恢复点 (更改需重启)
#recovery_target_time = ''      # 恢复到指定的时间戳 (更改需重启)
#recovery_target_xid = ''       # 恢复到指定的事务ID(更改需重启)
#recovery_target_lsn = ''       # 恢复到指定的WAL LSN (更改需重启)
#recovery_target_inclusive = on # 指定停止的方式:
                                # 在指定恢复目标之后(on)
                                # 在指定恢复目标之前(off) (更改需重启)
#recovery_target_timeline = 'latest'    # 恢复到特定的时间线: 'current', 'latest' 或时间线ID (更改需重启)
#recovery_target_action = 'pause'       # 恢复目标后应执行的操作: 'pause', 'promote', 'shutdown' (更改需重启)

3.6. 提示和示例

在PostgreSQL中,连续归档(Continuous Archiving)是确保数据安全和实现时间点恢复的关键策略之一。以下是一些关于如何配置和优化连续归档的提示和示例:

3.6.1. 独立热备份

  • 独立热备份是使用pg_basebackup工具创建的,这种备份速度快但占用空间较大,适用于快速恢复场景但不支持时间点恢复。
  • 使用-X选项时,pg_basebackup会包括所有预写日志(WAL),使得备份可以直接恢复而无需额外的操作。

3.6.2. 压缩的归档日志

  • 压缩归档可以减少存储空间需求,使用gzip压缩WAL文件是一种常见做法。
  • 在postgresql.conf中设置archive_command为压缩命令:
代码语言:javascript复制
archive_command = 'gzip < %p > /mnt/server/archivedir/%f.gz'
  • 相应地,restore_command应设置为解压命令:
代码语言:javascript复制
restore_command = 'gunzip < /mnt/server/archivedir/%f.gz > %p'

3.6.3. 脚本化的archive_command

  • 使用脚本定义archive_command可以提供更大的灵活性和功能,比如异地数据复制、批量处理WAL文件、与其他备份软件集成等。
  • 示例脚本可以是:
代码语言:javascript复制
 archive_command = 'local_backup_script.sh "%p" "%f"'
  • 脚本可以使用如bash或perl等脚本语言编写,以实现复杂逻辑。

提示

  • 启用logging_collector有助于调试复杂配置问题,因为脚本中的错误信息将被记录在数据库服务器的日志中。

这些提示和示例帮助你更好地理解和配置PostgreSQL的连续归档策略,从而提高数据的安全性和恢复效率。通过适当的规划和实施,你可以确保在数据丢失或损坏的情况下能够迅速恢复到预期的状态。

3.7 注意事项

在PostgreSQL中使用连续归档时,有几点重要的注意事项需要考虑,以确保数据的一致性和完整性:

创建数据库与模板数据库的修改

  • 如果在进行基础备份的同时执行了CREATE DATABASE命令,并对模板数据库进行了修改,那么这些修改可能会在恢复过程中传播到新创建的数据库中,这是不期望的行为。
  • 解决方案:避免在进行基础备份时修改任何模板数据库。

表空间的绝对路径问题

  • CREATE TABLESPACE命令在WAL记录中使用绝对路径,这意味着在重放WAL时,表空间将以相同的绝对路径创建。
  • 这在不同机器上重放WAL时可能引起问题,即使在同一机器上的新数据目录中重放也可能覆盖原有的表空间内容。
  • 最佳实践:在创建或删除表空间后,进行一个新的基础备份以避免潜在冲突。

WAL格式与页面快照

  • 默认的WAL格式包含大量的磁盘页面快照,这些是为了支持崩溃恢复,但在某些环境下这部分写入的风险可能很小。
  • 可以通过关闭full_page_writes参数来减少WAL文件的大小,但这需要仔细评估系统的硬件和软件环境,以及可能的风险。
  • 关闭页面快照不会影响使用WAL进行的时间点恢复(PITR)操作。
  • 未来的开发方向之一是优化WAL数据的压缩,减少不必要的页面副本,同时保持full_page_writes开启。
  • 管理员还可以通过增加检查点间隔来减少WAL中包含的页面快照数量,以此减少WAL的总体量。

遵循这些注意事项和建议,可以帮助你更安全、高效地利用PostgreSQL的连续归档功能,确保数据在各种情况下的完整性和可恢复性。

上一篇:从零开始学PostgreSQL (五): 日常数据库维护任务

0 人点赞