ar_mysql_flexmaster 0.2.0 → 0.2.1
Sign up to get free protection for your applications and to get access to all the features.
- data/ar_mysql_flexmaster.gemspec +1 -1
- data/bin/master_cut +17 -7
- data/test/integration/there_and_back_again_test.rb +8 -1
- data/test/mysql_isolated_server.rb +12 -4
- metadata +4 -4
data/ar_mysql_flexmaster.gemspec
CHANGED
@@ -12,7 +12,7 @@ Gem::Specification.new do |gem|
|
|
12
12
|
gem.test_files = gem.files.grep(%r{^(test|spec|features)/})
|
13
13
|
gem.name = "ar_mysql_flexmaster"
|
14
14
|
gem.require_paths = ["lib"]
|
15
|
-
gem.version = "0.2.
|
15
|
+
gem.version = "0.2.1"
|
16
16
|
|
17
17
|
gem.add_runtime_dependency("mysql2")
|
18
18
|
gem.add_runtime_dependency("activerecord")
|
data/bin/master_cut
CHANGED
@@ -11,6 +11,7 @@ Thread.abort_on_exception = false
|
|
11
11
|
opts = GetoptLong.new(
|
12
12
|
["--password", "-p", GetoptLong::REQUIRED_ARGUMENT],
|
13
13
|
["--rehome-master", "-r", GetoptLong::NO_ARGUMENT],
|
14
|
+
["--start-slave", "-s", GetoptLong::NO_ARGUMENT],
|
14
15
|
)
|
15
16
|
|
16
17
|
opts.each do |opt, arg|
|
@@ -19,17 +20,26 @@ opts.each do |opt, arg|
|
|
19
20
|
$password = arg
|
20
21
|
when '--rehome-master'
|
21
22
|
$rehome_master = true
|
23
|
+
when '--start-slave'
|
24
|
+
$start_slave = true
|
25
|
+
$rehome_master = true
|
22
26
|
end
|
23
27
|
end
|
24
28
|
|
25
|
-
|
26
|
-
unless $old_master && $new_master && $username
|
29
|
+
def usage
|
27
30
|
puts "Usage: master_cut OLD_MASTER NEW_MASTER ADMIN_USERNAME"
|
28
31
|
puts " [-p,--password PASSWORD]"
|
29
|
-
puts " [-r,--
|
30
|
-
|
32
|
+
puts " [-r,--rehome-master]"
|
33
|
+
puts " [-s,--start-slave]"
|
34
|
+
exit false
|
31
35
|
end
|
32
36
|
|
37
|
+
$old_master, $new_master, $username = *ARGV
|
38
|
+
unless $old_master && $new_master && $username
|
39
|
+
usage
|
40
|
+
end
|
41
|
+
|
42
|
+
|
33
43
|
def open_cx(host)
|
34
44
|
host, port = host.split(":")
|
35
45
|
port = port.to_i if port
|
@@ -123,19 +133,19 @@ def swap_thread
|
|
123
133
|
puts "New master information at time of swap: "
|
124
134
|
pp new_master_info
|
125
135
|
if $rehome_master
|
126
|
-
rehome_master(new_master_info)
|
136
|
+
rehome_master(new_master_info, $start_slave)
|
127
137
|
end
|
128
138
|
exit
|
129
139
|
end
|
130
140
|
end
|
131
141
|
|
132
|
-
def rehome_master(info)
|
142
|
+
def rehome_master(info, start_slave)
|
133
143
|
puts "Reconfiguring #{$old_master} to be a slave of #{$new_master}..."
|
134
144
|
host, port = $new_master.split(":")
|
135
145
|
port_clause = port ? "master_port = #{port}," : ""
|
136
146
|
cx = open_cx($old_master)
|
137
147
|
cx.query("change master to master_host='#{host}', #{port_clause} master_log_file = '#{info['File']}', master_log_pos=#{info['Position']}")
|
138
|
-
cx.query("slave start")
|
148
|
+
cx.query("slave start") if start_slave
|
139
149
|
end
|
140
150
|
|
141
151
|
ask_for_password
|
@@ -1,5 +1,8 @@
|
|
1
1
|
require 'bundler/setup'
|
2
2
|
require 'mysql2'
|
3
|
+
require 'test/unit/assertions'
|
4
|
+
|
5
|
+
include Test::Unit::Assertions
|
3
6
|
require_relative '../boot_mysql_env'
|
4
7
|
master_cut_script = File.expand_path(File.dirname(__FILE__)) + "/../../bin/master_cut"
|
5
8
|
|
@@ -15,13 +18,17 @@ def assert_ro(cx, str, bool)
|
|
15
18
|
end
|
16
19
|
puts "testing first cutover..."
|
17
20
|
|
18
|
-
system "#{master_cut_script} 127.0.0.1:#{$mysql_master.port} 127.0.0.1:#{$mysql_slave.port} root -p '' -r"
|
21
|
+
system "#{master_cut_script} 127.0.0.1:#{$mysql_master.port} 127.0.0.1:#{$mysql_slave.port} root -p '' -r -s"
|
19
22
|
assert_ro($mysql_master.connection, 'original master', true)
|
20
23
|
assert_ro($mysql_slave.connection, 'original slave', false)
|
21
24
|
|
25
|
+
assert "Yes" == $mysql_master.connection.query("show slave status").first['Slave_IO_Running']
|
26
|
+
|
22
27
|
system "#{master_cut_script} 127.0.0.1:#{$mysql_slave.port} 127.0.0.1:#{$mysql_master.port} root -p '' -r"
|
23
28
|
assert_ro($mysql_master.connection, 'original master', false)
|
24
29
|
assert_ro($mysql_slave.connection, 'original slave', true)
|
25
30
|
|
31
|
+
assert "No" == $mysql_slave.connection.query("show slave status").first['Slave_IO_Running']
|
32
|
+
|
26
33
|
puts "everything went real nice."
|
27
34
|
|
@@ -39,6 +39,12 @@ class MysqlIsolatedServer
|
|
39
39
|
end
|
40
40
|
|
41
41
|
|
42
|
+
def locate_executable(*candidates)
|
43
|
+
output = `which #{candidates.join(' ')}`
|
44
|
+
return nil if output == "\n"
|
45
|
+
output.split("\n").first
|
46
|
+
end
|
47
|
+
|
42
48
|
def boot!
|
43
49
|
@port ||= grab_free_port
|
44
50
|
system("rm -Rf #{@mysql_data_dir}")
|
@@ -63,10 +69,12 @@ class MysqlIsolatedServer
|
|
63
69
|
sleep(0.1)
|
64
70
|
end
|
65
71
|
|
66
|
-
|
72
|
+
tzinfo_to_sql = locate_executable("mysql_tzinfo_to_sql5", "mysql_tzinfo_to_sql")
|
73
|
+
raise "could not find mysql_tzinfo_to_sql" unless tzinfo_to_sql
|
74
|
+
system("#{tzinfo_to_sql} /usr/share/zoneinfo 2>/dev/null | mysql -h127.0.0.1 --database=mysql --port=#{@port} -u root mysql ")
|
67
75
|
|
68
|
-
system(%Q(mysql --port=#{@port} --database=mysql -u root -e "SET GLOBAL time_zone='UTC'"))
|
69
|
-
system(%Q(mysql --port=#{@port} --database=mysql -u root -e "GRANT SELECT ON *.* to 'zdslave'@'localhost'"))
|
76
|
+
system(%Q(mysql -h127.0.0.1 --port=#{@port} --database=mysql -u root -e "SET GLOBAL time_zone='UTC'"))
|
77
|
+
system(%Q(mysql -h127.0.0.1 --port=#{@port} --database=mysql -u root -e "GRANT SELECT ON *.* to 'zdslave'@'localhost'"))
|
70
78
|
end
|
71
79
|
|
72
80
|
def grab_free_port
|
@@ -102,7 +110,7 @@ class MysqlIsolatedServer
|
|
102
110
|
end
|
103
111
|
at_exit {
|
104
112
|
Process.kill("TERM", pid)
|
105
|
-
|
113
|
+
system("rm -Rf #{base}")
|
106
114
|
}
|
107
115
|
@pid = pid
|
108
116
|
devnull.close
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: ar_mysql_flexmaster
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.2.
|
4
|
+
version: 0.2.1
|
5
5
|
prerelease:
|
6
6
|
platform: ruby
|
7
7
|
authors:
|
@@ -9,7 +9,7 @@ authors:
|
|
9
9
|
autorequire:
|
10
10
|
bindir: bin
|
11
11
|
cert_chain: []
|
12
|
-
date: 2013-03-
|
12
|
+
date: 2013-03-18 00:00:00.000000000 Z
|
13
13
|
dependencies:
|
14
14
|
- !ruby/object:Gem::Dependency
|
15
15
|
name: mysql2
|
@@ -142,7 +142,7 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
142
142
|
version: '0'
|
143
143
|
segments:
|
144
144
|
- 0
|
145
|
-
hash:
|
145
|
+
hash: -961261778755012131
|
146
146
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
147
147
|
none: false
|
148
148
|
requirements:
|
@@ -151,7 +151,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
151
151
|
version: '0'
|
152
152
|
segments:
|
153
153
|
- 0
|
154
|
-
hash:
|
154
|
+
hash: -961261778755012131
|
155
155
|
requirements: []
|
156
156
|
rubyforge_project:
|
157
157
|
rubygems_version: 1.8.24
|