Changeset 162 for trunk

Show
Ignore:
Timestamp:
06/04/10 22:38:30 (4 years ago)
Author:
depesz
Message:

Add workaround for PostgreSQL 8.2 and 8.3, which do not wait for .backup "wal segment" to be archived before returning control from pg_stop_backup() call.

Files:

Legend:

Unmodified
Added
Removed
Modified
Copied
Moved
  • trunk/omnipitr/lib/OmniPITR/Program/Backup/Master.pm

    r158 r162  
    3636 
    3737    $self->stop_pg_backup(); 
     38    $self->wait_for_final_xlog_and_remove_dst_backup(); 
    3839    $self->compress_xlogs(); 
    3940 
     
    4445 
    4546    return; 
     47} 
     48 
     49=head1 wait_for_final_xlog_and_remove_dst_backup() 
     50 
     51In PostgreSQL < 8.4 pg_stop_backup() finishes before .backup "wal segment" is archived. 
     52 
     53So we need to wait till it appears in backup xlog destination before we can remove symlink. 
     54 
     55=cut 
     56 
     57sub wait_for_final_xlog_and_remove_dst_backup { 
     58    my $self = shift; 
     59 
     60    my $search_in_dir = $self->{ 'xlogs' }; 
     61 
     62    my $re     = $self->{ 'stop_backup_filename_re' }; 
     63    my $waited = 0; 
     64    while ( 1 ) { 
     65        opendir( my $dir, $search_in_dir ) or $self->clean_and_die( 'Cannot open %s for scanning: %s', $search_in_dir, $OS_ERROR ); 
     66        my @matching = grep { $_ =~ $re } readdir $dir; 
     67        closedir $dir; 
     68        last if 0 < scalar @matching; 
     69        $waited++; 
     70        $self->clean_and_die( 'Waited 10 minutes for file matching %s, but it did not appear. Something is wrong. No sense in waiting longer.', $re ) if 600 < $waited; 
     71        sleep 1; 
     72    } 
     73 
     74    $self->log->log( '.backup file arrived after %u seconds.', $waited ) if $self->verbose; 
     75 
     76    unlink( $self->{ 'xlogs' } ); 
    4677} 
    4778 
     
    353384    my $subdir = basename( $self->{ 'data-dir' } ); 
    354385 
    355     unlink( $self->{ 'xlogs' } ); 
    356  
    357386    return; 
    358387} 
     
    386415    $status->{ 'stdout' } =~ s/\s*\z//; 
    387416    $self->log->log( q{pg_start_backup('omnipitr') returned %s.}, $status->{ 'stdout' } ); 
    388  
    389     $self->{ 'pg_start_backup_done' } = 1; 
     417    $self->clean_and_die( 'Ouput from pg_start_backup is not parseable?!' ) unless $status->{ 'stdout' } =~ m{\A([0-9A-F]+)/([0-9A-F]{1,8})\z}; 
     418 
     419    my ( $part_1, $part_2 ) = ( $1, $2 ); 
     420    $part_2 =~ s/(.{1,6})\z//; 
     421    my $part_3 = $1; 
     422 
     423    my $expected_filename_suffix = sprintf '%08s%08s.%08s.backup', $part_1, $part_2, $part_3; 
     424    my $backup_filename_re = qr{\A[0-9A-F]{8}\Q$expected_filename_suffix\E\z}; 
     425 
     426    $self->{ 'stop_backup_filename_re' } = $backup_filename_re; 
     427    $self->{ 'pg_start_backup_done' }    = 1; 
    390428 
    391429    return;