mysql_import 0.5.2 → 0.5.3
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/lib/mysql_import/logger.rb +4 -2
- data/lib/mysql_import/version.rb +1 -1
- data/lib/mysql_import.rb +90 -32
- metadata +2 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 06c89712eae3231ff8008e95ae2f918641392538
|
4
|
+
data.tar.gz: 8f070851b68245e1fe809997d91e7aaef3b6a079
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 6753df47ee3e60af5db61f00aab235a484fcf8a735f8c9b3f352683632514b4e70bd2cc402de9046952083a8d62041dc4ce850efacc2dd92281c8a1e354b5d91
|
7
|
+
data.tar.gz: 561b7c0146843c0ec9940b62a3c1b56bb3099448ef964435348fc2f18e996d5bc945621586b575366fd9da0900c10f7a8237fefa8d9333861db280e57e7e3759
|
data/lib/mysql_import/logger.rb
CHANGED
@@ -30,10 +30,12 @@ class MysqlImport
|
|
30
30
|
ensure
|
31
31
|
@logger.info('Imported tables:')
|
32
32
|
if @result.imported.size > 0
|
33
|
+
max_len = @result.imported.map(&:first).max_by{|w| w.length}.length
|
33
34
|
@result.imported.sort.each do |t|
|
34
|
-
|
35
|
+
space = ' ' * ((max_len - t[0].length) + 1)
|
36
|
+
msg = " #{t[0]}#{space}[exec:#{format('%.3fs', t[1])}"
|
35
37
|
msg << " lock:#{format('%.3fs', t[2])}" if t[2]
|
36
|
-
msg << '
|
38
|
+
msg << ']'
|
37
39
|
@logger.info(msg)
|
38
40
|
end
|
39
41
|
else
|
data/lib/mysql_import/version.rb
CHANGED
data/lib/mysql_import.rb
CHANGED
@@ -3,6 +3,7 @@ require 'mysql_import/logger'
|
|
3
3
|
require 'load_data_infile2'
|
4
4
|
require 'connection_pool'
|
5
5
|
require 'parallel'
|
6
|
+
require 'benchmark'
|
6
7
|
|
7
8
|
class MysqlImport
|
8
9
|
def initialize(config, opts = {})
|
@@ -23,7 +24,12 @@ class MysqlImport
|
|
23
24
|
def import(filters = nil)
|
24
25
|
Parallel.each(filtered_list(filters), parallel_opts) do |args|
|
25
26
|
@client.with do |cli|
|
26
|
-
|
27
|
+
begin
|
28
|
+
store[:client] = cli
|
29
|
+
import_internal(*args)
|
30
|
+
ensure
|
31
|
+
clear_store
|
32
|
+
end
|
27
33
|
end
|
28
34
|
end
|
29
35
|
end
|
@@ -43,57 +49,107 @@ class MysqlImport
|
|
43
49
|
{ in_threads: @concurrency }
|
44
50
|
end
|
45
51
|
|
46
|
-
def
|
47
|
-
t = Time.now
|
48
|
-
imported = false
|
49
|
-
|
52
|
+
def import_internal(fpath, opts)
|
50
53
|
sql_opts = opts.reject {|k, _| %i(before after).include?(k) }
|
51
|
-
table = sql_opts[:table] || File.basename(fpath, '.*')
|
52
|
-
lock = opts.fetch(:lock, @lock)
|
54
|
+
store[:table] = sql_opts[:table] || File.basename(fpath, '.*')
|
53
55
|
|
54
|
-
|
55
|
-
|
56
|
-
|
57
|
-
|
58
|
-
end
|
56
|
+
with_recording do
|
57
|
+
with_lock_if_needed(opts.fetch(:lock, @lock)) do
|
58
|
+
with_skip_handling do
|
59
|
+
run_before_action(opts[:before])
|
59
60
|
|
60
|
-
|
61
|
+
store[:client].import(fpath, sql_opts)
|
61
62
|
|
62
|
-
|
63
|
-
|
63
|
+
run_after_action(opts[:after])
|
64
|
+
end
|
65
|
+
end
|
66
|
+
end
|
67
|
+
end
|
64
68
|
|
65
|
-
|
66
|
-
|
67
|
-
|
68
|
-
|
69
|
-
|
70
|
-
|
71
|
-
|
72
|
-
|
69
|
+
def with_recording
|
70
|
+
store[:exec_time] = realtime { yield }
|
71
|
+
ensure
|
72
|
+
if store[:before_break]
|
73
|
+
@result.skipped.push(store[:table])
|
74
|
+
else
|
75
|
+
res = [store[:table], store[:exec_time]]
|
76
|
+
res.push(store[:lock_time]) if store[:lock_time]
|
77
|
+
@result.imported.push(res)
|
78
|
+
end
|
79
|
+
end
|
80
|
+
|
81
|
+
def with_lock_if_needed(need)
|
82
|
+
if need
|
83
|
+
begin
|
84
|
+
write_lock
|
85
|
+
store[:lock_time] = realtime { yield }
|
86
|
+
ensure
|
87
|
+
unlock
|
73
88
|
end
|
74
|
-
|
89
|
+
else
|
90
|
+
yield
|
75
91
|
end
|
76
92
|
end
|
77
93
|
|
78
|
-
def
|
94
|
+
def with_skip_handling
|
95
|
+
yield
|
96
|
+
rescue BeforeBreak
|
97
|
+
store[:before_break] = true
|
98
|
+
rescue AfterBreak
|
99
|
+
store[:after_break] = true
|
100
|
+
end
|
101
|
+
|
102
|
+
def realtime
|
103
|
+
Benchmark.realtime { yield }
|
104
|
+
end
|
105
|
+
|
106
|
+
def run_action(action)
|
79
107
|
return unless action
|
80
108
|
|
81
109
|
case action
|
82
110
|
when Array
|
83
|
-
action.each { |act| run_action(act
|
111
|
+
action.each { |act| run_action(act) }
|
84
112
|
when String
|
85
|
-
|
113
|
+
store[:client].query(action)
|
86
114
|
else
|
87
|
-
action.call(
|
115
|
+
action.call(store[:client])
|
88
116
|
end
|
89
117
|
end
|
90
118
|
|
91
|
-
def
|
92
|
-
|
119
|
+
def run_before_action(action)
|
120
|
+
run_action(action)
|
121
|
+
rescue Break
|
122
|
+
raise BeforeBreak
|
123
|
+
end
|
124
|
+
|
125
|
+
def run_after_action(action)
|
126
|
+
run_action(action)
|
127
|
+
rescue Break
|
128
|
+
raise AfterBreak
|
129
|
+
end
|
130
|
+
|
131
|
+
def write_lock
|
132
|
+
[
|
133
|
+
'SET @old_autocommit=@@autocommit;',
|
134
|
+
'SET autocommit=0;',
|
135
|
+
"LOCK TABLE `#{store[:table]}` WRITE;"
|
136
|
+
].each {|sql| store[:client].query(sql)}
|
137
|
+
end
|
138
|
+
|
139
|
+
def unlock
|
140
|
+
[
|
141
|
+
'COMMIT;',
|
142
|
+
'UNLOCK TABLES;',
|
143
|
+
'SET autocommit=@old_autocommit;'
|
144
|
+
].each {|sql| store[:client].query(sql)}
|
145
|
+
end
|
146
|
+
|
147
|
+
def store
|
148
|
+
Thread.current[:store] ||= {}
|
93
149
|
end
|
94
150
|
|
95
|
-
def
|
96
|
-
|
151
|
+
def clear_store
|
152
|
+
Thread.current[:store] = nil
|
97
153
|
end
|
98
154
|
|
99
155
|
class Result
|
@@ -112,4 +168,6 @@ class MysqlImport
|
|
112
168
|
end
|
113
169
|
|
114
170
|
class Break < StandardError; end
|
171
|
+
class BeforeBreak < Break; end
|
172
|
+
class AfterBreak < Break; end
|
115
173
|
end
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: mysql_import
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.5.
|
4
|
+
version: 0.5.3
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- nalabjp
|
8
8
|
autorequire:
|
9
9
|
bindir: exe
|
10
10
|
cert_chain: []
|
11
|
-
date: 2016-
|
11
|
+
date: 2016-12-05 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: load_data_infile2
|