diff options
author | justdave%syndicomm.com <> | 2001-08-31 14:49:01 +0200 |
---|---|---|
committer | justdave%syndicomm.com <> | 2001-08-31 14:49:01 +0200 |
commit | 31152e8e947876fb59da202dbee8cec5034a6e42 (patch) | |
tree | b31068f7b0d77e2a33535ec056b50d65f590807a | |
parent | 5d1bca95620daf504093e781e26bea10357c9850 (diff) | |
download | bugzilla-31152e8e947876fb59da202dbee8cec5034a6e42.tar.gz bugzilla-31152e8e947876fb59da202dbee8cec5034a6e42.tar.xz |
Fix for bug 75840: syncshadowdb -syncall now properly shuts down Bugzilla during the sync process so mysql doesn't get overloaded while the tables are locked. This patch also adds some funtionality to the script to allow you to specify an alternate temp directory on the command line, in case you have a large database and need it made to a different filesystem for space reasons.
Patch by Dawn Endico <endico@mozilla.org> and Jake Steenhagen <jake@acutex.net>
r= justdave@syndicomm.com
-rwxr-xr-x | checksetup.pl | 19 | ||||
-rwxr-xr-x | syncshadowdb | 95 |
2 files changed, 107 insertions, 7 deletions
diff --git a/checksetup.pl b/checksetup.pl index 7c165b9eb..053adc192 100755 --- a/checksetup.pl +++ b/checksetup.pl @@ -283,6 +283,25 @@ sub LocalVar ($$) # Set up the defaults for the --LOCAL-- variables below: # +my $mysql_binaries = `which mysql`; +if ($mysql_binaries =~ /no mysql/) { + # If which didn't find it, just provide a reasonable default + $mysql_binaries = "/usr/bin"; +} else { + $mysql_binaries =~ s:/mysql\n$::; +} + +LocalVar('mysqlpath', <<"END"); +# +# In order to do certain functions in Bugzilla (such as sync the shadow +# database), we require the MySQL Binaries (mysql, mysqldump, and mysqladmin). +# Because it's possible that these files aren't in your path, you can specify +# their location here. +# Please specify only the directory name, with no trailing slash. +\$mysqlpath = "$mysql_binaries"; +END + + LocalVar('create_htaccess', <<'END'); # # If you are using Apache for your web server, Bugzilla can create .htaccess diff --git a/syncshadowdb b/syncshadowdb index 4733dbb58..b60807a99 100755 --- a/syncshadowdb +++ b/syncshadowdb @@ -39,18 +39,35 @@ sub sillyness { 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]\n"; + print "Usage: syncshadowdb [-v] [-syncall] [-shutdown] [-tempdir dirname] [-force]\n"; exit; } -foreach my $opt (@ARGV) { +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 @@ -78,6 +95,63 @@ if (!Param("shadowdb")) { exit; } +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 comand line param) + $wasshutdown = Param("shutdownhtml"); + $::param{'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"; + if ($::db_pass) { $cmd .= " -p$::db_pass" } + $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."); + $::param{'shutdownhtml'} = $wasshutdown; + WriteParams(); + exit; + } + } +} + + my $wasusing = Param("queryagainstshadowdb"); $::param{'queryagainstshadowdb'} = 1; # Force us to be able to use the @@ -114,8 +188,10 @@ if ($syncall) { if ($wasusing) { $::param{'queryagainstshadowdb'} = 0; WriteParams(); - Verbose("Disabled reading from the shadowdb. Sleeping 10 seconds to let other procs catch up."); - sleep(10); + if (! $shutdown) { + Verbose("Disabled reading from the shadowdb. Sleeping 10 seconds to let other procs catch up."); + sleep(10); + } $::param{'queryagainstshadowdb'} = 1; } my @tables; @@ -157,7 +233,7 @@ if ($syncall) { } Verbose("Locking entire database"); SendSQL($query); - my $tempfile = "data/tmpsyncshadow.$$"; + 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" } @@ -165,7 +241,7 @@ if ($syncall) { open SAVEOUT, ">&STDOUT"; # stash the original output stream open STDOUT, ">$tempfile"; # redirect to file select STDOUT; $| = 1; # disable buffering - system("mysqldump", @ARGS); + system("$::mysqlpath/mysqldump", @ARGS); open STDOUT, ">&SAVEOUT"; # redirect back to original stream Verbose("Restoring from tempfile into shadowdb"); my $extra = "-u $::db_user"; @@ -175,7 +251,7 @@ if ($syncall) { if ($verbose) { $extra .= " -v"; } - open(MYSQL, "cat $tempfile | mysql $extra " . + open(MYSQL, "cat $tempfile | $::mysqlpath/mysql $extra " . Param("shadowdb") . "|") || die "Couldn't do db copy"; my $count = 0; while (<MYSQL>) { @@ -199,6 +275,11 @@ if ($syncall) { $::param{'queryagainstshadowdb'} = 1; WriteParams(); } + if ($shutdown) { + Verbose("Restoring the original shutdown message (if any)"); + $::param{'shutdownhtml'} = $wasshutdown; + WriteParams(); + } Verbose("OK, done."); } |