PostgreSQL数据备份方式
按照备份后的文件类型划分为
- 物理备份:文件系统级别的备份
- 逻辑备份:备份后的文件是sql文件或特定格式的导出文件
按照备份过程中是否停止数据库服务划分为
- 冷备份
- 热备份
按照备份是否是完整的数据库划分为
- 全量备份:备份是完整的数据库
- 增量备份:备份是上一次全量备份后数据库改变的内容
有三种不同的基本方法来备份PostgreSQL数据:
1、SQL转储 *
2、文件系统级备份 *
3、连续归档 *
每一种都有其优缺点
SQL转储
用到的工具是pg_dump
和pg_dumpall
。
SQL 转储方法的思想是创建一个由SQL命令组成的文件,当把这个文件回馈给服务器时,服务器将利用其中的SQL命令重建与转储时状态一样的数据库。 PostgreSQL为此提供了工具pg_dump
pg_dump
每次只转储一个数据库,而且它不会转储关于角色或表空间(因为它们是集簇范围的)的信息。为了支持方便地转储一个数据库集簇的全部内容,提供了pg_dumpall程序。pg_dumpall
备份一个给定集簇中的每一个数据库,并且也保留了集簇范围的数据,如角色和表空间定义
文件系统级别备份(冷备份)
文件系统级别备份策略是直接复制PostgreSQL用于存储数据库中数据的文件。你可以采用任何你喜欢的方式进行文件系统备份。
数据库集簇说明:
在磁盘上初始化一个数据库存储区域称之为一个数据库集簇(SQL标准使用的术语是目录集簇)。一个数据库集簇是被一个运行数据库服务器的单一实例所管理的多个数据库的集合。
在文件系统术语中,一个数据库集簇是一个单一目录,所有数据都将被存储在其中。我们称它为数据目录或数据区域。在哪里存储你的数据完全由你选择。没有默认的位置,不过/usr/local/pgsql/data或/var/lib/pgsql/data位置比较流行。
文件系统级别备份数据的方法有两个限制,使得这种方法不实用:
1.为了得到一个可用的备份,数据库服务器必须被关闭。例如阻止所有连接这样的不彻底的措施是不起作用的(部分原因是tar和类似工具无法得到文件系统状态的一个原子的快照,还有服务器内部缓冲的原因)不用说,在恢复数据之前你也需要关闭服务器。
2.如果你已经深入地了解了数据库的文件系统布局的细节,你可能会有兴趣尝试通过相应的文件或目录来备份或恢复特定的表或数据库。这种方法也不会起作用,因为包含在这些文件中的信息只有配合提交日志文件(pg_xact/)才有用,提交日志文件包含了所有事务的提交状态。一个表文件只有和这些信息一起才有用。当然也不可能只恢复一个表及相关的pg_xact数据,因为这会导致数据库集簇中所有其他表变得无用。因此文件系统备份只适合于完整地备份或恢复整个数据库集簇*。
连续归档和时间点恢复(PITR)
2.3.1.整体介绍
在任何时间,PostgreSQL在数据集簇目录的pg_wal/子目录下都保持有一个预写式日志(WAL)。这个日志存在的目的是为了保证崩溃后的安全:如果系统崩溃,可以“重放”从最后一次检查点以来的日志项来恢复数据库的一致性。该日志的存在也使得第三种备份数据库的策略变得可能:我们可以把一个文件系统级别的备份和WAL文件的备份结合起来。当需要恢复时,我们先恢复文件系统备份,然后从备份的WAL文件中重放来把系统带到一个当前状态。这种方法比之前的方法管理起来要更复杂,但是有其显著的优点。
优点:
1.我们不需要一个完美的一致的文件系统备份作为开始点。备份中的任何内部不一致性将通过日志重放(这和崩溃恢复期间发生的并无显著不同)来修正。因此我们不需要文件系统快照功能,只需要tar或一个类似的归档工具。
- 由于我们可以结合一个无穷长的WAL文件序列用于重放,可以通过简单地归档WAL文件来达到连续备份。这对于大型数据库特别有用,因为在其中不方便频繁地进行完全备份。
3.并不需要一直重放WAL项一直到最后。我们可以在任何点停止重放,并得到一个数据库在当时的一致快照。这样,该技术支持时间点恢复:在得到你的基础备份以后,可以将数据库恢复到它在其后任何时间的状态。
4.如果我们连续地将一系列WAL文件输送给另一台已经载入了相同基础备份文件的机器,我们就得到了一个热备份系统:在任何时间点我们都能提出第二台机器,它差不多是数据库的当前副本。
执行一次基础备份最简单的方法是使用pg_basebackup
工具。
恢复时主要是将base下的内容拷贝到数据库data/base目录下(注意先清空)
另外WAL文件通过设置postgresql.conf的restore_command和recovery_target_timeline ,另新增recovery.signal标志文件,启动数据库进行恢复
restore_command = 'copy "E:\\20250101\\pg_wal\\%f" "%p"'
recovery_target_timeline = 'latest'
