IPP Software Navigation Tools IPP Links Communication Pan-STARRS Links

Changeset 29425


Ignore:
Timestamp:
Oct 14, 2010, 5:13:27 PM (16 years ago)
Author:
watersc1
Message:

Majority of balance code looks good. Will do a few more tests.

File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/Nebulous-Server/bin/neb-admin

    r24632 r29425  
    2727    $limit,
    2828    $pending,
     29    $balance,
     30    $balance_N_sources,
     31    $balance_M_destinations,
    2932    $removal,
    3033    $verbose,
     
    4245    'pass|p=s'              => \$dbpass,
    4346    'pendingreplicate|r'    => \$pending,
    44     'pendingremoval'        => \$removal,
     47    'pendingbalance|b'      => \$balance,
     48    'balancesources|N=s'      => \$balance_N_sources,
     49    'balancedestinations|M=s' => \$balance_M_destinations,
     50#    'pendingremoval'        => \$removal,
    4551    'so_id_start=i'         => \$so_id_start,
    4652    'so_id_range=i'         => \$so_id_range,
     
    5460pod2usage( -msg => "--limit is meaningless without --pendingreplicate",
    5561        -exitval => 2 )
    56     if defined $limit and not defined $pending;
     62    if defined $limit and not (defined $pending or defined $balance);
    5763pod2usage( -msg => "no operation specified", -exitval => 2 )
    58     unless defined $pending or defined $removal;
    59 
     64    unless defined $pending or defined $balance;
     65pod2usage( -msg => "--pendingbalance needs --balancesources and --balancedestinations options",
     66           -exitval => 2)
     67    if defined $balance and not (defined $balance_N_sources or defined $balance_M_destinations);
    6068# set default limit to 5
    6169$limit ||= 5;
     
    8492} elsif ($removal) {
    8593    removal();
     94} elsif ($balance) {
     95    balance();
    8696} else {
    8797    die "THIS SHOULD NOT HAPPEN";
     
    137147            AND so.so_id <  $so_id_end
    138148        GROUP BY so_id
    139         HAVING available_instances < instances OR instances < copies
     149        HAVING available_instances != instances OR instances != copies
    140150        LIMIT $limit"
    141151    );
     152
    142153    $query->execute;
    143 
    144 #    $dbh->do("DROP TABLE IF EXISTS mymountedvol");
    145154
    146155    my @rows;
     
    168177        my $vol_name = $obj->{volume_name};
    169178        my $vol_host = $obj->{volume_host};
    170         my $available = $obj->{available_instances} || 0;
     179        my $available = $obj->{available_instances} || 0;
    171180        my $need_recovery = $obj->{need_recovery};
    172181        my $recoverable = $obj->{recoverable};
     
    189198
    190199        my $need = $copies - $available;
    191         $need = 0 if $need < 0;
    192 
     200        my $cmd = 'neb-stat';
     201#        $need = 0 if $need < 0;
    193202        next unless $need;
     203
     204        if ($need > 0) {
     205            $cmd = 'neb-replicate';
     206        }
     207        elsif ($need < 0) {
     208            $cmd = 'neb-cull';
     209        }
    194210
    195211        my %md = (
    196212            key         => $key,
     213            command     => $cmd,
    197214            need_copies => $need,
    198215            volume_name => $vol_name,
    199216            volume_host => $vol_host,
     217
     218#           has         => $has,
     219            available   => $available,
     220            xattr_copies      => $copies,
     221#           recoverable => $recoverable,
     222#           need_recovery => $need_recovery,
     223           
    200224        );
    201 
     225#       print "$key $cmd $need $vol_name $vol_host\n";
    202226        print_metadata("replicatePending", \%md);
     227        print "\n";
     228    }
     229
     230    # use a different exit status if we hit the limit (likely more files pending)
     231    if ($Npending == $limit) {
     232        exit 1;
     233    }
     234    exit 0;
     235}
     236
     237sub balance
     238{
     239# so_id, ext_id, instances, available_instances, need_recovery, recoverable
     240# XXX don't remove the temp table code -- testing w/o it
     241#    $dbh->do("CREATE TEMPORARY TABLE mymountedvol LIKE mountedvol");
     242#    $dbh->do("INSERT INTO mymountedvol SELECT * FROM mountedvol");
     243
     244    if (not defined $so_id_start) { $so_id_start = 0; }
     245    if (not defined $so_id_range) { $so_id_range = 100000; }
     246    my $so_id_end = $so_id_start + $so_id_range;
     247
     248    # XXX check if so_id_start is beyond MAX(so_id): if so, exit with exit status 10
     249    {
     250        my $query = $dbh->prepare("SELECT MAX(so_id) from storage_object");
     251        $query->execute;
     252        my $answer = $query->fetchrow_arrayref;
     253        my $max_so_id = $$answer[0];
     254        $query->finish;
     255
     256        if ($so_id_start > $max_so_id) {
     257            print STDERR "at end of so_id range, reset please\n";
     258            exit 10;
     259        }
     260    }
     261
     262    # Calculate the average disk usage
     263    my $average = 0;
     264    my $avg_query = $dbh->prepare(
     265        "select sum(used)/sum(total) AS average from mountedvol WHERE available = 1 AND allocate = 1"
     266        );
     267    $avg_query->execute();
     268    while (my $row = $avg_query->fetchrow_hashref) {
     269        $average = $row->{average};
     270    }
     271    $avg_query->finish;
     272    print STDERR "average: $average\n";
     273    if ($average == 0) {
     274        exit 1;
     275    }
     276    # I truly am sorry for this statement.
     277    my $query = $dbh->prepare(
     278        "
     279SELECT * FROM (
     280 -- U Randomize the list of all possible source/destination matches,then group by so_id to select one at random
     281 SELECT T.*,volume.cab_id AS source_cab_id,volume.name AS source_name,volume.host AS source_host,
     282        destination.vol_id AS destination_vol_id,destination.cab_id AS destination_cab_id,
     283        destination.name AS destination_name,destination.host AS destination_host FROM (
     284  -- V Ensure that the copy we found on the source volume is the second copy instance
     285  SELECT K.vol_id AS here,K.ins_id,K.so_id,ext_id,value AS user_copies,MAXins_id,instance.vol_id AS there FROM (
     286   -- W Determine what the second copy instance is
     287   SELECT V.*,MAX(instance.ins_id) AS MAXins_id FROM (
     288    -- X Determine which hosts have instances of an object
     289    SELECT vol_id,ins_id,so_id,ext_id,value FROM
     290    storage_object JOIN storage_object_xattr USING(so_id) JOIN instance USING(so_id)
     291    WHERE vol_id IN (
     292     -- Y Extra select for debugging purposes
     293     SELECT vol_id FROM (
     294      -- Z Ran hosts by R (need to be a source) and return top N
     295      SELECT mountedvol.vol_id,mountedvol.name,mountedvol.available,mountedvol.allocate,total,used,
     296             (used / total) AS D,total * ((used / total) - $average ) AS R,  -- average
     297             cab_id FROM
     298      mountedvol JOIN volume USING(vol_id)
     299      WHERE mountedvol.available = 1 AND mountedvol.allocate = 1
     300      ORDER BY R DESC LIMIT $balance_N_sources                                            -- N
     301      ) AS ranked_sources
     302      -- Z End
     303     )
     304     -- Y End
     305    AND name = 'user.copies' AND value >= 2
     306    AND so_id >= $so_id_start                                  -- so_id_start
     307    AND so_id <  $so_id_end                                    -- so_id_end
     308    LIMIT $limit                                               -- limit
     309   ) AS V -- volumes that host a copy
     310   -- X End
     311  LEFT OUTER JOIN instance USING(so_id) GROUP BY so_id
     312  ) AS K -- copies that are the second copy
     313  -- W End
     314 JOIN instance ON MAXins_id = instance.ins_id GROUP BY so_id
     315 ) AS T -- matched copies that I know the second copy is on my source volume
     316 -- V End
     317 JOIN volume on T.here = volume.vol_id RIGHT JOIN (
     318  -- Y2 Chose a random destination from the list
     319  SELECT vol_id,cab_id,name,host FROM (
     320   -- Z2 Reverse rank hosts by R and return top M
     321   SELECT mountedvol.vol_id,mountedvol.name,mountedvol.host,mountedvol.available,mountedvol.allocate,total,used,
     322          (used / total) AS D,total * ((used / total) - $average ) AS R,  -- average
     323          cab_id FROM
     324   mountedvol JOIN volume USING(vol_id)
     325   WHERE mountedvol.available = 1 AND mountedvol.allocate = 1
     326   ORDER BY R ASC LIMIT $balance_M_destinations                                               -- M
     327  ) AS ranked_destinations
     328  -- Z2 End
     329 ORDER BY RAND()
     330 ) AS destination
     331 -- Y2 End
     332 ON destination.cab_id != volume.cab_id
     333 WHERE here = there
     334 ORDER BY RAND()
     335) AS results
     336-- U End
     337GROUP BY so_id
     338"    );
     339
     340    $query->execute();
     341                   
     342                   
     343
     344    my @rows;
     345    while (my $row = $query->fetchrow_hashref) {
     346        push @rows, $row;       
     347    }
     348    $query->finish;
     349
     350    print STDERR "No rows found\n" unless scalar @rows;
     351    exit unless scalar @rows;
     352   
     353    # compare number of responses to limit below
     354    my $Npending = @rows;
     355
     356    print "balancePending MULTI\n\n";
     357
     358    foreach my $obj (@rows) {
     359        if (defined $verbose) {
     360            require Data::Dumper;
     361            print Data::Dumper::Dumper($obj);
     362        }
     363       
     364
     365        my $here = $obj->{here};
     366        my $there = $obj->{there};
     367        my $ins_id = $obj->{ins_id};
     368        my $max_ins_id = $obj->{MAXins_id};
     369       
     370        my $so_id = $obj->{so_id};
     371        my $key   = $obj->{ext_id};
     372        my $copies = $obj->{user_copies};
     373
     374        my $source_vol_id = $obj->{here};
     375        my $source_cab_id = $obj->{source_cab_id};
     376        my $source_name   = $obj->{source_name};
     377        my $source_host   = $obj->{source_host};
     378
     379        my $destination_vol_id = $obj->{destination_vol_id};
     380        my $destination_cab_id = $obj->{destination_cab_id};
     381        my $destination_name   = $obj->{destination_name};
     382        my $destination_host   = $obj->{destination_host};
     383       
     384        unless ($here == $there) { next; }
     385        unless ($ins_id == $max_ins_id) { next; }
     386        unless ($source_cab_id != $destination_cab_id) { next; }
     387       
     388        my %md = (
     389            key           => $key,
     390            copies        => $copies,
     391            so_id         => $so_id,
     392            source_vol_id => $source_vol_id,
     393            source_cab_id => $source_cab_id,
     394            source_name   => $source_name,
     395            source_host   => $source_host,
     396            destination_vol_id => $destination_vol_id,
     397            destination_cab_id => $destination_cab_id,
     398            destination_name   => $destination_name,
     399            destination_host   => $destination_host,
     400#             key         => $key,
     401#           command     => $cmd,
     402#             need_copies => $need,
     403#             volume_name => $vol_name,
     404#             volume_host => $vol_host,
     405
     406# #         has         => $has,
     407#           available   => $available,
     408#           xattr_copies      => $copies,
     409# #         recoverable => $recoverable,
     410# #         need_recovery => $need_recovery,
     411           
     412        );
     413#       print "$key $cmd $need $vol_name $vol_host\n";
     414        print_metadata("balancePending", \%md);
    203415        print "\n";
    204416    }
Note: See TracChangeset for help on using the changeset viewer.