Created
October 18, 2012 20:02
-
-
Save pyh/3914461 to your computer and use it in GitHub Desktop.
MogileFS helper script that quickly drains selected hosts
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!/usr/bin/perl | |
# Efficient script to remove all files from some storage nodes | |
# Use with caution... | |
# Replicates status=="drain": | |
# UPDATE device SET status="drain" WHERE hostid IN(1,2,3,4) AND status="alive"; | |
# file_to_queue: | |
#| fid | devid | type | nexttry | failcount | flags | arg | | |
#+-------+-------+------+------------+-----------+-------+--------------------------+ | |
#| 1040 | 7 | 2 | 1350564913 | 0 | 0 | 1337,1268,1201,1333,1372 | | |
#| 1721 | 7 | 2 | 1350564913 | 0 | 0 | 1378,1270,1369,1238,1212 | | |
use warnings; | |
use strict; | |
use MogileFS::Server; | |
MogileFS::Config->load_config; | |
our $dbh = Mgd::get_store()->dbh; | |
my $rebal_devs = $dbh->selectcol_arrayref('SELECT devid FROM device WHERE status="drain"'); | |
my $destination_devs = $dbh->selectcol_arrayref('SELECT devid FROM device WHERE hostid IN(23,24) AND status="alive"'); | |
if(!@{$rebal_devs}){ | |
print "Couldn't find anything that needs to be drained\n"; | |
exit 1; | |
} | |
my %done_devs=(); | |
while(1){ | |
while( ($dbh->selectrow_array("SELECT COUNT(*) FROM file_to_queue WHERE type=2"))[0] > 15000 ) { | |
print "sleeping\n"; | |
sleep 2; | |
} | |
my $dest_devs = order_dest_devs($destination_devs); | |
foreach my $drain_dev (@$rebal_devs){ | |
next if $done_devs{$drain_dev}; | |
my $fids = $dbh->selectcol_arrayref("SELECT fid FROM file_on WHERE devid=? LIMIT 140", undef, $drain_dev); | |
# no more files, mark device as done | |
if(!@$fids){ | |
$done_devs{$drain_dev}=1; | |
next; | |
} | |
my $nexttry=time(); | |
my $dest = join(",",@{$dest_devs}[0..20]); | |
my $retval; | |
eval { $retval = $dbh->do("INSERT IGNORE INTO file_to_queue (fid,devid,type,nexttry,arg) VALUES". join(",", ("(?,$drain_dev,2,$nexttry,\"$dest\")")x@$fids), undef, @$fids) }; | |
if($@) { | |
if ( $@ =~ /Deadlock found when trying to get lock; try restarting transaction/ ){ | |
print "Deadlock skipping for now\n"; | |
}else{ | |
die($@); | |
} | |
} | |
print "Queued $drain_dev: ".join(" ", @$fids)."\n"; | |
} | |
} | |
sub order_dest_devs { | |
my $dest = shift; | |
return $dbh->selectcol_arrayref('SELECT devid FROM device WHERE devid IN('. join(',',('?')x@$dest).') AND status="alive" ORDER BY mb_used', undef, @$dest); | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment