/[BackupPC]/trunk/bin/BackupPC_updatedb
This is repository of my old source code which isn't updated any more. Go to git.rot13.org for current projects!
ViewVC logotype

Diff of /trunk/bin/BackupPC_updatedb

Parent Directory Parent Directory | Revision Log Revision Log | View Patch Patch

revision 98 by dpavlin, Tue Aug 30 14:19:54 2005 UTC revision 248 by dpavlin, Fri Dec 9 14:41:13 2005 UTC
# Line 11  use Getopt::Std; Line 11  use Getopt::Std;
11  use Time::HiRes qw/time/;  use Time::HiRes qw/time/;
12  use File::Pid;  use File::Pid;
13  use POSIX qw/strftime/;  use POSIX qw/strftime/;
14    use BackupPC::SearchLib;
15    
16  use constant BPC_FTYPE_DIR => 5;  use constant BPC_FTYPE_DIR => 5;
17  use constant EST_CHUNK => 10000;  use constant EST_CHUNK => 100000;
18    
19    # daylight saving time change offset for 1h
20    my $dst_offset = 60 * 60;
21    
22  my $debug = 0;  my $debug = 0;
23  $|=1;  $|=1;
# Line 41  my $beenThere = {}; Line 45  my $beenThere = {};
45    
46  my $dsn = $Conf{SearchDSN} || die "Need SearchDSN in config.pl\n";  my $dsn = $Conf{SearchDSN} || die "Need SearchDSN in config.pl\n";
47  my $user = $Conf{SearchUser} || '';  my $user = $Conf{SearchUser} || '';
 my $index_path = $Conf{HyperEstraierIndex};  
 $index_path = $TopDir . '/' . $index_path;  
 $index_path =~ s#//#/#g;  
 if ($index_path) {  
         use HyperEstraier;  
 }  
48    
49    my $use_hest = $Conf{HyperEstraierIndex};
50    my ($index_path, $index_node_url) = BackupPC::SearchLib::getHyperEstraier_url($use_hest);
51    
52  my $dbh = DBI->connect($dsn, $user, "", { RaiseError => 1, AutoCommit => 0 });  my $dbh = DBI->connect($dsn, $user, "", { RaiseError => 1, AutoCommit => 0 });
53    
54  my %opt;  my %opt;
55    
56  if ( !getopts("cdm:v:i", \%opt ) ) {  if ( !getopts("cdm:v:ijf", \%opt ) ) {
57          print STDERR <<EOF;          print STDERR <<EOF;
58  usage: $0 [-c|-d] [-m num] [-v|-v level] [-i]  usage: $0 [-c|-d] [-m num] [-v|-v level] [-i|-j|-f]
59    
60  Options:  Options:
61          -c      create database on first use          -c      create database on first use
62          -d      delete database before import          -d      delete database before import
63          -m num  import just num increments for one host          -m num  import just num increments for one host
64          -v num  set verbosity (debug) level (default $debug)          -v num  set verbosity (debug) level (default $debug)
65          -i      update HyperEstraier full text index          -i      update Hyper Estraier full text index
66            -j      update full text, don't check existing files
67            -f      don't do anything with full text index
68    
69    Option -j is variation on -i. It will allow faster initial creation
70    of full-text index from existing database.
71    
72    Option -f will create database which is out of sync with full text index. You
73    will have to re-run $0 with -i to fix it.
74    
75  EOF  EOF
76          exit 1;          exit 1;
77  }  }
# Line 70  EOF Line 79  EOF
79  if ($opt{v}) {  if ($opt{v}) {
80          print "Debug level at $opt{v}\n";          print "Debug level at $opt{v}\n";
81          $debug = $opt{v};          $debug = $opt{v};
82    } elsif ($opt{f}) {
83            print "WARNING: disabling full-text index update. You need to re-run $0 -j !\n";
84            ($use_hest, $index_path, $index_node_url) = (undef, undef, undef);
85  }  }
86    
87  #---- subs ----  #---- subs ----
# Line 88  sub curr_time { Line 100  sub curr_time {
100  }  }
101    
102  my $hest_db;  my $hest_db;
103    my $hest_node;
104    
105  sub signal {  sub signal {
106          my($sig) = @_;          my($sig) = @_;
# Line 106  sub hest_update { Line 119  sub hest_update {
119    
120          my ($host_id, $share_id, $num) = @_;          my ($host_id, $share_id, $num) = @_;
121    
122            my $skip_check = $opt{j} && print STDERR "Skipping check for existing files -- this should be used only with initital import\n";
123    
124            unless (defined($use_hest)) {
125                    print STDERR "HyperEstraier support not enabled in configuration\n";
126                    $use_hest = 0;
127                    return;
128            }
129    
130          print curr_time," updating HyperEstraier:";          print curr_time," updating HyperEstraier:";
131    
132          my $t = time();          my $t = time();
# Line 113  sub hest_update { Line 134  sub hest_update {
134          my $offset = 0;          my $offset = 0;
135          my $added = 0;          my $added = 0;
136    
137          print " opening index $index_path";          print " opening index $use_hest";
138          $hest_db = HyperEstraier::Database->new();          if ($index_path) {
139          $hest_db->open($index_path, $HyperEstraier::Database::DBWRITER | $HyperEstraier::Database::DBCREAT);                  $hest_db = HyperEstraier::Database->new();
140                    $hest_db->open($TopDir . $index_path, $HyperEstraier::Database::DBWRITER | $HyperEstraier::Database::DBCREAT);
141                    print " directly";
142            } elsif ($index_node_url) {
143                    $hest_node ||= HyperEstraier::Node->new($index_node_url);
144                    $hest_node->set_auth('admin', 'admin');
145                    print " via node URL";
146            } else {
147                    die "don't know how to use HyperEstraier Index $use_hest";
148            }
149            print " increment is " . EST_CHUNK . " files:";
150    
151          my $results = 0;          my $results = 0;
152    
153          do {          do {
154    
155                  my $where = '';                  my $where = '';
156                  if ($host_id && $share_id && $num) {                  my @data;
157                    if (defined($host_id) && defined($share_id) && defined($num)) {
158                          $where = qq{                          $where = qq{
159                          WHERE                          WHERE
160                                  hosts.id = ? AND                                  hosts.id = ? AND
161                                  shares.id = ? AND                                  shares.id = ? AND
162                                  files.backupnum = ?                                  files.backupnum = ?
163                          };                          };
164                            @data = ( $host_id, $share_id, $num );
165                  }                  }
166    
167                  my $limit = sprintf('LIMIT '.EST_CHUNK.' OFFSET %d', $offset);                  my $limit = sprintf('LIMIT '.EST_CHUNK.' OFFSET %d', $offset);
# Line 155  sub hest_update { Line 188  sub hest_update {
188                          $limit                          $limit
189                  });                  });
190    
191                  $sth->execute(@_);                  $sth->execute(@data);
192                  $results = $sth->rows;                  $results = $sth->rows;
193    
194                  if ($results == 0) {                  if ($results == 0) {
195                          print " - no more files\n";                          print " - no new files\n";
196                          last;                          last;
197                  }                  }
198    
# Line 175  sub hest_update { Line 208  sub hest_update {
208                          my $fid = $row->{'fid'} || die "no fid?";                          my $fid = $row->{'fid'} || die "no fid?";
209                          my $uri = 'file:///' . $fid;                          my $uri = 'file:///' . $fid;
210    
211                          my $id = $hest_db->uri_to_id($uri);                          unless ($skip_check) {
212                          next unless ($id == -1);                                  my $id = ($hest_db || $hest_node)->uri_to_id($uri);
213                                    next unless ($id == -1);
214                            }
215    
216                          # create a document object                          # create a document object
217                          my $doc = HyperEstraier::Document->new;                          my $doc = HyperEstraier::Document->new;
# Line 185  sub hest_update { Line 220  sub hest_update {
220                          $doc->add_attr('@uri', $uri);                          $doc->add_attr('@uri', $uri);
221    
222                          foreach my $c (@{ $sth->{NAME} }) {                          foreach my $c (@{ $sth->{NAME} }) {
223                                  $doc->add_attr($c, $row->{$c}) if ($row->{$c});                                  $doc->add_attr($c, $row->{$c}) if (defined($row->{$c}));
224                          }                          }
225    
226                          #$doc->add_attr('@cdate', fmt_date($row->{'date'}));                          #$doc->add_attr('@cdate', fmt_date($row->{'date'}));
# Line 199  sub hest_update { Line 234  sub hest_update {
234                          print STDERR $doc->dump_draft,"\n" if ($debug > 1);                          print STDERR $doc->dump_draft,"\n" if ($debug > 1);
235    
236                          # register the document object to the database                          # register the document object to the database
237                          $hest_db->put_doc($doc, $HyperEstraier::Database::PDCLEAN);                          if ($hest_db) {
238                                    $hest_db->put_doc($doc, $HyperEstraier::Database::PDCLEAN);
239                            } elsif ($hest_node) {
240                                    $hest_node->put_doc($doc);
241                            } else {
242                                    die "not supported";
243                            }
244                          $added++;                          $added++;
245                  }                  }
246    
247                  print " $added";                  print " $added";
248                  $hest_db->sync();                  $hest_db->sync() if ($index_path);
249    
250                  $offset += EST_CHUNK;                  $offset += EST_CHUNK;
251    
252          } while ($results == EST_CHUNK);          } while ($results == EST_CHUNK);
253    
254          print ", close";          if ($index_path) {
255          $hest_db->close();                  print ", close";
256                    $hest_db->close();
257            }
258    
259          my $dur = (time() - $t) || 1;          my $dur = (time() - $t) || 1;
260          printf(" [%.2f/s dur: %s]\n",          printf(" [%.2f/s dur: %s]\n",
# Line 224  sub hest_update { Line 267  sub hest_update {
267    
268    
269  ## update index ##  ## update index ##
270  if (($opt{i} || ($index_path && ! -e $index_path)) && !$opt{c}) {  if (($opt{i} || $opt{j} || ($index_path && ! -e $TopDir . $index_path)) && !$opt{c}) {
271          # update all          # update all
272          print "force update of HyperEstraier index ";          print "force update of HyperEstraier index ";
273          print "importing existing data" unless (-e $index_path);          print "importing existing data" unless (-e $TopDir . $index_path);
274          print "by -i flag" if ($opt{i});          print "by -i flag" if ($opt{i});
275            print "by -j flag" if ($opt{j});
276          print "\n";          print "\n";
277          hest_update();          hest_update();
278  }  }
# Line 237  if (($opt{i} || ($index_path && ! -e $in Line 281  if (($opt{i} || ($index_path && ! -e $in
281  if ($opt{c}) {  if ($opt{c}) {
282          sub do_index {          sub do_index {
283                  my $index = shift || return;                  my $index = shift || return;
284                  my ($table,$col,$unique) = split(/_/, $index);                  my ($table,$col,$unique) = split(/:/, $index);
285                  $unique ||= '';                  $unique ||= '';
286                  $index =~ s/,/_/g;                  $index =~ s/\W+/_/g;
287                    print "$index on $table($col)" . ( $unique ? "u" : "" ) . " ";
288                  $dbh->do(qq{ create $unique index $index on $table($col) });                  $dbh->do(qq{ create $unique index $index on $table($col) });
289          }          }
290    
291          print "creating tables...\n";          print "creating tables...\n";
292          
293          $dbh->do(qq{          $dbh->do( qq{
294                  create table hosts (                  create table hosts (
295                          ID      SERIAL          PRIMARY KEY,                          ID      SERIAL          PRIMARY KEY,
296                          name    VARCHAR(30)     NOT NULL,                          name    VARCHAR(30)     NOT NULL,
297                          IP      VARCHAR(15)                          IP      VARCHAR(15)
298                  );                              );            
299          });  
                 
         $dbh->do(qq{  
300                  create table shares (                  create table shares (
301                          ID      SERIAL          PRIMARY KEY,                          ID      SERIAL          PRIMARY KEY,
302                          hostID  INTEGER         NOT NULL references hosts(id),                          hostID  INTEGER         NOT NULL references hosts(id),
303                          name    VARCHAR(30)     NOT NULL,                          name    VARCHAR(30)     NOT NULL,
304                          share   VARCHAR(200)    NOT NULL,                          share   VARCHAR(200)    NOT NULL
                         localpath VARCHAR(200)        
305                  );                              );            
306          });  
307                            create table dvds (
308          $dbh->do(qq{                          ID      SERIAL          PRIMARY KEY,
309                            num     INTEGER         NOT NULL,
310                            name    VARCHAR(255)    NOT NULL,
311                            mjesto  VARCHAR(255)
312                    );
313    
314                  create table backups (                  create table backups (
315                            id      serial,
316                          hostID  INTEGER         NOT NULL references hosts(id),                          hostID  INTEGER         NOT NULL references hosts(id),
317                          num     INTEGER         NOT NULL,                          num     INTEGER         NOT NULL,
318                          date    integer         NOT NULL,                          date    integer         NOT NULL,
319                          type    CHAR(4)         not null,                          type    CHAR(4)         not null,
320                          shareID integer         not null references shares(id),                          shareID integer         not null references shares(id),
321                          size    integer         not null,                          size    bigint          not null,
322                          PRIMARY KEY(hostID, num, shareID)                          inc_size bigint         not null default -1,
323                            inc_deleted boolean     default false,
324                            parts   integer         not null default 1,
325                            PRIMARY KEY(id)
326                  );                              );            
         });  
327    
328          #do_index('backups_hostid,num_unique');                  create table files (
329                            ID              SERIAL,
330                            shareID         INTEGER NOT NULL references shares(id),
331                            backupNum       INTEGER NOT NULL,
332                            name            VARCHAR(255) NOT NULL,
333                            path            VARCHAR(255) NOT NULL,
334                            date            integer NOT NULL,
335                            type            INTEGER NOT NULL,
336                            size            bigint  NOT NULL,
337                            primary key(id)
338                    );
339    
340          $dbh->do(qq{                  create table archive (
341                  create table dvds (                          id              serial,
342                          ID      SERIAL          PRIMARY KEY,                          dvd_nr          int not null,
343                          num     INTEGER         NOT NULL,                          total_size      bigint default -1,
344                          name    VARCHAR(255)    NOT NULL,                          note            text,
345                          mjesto  VARCHAR(255)                          username        varchar(20) not null,
346                            date            timestamp default now(),
347                            primary key(id)
348                    );      
349    
350                    create table archive_backup (
351                            archive_id      int not null references archive(id) on delete cascade,
352                            backup_id       int not null references backups(id),
353                            primary key(archive_id, backup_id)
354                  );                  );
         });  
355    
356          $dbh->do(qq{                      create table archive_burned (
357                  create table files (                          archive_id      int references archive(id),
358                          ID      SERIAL          PRIMARY KEY,                            date            timestamp default now(),
359                          shareID INTEGER         NOT NULL references shares(id),                          part            int not null default 1,
360                          backupNum  INTEGER      NOT NULL,                          copy            int not null default 1,
361                          name       VARCHAR(255) NOT NULL,                          iso_size bigint default -1
362                          path       VARCHAR(255) NOT NULL,                  );
363                          date       integer      NOT NULL,  
364                          type       INTEGER      NOT NULL,                  create table backup_parts (
365                          size       INTEGER      NOT NULL,                          id serial,
366                          dvdid      INTEGER      references dvds(id)                              backup_id int references backups(id),
367                            part_nr int not null check (part_nr > 0),
368                            tar_size bigint not null check (tar_size > 0),
369                            size bigint not null check (size > 0),
370                            md5 text not null,
371                            items int not null check (items > 0),
372                            date timestamp default now(),
373                            primary key(id)
374                  );                  );
375          });          });
376    
377          print "creating indexes:";          print "creating indexes: ";
378    
379          foreach my $index (qw(          foreach my $index (qw(
380                  hosts_name                  hosts:name
381                  backups_hostID                  backups:hostID
382                  backups_num                  backups:num
383                  shares_hostID                  backups:shareID
384                  shares_name                  shares:hostID
385                  files_shareID                  shares:name
386                  files_path                  files:shareID
387                  files_name                  files:path
388                  files_date                  files:name
389                  files_size                  files:date
390                    files:size
391                    archive:dvd_nr
392                    archive_burned:archive_id
393                    backup_parts:backup_id,part_nr
394          )) {          )) {
                 print " $index";  
395                  do_index($index);                  do_index($index);
396          }          }
397    
398            print " creating sequence: ";
399            foreach my $seq (qw/dvd_nr/) {
400                    print "$seq ";
401                    $dbh->do( qq{ CREATE SEQUENCE $seq } );
402            }
403    
404    
405          print "...\n";          print "...\n";
406    
407          $dbh->commit;          $dbh->commit;
# Line 360  WHERE hostID=? AND num=? AND shareid=? Line 445  WHERE hostID=? AND num=? AND shareid=?
445    
446  $sth->{insert_backups} = $dbh->prepare(qq{  $sth->{insert_backups} = $dbh->prepare(qq{
447  INSERT INTO backups (hostID, num, date, type, shareid, size)  INSERT INTO backups (hostID, num, date, type, shareid, size)
448  VALUES (?,?,?,?,?,?)  VALUES (?,?,?,?,?,-1)
449    });
450    
451    $sth->{update_backups_size} = $dbh->prepare(qq{
452    UPDATE backups SET size = ?
453    WHERE hostID = ? and num = ? and date = ? and type =? and shareid = ?
454  });  });
455    
456  $sth->{insert_files} = $dbh->prepare(qq{  $sth->{insert_files} = $dbh->prepare(qq{
# Line 369  INSERT INTO files Line 459  INSERT INTO files
459          VALUES (?,?,?,?,?,?,?)          VALUES (?,?,?,?,?,?,?)
460  });  });
461    
462  foreach my $host_key (keys %{$hosts}) {  my @hosts = keys %{$hosts};
463    my $host_nr = 0;
464    
465    foreach my $host_key (@hosts) {
466    
467          my $hostname = $hosts->{$host_key}->{'host'} || die "can't find host for $host_key";          my $hostname = $hosts->{$host_key}->{'host'} || die "can't find host for $host_key";
468    
# Line 384  foreach my $host_key (keys %{$hosts}) { Line 477  foreach my $host_key (keys %{$hosts}) {
477                  $hostID = $dbh->last_insert_id(undef,undef,'hosts',undef);                  $hostID = $dbh->last_insert_id(undef,undef,'hosts',undef);
478          }          }
479    
480          print "host ".$hosts->{$host_key}->{'host'}.": ";          $host_nr++;
481            print "host ", $hosts->{$host_key}->{'host'}, " [",
482                    $host_nr, "/", ($#hosts + 1), "]: ";
483    
484          # get backups for a host          # get backups for a host
485          my @backups = $bpc->BackupInfoRead($hostname);          my @backups = $bpc->BackupInfoRead($hostname);
# Line 426  foreach my $host_key (keys %{$hosts}) { Line 521  foreach my $host_key (keys %{$hosts}) {
521                          # dump some log                          # dump some log
522                          print curr_time," ", $share;                          print curr_time," ", $share;
523    
                         my ($f, $nf, $d, $nd, $size) = recurseDir($bpc, $hostname, $files, $backupNum, $share, "", $shareID);  
   
524                          $sth->{insert_backups}->execute(                          $sth->{insert_backups}->execute(
525                                  $hostID,                                  $hostID,
526                                  $backupNum,                                  $backupNum,
527                                  $backup->{'endTime'},                                  $backup->{'endTime'},
528                                  $backup->{'type'},                                  substr($backup->{'type'},0,4),
529                                  $shareID,                                  $shareID,
530                            );
531    
532                            my ($f, $nf, $d, $nd, $size) = recurseDir($bpc, $hostname, $files, $backupNum, $share, "", $shareID);
533    
534                            $sth->{update_backups_size}->execute(
535                                  $size,                                  $size,
536                                    $hostID,
537                                    $backupNum,
538                                    $backup->{'endTime'},
539                                    substr($backup->{'type'},0,4),
540                                    $shareID,
541                          );                          );
542    
543                          print " commit";                          print " commit";
# Line 448  foreach my $host_key (keys %{$hosts}) { Line 551  foreach my $host_key (keys %{$hosts}) {
551                                  fmt_time($dur)                                  fmt_time($dur)
552                          );                          );
553    
554                          hest_update($hostID, $shareID, $backupNum);                          hest_update($hostID, $shareID, $backupNum) if ($nf + $nd > 0);
555                  }                  }
556    
557          }          }
# Line 477  sub getShareID() { Line 580  sub getShareID() {
580    
581          $sth->{insert_share} ||= $dbh->prepare(qq{          $sth->{insert_share} ||= $dbh->prepare(qq{
582                  INSERT INTO shares                  INSERT INTO shares
583                          (hostID,name,share,localpath)                          (hostID,name,share)
584                  VALUES (?,?,?,?)                  VALUES (?,?,?)
585          });          });
586    
587          my $drop_down = $hostname . '/' . $share;          my $drop_down = $hostname . '/' . $share;
588          $drop_down =~ s#//+#/#g;          $drop_down =~ s#//+#/#g;
589    
590          $sth->{insert_share}->execute($hostID,$share, $drop_down ,undef);          $sth->{insert_share}->execute($hostID,$share, $drop_down);
591          return $dbh->last_insert_id(undef,undef,'shares',undef);          return $dbh->last_insert_id(undef,undef,'shares',undef);
592  }  }
593    
# Line 501  sub found_in_db { Line 604  sub found_in_db {
604                  SELECT 1 FROM files                  SELECT 1 FROM files
605                  WHERE shareID = ? and                  WHERE shareID = ? and
606                          path = ? and                          path = ? and
607                          date = ? and                          size = ? and
608                          size = ?                          ( date = ? or date = ? or date = ? )
609                  LIMIT 1                  LIMIT 1
610          });          });
611    
612          my @param = ($shareID,$path,$date,$size);          my @param = ($shareID,$path,$size,$date, $date-$dst_offset, $date+$dst_offset);
613          $sth->{file_in_db}->execute(@param);          $sth->{file_in_db}->execute(@param);
614          my $rows = $sth->{file_in_db}->rows;          my $rows = $sth->{file_in_db}->rows;
615          print STDERR "## found_in_db($shareID,$path,$date,$size) ",( $rows ? '+' : '-' ), join(" ",@param), "\n" if ($debug >= 3);          print STDERR "## found_in_db($shareID,$path,$date,$size) ",( $rows ? '+' : '-' ), join(" ",@param), "\n" if ($debug >= 3);
# Line 556  sub recurseDir($$$$$$$$) { Line 659  sub recurseDir($$$$$$$$) {
659                                  $filesInBackup->{$path_key}->{'size'}                                  $filesInBackup->{$path_key}->{'size'}
660                          ));                          ));
661    
662                            my $key_dst_prev = join(" ", (
663                                    $shareID,
664                                    $dir,
665                                    $path_key,
666                                    $filesInBackup->{$path_key}->{'mtime'} - $dst_offset,
667                                    $filesInBackup->{$path_key}->{'size'}
668                            ));
669    
670                            my $key_dst_next = join(" ", (
671                                    $shareID,
672                                    $dir,
673                                    $path_key,
674                                    $filesInBackup->{$path_key}->{'mtime'} + $dst_offset,
675                                    $filesInBackup->{$path_key}->{'size'}
676                            ));
677    
678                          my $found;                          my $found;
679                          if (! defined($beenThere->{$key}) && ! ($found = found_in_db($key, @data)) ) {                          if (
680                                    ! defined($beenThere->{$key}) &&
681                                    ! defined($beenThere->{$key_dst_prev}) &&
682                                    ! defined($beenThere->{$key_dst_next}) &&
683                                    ! ($found = found_in_db($key, @data))
684                            ) {
685                                  print STDERR "# key: $key [", $beenThere->{$key},"]" if ($debug >= 2);                                  print STDERR "# key: $key [", $beenThere->{$key},"]" if ($debug >= 2);
686    
687                                  if ($filesInBackup->{$path_key}->{'type'} == BPC_FTYPE_DIR) {                                  if ($filesInBackup->{$path_key}->{'type'} == BPC_FTYPE_DIR) {

Legend:
Removed from v.98  
changed lines
  Added in v.248

  ViewVC Help
Powered by ViewVC 1.1.26