mysql_replication_monitor 0.1.4

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.
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
+