Changeset 29519
- Timestamp:
- Oct 21, 2010, 2:48:03 PM (16 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
branches/eam_branches/ipp-20100823/Nebulous-Server/bin/neb-admin
r24632 r29519 27 27 $limit, 28 28 $pending, 29 $balance, 30 $balance_N_sources, 31 $balance_M_destinations, 29 32 $removal, 30 33 $verbose, … … 42 45 'pass|p=s' => \$dbpass, 43 46 '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, 45 51 'so_id_start=i' => \$so_id_start, 46 52 'so_id_range=i' => \$so_id_range, … … 54 60 pod2usage( -msg => "--limit is meaningless without --pendingreplicate", 55 61 -exitval => 2 ) 56 if defined $limit and not defined $pending;62 if defined $limit and not (defined $pending or defined $balance); 57 63 pod2usage( -msg => "no operation specified", -exitval => 2 ) 58 unless defined $pending or defined $removal; 59 64 unless defined $pending or defined $balance; 65 pod2usage( -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); 60 68 # set default limit to 5 61 69 $limit ||= 5; … … 84 92 } elsif ($removal) { 85 93 removal(); 94 } elsif ($balance) { 95 balance(); 86 96 } else { 87 97 die "THIS SHOULD NOT HAPPEN"; … … 137 147 AND so.so_id < $so_id_end 138 148 GROUP BY so_id 139 HAVING available_instances < instances OR instances <copies149 HAVING available_instances != instances OR instances != copies 140 150 LIMIT $limit" 141 151 ); 152 142 153 $query->execute; 143 144 # $dbh->do("DROP TABLE IF EXISTS mymountedvol");145 154 146 155 my @rows; … … 168 177 my $vol_name = $obj->{volume_name}; 169 178 my $vol_host = $obj->{volume_host}; 170 my $available = $obj->{available_instances} || 0;179 my $available = $obj->{available_instances} || 0; 171 180 my $need_recovery = $obj->{need_recovery}; 172 181 my $recoverable = $obj->{recoverable}; … … 189 198 190 199 my $need = $copies - $available; 191 $need = 0 if $need < 0;192 200 my $cmd = 'neb-stat'; 201 # $need = 0 if $need < 0; 193 202 next unless $need; 203 204 if ($need > 0) { 205 $cmd = 'neb-replicate'; 206 } 207 elsif ($need < 0) { 208 $cmd = 'neb-cull'; 209 } 194 210 195 211 my %md = ( 196 212 key => $key, 213 command => $cmd, 197 214 need_copies => $need, 198 215 volume_name => $vol_name, 199 216 volume_host => $vol_host, 217 218 # has => $has, 219 available => $available, 220 xattr_copies => $copies, 221 # recoverable => $recoverable, 222 # need_recovery => $need_recovery, 223 200 224 ); 201 225 # print "$key $cmd $need $vol_name $vol_host\n"; 202 226 print_metadata("replicatePending", \%md); 203 227 print "\n"; … … 205 229 206 230 # 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 245 sub 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 " 287 SELECT * 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 344 GROUP 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; 211 441 } 212 442
Note:
See TracChangeset
for help on using the changeset viewer.
