afuna: Cat under a blanket. Text: "Cats are just little people with Fur and Fangs" (Default)
afuna ([personal profile] afuna) wrote in [site community profile] changelog2009-09-05 11:33 am

[dw-free] remove legacy database tables

[commit: http://hg.dwscoalition.org/dw-free/rev/ee7de5f9dd15]

http://bugs.dwscoalition.org/show_bug.cgi?id=1710

Remove support for pre-clustering migration tables and script.

Patch by [personal profile] kareila.

Files modified:
  • bin/upgrading/base-data.sql
  • bin/upgrading/move0cluster.pl
  • bin/upgrading/update-db-general.pl
--------------------------------------------------------------------------------
diff -r 8a1034a41fe1 -r ee7de5f9dd15 bin/upgrading/base-data.sql
--- a/bin/upgrading/base-data.sql	Sat Sep 05 10:51:57 2009 +0000
+++ b/bin/upgrading/base-data.sql	Sat Sep 05 11:33:28 2009 +0000
@@ -928,7 +928,6 @@ REPLACE INTO schematables (des, public_b
 REPLACE INTO schematables (des, public_browsable, redist_mode, redist_where, tablename) VALUES ('Historic. Global. Stores a user\'s posts on other clusters, when either 1) that user isn\'t clustered themselves yet, or 2) we\'re doing a mass conversion (moveucluster.pl) and don\'t want to look it up.\n\r\nA maintenance task (clean_caches) moves data from here to [dbtable[talkleft]] on clusters.', '0', 'off', NULL, 'talkleft_xfp');
 REPLACE INTO schematables (des, public_browsable, redist_mode, redist_where, tablename) VALUES ('Lookup table for states, countries, languages, etc...', '1', 'replace', NULL, 'codes');
 REPLACE INTO schematables (des, public_browsable, redist_mode, redist_where, tablename) VALUES ('Stores data on valid invite codes and who has used them. The acctinvite table stores the data on why they were made.', '0', 'off', NULL, 'acctcode');
-REPLACE INTO schematables (des, public_browsable, redist_mode, redist_where, tablename) VALUES ('Stores globally-unique itemid and talkid ID (entries and comments), for URL compatibility. These were used pre-clustering. The LJ::get_newids function uses this table to find out what journal an old global ID belongs to and maps it to its new ID.', '0', 'off', NULL, 'oldids');
 REPLACE INTO schematables (des, public_browsable, redist_mode, redist_where, tablename) VALUES ('Stores metadata for entries users mark as \"Memories\". Please see also the clustered [dbtable[memorable2]] table.', '0', 'off', NULL, 'memorable');
 REPLACE INTO schematables (des, public_browsable, redist_mode, redist_where, tablename) VALUES ('Stores per-user counters on the global (contrary to the name). These are allocated by the LJ::alloc_user_counter function. Please see also [dbtable[counter]].', '0', 'off', NULL, 'usercounter');
 REPLACE INTO schematables (des, public_browsable, redist_mode, redist_where, tablename) VALUES ('Stores the documentation for the database tables.', '0', 'replace', NULL, 'schematables');
diff -r 8a1034a41fe1 -r ee7de5f9dd15 bin/upgrading/move0cluster.pl
--- a/bin/upgrading/move0cluster.pl	Sat Sep 05 10:51:57 2009 +0000
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,867 +0,0 @@
-#!/usr/bin/perl
-#
-# Moves a user between clusters.
-#
-
-use strict;
-use Getopt::Long;
-
-my $opt_del = 0;
-my $opt_destdel = 0;
-my $opt_useslow = 0;
-my $opt_slowalloc = 0;
-my $opt_verbose = 1;
-my $opt_movemaster = 0;
-my $opt_prelocked = 0;
-my $opt_expungedel = 0;
-my $opt_ignorebit = 0;
-exit 1 unless GetOptions('delete' => \$opt_del,
-                         'destdelete' => \$opt_destdel,
-                         'useslow' => \$opt_useslow, # use slow db role for read
-                         'slowalloc' => \$opt_slowalloc, # see note below
-			 'verbose=i' => \$opt_verbose,
-			 'movemaster|mm' => \$opt_movemaster,
-                         'prelocked' => \$opt_prelocked,
-			 'expungedel' => \$opt_expungedel,
-			 'ignorebit' => \$opt_ignorebit,
-                         );
-my $optv = $opt_verbose;
-
-require "$ENV{'LJHOME'}/cgi-bin/ljlib.pl";
-require "$ENV{'LJHOME'}/cgi-bin/ljcmdbuffer.pl";
-
-my $dbh = LJ::get_dbh({raw=>1}, "master");
-die "No master db available.\n" unless $dbh;
-$dbh->do("SET wait_timeout=28800");
-
-my $dbr = $dbh;
-if ($opt_useslow) {
-    $dbr = LJ::get_dbh({raw=>1}, "slow");
-    unless ($dbr) { die "Can't get slow db from which to read.\n"; }
-}
-
-my $user = LJ::canonical_username(shift @ARGV);
-my $dclust = shift @ARGV;
-
-# tables which are dumbly copied by sucking all into memory first.
-# use smarter mover code for anything that shouldn't all go into memory.
-# also, to use this you have to define the primary keys below
-my @manual_move = qw(loginstall ratelog sessions userproplite2
-                     sessions_data userbio userpicblob2 userpropblob
-                     modlog modblob counter
-                     links userblob clustertrack2);
-sub usage {
-    die "Usage:\n  movecluster.pl <user> <destination cluster #>\n";
-}
-
-usage() unless defined $user;
-usage() unless defined $dclust;
-
-die "Failed to get move lock.\n"
-    unless ($dbh->selectrow_array("SELECT GET_LOCK('moveucluster-$user', 10)"));
-
-my $u = $dbh->selectrow_hashref("SELECT * FROM user WHERE user=?", undef, $user);
-die "Non-existent user $user.\n" unless $u;
-
-die "Can't move back to legacy cluster 0\n" unless $dclust;
-
-my $dbch = LJ::get_cluster_master({raw=>1}, $dclust);
-
-die "Undefined or down cluster \#$dclust\n" unless $dbch;
-$dbch->do("SET wait_timeout=28800");
-
-my $separate_cluster = LJ::use_diff_db("master", "cluster$dclust");
-
-$dbh->{'RaiseError'} = 1;
-$dbch->{'RaiseError'} = 1;
-
-my $sclust = $u->{'clusterid'};
-
-if ($sclust == $dclust) {
-    die "User '$user' is already on cluster $dclust\n";
-}
-
-if ($sclust) {
-    verify_movable_tables();
-}
-
-# original cluster db handle.
-my $dbo;
-if ($sclust) {
-    $dbo = $opt_movemaster ?
-        LJ::get_dbh({raw=>1}, "cluster$u->{clusterid}movemaster") :
-	LJ::get_cluster_master({raw=>1}, $u);
-    die "Can't get source cluster handle.\n" unless $dbo;
-    $dbo->{'RaiseError'} = 1;
-    $dbo->do("SET wait_timeout=28800");
-}
-
-my $userid = $u->{'userid'};
-
-# find readonly cap class, complain if not found
-my $readonly_bit = undef;
-foreach (keys %LJ::CAP) {
-    if ($LJ::CAP{$_}->{'_name'} eq "_moveinprogress" &&
-        $LJ::CAP{$_}->{'readonly'} == 1) {
-        $readonly_bit = $_;
-        last;
-    }
-}
-unless (defined $readonly_bit) {
-    die "Won't move user without %LJ::CAP capability class named '_moveinprogress' with readonly => 1\n";
-}
-
-# make sure a move isn't already in progress
-if ($opt_prelocked) {
-    unless (($u->{'caps'}+0) & (1 << $readonly_bit)) {
-        die "User '$user' should have been prelocked.\n";
-    }
-} else {
-    if (($u->{'caps'}+0) & (1 << $readonly_bit)) {
-        die "User '$user' is already in the process of being moved? (cap bit $readonly_bit set)\n"
-            unless $opt_ignorebit;
-    }
-}
-
-if ($opt_expungedel && $u->is_deleted &&
-    LJ::mysqldate_to_time($u->{'statusvisdate'}) < time() - 86400*31) {
-
-    print "Expunging user '$u->{'user'}'\n";
-    $dbh->do("INSERT INTO clustermove (userid, sclust, dclust, timestart, timedone) ".
-	     "VALUES (?,?,?,UNIX_TIMESTAMP(),UNIX_TIMESTAMP())", undef, 
-	     $userid, $sclust, 0);
-    LJ::update_user($userid, { clusterid => 0,
-                               statusvis => 'X',
-			       raw => "caps=caps&~(1<<$readonly_bit), statusvisdate=NOW()" });
-    exit 0;
-}
-
-print "Moving '$u->{'user'}' from cluster $sclust to $dclust\n" if $optv >= 1;
-
-# mark that we're starting the move
-$dbh->do("INSERT INTO clustermove (userid, sclust, dclust, timestart) ".
-         "VALUES (?,?,?,UNIX_TIMESTAMP())", undef, $userid, $sclust, $dclust);
-my $cmid = $dbh->{'mysql_insertid'};
-
-# set readonly cap bit on user
-LJ::update_user($userid, { raw => "caps=caps|(1<<$readonly_bit)" })
-    unless $opt_prelocked;
-$dbh->do("SELECT RELEASE_LOCK('moveucluster-$user')");
-
-unless ($opt_prelocked) {
-# wait a bit for writes to stop if journal is somewhat active (last week update)
-    my $secidle = $dbh->selectrow_array("SELECT UNIX_TIMESTAMP()-UNIX_TIMESTAMP(timeupdate) ".
-                                        "FROM userusage WHERE userid=$userid");
-    if ($secidle) {
-        sleep(2) unless $secidle > 86400*7;
-        sleep(1) unless $secidle > 86400;
-    }
-}
-
-# make sure slow is caught up:
-if ($opt_useslow)
-{
-    my $ms = $dbh->selectrow_hashref("SHOW MASTER STATUS");
-    my $loop = 1;
-    while ($loop) {
-        my $ss = $dbr->selectrow_hashref("SHOW SLAVE STATUS");
-        $loop = 0;
-        unless ($ss->{'Log_File'} gt $ms->{'File'} ||
-                ($ss->{'Log_File'} eq $ms->{'File'} && $ss->{'Pos'} >= $ms->{'Position'}))
-        {
-            $loop = 1;
-            print "Waiting for slave ($ss->{'Pos'} < $ms->{'Position'})\n";
-            sleep 1;
-        }
-    }
-}
-
-my $last = time();
-my $stmsg = sub {
-    my $msg = shift;
-    my $now = time();
-    return if ($now < $last + 1);
-    $last = $now;
-    print $msg;
-};
-
-my %bufcols = ();  # db|table -> scalar "(foo, anothercol, lastcol)" or undef or ""
-my %bufrows = ();  # db|table -> [ []+ ]
-my %bufdbmap = (); # scalar(DBI hashref) -> DBI hashref
-
-my $flush_buffer = sub {
-    my $dbandtable = shift;
-    my ($db, $table) = split(/\|/, $dbandtable);
-    $db = $bufdbmap{$db};
-    return unless exists $bufcols{$dbandtable};
-    my $sql = "REPLACE INTO $table $bufcols{$dbandtable} VALUES ";
-    $sql .= join(", ",
-                 map { my $r = $_;
-                       "(" . join(", ",
-                                  map { $db->quote($_) } @$r) . ")" }
-                 @{$bufrows{$dbandtable}});
-    $db->do($sql);
-    delete $bufrows{$dbandtable};
-    delete $bufcols{$dbandtable};
-};
-
-my $flush_all = sub {
-    foreach (keys %bufcols) {
-        $flush_buffer->($_);
-    }
-};
-
-my $replace_into = sub {
-    my $db = ref $_[0] ? shift : $dbch;  # optional first arg
-    my ($table, $cols, $max, @vals) = @_;
-    my $dbandtable = scalar($db) . "|$table";
-    $bufdbmap{$db} = $db;
-    if (exists $bufcols{$dbandtable} && $bufcols{$dbandtable} ne $cols) {
-        $flush_buffer->($dbandtable);
-    }
-    $bufcols{$dbandtable} = $cols;
-    push @{$bufrows{$dbandtable}}, [ @vals ];
-
-    if (scalar @{$bufrows{$dbandtable}} > $max) {
-        $flush_buffer->($dbandtable);
-    }
-};
-
-# assume never tried to move this user before.  however, if reported crap
-# in the oldids table, we'll revert to slow alloc_id functionality,
-# where we do a round-trip to $dbh for everything and see if every id
-# has been remapped already.  otherwise we do it in perl and batch
-# updates to the oldids table, which is the common/fast case.
-my $first_move = ! $opt_slowalloc;
-
-my %alloc_data;
-my %alloc_arealast;
-my $alloc_id = sub {
-    my ($area, $orig) = @_;
-
-    # fast version
-    if ($first_move) {
-        my $id = $alloc_data{$area}->{$orig} = ++$alloc_arealast{$area};
-        $replace_into->($dbh, "oldids", "(area, oldid, userid, newid)", 250,
-                        $area, $orig, $userid, $id);
-        return $id;
-    }
-
-    # slow version
-    $dbh->{'RaiseError'} = 0;
-    $dbh->do("INSERT INTO oldids (area, oldid, userid, newid) ".
-             "VALUES ('$area', $orig, $userid, NULL)");
-    my $id;
-    if ($dbh->err) {
-        $id = $dbh->selectrow_array("SELECT newid FROM oldids WHERE area='$area' AND oldid=$orig");
-    } else {
-        $id = $dbh->{'mysql_insertid'};
-    }
-    $dbh->{'RaiseError'} = 1;
-    $alloc_data{$area}->{$orig} = $id;
-    return $id;
-};
-
-my $bufread;
-
-if ($sclust == 0)
-{
-    # do bio stuff
-    {
-        my $bio = $dbr->selectrow_array("SELECT bio FROM userbio WHERE userid=$userid");
-        my $bytes = length($bio);
-        $dbch->do("REPLACE INTO dudata (userid, area, areaid, bytes) VALUES ($userid, 'B', 0, $bytes)");
-        if ($separate_cluster) {
-            $bio = $dbh->quote($bio);
-            $dbch->do("REPLACE INTO userbio (userid, bio) VALUES ($userid, $bio)");
-        }
-    }
-
-    my @itemids = reverse @{$dbr->selectcol_arrayref("SELECT itemid FROM log ".
-                                                     "WHERE ownerid=$u->{'userid'} ".
-                                                     "ORDER BY ownerid, rlogtime")};
-
-    $bufread = make_buffer_reader("itemid", \@itemids);
-
-    my $todo = @itemids;
-    my $done = 0;
-    my $stime = time();
-    print "Total: $todo\n";
-
-    # moving time, journal item at a time, and everything recursively under it
-    foreach my $itemid (@itemids) {
-        movefrom0_logitem($itemid);
-        $done++;
-        my $percent = $done/$todo;
-        my $elapsed = time() - $stime;
-        my $totaltime = $elapsed * (1 / $percent);
-        my $timeremain = int($totaltime - $elapsed);
-        $stmsg->(sprintf "$user: copy $done/$todo (%.2f%%) +${elapsed}s -${timeremain}s\n", 100*$percent);
-    }
-
-    $flush_all->();
-
-    # update their memories.  in particular, any memories of their own
-    # posts need to to be updated from the (0, globalid) to
-    # (journalid, jitemid) format, to make the memory filter feature
-    # work.  (it checks the first 4 bytes only, not joining the
-    # globalid on the clustered log table)
-    print "Fixing memories.\n";
-    my @fix = @{$dbh->selectall_arrayref("SELECT memid, jitemid FROM memorable WHERE ".
-                                         "userid=$u->{'userid'} AND journalid=0")};
-    foreach my $f (@fix) {
-        my ($memid, $newid) = ($f->[0], $alloc_data{'L'}->{$f->[1]});
-        next unless $newid;
-        my ($newid2, $anum) = $dbch->selectrow_array("SELECT jitemid, anum FROM log2 ".
-                                                     "WHERE journalid=$u->{'userid'} AND ".
-                                                     "jitemid=$newid");
-        if ($newid2 == $newid) {
-            my $ditemid = $newid * 256 + $anum;
-            print "UPDATE $memid TO $ditemid\n";
-            $dbh->do("UPDATE memorable SET journalid=$u->{'userid'}, jitemid=$ditemid ".
-                     "WHERE memid=$memid");
-        }
-    }
-
-    # fix polls
-    print "Fixing polls.\n";
-    @fix = @{$dbh->selectall_arrayref("SELECT pollid, itemid FROM poll ".
-                                      "WHERE journalid=$u->{'userid'}")};
-    foreach my $f (@fix) {
-        my ($pollid, $newid) = ($f->[0], $alloc_data{'L'}->{$f->[1]});
-        next unless $newid;
-        my ($newid2, $anum) = $dbch->selectrow_array("SELECT jitemid, anum FROM log2 ".
-                                                     "WHERE journalid=$u->{'userid'} AND ".
-                                                     "jitemid=$newid");
-        if ($newid2 == $newid) {
-            my $ditemid = $newid * 256 + $anum;
-            print "UPDATE $pollid TO $ditemid\n";
-            $dbh->do("UPDATE poll SET itemid=$ditemid WHERE pollid=$pollid");
-        }
-    }
-
-    # move userpics
-    print "Copying over userpics.\n";
-    my @pics = @{$dbr->selectcol_arrayref("SELECT picid FROM userpic WHERE ".
-                                          "userid=$u->{'userid'}")};
-    foreach my $picid (@pics) {
-        print "  picid\#$picid...\n";
-        my $imagedata = $dbr->selectrow_array("SELECT imagedata FROM userpicblob ".
-                                              "WHERE picid=$picid");
-        $imagedata = $dbh->quote($imagedata);
-        $dbch->do("REPLACE INTO userpicblob2 (userid, picid, imagedata) VALUES ".
-                  "($u->{'userid'}, $picid, $imagedata)");
-    }
-
-    $dbh->do("UPDATE userusage SET lastitemid=0 WHERE userid=$userid");
-
-    my $dversion = 2;
-
-    # if everything's good (nothing's died yet), then delete all from source
-    if ($opt_del)
-    {
-        # before we start deleting, record they've moved servers.
-        LJ::update_user($userid, { dversion => $dversion, clusterid => $dclust });
-
-        $done = 0;
-        $stime = time();
-        foreach my $itemid (@itemids) {
-            deletefrom0_logitem($itemid);
-            $done++;
-            my $percent = $done/$todo;
-            my $elapsed = time() - $stime;
-            my $totaltime = $elapsed * (1 / $percent);
-            my $timeremain = int($totaltime - $elapsed);
-            $stmsg->(sprintf "$user: delete $done/$todo (%.2f%%) +${elapsed}s -${timeremain}s\n", 100*$percent);
-        }
-
-        # delete bio from source, if necessary
-        if ($separate_cluster) {
-            $dbh->do("DELETE FROM userbio WHERE userid=$userid");
-        }
-
-        # delete source userpics
-        print "Deleting cluster0 userpics...\n";
-        foreach my $picid (@pics) {
-            print "  picid\#$picid...\n";
-            $dbh->do("DELETE FROM userpicblob WHERE picid=$picid");
-        }
-
-        # unset read-only bit (marks the move is complete, also, and not aborted mid-delete)
-        LJ::update_user($userid, { raw => "caps=caps&~(1<<$readonly_bit)" });
-        $dbh->do("UPDATE clustermove SET sdeleted='1', timedone=UNIX_TIMESTAMP() ".
-                 "WHERE cmid=?", undef, $cmid);
-                 
-    }
-    else
-    {
-        # unset readonly and move to new cluster in one update
-        LJ::update_user($userid, { dversion => $dversion, clusterid => $dclust,
-                                   raw => "caps=caps&~(1<<$readonly_bit)" });
-        $dbh->do("UPDATE clustermove SET sdeleted='0', timedone=UNIX_TIMESTAMP() ".
-                 "WHERE cmid=?", undef, $cmid);
-    }
-    exit 0;
-} 
-elsif ($sclust > 0) 
-{
-    print "Moving away from cluster $sclust\n" if $optv;
-
-    while (my $cmd = $dbo->selectrow_array("SELECT cmd FROM cmdbuffer WHERE journalid=$userid")) {
-	my $dbcm = LJ::get_cluster_master($sclust);
-        print "Flushing cmdbuffer for cmd: $cmd\n" if $optv > 1;
-        LJ::Cmdbuffer::flush($dbh, $dbcm, $cmd, $userid);
-    }
-
-    my $pri_key = {
-        # flush this first:
-        'cmdbuffer' => 'journalid',
-
-        # this is populated as we do log/talk
-        'dudata' => 'userid',
-
-        # manual
-        'loginstall' => 'userid',
-        'ratelog' => 'userid',
-        'sessions' => 'userid',
-        'sessions_data' => 'userid',
-        'userbio' => 'userid',
-        'userpicblob2' => 'userid',
-        'userproplite2' => 'userid',
-        'modlog' => 'journalid',
-        'modblob' => 'journalid',
-        'counter' => 'journalid',
-        'userblob' => 'journalid',
-        'userpropblob' => 'userid',
-        'clustertrack2' => 'userid',
-
-        # log
-        'log2' => 'journalid',
-        'logsec2' => 'journalid',
-        'logprop2' => 'journalid',
-        'logtext2' => 'journalid',
-
-        # talk
-        'talk2' => 'journalid',
-        'talkprop2' => 'journalid',
-        'talktext2' => 'journalid',
-
-        # no primary key... move up by posttime
-        'talkleft' => 'userid',
-
-        # link lists
-        'links' => 'journalid',
-    };
-
-    # ask the local mods if they have any tables to move
-    my @local_tables;
-    my $local_tables = LJ::run_hook("moveucluster_local_tables");
-    if ($local_tables) {
-        while (my ($tab, $key) = each %$local_tables) {
-            push @local_tables, $tab;
-            $pri_key->{$tab} = $key;
-        }
-    }
-
-    my @existing_data;
-    print "Checking for existing data on target cluster...\n" if $optv > 1;
-    foreach my $table (sort keys %$pri_key) {
-        my $pri = $pri_key->{$table};
-        my $is_there = $dbch->selectrow_array("SELECT $pri FROM $table WHERE $pri=$userid LIMIT 1");
-        next unless $is_there;
-        if ($opt_destdel) {
-            while ($dbch->do("DELETE FROM $table WHERE $pri=$userid LIMIT 500") > 0) {
-                print "  deleted from $table\n" if $optv;
-            }
-        } else {
-            push @existing_data, $table;
-        }
-    }
-    if (@existing_data) {
-        die "  Existing data in tables: @existing_data\n";
-    }
-
-    my %pendreplace;  # "logprop2:(col,col)" => { 'values' => [ [a, b, c], [d, e, f] ],
-                      #                           'bytes' => 3043, 'recs' => 35 }
-    my $flush = sub {
-        my $dest = shift;
-        return 1 unless $pendreplace{$dest};
-        my ($table, $cols) = split(/:/, $dest);
-        my $vals;
-        foreach my $v (@{$pendreplace{$dest}->{'values'}}) {
-            $vals .= "," if $vals;
-            $vals .= "(" . join(',', map { $dbch->quote($_) } @$v) . ")";
-        }
-        print "  flushing write to $table\n" if $optv > 1;
-        $dbch->do("REPLACE INTO $table $cols VALUES $vals");
-	die $dbh->errstr if $dbch->err;
-        delete $pendreplace{$dest};
-        return 1;
-    };
-
-    my $write = sub {
-        my $dest = shift;
-        my @values = @_;
-        my $new_bytes = 0; foreach (@values) { $new_bytes += length($_); }
-        push @{$pendreplace{$dest}->{'values'}}, \@values;
-        $pendreplace{$dest}->{'bytes'} += $new_bytes;
-        $pendreplace{$dest}->{'recs'}++;
-        if ($pendreplace{$dest}->{'bytes'} > 1024*500 ||
-            $pendreplace{$dest}->{'recs'} > 500) { $flush->($dest); }
-    };
-
-    # manual moving (dumb copies)
-    foreach my $table (@manual_move, @local_tables) {
-	next if ($table eq "modlog" || $table eq "modblob") && $u->is_person;
-        print "  moving $table ...\n" if $optv > 1;
-        my @cols;
-        my $sth = $dbo->prepare("DESCRIBE $table");
-        $sth->execute;
-        my $styleidcolnum = -1;
-        my $colnum = 0;
-        while ($_ = $sth->fetchrow_hashref) {
-            push @cols, $_->{'Field'};
-            $styleidcolnum = $colnum if $_->{'Field'} eq 'styleid';
-            $colnum++;
-        }
-        my $cols = join(',', @cols);
-        my $dest = "$table:($cols)";
-        my $pri = $pri_key->{$table};
-        $sth = $dbo->prepare("SELECT $cols FROM $table WHERE $pri=$userid");
-        $sth->execute;
-        while (my @vals = $sth->fetchrow_array) {
-            $write->($dest, @vals);
-        }
-    }
-
-    # size of bio
-    my $bio_size = $dbch->selectrow_array("SELECT LENGTH(bio) FROM userbio WHERE userid=$userid");
-    $write->("dudata:(userid,area,areaid,bytes)", $userid, 'B', 0, $bio_size) if $bio_size;
-
-    # journal items
-    {
-        my $maxjitem = $dbo->selectrow_array("SELECT MAX(jitemid) FROM log2 WHERE journalid=$userid");
-        my $load_amt = 1000;
-        my ($lo, $hi) = (1, $load_amt);
-        my $sth;
-        my $cols = "security,allowmask,journalid,jitemid,posterid,eventtime,logtime,compressed,anum,replycount,year,month,day,rlogtime,revttime"; # order matters.  see indexes below
-        while ($lo <= $maxjitem) {
-            print "  log ($lo - $hi, of $maxjitem)\n" if $optv > 1;
-
-            # log2/logsec2
-            $sth = $dbo->prepare("SELECT $cols FROM log2 ".
-                                 "WHERE journalid=$userid AND jitemid BETWEEN $lo AND $hi");
-            $sth->execute;
-            while (my @vals = $sth->fetchrow_array) {
-                $write->("log2:($cols)", @vals);
-
-                if ($vals[0] eq "usemask") {
-                    $write->("logsec2:(journalid,jitemid,allowmask)",
-                             $userid, $vals[3], $vals[1]);
-                }
-            }
-
-            # logprop2
-            $sth = $dbo->prepare("SELECT journalid,jitemid,propid,value ".
-                                 "FROM logprop2 WHERE journalid=$userid AND jitemid BETWEEN $lo AND $hi");
-            $sth->execute;
-            while (my @vals = $sth->fetchrow_array) {
-                $write->("logprop2:(journalid,jitemid,propid,value)", @vals);
-            }
-
-            # logtext2
-            $sth = $dbo->prepare("SELECT journalid,jitemid,subject,event ".
-                                 "FROM logtext2 WHERE journalid=$userid AND jitemid BETWEEN $lo AND $hi");
-            $sth->execute;
-            while (my @vals = $sth->fetchrow_array) {
-                my $size = length($vals[2]) + length($vals[3]);
-                LJ::text_compress(\$vals[3]);
-                $write->("logtext2:(journalid,jitemid,subject,event)", @vals);
-                $write->("dudata:(userid,area,areaid,bytes)", $userid, 'L', $vals[1], $size);
-            }
-
-            $hi += $load_amt; $lo += $load_amt;
-        }
-    }
-
-    # comments
-    {
-        my $maxtalkid = $dbo->selectrow_array("SELECT MAX(jtalkid) FROM talk2 WHERE journalid=$userid");
-        my $load_amt = 1000;
-        my ($lo, $hi) = (1, $load_amt);
-        my $sth;
-        
-        my %cols = ('talk2' => 'journalid,jtalkid,nodetype,nodeid,parenttalkid,posterid,datepost,state',
-                    'talkprop2' => 'journalid,jtalkid,tpropid,value',
-                    'talktext2' => 'journalid,jtalkid,subject,body');
-        while ($lo <= $maxtalkid) {
-            print "  talk ($lo - $hi, of $maxtalkid)\n" if $optv > 1;
-            foreach my $table (keys %cols) {
-                $sth = $dbo->prepare("SELECT $cols{$table} FROM $table ".
-                                     "WHERE journalid=$userid AND jtalkid BETWEEN $lo AND $hi");
-                $sth->execute;
-                while (my @vals = $sth->fetchrow_array) {
-                    LJ::text_compress(\$vals[3]) if $table eq "talktext2";
-                    $write->("$table:($cols{$table})", @vals);
-                }
-            }
-            
-            $hi += $load_amt; $lo += $load_amt;
-        }
-    }
-
-    # talkleft table.  
-    {
-        # no primary key... delete all of target first.
-        while ($dbch->do("DELETE FROM talkleft WHERE userid=$userid LIMIT 1000") > 0) {
-            print "  deleted from talkleft\n" if $optv > 1;
-        }
-
-        my $last_max = 0;
-        my $cols = "userid,posttime,journalid,nodetype,nodeid,jtalkid,publicitem";
-        while (defined $last_max) {
-            print "  talkleft: $last_max\n" if $optv > 1;
-            my $sth = $dbo->prepare("SELECT $cols FROM talkleft WHERE userid=$userid ".
-                                    "AND posttime > $last_max ORDER BY posttime LIMIT 1000");
-            $sth->execute;
-            undef $last_max;
-            while (my @vals = $sth->fetchrow_array) {
-                $write->("talkleft:($cols)", @vals);
-                $last_max = $vals[1];
-            }
-        }
-    }
-
-    # flush remaining items
-    foreach (keys %pendreplace) { $flush->($_); }
-
-    # unset readonly and move to new cluster in one update
-    LJ::update_user($userid, { clusterid => $dclust, raw => "caps=caps&~(1<<$readonly_bit)" });
-    print "Moved.\n" if $optv;
-
-    # delete from source cluster
-    if ($opt_del) {
-        print "Deleting from source cluster...\n" if $optv;
-        foreach my $table (sort keys %$pri_key) {
-            my $pri = $pri_key->{$table};
-            while ($dbo->do("DELETE FROM $table WHERE $pri=$userid LIMIT 500") > 0) {
-                print "  deleted from $table\n" if $optv;
-            }
-        }
-    } else {
-        # at minimum, we delete the clustertrack2 row so it doesn't get
-        # included in a future ljumover.pl query from that cluster.
-        $dbo->do("DELETE FROM clustertrack2 WHERE userid=$userid");
-    }
-
-    $dbh->do("UPDATE clustermove SET sdeleted=?, timedone=UNIX_TIMESTAMP() ".
-             "WHERE cmid=?", undef, $opt_del ? 1 : 0, $cmid);
-    exit 0;
-}
-
-sub deletefrom0_logitem
-{
-    my $itemid = shift;
-
-    # delete all the comments
-    my $talkids = $dbh->selectcol_arrayref("SELECT talkid FROM talk ".
-                                           "WHERE nodetype='L' AND nodeid=$itemid");
-
-    my $talkidin = join(",", @$talkids);
-    if ($talkidin) {
-        foreach my $table (qw(talktext talkprop talk)) {
-            $dbh->do("DELETE FROM $table WHERE talkid IN ($talkidin)");
-        }
-    }
-
-    $dbh->do("DELETE FROM logsec WHERE ownerid=$userid AND itemid=$itemid");
-    foreach my $table (qw(logprop logtext log)) {
-        $dbh->do("DELETE FROM $table WHERE itemid=$itemid");
-    }
-}
-
-sub movefrom0_logitem
-{
-    my $itemid = shift;
-
-    my $item = $bufread->(100, "SELECT * FROM log", $itemid);
-    my $itemtext = $bufread->(50, "SELECT itemid, subject, event FROM logtext", $itemid);
-    return 1 unless $item && $itemtext;   # however that could happen.
-
-    # we need to allocate a new jitemid (journal-specific itemid) for this item now.
-    my $jitemid = $alloc_id->('L', $itemid);
-    unless ($jitemid) {
-        die "ERROR: could not allocate a new jitemid\n";
-    }
-    $dbh->{'RaiseError'} = 1;
-    $item->{'jitemid'} = $jitemid;
-    $item->{'anum'} = int(rand(256));
-
-    # copy item over:
-    $replace_into->("log2", "(journalid, jitemid, posterid, eventtime, logtime, ".
-                    "compressed, security, allowmask, replycount, year, month, day, ".
-                    "rlogtime, revttime, anum)",
-                    50, map { $item->{$_} } qw(ownerid jitemid posterid eventtime
-                                               logtime compressed security allowmask replycount
-                                               year month day rlogtime revttime anum));
-
-    $replace_into->("logtext2", "(journalid, jitemid, subject, event)", 10,
-                    $userid, $jitemid, map { $itemtext->{$_} } qw(subject event));
-
-    # add disk usage info!  (this wasn't in cluster0 anywhere)
-    my $bytes = length($itemtext->{'event'}) + length($itemtext->{'subject'});
-    $replace_into->("dudata", "(userid, area, areaid, bytes)", 50, $userid, 'L', $jitemid, $bytes);
-
-    # add the logsec item, if necessary:
-    if ($item->{'security'} ne "public") {
-        $replace_into->("logsec2", "(journalid, jitemid, allowmask)", 50,
-                        map { $item->{$_} } qw(ownerid jitemid allowmask));
-    }
-
-    # copy its logprop over:
-    while (my $lp = $bufread->(50, "SELECT itemid, propid, value FROM logprop", $itemid)) {
-        next unless $lp->{'value'};
-        $replace_into->("logprop2", "(journalid, jitemid, propid, value)", 50,
-                        $userid, $jitemid, $lp->{'propid'}, $lp->{'value'});
-    }
-
-    # copy its talk shit over:
-    my %newtalkids = (0 => 0);  # 0 maps back to 0 still
-    my $talkids = $dbr->selectcol_arrayref("SELECT talkid FROM talk ".
-                                           "WHERE nodetype='L' AND nodeid=$itemid");
-    my @talkids = sort { $a <=> $b } @$talkids;
-    my $treader = make_buffer_reader("talkid", \@talkids);
-    foreach my $t (@talkids) {
-        movefrom0_talkitem($t, $jitemid, \%newtalkids, $item, $treader);
-    }
-}
-
-sub movefrom0_talkitem
-{
-    my $talkid = shift;
-    my $jitemid = shift;
-    my $newtalkids = shift;
-    my $logitem = shift;
-    my $treader = shift;
-
-    my $item = $treader->(100, "SELECT *, UNIX_TIMESTAMP(datepost) AS 'datepostunix' FROM talk", $talkid);
-    my $itemtext = $treader->(50, "SELECT talkid, subject, body FROM talktext", $talkid);
-    return 1 unless $item && $itemtext;   # however that could happen.
-
-    # abort if this is a stranded entry.  (shouldn't happen, anyway.  even if it does, it's 
-    # not like we're losing data:  the UI (talkread.bml) won't show it anyway)
-    return unless defined $newtalkids->{$item->{'parenttalkid'}};
-
-    # we need to allocate a new jitemid (journal-specific itemid) for this item now.
-    my $jtalkid = $alloc_id->('T', $talkid);
-    unless ($jtalkid) {
-        die "ERROR: could not allocate a new jtalkid\n";
-    }
-    $newtalkids->{$talkid} = $jtalkid;
-    $dbh->{'RaiseError'} = 1;
-
-    # copy item over:
-    $replace_into->("talk2", "(journalid, jtalkid, parenttalkid, nodeid, ".
-                    "nodetype, posterid, datepost, state)", 50,
-                    $userid, $jtalkid, $newtalkids->{$item->{'parenttalkid'}},
-                    $jitemid, 'L',  map { $item->{$_} } qw(posterid datepost state));
-
-
-    $replace_into->("talktext2", "(journalid, jtalkid, subject, body)",
-                    20, $userid, $jtalkid, map { $itemtext->{$_} } qw(subject body));
-
-    # copy its logprop over:
-    while (my $lp = $treader->(50, "SELECT talkid, tpropid, value FROM talkprop", $talkid)) {
-        next unless $lp->{'value'};
-        $replace_into->("talkprop2", "(journalid, jtalkid, tpropid, value)", 50,
-                        $userid, $jtalkid, $lp->{'tpropid'}, $lp->{'value'});
-    }
-
-    # note that poster commented here
-    if ($item->{'posterid'}) {
-        my $pub = $logitem->{'security'} eq "public" ? 1 : 0;
-        my ($table, $db) = ("talkleft_xfp", $dbh);
-        ($table, $db) = ("talkleft", $dbch) if $userid == $item->{'posterid'};
-        $replace_into->($db, $table, "(userid, posttime, journalid, nodetype, ".
-                        "nodeid, jtalkid, publicitem)", 50,
-                        $item->{'posterid'}, $item->{'datepostunix'}, $userid,
-                        'L', $jitemid, $jtalkid, $pub);
-    }
-}
-
-sub make_buffer_reader
-{
-    my $pricol = shift;
-    my $valsref = shift;
-
-    my %bfd;  # buffer read data.  halfquery -> { 'rows' => { id => [] },
-              #                                   'remain' => [], 'loaded' => { id => 1 } }
-    return sub
-    {
-        my ($amt, $hq, $pid) = @_;
-        if (not defined $bfd{$hq}->{'loaded'}->{$pid})
-        {
-            if (not exists $bfd{$hq}->{'remain'}) {
-                $bfd{$hq}->{'remain'} = [ @$valsref ];
-            }
-
-            my @todo;
-            for (1..$amt) {
-                next unless @{$bfd{$hq}->{'remain'}};
-                my $id = shift @{$bfd{$hq}->{'remain'}};
-                push @todo, $id;
-                $bfd{$hq}->{'loaded'}->{$id} = 1;
-            }
-
-            if (@todo) {
-                my $sql = "$hq WHERE $pricol IN (" . join(",", @todo) . ")";
-                my $sth = $dbr->prepare($sql);
-                $sth->execute;
-                while (my $r = $sth->fetchrow_hashref) {
-                    push @{$bfd{$hq}->{'rows'}->{$r->{$pricol}}}, $r;
-                }
-            }
-        }
-
-        return shift @{$bfd{$hq}->{'rows'}->{$pid}};
-    };
-}
-
-# this function needs to die loudly if moveucluster.pl is unable to move
-# any type of table that exists on this installation
-sub verify_movable_tables {
-    my %table;  # tablename -> unhandled flag
-
-    # first, assume everything's unhandled
-    foreach my $t (@LJ::USER_TABLES, @LJ::USER_TABLES_LOCAL) {
-        $table{$t} = 1;
-    }
-
-    # now, clear things we know how to move
-    foreach my $t (qw(cmdbuffer dudata log2 logsec2 logprop2 logtext2
-                      talk2 talkprop2 talktext2 talkleft
-                      ), @manual_move) {
-        delete $table{$t};
-    }
-
-    # local stuff
-    my $local_tables = LJ::run_hook("moveucluster_local_tables");
-    if ($local_tables) {
-        while (my ($tab, $key) = each %$local_tables) {
-            delete $table{$tab};
-        }
-    }
-
-    # things we list as active tables but don't use yet
-    delete $table{"events"};
-
-    # things we don't move because it doesn't really matter
-    delete $table{"captcha_session"};
-
-    if (%table) {
-        die "ERROR.  Won't try to move user, because this mover script can't move all live tables for this user.  List of tables without mover code available: \n -- " . join("\n -- ", sort keys %table), "\n";
-    }
-
-}
-
-1; # return true;
diff -r 8a1034a41fe1 -r ee7de5f9dd15 bin/upgrading/update-db-general.pl
--- a/bin/upgrading/update-db-general.pl	Sat Sep 05 10:51:57 2009 +0000
+++ b/bin/upgrading/update-db-general.pl	Sat Sep 05 11:33:28 2009 +0000
@@ -975,6 +975,7 @@ register_tabledrop("adoptlast");
 register_tabledrop("adoptlast");
 register_tabledrop("urimap");
 register_tabledrop("syndicated_hubbub");
+register_tabledrop("oldids");
 
 register_tablecreate("portal", <<'EOC');
 CREATE TABLE portal (
@@ -1116,22 +1117,6 @@ CREATE TABLE includetext (
 
     INDEX (updatetime)
 )
-EOC
-
-# TODO: As part of migration from LJ to DW, hard redirect everything in here,
-# then get rid of this table and of code that references it. Per discussion
-# with xb95, it's not needed anywhere.
-register_tablecreate("oldids", <<'EOC');
-CREATE TABLE oldids (
-    area     CHAR(1) NOT NULL,
-    oldid    INT UNSIGNED NOT NULL,
-    UNIQUE (area, oldid),
-    userid   INT UNSIGNED NOT NULL,
-    newid    INT UNSIGNED NOT NULL AUTO_INCREMENT,
-
-    PRIMARY KEY (area,userid, newid),
-    INDEX (userid)
-) TYPE=MYISAM
 EOC
 
 register_tablecreate("dudata", <<'EOC');
--------------------------------------------------------------------------------