mysql_truck 0.2.1 → 0.3.0

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.
@@ -27,27 +27,34 @@ module MysqlTruck
27
27
  if dump_table?(table)
28
28
 
29
29
  # This command creates a table_name.sql and a table_name.txt file
30
- cmd = "mysqldump --quick -T #{tmp_path} "
31
- cmd += csv_options
32
- cmd += "#{db_connection_options} #{table}"
33
- puts cmd
34
- `#{cmd}`
35
-
36
- # `mysqldump` creates files with .txt extensions, so we rename it.
37
- mv filename(table)[:txt_file], filename(table)[:csv_file]
30
+ base_cmd = "mysqldump --quick"
31
+
32
+ # Dump schema
33
+ schema_cmd = "#{base_cmd} --no-data "
34
+ schema_cmd += "#{db_connection_options} #{table}"
35
+ schema_cmd += " > #{filename(table)[:schema_file]}"
36
+ puts schema_cmd
37
+ `#{schema_cmd}`
38
+
39
+ # Dump data
40
+ data_cmd = "#{base_cmd} --no-create-info "
41
+ data_cmd += "#{db_connection_options} #{table}"
42
+ data_cmd += " > #{filename(table)[:data_file]}"
43
+ puts data_cmd
44
+ `#{data_cmd}`
38
45
  end
39
46
 
40
47
  if split_schema_file?(table)
41
48
  schema_contents = filename(table)[:schema_file].read
42
49
 
43
50
  # Create schema with no indexes
44
- File.open(filename(table)[:no_index_sql_file], 'w') do |f|
51
+ File.open(filename(table)[:no_index_schema_file], 'w') do |f|
45
52
  f.write(schema_contents.gsub(REGEX, ''))
46
53
  end
47
54
 
48
55
  # Create an alter table
49
56
  indices = []
50
- File.open(filename(table)[:index_sql_file], 'w') do |f|
57
+ File.open(filename(table)[:alter_table_file], 'w') do |f|
51
58
  f.write("ALTER TABLE #{table}\n")
52
59
 
53
60
  schema_contents.gsub(/^,?\s*((UNIQUE)?\s*KEY\s`[A-Za-z\d_]+`\s*\([A-Za-z\d_,`]+\)),?\s*$/) do |part|
@@ -58,14 +65,14 @@ module MysqlTruck
58
65
  end
59
66
 
60
67
  if gzip_files?(table)
61
- puts "gzipping #{filename(table)[:no_index_sql_file]}."
62
- `gzip #{filename(table)[:no_index_sql_file]}`
68
+ puts "gzipping #{filename(table)[:no_index_schema_file]}."
69
+ `gzip #{filename(table)[:no_index_schema_file]}`
63
70
 
64
- puts "gzipping #{filename(table)[:index_sql_file]}."
65
- `gzip #{filename(table)[:index_sql_file]}`
71
+ puts "gzipping #{filename(table)[:alter_table_file]}."
72
+ `gzip #{filename(table)[:alter_table_file]}`
66
73
 
67
- puts "gziping #{filename(table)[:csv_file]}."
68
- `gzip #{filename(table)[:csv_file]}`
74
+ puts "gziping #{filename(table)[:data_file]}."
75
+ `gzip #{filename(table)[:data_file]}`
69
76
  end
70
77
 
71
78
  puts "#{table} dumped.\n\n"
@@ -105,28 +112,31 @@ module MysqlTruck
105
112
  end
106
113
 
107
114
  def bucket_path
108
- @bucket_path ||= Pathname.new(bucket_dir).join(@time.strftime("%Y-%m-%d-%H-%M"))
115
+ @bucket_path ||= Pathname.new(bucket_dir).join(@time.strftime("%Y-%m-%d"))
109
116
  end
110
117
 
111
118
  def filename(table)
112
119
  @table_filenames ||= {}
113
120
  @table_filenames[table] ||= {
114
- :schema_file => tmp_path.join("#{table}.sql"),
115
- :no_index_sql_file => tmp_path.join("#{table}.no_index.sql"),
116
- :index_sql_file => tmp_path.join("#{table}.indices.sql"),
117
- :txt_file => tmp_path.join("#{table}.txt"),
118
- :csv_file => tmp_path.join("#{table}.csv"),
119
- :gz_no_index_sql_file => tmp_path.join("#{table}.no_index.sql.gz"),
120
- :gz_index_sql_file => tmp_path.join("#{table}.indices.sql.gz"),
121
- :gz_csv_file => tmp_path.join("#{table}.csv.gz"),
121
+ # mysqldump files
122
+ :schema_file => tmp_path.join("#{table}.schema.sql"),
123
+ :no_index_schema_file => tmp_path.join("#{table}.no_index.sql"),
124
+
125
+ # altered mysql dump files
126
+ :alter_table_file => tmp_path.join("#{table}.indices.sql"),
127
+ :data_file => tmp_path.join("#{table}.data.sql"),
128
+
129
+ # Gzip filenames
130
+ :gz_no_index_schema_file => tmp_path.join("#{table}.no_index.sql.gz"),
131
+ :gz_alter_table_file => tmp_path.join("#{table}.indices.sql.gz"),
132
+ :gz_data_file => tmp_path.join("#{table}.data.sql.gz"),
122
133
  }
123
134
  end
124
135
 
125
136
  def gzip_files_exist?(table)
126
- tmp_path.join("#{table}.sql.gz").file? &&
127
- tmp_path.join("#{table}.no_index.sql.gz") &&
128
- tmp_path.join("#{table}.indexes.sql.gz") &&
129
- tmp_path.join("#{table}.csv.gz")
137
+ filename(table)[:gz_no_index_schema_file].file? &&
138
+ filename(table)[:gz_alter_table_file].file? &&
139
+ filename(table)[:gz_data_file].file?
130
140
  end
131
141
 
132
142
 
@@ -135,12 +145,7 @@ module MysqlTruck
135
145
  (
136
146
  smartly? &&
137
147
  !filename(table)[:schema_file].exist? &&
138
- !filename(table)[:csv_file].exist? &&
139
- !filename(table)[:no_index_sql_file].exist? &&
140
- !filename(table)[:index_sql_file].exist? &&
141
- !filename(table)[:gz_no_index_sql_file].exist? &&
142
- !filename(table)[:gz_index_sql_file].exist? &&
143
- !filename(table)[:gz_csv_file].exist?
148
+ !filename(table)[:data_file].exist?
144
149
  )
145
150
  end
146
151
 
@@ -149,12 +154,9 @@ module MysqlTruck
149
154
  (
150
155
  smartly? &&
151
156
  filename(table)[:schema_file].exist? &&
152
- filename(table)[:csv_file].exist? &&
153
- !filename(table)[:no_index_sql_file].exist? &&
154
- !filename(table)[:index_sql_file].exist? &&
155
- !filename(table)[:gz_no_index_sql_file].exist? &&
156
- !filename(table)[:gz_index_sql_file].exist? &&
157
- !filename(table)[:gz_csv_file].exist?
157
+ filename(table)[:data_file].exist? &&
158
+ !filename(table)[:no_index_schema_file].exist? &&
159
+ !filename(table)[:alter_table_file].exist?
158
160
  )
159
161
  end
160
162
 
@@ -162,13 +164,10 @@ module MysqlTruck
162
164
  !smartly? ||
163
165
  (
164
166
  smartly? &&
165
- filename(table)[:schema_file].exist? &&
166
- filename(table)[:csv_file].exist? &&
167
- filename(table)[:no_index_sql_file].exist? &&
168
- filename(table)[:index_sql_file].exist? &&
169
- !filename(table)[:gz_no_index_sql_file].exist? &&
170
- !filename(table)[:gz_index_sql_file].exist? &&
171
- !filename(table)[:gz_csv_file].exist?
167
+ filename(table)[:data_file].exist? &&
168
+ filename(table)[:no_index_schema_file].exist? &&
169
+ filename(table)[:alter_table_file].exist? &&
170
+ !gzip_files_exist?(table)
172
171
  )
173
172
  end
174
173
  end # class Dumper
@@ -1,3 +1,4 @@
1
+ require 'benchmark'
1
2
  module MysqlTruck
2
3
  module Helper
3
4
  include FileUtils
@@ -29,10 +30,6 @@ module MysqlTruck
29
30
  !local_host?
30
31
  end
31
32
 
32
- def csv_options
33
- " --fields-enclosed-by=\\\" --fields-terminated-by=, "
34
- end
35
-
36
33
  def initialize_directories
37
34
  mkdir_p base_path
38
35
  mkdir_p tmp_path
@@ -59,5 +56,15 @@ module MysqlTruck
59
56
  def bucket_dir
60
57
  "mysql/#{config[:bucket_dir] || config[:database]}/"
61
58
  end
59
+
60
+ def benchmark
61
+ Benchmark.realtime do
62
+ yield
63
+ end
64
+ end
65
+
66
+ def formatted_time(time)
67
+ "#{"%0.5f" % time}ms"
68
+ end
62
69
  end
63
70
  end
@@ -25,7 +25,7 @@ module MysqlTruck
25
25
  @time = Time.new(*prefix.split("/").last.split("-"))
26
26
  initialize_directories
27
27
 
28
- puts "Downloading backups"
28
+ puts "Download & gunzip backups"
29
29
  puts "-------------------"
30
30
  @bucket.keys(:prefix => prefix).each do |key|
31
31
  puts "\n#{key}"
@@ -34,8 +34,8 @@ module MysqlTruck
34
34
  # gunzip file
35
35
  if tmp_path.join(filename).exist?
36
36
  print " - Inflating #{filename} ... "
37
- `gunzip -f #{tmp_path.join(filename)}`
38
- print "complete.\n"
37
+ time = benchmark { `gunzip -f #{tmp_path.join(filename)}` }
38
+ print "complete (#{formatted_time time}).\n"
39
39
  end
40
40
  end
41
41
 
@@ -47,39 +47,48 @@ module MysqlTruck
47
47
  else
48
48
  import_cmd = "mysqlimport #{db_connection_options}"
49
49
  end
50
- import_cmd += csv_options
50
+
51
+ files = Dir["#{tmp_path}/*.no_index.sql"]
52
+ total = files.size
53
+ count = 0
51
54
 
52
55
  # Find all .no_index.sql files and process
53
- Dir["#{tmp_path}/*.no_index.sql"].each do |file|
54
- table = File.basename(file, ".no_index.sql")
55
- puts "\nProcessing #{table}"
56
+ files.sort.each do |file|
57
+ count += 1
58
+ table = File.basename(file, ".no_index.sql")
59
+
60
+ puts "\nProcessing #{table} (#{count}/#{total})"
56
61
 
57
62
  schema_file = Pathname.new(file)
58
63
  index_file = tmp_path.join("#{table}.indices.sql")
59
- csv_file = tmp_path.join("#{table}.csv")
64
+ data_file = tmp_path.join("#{table}.data.sql")
60
65
 
61
66
 
62
67
  print " - Loading schema for #{table} ... "
63
68
  cmd = "cat #{schema_file} | mysql #{db_connection_options}"
64
- `#{cmd}`
65
- print "complete.\n"
69
+ time = benchmark { `#{cmd}` }
70
+ print "complete (#{formatted_time time}).\n"
66
71
 
67
- if csv_file.exist?
72
+ if data_file.exist?
68
73
  print " - Importing #{schema_file.basename(".sql")} ... "
69
- `#{import_cmd} #{csv_file}`
70
- print "complete.\n"
74
+ time = benchmark do
75
+ `cat #{data_file} | mysql #{db_connection_options}`
76
+ end
77
+ print "complete (#{formatted_time time}).\n"
71
78
  end
72
79
 
73
80
  if index_file.exist?
74
81
  print " - Adding indices for #{schema_file.basename(".no_index.sql")} ... "
75
82
  cmd = "cat #{index_file} | mysql #{db_connection_options}"
76
- `#{cmd}`
77
- print "complete.\n"
83
+ time = benchmark do
84
+ `#{cmd}`
85
+ end
86
+ print "complete (#{formatted_time time}).\n"
78
87
  end
79
88
 
80
89
  schema_file.delete if schema_file.exist?
81
90
  index_file.delete if index_file.exist?
82
- csv_file.delete if csv_file.exist?
91
+ data_file.delete if data_file.exist?
83
92
  end
84
93
 
85
94
  puts "Backup loaded."
@@ -106,13 +115,15 @@ module MysqlTruck
106
115
  if !smartly? || (smartly? && !unzipped_file.exist?)
107
116
  print " - Downloading... "
108
117
 
109
- file.open("wb") do |f|
110
- @bucket.s3.interface.get(@bucket.name, key.name) do |chunk|
111
- f.write chunk
118
+ time = benchmark do
119
+ file.open("wb") do |f|
120
+ @bucket.s3.interface.get(@bucket.name, key.name) do |chunk|
121
+ f.write chunk
122
+ end
112
123
  end
113
124
  end
114
125
 
115
- puts "complete."
126
+ puts "complete (#{formatted_time time})."
116
127
  else
117
128
  puts " already downloaded."
118
129
  end
@@ -133,7 +144,7 @@ module MysqlTruck
133
144
  return only_tables.include?(table_name)
134
145
  end
135
146
 
136
- if filename.match(/\.csv\.gz$/)
147
+ if filename.match(/\.data\.sql\.gz$/)
137
148
  is_data = true
138
149
  is_schema = false
139
150
  else
@@ -1,3 +1,3 @@
1
1
  module MysqlTruck
2
- VERSION = "0.2.1"
2
+ VERSION = "0.3.0"
3
3
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: mysql_truck
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.2.1
4
+ version: 0.3.0
5
5
  prerelease:
6
6
  platform: ruby
7
7
  authors:
@@ -11,11 +11,11 @@ authors:
11
11
  autorequire:
12
12
  bindir: bin
13
13
  cert_chain: []
14
- date: 2012-05-30 00:00:00.000000000Z
14
+ date: 2012-06-20 00:00:00.000000000Z
15
15
  dependencies:
16
16
  - !ruby/object:Gem::Dependency
17
17
  name: right_aws
18
- requirement: &70252611012460 !ruby/object:Gem::Requirement
18
+ requirement: &70141600570020 !ruby/object:Gem::Requirement
19
19
  none: false
20
20
  requirements:
21
21
  - - ! '>='
@@ -23,7 +23,7 @@ dependencies:
23
23
  version: '0'
24
24
  type: :runtime
25
25
  prerelease: false
26
- version_requirements: *70252611012460
26
+ version_requirements: *70141600570020
27
27
  description: Mysql database backup tool. Dumps/Loads to/from S3.
28
28
  email:
29
29
  - peter@paydrotalks.com