lhm 1.0.0.rc4 → 1.0.0.rc5
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.
- data/CHANGELOG.md +3 -0
- data/bin/lhm-kill-queue +153 -0
- data/bin/lhm-spec-clobber +10 -0
- data/{spec/config/clobber → bin/lhm-spec-clobber.sh} +3 -3
- data/bin/lhm-spec-grants +10 -0
- data/{spec/config/grants → bin/lhm-spec-grants.sh} +1 -1
- data/bin/lhm-spec-setup-cluster +10 -0
- data/{spec/config/setup-cluster → bin/lhm-spec-setup-cluster.sh} +5 -3
- data/lhm.gemspec +6 -1
- data/lib/lhm/version.rb +1 -1
- data/spec/{config/.config → .lhm.example} +0 -0
- data/spec/README.md +33 -8
- metadata +16 -13
data/CHANGELOG.md
CHANGED
data/bin/lhm-kill-queue
ADDED
|
@@ -0,0 +1,153 @@
|
|
|
1
|
+
#!/usr/bin/env ruby
|
|
2
|
+
|
|
3
|
+
require 'active_record'
|
|
4
|
+
require 'optparse'
|
|
5
|
+
|
|
6
|
+
module Lhm
|
|
7
|
+
class KillQueue
|
|
8
|
+
|
|
9
|
+
def initialize
|
|
10
|
+
@port = 3306
|
|
11
|
+
|
|
12
|
+
OptionParser.new do |opts|
|
|
13
|
+
opts.on("-h", "--hostname HOSTNAME") { |v| @hostname = v }
|
|
14
|
+
opts.on("-u", "--username USERNAME") { |v| @username = v }
|
|
15
|
+
opts.on("-p", "--password PASSWORD") { |v| @password = v }
|
|
16
|
+
opts.on("-d", "--database DATABASE") { |v| @database = v }
|
|
17
|
+
opts.on("-m", "--mode MODE") { |v| @mode = v.to_sym }
|
|
18
|
+
end.parse!
|
|
19
|
+
|
|
20
|
+
unless(@hostname && @username && @password && @database)
|
|
21
|
+
abort usage
|
|
22
|
+
end
|
|
23
|
+
|
|
24
|
+
unless([:kill, :master, :slave].include?(@mode))
|
|
25
|
+
abort "specify -m kill OR -m master OR -m slave"
|
|
26
|
+
end
|
|
27
|
+
|
|
28
|
+
connect
|
|
29
|
+
end
|
|
30
|
+
|
|
31
|
+
def usage
|
|
32
|
+
<<-desc.gsub(/^ /, '')
|
|
33
|
+
kills queries on the given server after detecting 'lock table% -- lhm'.
|
|
34
|
+
usage:
|
|
35
|
+
lhm-kill-queue -h hostname -u username -p password -d database \\
|
|
36
|
+
(--kill | --master | --slave)
|
|
37
|
+
|
|
38
|
+
desc
|
|
39
|
+
end
|
|
40
|
+
|
|
41
|
+
def run
|
|
42
|
+
case @mode
|
|
43
|
+
when :kill then kill
|
|
44
|
+
when :master then master
|
|
45
|
+
when :slave then slave
|
|
46
|
+
end
|
|
47
|
+
end
|
|
48
|
+
|
|
49
|
+
def kill
|
|
50
|
+
lock = trip
|
|
51
|
+
puts "killing lock process #{ lock }."
|
|
52
|
+
kill_process(lock)
|
|
53
|
+
end
|
|
54
|
+
|
|
55
|
+
def master
|
|
56
|
+
lock = trip
|
|
57
|
+
puts "starting to kill non lhm processes in 1 second"
|
|
58
|
+
sleep(1)
|
|
59
|
+
|
|
60
|
+
[list_non_lhm].flatten.each do |process|
|
|
61
|
+
puts "killing #{ select_statement(process) }"
|
|
62
|
+
kill_process(process)
|
|
63
|
+
sleep(0.05)
|
|
64
|
+
end
|
|
65
|
+
end
|
|
66
|
+
|
|
67
|
+
def slave
|
|
68
|
+
lock = trip
|
|
69
|
+
puts "starting to kill non lhm SELECT processes in 1 second"
|
|
70
|
+
sleep(1)
|
|
71
|
+
|
|
72
|
+
[list_non_lhm].flatten.each do |process|
|
|
73
|
+
if(select?(process))
|
|
74
|
+
puts "killing #{ select_statement(process) }"
|
|
75
|
+
kill_process(process)
|
|
76
|
+
sleep(0.05)
|
|
77
|
+
end
|
|
78
|
+
end
|
|
79
|
+
end
|
|
80
|
+
|
|
81
|
+
private
|
|
82
|
+
|
|
83
|
+
def connect
|
|
84
|
+
ActiveRecord::Base.establish_connection({
|
|
85
|
+
:adapter => 'mysql',
|
|
86
|
+
:host => @hostname,
|
|
87
|
+
:port => @port,
|
|
88
|
+
:username => @username,
|
|
89
|
+
:password => @password,
|
|
90
|
+
:database => @database
|
|
91
|
+
})
|
|
92
|
+
end
|
|
93
|
+
|
|
94
|
+
def connection
|
|
95
|
+
ActiveRecord::Base.connection
|
|
96
|
+
end
|
|
97
|
+
|
|
98
|
+
def list_non_lhm
|
|
99
|
+
select_process("info not like '% -- lhm' and time > 0 and command = 'Query'")
|
|
100
|
+
end
|
|
101
|
+
|
|
102
|
+
def trip
|
|
103
|
+
until res = select_process("info like 'lock table% -- lhm'")
|
|
104
|
+
sleep 0.2
|
|
105
|
+
print '.'
|
|
106
|
+
end
|
|
107
|
+
|
|
108
|
+
res
|
|
109
|
+
end
|
|
110
|
+
|
|
111
|
+
def kill_process(process_id)
|
|
112
|
+
connection.execute("kill #{ process_id }")
|
|
113
|
+
end
|
|
114
|
+
|
|
115
|
+
def select?(process)
|
|
116
|
+
if statement = select_statement(process)
|
|
117
|
+
|
|
118
|
+
case statement
|
|
119
|
+
when /delete/i then false
|
|
120
|
+
when /update/i then false
|
|
121
|
+
when /insert/i then false
|
|
122
|
+
else
|
|
123
|
+
!!statement.match(/select/i)
|
|
124
|
+
end
|
|
125
|
+
end
|
|
126
|
+
end
|
|
127
|
+
|
|
128
|
+
def select_statement(process)
|
|
129
|
+
if process
|
|
130
|
+
value %Q(
|
|
131
|
+
select info from information_schema.processlist where id = #{ process }
|
|
132
|
+
)
|
|
133
|
+
end
|
|
134
|
+
end
|
|
135
|
+
|
|
136
|
+
def select_process(predicate)
|
|
137
|
+
value %Q(
|
|
138
|
+
select id from information_schema.processlist
|
|
139
|
+
where db = '#{ @database }'
|
|
140
|
+
and user = '#{ @username }'
|
|
141
|
+
and #{ predicate }
|
|
142
|
+
)
|
|
143
|
+
end
|
|
144
|
+
|
|
145
|
+
def value(statement)
|
|
146
|
+
connection.select_value(statement)
|
|
147
|
+
end
|
|
148
|
+
end
|
|
149
|
+
end
|
|
150
|
+
|
|
151
|
+
killer = Lhm::KillQueue.new
|
|
152
|
+
killer.run
|
|
153
|
+
.
|
|
@@ -3,7 +3,7 @@
|
|
|
3
3
|
set -e
|
|
4
4
|
set -u
|
|
5
5
|
|
|
6
|
-
source
|
|
6
|
+
source ~/.lhm
|
|
7
7
|
|
|
8
8
|
lhmkill() {
|
|
9
9
|
ps -ef | gsed -n "/[m]ysqld.*lhm-cluster/p" | awk '{ print $2 }' | xargs kill
|
|
@@ -21,7 +21,7 @@ echo removing $basedir
|
|
|
21
21
|
rm -rf "$basedir"
|
|
22
22
|
|
|
23
23
|
echo setting up cluster
|
|
24
|
-
spec
|
|
24
|
+
lhm-spec-setup-cluster
|
|
25
25
|
|
|
26
26
|
echo staring instances
|
|
27
27
|
"$mysqldir"/bin/mysqld --defaults-file="$basedir/master/my.cnf" 2>&1 >$basedir/master/lhm.log &
|
|
@@ -29,7 +29,7 @@ echo staring instances
|
|
|
29
29
|
sleep 5
|
|
30
30
|
|
|
31
31
|
echo running grants
|
|
32
|
-
spec
|
|
32
|
+
lhm-spec-grants
|
|
33
33
|
|
|
34
34
|
trap lhmkill SIGTERM SIGINT
|
|
35
35
|
|
data/bin/lhm-spec-grants
ADDED
|
@@ -7,12 +7,14 @@
|
|
|
7
7
|
set -e
|
|
8
8
|
set -u
|
|
9
9
|
|
|
10
|
-
source
|
|
10
|
+
source ~/.lhm
|
|
11
11
|
|
|
12
12
|
#
|
|
13
13
|
# Main
|
|
14
14
|
#
|
|
15
15
|
|
|
16
|
+
install_bin="$(echo ./*/mysql_install_db)"
|
|
17
|
+
|
|
16
18
|
mkdir -p "$basedir/master/data" "$basedir/slave/data"
|
|
17
19
|
|
|
18
20
|
cat <<-CNF > $basedir/master/my.cnf
|
|
@@ -59,7 +61,7 @@ CNF
|
|
|
59
61
|
|
|
60
62
|
(
|
|
61
63
|
cd "$mysqldir"
|
|
62
|
-
|
|
63
|
-
|
|
64
|
+
$install_bin --datadir="$basedir/master/data"
|
|
65
|
+
$install_bin --datadir="$basedir/slave/data"
|
|
64
66
|
|
|
65
67
|
)
|
data/lhm.gemspec
CHANGED
|
@@ -16,8 +16,13 @@ Gem::Specification.new do |s|
|
|
|
16
16
|
s.homepage = %q{http://github.com/soundcloud/large-hadron-migrator}
|
|
17
17
|
s.files = `git ls-files`.split("\n")
|
|
18
18
|
s.test_files = `git ls-files -- {test,spec,features}/*`.split("\n")
|
|
19
|
-
s.executables = `git ls-files -- bin/*`.split("\n").map{ |f| File.basename(f) }
|
|
20
19
|
s.require_paths = ["lib"]
|
|
20
|
+
s.executables = [
|
|
21
|
+
"lhm-spec-clobber",
|
|
22
|
+
"lhm-spec-grants",
|
|
23
|
+
"lhm-spec-setup-cluster",
|
|
24
|
+
"lhm-kill-queue"
|
|
25
|
+
]
|
|
21
26
|
|
|
22
27
|
# this should be a real dependency, but we're using a different gem in our code
|
|
23
28
|
s.add_development_dependency "mysql", "~> 2.8.1"
|
data/lib/lhm/version.rb
CHANGED
|
File without changes
|
data/spec/README.md
CHANGED
|
@@ -1,26 +1,51 @@
|
|
|
1
1
|
Preparing for master slave integration tests
|
|
2
2
|
--------------------------------------------
|
|
3
3
|
|
|
4
|
+
# configuration
|
|
5
|
+
|
|
6
|
+
create ~/.lhm:
|
|
7
|
+
|
|
8
|
+
mysqldir=/usr/local/mysql
|
|
9
|
+
basedir=/opt/lhm-cluster
|
|
10
|
+
master_port=3306
|
|
11
|
+
slave_port=3307
|
|
12
|
+
|
|
13
|
+
mysqldir specifies the location of your mysql install. basedir is the
|
|
14
|
+
directory master and slave databases will get installed into.
|
|
15
|
+
|
|
16
|
+
# setup
|
|
17
|
+
|
|
4
18
|
You can set the integration specs up to run against a master slave setup by
|
|
5
|
-
running the included `
|
|
19
|
+
running the included `lhm-spec-clobber` script. this deletes the configured
|
|
20
|
+
lhm master slave setup and reinstalls and configures a master slave setup.
|
|
6
21
|
|
|
7
|
-
|
|
22
|
+
Follow the manual instructions if you want more control over this process.
|
|
8
23
|
|
|
9
|
-
|
|
24
|
+
# manual setup
|
|
10
25
|
|
|
11
|
-
|
|
26
|
+
## set up instances
|
|
12
27
|
|
|
13
|
-
|
|
28
|
+
lhm-spec-setup-cluster
|
|
29
|
+
|
|
30
|
+
## start instances
|
|
31
|
+
|
|
32
|
+
basedir=/opt/lhm-luster
|
|
14
33
|
mysqld --defaults-file="$basedir/master/my.cnf"
|
|
15
34
|
mysqld --defaults-file="$basedir/slave/my.cnf"
|
|
16
35
|
|
|
17
|
-
|
|
36
|
+
## run the grants
|
|
18
37
|
|
|
19
|
-
spec
|
|
38
|
+
lhm-spec-grants
|
|
20
39
|
|
|
21
|
-
|
|
40
|
+
## run specs
|
|
22
41
|
|
|
23
42
|
To run specs in slave mode, set the SLAVE=1 when running tests:
|
|
24
43
|
|
|
25
44
|
MASTER_SLAVE=1 rake specs
|
|
26
45
|
|
|
46
|
+
# connecting
|
|
47
|
+
|
|
48
|
+
you can connect by running (with the respective ports):
|
|
49
|
+
|
|
50
|
+
mysql --protocol=TCP -p3307
|
|
51
|
+
|
metadata
CHANGED
|
@@ -6,8 +6,8 @@ version: !ruby/object:Gem::Version
|
|
|
6
6
|
- 1
|
|
7
7
|
- 0
|
|
8
8
|
- 0
|
|
9
|
-
-
|
|
10
|
-
version: 1.0.0.
|
|
9
|
+
- rc5
|
|
10
|
+
version: 1.0.0.rc5
|
|
11
11
|
platform: ruby
|
|
12
12
|
authors:
|
|
13
13
|
- SoundCloud
|
|
@@ -18,7 +18,7 @@ autorequire:
|
|
|
18
18
|
bindir: bin
|
|
19
19
|
cert_chain: []
|
|
20
20
|
|
|
21
|
-
date: 2012-01-
|
|
21
|
+
date: 2012-01-31 00:00:00 +01:00
|
|
22
22
|
default_executable:
|
|
23
23
|
dependencies:
|
|
24
24
|
- !ruby/object:Gem::Dependency
|
|
@@ -79,8 +79,11 @@ dependencies:
|
|
|
79
79
|
version_requirements: *id004
|
|
80
80
|
description: 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.
|
|
81
81
|
email: rany@soundcloud.com, tobi@soundcloud.com, ts@soundcloud.com
|
|
82
|
-
executables:
|
|
83
|
-
|
|
82
|
+
executables:
|
|
83
|
+
- lhm-spec-clobber
|
|
84
|
+
- lhm-spec-grants
|
|
85
|
+
- lhm-spec-setup-cluster
|
|
86
|
+
- lhm-kill-queue
|
|
84
87
|
extensions: []
|
|
85
88
|
|
|
86
89
|
extra_rdoc_files: []
|
|
@@ -92,6 +95,13 @@ files:
|
|
|
92
95
|
- LICENSE
|
|
93
96
|
- README.md
|
|
94
97
|
- Rakefile
|
|
98
|
+
- bin/lhm-kill-queue
|
|
99
|
+
- bin/lhm-spec-clobber
|
|
100
|
+
- bin/lhm-spec-clobber.sh
|
|
101
|
+
- bin/lhm-spec-grants
|
|
102
|
+
- bin/lhm-spec-grants.sh
|
|
103
|
+
- bin/lhm-spec-setup-cluster
|
|
104
|
+
- bin/lhm-spec-setup-cluster.sh
|
|
95
105
|
- gemfiles/ar-2.3.gemfile
|
|
96
106
|
- gemfiles/ar-3.1.gemfile
|
|
97
107
|
- lhm.gemspec
|
|
@@ -107,12 +117,9 @@ files:
|
|
|
107
117
|
- lib/lhm/sql_helper.rb
|
|
108
118
|
- lib/lhm/table.rb
|
|
109
119
|
- lib/lhm/version.rb
|
|
120
|
+
- spec/.lhm.example
|
|
110
121
|
- spec/README.md
|
|
111
122
|
- spec/bootstrap.rb
|
|
112
|
-
- spec/config/.config
|
|
113
|
-
- spec/config/clobber
|
|
114
|
-
- spec/config/grants
|
|
115
|
-
- spec/config/setup-cluster
|
|
116
123
|
- spec/fixtures/destination.ddl
|
|
117
124
|
- spec/fixtures/origin.ddl
|
|
118
125
|
- spec/fixtures/users.ddl
|
|
@@ -167,10 +174,6 @@ summary: online schema changer for mysql
|
|
|
167
174
|
test_files:
|
|
168
175
|
- spec/README.md
|
|
169
176
|
- spec/bootstrap.rb
|
|
170
|
-
- spec/config/.config
|
|
171
|
-
- spec/config/clobber
|
|
172
|
-
- spec/config/grants
|
|
173
|
-
- spec/config/setup-cluster
|
|
174
177
|
- spec/fixtures/destination.ddl
|
|
175
178
|
- spec/fixtures/origin.ddl
|
|
176
179
|
- spec/fixtures/users.ddl
|