Changeset 32 for trunk/dnsbl/DNSBL.pm


Ignore:
Timestamp:
03/25/11 17:16:38 (13 years ago)
Author:
Kris Deugau
Message:

/trunk/dnsbl

Changeset to improve export speed on DNSBL database. By keeping
IP counts for each block, and directly tracking the parent of
each block and IP, an export taking ~90 seconds can be brought
down under 20.

  • updated initial tabledef SQL
  • Add addparents.sql SQL tabeldef and setparents.pl data update script
  • Tweak reporting of IP since it now requires the parent block(s) so the parent field can be filled in

Also add delist-ip script and Makefile

File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/dnsbl/DNSBL.pm

    r29 r32  
    138138sub initexport {
    139139  $parsth = $dbh->prepare("SELECT count(i.ip),b.block,b.level,b.listme AS oobblock,o.listme AS ooborg ".
    140         "FROM iplist i INNER JOIN blocks b ON i.ip << b.block INNER JOIN orgs o ON b.orgid = o.orgid ".
     140        "FROM iplist i INNER JOIN blocks b ON i.parent = b.block INNER JOIN orgs o ON b.orgid = o.orgid ".
    141141        "WHERE b.block >>= ? ".
    142142        "GROUP BY b.block,b.level,b.listme,o.listme ORDER BY b.block");
    143   $sthmoron = $dbh->prepare("SELECT ip,s4list FROM iplist WHERE ip << ? ORDER BY ip");
     143  $sthmoron = $dbh->prepare("SELECT ip,s4list FROM iplist WHERE parent = ?");
    144144}
    145145
     
    166166  if ($rep =~ /^[\d.]+$/) {
    167167    # weesa gonna ASS-U-ME IP addresses are sanely formatted.
    168     $sth = $dbh->prepare("SELECT count FROM iplist WHERE ip=?");
    169     $sth->execute($rep) or die "eep?  ".$dbh->errstr."\n";
    170     $rows = $sth->rows;
    171     if ($rows == 0) {
    172       $sth = $dbh->prepare("INSERT INTO iplist (ip) VALUES (?)");
    173     } elsif ($rows == 1) {
    174       $sth = $dbh->prepare("UPDATE iplist SET count=count+1 WHERE ip=?");
    175     } else {
    176       die "db corrupt: found $rows matches on $rep\n";
     168    eval {
     169      $sth = $dbh->prepare("SELECT count FROM iplist WHERE ip=?");
     170      $sth->execute($rep) or die "eep?  ".$dbh->errstr."\n";
     171      $rows = $sth->rows;
     172      if ($rows == 0) {
     173        $sth = $dbh->prepare("INSERT INTO iplist (ip,parent) VALUES ".
     174                "(?,(SELECT block FROM blocks WHERE block >> ? ORDER BY level DESC LIMIT 1))");
     175        $sth->execute($rep,$rep) or die "couldn't add entry for $rep: ".$dbh->errstr."\n";
     176      } elsif ($rows == 1) {
     177        $sth = $dbh->prepare("UPDATE iplist SET count=count+1 WHERE ip=?");
     178        $sth->execute($rep) or die "couldn't update listing for $rep: ".$dbh->errstr."\n";
     179      } else {
     180        die "db corrupt: found $rows matches on $rep\n";
     181      }
     182      $sth = $dbh->prepare("SELECT block FROM blocks WHERE block >> ?");
     183      $sth->execute($rep);
     184      my $updsth = $dbh->prepare("UPDATE blocks SET ipcount=(SELECT count(*) FROM iplist WHERE ip << ?) WHERE block=?");
     185      while (my ($block) = $sth->fetchrow_array) {
     186        $updsth->execute($block,$block);
     187      }
     188      $dbh->commit;
     189    };
     190    if ($@) {
     191      my $msg = $@;
     192      return "failed adding $rep: $msg";
    177193    }
    178     $sth->execute($rep) or die "couldn't update listing for $rep: ".$dbh->errstr."\n";
    179194  } else {
    180195    return;
    181196  }
    182   $dbh->commit;
    183197  return $rows;
    184198} # end report()
     
    228242  return "$blockin not a single CIDR range" if !$block;
    229243
    230   local $dbh->{AutoCommit} = 1; # force autocommit
    231 
    232   my $sth = $dbh->prepare("INSERT INTO blocks (block,orgid,level) VALUES (?,?,?)");
    233   $sth->execute("$block",$orgid,$level);
    234   return $sth->errstr if $sth->err;
     244#  local $dbh->{AutoCommit} = 1;        # force autocommit
     245
     246  my $sth;
     247  eval {
     248    my $parent = '0/0';
     249    if ($level > 0) {
     250      $sth = $dbh->prepare("SELECT block FROM blocks WHERE block >> ? ORDER BY level DESC LIMIT 1");
     251      $sth->execute("$block");
     252      ($parent) = $sth->fetchrow_array;
     253    }
     254    $sth = $dbh->prepare("INSERT INTO blocks (block,orgid,level,parent,ipcount) VALUES (?,?,?,?,".
     255        "(SELECT count(*) FROM iplist WHERE ip << ?))");
     256    $sth->execute("$block",$orgid,$level,$parent,"$block");
     257    $sth = $dbh->prepare("UPDATE iplist SET parent=? WHERE parent=? AND ip << ?");
     258    $sth->execute("$block",$parent,"$block");
     259    $dbh->commit;
     260  };
     261  if ($@) {
     262    my $msg = $@;
     263    eval { dbh->rollback; };
     264    return "failed to add $block: $msg";
     265  }
    235266  # nb: no need to return anything, since the CIDR block is the key
    236267}
     
    287318    return if !$block;
    288319
    289     $sth = $dbh->prepare("SELECT count(*) FROM iplist WHERE ip << ?");
     320    $sth = $dbh->prepare("SELECT ipcount FROM blocks WHERE block = ?");
    290321    $sth->execute($entity);
    291322    my ($bcount) = $sth->fetchrow_array;
     
    343374  }
    344375
    345   my $sth = $dbh->prepare("SELECT count(*) FROM blocks WHERE block << ?");
     376  my $sth = $dbh->prepare("SELECT count(*) FROM blocks WHERE parent = ?");
    346377  $sth->execute($container);
    347378  my ($nblocks) = $sth->fetchrow_array();
     
    356387  my $bcount;
    357388  if ($container ne '0.0.0.0/0') {
    358     $sth = $dbh->prepare("SELECT count(*) FROM iplist WHERE ip << ?");
    359     $sth->execute($container);
    360     ($bcount) = $sth->fetchrow_array();
    361 
    362     $sth = $dbh->prepare("SELECT b.listme,o.listme ".
     389    $sth = $dbh->prepare("SELECT b.ipcount,b.listme,o.listme ".
    363390        "FROM blocks b INNER JOIN orgs o ON b.orgid=o.orgid ".
    364391        "WHERE b.block = ?");
    365392    $sth->execute($container);
    366     ($listme,$listorg) = $sth->fetchrow_array();
     393    ($bcount,$listme,$listorg) = $sth->fetchrow_array();
    367394
    368395    $bitmask |= $bitfields{$level-1} if $bcount >= $autolist{$masklen};
     
    374401  if ($nblocks > 0) {
    375402    my $sthsubblocks = $dbh->prepare("SELECT block FROM blocks ".
    376         "WHERE level=? and block << ? ORDER BY block, masklen(block) DESC");
     403        "WHERE level = ? AND parent = ?");
    377404    $sthsubblocks->execute($level, $container);
    378405    while (my ($cidr) = $sthsubblocks->fetchrow_array()) {
     
    490517
    491518  my $cidr = new NetAddr::IP "$block";
    492   my $sth = $dbh->prepare("select count(*) from iplist where ip << ?");
     519  my $sth = $dbh->prepare("SELECT ipcount FROM blocks WHERE block = ?");
    493520  $sth->execute("$cidr");
    494521  my ($count) = $sth->fetchrow_array;
Note: See TracChangeset for help on using the changeset viewer.