Changeset 1339

Show
Ignore:
Timestamp:
11/03/09 05:04:29 (4 weeks ago)
Author:
robbat2
Message:

Allow regeneration of DB connections if we have given out too many
handles to the same connection.

Thanks to <victoriggy@…> for the idea and the original
implementation. Refactored extensively and max_requests renamed to
max_handles to better represent the functionality.

Location:
trunk/server
Files:
4 modified

Legend:

Unmodified
Added
Removed
  • trunk/server/CHANGES

    r1338 r1339  
     1        * Add 'max_handles' config option to restart a DB connection if there 
     2          are too many handles to it (victori). 
     3 
    14        * Close possibly invalid DB connections as we go out of scope 
    25          (victori). 
  • trunk/server/lib/MogileFS/Config.pm

    r1331 r1339  
    5959    $reaper_jobs, 
    6060    $monitor_jobs, 
     61    $max_handles, 
    6162    $min_free_space, 
    6263    $max_disk_age, 
     
    9495                             'default_mindevcount=i' => \$cmdline{default_mindevcount}, 
    9596                             'node_timeout=i' => \$cmdline{node_timeout}, 
     97                             'max_handles=i'  => \$cmdline{max_handles}, 
    9698                             'pidfile=s'      => \$cmdline{pidfile}, 
    9799                             'no_schema_check' => \$cmdline{no_schema_check}, 
     
    153155    $min_free_space = choose_value( 'min_free_space', 100 ); 
    154156    $max_disk_age   = choose_value( 'max_disk_age', 5 ); 
     157    $max_handles    = choose_value( 'max_handles', 0 ); 
    155158    $DEBUG          = choose_value( 'debug', $ENV{DEBUG} || 0 ); 
    156159    $pidfile        = choose_value( 'pidfile', "" ); 
  • trunk/server/lib/MogileFS/Store.pm

    r1338 r1339  
    2121sub new { 
    2222    my ($class) = @_; 
    23     return $class->new_from_dsn_user_pass(map { MogileFS->config($_) } qw(db_dsn db_user db_pass)); 
     23    return $class->new_from_dsn_user_pass(map { MogileFS->config($_) } qw(db_dsn db_user db_pass max_handles)); 
    2424} 
    2525 
    2626sub new_from_dsn_user_pass { 
    27     my ($class, $dsn, $user, $pass) = @_; 
     27    my ($class, $dsn, $user, $pass, $max_handles) = @_; 
    2828    my $subclass; 
    2929    if ($dsn =~ /^DBI:mysql:/i) { 
     
    4545        user   => $user, 
    4646        pass   => $pass, 
     47        max_handles => $max_handles, # Max number of handles to allow 
    4748        raise_errors => $subclass->want_raise_errors, 
    4849        slave_list_cachetime => 0, 
     
    5051        recheck_req_gen  => 0,  # incremented generation, of recheck of dbh being requested 
    5152        recheck_done_gen => 0,  # once recheck is done, copy of what the request generation was 
     53        handles_given => 0,     # amount of handles given out. 
    5254        server_setting_cache => {}, # value-agnostic db setting cache. 
    5355    }, $subclass; 
     
    250252sub dbh { 
    251253    my $self = shift; 
     254     
    252255    if ($self->{dbh}) { 
    253256        if ($self->{recheck_done_gen} != $self->{recheck_req_gen}) { 
     
    255258            $self->{recheck_done_gen} = $self->{recheck_req_gen}; 
    256259        } 
    257         return $self->{dbh} if $self->{dbh}; 
    258     } 
    259  
    260     $self->{dbh} = DBI->connect($self->{dsn}, $self->{user}, $self->{pass}, { 
    261         PrintError => 0, 
    262         AutoCommit => 1, 
    263         InactiveDestroy => 1, 
    264         # FUTURE: will default to on (have to validate all callers first): 
    265         RaiseError => ($self->{raise_errors} || 0), 
    266     }) or 
    267         die "Failed to connect to database: " . DBI->errstr; 
    268     $self->post_dbi_connect; 
     260         
     261        # If we have exceeded the number of handles/requests-for-dbh, then it 
     262        # is time to reset for a new connection. Reported to give a large 
     263        # performance boost on Solaris with Postgresql. 
     264        if ($self->{dbh} && 
     265                $self->{max_handles} && 
     266                $self->{max_handles} > 0 &&  
     267                $self->{handles_given} > $self->{max_handles}) { 
     268                        # TODO: Not sure about this disconnect. We probably want existing 
     269                        # users of the connection to continue to do so. 
     270                        $self->{dbh}->disconnect(); 
     271            $self->{dbh} = undef; 
     272            $self->{handles_given} = 0; 
     273        } 
     274    } 
     275 
     276    unless($self->{dbh}) { 
     277        $self->{dbh} = DBI->connect($self->{dsn}, $self->{user}, $self->{pass}, { 
     278            PrintError => 0, 
     279            AutoCommit => 1, 
     280            InactiveDestroy => 1, 
     281            # FUTURE: will default to on (have to validate all callers first): 
     282            RaiseError => ($self->{raise_errors} || 0), 
     283        }) or 
     284            die "Failed to connect to database: " . DBI->errstr; 
     285        $self->post_dbi_connect; 
     286    } 
     287    $self->{handles_given} += 1; 
    269288    return $self->{dbh}; 
    270289} 
  • trunk/server/mogdbsetup

    r1282 r1339  
    44use lib 'lib'; 
    55use MogileFS::Store; 
     6use MogileFS::Config; 
    67 
    78# Rename binary in process list to make init scripts saner 
     
    108109$sclass->on_confirm(\&confirm); 
    109110 
     111MogileFS::Config->load_config; 
     112 
    110113my $sto = $sclass->new_from_mogdbsetup( 
    111114                                       map { $_ => $args{$_} }