summaryrefslogtreecommitdiff
path: root/byteback-mysql/scripts.d/Bytemyback/lvm
diff options
context:
space:
mode:
authorSteve Kemp <steve@bytemark.co.uk>2016-09-21 12:27:06 +0100
committerSteve Kemp <steve@bytemark.co.uk>2016-09-21 12:27:06 +0100
commitc68fe975ab4b47436bd90fa701b83a78793b0f32 (patch)
tree99ba226baa3d2d7cdac0470a9af93650e2449be0 /byteback-mysql/scripts.d/Bytemyback/lvm
parent2e96f802b1aa2cd374ef727c5573b30ab38001ce (diff)
parent10d3ddac7a625be28e9896f52bade5c99dc34462 (diff)
Merge branch 'byteback-mysql' into 'master'
Byteback mysql See merge request !3
Diffstat (limited to 'byteback-mysql/scripts.d/Bytemyback/lvm')
-rwxr-xr-xbyteback-mysql/scripts.d/Bytemyback/lvm80
1 files changed, 80 insertions, 0 deletions
diff --git a/byteback-mysql/scripts.d/Bytemyback/lvm b/byteback-mysql/scripts.d/Bytemyback/lvm
new file mode 100755
index 0000000..c3ff4fb
--- /dev/null
+++ b/byteback-mysql/scripts.d/Bytemyback/lvm
@@ -0,0 +1,80 @@
+#!/usr/bin/perl
+
+use DBI;
+use Data::Dumper;
+
+use warnings;
+use strict;
+
+my $mountpoint = "/var/backups/bytemyback/mnt/";
+my $snapshot_name = "byteback_data_snap";
+my $snapshot_size = "20G";
+my $dbh;
+
+die "Must specify either pre or post\n" unless @ARGV;
+
+if ($ARGV[0] eq 'pre') {
+ # Check snapshot doesn't already exist
+ die "Snapshot still exists\n" if `lvs 2>&1` =~ /$snapshot_name/;
+ my $lock_tables = 1; # This will be configurable. Whether or not it runs FLUSH TABLES WITH READ LOCK before taking the snapshot.
+ my $defaults_file = '/etc/mysql/debian.cnf';
+ my $dsn = "DBI:mysql:;mysql_read_default_file=$defaults_file";
+ $dbh = DBI->connect(
+ $dsn,
+ undef,
+ undef,
+ {RaiseError => 1}
+ ) or die "DBI::errstr: $DBI::errstr";
+
+ my $data_dir = ask_mysql_for_var('datadir');
+ my $lvm_dir = get_LVM_dir();
+ die "MySQL doesn't seem to be running from LVM\n" if !$lvm_dir;
+ $dbh->do("FLUSH TABLES WITH READ LOCK") if $lock_tables;
+ # Create snapshot
+ my $mounted_lvm = `df $lvm_dir | tail -n1 | cut -f1 -d" "`;
+ if (!`lvcreate -n $snapshot_name -L $snapshot_size --snapshot $mounted_lvm`) {
+ my $error = $!;
+ $dbh->do("UNLOCK TABLES") if $lock_tables;
+ die("Unable to create snapshot: $!\n");
+ }
+ else {
+ $dbh->do("UNLOCK TABLES") if $lock_tables;
+ chomp (my $mapped_snapshot = "/dev/mapper/" . `dmsetup ls | grep $snapshot_name | grep -v cow | cut -f1 -d " "`);
+ `mkdir -p $mountpoint`;
+ `mount $mapped_snapshot $mountpoint`;
+ `touch ${mountpoint}.bytebacklvm`;
+ }
+}
+elsif ($ARGV[0] eq 'post') {
+ `umount $mountpoint`;
+ chomp (my $mapped_snapshot = "/dev/mapper/" . `dmsetup ls | grep $snapshot_name | grep -v cow | cut -f1 -d " "`);
+ `lvremove -f $mapped_snapshot`;
+}
+
+sub ask_mysql_for_var {
+ my $var = '@@' . shift;
+ my $query = $dbh->prepare("SELECT ${var}");
+ $query->execute;
+ return $query->fetchrow_hashref()->{$var};
+}
+
+sub get_LVM_dir {
+ # This is a bit hacky, it checks if lvs returns,
+ # then checks if the mountpoint is /dev/mapper/$firstbit-$secondbit
+ # Returns true only if above matches and lvs output has $secondbit $firstbit somewhere
+ my $datadir = ask_mysql_for_var('datadir');
+ my $lvs = `lvs 2>&1`;
+ if (($?) || ($lvs =~ /No volume groups found/)) {
+ return 0;
+ }
+ my $output = `df $datadir | tail -n1`;
+ $output =~ s/--/:/g;
+ if ($output =~ m#/dev/mapper/([\w:]+)-([\w:]+)\s#) {
+ my ($vg, $lv) = ($1, $2);
+ $vg =~ s/:/-/; $lv =~ s/:/-/;
+ if ($lvs =~ /\s+$lv\s+$vg\s/) {
+ return $datadir;
+ }
+ }
+ return 0;
+}