mysql_replication_status 0.1.1 → 0.1.2

Sign up to get free protection for your applications and to get access to all the features.
Files changed (2) hide show
  1. data/lib/mysql_replication_status.rb +165 -0
  2. metadata +2 -1
@@ -0,0 +1,165 @@
1
+ # utility to check the replication status between MySQL master and slave
2
+ # dbs set up to replicate to each other
3
+ #
4
+ # All that is needed is to specify the two dbs by their rails database
5
+ # config (environment) names (e.g. 'staging_master', 'staging_slave' or
6
+ # whatever).
7
+ #
8
+ # examples:
9
+ #
10
+ # # specify both master and slave db configs
11
+ # status = MysqlReplicationStatus.new(:master => 'master', :slave => 'slave)
12
+ # # default slave to the current environment
13
+ # status = MysqlReplicationStatus.new(:master => 'master')
14
+ # # override the default time to cache the statuses (in seconds)
15
+ # status = MysqlReplicationStatus.new(:master => 'master', :slave => 'slave,
16
+ # :refresh_time => 10)
17
+ # # override the default database config file (not recommended)
18
+ # status = MysqlReplicationStatus.new(:master => 'master', :slave => 'slave,
19
+ # :db_config_file => 'foofile.txt')
20
+ #
21
+ # TODO: did a quick google search on the class name and didn't have anything
22
+ # returned, but do we have any sort of namespace we want to use?....
23
+ #-------------------------------------------------------------------------------
24
+ class MysqlReplicationStatus
25
+
26
+ # exception raised if the class detects that either master or slave do not
27
+ # appear to be configured for replication
28
+ #-----------------------------------------------------------------------------
29
+ class NoReplicationError < Exception; end
30
+
31
+
32
+ # constructor accepts environment labels for the dbs to query replication
33
+ # status for. if one or the other is not specified, will use the
34
+ # rails environment that the class is currently running under. this
35
+ # object can cache status to reduce traffic on master and slave if this
36
+ # class's objects are to be called frequently (see :refresh_time option)
37
+ # options:
38
+ # :master => string containing environment to query the master db status
39
+ # :slave => string containing environment to query the slave db status
40
+ # (one or the other is optional, but never both)
41
+ # :refresh_time => how many seconds can elapse since last time the dbs
42
+ # were polled before we need to hit dbs again (in between
43
+ # any status methods called will just return cached
44
+ # values). optional, default => 1 (cache very briefly).
45
+ # recommend not setting this to 0, as calls like
46
+ # slave_running? will result in two db hits.
47
+ # :db_config_file => file containing database config settings. optional,
48
+ # default is rails default (recommended)
49
+ #-----------------------------------------------------------------------------
50
+ def initialize(options)
51
+ if options.blank? || (!options.include?(:master) &&
52
+ !options.include?(:slave))
53
+ raise "Invalid options configuration: should be a hash that includes " +
54
+ "either :master or :slave or both"
55
+ end
56
+
57
+ # if asked to override database config file, use the special init()
58
+ # function
59
+ if options[:db_config_file]
60
+ MultipleConnectionHandler.init(:config_file => options[:db_config_file])
61
+ end
62
+
63
+ @master_env = options[:master] || RAILS_ENV
64
+ @slave_env = options[:slave] || RAILS_ENV
65
+
66
+ @slave_status = nil
67
+ @master_status = nil
68
+
69
+ @refresh_time = options[:refresh_time] || 1
70
+ @last_refresh = nil
71
+ end
72
+
73
+
74
+ # force a refresh of the cached status. overrides :refresh_time option.
75
+ #-----------------------------------------------------------------------------
76
+ def refresh
77
+ @master_status = MultipleConnectionHandler.connection(@master_env).
78
+ execute("SHOW MASTER STATUS").all_hashes[0]
79
+ @slave_status = MultipleConnectionHandler.connection(@slave_env).
80
+ execute("SHOW SLAVE STATUS").all_hashes[0]
81
+
82
+ @last_refresh = Time.now
83
+
84
+ if @master_status.blank? && @slave_status.blank?
85
+ raise NoReplicationError,
86
+ "Neither master (#{@master_env}) nor slave (#{@slave_env}) " +
87
+ "appear to be configured for replication"
88
+ elsif @master_status.blank?
89
+ raise NoReplicationError,
90
+ "Master (#{@master_env}) does not appear to be configured for replication"
91
+ elsif @slave_status.blank?
92
+ raise NoReplicationError,
93
+ "Slave (#{@slave_env}) does not appear to be configured for replication"
94
+ end
95
+ end
96
+
97
+
98
+ # indicates if both IO and SQL threads are running
99
+ #-----------------------------------------------------------------------------
100
+ def slave_running?
101
+ cache_check_or_refresh
102
+
103
+ slave_io_running? && slave_sql_running?
104
+ end
105
+
106
+
107
+ # indicates if master and slave currently have same log file and log file
108
+ # position. note that if returns false, doesn't necessarily mean anything is
109
+ # wrong...just that slave is lagging. but if returns true, it may be that
110
+ # slave_running? is false.
111
+ #-----------------------------------------------------------------------------
112
+ def master_and_slave_in_sync?
113
+ cache_check_or_refresh
114
+
115
+ @master_status['Position'] == @slave_status['Exec_Master_Log_Pos'] &&
116
+ @master_status['File'] == @slave_status['Relay_Master_Log_File']
117
+ end
118
+
119
+
120
+ # returns true if the slave IO thread is running
121
+ #-----------------------------------------------------------------------------
122
+ def slave_io_running?
123
+ cache_check_or_refresh
124
+
125
+ @slave_status['Slave_IO_Running'].downcase == 'yes'
126
+ end
127
+
128
+
129
+ # returns true if the slave SQL thread is running
130
+ #-----------------------------------------------------------------------------
131
+ def slave_sql_running?
132
+ cache_check_or_refresh
133
+
134
+ @slave_status['Slave_SQL_Running'].downcase == 'yes'
135
+ end
136
+
137
+
138
+ # return a hashed version of the result of running SHOW SLAVE STATUS
139
+ #-----------------------------------------------------------------------------
140
+ def raw_slave_status
141
+ cache_check_or_refresh
142
+
143
+ @slave_status
144
+ end
145
+
146
+
147
+ # return a hashed version of the result of running SHOW MASTER STATUS
148
+ #-----------------------------------------------------------------------------
149
+ def raw_master_status
150
+ cache_check_or_refresh
151
+
152
+ @master_status
153
+ end
154
+
155
+ private
156
+
157
+ # check to see if the cache needs refreshing and do so if so.
158
+ #-----------------------------------------------------------------------------
159
+ def cache_check_or_refresh
160
+ if @last_refresh.nil? || @last_refresh + @refresh_time < Time.now
161
+ refresh
162
+ end
163
+ end
164
+
165
+ end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: mysql_replication_status
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.1
4
+ version: 0.1.2
5
5
  platform: ruby
6
6
  authors:
7
7
  - bmpercy
@@ -31,6 +31,7 @@ extensions: []
31
31
  extra_rdoc_files: []
32
32
 
33
33
  files:
34
+ - lib/mysql_replication_status.rb
34
35
  - README
35
36
  has_rdoc: true
36
37
  homepage: