sqlup 0.0.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (39) hide show
  1. data/History.txt +5 -0
  2. data/Manifest.txt +38 -0
  3. data/README.txt +122 -0
  4. data/Rakefile +18 -0
  5. data/bin/sqlup +107 -0
  6. data/bin/sqlup_control +25 -0
  7. data/config/environment.rb +0 -0
  8. data/lib/mysql_backup/entity/files/innodb.rb +77 -0
  9. data/lib/mysql_backup/entity/files/myisam.rb +62 -0
  10. data/lib/mysql_backup/entity/files.rb +95 -0
  11. data/lib/mysql_backup/entity/identifier.rb +179 -0
  12. data/lib/mysql_backup/entity/logs.rb +44 -0
  13. data/lib/mysql_backup/entity/mysqldump.rb +57 -0
  14. data/lib/mysql_backup/entity.rb +38 -0
  15. data/lib/mysql_backup/librarian/backup.rb +134 -0
  16. data/lib/mysql_backup/librarian/backup_collection.rb +63 -0
  17. data/lib/mysql_backup/librarian.rb +176 -0
  18. data/lib/mysql_backup/server.rb +237 -0
  19. data/lib/mysql_backup/storage/s3.rb +110 -0
  20. data/lib/mysql_backup/storage.rb +13 -0
  21. data/lib/mysql_backup/utilities/factory_create_method.rb +51 -0
  22. data/lib/mysql_backup.rb +8 -0
  23. data/lib/sqlup.rb +2 -0
  24. data/test/unit/mysql_backup/entity/files/files_test.rb +45 -0
  25. data/test/unit/mysql_backup/entity/files/innodb_test.rb +50 -0
  26. data/test/unit/mysql_backup/entity/files/myisam_test.rb +42 -0
  27. data/test/unit/mysql_backup/entity/identifier_test.rb +51 -0
  28. data/test/unit/mysql_backup/entity/logs_test.rb +13 -0
  29. data/test/unit/mysql_backup/entity/mysqldump_test.rb +64 -0
  30. data/test/unit/mysql_backup/librarian/backup_collection_test.rb +52 -0
  31. data/test/unit/mysql_backup/librarian/backup_test.rb +25 -0
  32. data/test/unit/mysql_backup/librarian/librarian_test.rb +103 -0
  33. data/test/unit/mysql_backup/server_test.rb +63 -0
  34. data/test/unit/mysql_backup/storage/s3_test.rb +69 -0
  35. data/test/unit/mysql_backup/storage/test_helper.rb +1 -0
  36. data/test/unit/mysql_backup/test_helper.rb +1 -0
  37. data/test/unit/mysql_backup/utilities/test_helper.rb +1 -0
  38. data/test/unit/test_helper.rb +10 -0
  39. metadata +116 -0
data/History.txt ADDED
@@ -0,0 +1,5 @@
1
+ == 0.0.1 / 2007-06-18
2
+
3
+ * 1 major enhancement
4
+ * Birthday!
5
+
data/Manifest.txt ADDED
@@ -0,0 +1,38 @@
1
+ History.txt
2
+ Manifest.txt
3
+ README.txt
4
+ Rakefile
5
+ bin/sqlup
6
+ bin/sqlup_control
7
+ test/unit/mysql_backup/librarian/librarian_test.rb
8
+ test/unit/mysql_backup/librarian/backup_test.rb
9
+ test/unit/mysql_backup/librarian/backup_collection_test.rb
10
+ test/unit/mysql_backup/utilities/test_helper.rb
11
+ test/unit/mysql_backup/storage/test_helper.rb
12
+ test/unit/mysql_backup/storage/s3_test.rb
13
+ test/unit/mysql_backup/entity/files/myisam_test.rb
14
+ test/unit/mysql_backup/entity/files/files_test.rb
15
+ test/unit/mysql_backup/entity/files/innodb_test.rb
16
+ test/unit/mysql_backup/entity/logs_test.rb
17
+ test/unit/mysql_backup/entity/mysqldump_test.rb
18
+ test/unit/mysql_backup/entity/identifier_test.rb
19
+ test/unit/mysql_backup/test_helper.rb
20
+ test/unit/mysql_backup/server_test.rb
21
+ test/unit/test_helper.rb
22
+ lib/mysql_backup/librarian/backup.rb
23
+ lib/mysql_backup/librarian/backup_collection.rb
24
+ lib/mysql_backup/entity/files/myisam.rb
25
+ lib/mysql_backup/entity/files/innodb.rb
26
+ lib/mysql_backup/entity/identifier.rb
27
+ lib/mysql_backup/entity/logs.rb
28
+ lib/mysql_backup/entity/mysqldump.rb
29
+ lib/mysql_backup/entity/files.rb
30
+ lib/mysql_backup/storage/s3.rb
31
+ lib/mysql_backup/utilities/factory_create_method.rb
32
+ lib/mysql_backup/server.rb
33
+ lib/mysql_backup/librarian.rb
34
+ lib/mysql_backup/storage.rb
35
+ lib/mysql_backup/entity.rb
36
+ lib/mysql_backup.rb
37
+ lib/sqlup.rb
38
+ config/environment.rb
data/README.txt ADDED
@@ -0,0 +1,122 @@
1
+ sqldump
2
+ by James Moore
3
+
4
+ == DESCRIPTION:
5
+
6
+ sqlup is a set of libraries and utilities to automate backups of a MySQL server running on Amazon's EC2
7
+ service to Amazon's S3 storage service.
8
+
9
+ === Quick start
10
+
11
+ Create an S3 bucket named 'sqlup' for your backups. (You'll need to choose a different name for your bucket.)
12
+
13
+ Install the gem:
14
+ gem install sqlup
15
+
16
+ Put your S3 keys in a .sqluprc file in the backup user's home directory:
17
+ cat ~/.sqluprc
18
+ access_key_id: xxxxxxxxxxxxxxxx
19
+ secret_access_key: xxxxxxxxxxxxxxxxx
20
+
21
+ Backup your database:
22
+ sqlup binary -bucket sqlup
23
+
24
+ See what was written:
25
+ sqlup ls -bucket sqlup
26
+
27
+ Start the backup daemon that will store the binary logs as they're written:
28
+ sqlup_control start -- -logs_delay 10 log_daemon -bucket sqlup
29
+
30
+ Retrieve the backup files (where full:type_mysqldump:log_file_domU-12-31-35-00-35-42-bin.000019:log_position_0000000169 is the name of the full backup you want):
31
+ sqlup get_logs -bucket sqlup -d /tmp
32
+ sqlup get -bucket sqlup -d /tmp -name full:type_mysqldump:log_file_domU-12-31-35-00-35-42-bin.000019:log_position_0000000169
33
+
34
+ === Usage
35
+
36
+ Get help:
37
+ sqlup �h
38
+ Back up the data files:
39
+ sqlup binary -bucket sqlup
40
+ Back up a mysqldump run:
41
+ sqlup mysqldump -bucket sqlup
42
+ Start the sqlup daemon to take a backup every 10 seconds, to the bucket 'sqlup', with a pidfile in /tmp:
43
+ export SQLUP_PID_DIR=/tmp
44
+ sqlup_control start -- -logs_delay 10 log_daemon -bucket sqlup
45
+ Get a list of the backup files:
46
+ sqlup ls -bucket sqlup
47
+ Remove a backup file from the bucket 'sqlup':
48
+ sqlup -bucket sqlup rm -name log:type_complete:log_file_fnord.000002
49
+ Remove obsolete current logs:
50
+ obsolete_files=`bin/sqlup -bucket sqlup ls -backup_type log_current -skip_most_recent 3`
51
+ for i in $obsolete_files ; do
52
+ sqlup -bucket sqlup rm -name $i
53
+ done
54
+
55
+ You need to specify your access codes using the AWS::S3 environment variables:
56
+
57
+ export AMAZON_ACCESS_KEY_ID='xxxxxxx'
58
+ export AMAZON_SECRET_ACCESS_KEY='xxxxxxxxxx'
59
+
60
+
61
+ It�s primarily targeted at MySQL servers running on Amazon�s EC2 virtual server system,
62
+ with backups sent to Amazon�s S3 storage service.
63
+
64
+ === What it backs up
65
+ There are three parts to a MySQL backup system:
66
+
67
+ 1. The actual MySQL data files (by default, the files in /var/lib/mysql).
68
+ 2. Full dumps using the mysqldump tool.
69
+ 3. The binary log files.
70
+
71
+ Normally, you�d make a full copy of your system using either #1 or #2, and then have sqlup make backups of the binary logs to S3 every N seconds.
72
+ Backups are tarred, gzip�ed, and split to fit into S3 buckets.
73
+
74
+ === FAQs
75
+
76
+ * Why would I want to make copies of the data files instead of using mysqldump?
77
+
78
+ Speed. Recovering mysqldump files can take a while; recovering when you have copies of the data files is much faster. If you�ve got a small database, though, just use mysqldump. You can test this yourself; just do a mysqldump of your current database, and run it against a MySQL server on another machine. If that�s fast enough for you, you don�t need to worry about the binary files.
79
+
80
+ * Can I use the database while it�s being backed up?
81
+
82
+ Yes, sort of. The binary backup is going to lock every table in the system until it�s finished making a tarball of all the data files. (A future enhancement will be to use a versioning file system.) As long as no one writes to the database, reads will continue. However, as soon as someone wants to write to a table, it�s very likely that all future readers will be blocked until the backup is finished writing temporary files to disk.
83
+
84
+ * Is there an automated recovery system?
85
+
86
+ Not yet. There�s a command to get the backups back from S3, but you need to go through the standard mysql recovery process by hand once you have the files.
87
+
88
+
89
+ == FEATURES/PROBLEMS:
90
+
91
+ == TODO:
92
+
93
+ 1. Improve the recovery process.
94
+ 2. Improve the ability to do backups from slaves.
95
+
96
+ == REQUIREMENTS:
97
+
98
+ * You must run MySQL with binary logging enabled. No logs == no backups.
99
+
100
+ == INSTALL:
101
+
102
+ gem install sqlup
103
+
104
+ == LICENSE:
105
+
106
+ sqlup - a backup tool for MySQL, EC2, and S3
107
+
108
+ Copyright (C) 2007 James Moore
109
+
110
+ This program is free software; you can redistribute it and/or
111
+ modify it under the terms of the GNU General Public License
112
+ as published by the Free Software Foundation; either version 2
113
+ of the License, or (at your option) any later version.
114
+
115
+ This program is distributed in the hope that it will be useful,
116
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
117
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
118
+ GNU General Public License for more details.
119
+
120
+ You should have received a copy of the GNU General Public License
121
+ along with this program; if not, write to the Free Software
122
+ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
data/Rakefile ADDED
@@ -0,0 +1,18 @@
1
+ require 'rubygems'
2
+ require 'hoe'
3
+ require './lib/mysql_backup'
4
+
5
+ Hoe.new('sqlup', MysqlBackup::VERSION) do |p|
6
+ p.rubyforge_name = 'sqlup'
7
+ p.author = 'James Moore'
8
+ p.email = 'banshee@restphone.com'
9
+ p.summary = "A backup tool for saving MySQL data to Amazon's S3 service"
10
+ p.changes = p.paragraphs_of('History.txt', 0..1).join("\n\n")
11
+ p.extra_deps << ['named_arguments', '>= 0.0.5']
12
+ p.extra_deps << ['optiflag', '>= 0.6.5']
13
+ end
14
+
15
+ Rake::TestTask.new do |t|
16
+ t.test_files = FileList['test/**/*_test.rb']
17
+ t.verbose = true
18
+ end
data/bin/sqlup ADDED
@@ -0,0 +1,107 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ require 'rubygems'
4
+ require 'optiflag'
5
+ require 'pp'
6
+ require 'logger'
7
+ require File.dirname(__FILE__) + '/../lib/mysql_backup'
8
+
9
+ module Example extend OptiFlagSet
10
+ keyword 'ls', :description => "Print a list of all backups."
11
+ keyword 'mysqldump', :description => 'Backup using mysqldump'
12
+ keyword 'binary', :description => 'Backup mysql data files'
13
+ keyword 'logs', :description => 'Backup the binary log files'
14
+ keyword 'log_daemon', :description => "Backup the binary logs every --logs_delay seconds."
15
+ keyword 'get', :description => 'Get a binary or a mysqldump backup. Requires --name'
16
+ keyword 'get_logs', :description => "Get all the current and complete logs"
17
+ keyword 'rm', :description => 'Remove a backup (use -name to specify which backup to remove)'
18
+ flag 'bucket', :description => "The name of the S3 bucket"
19
+ optional_flag 'backup_type', :description => "(ls) The kind of backup"
20
+ optional_flag 'skip_most_recent', :description => "(ls) Do not display the most recent N logs. Usually used to get a list of obsolete current logs."
21
+ optional_flag 'name', :description => '(get, rm) The name of the backup to process'
22
+ optional_flag "engine", :description => "The storage engine. The default (and currently the only option) is s3."
23
+ optional_flag "get_directory", :alternate_forms => 'd', :description => "The directory to write files for the get command (defaults to the current directory)"
24
+ optional_flag 'logs_delay', :description => 'The delay (in seconds, as a float) to use for log_daemon. Defaults to 1.'
25
+ optional_switch_flag 'verbose', :alternate_forms => %w(v) do
26
+ description 'Send verbose output'
27
+ end
28
+ and_process!
29
+ end
30
+
31
+ flags = ARGV.flags
32
+
33
+ if flags.get && !flags.name
34
+ raise RuntimeError, "You must specify the name of a backup (--name)"
35
+ end
36
+
37
+ if flags.verbose?
38
+ log = Logger.new $stderr
39
+ log.level = Logger::DEBUG
40
+ else
41
+ log = nil
42
+ end
43
+
44
+ engine = flags.engine || 's3'
45
+
46
+ case engine
47
+ when 's3'
48
+ # Read the keys from the $HOME/.sqluprc file
49
+ args = {:log => log, :bucket => flags.bucket}
50
+ p = Pathname.new(ENV['HOME']) + '.sqluprc'
51
+ if p.readable?
52
+ keys = YAML::load p.open
53
+ keys.each_pair do |k,v|
54
+ args[k.to_sym] = v
55
+ end
56
+ else
57
+ raise RuntimeError, ("Cannot open #{p.to_s}; that file should have two lines, one for access_key_id: yourkey and the other for secret_access_key: yourotherkey")
58
+ end
59
+ engine = MysqlBackup::Storage::S3.new args
60
+ engine.read_existing_objects
61
+ end
62
+ librarian = MysqlBackup::Librarian.new :log => log, :storage => engine, :user => 'root', :bucket => 'banshee', :sock => '/var/lib/mysql/mysql.sock'
63
+
64
+ begin
65
+ if flags.ls?
66
+ klass = Kernel.const_get flags.backup_type rescue nil
67
+ klass ||= case flags.backup_type
68
+ when /log_complete/: MysqlBackup::Librarian::Backup::Log::Complete
69
+ when /log_current/: MysqlBackup::Librarian::Backup::Log::Current
70
+ when /log/: MysqlBackup::Librarian::Backup::Log
71
+ end
72
+ klass ||= Object
73
+ range = 0..-1
74
+ if flags.skip_most_recent
75
+ range = 0..(-(flags.skip_most_recent.to_i) - 1)
76
+ end
77
+ puts librarian.ls(klass).slice(range).join("\n")
78
+ end
79
+ if flags.mysqldump?
80
+ librarian.backup_mysqldump
81
+ end
82
+ if flags.binary?
83
+ librarian.backup_data_files
84
+ end
85
+ if flags.rm?
86
+ librarian.rm flags.name
87
+ end
88
+ if flags.logs?
89
+ librarian.backup_binary_logs
90
+ end
91
+ if flags.get?
92
+ librarian.get flags.name, flags.get_directory || '.'
93
+ end
94
+ if flags.get_logs?
95
+ librarian.get_logs flags.get_directory || '.'
96
+ end
97
+ if flags.log_daemon?
98
+ while true
99
+ librarian.backup_binary_logs
100
+ delay = flags.logs_delay.to_f
101
+ sleep(delay == 0 ? 1 : delay)
102
+ end
103
+ end
104
+ rescue Exception => e
105
+ puts "Exception: #{e.class}: #{e.message}\n\t#{e.backtrace.join("\n\t")}"
106
+ exit 1
107
+ end
data/bin/sqlup_control ADDED
@@ -0,0 +1,25 @@
1
+ #!/usr/bin/env ruby
2
+ #
3
+ # Normally run like so:
4
+ #
5
+ # export SQLUP_PID_DIR=/tmp
6
+ # sqlup_control start -- -logs_delay 10 log_daemon
7
+ #
8
+ # This will back up your log files every 10 seconds.
9
+
10
+ require 'rubygems'
11
+ require 'daemons'
12
+ require 'optiflag'
13
+
14
+ options = {}
15
+
16
+ pid_dir = ENV['SQLUP_PID_DIR']
17
+
18
+ if pid_dir
19
+ options[:dir] = pid_dir
20
+ options[:dir_mode] = :normal
21
+ else
22
+ options[:dir_mode] = :script
23
+ end
24
+
25
+ Daemons.run(File.dirname(__FILE__) + '/sqlup', options)
File without changes
@@ -0,0 +1,77 @@
1
+ require 'mysql_backup/entity/files'
2
+
3
+ # Used to save all of the files for a MySQL Innodb database.
4
+ #
5
+ # Normal use is:
6
+ #
7
+ # i = Mysql::InnodbFiles.new
8
+ # array_of_pathname_objects = i.tar_files
9
+ #
10
+ # The caller is responsible for removing the files returned
11
+ # from tar_files.
12
+ #
13
+ # See new for a description of the arguments used to create a Mysql::InnodbFiles object
14
+ # matching your mysql layout.
15
+ #
16
+ # You can create instances of Mysql::InnodbFiles by hand, but normally
17
+ # you'd use MysqlBackup::Server to create them for you.
18
+ # MysqlBackup::Server
19
+ # objects will detect where your data files are and fill in the correct options for
20
+ # Mysql::InnodbFiles.new.
21
+ #
22
+ # = What is backed up
23
+ #
24
+ # - Innodb data files. Your innodb files must all start with the same string
25
+ # and end with a sequence of digits. +ibdata001+, +ibdata002+, etc. is fine,
26
+ # but +firstfile+, +secondfile+ is not supported.
27
+ # - MyISAM files.
28
+ # - Log files. You need to specify the directory where the log files are stored;
29
+ # there's no way to extract this from a running server.
30
+ # - +mysqladmindump+ files.
31
+ #
32
+ # For all of these, we track the log positions (the log file/log position pair).
33
+ class MysqlBackup::Entity::Files::Innodb < MysqlBackup::Entity::Files
34
+ attr_accessor :datadir, :innodb_data_home_dir, :innodb_data_file_path
35
+
36
+ # Takes the following arguments:
37
+ #
38
+ # :datadir => The MySQL data directory.
39
+ # :innodb_data_home_dir => The directory for innodb files.
40
+ # :innodb_data_file_path => The root name for the innodb files.
41
+ # :log_bin_dir => The directory containing the log files.
42
+ # :log_bin => The prefix of the log files.
43
+ #
44
+ # The following files will be backed up with the default base_dir and ib_basename:
45
+ #
46
+ # /var/lib/mysql/ibdata*
47
+ # /var/lib/mysql/*/*.frm - all files in any directory that contain one or more *.frm files
48
+ # /var/lib/mysql/*/*.MYD - all files in any directory that contain one or more *.MYD files
49
+ def initialize args = {}
50
+ set_path_vars %w(datadir innodb_data_home_dir), args
51
+ end
52
+
53
+ # Returns a list of Pathname objects that need to be
54
+ # backed up for a mysql server using innodb.
55
+ def required_paths
56
+ result = []
57
+ result.concat innodb_files
58
+ result.concat innodb_database_dirs
59
+ result.uniq
60
+ end
61
+
62
+ # Returns an array of Pathnames for all databases
63
+ # in the base directory.
64
+ #
65
+ # A database in this case is a directory containing
66
+ # any files matching *.frm.
67
+ def innodb_database_dirs
68
+ result = Pathname.glob(@innodb_data_home_dir_path + '*/*.frm')
69
+ result = result.map {|d| d.dirname}
70
+ result.uniq
71
+ end
72
+
73
+ def innodb_files
74
+ ib = @innodb_data_home_dir_path + @innodb_data_file_path
75
+ Pathname.glob ib.cleanpath.to_s + '*'
76
+ end
77
+ end
@@ -0,0 +1,62 @@
1
+ require 'mysql_backup/entity/files'
2
+
3
+ # Used to save all of the files for a MySQL MyISAM database.
4
+ #
5
+ # Normal use is:
6
+ #
7
+ # i = Mysql::InnodbFiles.new
8
+ # array_of_pathname_objects = i.tar_files
9
+ #
10
+ # The caller is responsible for removing the files returned
11
+ # from tar_files.
12
+ #
13
+ # See new for a description of the arguments used to create a Mysql::InnodbFiles object
14
+ # matching your mysql layout.
15
+ #
16
+ # You can create instances of Mysql::InnodbFiles by hand, but normally
17
+ # you'd use MysqlBackup::Server to create them for you.
18
+ # MysqlBackup::Server
19
+ # objects will detect where your data files are and fill in the correct options for
20
+ # Mysql::InnodbFiles.new.
21
+ #
22
+ # = What is backed up
23
+ #
24
+ # - MyISAM files.
25
+ #
26
+ # For all of these, we track the log positions (the log file/log position pair).
27
+ class MysqlBackup::Entity::Files::Myisam < MysqlBackup::Entity::Files
28
+ # Takes the following arguments:
29
+ #
30
+ # :datadir => The MySQL data directory.
31
+ #
32
+ # The following files will be backed up with the default base_dir and ib_basename:
33
+ #
34
+ # /var/lib/mysql/*/*.MYD - all files in any directory that contain one or more *.MYD files
35
+
36
+ attr_accessor :datadir
37
+
38
+ def initialize args = {}
39
+ super
40
+ set_path_vars %w(datadir), args
41
+ end
42
+
43
+ # Returns a list of Pathname objects that need to be
44
+ # backed up for a mysql server using innodb.
45
+ def required_paths
46
+ result = []
47
+ result.concat myisam_database_dirs
48
+ result.uniq
49
+ end
50
+
51
+ # Returns an array of Pathnames for all databases
52
+ # in the base directory.
53
+ #
54
+ # A database in this case is a directory containing
55
+ # any files matching *.frm.
56
+ def myisam_database_dirs
57
+ result = Pathname.glob(@datadir_path + '*/*.MYD')
58
+ result.concat Pathname.glob(@datadir_path + '*/*.MYI')
59
+ result = result.map {|d| d.dirname}
60
+ result.uniq
61
+ end
62
+ end
@@ -0,0 +1,95 @@
1
+ require 'pathname'
2
+ require 'tempfile'
3
+
4
+ require 'mysql_backup/entity'
5
+ require 'mysql_backup/entity/identifier'
6
+
7
+ # See MysqlBackup::Entity::Files::Innodb and MysqlBackup::Entity::Files::Myisam
8
+ # for implementations of this abstract base class.
9
+ class MysqlBackup::Entity::Files < MysqlBackup::Entity
10
+ def initialize args = {}
11
+ super()
12
+ end
13
+
14
+ # Create the tar files to back up a mysql instance.
15
+ #
16
+ # Takes the following:
17
+ #
18
+ # :mysql_server => a MysqlBackup::Server object
19
+ # :mysql_files => an array of MysqlBackup::Entity::Files objects
20
+ #
21
+ # Yields a hash:
22
+ #
23
+ # :identifier => a MysqlBackup::Entity::Identifier object
24
+ # :file => a Pathname object
25
+ def self.create_tar_files args = {}, &block
26
+ begin
27
+ log_data = build_files args
28
+ log_data[:files].each do |p|
29
+ process_file(log_data.merge(:file => p), &block)
30
+ end
31
+ ensure
32
+ # files.each {|f| f.unlink if f.exist?}
33
+ end
34
+ end
35
+
36
+ # Create the actual files in a
37
+ # <tt>with_lock</tt> block.
38
+ def self.build_files args #:nodoc:
39
+ log_data = nil
40
+ args[:mysql_server].with_lock do |l|
41
+ log_data = l
42
+ mysql_file_objs = args[:mysql_files]
43
+ mysql_file_objs.each do |o|
44
+ o.confirm_required_paths_are_readable
45
+ end
46
+ path_strings = (mysql_file_objs.map {|o| o.required_path_strings}).flatten.uniq
47
+ log_data[:files] = tar_files path_strings
48
+ log_data[:n_parts] = log_data[:files].length
49
+ end
50
+ log_data
51
+ end
52
+
53
+ # Process each file with the specified block
54
+ def self.process_file args, &block #:nodoc:
55
+ part_number = args[:file].to_s[/.*(\d+)$/, 1].to_i
56
+ identifier = MysqlBackup::Entity::Identifier.create_object args.merge(:category => :full, :type => :binary, :part_number => part_number)
57
+ block.call(:identifier => identifier, :file => args[:file])
58
+ end
59
+
60
+ def confirm_required_paths_are_readable
61
+ required_paths.each do |p|
62
+ raise RuntimeError, "Not readable: #{p}" unless p.readable?
63
+ end
64
+ end
65
+
66
+ # Returns a list of path strings that need to be
67
+ # backed up.
68
+ def required_path_strings
69
+ files = required_paths.map {|p| p.cleanpath.to_s}
70
+ end
71
+
72
+ def self.do_tar args #:nodoc:
73
+ log = args[:log]
74
+ log && log.info("running #{cmd}")
75
+ system args[:cmd] or raise RuntimeError, "The command failed with status #{$?}"
76
+ end
77
+
78
+ # Given a set of variable names, create a
79
+ # set of matching Pathname objects with
80
+ # <tt>_path</tt> appended to the name.
81
+ def set_path_vars var_names, args = {} #:nodoc:
82
+ args.each_pair do |k,v|
83
+ send "#{k}=", v
84
+ end
85
+ var_names.each do |p|
86
+ instance_var_name = "@#{p}"
87
+ instance_var_value = instance_variable_get(instance_var_name)
88
+ path_instance_var_name = "@#{p}_path"
89
+ raise RuntimeError, "Must pass :#{p}" unless instance_var_value
90
+ new_path = Pathname.new(instance_var_value)
91
+ instance_variable_set path_instance_var_name, new_path
92
+ raise RuntimeError, "Must provide a readable file for #{instance_var_name}" unless new_path.readable?
93
+ end
94
+ end
95
+ end