@@ -46,7 +46,14 @@ PostgresNode - class representing PostgreSQL server instance
4646 or print "timed out";
4747
4848 # Do an online pg_basebackup
49- my $ret = $node->backup('testbackup');
49+ my $ret = $node->backup('testbackup1');
50+
51+ # Take a backup of a running server
52+ my $ret = $node->backup_fs_hot('testbackup2');
53+
54+ # Take a backup of a stopped server
55+ $node->stop;
56+ my $ret = $node->backup_fs_cold('testbackup3')
5057
5158 # Restore it to create a new independent node (not a replica)
5259 my $replica = get_new_node('replica');
@@ -448,11 +455,11 @@ sub append_conf
448455
449456=item $node->backup(backup_name)
450457
451- Create a hot backup with pg_basebackup in $node->backup_dir,
452- including the transaction logs. xlogs are fetched at the
453- end of the backup, not streamed.
458+ Create a hot backup with B< pg_basebackup > in subdirectory B< backup_name > of
459+ B<< $node->backup_dir >> , including the transaction logs. Transaction logs are
460+ fetched at the end of the backup, not streamed.
454461
455- You'll have to configure a suitable max_wal_senders on the
462+ You'll have to configure a suitable B< max_wal_senders > on the
456463target server since it isn't done by default.
457464
458465=cut
@@ -464,11 +471,86 @@ sub backup
464471 my $port = $self -> port;
465472 my $name = $self -> name;
466473
467- print " # Taking backup $backup_name from node \" $name \"\n " ;
474+ print " # Taking pg_basebackup $backup_name from node \" $name \"\n " ;
468475 TestLib::system_or_bail(" pg_basebackup -D $backup_path -p $port -x" );
469476 print " # Backup finished\n " ;
470477}
471478
479+ =item $node->backup_fs_hot(backup_name)
480+
481+ Create a backup with a filesystem level copy in subdirectory B<backup_name > of
482+ B<< $node->backup_dir >> , including transaction logs.
483+
484+ Archiving must be enabled, as B<pg_start_backup() > and B<pg_stop_backup() > are
485+ used. This is not checked or enforced.
486+
487+ The backup name is passed as the backup label to B<pg_start_backup() > .
488+
489+ =cut
490+
491+ sub backup_fs_hot
492+ {
493+ my ($self , $backup_name ) = @_ ;
494+ $self -> _backup_fs($backup_name , 1);
495+ }
496+
497+ =item $node->backup_fs_cold(backup_name)
498+
499+ Create a backup with a filesystem level copy in subdirectory B<backup_name > of
500+ B<< $node->backup_dir >> , including transaction logs. The server must be
501+ stopped as no attempt to handle concurrent writes is made.
502+
503+ Use B<backup > or B<backup_fs_hot > if you want to back up a running server.
504+
505+ =cut
506+
507+ sub backup_fs_cold
508+ {
509+ my ($self , $backup_name ) = @_ ;
510+ $self -> _backup_fs($backup_name , 0);
511+ }
512+
513+
514+ # Common sub of backup_fs_hot and backup_fs_cold
515+ sub _backup_fs
516+ {
517+ my ($self , $backup_name , $hot ) = @_ ;
518+ my $backup_path = $self -> backup_dir . ' /' . $backup_name ;
519+ my $port = $self -> port;
520+ my $name = $self -> name;
521+
522+ print " # Taking filesystem backup $backup_name from node \" $name \"\n " ;
523+
524+ if ($hot )
525+ {
526+ my $stdout = $self -> safe_psql(' postgres' ,
527+ " SELECT * FROM pg_start_backup('$backup_name ');" );
528+ print " # pg_start_backup: $stdout \n " ;
529+ }
530+
531+ RecursiveCopy::copypath(
532+ $self -> data_dir,
533+ $backup_path ,
534+ filterfn => sub {
535+ my $src = shift ;
536+ return ($src ne ' pg_log' and $src ne ' postmaster.pid' );
537+ });
538+
539+ if ($hot )
540+ {
541+ # We ignore pg_stop_backup's return value. We also assume archiving
542+ # is enabled; otherwise the caller will have to copy the remaining
543+ # segments.
544+ my $stdout = $self -> safe_psql(' postgres' ,
545+ ' SELECT * FROM pg_stop_backup();' );
546+ print " # pg_stop_backup: $stdout \n " ;
547+ }
548+
549+ print " # Backup finished\n " ;
550+ }
551+
552+
553+
472554=pod
473555
474556=item $node->init_from_backup(root_node, backup_name)
0 commit comments