ey_snaplock 0.1.0 → 0.1.1.pre

Sign up to get free protection for your applications and to get access to all the features.
@@ -20,6 +20,22 @@ module EY
20
20
  release_lock
21
21
  end
22
22
 
23
+ def has_long_running_queries?(cutoff_in_seconds)
24
+ %x<#{@mysql} -B -N -e 'show processlist;'>.split("\n").each do |process_entry|
25
+ id, user, host, db, command, time, state, info = process_entry.split("\t")
26
+
27
+ next if %w{root system}.include? user
28
+ next if ['Sleep', 'Binlog Dump'].include? command
29
+
30
+ return true if time.to_i > cutoff_in_seconds
31
+ end
32
+ false
33
+ end
34
+
35
+ def dump_process_list(logfile)
36
+ system("#{@mysql} -N -e 'show processlist;' >> #{logfile}")
37
+ end
38
+
23
39
  private
24
40
 
25
41
  def write_master_status(file)
@@ -1,5 +1,5 @@
1
1
  module EY
2
2
  class Snaplock
3
- VERSION = '0.1.0'
3
+ VERSION = '0.1.1.pre'
4
4
  end
5
5
  end
data/lib/ey_snaplock.rb CHANGED
@@ -7,6 +7,7 @@ module EY
7
7
  class Snaplock
8
8
  REQUEST_TIMEOUT = 15
9
9
  PER_DATABASE_TIMEOUT = 5
10
+ LONG_RUNNING_QUERY_RETRIES = 3
10
11
 
11
12
  def self.call(*argv)
12
13
  new(*argv).call
@@ -70,6 +71,25 @@ module EY
70
71
  def database_lock(database_uri, timeout, &block)
71
72
  database = Database.for(database_uri)
72
73
  with_locked_db = block
74
+
75
+ if database.respond_to?(:has_long_running_queries?)
76
+ log_file = '/var/log/ey-snaplock.' + Time.now.strftime("%Y-%m-%dT%H-%M-%S") + '.log'
77
+ remaining_retries = LONG_RUNNING_QUERY_RETRIES
78
+
79
+ while database.has_long_running_queries?(PER_DATABASE_TIMEOUT) && remaining_retries >= 0
80
+ if remaining_retries == 0
81
+ database.dump_process_list(log_file)
82
+ clean_up_old_log_files
83
+ $stderr.puts "Aborting Snaplock due to long running queries. Process list dumped to #{log_file}."
84
+ exit 1
85
+ else
86
+ remaining_retries -= 1
87
+ sleep PER_DATABASE_TIMEOUT
88
+ end
89
+ end
90
+
91
+ end
92
+
73
93
  lambda do
74
94
  lock_filename = database.lock_filename
75
95
  file = File.open(lock_filename, File::RDWR|File::EXCL|File::CREAT) rescue nil
@@ -90,6 +110,11 @@ module EY
90
110
  end
91
111
  end
92
112
 
113
+ def clean_up_old_log_files(logs_to_keep = 10)
114
+ ordinal = logs_to_keep.succ.to_s
115
+ system("ls -r /var/log/ey-snaplock.*.log | tail -n +#{ordinal} | xargs -I@ rm @")
116
+ end
117
+
93
118
  private
94
119
 
95
120
  def post_path_for_uri(uri)
metadata CHANGED
@@ -1,15 +1,15 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: ey_snaplock
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.0
5
- prerelease:
4
+ version: 0.1.1.pre
5
+ prerelease: 6
6
6
  platform: ruby
7
7
  authors:
8
8
  - Engine Yard
9
9
  autorequire:
10
10
  bindir: bin
11
11
  cert_chain: []
12
- date: 2012-11-17 00:00:00.000000000 Z
12
+ date: 2012-11-20 00:00:00.000000000 Z
13
13
  dependencies:
14
14
  - !ruby/object:Gem::Dependency
15
15
  name: addressable
@@ -138,12 +138,12 @@ required_ruby_version: !ruby/object:Gem::Requirement
138
138
  required_rubygems_version: !ruby/object:Gem::Requirement
139
139
  none: false
140
140
  requirements:
141
- - - ! '>='
141
+ - - ! '>'
142
142
  - !ruby/object:Gem::Version
143
- version: '0'
143
+ version: 1.3.1
144
144
  requirements: []
145
145
  rubyforge_project:
146
- rubygems_version: 1.8.24
146
+ rubygems_version: 1.8.23
147
147
  signing_key:
148
148
  specification_version: 3
149
149
  summary: Server side components for Engine Yard's snapshotting process