ey_snaplock 0.0.11 → 0.0.12.pre
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/README.md +4 -1
- data/lib/ey_snaplock/database/mysql.rb +17 -1
- data/lib/ey_snaplock/version.rb +1 -1
- data/lib/ey_snaplock.rb +33 -2
- metadata +88 -119
data/README.md
CHANGED
@@ -14,8 +14,11 @@ archive_command = '/usr/bin/true'
|
|
14
14
|

|
15
15
|
|
16
16
|
Release process:
|
17
|
+
|
18
|
+
```
|
17
19
|
edit version file
|
18
20
|
gem build ey_snaplock.gemspec
|
19
|
-
|
21
|
+
gem push ey_snaplock-0.0.5.gem
|
20
22
|
edit version file again
|
21
23
|
commit
|
24
|
+
```
|
@@ -31,7 +31,7 @@ module EY
|
|
31
31
|
pipe = IO.popen(@mysql, 'w')
|
32
32
|
@read_lock_pid = pipe.pid
|
33
33
|
pipe.puts('flush tables with read lock;')
|
34
|
-
|
34
|
+
SnaplockTimer.timeout(timeout) do
|
35
35
|
until locked?
|
36
36
|
sleep 1
|
37
37
|
end
|
@@ -56,6 +56,22 @@ module EY
|
|
56
56
|
Process.kill('TERM', @read_lock_pid) # unlock tables
|
57
57
|
end
|
58
58
|
|
59
|
+
def has_long_running_queries?(cutoff_in_seconds)
|
60
|
+
%x<#{@mysql} -B -N -e 'show processlist;'>.split("\n").each do |process_entry|
|
61
|
+
id, user, host, db, command, time, state, info = process_entry.split("\t")
|
62
|
+
|
63
|
+
next if %w{root system}.include? user
|
64
|
+
next if ['Sleep', 'Binlog Dump'].include? command
|
65
|
+
|
66
|
+
return true if time.to_i > cutoff_in_seconds
|
67
|
+
end
|
68
|
+
false
|
69
|
+
end
|
70
|
+
|
71
|
+
def dump_process_list(logfile)
|
72
|
+
system("#{@mysql} -N -e 'show processlist;' >> #{logfile}")
|
73
|
+
end
|
74
|
+
|
59
75
|
def mysql_command(uri)
|
60
76
|
command = "mysql"
|
61
77
|
command << " -u" << (uri.user || 'root')
|
data/lib/ey_snaplock/version.rb
CHANGED
data/lib/ey_snaplock.rb
CHANGED
@@ -1,12 +1,20 @@
|
|
1
1
|
require 'net/http'
|
2
2
|
require 'net/https'
|
3
3
|
require 'ey_snaplock/database'
|
4
|
-
|
4
|
+
|
5
|
+
begin
|
6
|
+
require 'system_timer'
|
7
|
+
SnaplockTimer = SystemTimer
|
8
|
+
rescue LoadError => e
|
9
|
+
require 'timeout'
|
10
|
+
SnaplockTimer = Timeout
|
11
|
+
end
|
5
12
|
|
6
13
|
module EY
|
7
14
|
class Snaplock
|
8
15
|
REQUEST_TIMEOUT = 15
|
9
16
|
PER_DATABASE_TIMEOUT = 5
|
17
|
+
LONG_RUNNING_QUERY_RETRIES = 3
|
10
18
|
|
11
19
|
def self.call(*argv)
|
12
20
|
new(*argv).call
|
@@ -52,7 +60,7 @@ module EY
|
|
52
60
|
def timeout
|
53
61
|
lambda do
|
54
62
|
begin
|
55
|
-
|
63
|
+
SnaplockTimer.timeout(REQUEST_TIMEOUT) { yield }
|
56
64
|
rescue Timeout::Error
|
57
65
|
$stderr.puts "Timeout Exceeded: Callback request took longer than #{REQUEST_TIMEOUT} seconds."
|
58
66
|
raise
|
@@ -70,6 +78,24 @@ module EY
|
|
70
78
|
def database_lock(database_uri, timeout, &block)
|
71
79
|
database = Database.for(database_uri)
|
72
80
|
with_locked_db = block
|
81
|
+
|
82
|
+
if database.respond_to?(:has_long_running_queries?)
|
83
|
+
log_file = '/var/log/ey-snaplock.' + Time.now.strftime("%Y-%m-%dT%H-%M-%S") + '.log'
|
84
|
+
remaining_retries = LONG_RUNNING_QUERY_RETRIES
|
85
|
+
|
86
|
+
while database.has_long_running_queries? && remaining_retries >= 0
|
87
|
+
if remaining_retries == 0
|
88
|
+
database.dump_process_list(log_file)
|
89
|
+
clean_up_old_log_files
|
90
|
+
$stderr.puts "Bailing due to long running queries, process list dumped."
|
91
|
+
exit 1
|
92
|
+
else
|
93
|
+
sleep PER_DATABASE_TIMEOUT
|
94
|
+
end
|
95
|
+
end
|
96
|
+
|
97
|
+
end
|
98
|
+
|
73
99
|
lambda do
|
74
100
|
lock_filename = database.lock_filename
|
75
101
|
file = File.open(lock_filename, File::RDWR|File::EXCL|File::CREAT) rescue nil
|
@@ -90,6 +116,11 @@ module EY
|
|
90
116
|
end
|
91
117
|
end
|
92
118
|
|
119
|
+
def clean_up_old_log_files(count = 10)
|
120
|
+
ordinal = count.succ.to_s
|
121
|
+
"ls -r /var/log/ey-snaplock.*.log | tail -n +#{ordinal} | xargs -I@ rm @"
|
122
|
+
end
|
123
|
+
|
93
124
|
private
|
94
125
|
|
95
126
|
def post_path_for_uri(uri)
|
metadata
CHANGED
@@ -1,140 +1,119 @@
|
|
1
|
-
--- !ruby/object:Gem::Specification
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
2
|
name: ey_snaplock
|
3
|
-
version: !ruby/object:Gem::Version
|
4
|
-
|
5
|
-
prerelease:
|
6
|
-
segments:
|
7
|
-
- 0
|
8
|
-
- 0
|
9
|
-
- 11
|
10
|
-
version: 0.0.11
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.0.12.pre
|
5
|
+
prerelease: 7
|
11
6
|
platform: ruby
|
12
|
-
authors:
|
7
|
+
authors:
|
13
8
|
- Engine Yard
|
14
9
|
autorequire:
|
15
10
|
bindir: bin
|
16
11
|
cert_chain: []
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
- !ruby/object:Gem::Dependency
|
12
|
+
date: 2012-11-15 00:00:00.000000000 Z
|
13
|
+
dependencies:
|
14
|
+
- !ruby/object:Gem::Dependency
|
21
15
|
name: addressable
|
22
|
-
|
23
|
-
requirement: &id001 !ruby/object:Gem::Requirement
|
16
|
+
requirement: !ruby/object:Gem::Requirement
|
24
17
|
none: false
|
25
|
-
requirements:
|
18
|
+
requirements:
|
26
19
|
- - ~>
|
27
|
-
- !ruby/object:Gem::Version
|
28
|
-
hash: 3
|
29
|
-
segments:
|
30
|
-
- 2
|
31
|
-
- 2
|
32
|
-
- 2
|
20
|
+
- !ruby/object:Gem::Version
|
33
21
|
version: 2.2.2
|
34
22
|
type: :runtime
|
35
|
-
version_requirements: *id001
|
36
|
-
- !ruby/object:Gem::Dependency
|
37
|
-
name: SystemTimer
|
38
23
|
prerelease: false
|
39
|
-
|
24
|
+
version_requirements: !ruby/object:Gem::Requirement
|
40
25
|
none: false
|
41
|
-
requirements:
|
26
|
+
requirements:
|
42
27
|
- - ~>
|
43
|
-
- !ruby/object:Gem::Version
|
44
|
-
|
45
|
-
|
46
|
-
- 1
|
47
|
-
- 2
|
48
|
-
- 1
|
49
|
-
version: 1.2.1
|
50
|
-
type: :runtime
|
51
|
-
version_requirements: *id002
|
52
|
-
- !ruby/object:Gem::Dependency
|
28
|
+
- !ruby/object:Gem::Version
|
29
|
+
version: 2.2.2
|
30
|
+
- !ruby/object:Gem::Dependency
|
53
31
|
name: rake
|
54
|
-
|
55
|
-
requirement: &id003 !ruby/object:Gem::Requirement
|
32
|
+
requirement: !ruby/object:Gem::Requirement
|
56
33
|
none: false
|
57
|
-
requirements:
|
58
|
-
- -
|
59
|
-
- !ruby/object:Gem::Version
|
60
|
-
hash: 49
|
61
|
-
segments:
|
62
|
-
- 0
|
63
|
-
- 8
|
64
|
-
- 7
|
34
|
+
requirements:
|
35
|
+
- - '='
|
36
|
+
- !ruby/object:Gem::Version
|
65
37
|
version: 0.8.7
|
66
38
|
type: :development
|
67
|
-
version_requirements: *id003
|
68
|
-
- !ruby/object:Gem::Dependency
|
69
|
-
name: realweb
|
70
39
|
prerelease: false
|
71
|
-
|
40
|
+
version_requirements: !ruby/object:Gem::Requirement
|
41
|
+
none: false
|
42
|
+
requirements:
|
43
|
+
- - '='
|
44
|
+
- !ruby/object:Gem::Version
|
45
|
+
version: 0.8.7
|
46
|
+
- !ruby/object:Gem::Dependency
|
47
|
+
name: realweb
|
48
|
+
requirement: !ruby/object:Gem::Requirement
|
72
49
|
none: false
|
73
|
-
requirements:
|
50
|
+
requirements:
|
74
51
|
- - ~>
|
75
|
-
- !ruby/object:Gem::Version
|
76
|
-
hash: 21
|
77
|
-
segments:
|
78
|
-
- 0
|
79
|
-
- 2
|
80
|
-
- 1
|
52
|
+
- !ruby/object:Gem::Version
|
81
53
|
version: 0.2.1
|
82
54
|
type: :development
|
83
|
-
version_requirements: *id004
|
84
|
-
- !ruby/object:Gem::Dependency
|
85
|
-
name: cucumber
|
86
55
|
prerelease: false
|
87
|
-
|
56
|
+
version_requirements: !ruby/object:Gem::Requirement
|
57
|
+
none: false
|
58
|
+
requirements:
|
59
|
+
- - ~>
|
60
|
+
- !ruby/object:Gem::Version
|
61
|
+
version: 0.2.1
|
62
|
+
- !ruby/object:Gem::Dependency
|
63
|
+
name: cucumber
|
64
|
+
requirement: !ruby/object:Gem::Requirement
|
88
65
|
none: false
|
89
|
-
requirements:
|
66
|
+
requirements:
|
90
67
|
- - ~>
|
91
|
-
- !ruby/object:Gem::Version
|
92
|
-
hash: 55
|
93
|
-
segments:
|
94
|
-
- 0
|
95
|
-
- 10
|
96
|
-
- 0
|
68
|
+
- !ruby/object:Gem::Version
|
97
69
|
version: 0.10.0
|
98
70
|
type: :development
|
99
|
-
version_requirements: *id005
|
100
|
-
- !ruby/object:Gem::Dependency
|
101
|
-
name: aruba
|
102
71
|
prerelease: false
|
103
|
-
|
72
|
+
version_requirements: !ruby/object:Gem::Requirement
|
73
|
+
none: false
|
74
|
+
requirements:
|
75
|
+
- - ~>
|
76
|
+
- !ruby/object:Gem::Version
|
77
|
+
version: 0.10.0
|
78
|
+
- !ruby/object:Gem::Dependency
|
79
|
+
name: aruba
|
80
|
+
requirement: !ruby/object:Gem::Requirement
|
104
81
|
none: false
|
105
|
-
requirements:
|
82
|
+
requirements:
|
106
83
|
- - ~>
|
107
|
-
- !ruby/object:Gem::Version
|
108
|
-
|
109
|
-
segments:
|
110
|
-
- 0
|
111
|
-
- 3
|
112
|
-
version: "0.3"
|
84
|
+
- !ruby/object:Gem::Version
|
85
|
+
version: '0.3'
|
113
86
|
type: :development
|
114
|
-
version_requirements: *id006
|
115
|
-
- !ruby/object:Gem::Dependency
|
116
|
-
name: sinatra
|
117
87
|
prerelease: false
|
118
|
-
|
88
|
+
version_requirements: !ruby/object:Gem::Requirement
|
89
|
+
none: false
|
90
|
+
requirements:
|
91
|
+
- - ~>
|
92
|
+
- !ruby/object:Gem::Version
|
93
|
+
version: '0.3'
|
94
|
+
- !ruby/object:Gem::Dependency
|
95
|
+
name: sinatra
|
96
|
+
requirement: !ruby/object:Gem::Requirement
|
119
97
|
none: false
|
120
|
-
requirements:
|
121
|
-
- -
|
122
|
-
- !ruby/object:Gem::Version
|
123
|
-
|
124
|
-
segments:
|
125
|
-
- 0
|
126
|
-
version: "0"
|
98
|
+
requirements:
|
99
|
+
- - ! '>='
|
100
|
+
- !ruby/object:Gem::Version
|
101
|
+
version: '0'
|
127
102
|
type: :development
|
128
|
-
|
103
|
+
prerelease: false
|
104
|
+
version_requirements: !ruby/object:Gem::Requirement
|
105
|
+
none: false
|
106
|
+
requirements:
|
107
|
+
- - ! '>='
|
108
|
+
- !ruby/object:Gem::Version
|
109
|
+
version: '0'
|
129
110
|
description: Server side components for Engine Yard's snapshotting process
|
130
111
|
email:
|
131
|
-
executables:
|
112
|
+
executables:
|
132
113
|
- ey-snaplock
|
133
114
|
extensions: []
|
134
|
-
|
135
115
|
extra_rdoc_files: []
|
136
|
-
|
137
|
-
files:
|
116
|
+
files:
|
138
117
|
- bin/ey-snaplock
|
139
118
|
- lib/ey_snaplock/database/mysql.rb
|
140
119
|
- lib/ey_snaplock/database/postgresql9.rb
|
@@ -145,36 +124,26 @@ files:
|
|
145
124
|
- README.md
|
146
125
|
homepage:
|
147
126
|
licenses: []
|
148
|
-
|
149
127
|
post_install_message:
|
150
128
|
rdoc_options: []
|
151
|
-
|
152
|
-
require_paths:
|
129
|
+
require_paths:
|
153
130
|
- lib
|
154
|
-
required_ruby_version: !ruby/object:Gem::Requirement
|
131
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
155
132
|
none: false
|
156
|
-
requirements:
|
157
|
-
- -
|
158
|
-
- !ruby/object:Gem::Version
|
159
|
-
|
160
|
-
|
161
|
-
- 0
|
162
|
-
version: "0"
|
163
|
-
required_rubygems_version: !ruby/object:Gem::Requirement
|
133
|
+
requirements:
|
134
|
+
- - ! '>='
|
135
|
+
- !ruby/object:Gem::Version
|
136
|
+
version: '0'
|
137
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
164
138
|
none: false
|
165
|
-
requirements:
|
166
|
-
- -
|
167
|
-
- !ruby/object:Gem::Version
|
168
|
-
|
169
|
-
segments:
|
170
|
-
- 0
|
171
|
-
version: "0"
|
139
|
+
requirements:
|
140
|
+
- - ! '>'
|
141
|
+
- !ruby/object:Gem::Version
|
142
|
+
version: 1.3.1
|
172
143
|
requirements: []
|
173
|
-
|
174
144
|
rubyforge_project:
|
175
|
-
rubygems_version: 1.8.
|
145
|
+
rubygems_version: 1.8.23
|
176
146
|
signing_key:
|
177
147
|
specification_version: 3
|
178
148
|
summary: Server side components for Engine Yard's snapshotting process
|
179
149
|
test_files: []
|
180
|
-
|