Class: TyrantManager::Commands::ArchiveUlogs
- Inherits:
-
TyrantManager::Command
- Object
- TyrantManager::Command
- TyrantManager::Commands::ArchiveUlogs
- Defined in:
- lib/tyrant_manager/commands/archive_ulogs.rb
Overview
Archive ulog files that are no longer used for replication.
You must give the list of slave connection strings on the commandline, or if the server is in a single master-master relationship, then you can allow tyrantmanager to figure that out and do the right thing.
Give the slaves of a particular master
tyrantmanager archive-ulogs master1 --slaves slave1:11011,slave2:11012,slave3:11013
Or if there is a master-master relationship tyrant manager can figure it out.
tyrantmanager archive-ulogs master1
Sometimes it is useful to force a record from the master to the slave(s) so that the replication timestamp (rts) in the slaves is updated.
This is mainly useful for archiving the ulog files in the failover master of a master-master setup. The failover may never have an updated ‘rts’ value since its slave is the primary master, and the primary master may not have replicated from the failover master in quite some time.
tyrantemanager archive-ulogs --force
Instance Attribute Summary
Attributes inherited from TyrantManager::Command
Class Method Summary collapse
Instance Method Summary collapse
-
#archive_files_with_method(list, method) ⇒ Object
Archive each of the files in the list with the given method.
-
#determine_master_slave_mappings(list_of_slaves) ⇒ Object
Given a list of slaves, create a hash that has as the key, the instance connection string of a master, as as the value, an array of Rufus::Tokyo::Tyrant connections.
-
#potential_ulog_archive_files(instance) ⇒ Object
The list of potential files to remove from the ulog directory.
-
#remove_newer_than(potential, whence) ⇒ Object
Filter all the ulogs from the list whose value is greater than the input time.
- #run ⇒ Object
-
#trim_potential_removals(master_instance, potential, slave_conn) ⇒ Object
Remove all items from the potential removals list that have a timestamp that is newer than the last replication timestamp of the tyrant connection.
Methods inherited from TyrantManager::Command
#after, #before, #command_name, #error, find, inherited, #initialize, list, #logger
Constructor Details
This class inherits a constructor from TyrantManager::Command
Class Method Details
.command_name ⇒ Object
38 39 40 |
# File 'lib/tyrant_manager/commands/archive_ulogs.rb', line 38 def self.command_name 'archive-ulogs' end |
Instance Method Details
#archive_files_with_method(list, method) ⇒ Object
Archive each of the files in the list with the given method
80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 |
# File 'lib/tyrant_manager/commands/archive_ulogs.rb', line 80 def archive_files_with_method( list, method ) list.each do |fname| leader = (['dry-run']) ? "(dry-run)" : "" if "delete" == method then File.unlink( fname ) unless ['dry-run'] manager.logger.info "deleted #{leader} #{fname}" else if File.extname( fname ) == ".ulog" then %x[ gzip #{fname} ] unless ['dry-run'] manager.logger.info "#{leader} compressed #{fname}" else manager.logger.debug "#{leader} already compressed #{fname}" end end end end |
#determine_master_slave_mappings(list_of_slaves) ⇒ Object
Given a list of slaves, create a hash that has as the key, the instance connection string of a master, as as the value, an array of Rufus::Tokyo::Tyrant connections.
163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 |
# File 'lib/tyrant_manager/commands/archive_ulogs.rb', line 163 def determine_master_slave_mappings( list_of_slaves ) master_to_slaves = Hash.new{ |h,k| h[k] = [] } list_of_slaves ||= [] list_of_slaves.each do |connection_string| host, port = connection_string.split(":") conn = Rufus::Tokyo::Tyrant.new( host, port.to_i ) stat = conn.stat master_host = stat['mhost'] master_port = stat['mport'] if master_host and master_port then master_to_slaves["#{master_host}:#{master_port}"] << conn else manager.logger.warn "Slave #{connection_string} does not have a master server configured, skipping using it as a slave" end end return master_to_slaves end |
#potential_ulog_archive_files(instance) ⇒ Object
The list of potential files to remove from the ulog directory. This is all the files in the ulog directory, minus the last one lexically.
A hash of filename => File.mtime values is returned
148 149 150 151 152 153 154 155 156 |
# File 'lib/tyrant_manager/commands/archive_ulogs.rb', line 148 def potential_ulog_archive_files( instance ) names = instance.ulog_files[0..-2] names += Dir.glob( "#{instance.ulog_dir}/*.ulog.gz" ) potential = {} names.each do |name| potential[name] = File.mtime( name ) end return potential end |
#remove_newer_than(potential, whence) ⇒ Object
Filter all the ulogs from the list whose value is greater than the input time.
131 132 133 134 135 136 137 138 139 140 |
# File 'lib/tyrant_manager/commands/archive_ulogs.rb', line 131 def remove_newer_than( potential, whence ) fmt = "%Y-%m-%d %H:%M:%S" potential.keys.sort.each do |fname| if potential[fname] > whence then manager.logger.info " ulog #{fname} timestamp #{potential[fname].strftime(fmt)} is newer than #{whence.strftime(fmt)}. Skipping." potential.delete( fname ) end end return potential end |
#run ⇒ Object
42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 |
# File 'lib/tyrant_manager/commands/archive_ulogs.rb', line 42 def run instance_slaves = determine_master_slave_mappings( ['slaves'] ) = Time.now.strftime("%Y-%m-%d %H:%M:%S") manager.each_instance( ['instances'] ) do |instance| if instance.is_master_master? then manager.logger.debug "#{instance.name} is master_master" instance_slaves[instance.connection_string] << instance.master_connection if ['force'] then msg = "Forcing a record #{['force-key']} => #{} from master #{instance.connection_string} through to slaves" msg = "(dry-run) #{msg}" if ['dry-run'] manager.logger.info msg if not ['dry-run'] then c = instance.connection[['force-key']] = end end end slave_connections = instance_slaves[instance.connection_string] potential_removals = potential_ulog_archive_files( instance ) manager.logger.info "Checking #{slave_connections.size} slaves of #{instance.name}" slave_connections.each do |conn| manager.logger.info "Slave has #{['force-key']} => #{conn[['force-key']]}" if ['force'] potential_removals = trim_potential_removals( instance, potential_removals, conn ) end archive_files_with_method( potential_removals.keys.sort, ['archive-method'] ) end end |
#trim_potential_removals(master_instance, potential, slave_conn) ⇒ Object
Remove all items from the potential removals list that have a timestamp that is newer than the last replication timestamp of the tyrant connection
102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 |
# File 'lib/tyrant_manager/commands/archive_ulogs.rb', line 102 def trim_potential_removals( master_instance, potential, slave_conn ) slave_stat = slave_conn.stat milliseconds = Float( slave_stat['rts'] ) last_replication_at = Time.at( milliseconds / 1_000_000 ) 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}" if milliseconds.to_i == 0 then manager.logger.warn "It appears that the slave at #{slave_conn.host}:#{slave_conn.port} has never replicated" manager.logger.warn "This means that no ulogs on the master will be removed, since there is no evidence of replication." manager.logger.warn "It may be necessary to force a replication by inserting a record into the master:" manager.logger.warn "" manager.logger.warn " tcrmgr put -port #{master_instance.configuration.port} #{master_instance.configuration.host} __tyrant_manager.force_replication_at #{Time.now.utc.to_i}" manager.logger.warn "" manager.logger.warn "And then removing that record if you so choose:" manager.logger.warn "" manager.logger.warn " tcrmgr out -port #{master_instance.configuration.port} #{master_instance.configuration.host} __tyrant_manager.force_replication_at" manager.logger.warn "" end manager.logger.debug "Trimming ulog files that are newer than #{last_replication_at.strftime("%Y-%m-%d %H:%M:%S")}" trimmed_potential = remove_newer_than( potential, last_replication_at ) end |