tyrantmanager 1.4.1 → 1.5.0

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/HISTORY.rdoc CHANGED
@@ -1,4 +1,9 @@
1
1
  = Changelog
2
+ == Version 1.5.0 2010-03-07
3
+
4
+ * update archive-ulog command with --force option to insert a record
5
+ and force a replication to take place
6
+
2
7
  == Version 1.4.1 2010-01-22
3
8
 
4
9
  * reduce the logging level of a skipped operation to debug
@@ -127,6 +127,22 @@ class TyrantManager
127
127
  default false
128
128
  }
129
129
 
130
+ option( 'force' ) {
131
+ description "Force a record through the master to the slave so the replication timestamps are updated."
132
+ default false
133
+ cast :boolean
134
+ }
135
+
136
+ option('force-key') {
137
+ description "When used with --force, this is the key that is forced from the master to the slaves.
138
+ The value iinserted at the key is the current timestamp in the form
139
+ #{Time.now.strftime('%Y-%m-%d %H:%M:%S')}"
140
+ argument :required
141
+ default "__tyrant_manager.force_replication_at"
142
+ cast :string
143
+ }
144
+
145
+
130
146
  option( 'slaves' ) {
131
147
  description "Comma separated list of slave instances connection strings host:port,host:port,..."
132
148
  argument :required
@@ -12,13 +12,22 @@ class TyrantManager
12
12
  #
13
13
  # Give the slaves of a particular master
14
14
  #
15
- # tyrantmanager archive-ulogs master1 --slaves slave1:11011,slave2:11012,slave3:11013
15
+ # tyrantmanager archive-ulogs master1 --slaves slave1:11011,slave2:11012,slave3:11013
16
16
  #
17
17
  # Or if there is a master-master relationship tyrant manager can figure it
18
18
  # out.
19
19
  #
20
- # tyrantmanager archive-ulogs master1
20
+ # tyrantmanager archive-ulogs master1
21
21
  #
22
+ # Sometimes it is useful to force a record from the master to the slave(s)
23
+ # so that the replication timestamp (rts) in the slaves is updated.
24
+ #
25
+ # This is mainly useful for archiving the ulog files in the failover master
26
+ # of a master-master setup. The failover may never have an updated 'rts'
27
+ # value since its slave is the primary master, and the primary master may
28
+ # not have replicated from the failover master in quite some time.
29
+ #
30
+ # tyrantemanager archive-ulogs --force
22
31
  #
23
32
  class ArchiveUlogs < Command
24
33
  def self.command_name
@@ -27,18 +36,31 @@ class TyrantManager
27
36
 
28
37
  def run
29
38
  instance_slaves = determine_master_slave_mappings( options['slaves'] )
39
+ current_timestamp = Time.now.strftime("%Y-%m-%d %H:%M:%S")
30
40
 
31
41
  manager.each_instance( options['instances'] ) do |instance|
32
42
  if instance.is_master_master? then
33
43
  manager.logger.debug "#{instance.name} is master_master"
34
44
  instance_slaves[instance.connection_string] << instance.master_connection
45
+
46
+ if options['force'] then
47
+ msg = "Forcing a record #{options['force-key']} => #{current_timestamp} from master #{instance.connection_string} through to slaves"
48
+ msg = "(dry-run) #{msg}" if options['dry-run']
49
+ manager.logger.info msg
50
+ if not options['dry-run'] then
51
+ c =
52
+ instance.connection[options['force-key']] = current_timestamp
53
+ end
54
+ end
35
55
  end
56
+
36
57
  slave_connections = instance_slaves[instance.connection_string]
37
58
 
38
59
  potential_removals = potential_ulog_archive_files( instance )
39
60
  manager.logger.info "Checking #{slave_connections.size} slaves of #{instance.name}"
40
61
 
41
62
  slave_connections.each do |conn|
63
+ manager.logger.info "Slave has #{options['force-key']} => #{conn[options['force-key']]}" if options['force']
42
64
  potential_removals = trim_potential_removals( instance, potential_removals, conn )
43
65
  end
44
66
 
@@ -77,7 +99,7 @@ class TyrantManager
77
99
  milliseconds = Float( slave_stat['rts'] )
78
100
  last_replication_at = Time.at( milliseconds / 1_000_000 )
79
101
 
80
- manager.logger.debug "Slave #{slave_conn.host}:#{slave_conn.port} last replicated at #{last_replication_at.strftime("%Y-%m-%d %H:%M:%S")} from #{master_instance.connection_string}"
102
+ manager.logger.info "Slave #{slave_conn.host}:#{slave_conn.port} last replicated at #{last_replication_at.strftime("%Y-%m-%d %H:%M:%S")} from #{master_instance.connection_string}"
81
103
 
82
104
  if milliseconds.to_i == 0 then
83
105
  manager.logger.warn "It appears that the slave at #{slave_conn.host}:#{slave_conn.port} has never replicated"
@@ -102,8 +124,10 @@ class TyrantManager
102
124
  # time.
103
125
  #
104
126
  def remove_newer_than( potential, whence )
127
+ fmt = "%Y-%m-%d %H:%M:%S"
105
128
  potential.keys.sort.each do |fname|
106
129
  if potential[fname] > whence then
130
+ manager.logger.info " ulog #{fname} timestamp #{potential[fname].strftime(fmt)} is newer than #{whence.strftime(fmt)}. Skipping."
107
131
  potential.delete( fname )
108
132
  end
109
133
  end
@@ -126,6 +150,7 @@ class TyrantManager
126
150
  return potential
127
151
  end
128
152
 
153
+ #
129
154
  # Given a list of slaves, create a hash that has as the key, the instance
130
155
  # connection string of a master, as as the value, an array of
131
156
  # Rufus::Tokyo::Tyrant connections.
@@ -6,8 +6,8 @@
6
6
  class TyrantManager
7
7
  module Version
8
8
  MAJOR = 1
9
- MINOR = 4
10
- BUILD = 1
9
+ MINOR = 5
10
+ BUILD = 0
11
11
 
12
12
  def to_a
13
13
  [MAJOR, MINOR, BUILD]
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: tyrantmanager
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.4.1
4
+ version: 1.5.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Jeremy Hinegardner
@@ -9,7 +9,7 @@ autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
11
 
12
- date: 2010-01-22 00:00:00 -07:00
12
+ date: 2010-03-07 00:00:00 -07:00
13
13
  default_executable:
14
14
  dependencies:
15
15
  - !ruby/object:Gem::Dependency