ar_mysql_flexmaster 0.2.2 → 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.
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.
|
15
|
+
gem.version = "0.3.0"
|
16
16
|
|
17
17
|
gem.add_runtime_dependency("mysql2")
|
18
18
|
gem.add_runtime_dependency("activerecord")
|
data/bin/master_cut
CHANGED
@@ -88,7 +88,7 @@ def preflight_check
|
|
88
88
|
fail("slave is delayed") if slave_info['Seconds_Behind_Master'].nil? || slave_info['Seconds_Behind_Master'] > 0
|
89
89
|
|
90
90
|
masters_slave_info = cx.query("show slave status").first
|
91
|
-
if $rehome_master && masters_slave_info.nil? || masters_slave_info['Master_User'] == 'test'
|
91
|
+
if $rehome_master && (masters_slave_info.nil? || masters_slave_info['Master_User'] == 'test')
|
92
92
|
fail("I can't rehome the original master -- it has no slave user or password.")
|
93
93
|
end
|
94
94
|
|
@@ -47,25 +47,34 @@ module ActiveRecord
|
|
47
47
|
|
48
48
|
def begin_db_transaction
|
49
49
|
if !cx_correct? && open_transactions == 0
|
50
|
-
refind_correct_host
|
50
|
+
refind_correct_host!
|
51
51
|
end
|
52
52
|
super
|
53
53
|
end
|
54
54
|
|
55
55
|
def execute(sql, name = nil)
|
56
56
|
if open_transactions == 0 && sql =~ /^(INSERT|UPDATE|DELETE|ALTER|CHANGE)/ && !cx_correct?
|
57
|
-
refind_correct_host
|
57
|
+
refind_correct_host!
|
58
58
|
else
|
59
59
|
@select_counter += 1
|
60
60
|
if (@select_counter % CHECK_EVERY_N_SELECTS == 0) && !cx_correct?
|
61
61
|
# on select statements, check every 10 times to see if we need to switch masters,
|
62
|
-
# but don't
|
63
|
-
|
62
|
+
# but don't sleep, and if existing connection isn't correct, go ahead anyway.
|
63
|
+
cx = find_correct_host
|
64
|
+
@connection = cx if cx
|
64
65
|
end
|
65
66
|
end
|
66
67
|
super
|
67
68
|
end
|
68
69
|
|
70
|
+
def current_host
|
71
|
+
@connection.query_options[:host]
|
72
|
+
end
|
73
|
+
|
74
|
+
def current_port
|
75
|
+
@connection.query_options[:port]
|
76
|
+
end
|
77
|
+
|
69
78
|
private
|
70
79
|
|
71
80
|
def connect
|
@@ -90,11 +99,12 @@ module ActiveRecord
|
|
90
99
|
collected_errors.map { |e| "#{e.class.name}: #{e.message}" }.uniq.join(",")
|
91
100
|
end
|
92
101
|
|
93
|
-
def refind_correct_host
|
102
|
+
def refind_correct_host!
|
94
103
|
clear_collected_errors!
|
95
104
|
|
96
|
-
|
97
|
-
|
105
|
+
sleep_interval = 0.1
|
106
|
+
tries = @tx_hold_timeout.to_f / sleep_interval
|
107
|
+
|
98
108
|
tries.to_i.times do
|
99
109
|
cx = find_correct_host
|
100
110
|
if cx
|
@@ -128,7 +138,6 @@ module ActiveRecord
|
|
128
138
|
chosen_cx = correct_cxs.first
|
129
139
|
else
|
130
140
|
# nothing read-write, or too many read-write
|
131
|
-
# (should we manually close the connections?)
|
132
141
|
if correct_cxs.size > 1
|
133
142
|
collected_errors << TooManyMastersException.new("found #{correct_cxs.size} read-write servers")
|
134
143
|
else
|
data/test/ar_flexmaster_test.rb
CHANGED
@@ -121,6 +121,18 @@ class TestArFlexmaster < Test::Unit::TestCase
|
|
121
121
|
assert !main_connection_is_original_master?
|
122
122
|
end
|
123
123
|
|
124
|
+
# there's a small window in which the old master is read-only but the new slave hasn't come online yet.
|
125
|
+
# Allow side-effect free statements to continue.
|
126
|
+
def test_should_not_crash_selects_in_the_double_read_only_window
|
127
|
+
ActiveRecord::Base.connection
|
128
|
+
$mysql_master.set_rw(false)
|
129
|
+
$mysql_slave.set_rw(false)
|
130
|
+
assert main_connection_is_original_master?
|
131
|
+
100.times do
|
132
|
+
u = User.first
|
133
|
+
end
|
134
|
+
end
|
135
|
+
|
124
136
|
def test_should_choose_a_random_slave_connection
|
125
137
|
h = {}
|
126
138
|
10.times do
|
@@ -131,6 +143,12 @@ class TestArFlexmaster < Test::Unit::TestCase
|
|
131
143
|
assert_equal 2, h.size
|
132
144
|
end
|
133
145
|
|
146
|
+
def test_should_expose_the_current_master_and_port
|
147
|
+
cx = ActiveRecord::Base.connection
|
148
|
+
assert_equal "127.0.0.1", cx.current_host
|
149
|
+
assert_equal $mysql_master.port, cx.current_port
|
150
|
+
end
|
151
|
+
|
134
152
|
def test_should_flip_the_slave_after_it_becomes_master
|
135
153
|
UserSlave.first
|
136
154
|
User.create!
|
data/test/boot_mysql_env.rb
CHANGED
@@ -38,3 +38,5 @@ $mysql_master.connection.query("CREATE DATABASE flexmaster_test")
|
|
38
38
|
$mysql_master.connection.query("CREATE TABLE flexmaster_test.users (id INT(10) NOT NULL AUTO_INCREMENT PRIMARY KEY, name varchar(20))")
|
39
39
|
$mysql_master.connection.query("INSERT INTO flexmaster_test.users set name='foo'")
|
40
40
|
|
41
|
+
$mysql_slave.set_rw(false)
|
42
|
+
sleep if __FILE__ == $0
|
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.
|
4
|
+
version: 0.3.0
|
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-28 00:00:00.000000000 Z
|
13
13
|
dependencies:
|
14
14
|
- !ruby/object:Gem::Dependency
|
15
15
|
name: mysql2
|