lhm 1.2.0 → 2.2.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.
Files changed (65) hide show
  1. checksums.yaml +7 -0
  2. data/.gitignore +7 -0
  3. data/.rubocop.yml +256 -0
  4. data/.travis.yml +5 -1
  5. data/CHANGELOG.md +26 -0
  6. data/README.md +87 -8
  7. data/Rakefile +6 -4
  8. data/bin/lhm-config.sh +7 -0
  9. data/bin/lhm-kill-queue +13 -15
  10. data/bin/lhm-spec-clobber.sh +5 -4
  11. data/bin/lhm-spec-grants.sh +2 -2
  12. data/bin/lhm-spec-setup-cluster.sh +2 -3
  13. data/gemfiles/ar-2.3_mysql.gemfile +2 -1
  14. data/gemfiles/ar-3.2_mysql.gemfile +1 -1
  15. data/gemfiles/ar-3.2_mysql2.gemfile +1 -1
  16. data/gemfiles/dm_mysql.gemfile +1 -1
  17. data/lhm.gemspec +7 -8
  18. data/lib/lhm/atomic_switcher.rb +2 -1
  19. data/lib/lhm/chunker.rb +51 -39
  20. data/lib/lhm/command.rb +4 -2
  21. data/lib/lhm/connection.rb +14 -2
  22. data/lib/lhm/entangler.rb +5 -5
  23. data/lib/lhm/intersection.rb +29 -16
  24. data/lib/lhm/invoker.rb +31 -10
  25. data/lib/lhm/locked_switcher.rb +6 -6
  26. data/lib/lhm/migration.rb +7 -5
  27. data/lib/lhm/migrator.rb +57 -9
  28. data/lib/lhm/printer.rb +54 -0
  29. data/lib/lhm/sql_helper.rb +4 -4
  30. data/lib/lhm/table.rb +12 -12
  31. data/lib/lhm/throttler/time.rb +29 -0
  32. data/lib/lhm/throttler.rb +32 -0
  33. data/lib/lhm/version.rb +1 -1
  34. data/lib/lhm.rb +71 -6
  35. data/spec/.lhm.example +1 -1
  36. data/spec/README.md +20 -13
  37. data/spec/fixtures/lines.ddl +7 -0
  38. data/spec/fixtures/permissions.ddl +5 -0
  39. data/spec/fixtures/tracks.ddl +5 -0
  40. data/spec/fixtures/users.ddl +4 -2
  41. data/spec/integration/atomic_switcher_spec.rb +7 -7
  42. data/spec/integration/chunker_spec.rb +11 -5
  43. data/spec/integration/cleanup_spec.rb +72 -0
  44. data/spec/integration/entangler_spec.rb +11 -11
  45. data/spec/integration/integration_helper.rb +49 -17
  46. data/spec/integration/lhm_spec.rb +157 -37
  47. data/spec/integration/locked_switcher_spec.rb +7 -7
  48. data/spec/integration/table_spec.rb +15 -17
  49. data/spec/test_helper.rb +28 -0
  50. data/spec/unit/atomic_switcher_spec.rb +6 -6
  51. data/spec/unit/chunker_spec.rb +95 -73
  52. data/spec/unit/datamapper_connection_spec.rb +1 -0
  53. data/spec/unit/entangler_spec.rb +19 -19
  54. data/spec/unit/intersection_spec.rb +27 -15
  55. data/spec/unit/lhm_spec.rb +29 -0
  56. data/spec/unit/locked_switcher_spec.rb +14 -14
  57. data/spec/unit/migration_spec.rb +10 -5
  58. data/spec/unit/migrator_spec.rb +53 -41
  59. data/spec/unit/printer_spec.rb +79 -0
  60. data/spec/unit/sql_helper_spec.rb +10 -10
  61. data/spec/unit/table_spec.rb +11 -11
  62. data/spec/unit/throttler_spec.rb +73 -0
  63. data/spec/unit/unit_helper.rb +1 -13
  64. metadata +63 -24
  65. data/spec/bootstrap.rb +0 -13
checksums.yaml ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: dea357ff2aae21b2cee84cc6d546aa2328fd6164
4
+ data.tar.gz: b6b3e4b06ed6f7ea1b14ac2be2444cc8b6357966
5
+ SHA512:
6
+ metadata.gz: a4a2e08f68b46ba6141bd37093f3c5341488c60d4a1bf6069b1339481f11ff1117ebe1198a383e09f1ae635d68966e98256d31a981ff89171eb582fd7b075170
7
+ data.tar.gz: 49174830b37493a1652394a4ee717f52939675d39289bc183f38969ae840cc5c9f00b5668d585888751916e395f471a3f24501192c8bf52cd3321d1c9d50dc32
data/.gitignore CHANGED
@@ -4,3 +4,10 @@ Gemfile.lock
4
4
  gemfiles/*.lock
5
5
  pkg/*
6
6
  .rvmrc
7
+ .ruby-version
8
+ .ruby-gemset
9
+ bin/rake
10
+ spec/integration/database.yml
11
+ Gemfile
12
+ gemfiles/vendor
13
+ omg.ponies
data/.rubocop.yml ADDED
@@ -0,0 +1,256 @@
1
+ # This configuration was generated by `rubocop --auto-gen-config`
2
+ # on 2015-01-12 14:49:41 +0100 using RuboCop version 0.26.1.
3
+ # The point is for the user to remove these configuration records
4
+ # one by one as the offenses are removed from the code base.
5
+ # Note that changes in the inspected code, or installation of new
6
+ # versions of RuboCop, may require this file to be generated again.
7
+
8
+ # Offense count: 2
9
+ Lint/AmbiguousRegexpLiteral:
10
+ Enabled: false
11
+
12
+ # Offense count: 2
13
+ # Configuration parameters: AllowSafeAssignment.
14
+ Lint/AssignmentInCondition:
15
+ Enabled: false
16
+
17
+ # Offense count: 1
18
+ Lint/ConditionPosition:
19
+ Enabled: false
20
+
21
+ # Offense count: 1
22
+ Lint/HandleExceptions:
23
+ Enabled: false
24
+
25
+ # Offense count: 6
26
+ # Cop supports --auto-correct.
27
+ Lint/UnusedBlockArgument:
28
+ Enabled: false
29
+
30
+ # Offense count: 3
31
+ # Cop supports --auto-correct.
32
+ Lint/UnusedMethodArgument:
33
+ Enabled: false
34
+
35
+ # Offense count: 4
36
+ Lint/UselessAssignment:
37
+ Enabled: false
38
+
39
+ # Offense count: 1
40
+ # Configuration parameters: CountComments.
41
+ Metrics/ClassLength:
42
+ Max: 131
43
+
44
+ # Offense count: 3
45
+ Metrics/CyclomaticComplexity:
46
+ Max: 19
47
+
48
+ # Offense count: 77
49
+ # Configuration parameters: AllowURI, URISchemes.
50
+ Metrics/LineLength:
51
+ Max: 197
52
+
53
+ # Offense count: 11
54
+ # Configuration parameters: CountComments.
55
+ Metrics/MethodLength:
56
+ Max: 27
57
+
58
+ # Offense count: 3
59
+ Metrics/PerceivedComplexity:
60
+ Max: 15
61
+
62
+ # Offense count: 10
63
+ # Cop supports --auto-correct.
64
+ # Configuration parameters: EnforcedStyle, SupportedStyles.
65
+ Style/AccessModifierIndentation:
66
+ Enabled: false
67
+
68
+ # Offense count: 4
69
+ # Cop supports --auto-correct.
70
+ # Configuration parameters: EnforcedStyle, SupportedStyles.
71
+ Style/AlignParameters:
72
+ Enabled: false
73
+
74
+ # Offense count: 5
75
+ # Cop supports --auto-correct.
76
+ # Configuration parameters: EnforcedStyle, SupportedStyles.
77
+ Style/AndOr:
78
+ Enabled: false
79
+
80
+ # Offense count: 13
81
+ # Cop supports --auto-correct.
82
+ # Configuration parameters: EnforcedStyle, SupportedStyles.
83
+ Style/BarePercentLiterals:
84
+ Enabled: false
85
+
86
+ # Offense count: 1
87
+ # Cop supports --auto-correct.
88
+ Style/Blocks:
89
+ Enabled: false
90
+
91
+ # Offense count: 11
92
+ # Cop supports --auto-correct.
93
+ # Configuration parameters: EnforcedStyle, SupportedStyles.
94
+ Style/BracesAroundHashParameters:
95
+ Enabled: false
96
+
97
+ # Offense count: 5
98
+ Style/ClassVars:
99
+ Enabled: false
100
+
101
+ # Offense count: 3
102
+ # Cop supports --auto-correct.
103
+ # Configuration parameters: PreferredMethods.
104
+ Style/CollectionMethods:
105
+ Enabled: false
106
+
107
+ # Offense count: 24
108
+ Style/Documentation:
109
+ Enabled: false
110
+
111
+ # Offense count: 28
112
+ # Cop supports --auto-correct.
113
+ # Configuration parameters: EnforcedStyle, SupportedStyles.
114
+ Style/DotPosition:
115
+ Enabled: false
116
+
117
+ # Offense count: 4
118
+ Style/DoubleNegation:
119
+ Enabled: false
120
+
121
+ # Offense count: 1
122
+ Style/EachWithObject:
123
+ Enabled: false
124
+
125
+ # Offense count: 1
126
+ # Configuration parameters: Exclude.
127
+ Style/FileName:
128
+ Enabled: false
129
+
130
+ # Offense count: 11
131
+ # Configuration parameters: EnforcedStyle, SupportedStyles.
132
+ Style/FormatString:
133
+ Enabled: false
134
+
135
+ # Offense count: 10
136
+ # Configuration parameters: AllowedVariables.
137
+ Style/GlobalVars:
138
+ Enabled: false
139
+
140
+ # Offense count: 9
141
+ # Configuration parameters: MinBodyLength.
142
+ Style/GuardClause:
143
+ Enabled: false
144
+
145
+ # Offense count: 88
146
+ # Cop supports --auto-correct.
147
+ # Configuration parameters: EnforcedStyle, SupportedStyles.
148
+ Style/HashSyntax:
149
+ Enabled: false
150
+
151
+ # Offense count: 3
152
+ # Configuration parameters: MaxLineLength.
153
+ Style/IfUnlessModifier:
154
+ Enabled: false
155
+
156
+ # Offense count: 14
157
+ # Cop supports --auto-correct.
158
+ # Configuration parameters: EnforcedStyle, SupportedStyles.
159
+ Style/IndentHash:
160
+ Enabled: false
161
+
162
+ # Offense count: 1
163
+ # Cop supports --auto-correct.
164
+ Style/IndentationConsistency:
165
+ Enabled: false
166
+
167
+ # Offense count: 1
168
+ # Cop supports --auto-correct.
169
+ Style/IndentationWidth:
170
+ Enabled: false
171
+
172
+ # Offense count: 2
173
+ Style/ModuleFunction:
174
+ Enabled: false
175
+
176
+ # Offense count: 2
177
+ Style/MultilineBlockChain:
178
+ Enabled: false
179
+
180
+ # Offense count: 1
181
+ # Cop supports --auto-correct.
182
+ Style/NegatedIf:
183
+ Enabled: false
184
+
185
+ # Offense count: 4
186
+ # Cop supports --auto-correct.
187
+ Style/NumericLiterals:
188
+ MinDigits: 8
189
+
190
+ # Offense count: 14
191
+ # Cop supports --auto-correct.
192
+ # Configuration parameters: PreferredDelimiters.
193
+ Style/PercentLiteralDelimiters:
194
+ Enabled: false
195
+
196
+ # Offense count: 3
197
+ # Configuration parameters: EnforcedStyle, SupportedStyles.
198
+ Style/RaiseArgs:
199
+ Enabled: false
200
+
201
+ # Offense count: 1
202
+ # Cop supports --auto-correct.
203
+ # Configuration parameters: AllowMultipleReturnValues.
204
+ Style/RedundantReturn:
205
+ Enabled: false
206
+
207
+ # Offense count: 2
208
+ # Cop supports --auto-correct.
209
+ Style/RedundantSelf:
210
+ Enabled: false
211
+
212
+ # Offense count: 1
213
+ Style/RescueModifier:
214
+ Enabled: false
215
+
216
+ # Offense count: 1
217
+ Style/SelfAssignment:
218
+ Enabled: false
219
+
220
+ # Offense count: 7
221
+ # Cop supports --auto-correct.
222
+ # Configuration parameters: EnforcedStyle, SupportedStyles.
223
+ Style/SignalException:
224
+ Enabled: false
225
+
226
+ # Cop supports --auto-correct.
227
+ # Configuration parameters: EnforcedStyle, EnforcedStyleForEmptyBraces, SupportedStyles.
228
+ Style/SpaceInsideHashLiteralBraces:
229
+ SupportedStyles: space
230
+
231
+ # Offense count: 2
232
+ # Cop supports --auto-correct.
233
+ Style/SpecialGlobalVars:
234
+ Enabled: false
235
+
236
+ # Offense count: 5
237
+ # Cop supports --auto-correct.
238
+ # Configuration parameters: ExactNameMatch, AllowPredicates, AllowDSLWriters, Whitelist.
239
+ Style/TrivialAccessors:
240
+ Enabled: false
241
+
242
+ # Offense count: 15
243
+ # Cop supports --auto-correct.
244
+ Style/UnneededPercentQ:
245
+ Enabled: false
246
+
247
+ # Offense count: 3
248
+ # Cop supports --auto-correct.
249
+ Style/WordArray:
250
+ MinSize: 2
251
+
252
+ # Offense count: 2
253
+ # Cop supports --auto-correct.
254
+ # Configuration parameters: AllowSafeAssignment.
255
+ Style/ParenthesesAroundCondition:
256
+ Enabled: false
data/.travis.yml CHANGED
@@ -2,8 +2,12 @@ language: ruby
2
2
  before_script:
3
3
  - "mysql -e 'create database lhm;'"
4
4
  rvm:
5
- - 1.8.7
6
5
  - 1.9.3
6
+ - 2.0.0
7
+ - 2.1
8
+ sudo: false
9
+ matrix:
10
+ fast_finish: true
7
11
  gemfile:
8
12
  - gemfiles/ar-2.3_mysql.gemfile
9
13
  - gemfiles/ar-3.2_mysql.gemfile
data/CHANGELOG.md CHANGED
@@ -1,3 +1,29 @@
1
+ # 2.2.0 (not released)
2
+
3
+ * #84 - Require index names to be strings or symbols (Thibaut)
4
+ * #39 - Adding the ability to rename columns (erikogan)
5
+ * #67 - Allow for optional time filter on .cleanup (joelr)
6
+
7
+ # 2.1.0
8
+
9
+ * #48 - Add percentage output for migrations (@arthurnn)
10
+ * #60 - Quote table names (@spickermann)
11
+ * #59 - Escape table name in select_limit and select_start methods (@stevehodgkiss)
12
+ * #57 - Ensure chunking 'where' clause handled separately (@rentalcustard)
13
+ * #54 - Chunker handle stride changes (@rentalcustard)
14
+ * #52 - Implement ability to control timeout and stride from Throttler (@edmundsalvacion)
15
+ * #51 - Ensure Lhm.cleanup removes temporary triggers (@edmundsalvacion)
16
+ * #46 - Allow custom throttler (@arthurnn)
17
+
18
+ # 2.0.0
19
+
20
+ * #44 - Conditional migrations (@durran)
21
+
22
+ # 1.3.0 (May 28, 2013)
23
+
24
+ * Add Lhm.cleanup method for removing copy tables, thanks @bogdan
25
+ * Limit copy table names to 64 characters, thanks @charliesome
26
+
1
27
  # 1.2.0 (February 22, 2013)
2
28
 
3
29
  * Added DataMapper support, no API changes for current users. Refer to the
data/README.md CHANGED
@@ -1,4 +1,4 @@
1
- # Large Hadron Migrator [![Build Status](https://secure.travis-ci.org/soundcloud/large-hadron-migrator.png?branch=master)][4]
1
+ # Large Hadron Migrator [![Build Status][5]][4]
2
2
 
3
3
  Rails style database migrations are a useful way to evolve your data schema in
4
4
  an agile manner. Most Rails projects start like this, and at first, making
@@ -45,13 +45,19 @@ the [twitter solution][2], it does not require the presence of an indexed
45
45
  Lhm currently only works with MySQL databases and requires an established
46
46
  ActiveRecord or DataMapper connection.
47
47
 
48
- It is compatible and [continuously tested][4] with Ruby 1.8.7 and Ruby 1.9.x,
48
+ It is compatible and [continuously tested][4] with MRI 1.9.x, 2.0.x, 2.1.x,
49
49
  ActiveRecord 2.3.x and 3.x (mysql and mysql2 adapters), as well as DataMapper
50
50
  1.2 (dm-mysql-adapter).
51
51
 
52
52
  Lhm also works with dm-master-slave-adapter, it'll bind to the master before
53
53
  running the migrations.
54
54
 
55
+
56
+ ## Limitations
57
+
58
+ Lhm requires a monotonically increasing numeric Primary Key on the table, due to how
59
+ the Chunker works.
60
+
55
61
  ## Installation
56
62
 
57
63
  Install it via `gem install lhm` or add `gem "lhm"` to your Gemfile.
@@ -133,18 +139,35 @@ end
133
139
  **Note:** Lhm won't delete the old, leftover table. This is on purpose, in order
134
140
  to prevent accidental data loss.
135
141
 
142
+ ## Throttler
143
+
144
+ Lhm is using a throttle mecanism to read data in your original table.
145
+
146
+ By default, 40000 rows are read each 0.1 second.
147
+
148
+ If you want to change that behiavour, you can pass an instance of a throttler with the `throttler` option.
149
+
150
+ In this example, 1000 rows will be read with a 10 seconds delay between each processing:
151
+ ```ruby
152
+ my_throttler = Lhm::Throttler::Time.new(stride: 1000, delay: 10)
153
+
154
+ Lhm.change_table :users, throttler: my_throttler do |m|
155
+ #
156
+ end
157
+ ```
158
+
136
159
  ## Table rename strategies
137
160
 
138
161
  There are two different table rename strategies available: LockedSwitcher and
139
162
  AtomicSwitcher.
140
163
 
141
- The LockedSwitcher strategy locks the table being migrated and issues two ALTER TABLE statements.
164
+ The LockedSwitcher strategy locks the table being migrated and issues two ALTER TABLE statements.
142
165
  The AtomicSwitcher uses a single atomic RENAME TABLE query and is the favored solution.
143
166
 
144
- Lhm chooses AtomicSwitcher if no strategy is specified, **unless** your version of MySQL is
145
- affected by [binlog bug #39675](http://bugs.mysql.com/bug.php?id=39675). If your version is
146
- affected, Lhm will raise an error if you don't specify a strategy. You're recommended
147
- to use the LockedSwitcher in these cases to avoid replication issues.
167
+ Lhm chooses AtomicSwitcher if no strategy is specified, **unless** your version of MySQL is
168
+ affected by [binlog bug #39675](http://bugs.mysql.com/bug.php?id=39675). If your version is
169
+ affected, Lhm will raise an error if you don't specify a strategy. You're recommended
170
+ to use the LockedSwitcher in these cases to avoid replication issues.
148
171
 
149
172
  To specify the strategy in your migration:
150
173
 
@@ -154,8 +177,63 @@ Lhm.change_table :users, :atomic_switch => true do |m|
154
177
  end
155
178
  ```
156
179
 
180
+ ## Limiting the data that is migrated
181
+
182
+ For instances where you want to limit the data that is migrated to the new
183
+ table by some conditions, you may tell the migration to filter by a set of
184
+ conditions:
185
+
186
+ ```ruby
187
+ Lhm.change_table(:sounds) do |m|
188
+ m.filter("inner join users on users.`id` = sounds.`user_id` and sounds.`public` = 1")
189
+ end
190
+ ```
191
+
192
+ Note that this SQL will be inserted into the copy directly after the "from"
193
+ statement - so be sure to use inner/outer join syntax and not cross joins. These
194
+ conditions will not affect the triggers, so any modifications to the table
195
+ during the run will happen on the new table as well.
196
+
197
+ ## Cleaning up after an interrupted Lhm run
198
+
199
+ If an Lhm migration is interrupted, it may leave behind the temporary tables
200
+ and/or triggers used in the migration. If the migration is re-started, the
201
+ unexpected presence of these tables will cause an error.
202
+
203
+ In this case, `Lhm.cleanup` can be used to drop any orphaned Lhm temporary tables or triggers.
204
+
205
+ To see what Lhm tables/triggers are found:
206
+
207
+ ```ruby
208
+ Lhm.cleanup
209
+ ```
210
+
211
+ To remove any Lhm tables/triggers found:
212
+ ```ruby
213
+ Lhm.cleanup(true)
214
+ ```
215
+
216
+ Optionally only remove tables up to a specific Time, if you want to retain previous migrations.
217
+
218
+ Rails:
219
+ ```ruby
220
+ Lhm.cleanup(true, until: 1.day.ago)
221
+ ```
222
+
223
+ Ruby:
224
+ ```ruby
225
+ Lhm.cleanup(true, until: Time.now - 86400)
226
+ ```
227
+
157
228
  ## Contributing
158
229
 
230
+ First, get set up for local development:
231
+
232
+ git clone git://github.com/soundcloud/lhm.git
233
+ cd lhm
234
+
235
+ To run the tests, follow the instructions on [spec/README](https://github.com/soundcloud/lhm/blob/master/spec/README.md).
236
+
159
237
  We'll check out your contribution if you:
160
238
 
161
239
  * Provide a comprehensive suite of tests for your fork.
@@ -179,4 +257,5 @@ The license is included as LICENSE in this directory.
179
257
  [1]: http://www.facebook.com/note.php?note\_id=430801045932
180
258
  [2]: https://github.com/freels/table_migrator
181
259
  [3]: http://www.percona.com/doc/percona-toolkit/2.1/pt-online-schema-change.html
182
- [4]: http://travis-ci.org/soundcloud/large-hadron-migrator
260
+ [4]: https://travis-ci.org/soundcloud/lhm
261
+ [5]: https://travis-ci.org/soundcloud/lhm.svg?branch=master
data/Rakefile CHANGED
@@ -3,14 +3,16 @@ require 'bundler'
3
3
 
4
4
  Bundler::GemHelper.install_tasks
5
5
 
6
- Rake::TestTask.new("unit") do |t|
7
- t.libs.push "lib"
6
+ Rake::TestTask.new('unit') do |t|
7
+ t.libs << 'lib'
8
+ t.libs << 'spec'
8
9
  t.test_files = FileList['spec/unit/*_spec.rb']
9
10
  t.verbose = true
10
11
  end
11
12
 
12
- Rake::TestTask.new("integration") do |t|
13
- t.libs.push "lib"
13
+ Rake::TestTask.new('integration') do |t|
14
+ t.libs << 'lib'
15
+ t.libs << 'spec'
14
16
  t.test_files = FileList['spec/integration/*_spec.rb']
15
17
  t.verbose = true
16
18
  end
data/bin/lhm-config.sh ADDED
@@ -0,0 +1,7 @@
1
+ #!/bin/sh
2
+
3
+ if [ -z ${LHM_TEST_CONFIG+x} ] ; then
4
+ source $HOME/.lhm
5
+ else
6
+ source $LHM_TEST_CONFIG
7
+ fi
data/bin/lhm-kill-queue CHANGED
@@ -6,7 +6,6 @@ require 'optparse'
6
6
 
7
7
  module Lhm
8
8
  class KillQueue
9
-
10
9
  def initialize
11
10
  @port = 3306
12
11
  @grace = 10
@@ -14,20 +13,20 @@ module Lhm
14
13
  @marker = "%#{ SqlHelper.annotation }%"
15
14
 
16
15
  OptionParser.new do |opts|
17
- opts.on("-h", "--hostname HOSTNAME") { |v| @hostname = v }
18
- opts.on("-u", "--username USERNAME") { |v| @username = v }
19
- opts.on("-p", "--password PASSWORD") { |v| @password = v }
20
- opts.on("-d", "--database DATABASE") { |v| @database = v }
21
- opts.on("-m", "--mode MODE") { |v| @mode = v.to_sym }
22
- opts.on("-y", "--confirm") { |v| @confirm = true }
16
+ opts.on('-h', '--hostname HOSTNAME') { |v| @hostname = v }
17
+ opts.on('-u', '--username USERNAME') { |v| @username = v }
18
+ opts.on('-p', '--password PASSWORD') { |v| @password = v }
19
+ opts.on('-d', '--database DATABASE') { |v| @database = v }
20
+ opts.on('-m', '--mode MODE') { |v| @mode = v.to_sym }
21
+ opts.on('-y', '--confirm') { |v| @confirm = true }
23
22
  end.parse!
24
23
 
25
- unless(@hostname && @username && @password && @database)
24
+ unless (@hostname && @username && @password && @database)
26
25
  abort usage
27
26
  end
28
27
 
29
- unless([:kill, :master, :slave].include?(@mode))
30
- abort "specify -m kill OR -m master OR -m slave"
28
+ unless ([:kill, :master, :slave].include?(@mode))
29
+ abort 'specify -m kill OR -m master OR -m slave'
31
30
  end
32
31
 
33
32
  connect
@@ -73,7 +72,7 @@ module Lhm
73
72
  sleep(@grace + @tiny)
74
73
 
75
74
  [list_non_lhm].flatten.each do |process|
76
- if(select?(process))
75
+ if (select?(process))
77
76
  kill_process(process)
78
77
  sleep(@tiny)
79
78
  end
@@ -115,11 +114,11 @@ module Lhm
115
114
  def kill_process(process_id)
116
115
  puts "killing #{ select_statement(process_id) }"
117
116
 
118
- if(@confirm)
117
+ if (@confirm)
119
118
  print "confirm ('y' to confirm): "
120
119
 
121
- if(gets.strip != 'y')
122
- puts "skipped."
120
+ if (gets.strip != 'y')
121
+ puts 'skipped.'
123
122
  return
124
123
  end
125
124
  end
@@ -169,4 +168,3 @@ end
169
168
 
170
169
  killer = Lhm::KillQueue.new
171
170
  killer.run
172
-
@@ -3,17 +3,18 @@
3
3
  set -e
4
4
  set -u
5
5
 
6
- source ~/.lhm
6
+ source `dirname $0`/lhm-config.sh
7
7
 
8
8
  lhmkill() {
9
9
  echo killing lhm-cluster
10
10
  ps -ef | sed -n "/[m]ysqld.*lhm-cluster/p" | awk '{ print $2 }' | xargs kill
11
+ echo running homebrew mysql instance
12
+ launchctl load -w ~/Library/LaunchAgents/homebrew.mxcl.mysql.plist
11
13
  sleep 2
12
14
  }
13
15
 
14
- echo stopping other running mysql instance
15
- launchctl remove com.mysql.mysqld || { echo launchctl did not remove mysqld; }
16
- "$mysqldir"/bin/mysqladmin shutdown || { echo mysqladmin did not shut down anything; }
16
+ echo stopping homebrew running mysql instance
17
+ ls -lrt -d -1 ~/Library/LaunchAgents/* | grep 'mysql.plist' | xargs launchctl unload -w
17
18
 
18
19
  lhmkill
19
20
 
@@ -1,6 +1,6 @@
1
1
  #!/bin/sh
2
2
 
3
- source ~/.lhm
3
+ source `dirname $0`/lhm-config.sh
4
4
 
5
5
  master() { "$mysqldir"/bin/mysql --protocol=TCP -P $master_port -uroot; }
6
6
  slave() { "$mysqldir"/bin/mysql --protocol=TCP -P $slave_port -uroot; }
@@ -12,7 +12,7 @@ echo "grant replication slave on *.* to 'slave'@'localhost'" | master
12
12
 
13
13
  # set up slave
14
14
 
15
- echo "change master to master_user = 'slave', master_password = 'slave', master_port = 3306, master_host = 'localhost'" | slave
15
+ echo "change master to master_user = 'slave', master_password = 'slave', master_port = $master_port, master_host = 'localhost'" | slave
16
16
  echo "start slave" | slave
17
17
  echo "show slave status \G" | slave
18
18
 
@@ -7,13 +7,12 @@
7
7
  set -e
8
8
  set -u
9
9
 
10
- source ~/.lhm
10
+ source `dirname $0`/lhm-config.sh
11
11
 
12
12
  #
13
13
  # Main
14
14
  #
15
15
 
16
- install_bin="$(echo ./*/mysql_install_db)"
17
16
 
18
17
  mkdir -p "$basedir/master/data" "$basedir/slave/data"
19
18
 
@@ -61,7 +60,7 @@ CNF
61
60
 
62
61
  (
63
62
  cd "$mysqldir"
63
+ install_bin="$(echo ./*/mysql_install_db | tr " " "\\n" | head -1)"
64
64
  $install_bin --datadir="$basedir/master/data"
65
65
  $install_bin --datadir="$basedir/slave/data"
66
-
67
66
  )
@@ -1,5 +1,6 @@
1
- source :rubygems
1
+ source "https://rubygems.org"
2
2
 
3
3
  gem "mysql", "~> 2.8.1"
4
4
  gem "activerecord", "~> 2.3.14"
5
+ gem "iconv", "~> 1.0.4"
5
6
  gemspec :path=>"../"
@@ -1,4 +1,4 @@
1
- source :rubygems
1
+ source "https://rubygems.org"
2
2
 
3
3
  gem "mysql", "~> 2.8.1"
4
4
  gem "activerecord", "~> 3.2.2"
@@ -1,4 +1,4 @@
1
- source :rubygems
1
+ source "https://rubygems.org"
2
2
 
3
3
  gem "mysql2", "~> 0.3.11"
4
4
  gem "activerecord", "~> 3.2.2"
@@ -1,4 +1,4 @@
1
- source :rubygems
1
+ source "https://rubygems.org"
2
2
 
3
3
  gem 'dm-core'
4
4
  gem 'dm-mysql-adapter'
data/lhm.gemspec CHANGED
@@ -6,20 +6,19 @@ $:.unshift(lib) unless $:.include?(lib)
6
6
  require 'lhm/version'
7
7
 
8
8
  Gem::Specification.new do |s|
9
- s.name = "lhm"
9
+ s.name = 'lhm'
10
10
  s.version = Lhm::VERSION
11
11
  s.platform = Gem::Platform::RUBY
12
- s.authors = ["SoundCloud", "Rany Keddo", "Tobias Bielohlawek", "Tobias Schmidt"]
12
+ s.authors = ['SoundCloud', 'Rany Keddo', 'Tobias Bielohlawek', 'Tobias Schmidt']
13
13
  s.email = %q{rany@soundcloud.com, tobi@soundcloud.com, ts@soundcloud.com}
14
14
  s.summary = %q{online schema changer for mysql}
15
15
  s.description = %q{Migrate large tables without downtime by copying to a temporary table in chunks. The old table is not dropped. Instead, it is moved to timestamp_table_name for verification.}
16
- s.homepage = %q{http://github.com/soundcloud/large-hadron-migrator}
16
+ s.homepage = %q{http://github.com/soundcloud/lhm}
17
17
  s.files = `git ls-files`.split("\n")
18
18
  s.test_files = `git ls-files -- {test,spec,features}/*`.split("\n")
19
- s.require_paths = ["lib"]
20
- s.executables = ["lhm-kill-queue"]
19
+ s.require_paths = ['lib']
20
+ s.executables = ['lhm-kill-queue']
21
21
 
22
- s.add_development_dependency "minitest", "= 2.10.0"
23
- s.add_development_dependency "rake"
22
+ s.add_development_dependency 'minitest', '~> 5.0.8'
23
+ s.add_development_dependency 'rake'
24
24
  end
25
-