db-remove-orphaned-attachments 2.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596
  1. #!/usr/bin/perl -w
  2. use strict;
  3. use DBI;
  4. my $L1 = 10;
  5. my $L2 = 20;
  6. sub do_error($) {
  7. exit(1);
  8. }
  9. sub readconfig($) {
  10. my ($fn) = @_;
  11. my %options;
  12. open(CFG, $fn) or die("unable to open ".$fn." config file");
  13. while (<CFG>) {
  14. if ($_ =~ /^\s*[#!]/) {
  15. next;
  16. }
  17. if ($_ =~ /^\s*(\S+)\s*=\s*([^\r]+)\r?$/) {
  18. my $idx = $1;
  19. my $val = $2;
  20. chomp($val);
  21. $val =~ s/\s+$//;
  22. $options{$idx} = $val;
  23. }
  24. }
  25. close(CFG);
  26. return %options;
  27. }
  28. # TODO: parse config, and use settings
  29. if(scalar(@ARGV) < 1) {
  30. print "Usage: $0 <server.cfg>\n";
  31. exit(1);
  32. }
  33. my $servercfg = $ARGV[0];
  34. $servercfg = "/etc/kopano/server.cfg" if (!defined($servercfg));
  35. my %serveropt = readconfig($servercfg);
  36. my $basepath = $serveropt{attachment_path};
  37. my $db = DBI->connect("dbi:mysql:database=".$serveropt{mysql_database}.";host=".$serveropt{mysql_host}, $serveropt{mysql_user}, $serveropt{mysql_password})
  38. or die "Database error: ".$DBI::errstr;
  39. my $res;
  40. my $sth;
  41. my $rows;
  42. my @row;
  43. if (!defined($db)) {
  44. print "did not connect to mysql\n";
  45. exit(1);
  46. }
  47. print "Finding all orphaned attachments...\n";
  48. $sth = $db->prepare("SELECT DISTINCT(instanceid) FROM singleinstances LEFT JOIN hierarchy ON hierarchyid=hierarchy.id WHERE hierarchy.id IS NULL;");
  49. $sth->execute() || die $DBI::errstr;;
  50. if ($sth->rows == 0) {
  51. print "No orphaned attachments found.\n";
  52. exit(0);
  53. }
  54. if ($serveropt{attachment_storage} eq "files") {
  55. print "Processing ".$sth->rows." orphaned attachments\n";
  56. while(@row = $sth->fetchrow_array()) {
  57. my $filename = $basepath."/".($row[0] % $L1)."/".(($row[0] / $L1) % $L2)."/".$row[0];
  58. # can be either with or without compression
  59. system("rm -f ".$filename." ".$filename.".gz");
  60. }
  61. }
  62. $res = $db->do("begin;");
  63. if(!$res) {
  64. do_error(1);
  65. }
  66. print "Cleaning singleinstances...\n";
  67. $sth = $db->prepare("DELETE singleinstances.* FROM singleinstances LEFT JOIN hierarchy ON hierarchyid=hierarchy.id WHERE hierarchy.id IS NULL;");
  68. $sth->execute() || die $DBI::errstr;;
  69. print "Cleaning lob...\n";
  70. $sth = $db->prepare("DELETE lob.* FROM lob LEFT JOIN singleinstances ON lob.instanceid = singleinstances.instanceid WHERE singleinstances.instanceid IS NULL;");
  71. $sth->execute() || die $DBI::errstr;;
  72. print "Flush database changes to disk...\n";
  73. $db->do("commit;");
  74. print "Done.\n";