Postgresql@H_502_2@提供了三种备份和恢复的方式@H_502_2@:@H_502_2@sql@H_502_2@ dump@H_502_2@、@H_502_2@文件系统复制@H_502_2@和@H_502_2@联机热备份@H_502_2@。 @H_502_2@每一种备份方式都有自己的优点和缺点,下面将详细介绍。
9.1 sql Dump
@H_502_2@这种备份方式产生一个文本文件,里面包含创建各种数据库对象的@H_502_2@sql@H_502_2@语句和每个表中的数据。另外,表上创建的索引中的数据不会被导出,只会导出索引的定义信息。在恢复数据库的时候,索引会被重建。可以使用数据库提供的工具@H_502_2@pg_dumpall@H_502_2@和@H_502_2@pg_dump@H_502_2@来进行备份。@H_502_2@pg_dumpall@H_502_2@会备份一个数据库集群中的所有信息和数据。@H_502_2@pg_dump@H_502_2@只备份数据库集群中的某个数据库的数据,它不会导出角色和表空间相关的信息,因为这些信息是整个数据库集群共用的,不属于某个单独的数据库。@H_502_2@pg_dump@H_502_2@的基本用法如下:
@H_502_2@pg_dump @H_502_2@数据库名@H_502_2@ > @H_502_2@备份文件名
@H_502_2@pg_dump@H_502_2@将结果写到标准输出中,可以用操作系统的重定向命令将结果写到文件中。
@H_502_2@
@H_502_2@可以在运行数据库的机器上执行@H_502_2@pg_dump@H_502_2@命令,也可以在其它的机器上执行@H_502_2@pg_dump@H_502_2@命令。 可以使用选项@H_502_2@-h@H_502_2@和@H_502_2@-p@H_502_2@来指定运行数据库的主机名和数据库监听的端口。例如:
@H_502_2@pg_dump -h db_server1 -p 5432
product > backup_file
@H_502_2@该命令连接机器@H_502_2@db_server1@H_502_2@上在端口@H_502_2@5432@H_502_2@处监听的数据库,将数据库@H_502_2@product@H_502_2@的数据备份到文件@H_502_2@backup_file@H_502_2@中。如果@H_502_2@pg_dump@H_502_2@命令没有使用@H_502_2@-h@H_502_2@和@H_502_2@-p@H_502_2@选项,将使用环境变量@H_502_2@PGHOST@H_502_2@的值作为机器名,使用环境变量@H_502_2@PGPORT@H_502_2@的值作为数据库的端口。如果用户没有定义环境变量@H_502_2@PGHOST@H_502_2@,默认使用本机名作为运行数据库的机器名。
@H_502_2@
@H_502_2@默认的情况下,@H_502_2@pg_dump@H_502_2@使用当前的操作系统用户作为连接数据库时使用的用户。可以使用选项@H_502_2@-U@H_502_2@或者设置环境变量@H_502_2@PGUSER@H_502_2@来指定连接数据库时使用的用户名。例如:
@H_502_2@pg_dump -U liming -h db_server1 -p 5432
product > backup_file
@H_502_2@该命令使用用户@H_502_2@liming@H_502_2@连接机器@H_502_2@db_server1@H_502_2@上在端口@H_502_2@5432@H_502_2@处监听的数据库,将数据库@H_502_2@product@H_502_2@的数据备份到文件@H_502_2@backup_file@H_502_2@中。
@H_502_2@一般情况下,应该使用超级用户连接数据库进行备份操作,因为超级用户可以访问数据库中的任何信息。使用普通数据用户连接数据库,有些表可能无法访问。
@H_502_2@运行@H_502_2@pg_dump@H_502_2@时,数据可以正常地执行其它操作。但@H_502_2@ALTER TABLE@H_502_2@这类修改数据库对象定义的操作会受到影响,可能会长时间处于等待状态而无法执行,所以在运行@H_502_2@pg_dump@H_502_2@命令时,不要在数据库中运行修改数据库对象定义的操作。
@H_502_2@
@H_502_2@另外要注意的是,如果数据库中有些表使用@H_502_2@OID@H_502_2@来实现外键约束,应当在备份数据库时同时备份表的@H_502_2@OID@H_502_2@信息,使用@H_502_2@pg_dump@H_502_2@时加上选项–@H_502_2@o@H_502_2@即可达到这个目的。
9.1.1
恢复数据库
@H_502_2@pg_dump@H_502_2@创建的备份文件可以被工具@H_502_2@psql@H_502_2@识别。因此可以使用@H_502_2@psql@H_502_2@来读取@H_502_2@pg_dump@H_502_2@创建的备份文件,实现恢复数据库的功能。例如:
@H_502_2@psql @H_502_2@dbname@H_502_2@ < @H_502_2@backup_file
@H_502_2@psql@H_502_2@后面的参数@H_502_2@dbname@H_502_2@指定的数据库必须已经存在。如果不存在,用户应当先创建@H_502_2@dbname@H_502_2@指定的数据库,然后再执行恢复数据的命令。@H_502_2@psql@H_502_2@也支持和@H_502_2@pg_dump@H_502_2@一样的命令行选项,如@H_502_2@-h@H_502_2@和@H_502_2@-p@H_502_2@等。创建数据库@H_502_2@dbname@H_502_2@时,必须使用@H_502_2@template0@H_502_2@作为模板数据库,可以使用工具@H_502_2@createdb@H_502_2@创建数据库,也可以在@H_502_2@psql@H_502_2@中执行@H_502_2@sql@H_502_2@命令@H_502_2@create database@H_502_2@来创建数据库。下面是两个实例:
@H_502_2@(@H_502_2@1@H_502_2@)@H_502_2@createdb -T template0 dbname
@H_502_2@(@H_502_2@2@H_502_2@)@H_502_2@create database @H_502_2@dbname @H_502_2@template=@H_502_2@template0
@H_502_2@
@H_502_2@另外,在执行恢复数据的操作以前,那些拥有数据库备份中的数据库对象或则对这些对象有访问权限的数据库的用户必须已经在数据库中存在,否则,恢复数据库以后,数据库备份中的数据库对象的所有者会发生改变。
@H_502_2@
@H_502_2@默认的情况下,@H_502_2@psql@H_502_2@命令会一直执行下去直到结束,即使中间遇到@H_502_2@sql@H_502_2@错误,恢复操作也会继续执行。如果想让@H_502_2@psql@H_502_2@在执行过程中遇到错误以后,停止恢复操作,可以在执行恢复操作以前,在@H_502_2@psql@H_502_2@中运行下面的命令:
@H_502_2@\set ON_ERROR_STOP
@H_502_2@
@H_502_2@如果@H_502_2@psql@H_502_2@在执行过程中遇到错误,则只有一部分数据被正确地恢复,这时被恢复数据库中的数据是不完整的。@H_502_2@psql@H_502_2@提供了另外一种恢复模式,在这种模式下,一旦恢复操作执行过程中遇到任何错误,已经恢复的数据都会自动从数据库中被删除。可以使用@H_502_2@psql@H_502_2@的命令行选项@H_502_2@-l@H_502_2@或@H_502_2@--single-transaction@H_502_2@来打开这种模式。
@H_502_2@在恢复操作结束以后,应该使用@H_502_2@ANALYZE@H_502_2@命令来重新收集查询优化器统计数据。
9.1.2
使用pg_dumpall
@H_502_2@
@H_502_2@pg_dump@H_502_2@只备份数据库集群中的某个数据库的数据,它不会导出角色和表空间相关的信息。@H_502_2@pg_dumpall@H_502_2@则可以导出整个数据库集群中所有的数据库中@H_502_2@的@H_502_2@数据,同时也会导出角色、用户和表空间的定义信息。使用@H_502_2@pg_dumpall@H_502_2@的一般命令格式如下:
@H_502_2@pg_dumpall > @H_502_2@backup_file
@H_502_2@pg_dumpall@H_502_2@也支持和@H_502_2@pg_dump@H_502_2@一样的命令行选项,如@H_502_2@-h@H_502_2@和@H_502_2@-p@H_502_2@等。同样可以使用@H_502_2@psql@H_502_2@来从@H_502_2@pg_dumpall@H_502_2@创建的备份文件中恢复数据库。应该使用数据库超级用户来进行恢复数据库的操作。命令格式如下:
@H_502_2@psql -f @H_502_2@backup_file@H_502_2@ postgres
@H_502_2@pg_dumpall@H_502_2@在执行的过程中,用postgres作为用户名来连接数据库。系统自动创建的数据库postgres中的内容也会被导出来,数据库@H_502_2@template0@H_502_2@和@H_502_2@template@H_502_2@1@H_502_2@中的内容不会被导出来。
9.1.3
大型数据库的备份和恢复
@H_502_2@如果数据库的规模比较大,产生的备份文件的大小超级了操作系统能够允许的单个文件的大小的最大值,可以使用压缩和将备份文件分成对个部分这两个方法来解决这个问题。
@H_502_2@(@H_502_2@1@H_502_2@)采用压缩的方法,可以采用操作系统提供的任何一种压缩工具来实现,常用的是@H_502_2@gzip@H_502_2@。例如:
@H_502_2@pg_dump @H_502_2@dbname@H_502_2@ | gzip > @H_502_2@filename@H_502_2@.gz
@H_502_2@恢复时,使用下面的命令:
@H_502_2@gunzip -c @H_502_2@filename@H_502_2@.gz | psql @H_502_2@dbname
@H_502_2@也可以使用下面的命令来恢复数据库:
@H_502_2@cat @H_502_2@filename@H_502_2@.gz | gunzip | psql @H_502_2@dbname
@H_502_2@(@H_502_2@2@H_502_2@)将备份文件分成多个部分。使用操作系统的工具@H_502_2@split@H_502_2@来实现。例如@H_502_2@:
@H_502_2@pg_dump @H_502_2@dbname@H_502_2@ | split -b 1m - @H_502_2@filename
@H_502_2@在这个例子中,数据库备份被分成多个大小为@H_502_2@1MB@H_502_2@的文件。
@H_502_2@使用下面的命令进行恢复操作:
@H_502_2@cat @H_502_2@filename@H_502_2@* | psql @H_502_2@dbname
@H_502_2@(@H_502_2@3@H_502_2@)使用@H_502_2@pg_dump@H_502_2@自带的压缩功能。这种方法产生的备份文件也是被压缩的,同第一种方法相比,它有一个优点,就是可以只恢复备份文件中的某个表的数据。这种方法的命令格式如下,就是增加了选项@H_502_2@-Fc@H_502_2@:
@H_502_2@pg_dump -Fc @H_502_2@dbname@H_502_2@ > @H_502_2@filename
@H_502_2@不能使用@H_502_2@psql@H_502_2@命令恢复用这种方法备份的数据,必须使用@H_502_2@pg_restore@H_502_2@来进行恢复操作。命令格式如下:
@H_502_2@pg_restore -d @H_502_2@dbname
@H_502_2@filename
@H_502_2@
@H_502_2@对于非常大的数据库,可以将压缩与分割的方法同时使用(同时使用第一种和第二种方法,或者同时使用第二种和第三种方法)。
9.2文件系统复制@H_502_2@
@H_502_2@
@H_502_2@文件系统复制这种方法是直接复制所有的数据库文件,存放到其它的存储介质上。这是最简单的备份数据库的方法。可以使用操作系统的命令来完成备份,例如:
@H_502_2@tar -cf backup.tar /usr/local/pgsql/data
@H_502_2@
@H_502_2@复制数据文件以前,必须关闭数据库。这种备份方法产生的备份文件比较大,因为索引数据也会被备份。恢复数据库时只要把备份文件复制到存放数据文件的目录中即可。
9.3 联机热备份与归档恢复9.3.1
联机热备份
@H_502_2@进行联机热备份时,不用关闭数据库。数据库可以正常地执行其它操作。@H_502_2@如果要使联机热备份,数据库必须运行在归档模式下,将参数数据库@H_502_2@archive_mode@H_502_2@设为@H_502_2@on@H_502_2@,然后再将参数@H_502_2@archive_dir@H_502_2@设成一个启动数据库的操作系统用户有读写权限的目录,数据库就会运行在归档模式。要使这两个参数生效,必须重新启动数据库。
@H_502_2@
@H_502_2@进行联机热备份的步骤如下:
@H_502_2@(@H_502_2@1@H_502_2@)检查数据库是否运行在归档模式下。
@H_502_2@(@H_502_2@2@H_502_2@)用超级用户连接数据库(推荐使用@H_502_2@psql@H_502_2@),然后执行下面的命令:@H_502_2@
SELECT pg_start_backup('label');
@H_502_2@label@H_502_2@是一个字符串,用来确定创建的备份,可以选取一个有明显的含义的名字作为@H_502_2@label@H_502_2@。
@H_502_2@pg_start_backup@H_502_2@命令可能会执行比较长的时间才会结束,因为数据库会自动开始一个检查点操作。
@H_502_2@(@H_502_2@3@H_502_2@)使用操作系统命令@H_502_2@(@H_502_2@如@H_502_2@cp)@H_502_2@,将所有的数据库文件复制到其它的存储介质上。
@H_502_2@(@H_502_2@4@H_502_2@)执行下面的命令结束@H_502_2@备份操作@H_502_2@:
@H_502_2@SELECT pg_stop_backup();
@H_502_2@
@H_502_2@备份操作结束以后,会在@H_502_2@pg_xlog@H_502_2@子目录下产生一个备份@H_502_2@描述@H_502_2@文件,该文件以“@H_502_2@.backup@H_502_2@”结尾,例如@H_502_2@000000010000000000000000.004535C0.backup@H_502_2@。注意数据库归档进程会自动将备份操作产生的备份@H_502_2@描述@H_502_2@文件从@H_502_2@pg_xlog@H_502_2@子目录@H_502_2@复制@H_502_2@到存放归档事务日志的目录中(参数@H_502_2@archive_dir@H_502_2@指定的目录),如果在@H_502_2@pg_xlog@H_502_2@目录中找不到备份@H_502_2@描述@H_502_2@文件,应该在存放归档事务日志的目录中去寻找它。@H_502_2@恢复数据库的时候需要使用@H_502_2@备份@H_502_2@描述@H_502_2@文件@H_502_2@中的信息。@H_502_2@备份@H_502_2@描述@H_502_2@文件中存放有下列信息:
@H_502_2@(@H_502_2@1@H_502_2@)开始事务日志文件名。
@H_502_2@(@H_502_2@2@H_502_2@)结束事务日志文件名。
@H_502_2@(@H_502_2@3@H_502_2@)检查点位置。
@H_502_2@(@H_502_2@4@H_502_2@)备份操作开始的时间。
@H_502_2@(@H_502_2@5@H_502_2@)备份操作结束的时间。
@H_502_2@(@H_502_2@6@H_502_2@)备份的名字(就是@H_502_2@pg_start_backup@H_502_2@命令中指定的名字)。
@H_502_2@
@H_502_2@下面是一个备份@H_502_2@描述@H_502_2@文件的实例:
@H_502_2@START WAL LOCATION: 0/4535C0 (file 000000010000000000000000)
@H_502_2@STOP WAL LOCATION: 0/453A98 (file 000000010000000000000000)
@H_502_2@CHECKPOINT LOCATION: 0/4535C0
@H_502_2@START TIME: 2009-03-28 23:02:34 CST
@H_502_2@LABEL: b1
@H_502_2@STOP TIME: 2009-03-28 23:04:05 CST
@H_502_2@从该文件中可以看出备份操作开始的时间是@H_502_2@2009-03-28 23:02:34@H_502_2@,结束的时间是@H_502_2@2009-03-28 23:04:05@H_502_2@,备份的名字是@H_502_2@b1@H_502_2@,开始事务日志的名字是@H_502_2@ 000000010000000000000000@H_502_2@,结束事务日志的名字也是@H_502_2@ 000000010000000000000000@H_502_2@,检查点的位置是@H_502_2@0/4535C0@H_502_2@。
@H_502_2@从开始事务日志文件到结束事务日志文件之间的所有事务日志文件(包括这两个事务日志文件)必须被保存好,不能丢失,否则创建的数据库备份将是无效的,不能将数据库恢复到一个一致的状态。
@H_502_2@
@H_502_2@备份操作在执行的过程中会在数据文件目下产生一个名为backup_label的文件,该文件叫做备份标号文件。备份标号文件在备份操作结束以后会被系统自动删除。在执行上面的第三步操作的过程中,必须同时复制备份标号文件,因为恢复数据库的时候需要使用备份标号文件中的信息。
9.3.2
归档恢复@H_502_2@
@H_502_2@进行归档恢复以前,应该准备好一个名为@H_502_2@recovery.conf@H_502_2@的文件,该文件中包含一些恢复操作的配置参数,这些参数决定恢复操作如何进行。下面详细介绍这些参数:
@H_502_2@(@H_502_2@1@H_502_2@)@H_502_2@archive_log_dir
@H_502_2@该参数指定存放归事务日志的目录,所有需要的归档事务日志都应该存放在该目录中,系统在进行恢复操作时会自动从该目录中读取需要的事务日志文件。
@H_502_2@(@H_502_2@2@H_502_2@)@H_502_2@recovery_target_time
@H_502_2@该参数指定一个时间,恢复操作进行到该时间时会自动停止。该参数用来实现时间点恢复(@H_502_2@p@H_502_2@oint-In-Time Recovery@H_502_2@)。@H_502_2@recovery_target_time@H_502_2@和下面的@H_502_2@recovery_target_xid@H_502_2@只能指定一个。
@H_502_2@(@H_502_2@3@H_502_2@)@H_502_2@recovery_target_xid
@H_502_2@该参数指定一个事务@H_502_2@id@H_502_2@,恢复操作进行到该事务时会自动停止。@H_502_2@recovery_target_xid@H_502_2@和上面的@H_502_2@recovery_target_time@H_502_2@只能指定一个。
@H_502_2@(@H_502_2@4@H_502_2@)@H_502_2@recovery_target_inclusive
@H_502_2@该参数的值是@H_502_2@true@H_502_2@或@H_502_2@false@H_502_2@。默认值是@H_502_2@true@H_502_2@。它影响参数@H_502_2@recovery_target_time@H_502_2@和@H_502_2@recovery_target_xid@H_502_2@,如果它的值为@H_502_2@true@H_502_2@,恢复操作在指定的目标(时间或事务@H_502_2@ID@H_502_2@)以后停止,如果它的值为@H_502_2@false@H_502_2@,恢复操作在指定的目标以后停止。
@H_502_2@
@H_502_2@参数@H_502_2@archive_log_dir@H_502_2@必须出现在@H_502_2@recovery.conf@H_502_2@的文件中,其它的参数则是可选的,如果@H_502_2@recovery_target_xid@H_502_2@和@H_502_2@recovery_target_time@H_502_2@都没有被指定,则默认恢复到最后一个事务日志文件确定的数据库的最近的状态。如果想进行时间点恢复,应该指定参数@H_502_2@r@H_502_2@ecovery_target_time@H_502_2@。
@H_502_2@
@H_502_2@下面是一个@H_502_2@recovery.conf@H_502_2@文件的实例,所有的参数的值都必须用两个单引号引起来:
@H_502_2@archive_log_dir = '/home/yan/archive_log'
@H_502_2@recovery_target_time = '2004-07-14 22:39:00 EST'
@H_502_2@recovery_target_xid = '1100842'
@H_502_2@recovery_target_inclusive = 'true'
@H_502_2@
@H_502_2@下面介绍进行@H_502_2@归档@H_502_2@恢复的具体步骤:
(1)停止数据库服务器。将当前数据库备份到其它目录中。
(2)准备好@H_502_2@recovery.conf@H_502_2@文件,将所有恢复操作需要的归档事务日志都存放在参数@H_502_2@archive_log_dir@H_502_2@指定的目录中@H_502_2@,备份描述文件也必须被存放在@H_502_2@参数@H_502_2@archive_log_dir@H_502_2@指定的目录中。
@H_502_2@(3)将以前创建的数据库备份复制到数据文件目录中(必须与以前的数据文件目录相同)。如果数据库使用了表空间,请验证@H_502_2@pg_tblspc@H_502_2@子目录下面的每个符号链接是否有效。将准备好的@H_502_2@recovery.conf@H_502_2@文件存放到数据文件目录中。@H_502_2@编辑文件pg_hba.conf,不允许任何用户在恢复的过程中连接数据库。
@H_502_2@(4)
@H_502_2@确保@H_502_2@数据文件目录@H_502_2@中存在一个名为@H_502_2@backup_label@H_502_2@的文件@H_502_2@。删除@H_502_2@pg_xlog@H_502_2@子目录中的所有文件,重新在@H_502_2@pg_xlog@H_502_2@中创建一个名为@H_502_2@archive_status@H_502_2@的子目录。
@H_502_2@(5)启动数据库,数据库在启动以后将自动进行恢复操作,恢复操作成功完成以后,数据库将自动打开,进入正常的工作状态。恢复操作成功以后,系统会将文件@H_502_2@recovery.conf@H_502_2@重命名为@H_502_2@recovery.done@H_502_2@。
@H_502_2@(6)检查数据库中的内容是否正确。
@H_502_2@归档恢复成功结束以后,数据库会自动打开,进入正常的工作状态,可以开始响应用户的连接请求,应该修改pg_hba.conf文件,允许用户连接数据库。归档恢复成功结束以后,在数据库的运行日志中会有下面的提示信息:
@H_502_2@……
@H_502_2@日志: 00000: 归档恢复结束。
@H_502_2@
@H_502_2@
@H_502_2@文件@H_502_2@backup_label@H_502_2@在恢复操作执行结束以后会被自动重命名为backup_label.old。确定归档恢复成功以后,应该删除backup_label.old,因为它已经没有任何作用。
9.3.3
注意事项@H_502_2@
@H_502_2@进行归档恢复时,有下面几个注意事项:
@H_502_2@(1)哈希索引上面的操作没有被记录到事务日志中,归档恢复完成以后,必须对每个哈希索引执行@H_502_2@REINDEX@H_502_2@操作。
@H_502_2@(2)在创建数据库备份时不要修改模板数据库。
9.3.4
时间线(timeline)@H_502_2@
@H_502_2@时间线是@H_502_2@Postgresql@H_502_2@独有的概念。它是一个整数值,与归档恢复有关。在用@H_502_2@initdb@H_502_2@创建一个初始的数据库集群以后,该数据库集群的时间线是1。每进行一次归档恢复,就会产生一个新的时间线,新的时间线的值在上一个时间线的值的基础上加一。每次归档恢复完成以后,都会产生一个时间线历史文件,该文件以“@H_502_2@.history@H_502_2@”结尾,例如@H_502_2@00000002.history@H_502_2@。时间线历史文件首先被存放在@H_502_2@pg_xlog@H_502_2@目录中,@H_502_2@数据库归档进程以后会自动将时间线历史文件从@H_502_2@pg_xlog@H_502_2@子目录@H_502_2@复制@H_502_2@到存放归档事务日志的目录中(参数@H_502_2@archive_dir@H_502_2@指定的目录)。