Skip to content

Harden mysqlbackup.sh script #170

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 5 commits into from
Jul 9, 2013
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions manifests/backup.pp
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,8 @@
# [*backuppassword*] - The password of the mysql backup user.
# [*backupdir*] - The target directory of the mysqldump.
# [*backupcompress*] - Boolean to compress backup with bzip2.
# [*backuprotate*] - Number of backups to keep. Default 30
# [*delete_before_dump*] - Clean existing backups before creating new
#
# Actions:
# GRANT SELECT, RELOAD, LOCK TABLES ON *.* TO 'user'@'localhost'
Expand All @@ -28,6 +30,8 @@
$backuppassword,
$backupdir,
$backupcompress = true,
$backuprotate = 30,
$delete_before_dump = false,
$ensure = 'present'
) {

Expand Down
17 changes: 12 additions & 5 deletions spec/classes/mysql_backup_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -3,9 +3,11 @@
describe 'mysql::backup' do

let(:default_params) {
{ 'backupuser' => 'testuser',
'backuppassword' => 'testpass',
'backupdir' => '/tmp',
{ 'backupuser' => 'testuser',
'backuppassword' => 'testpass',
'backupdir' => '/tmp',
'backuprotate' => '25',
'delete_before_dump' => true,
}
}
context "standard conditions" do
Expand Down Expand Up @@ -34,9 +36,14 @@

it 'should have compression by default' do
verify_contents(subject, 'mysqlbackup.sh', [
' --all-databases | bzcat -zc > ${DIR}/mysql_backup_`date +%Y%m%d-%H%M%S`.sql.bz2',
' --all-databases | bzcat -zc > ${DIR}/${PREFIX}`date +%Y%m%d-%H%M%S`.sql.bz2',
])
end

it 'should have 25 days of rotation' do
# MySQL counts from 0 I guess.
should contain_file('mysqlbackup.sh').with_content(/.*ROTATE=24.*/)
end
end

context "with compression disabled" do
Expand All @@ -51,7 +58,7 @@

it 'should be able to disable compression' do
verify_contents(subject, 'mysqlbackup.sh', [
' --all-databases > ${DIR}/mysql_backup_`date +%Y%m%d-%H%M%S`.sql',
' --all-databases > ${DIR}/${PREFIX}`date +%Y%m%d-%H%M%S`.sql',
])
end
end
Expand Down
25 changes: 22 additions & 3 deletions templates/mysqlbackup.sh.erb
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
#!/bin/sh
#!/bin/bash
#
# MySQL Backup Script
# Dumps mysql databases to a file for another backup tool to pick up.
Expand All @@ -13,11 +13,30 @@
USER=<%= @backupuser %>
PASS=<%= @backuppassword %>
DIR=<%= @backupdir %>
ROTATE=<%= [ Integer(@backuprotate) - 1, 0 ].max %>

PREFIX=mysql_backup_

##### STOP CONFIG ####################################################
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Some folks are tight on space and it is better to delete before writing a dump that fills the filesystem.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think it is good to have at least 1 good backup at any point in time, which means not deleting it before new backup has succeeded.

Secondly, at the moment there is non configurable default of 30 days worth of backups to keep. By introducing backuprotate parameter we give people tight on disk space some breathing space.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

All I am saying is to give people an option to change the default behaviour. Do not force it upon them.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think generally I agree with razorsedge, this would be pretty easy to handle with a toggle option. Maybe even just something as horribly named as $delete_before_dump = false as a default and then a quick if/else in the template to determine ordering. Would you be willing to go that route?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ok, will update pull request when ready.

PATH=/usr/bin:/usr/sbin:/bin:/sbin

find $DIR -mtime +30 -exec rm -f {} \;
set -o pipefail

cleanup()
{
find "${DIR}/" -maxdepth 1 -type f -name "${PREFIX}*.sql*" -mtime +${ROTATE} -print0 | xargs -0 -r rm -f
}

<% if @delete_before_dump -%>
cleanup

<% end -%>
mysqldump -u${USER} -p${PASS} --opt --flush-logs --single-transaction \
--all-databases <% if @backupcompress %>| bzcat -zc <% end %>> ${DIR}/mysql_backup_`date +%Y%m%d-%H%M%S`.sql<% if @backupcompress %>.bz2<% end %>
--all-databases <% if @backupcompress %>| bzcat -zc <% end %>> ${DIR}/${PREFIX}`date +%Y%m%d-%H%M%S`.sql<% if @backupcompress %>.bz2<% end %>

<% if not @delete_before_dump -%>
if [ $? -eq 0 ] ; then
cleanup
fi
<% end -%>