#!/usr/bin/env perl use warnings; use strict; use Getopt::Long; use DBIx::FileStore; use DBIx::FileStore::UtilityFunctions qw(get_date_and_time); # fdbtidy: cleans up stray blocks in an fdb database my $verbose = 0; my $clean = 0; main(); sub Usage { "fdbtidy [--verbose] [--clean]: Removes dangling FileDB blocks.\n"; } sub main { GetOptions("verbose" => \$verbose, "clean" => \$clean ) || die Usage(); my $filestore = new DBIx::FileStore(); my $dbh = $filestore->{dbh}; # THIS CODE SHOULD BE MOVED INTO A DBIx::FileStore method. $dbh->do( "lock tables files write, fileblocks write" ); # get a list of all the files and their checksums, my $files = $dbh->selectall_arrayref( "select name, c_len, c_md5 from files where b_num=0"); for my $f (@$files) { $f->[0] =~ s/ 0+$//; print "fdbtidy: looking for blocks of file: $f->[0]...\n" if $verbose; # then delete blocks that are 'old' and not matching first block's checksum my $badblocks = $dbh->selectall_arrayref( "select name, lasttime from files where name like ? and c_md5 != ? having lasttime < ?", {}, "$f->[0] %", $f->[2], get_date_and_time(time() - 60*60) ); for my $b (@$badblocks) { if (!$clean) { warn "fdbtidy: IGNORING dangling blocks named '$b->[0]'\n"; } else { warn "fdbtidy: DELETING dangling blocks named '$b->[0]'\n"; $dbh->do("delete from files where name is ?", {}, $b->[0]); $dbh->do("delete from fileblocks where name is ?", {}, $b->[0]); } } } $dbh->do( "unlock tables" ); } __END__ =pod =head1 NAME fdbtidy - Handle dangling blocks in the DBIx::FileStore filestore =head1 SYNOPSIS % fdbtidy shows if any rows in the fileblocks table don't have a corresponding for in the files table. % fdbtidy -v shows if any rows in the fileblocks table don't have a corresponding for in the files table, and shows files being checked. % fdbtidy -clean removes any dangling blocks found. =head1 DESCRIPTION fdbtidy - looks for dangling blocks in the DBIx::FileStore filestore. If --clean is used, it will clean up the dangling blocks. If --verbose is used, it will show verbose data about what it's doing. =head1 AUTHOR Josh Rabinowitz =head1 SEE ALSO L, L, L, L, L, L, L, L =cut