ar_mysql_flexmaster 0.0.6 → 0.0.8
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/README.md
CHANGED
@@ -1,6 +1,8 @@
|
|
1
1
|
# ArMysqlFlexmaster
|
2
2
|
|
3
|
-
|
3
|
+
Mysql Flexmaster is an adapter for ActiveRecord that allows an application node to choose
|
4
|
+
among a list of potential masters at runtime. It trades some properties of a more traditional
|
5
|
+
HA solution (load balancing, middleware) for simplicity of operation.
|
4
6
|
|
5
7
|
## Installation
|
6
8
|
|
@@ -16,9 +18,85 @@ Or install it yourself as:
|
|
16
18
|
|
17
19
|
$ gem install ar_mysql_flexmaster
|
18
20
|
|
19
|
-
##
|
21
|
+
## Configuration:
|
20
22
|
|
21
|
-
|
23
|
+
database.yml contains a list of hosts -- all of them potential masters, all of them potential replicas.
|
24
|
+
It should look like this:
|
25
|
+
|
26
|
+
```
|
27
|
+
production:
|
28
|
+
adapter: mysql_flexmaster
|
29
|
+
username: flex
|
30
|
+
hosts: ["db01:3306", "db02:3306"]
|
31
|
+
|
32
|
+
production_slave:
|
33
|
+
adapter: mysql_flexmaster
|
34
|
+
username: flex
|
35
|
+
slave: true
|
36
|
+
hosts: ["db01:3306", "db02:3306"]
|
37
|
+
```
|
38
|
+
|
39
|
+
|
40
|
+
## How it works
|
41
|
+
|
42
|
+
### Overview
|
43
|
+
|
44
|
+
The mysql "READ_ONLY" flag is used to indicate a current master amongst the cluster. Only one member
|
45
|
+
of the replication chain may be read-write at any given time. The application picks in run time, based
|
46
|
+
on the read_only flag, which host is correct.
|
47
|
+
|
48
|
+
### boot time
|
49
|
+
|
50
|
+
Your activerecord application will pick a correct mysql host for the given configuration by probing hosts until
|
51
|
+
it finds the correct host.
|
52
|
+
|
53
|
+
For master configurations (slave: true is not specified):
|
54
|
+
|
55
|
+
The application will probe each host in turn, and find the mysql candidate among these nodes
|
56
|
+
that is read-write (SET GLOBAL READ_ONLY=0). If it finds more than one node where READ_ONLY == 0, it will
|
57
|
+
abort.
|
58
|
+
|
59
|
+
For slave configurations (slave: true specified):
|
60
|
+
|
61
|
+
The application will choose a replica at random from amongst those where READ_ONLY == 1.
|
62
|
+
|
63
|
+
### run time
|
64
|
+
|
65
|
+
Before each transaction is begun on the master, the application checks the status of the READ_ONLY variable.
|
66
|
+
If READ_ONLY == 0, it will proceed with the transaction as normal. If READ_ONLY == 1, it will drop the current
|
67
|
+
connection and re-poll the cluster for the current master, sleeping up to a default of 5 seconds to wait for
|
68
|
+
the new master to be promoted. When it finds the new master, it will begin the transaction there.
|
69
|
+
|
70
|
+
### promoting a new master
|
71
|
+
|
72
|
+
*The bin/master_cut script in this project will perform steps 3-5 for you.*
|
73
|
+
|
74
|
+
The process of promoting a new master to head the cluster should be as follows:
|
75
|
+
|
76
|
+
1. identify a new candidate master
|
77
|
+
1. ensure that all other replicas in the cluster are chained off the candidate master; you want the
|
78
|
+
chain to look like this:
|
79
|
+
|
80
|
+
```
|
81
|
+
<existing master> -> <candidate master> -> <other replicas>
|
82
|
+
-> <other replicas>
|
83
|
+
|
84
|
+
```
|
85
|
+
|
86
|
+
1. set the old master to READ_ONLY = 1
|
87
|
+
1. record the master-bin-log position of the candidate master (if you want to re-use the old master)
|
88
|
+
1. set the new master to READ_ONLY = 0
|
89
|
+
|
90
|
+
The application will eventually shift slave traffic to another node in the cluster, if available, and
|
91
|
+
will drop their connection to the old master whenever a transaction is attempted, or after a certain
|
92
|
+
number of queries.
|
93
|
+
|
94
|
+
|
95
|
+
### caveats, gotchas
|
96
|
+
|
97
|
+
- Any explicit ( BEGIN ... END ) transaction that are in-flight when the old master goes READ_ONLY
|
98
|
+
will crash. In theory there's a workaround for this problem, in pratice it's rather unwieldy due
|
99
|
+
to a lack of shared global variables in mysql.
|
22
100
|
|
23
101
|
## Contributing
|
24
102
|
|
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.0.
|
15
|
+
gem.version = "0.0.8"
|
16
16
|
|
17
17
|
gem.add_runtime_dependency("mysql2")
|
18
18
|
gem.add_runtime_dependency("activerecord")
|
data/lib/ar_mysql_flexmaster.rb
CHANGED
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.0.
|
4
|
+
version: 0.0.8
|
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-
|
12
|
+
date: 2013-02-06 00:00:00.000000000 Z
|
13
13
|
dependencies:
|
14
14
|
- !ruby/object:Gem::Dependency
|
15
15
|
name: mysql2
|
@@ -137,7 +137,7 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
137
137
|
version: '0'
|
138
138
|
segments:
|
139
139
|
- 0
|
140
|
-
hash:
|
140
|
+
hash: 1068549902361046667
|
141
141
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
142
142
|
none: false
|
143
143
|
requirements:
|
@@ -146,7 +146,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
146
146
|
version: '0'
|
147
147
|
segments:
|
148
148
|
- 0
|
149
|
-
hash:
|
149
|
+
hash: 1068549902361046667
|
150
150
|
requirements: []
|
151
151
|
rubyforge_project:
|
152
152
|
rubygems_version: 1.8.24
|