summaryrefslogtreecommitdiffstats
path: root/syncshadowdb
diff options
context:
space:
mode:
Diffstat (limited to 'syncshadowdb')
-rwxr-xr-xsyncshadowdb327
1 files changed, 0 insertions, 327 deletions
diff --git a/syncshadowdb b/syncshadowdb
deleted file mode 100755
index 23d53a6f3..000000000
--- a/syncshadowdb
+++ /dev/null
@@ -1,327 +0,0 @@
-#!/usr/bonsaitools/bin/perl -w
-# -*- Mode: perl; indent-tabs-mode: nil -*-
-#
-# The contents of this file are subject to the Mozilla Public
-# License Version 1.1 (the "License"); you may not use this file
-# except in compliance with the License. You may obtain a copy of
-# the License at http://www.mozilla.org/MPL/
-#
-# Software distributed under the License is distributed on an "AS
-# IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
-# implied. See the License for the specific language governing
-# rights and limitations under the License.
-#
-# The Original Code is the Bugzilla Bug Tracking System.
-#
-# The Initial Developer of the Original Code is Netscape Communications
-# Corporation. Portions created by Netscape are
-# Copyright (C) 1998 Netscape Communications Corporation. All
-# Rights Reserved.
-#
-# Contributor(s): Terry Weissman <terry@mozilla.org>
-# David Gardiner <david.gardiner@unisa.edu.au>
-
-use strict;
-
-use lib qw(.);
-
-use Bugzilla::Config qw(:DEFAULT :admin);
-
-require "globals.pl";
-require "defparams.pl";
-
-# Shut up misguided -w warnings about "used only once". "use vars" just
-# doesn't work for me.
-
-sub sillyness {
- my $zz;
- open SAVEOUT,">/dev/null";
- $zz = $::db;
- $zz = $::dbwritesallowed;
- $zz = $::db_host;
- $zz = $::db_port;
-}
-
-my $verbose = 0;
-my $syncall = 0;
-my $shutdown = 0;
-my $tempdir = "data";
-my $force = 0;
-
-my $shutdown_msg = "Bugzilla is temporarily disabled while the database is backed up. Try again in a few minutes.";
-
-sub Usage {
- print "Usage: syncshadowdb [-v] [-syncall] [-shutdown] [-tempdir dirname] [-force]\n";
- exit;
-}
-
-while (my $opt = shift @ARGV) {
- if ($opt eq '-v') {
- $verbose = 1;
- } elsif ($opt eq '-syncall') {
- $syncall = 1;
- $verbose = 1;
- } elsif ($opt eq '-shutdown') {
- $shutdown = 1;
- } elsif ($opt eq '-tempdir') {
- my $dir = shift @ARGV;
- if (-d $dir) {
- $tempdir = $dir;
- } else {
- print "$dir does not exist or is not a directory. No syncing performed";
- exit;
- }
- } elsif ($opt eq '-force') {
- $force = 1;
- } elsif ($opt eq '--') {
- # do nothing - null parameter so we can use
- # multi-param system() call in globals.pl
- } else {
- Usage();
- }
-}
-$| = 1;
-
-my $logtostderr = 0;
-
-sub Verbose ($) {
- my ($str) = (@_);
- if ($verbose) {
- if ($logtostderr) {
- print STDERR $str, "\n";
- } else {
- print $str, "\n";
- }
- }
-}
-
-if (!Param("shadowdb")) {
- Verbose("We don't have shadow databases turned on; no syncing performed.");
- exit;
-}
-
-if (!Param("updateshadowdb")) {
- Verbose("This shadow database is not set to be updated by Bugzilla.\nSee the mysql replication FAQ if you want to pause the main db until the\nshadowdb catches up");
- # I could run the commands here, but that involves keeping a connection
- # open to the main db and the shadowdb at the same time, and our current
- # db stuff doesn't support that. Its not sufficient to reconnect, because
- # the lock on the main db will be dropped when the connection closes...
- exit 1;
-}
-
-if (Param("shutdownhtml") && ! $force) {
- Verbose("Bugzilla was shutdown prior to running syncshadowdb. \n" .
- " If you wish to sync anyway, use the -force command line option");
- exit;
-}
-
-my $wasshutdown = "";
-if ($shutdown) {
- Verbose ("Shutting down bugzilla and waiting for connections to clear");
- # Record the old shutdownhtml so it can be restored at the end (this will
- # only be an issue if we are called using the -force command line param)
- $wasshutdown = Param("shutdownhtml");
- SetParam('shutdownhtml', $shutdown_msg);
- WriteParams();
- # Now we need to wait for existing connections to this database to clear. We
- # do this by looking for connections to the main or shadow database using
- # 'mysqladmin processlist'
- my $cmd = "$::mysqlpath/mysqladmin -u $::db_user -h $::db_host -P $::db_port";
- if ($::db_pass) { $cmd .= " -p$::db_pass"; }
- if ($::db_sock) { $cmd .= " -S$::db_sock"; }
- $cmd .= " processlist";
- my $found_proc = 1;
- # We need to put together a nice little regular expression to use in the
- # following loop that'll tell us if the return from mysqladmin contains
- # either the main or shadow database.
- my @dbs = ($::db_name, Param("shadowdb"));
- my $db_expr = "^\\s*(" . join ("\|", @dbs) . ")\\s*\$";
- # Don't let this thing wait forever...
- my $starttime = time();
- while ($found_proc) {
- $found_proc = 0;
- open (PROC, $cmd . "|");
- my @output = <PROC>;
- close (PROC);
- foreach my $line(@output) {
- my @info = split (/\|/, $line);
- # Ignore any line that doesn't have 9 pieces of info
- # or contain Id (pretty printing crap)
- if ($#info != 9 || $line =~ /Id/) { next }
- if ($info[4] =~ m/$db_expr/) {
- $found_proc = 1;
- }
- }
- # If there are still active connections to Bugzilla 10 minutes after
- # shutting it down, then something is wrong.
- if ((time() - $starttime) > 600) {
- # There should be a better way to notify the admin of something bad like
- # this happening.
- Verbose ("*** Waited for 10 minutes and there were still active \n" .
- " connections to the bugzilla database. Giving up.");
- SetParam('shutdownhtml', $wasshutdown);
- WriteParams();
- exit;
- }
- }
-}
-
-
-my $wasusing = Param("queryagainstshadowdb");
-
-SetParam('queryagainstshadowdb', 1); # Force us to be able to use the
- # shadowdb, even if other processes
- # are not supposed to.
-
-
-ConnectToDatabase(1);
-
-Verbose("Acquiring lock");
-if ( $syncall == 1) {
- SendSQL("SELECT GET_LOCK('synclock', 2700)");
-} else {
- SendSQL("SELECT GET_LOCK('synclock', 1)");
-}
-if (!FetchOneColumn()) {
- Verbose("Couldn't get the lock to do the shadow database syncing.");
- exit;
-}
-
-my $shadowtable = "$::db_name.shadowlog";
-
-if (!$syncall) {
- Verbose("Looking for requests to sync the whole database.");
- SendSQL("SELECT id FROM $shadowtable " .
- "WHERE reflected = 0 AND command = 'SYNCUP'");
- if (FetchOneColumn()) {
- $syncall = 1;
- }
-}
-
-if ($syncall) {
- Verbose("Syncing up the shadow database by copying entire database in.");
- if ($wasusing) {
- SetParam('queryagainstshadowdb',0);
- WriteParams();
- if (! $shutdown) {
- Verbose("Disabled reading from the shadowdb. Sleeping 10 seconds to let other procs catch up.");
- sleep(10);
- }
- SetParam('queryagainstshadowdb', 1);
- }
- my @tables;
- SendSQL("SHOW TABLES");
- my $query = "";
- while (MoreSQLData()) {
- my $table = FetchOneColumn();
- push(@tables, $table);
- if ($query) {
- $query .= ", $table WRITE";
- } else {
- $query = "LOCK TABLES $table WRITE";
- }
- }
- if (@tables) {
- Verbose("Locking entire shadow database");
- SendSQL($query);
- foreach my $table (@tables) {
- Verbose("Dropping old shadow table $table");
- SendSQL("DROP TABLE $table");
- }
- SendSQL("UNLOCK TABLES");
- }
- # Carefully lock the whole real database for reading, except for the
- # shadowlog table, which we lock for writing. Then dump everything
- # into the shadowdb database. Then mark everything in the shadowlog
- # as reflected. Only then unlock everything. This sequence causes
- # us to be sure not to miss anything or get something twice.
- SendSQL("USE $::db_name");
- SendSQL("SHOW TABLES");
- @tables = ();
- $query = "LOCK TABLES shadowlog WRITE";
- while (MoreSQLData()) {
- my $table = FetchOneColumn();
- if ($table ne "shadowlog") {
- $query .= ", $table READ";
- push(@tables, $table);
- }
- }
- Verbose("Locking entire database");
- SendSQL($query);
- my $tempfile = "$tempdir/tmpsyncshadow.$$";
- Verbose("Dumping database to a temp file ($tempfile).");
- my @ARGS = ("-u", $::db_user);
- if ($::db_pass) { push @ARGS, "-p$::db_pass" }
- if ($::db_sock) { push @ARGS, "-S$::db_sock" }
- push @ARGS, "-l", "-e", $::db_name, @tables;
- open SAVEOUT, ">&STDOUT"; # stash the original output stream
- open STDOUT, ">$tempfile"; # redirect to file
- select STDOUT; $| = 1; # disable buffering
- system("$::mysqlpath/mysqldump", @ARGS);
- open STDOUT, ">&SAVEOUT"; # redirect back to original stream
- Verbose("Restoring from tempfile into shadowdb");
- my $extra = "-u $::db_user";
- if ($::db_pass) {
- $extra .= " -p$::db_pass";
- }
- if ($::db_sock) {
- $extra .= " -S$::db_sock";
- }
- if ($verbose) {
- $extra .= " -v";
- }
- open(MYSQL, "/bin/cat $tempfile | $::mysqlpath/mysql $extra " .
- Param("shadowdb") . "|") || die "Couldn't do db copy";
- my $count = 0;
- while (<MYSQL>) {
- print ".";
- $count++;
- if ($count % 70 == 0) {
- print "\n";
- }
- }
- close(MYSQL);
- unlink($tempfile);
- Verbose("");
-
-
- $::dbwritesallowed = 1;
-# SendSQL("UPDATE shadowlog SET reflected = 1 WHERE reflected = 0", 1);
- SendSQL("DELETE FROM shadowlog", 1);
- SendSQL("UNLOCK TABLES");
- if ($wasusing) {
- Verbose("Reenabling other processes to read from the shadow db");
- SetParam('queryagainstshadowdb', 1);
- WriteParams();
- }
- if ($shutdown) {
- Verbose("Restoring the original shutdown message (if any)");
- SetParam('shutdownhtml', $wasshutdown);
- WriteParams();
- }
- Verbose("OK, done.");
-}
-
-Verbose("Looking for commands to execute.");
-$::dbwritesallowed = 1;
-
-# Make us low priority, to not block anyone who is trying to actually use
-# the shadowdb. Note that this is carefully coded to ignore errors; we want
-# to keep going even on older mysqld's that don't have the
-# SQL_LOW_PRIORITY_UPDATES option.
-$::db->do("SET OPTION SQL_LOW_PRIORITY_UPDATES = 1");
-
-while (1) {
- SendSQL("SELECT id, command FROM $shadowtable WHERE reflected = 0 " .
- "ORDER BY id LIMIT 1");
- my ($id, $command) = (FetchSQLData());
- if (!$id) {
- last;
- }
- Verbose("Executing command in shadow db: $command");
- SendSQL($command, 1);
- SendSQL("UPDATE $shadowtable SET reflected = 1 WHERE id = $id", 1);
-}
-
-Verbose("Releasing lock.");
-SendSQL("SELECT RELEASE_LOCK('synclock')");