Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- #!/usr/bin/php
- <?php
- $missing = <<<MISSING
- Config file not found (/etc/inno_backup.conf)
- Create a new file with the following keys/values:
- user = backups
- pass = password1234
- backup_dir = /backups
- data_dir = /var/lib/mysql
- MISSING;
- if( ! file_exists('/etc/inno_backup.conf') ) {
- exit($missing."\n");
- }
- $conf = parse_ini_file('/etc/inno_backup.conf');
- $user = $conf['user'];
- $pass = $conf['pass'];
- $data_dir = $conf['data_dir'];
- $backup_dir = $conf['backup_dir'];
- $usage = <<<USAGE
- USAGE: inno_backup [option]
- Options:
- full : Start a full backup. This will delete ALL incrementals and the current full snapshot.
- incremental : Start an incremental. If no full backup exists, the script will fall back to a full backup.
- prepare : Glues all incrementals to the full snapshot in preparation for a restore.
- restore : Shuts down MySQL, removes content of datadir, replaces it with the backup. Dangerous.
- reset : THIS WILL NUKE THE BACKUP DIRECTORY AND ALL CONTENT WITHIN! Only use to start clean.
- USAGE;
- $arg = ( isset($argv[1]) ) ? $argv[1] : "";
- $base_args = "--user={$user} --password={$pass}";
- switch( strtolower($arg) ) {
- case "full":
- full();
- break;
- case "incremental":
- incremental();
- break;
- case "prepare":
- prepare();
- break;
- case "restore":
- // This is dangerous, yo. Gotta think of a good way to fool-proof it.
- restore();
- break;
- case "reset":
- exec("rm -rf {$backup_dir}/logs/* {$backup_dir}/incremental/* {$backup_dir}/full/* {$backup_dir}/last_incremental");
- echo "Backup directory cleaned.\n";
- break;
- default:
- echo "No option supplied. See usage below:\n\n";
- echo $usage."\n";
- exit();
- }
- ## Functions!
- function full() {
- global $user, $pass, $backup_dir, $base_args;
- if( ! file_exists($backup_dir) ) {
- echo "Cannot find backup directory : {$backup_dir}\n";
- exit();
- }
- if( file_exists($backup_dir."/full") ) {
- echo "Found existing full backup directory. Removing it and all incrementals.\n";
- exec("rm -rf {$backup_dir}/full {$backup_dir}/incremental/* {$backup_dir}/last_incremental");
- }
- echo "Starting backup -- this takes an average of 3 to 3.5 hours.\n";
- exec("innobackupex {$base_args} --no-timestamp {$backup_dir}/full &>{$backup_dir}/logs/full.log");
- if( check_log($backup_dir."/logs/full.log") ) {
- echo "Backup complete.\n";
- exec("rm -f {$backup_dir}/logs/full.log");
- } else {
- echo "Backup failed. Review {$backup_dir}/logs/full.log\n";
- }
- }
- function incremental() {
- global $user, $pass, $backup_dir, $base_args;
- echo "Starting incremental backup.\n";
- echo "Checking for existing full backup.\n";
- if( ! file_exists($backup_dir."/full/xtrabackup_checkpoints") ) {
- echo "There is no full backup. Please execute: inno_backup full\n";
- exit();
- }
- echo "Found existing full backup. Kicking off incremental backup.\n";
- if( ! file_exists($backup_dir."/last_incremental") ) {
- $inc = 1;
- file_put_contents($backup_dir."/last_incremental", $inc);
- } else {
- echo "Found last_incremental file\n";
- $inc = (int) file_get_contents($backup_dir."/last_incremental");
- echo "Last incremental: #{$inc}\n";
- $inc++;
- }
- if( $inc == 1 ) {
- exec("innobackupex {$base_args} --no-timestamp --incremental {$backup_dir}/incremental/{$inc} --incremental-basedir={$backup_dir}/full &>{$backup_dir}/logs/incremental.log");
- } else {
- $inc_prev = $inc-1;
- exec("innobackupex {$base_args} --no-timestamp --incremental {$backup_dir}/incremental/{$inc} --incremental-basedir={$backup_dir}/incremental/{$inc_prev} &>{$backup_dir}/logs/incremental.log");
- }
- if( check_log($backup_dir."/logs/incremental.log") ) {
- echo "Incremental complete.\n";
- exec("rm -f {$backup_dir}/logs/incremental.log");
- } else {
- echo "Backup failed. Review {$backup_dir}/logs/incremental.log\n";
- exit();
- }
- file_put_contents($backup_dir."/last_incremental", $inc++);
- }
- function prepare() {
- global $user, $pass, $backup_dir, $base_args;
- if( ! file_exists($backup_dir."/last_incremental") ) {
- exit("Missing {$backup_dir}/last_incremental.\n");
- }
- echo "Rebuilding full backup from incrementals for restoration. This may take a while ...\n";
- $inc = (int) file_get_contents($backup_dir."/last_incremental");
- exec("innobackupex {$base_args} --no-timestamp --use-memory=500M --apply-log {$backup_dir}/full &>{$backup_dir}/logs/prepare.log");
- if( ! check_log($backup_dir."/logs/prepare.log") ) {
- echo "Failed to prepare backup for restoration. Check {$backup_dir}/logs/prepare.log\n";
- exit();
- }
- for($i = 1; $i <= $inc; $i++) {
- echo "Processing incremental: {$i}\n";
- exec("innobackupex {$base_args} --apply-log --redo-only --incremental /backups/full/ --incremental-basedir=/backups/incremental/{$i} &>{$backup_dir}/logs/prepare.log");
- if( ! check_log($backup_dir."/logs/prepare.log") ) {
- echo "Failed to apply incremental #{$i} to full backup. Check {$backup_dir}/logs/prepare.log\n";
- exit();
- }
- }
- echo "Final preparation running ...\n";
- exec("innobackupex {$base_args} --apply-log {$backup_dir}/full --use-memory=500M &>{$backup_dir}/logs/prepare.log");
- if( check_log($backup_dir."/logs/prepare.log") ) {
- echo "Preparation has completed successfully. You may now attempt: inno_backup restore\n";
- } else {
- exit("Final preparation has failed. Review {$backup_dir}/logs/prepare.log\n");
- exec("rm -rf {$backup_dir}/last_incremental {$backup_dir}/incremental/* {$backup_dir}/logs/prepare.log");
- }
- }
- function restore() {
- global $user, $pass, $backup_dir, $base_args;
- echo "This is a highly destructive process. Do not run this unless absolutely sure.\n";
- echo "Are you sure you want to run the restore process? (y/N): ";
- $handle = fopen("php://stdin", "r");
- $line = fgets($handle);
- if( strtolower(trim($line)) != 'y' ) {
- exit("Aborting. Good choice, mortal.\n");
- }
- echo "Just kidding. This isn't implemented yet, meat-bag.\n";
- }
- function check_log($file) {
- $res = exec("tail -n 1 {$file}");
- if( strstr($res, "OK!" ) ) {
- return true;
- }
- return false;
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement