mysql_truck 0.2.1 → 0.3.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -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