Changeset 367

Show
Ignore:
Timestamp:
08/23/06 23:11:55 (2 years ago)
Author:
bradfitz
Message:

fix race, and don't poll for checker status every 2 seconds. change
to 15. and use new Util::every() feature to not sleep 15 when we're
making progress.

Files:

Legend:

Unmodified
Added
Removed
Modified
Copied
Moved
  • branches/server-newrepl/lib/MogileFS/Worker/Checker.pm

    r365 r367  
    3535    my ($run_count, $total_time, $total_done) = (0, 0, 0); 
    3636 
    37     every(2, sub { 
     37    every(15.0, sub { 
     38        my $sleep_set = shift; 
     39 
    3840        $self->parent_ping; 
    3941 
     
    129131        print "limit=$limit, highest=$highest_fid, total=$total_already\n"; 
    130132        if ($limit > 0) { 
    131             $dbh->do(qq{ 
    132                 INSERT INTO fsck (fid, nextcheck) 
     133            my $rv = $dbh->do(qq{ 
     134                INSERT IGNORE INTO fsck (fid, nextcheck) 
    133135                    SELECT fid, 0 FROM file WHERE fid > ? ORDER BY fid LIMIT $limit 
    134136            }, undef, $highest_fid); 
    135  
    136             # toss an error if we had one, but don't exit because we want to do the next block 
    137             # regardless.  that ensures that if we do get an error such as duplicate key because 
    138             # of the following race condition, we only see it once. 
    139             error("database error fetching new rows: " . $dbh->errstr) if $dbh->err; 
    140  
    141             # this is a bit racy, but it doesn't matter since it's kinda irrelevant what the 
    142             # value gets set to.  this is an optimization, so we just try to get it mostly right. 
    143             my $highest = $dbh->selectrow_array('SELECT MAX(fid) FROM fsck'); 
    144             Mgd::set_server_setting('fsck_highest_fid_checked', $highest||0); 
     137            return error("database error fetching new rows: " . $dbh->errstr) if $dbh->err; 
     138 
     139            # this value will usually be correct, but it could be zero/undef already 
     140            # if another process races us to it and deletes them all.  which is why 
     141            # in the next step, we take the max of this and our old window position 
     142            # plus the number of rows we inserted (which makes the window always make 
     143            # some progress in the case of a race, never resetting forever to zero) 
     144            my $max_fsck_fid = $dbh->selectrow_array('SELECT MAX(fid) FROM fsck'); 
     145            my $min_progress = $highest_fid + $rv; 
     146 
     147            # the race buster:  (keeps window moving in race described above) 
     148            my $new_max      = $max_fsck_fid > $min_progress ? $max_fsck_fid : $min_progress; 
     149 
     150            Mgd::set_server_setting('fsck_highest_fid_checked', $new_max || 0); 
     151            $sleep_set->(0); # don't sleep in next round. 
    145152        } 
    146153    });