IPP Software Navigation Tools IPP Links Communication Pan-STARRS Links

Changeset 29519


Ignore:
Timestamp:
Oct 21, 2010, 2:48:03 PM (16 years ago)
Author:
eugene
Message:

merge from trunk

File:
1 edited

Legend:

Unmodified
Added
Removed
  • branches/eam_branches/ipp-20100823/Nebulous-Server/bin/neb-admin

    r24632 r29519  
    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);
    203227        print "\n";
     
    205229
    206230    # use a different exit status if we hit the limit (likely more files pending)
    207     if ($Npending == $limit) {
    208         exit 1;
    209     }
    210     exit 0;
     231    # This is a better way to do this.
     232    if ($Npending == 0) {
     233        exit 0;
     234    }
     235    else {
     236        exit 1;
     237    }
     238
     239#     if ($Npending == $limit) {
     240#         exit 1;
     241#     }
     242#     exit 0;
     243}
     244
     245sub balance
     246{
     247# so_id, ext_id, instances, available_instances, need_recovery, recoverable
     248# XXX don't remove the temp table code -- testing w/o it
     249#    $dbh->do("CREATE TEMPORARY TABLE mymountedvol LIKE mountedvol");
     250#    $dbh->do("INSERT INTO mymountedvol SELECT * FROM mountedvol");
     251
     252    if (not defined $so_id_start) { $so_id_start = 0; }
     253    if (not defined $so_id_range) { $so_id_range = 100000; }
     254    my $so_id_end = $so_id_start + $so_id_range;
     255
     256    # XXX check if so_id_start is beyond MAX(so_id): if so, exit with exit status 10
     257    {
     258        my $query = $dbh->prepare("SELECT MAX(so_id) from storage_object");
     259        $query->execute;
     260        my $answer = $query->fetchrow_arrayref;
     261        my $max_so_id = $$answer[0];
     262        $query->finish;
     263
     264        if ($so_id_start > $max_so_id) {
     265            print STDERR "at end of so_id range, reset please\n";
     266            exit 10;
     267        }
     268    }
     269
     270    # Calculate the average disk usage
     271    my $average = 0;
     272    my $avg_query = $dbh->prepare(
     273        "select sum(used)/sum(total) AS average from mountedvol WHERE available = 1 AND allocate = 1"
     274        );
     275    $avg_query->execute();
     276    while (my $row = $avg_query->fetchrow_hashref) {
     277        $average = $row->{average};
     278    }
     279    $avg_query->finish;
     280    print STDERR "average: $average\n";
     281    if ($average == 0) {
     282        exit 1;
     283    }
     284    # I truly am sorry for this statement.
     285    my $query = $dbh->prepare(
     286        "
     287SELECT * FROM (
     288 -- U Randomize the list of all possible source/destination matches,then group by so_id to select one at random
     289 SELECT T.*,volume.cab_id AS source_cab_id,volume.name AS source_name,volume.host AS source_host,
     290        destination.vol_id AS destination_vol_id,destination.cab_id AS destination_cab_id,
     291        destination.name AS destination_name,destination.host AS destination_host FROM (
     292  -- V Ensure that the copy we found on the source volume is the second copy instance
     293  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 (
     294   -- W Determine what the second copy instance is
     295   SELECT V.*,MAX(instance.ins_id) AS MAXins_id FROM (
     296    -- X Determine which hosts have instances of an object
     297    SELECT vol_id,ins_id,so_id,ext_id,value FROM
     298    storage_object JOIN storage_object_xattr USING(so_id) JOIN instance USING(so_id)
     299    WHERE vol_id IN (
     300     -- Y Extra select for debugging purposes
     301     SELECT vol_id FROM (
     302      -- Z Ran hosts by R (need to be a source) and return top N
     303      SELECT mountedvol.vol_id,mountedvol.name,mountedvol.available,mountedvol.allocate,total,used,
     304             (used / total) AS D,total * ((used / total) - $average ) AS R,  -- average
     305             cab_id FROM
     306      mountedvol JOIN volume USING(vol_id)
     307      WHERE mountedvol.available = 1
     308      ORDER BY R DESC LIMIT $balance_N_sources                                            -- N
     309      ) AS ranked_sources
     310      -- Z End
     311     )
     312     -- Y End
     313    AND name = 'user.copies' AND value >= 2
     314    AND so_id >= $so_id_start                                  -- so_id_start
     315    AND so_id <  $so_id_end                                    -- so_id_end
     316   ) AS V -- volumes that host a copy
     317   -- X End
     318  LEFT OUTER JOIN instance USING(so_id) GROUP BY so_id
     319  ) AS K -- copies that are the second copy
     320  -- W End
     321 JOIN instance ON MAXins_id = instance.ins_id GROUP BY so_id
     322 ) AS T -- matched copies that I know the second copy is on my source volume
     323 -- V End
     324 JOIN volume on T.here = volume.vol_id RIGHT JOIN (
     325  -- Y2 Chose a random destination from the list
     326  SELECT vol_id,cab_id,name,host FROM (
     327   -- Z2 Reverse rank hosts by R and return top M
     328   SELECT mountedvol.vol_id,mountedvol.name,mountedvol.host,mountedvol.available,mountedvol.allocate,total,used,
     329          (used / total) AS D,total * ((used / total) - $average ) AS R,  -- average
     330          cab_id FROM
     331   mountedvol JOIN volume USING(vol_id)
     332   WHERE mountedvol.available = 1 AND mountedvol.allocate = 1
     333   ORDER BY R ASC LIMIT $balance_M_destinations                                               -- M
     334  ) AS ranked_destinations
     335  -- Z2 End
     336 ORDER BY RAND()
     337 ) AS destination
     338 -- Y2 End
     339 ON destination.cab_id != volume.cab_id
     340 WHERE here = there
     341 ORDER BY RAND()
     342) AS results
     343-- U End
     344GROUP BY so_id
     345    LIMIT $limit                                               -- limit
     346
     347"    );
     348
     349    $query->execute();
     350                   
     351                   
     352
     353    my @rows;
     354    while (my $row = $query->fetchrow_hashref) {
     355        push @rows, $row;       
     356    }
     357    $query->finish;
     358
     359    print STDERR "No rows found\n" unless scalar @rows;
     360    exit unless scalar @rows;
     361   
     362    # compare number of responses to limit below
     363    my $Npending = @rows;
     364
     365    print "balancePending MULTI\n\n";
     366
     367    foreach my $obj (@rows) {
     368        if (defined $verbose) {
     369            require Data::Dumper;
     370            print Data::Dumper::Dumper($obj);
     371        }
     372       
     373
     374        my $here = $obj->{here};
     375        my $there = $obj->{there};
     376        my $ins_id = $obj->{ins_id};
     377        my $max_ins_id = $obj->{MAXins_id};
     378       
     379        my $so_id = $obj->{so_id};
     380        my $key   = $obj->{ext_id};
     381        my $copies = $obj->{user_copies};
     382
     383        my $source_vol_id = $obj->{here};
     384        my $source_cab_id = $obj->{source_cab_id};
     385        my $source_name   = $obj->{source_name};
     386        my $source_host   = $obj->{source_host};
     387
     388        my $destination_vol_id = $obj->{destination_vol_id};
     389        my $destination_cab_id = $obj->{destination_cab_id};
     390        my $destination_name   = $obj->{destination_name};
     391        my $destination_host   = $obj->{destination_host};
     392       
     393        unless ($here == $there) { next; }
     394        unless ($ins_id == $max_ins_id) { next; }
     395        unless ($source_cab_id != $destination_cab_id) { next; }
     396       
     397        my %md = (
     398            key           => $key,
     399            copies        => $copies,
     400            so_id         => $so_id,
     401            source_vol_id => $source_vol_id,
     402            source_cab_id => $source_cab_id,
     403            source_name   => $source_name,
     404            source_host   => $source_host,
     405            destination_vol_id => $destination_vol_id,
     406            destination_cab_id => $destination_cab_id,
     407            destination_name   => $destination_name,
     408            destination_host   => $destination_host,
     409#             key         => $key,
     410#           command     => $cmd,
     411#             need_copies => $need,
     412#             volume_name => $vol_name,
     413#             volume_host => $vol_host,
     414
     415# #         has         => $has,
     416#           available   => $available,
     417#           xattr_copies      => $copies,
     418# #         recoverable => $recoverable,
     419# #         need_recovery => $need_recovery,
     420           
     421        );
     422#       print "$key $cmd $need $vol_name $vol_host\n";
     423        print_metadata("balancePending", \%md);
     424        print "\n";
     425    }
     426
     427    # use a different exit status if we hit the limit (likely more files pending)
     428    print STDERR "Which exit: $Npending $limit\n";
     429    # This is a better way to do this.
     430    if ($Npending == 0) {
     431        exit 0;
     432    }
     433    else {
     434        exit 1;
     435    }
     436
     437#     if ($Npending == $limit) {
     438#         exit 1;
     439#     }
     440#     exit 0;
    211441}
    212442
Note: See TracChangeset for help on using the changeset viewer.