ar_mysql_flexmaster 1.0.2 → 1.0.3

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 7128789a429103745358fcfae3ae85249b345f26
4
- data.tar.gz: e4f15822ba6c60a21c88044e23f82189f1a044d4
3
+ metadata.gz: 003ae600df9f49fa3ed61a3f24b50be9a1c1578f
4
+ data.tar.gz: 964eea239d02d3ac8984f690e73b0d9dcda4f4a8
5
5
  SHA512:
6
- metadata.gz: 131250bff67cc391ef60a8f2815c489948a639f7f4850bed10ac71893d8cfa90d76206e4b09dd39cdd5415a056a13be4daaeafa217c832cfd8875683ecf1eae0
7
- data.tar.gz: 631a3b9882f0583a71b66541f1208120139e8c119eb6446c3937a8508eb83c03a04bdd3d576272df7ca50bb564ad8046ba373987179e7595b2af7065b92de544
6
+ metadata.gz: 54d905d3643055ddd23984cb162519c7dac4f06613b63f2e0bee48e0f4b742983039f543244af8a425582b3a37fa7a65b6c163df586e802ab3ba13405e83f34e
7
+ data.tar.gz: 5d10d47653118fb716cf3af3146270e96c403eaf9041ccb1dec81dea699e481d3244eb3ef85917e4ebc6989acf3d8f13968881f382dcedaa236551c7c4ceccf5
@@ -1,26 +1,25 @@
1
1
  language: ruby
2
2
 
3
3
  rvm:
4
- - 2.0.0
5
- - 2.1.8
6
- - 2.2.4
4
+ - 2.2.6
5
+ - 2.3.3
6
+ - 2.4.1
7
7
 
8
8
  gemfile:
9
9
  - gemfiles/rails3.2.gemfile
10
- - gemfiles/rails4.0.gemfile
11
- - gemfiles/rails4.1.gemfile
12
10
  - gemfiles/rails4.2.gemfile
13
11
  - gemfiles/rails5.0.gemfile
14
12
 
15
- sudo: false
13
+ sudo: required
16
14
 
17
15
  bundler_args: --no-deployment
18
16
 
17
+ before_script:
18
+ - sudo cp /usr/share/doc/mysql-server-5.6/examples/my-default.cnf /usr/share/mysql/my-default.cnf
19
+
19
20
  script: bundle exec rake test
20
21
 
21
22
  matrix:
22
23
  exclude:
23
- - rvm: 2.0.0
24
- gemfile: gemfiles/rails5.0.gemfile
25
- - rvm: 2.1.8
26
- gemfile: gemfiles/rails5.0.gemfile
24
+ - rvm: 2.4.1
25
+ gemfile: gemfiles/rails3.2.gemfile
data/README.md CHANGED
@@ -1,19 +1,20 @@
1
- [![Build Status](https://travis-ci.org/osheroff/ar_mysql_flexmaster.svg?branch=master)](https://travis-ci.org/osheroff/ar_mysql_flexmaster)
1
+ [![Build Status](https://travis-ci.org/zendesk/ar_mysql_flexmaster.svg?branch=master)](https://travis-ci.org/zendesk/ar_mysql_flexmaster)
2
2
 
3
3
  # Flexmaster
4
4
 
5
- Flexmaster is an adapter for ActiveRecord and mysql that allows an application node to find a master
6
- among a list of potential masters at runtime. It trades some properties of a more traditional
7
- HA solution (load balancing, middleware) for simplicity of operation.
5
+ Flexmaster is an adapter for ActiveRecord and MySQL that allows an application
6
+ node to find a master among a list of potential masters at runtime. It trades
7
+ some properties of a more traditional HA solution (load balancing, middleware)
8
+ for simplicity of operation.
8
9
 
9
10
  ## Configuration:
10
11
 
11
- Your environment should be configured with 1 active master and N replicas. Each replica should have mysql's
12
- global "READ_ONLY" flag set to true (this is really best practices for your replicas anyway, but flexmaster
13
- depends on it).
12
+ Your environment should be configured with 1 active master and N replicas. Each
13
+ replica should have MySQL’s global `READ_ONLY` flag set to true (this is really
14
+ best practices for your replicas anyway, but Flexmaster depends on it).
14
15
 
15
- database.yml should contain a list of hosts -- all of them potential masters, all of them potential replicas.
16
- It should look like this:
16
+ database.yml should contain a list of hosts all of them potential masters, all
17
+ of them potential replicas. It should look like this:
17
18
 
18
19
  ```
19
20
  production:
@@ -28,79 +29,86 @@ production_slave:
28
29
  hosts: ["db01:3306", "db02:3306"]
29
30
  ```
30
31
 
31
- In this example, we've configured two diferent connections for rails to use. Note that they're identicle except for the `slave:true` key in the production_slave yaml block.
32
- Adding `slave:true` indicates to flexmaster that this connection should prefer a read-only slave wherever possible.
32
+ In this example, weve configured two different connections for Rails to use.
33
+ Note that they’re identical except for the `slave: true` key in the
34
+ `production_slave` YAML block. Adding `slave: true` indicates to Flexmaster that
35
+ this connection should prefer a read-only slave wherever possible.
33
36
 
34
37
  ## How it works
35
38
 
36
39
  ### Overview
37
40
 
38
- The mysql "READ_ONLY" flag is used to indicate a current master amongst the cluster. Only one member
39
- of the replication chain may be read-write at any given time. The application picks in run time, based
40
- on the read_only flag, which host is correct.
41
+ The MySQL `READ_ONLY` flag is used to indicate a current master amongst the
42
+ cluster. Only one member of the replication chain may be read-write at any given
43
+ time. The application picks in run time, based on the `READ_ONLY` flag, which
44
+ host is correct.
41
45
 
42
- ### boot time
46
+ ### Boot time
43
47
 
44
- Your activerecord application will pick a correct mysql host for the given configuration by probing hosts until
45
- it finds the correct host.
48
+ Your ActiveRecord application will pick a correct MySQL host for the given
49
+ configuration by probing hosts until it finds the correct host.
46
50
 
47
- For master configurations (slave: true is not specified):
51
+ For master configurations (`slave: true` is not specified):
48
52
 
49
- The application will probe each host in turn, and find the mysql candidate among these nodes
50
- that is read-write (SET GLOBAL READ\_ONLY=0).
53
+ The application will probe each host in turn, and find the MySQL candidate among
54
+ these nodes that is read-write (`SET GLOBAL READ_ONLY=0`).
51
55
 
52
- If it finds more than one node where READ_ONLY == 0, it will abort.
56
+ If it finds more than one node where `READ_ONLY == 0`, it will abort.
53
57
 
54
- For slave configurations (slave: true specified):
58
+ For slave configurations (`slave: true` specified):
55
59
 
56
- The application will choose a replica at random from amongst those where READ_ONLY == 1. If no active replicas are found,
57
- it will fall back to the master.
60
+ The application will choose a replica at random from amongst those where
61
+ `READ_ONLY == 1`. If no active replicas are found, it will fall back to the
62
+ master.
58
63
 
59
- ### run time
64
+ ### Run time
60
65
 
61
- Before each transaction is opened on the master, the application checks the status of the READ_ONLY variable.
62
- If READ\_ONLY == 0 (our active connection is still to the current master), it will proceed with the
63
- transaction as normal. If READ\_ONLY == 1 (the master has been demoted), it will drop the current connection
64
- and re-poll the cluster, sleeping for up to a default of 5 seconds for
65
- a new master to be promoted. When it finds the new master, it will continue playing the transaction on it.
66
+ Before each transaction is opened on the master, the application checks the
67
+ status of the `READ_ONLY` variable. If `READ_ONLY == 0` (our active connection
68
+ is still to the current master), it will proceed with the transaction as normal.
69
+ If `READ_ONLY == 1` (the master has been demoted), it will drop the current
70
+ connection and re-poll the cluster, sleeping for up to a default of 5 seconds
71
+ for a new master to be promoted. When it finds the new master, it will continue
72
+ playing the transaction on it.
66
73
 
67
- ### promoting a new master
74
+ ### Promoting a new master
68
75
 
69
- *The bin/master_cut script in this project will perform steps 3-5 for you.*
76
+ *The `bin/master_cut` script in this project will perform steps 35 for you.*
70
77
 
71
78
  The process of promoting a new master to head the cluster should be as follows:
72
79
 
73
- 1. identify a new candidate master
74
- 1. ensure that all other replicas in the cluster are chained off the candidate master; you want the
75
- chain to look like this:
80
+ 1. Identify a new candidate master.
81
+ 1. Ensure that all other replicas in the cluster are chained off the candidate
82
+ master; you want the chain to look like this:
76
83
 
77
84
  ```
78
85
  <existing master> -> <candidate master> -> <other replicas>
79
- -> <other replicas>
80
-
81
- ```
82
-
83
- 1. set the old master to READ_ONLY = 1
84
- 1. record the master-bin-log position of the candidate master (if you want to re-use the old master as a replica)
85
- 1. set the new master to READ_ONLY = 0
86
+ -> <other replicas>
86
87
 
87
- The application nodes will, in time, find that the old master is inactive and will move their connections to the
88
- new master.
88
+ ```
89
+ 1. Set the old master to `READ_ONLY = 1`.
90
+ 1. Record the master-bin-log position of the candidate master (if you want to
91
+ re-use the old master as a replica).
92
+ 1. Set the new master to `READ_ONLY = 0`.
89
93
 
90
- The application will also eventually shift slave traffic to another node in the cluster.
94
+ The application nodes will, in time, find that the old master is inactive and
95
+ will move their connections to the new master.
91
96
 
92
- ### caveats, gotchas
97
+ The application will also eventually shift slave traffic to another node in the
98
+ cluster.
93
99
 
94
- - Any explicit ( BEGIN ... END ) transaction that are in-flight when the old master goes READ_ONLY
95
- will crash. In theory there's a workaround for this problem, in pratice it's rather unwieldy due
96
- to a lack of shared global variables in mysql.
100
+ ### Caveats and gotchas
97
101
 
98
- - Connection variables are unsupported, due to the connection being able to go away at any time.
102
+ - Any explicit (`BEGIN` `END`) transaction that are in-flight when the old
103
+ master goes `READ_ONLY` will crash. In theory there’s a workaround for this
104
+ problem, in pratice it’s rather unwieldy due to a lack of shared global
105
+ variables in MySQL.
106
+ - Connection variables are unsupported, due to the connection being able to go
107
+ away at any time.
99
108
 
100
109
  ## Installation
101
110
 
102
- Do a little dance. Drink a little water. Or:
103
- Add this line to your application's Gemfile:
111
+ Add this line to your application’s Gemfile:
104
112
 
105
113
  gem 'ar_mysql_flexmaster'
106
114
 
@@ -119,5 +127,3 @@ Or install it yourself as:
119
127
  3. Commit your changes (`git commit -am 'Added some feature'`)
120
128
  4. Push to the branch (`git push origin my-new-feature`)
121
129
  5. Create new Pull Request
122
-
123
-
data/Rakefile CHANGED
@@ -1,4 +1,4 @@
1
- #!/usr/bin/env rake
1
+ require 'bundler/gem_tasks'
2
2
  require 'rake/testtask'
3
3
 
4
4
  require 'bump/tasks'
@@ -1,27 +1,30 @@
1
1
  # -*- encoding: utf-8 -*-
2
2
 
3
3
  Gem::Specification.new do |gem|
4
- gem.authors = ["Ben Osheroff"]
5
- gem.email = ["ben@zendesk.com"]
6
- gem.description = %q{ar_mysql_flexmaster allows configuring N mysql servers in database.yml and auto-selects which is a master at runtime}
7
- gem.summary = %q{select a master at runtime from a list}
8
- gem.homepage = "http://github.com/osheroff/ar_mysql_flexmaster"
4
+ gem.authors = ["Ben Osheroff", "Benjamin Quorning", "Gabe Martin-Dempesy", "Michael Grosser", "Pierre Schambacher"]
5
+ gem.email = ["bquorning@zendesk.com", "gabe@zendesk.com", "mgrosser@zendesk.com", "pschambacher@zendesk.com"]
6
+ gem.description = "ar_mysql_flexmaster allows configuring N mysql servers in database.yml and auto-selects which is a master at runtime"
7
+ gem.summary = "select a master at runtime from a list"
8
+ gem.homepage = "http://github.com/zendesk/ar_mysql_flexmaster"
9
9
 
10
10
  gem.files = `git ls-files`.split($\)
11
- gem.executables = gem.files.grep(%r{^bin/}).map{ |f| File.basename(f) }
11
+ gem.executables = gem.files.grep(%r{^bin/}).map { |f| File.basename(f) }
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 = "1.0.2"
15
+ gem.version = "1.0.3"
16
+
17
+ gem.required_ruby_version = ">= 2.2"
16
18
 
17
19
  gem.add_runtime_dependency("mysql2")
18
20
  gem.add_runtime_dependency("activerecord")
19
21
  gem.add_runtime_dependency("activesupport")
22
+ gem.add_development_dependency("bundler")
20
23
  gem.add_development_dependency("rake")
21
24
  gem.add_development_dependency("wwtd")
22
25
  gem.add_development_dependency("minitest")
23
26
  gem.add_development_dependency("mocha", "~> 1.1.0")
24
27
  gem.add_development_dependency("bump")
25
28
  gem.add_development_dependency("pry")
26
- gem.add_development_dependency("mysql_isolated_server", "~> 0.5")
29
+ gem.add_development_dependency("isolated_server")
27
30
  end
@@ -10,8 +10,8 @@ Thread.abort_on_exception = false
10
10
 
11
11
  opts = GetoptLong.new(
12
12
  ["--password", "-p", GetoptLong::REQUIRED_ARGUMENT],
13
- ["--rehome-master", "-r", GetoptLong::NO_ARGUMENT],
14
- ["--start-slave", "-s", GetoptLong::NO_ARGUMENT],
13
+ ["--rehome-master", "-r", GetoptLong::NO_ARGUMENT],
14
+ ["--start-slave", "-s", GetoptLong::NO_ARGUMENT]
15
15
  )
16
16
 
17
17
  opts.each do |opt, arg|
@@ -39,7 +39,6 @@ unless $old_master && $new_master && $username
39
39
  usage
40
40
  end
41
41
 
42
-
43
42
  def open_cx(host)
44
43
  host, port = host.split(":")
45
44
  port = port.to_i if port
@@ -121,7 +120,7 @@ def process_kill_thread
121
120
  end
122
121
 
123
122
  def wait_for_slave_catchup(master, slave)
124
- while true
123
+ loop do
125
124
  master_info = master.query("show master status").first
126
125
  slave_info = slave.query("show slave status").first
127
126
  break if master_info['Position'] <= slave_info['Exec_Master_Log_Pos']
@@ -129,11 +128,9 @@ def wait_for_slave_catchup(master, slave)
129
128
  end
130
129
 
131
130
  def kill_query!(cx, id)
132
- begin
133
- cx.query("kill #{id}")
134
- rescue Mysql2::Error => e
135
- raise e unless e.errno == 1094 # unknown thread id error
136
- end
131
+ cx.query("kill #{id}")
132
+ rescue Mysql2::Error => e
133
+ raise e unless e.errno == 1094 # unknown thread id error
137
134
  end
138
135
 
139
136
  def swap_thread
@@ -1,7 +1,7 @@
1
1
  PATH
2
- remote: ../
2
+ remote: ..
3
3
  specs:
4
- ar_mysql_flexmaster (0.6.0)
4
+ ar_mysql_flexmaster (1.0.2)
5
5
  activerecord
6
6
  activesupport
7
7
  mysql2
@@ -9,12 +9,12 @@ PATH
9
9
  GEM
10
10
  remote: https://rubygems.org/
11
11
  specs:
12
- actionmailer (3.2.22)
13
- actionpack (= 3.2.22)
12
+ actionmailer (3.2.22.5)
13
+ actionpack (= 3.2.22.5)
14
14
  mail (~> 2.5.4)
15
- actionpack (3.2.22)
16
- activemodel (= 3.2.22)
17
- activesupport (= 3.2.22)
15
+ actionpack (3.2.22.5)
16
+ activemodel (= 3.2.22.5)
17
+ activesupport (= 3.2.22.5)
18
18
  builder (~> 3.0.0)
19
19
  erubis (~> 2.7.0)
20
20
  journey (~> 1.0.4)
@@ -22,69 +22,69 @@ GEM
22
22
  rack-cache (~> 1.2)
23
23
  rack-test (~> 0.6.1)
24
24
  sprockets (~> 2.2.1)
25
- activemodel (3.2.22)
26
- activesupport (= 3.2.22)
25
+ activemodel (3.2.22.5)
26
+ activesupport (= 3.2.22.5)
27
27
  builder (~> 3.0.0)
28
- activerecord (3.2.22)
29
- activemodel (= 3.2.22)
30
- activesupport (= 3.2.22)
28
+ activerecord (3.2.22.5)
29
+ activemodel (= 3.2.22.5)
30
+ activesupport (= 3.2.22.5)
31
31
  arel (~> 3.0.2)
32
32
  tzinfo (~> 0.3.29)
33
- activeresource (3.2.22)
34
- activemodel (= 3.2.22)
35
- activesupport (= 3.2.22)
36
- activesupport (3.2.22)
33
+ activeresource (3.2.22.5)
34
+ activemodel (= 3.2.22.5)
35
+ activesupport (= 3.2.22.5)
36
+ activesupport (3.2.22.5)
37
37
  i18n (~> 0.6, >= 0.6.4)
38
38
  multi_json (~> 1.0)
39
39
  arel (3.0.3)
40
40
  builder (3.0.4)
41
- bump (0.5.3)
42
- coderay (1.1.0)
41
+ bump (0.5.4)
42
+ coderay (1.1.1)
43
43
  erubis (2.7.0)
44
44
  hike (1.2.3)
45
- i18n (0.7.0)
45
+ i18n (0.8.6)
46
+ isolated_server (0.4.12)
46
47
  journey (1.0.4)
47
- json (1.8.3)
48
- mail (2.5.4)
48
+ json (1.8.6)
49
+ mail (2.5.5)
49
50
  mime-types (~> 1.16)
50
51
  treetop (~> 1.4.8)
51
52
  metaclass (0.0.4)
52
53
  method_source (0.8.2)
53
54
  mime-types (1.25.1)
54
- minitest (5.8.3)
55
+ minitest (5.10.3)
55
56
  mocha (1.1.0)
56
57
  metaclass (~> 0.0.1)
57
- multi_json (1.11.2)
58
- mysql2 (0.3.20)
59
- mysql_isolated_server (0.5.3)
58
+ multi_json (1.12.1)
59
+ mysql2 (0.3.21)
60
60
  polyglot (0.3.5)
61
- pry (0.10.3)
61
+ pry (0.10.4)
62
62
  coderay (~> 1.1.0)
63
63
  method_source (~> 0.8.1)
64
64
  slop (~> 3.4)
65
65
  rack (1.4.7)
66
- rack-cache (1.5.1)
66
+ rack-cache (1.7.0)
67
67
  rack (>= 0.4)
68
68
  rack-ssl (1.3.4)
69
69
  rack
70
70
  rack-test (0.6.3)
71
71
  rack (>= 1.0)
72
- rails (3.2.22)
73
- actionmailer (= 3.2.22)
74
- actionpack (= 3.2.22)
75
- activerecord (= 3.2.22)
76
- activeresource (= 3.2.22)
77
- activesupport (= 3.2.22)
72
+ rails (3.2.22.5)
73
+ actionmailer (= 3.2.22.5)
74
+ actionpack (= 3.2.22.5)
75
+ activerecord (= 3.2.22.5)
76
+ activeresource (= 3.2.22.5)
77
+ activesupport (= 3.2.22.5)
78
78
  bundler (~> 1.0)
79
- railties (= 3.2.22)
80
- railties (3.2.22)
81
- actionpack (= 3.2.22)
82
- activesupport (= 3.2.22)
79
+ railties (= 3.2.22.5)
80
+ railties (3.2.22.5)
81
+ actionpack (= 3.2.22.5)
82
+ activesupport (= 3.2.22.5)
83
83
  rack-ssl (~> 1.3.2)
84
84
  rake (>= 0.8.7)
85
85
  rdoc (~> 3.4)
86
86
  thor (>= 0.14.6, < 2.0)
87
- rake (10.4.2)
87
+ rake (12.0.0)
88
88
  rdoc (3.12.2)
89
89
  json (~> 1.4)
90
90
  slop (3.6.0)
@@ -93,12 +93,12 @@ GEM
93
93
  multi_json (~> 1.0)
94
94
  rack (~> 1.0)
95
95
  tilt (~> 1.1, != 1.3.0)
96
- thor (0.19.1)
96
+ thor (0.20.0)
97
97
  tilt (1.4.1)
98
98
  treetop (1.4.15)
99
99
  polyglot
100
100
  polyglot (>= 0.3.1)
101
- tzinfo (0.3.46)
101
+ tzinfo (0.3.53)
102
102
  wwtd (1.3.0)
103
103
 
104
104
  PLATFORMS
@@ -107,14 +107,14 @@ PLATFORMS
107
107
  DEPENDENCIES
108
108
  ar_mysql_flexmaster!
109
109
  bump
110
+ isolated_server
110
111
  minitest
111
112
  mocha (~> 1.1.0)
112
113
  mysql2 (~> 0.3.0)
113
- mysql_isolated_server (~> 0.5)
114
114
  pry
115
115
  rails (~> 3.2.0)
116
116
  rake
117
117
  wwtd
118
118
 
119
119
  BUNDLED WITH
120
- 1.11.2
120
+ 1.15.4