Skip to content

Instantly share code, notes, and snippets.

@morungos
Created July 12, 2013 16:54
Show Gist options
  • Save morungos/5985955 to your computer and use it in GitHub Desktop.
Save morungos/5985955 to your computer and use it in GitHub Desktop.
Simple script to fairly safely dump a MySQL database to a bunch of tab files, with accompanying SQL definitions. It's not designed as a reliable backup, but as a way of archiving very large databases for processing by other tools.
#!/usr/bin/perl -w
use strict;
use Carp;
use DBI;
use File::Spec;
use File::Path qw(make_path);
use Getopt::Long;
my ($verbose, $username, $password, $hostname, $tabs);
$hostname = "localhost";
$tabs = "tabs";
GetOptions (
'u|username=s' => \$username,
'p|password=s' => \$password,
'h|host=s' => \$hostname,
't|tab=s' => \$tabs
);
my $database = shift @ARGV;
my $directory = shift @ARGV;
my ($dsn) = sprintf("DBI:mysql:database=%s;host=%s;mysql_use_result=1", $database, $hostname);
my $dbh = DBI->connect(
$dsn,
$username,
$password,
{
AutoCommit => 0,
}) or die $DBI::errstr;
sub dump_database {
my @tables = map { $_->[0] } @{$dbh->selectall_arrayref("SHOW TABLES")};
make_path($tabs);
foreach my $table (@tables) {
dump_table($table);
}
}
sub dump_table {
my ($table) = @_;
print STDERR "Dumping $table...\n";
my $output = File::Spec->rel2abs("$table.tsv", $tabs);
open(my $fh, ">", $output) or die("Can't write to: $output");
my $safe_table = $dbh->quote_identifier($table);
my $statement = $dbh->prepare("SELECT * FROM $safe_table") or return carp $dbh->errstr;
$statement->execute() or return carp $dbh->errstr;
print $fh join(",", map { encode($_); } @{$statement->{NAME}}) . "\n";
while(my $values = $statement->fetchrow_arrayref()) {
print $fh join(",", map { encode($_); } @$values) . "\n";
}
close($fh);
$statement->finish();
$output = File::Spec->rel2abs("$table.sql", $tabs);
open($fh, ">", $output) or die("Can't write to: $output");
my (undef, $sql) = $dbh->selectrow_array("SHOW CREATE TABLE $safe_table") or return carp $dbh->errstr;
print $fh "$sql\n";
close($fh);
}
sub encode {
my ($value) = @_;
if (! defined($value)) {
return "\\N";
} else {
if ($value =~ m{\n",}) {
$value =~ s{"}{""};
return qq{"$value"};
} else{
return $value;
}
}
}
dump_database();
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment