mysql_replication_monitor 0.1.4

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