#!/usr/bin/perl use strict; use warnings; =pod =head1 NAME vox-backup-wiki - backup a pollwiki =head1 SYNOPSIS > vox-backup-wiki > vox-backup-server VS =head1 DESCRIPTION Backs up the local pollwiki. It creates the following files: /var/cache/pollwiki/backup/cur/ wiki-dump-current.xml wiki-dump-full.xml wiki-images.tar.gz wikidb-dump.sql Normally you will also back up any vote-servers immediately afterward, as their backups currently fit in the same directory structure. Reference: http://www.mediawiki.org/wiki/Manual:Backing_up_a_wiki =head1 RESTORING =head2 MySQL restoration This is the preferred restoration method. It has yet to be tested locally, so no specific instructions are documented yet. Meantime see the general instructions: http://www.mediawiki.org/wiki/Manual:Restoring_a_wiki_from_backup http://dev.mysql.com/doc/mysql-backup-excerpt/5.1/en/reloading-sql-format-dumps.html http://dev.mysql.com/doc/refman/5.1/en/mysqldump.html =head2 MediaWiki restoration This is the failsafe restoration method. It is less complete and more complicated than the MySQL method. Resort to it only if necessary. =over =item 1 > e /etc/apache2/modules.d/90_mediawiki.conf Close access to the wiki, stopping the web server if necessary. =item 2 > mysql --password Create the wiki user and database by entering the following commands in the mysql database shell: @mysql> create database wikidb; @mysql> grant index, create, select, insert, update, delete, alter, lock tables on wikidb.* to 'wikiuser'@'localhost' identified by 'mw376ze'; Those commands are documented at http://www.mediawiki.org/wiki/Manual:Installing_MediaWiki#MySQL @mysql> grant create temporary tables, drop on wikidb.* to 'wikiuser'@'localhost'; The added permissions above are required for Semantic MediaWiki. See http://semantic-mediawiki.org/wiki/Help:Installation =item 3 Install MediaWiki. Choose the recommended default (binary mode) for characters. http://www.mediawiki.org/wiki/Manual:Installing_MediaWiki =item 4 Adjust the configuration in LocalSettings.php. =item 5 Install the extensions, including Semantic MediaWiki and its Validator. =item 6 Temporarily disable Semantic MediaWiki queries in LocalSettings.php: $smwgQEnabled = false; Otherwise importDump might fail with "Unable to free MySQL result". See also http://wikimedia.7.x6.nabble.com/Embedding-an-ask-query-td563478.html =item 7 Restore the pages and revisions (dry run). > (m=/var/www/localhost/htdocs/mediawiki; nice php $m/maintenance/importDump.php --conf $m/LocalSettings.php --dry-run /var/cache/pollwiki/backup/cur/wiki-dump-full.xml) http://www.mediawiki.org/wiki/Manual:Importing_XML_dumps =item 8 Restore the pages and revisions. > (m=/var/www/localhost/htdocs/mediawiki; nice php $m/maintenance/importDump.php --conf $m/LocalSettings.php /var/cache/pollwiki/backup/cur/wiki-dump-full.xml) =item 9 Delete the Main_Page that was automatically generated by the installation process, unless you want to keep it. =item 10 Unpack the images backup file: /var/cache/pollwiki/backup/cur/wiki-images.tar.gz To here: /tmp/wiki-images =item 11 Delete /tmp/wiki-images/archive, temp and thumb subdirectories. Delete all other files in /tmp/wiki-images/ except those in content subdirectories /tmp/wiki-images/0 to f. =item 12 Ensure the installed images directory is writable by the web server (Apache). /var/www/localhost/htdocs/mediawiki/images Otherwise thumbnails might not be created for the restored images. Instead you'll see an error message on the image pages. =item 13 Restore the images (dry run). > nice php /var/www/localhost/htdocs/mediawiki/maintenance/importImages.php --comment='restore from backup' --dry --search-recursively /tmp/wiki-images http://www.mediawiki.org/wiki/Manual:ImportImages.php =item 14 Restore the images. > nice php /var/www/localhost/htdocs/mediawiki/maintenance/importImages.php --comment='restore from backup' --search-recursively /tmp/wiki-images =item 15 Ensure that the newly created image files and directories are writable by the web server. > chown apache:apache /var/www/localhost/htdocs/mediawiki/images --recursive =item 16 Eagerly refresh the MediaWiki indices: > nice php /var/www/localhost/htdocs/mediawiki/maintenance/rebuildall.php > nice php /var/www/localhost/htdocs/mediawiki/maintenance/updateArticleCount.php --update =item 17 Enable Semantic MediaWiki queries in LocalSettings.php by commenting out or removing this line: $smwgQEnabled = true; # or just remove this, because the default value is true =item 18 Eagerly refresh the Semantic MediaWiki indices. First to parse the category, property and type pages (cpt): > nice php /var/www/localhost/htdocs/mediawiki/extensions/SemanticMediaWiki/maintenance/SMW_refreshData.php -cpt -v Next to parse all the other pages, with 5 ms delay (d) to limit server IO load: > nice php /var/www/localhost/htdocs/mediawiki/extensions/SemanticMediaWiki/maintenance/SMW_refreshData.php -d 5 -v http://semantic-mediawiki.org/wiki/Help:SMW_refreshData.php =item 19 > e /etc/apache2/modules.d/90_mediawiki.conf Restore access to the wiki. =back =cut sub rmdirRecursive( $ ) { use IO::Handle qw( flush ); my $dir = shift; print "remove directory $dir, and continue with backup? y/n "; flush STDOUT; # for sake of remote terminals my $reply = ; chomp $reply; $reply eq 'y' or die "backup aborted\n"; system( "rm --recursive $dir" ) and die; -e $dir and die; } # ---------------------------------------------------------------------------------------- # Create a new backup subdirectory # - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - my $backDir = "/var/cache/pollwiki/backup"; -d $backDir or die; my $backDirNew = $backDir . '/new'; -e $backDirNew and rmdirRecursive( $backDirNew ); mkdir $backDirNew or die; # Lock the wiki # - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - # To obtain an atomic snapshot of the wiki content: database + filebase. The database # snapshot from mysqldump will be atomic in itself regardless. my $mwDir = '/var/www/localhost/htdocs/mediawiki'; -d $mwDir or die; my $wgReadOnlyFile = $mwDir . '/images/lock_yBgMBwiR'; # http://www.mediawiki.org/wiki/Manual:$wgReadOnlyFile open FILE, ">$wgReadOnlyFile" or die "$wgReadOnlyFile: $!"; print FILE "A routine backup is in progress, it shouldn't take more than a few minutes."; close FILE; # MySQL content # - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - { my $command = "nice mysqldump --default-character-set=binary --password --single-transaction wikidb > $backDirNew/wikidb-dump.sql"; # http://dev.mysql.com/doc/refman/5.1/en/mysqldump.html # --default-character-set per http://www.mediawiki.org/wiki/Manual:$wgDBTableOptions print " $command\n"; system $command and die 'unable to execute: ' . $command; print "\n"; } # MediaWiki content - failsafe alternative to MySQL restoration # - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - { my $command = "nice php $mwDir/maintenance/dumpBackup.php --current > $backDirNew/wiki-dump-current.xml"; print " $command\n"; system $command and die 'unable to execute: ' . $command; print "\n"; } { my $command = "nice php $mwDir/maintenance/dumpBackup.php --full > $backDirNew/wiki-dump-full.xml"; print " $command\n"; system $command and die 'unable to execute: ' . $command; print "\n"; } # Filebase - images and such # - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - { my $command = "tar --create --directory $mwDir/images/ --exclude=lock_yBgMBwiR --file $backDirNew/wiki-images.tar.gz --gzip ."; print " $command\n"; system $command and die 'unable to execute: ' . $command; print "\n"; } # Unlock the wiki # - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - open FILE, ">$wgReadOnlyFile" or die "$wgReadOnlyFile: $!"; close FILE; # Rotate the backup directories # - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - my $backDirOld = $backDir . '/old'; -e $backDirOld and rmdirRecursive( $backDirOld ); my $backDirCur = $backDir . '/cur'; if( -e $backDirCur ) { system( "mv $backDirCur $backDirOld" ) and die; } system( "mv $backDirNew $backDirCur" ) and die;