maatkit-ruby 0.1.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.
Files changed (40) hide show
  1. data/Changelog +0 -0
  2. data/MIT-LICENSE +21 -0
  3. data/README +26 -0
  4. data/lib/maatkit-ruby.rb +11 -0
  5. data/lib/maatkit-ruby/mk-archiver.rb +473 -0
  6. data/lib/maatkit-ruby/mk-checksum-filter.rb +122 -0
  7. data/lib/maatkit-ruby/mk-deadlock-logger.rb +223 -0
  8. data/lib/maatkit-ruby/mk-duplicate-key-checker.rb +239 -0
  9. data/lib/maatkit-ruby/mk-error-log.rb +240 -0
  10. data/lib/maatkit-ruby/mk-fifo-split.rb +130 -0
  11. data/lib/maatkit-ruby/mk-find.rb +137 -0
  12. data/lib/maatkit-ruby/mk-heartbeat.rb +300 -0
  13. data/lib/maatkit-ruby/mk-index-usage.rb +164 -0
  14. data/lib/maatkit-ruby/mk-kill.rb +124 -0
  15. data/lib/maatkit-ruby/mk-loadavg.rb +313 -0
  16. data/lib/maatkit-ruby/mk-log-player.rb +316 -0
  17. data/lib/maatkit-ruby/mk-merge-mqd-results.rb +248 -0
  18. data/lib/maatkit-ruby/mk-parallel-dump.rb +400 -0
  19. data/lib/maatkit-ruby/mk-parallel-restore.rb +133 -0
  20. data/lib/maatkit-ruby/mk-profile-compact.rb +87 -0
  21. data/lib/maatkit-ruby/mk-purge-logs.rb +99 -0
  22. data/lib/maatkit-ruby/mk-query-advisor.rb +105 -0
  23. data/lib/maatkit-ruby/mk-query-digest.rb +149 -0
  24. data/lib/maatkit-ruby/mk-query-profiler.rb +106 -0
  25. data/lib/maatkit-ruby/mk-show-grants.rb +103 -0
  26. data/lib/maatkit-ruby/mk-slave-delay.rb +102 -0
  27. data/lib/maatkit-ruby/mk-slave-find.rb +98 -0
  28. data/lib/maatkit-ruby/mk-slave-move.rb +99 -0
  29. data/lib/maatkit-ruby/mk-slave-prefetch.rb +124 -0
  30. data/lib/maatkit-ruby/mk-slave-restart.rb +116 -0
  31. data/lib/maatkit-ruby/mk-table-checksum.rb +151 -0
  32. data/lib/maatkit-ruby/mk-table-sync.rb +468 -0
  33. data/lib/maatkit-ruby/mk-upgrade.rb +118 -0
  34. data/lib/maatkit-ruby/mk-variable-advisor.rb +99 -0
  35. data/lib/maatkit-ruby/mk-visual-explain.rb +98 -0
  36. data/lib/maatkit-ruby/version.rb +17 -0
  37. data/setup.rb +1585 -0
  38. data/test/test_helper.rb +2 -0
  39. data/test/test_maatkit_ruby.rb +11 -0
  40. metadata +105 -0
@@ -0,0 +1,124 @@
1
+ # = maatkit-ruby - A maatkit gem for Ruby
2
+ #
3
+ # Homepage:: http://github.com/jjuliano/maatkit-ruby
4
+ # Author:: Joel Bryan Juliano
5
+ # Copyright:: (cc) 2011 Joel Bryan Juliano
6
+ # License:: MIT
7
+
8
+ #
9
+ # Kill MySQL queries that match certain criteria.
10
+ #
11
+ # Maatkit::Kill.new( array, str, array)
12
+ #
13
+ class Maatkit::Kill
14
+
15
+ attr_accessor :all # FALSE
16
+ attr_accessor :ask_pass # FALSE
17
+ attr_accessor :busy_time # (No value)
18
+ attr_accessor :charset # (No value)
19
+ attr_accessor :config # /etc/maatkit/maatkit.conf,/etc/maatkit/mk_kill.conf,/home/joel/.maatkit.conf,/home/joel/.mk_kill.conf
20
+ attr_accessor :daemonize # FALSE
21
+ attr_accessor :defaults_file # (No value)
22
+ attr_accessor :execute_command # (No value)
23
+ attr_accessor :heartbeat # FALSE
24
+ attr_accessor :help # TRUE
25
+ attr_accessor :host # (No value)
26
+ attr_accessor :idle_time # (No value)
27
+ attr_accessor :ignore_command # (No value)
28
+ attr_accessor :ignore_db # (No value)
29
+ attr_accessor :ignore_host # (No value)
30
+ attr_accessor :ignore_info # (No value)
31
+ attr_accessor :ignore_self # TRUE
32
+ attr_accessor :ignore_state # Locked
33
+ attr_accessor :ignore_user # (No value)
34
+ attr_accessor :interval # 30
35
+ attr_accessor :iterations # 1
36
+ attr_accessor :kill # FALSE
37
+ attr_accessor :kill_query # FALSE
38
+ attr_accessor :log # (No value)
39
+ attr_accessor :match_command # (No value)
40
+ attr_accessor :match_db # (No value)
41
+ attr_accessor :match_host # (No value)
42
+ attr_accessor :match_info # (No value)
43
+ attr_accessor :match_state # (No value)
44
+ attr_accessor :match_user # (No value)
45
+ attr_accessor :only_oldest # TRUE
46
+ attr_accessor :password # (No value)
47
+ attr_accessor :pid # (No value)
48
+ attr_accessor :port # (No value)
49
+ attr_accessor :print # FALSE
50
+ attr_accessor :replication_threads # FALSE
51
+ attr_accessor :run_time # (No value)
52
+ attr_accessor :set_vars # wait_timeout=10000
53
+ attr_accessor :socket # (No value)
54
+ attr_accessor :user # (No value)
55
+ attr_accessor :version # FALSE
56
+ attr_accessor :wait_after_kill # (No value)
57
+ attr_accessor :wait_before_kill # (No value)
58
+
59
+ #
60
+ # Sets the executable path, otherwise the environment path will be used.
61
+ #
62
+ attr_accessor :path_to_mk_kill
63
+
64
+ #
65
+ # Returns a new Kill Object
66
+ #
67
+ def initialize()
68
+ end
69
+
70
+ #
71
+ # Execute the command
72
+ #
73
+ def start(options = nil)
74
+ tmp = Tempfile.new('tmp')
75
+ command = option_string() + options.to_s + " 2> " + tmp.path
76
+ success = system(command)
77
+ if success
78
+ begin
79
+ while (line = tmp.readline)
80
+ line.chomp
81
+ selected_string = line
82
+ end
83
+ rescue EOFError
84
+ tmp.close
85
+ end
86
+ return selected_string
87
+ else
88
+ tmp.close!
89
+ return success
90
+ end
91
+ end
92
+
93
+ def config
94
+ option_string()
95
+ end
96
+
97
+ private
98
+
99
+ def option_string()
100
+
101
+ unless @path_to_mk_kill
102
+ ostring = "mk-kill "
103
+ else
104
+ ostring = @path_to_mk_kill + " "
105
+ end
106
+
107
+ self.instance_variables.each do |i|
108
+ tmp_value = self.instance_variable_get "#{i}"
109
+ tmp_string = i.gsub("_", "-").gsub("@", "--")
110
+ unless tmp_string == "--path-to-mk-kill"
111
+ if (tmp_value.is_a? TrueClass) || (tmp_value.is_a? FalseClass)
112
+ ostring += "#{tmp_string} "
113
+ else
114
+ ostring += "#{tmp_string} #{tmp_value} "
115
+ end
116
+ end
117
+ end
118
+
119
+ return ostring
120
+
121
+ end
122
+
123
+ end
124
+
@@ -0,0 +1,313 @@
1
+ # = maatkit-ruby - A maatkit gem for Ruby
2
+ #
3
+ # Homepage:: http://github.com/jjuliano/maatkit-ruby
4
+ # Author:: Joel Bryan Juliano
5
+ # Copyright:: (cc) 2011 Joel Bryan Juliano
6
+ # License:: MIT
7
+
8
+ #
9
+ # Watch MySQL load and take action when it gets too high.
10
+ #
11
+ # Maatkit::LoadAvg.new( array, str, array)
12
+ #
13
+ class Maatkit::LoadAvg
14
+
15
+ #
16
+ # group: Action
17
+ # Trigger the actions only when all "--watch" items exceed their thresholds.
18
+ # The default is to trigger the actions when any one of the watched items exceeds its threshold. This
19
+ # option requires that all watched items exceed their thresholds before any action is triggered.
20
+ attr_accessor :and # FALSE
21
+
22
+ #
23
+ # Prompt for a password when connecting to MySQL.
24
+ attr_accessor :ask_pass # FALSE
25
+
26
+ #
27
+ # short form: -A; type: string
28
+ # Default character set. If the value is utf8, sets Perl's binmode on STDOUT to utf8, passes the
29
+ # mysql_enable_utf8 option to DBD::mysql, and runs SET NAMES UTF8 after connecting to MySQL. Any other
30
+ # value sets binmode on STDOUT without the utf8 layer, and runs SET NAMES after connecting to MySQL.
31
+ attr_accessor :charset # (No value)
32
+
33
+ #
34
+ # type: Array
35
+ # Read this comma-separated list of config files; if specified, this must be the first option on the
36
+ # command line.
37
+ attr_accessor :config # /etc/maatkit/maatkit.conf,/etc/maatkit/mk_loadavg.conf,/home/joel/.maatkit.conf,/home/joel/.mk_loadavg.conf
38
+
39
+ #
40
+ # Fork to the background and detach from the shell. POSIX operating systems only.
41
+ attr_accessor :daemonize # FALSE
42
+
43
+ #
44
+ # short form: -D; type: string
45
+ # Database to use.
46
+ attr_accessor :database # (No value)
47
+
48
+ #
49
+ # short form: -F; type: string
50
+ # Only read mysql options from the given file. You must give an absolute pathname.
51
+ attr_accessor :defaults_file # (No value)
52
+
53
+ #
54
+ # type: string; group: Action
55
+ # Execute this command when watched items exceed their threshold values
56
+ # This command will be executed every time a "--watch" item (or all items if "--and" is specified)
57
+ # exceeds its threshold. For example, if you specify "--watch "Server:vmstat:swpd:":0">, then this
58
+ # command will be executed when the server begins to swap and it will be executed again at each
59
+ # "--interval" so long as the server is still swapping.
60
+ # After the command is executed, mk-loadavg has no control over it, so it is responsible for its own info
61
+ # gathering, logging, interval, etc. Since the command is spawned from mk-loadavg, its STDOUT, STDERR
62
+ # and STDIN are closed so it doesn't interfere with mk-loadavg. Therefore, the command must redirect its
63
+ # output to files or some other destination. For example, if you specify "--execute-command 'echo
64
+ # Hello'", you will not see "Hello" printed anywhere (neither to screen nor "--log") because STDOUT is
65
+ # closed for the command.
66
+ # No information from mk-loadavg is passed to the command.
67
+ # See also "--and".
68
+ attr_accessor :execute_command # (No value)
69
+
70
+ #
71
+ # Show help and exit.
72
+ attr_accessor :help # TRUE
73
+
74
+ #
75
+ # short form: -h; type: string
76
+ # Connect to host.
77
+ attr_accessor :host # (No value)
78
+
79
+ #
80
+ # type: time; default: 60s; group: Watch
81
+ # How long to sleep between each check.
82
+ attr_accessor :interval # 60
83
+
84
+ #
85
+ # type: string
86
+ # Print all output to this file when daemonized.
87
+ # Output from "--execute-command" is not printed to this file.
88
+ attr_accessor :log # (No value)
89
+
90
+ #
91
+ # short form: -p; type: string
92
+ # Password to use when connecting.
93
+ attr_accessor :password # (No value)
94
+
95
+ #
96
+ # type: string
97
+ # Create the given PID file when daemonized. The file contains the process ID of the daemonized
98
+ # instance. The PID file is removed when the daemonized instance exits. The program checks for the
99
+ # existence of the PID file when starting; if it exists and the process with the matching PID exists, the
100
+ # program exits.
101
+ attr_accessor :pid # (No value)
102
+
103
+ #
104
+ # short form: -P; type: int
105
+ # Port number to use for connection.
106
+ attr_accessor :port # (No value)
107
+
108
+ #
109
+ # type: time
110
+ # Time to run before exiting.
111
+ # Causes "mk-loadavg" to stop after the specified time has elapsed. Optional suffix: s=seconds,
112
+ # m=minutes, h=hours, d=days; if no suffix, s is used.
113
+ attr_accessor :run_time # (No value)
114
+
115
+ #
116
+ # type: string; default: /tmp/mk-loadavg-sentinel
117
+ # Exit if this file exists.
118
+ attr_accessor :sentinel # /tmp/mk_loadavg_sentinel
119
+
120
+ #
121
+ # type: string; default: wait_timeout=10000
122
+ # Set these MySQL variables. Immediately after connecting to MySQL, this string will be appended to SET
123
+ # and executed.
124
+ attr_accessor :set_vars # wait_timeout=10000
125
+
126
+ #
127
+ # short form: -S; type: string
128
+ # Socket file to use for connection.
129
+ attr_accessor :socket # (No value)
130
+
131
+ #
132
+ # Stop running instances by creating the "--sentinel" file.
133
+ attr_accessor :stop # FALSE
134
+
135
+ #
136
+ # short form: -u; type: string
137
+ # User for login if not current user.
138
+ attr_accessor :user # (No value)
139
+
140
+ #
141
+ # short form: -v
142
+ # Print information to STDOUT about what is being done.
143
+ # This can be used as a heartbeat to see that mk-loadavg is still properly watching all its values. If
144
+ # "--log" is specified, this information will be printed to that file instead.
145
+ attr_accessor :verbose # FALSE
146
+
147
+ #
148
+ # Show version and exit.
149
+ attr_accessor :version # FALSE
150
+
151
+ #
152
+ # type: string; default: vmstat 1 2; group: Watch
153
+ # vmstat command for "--watch" Server:vmstat:...
154
+ # The vmstat output should look like:
155
+ # procs -----------memory---------- ---swap-- -----io---- -system-- ----cpu----
156
+ # r b # swpd # free # buff cache # si # so # bi # bo # in # cs us sy id wa
157
+ # 0 0 # # 0 590380 143756 571852 # 0 # 0 # 6 # 9 228 340 4 1 94 1
158
+ # 0 0 # # 0 590400 143764 571852 # 0 # 0 # 0 # 28 751 818 4 2 90 3
159
+ # The second line from the top needs to be column headers for subsequent lines. Values are taken from
160
+ # the last line.
161
+ # The default, "vmstat 1 2", gets current values. Running just "vmstat" would get average values since
162
+ # last reboot.
163
+ attr_accessor :vmstat # vmstat # 1 # 2
164
+
165
+ #
166
+ # type: time; default: 60s
167
+ # Wait this long to reconnect to MySQL.
168
+ # If the MySQL server goes away between "--interval" checks, mk-loadavg will attempt to reconnect to
169
+ # MySQL forever, sleeping this amount of time in between attempts.
170
+ attr_accessor :wait # 60
171
+
172
+ #
173
+ # type: string; group: Watch
174
+ # A comma-separated list of watched items and their thresholds (required).
175
+ # Each watched item is string of arguments separated by colons (like arg:arg). Each argument defines the
176
+ # watch item: what particular value is watched and how to compare the current value to a threshold value
177
+ # (N). Multiple watched items can be given by separating them with a comma, and the same watched item
178
+ # can be given multiple times (but, of course, it only makes sense to do this if the comparison and/or
179
+ # threshold values are differnt).
180
+ # The first argument is the most important and is case-sensitive. It defines the module responsible for
181
+ # watching the value. For example,
182
+ # --watch Status:...
183
+ # causes the WatchStatus module to be loaded. The second and subsequent arguments are passed to the
184
+ # WatchStatus module which parses them. Each watch module requires different arguments. The watch
185
+ # modules included in mk-loadavg and what arguments they require are listed below.
186
+ # This is a common error when specifying "--watch" on the commnad line:
187
+ # # mk-loadavg --watch Server:vmstat:swpd:>:0
188
+ # # Failed to load --watch WatchServer: Error parsing parameters vmstat:swpd:: No comparison parameter; expected >, < or = at ./mk-loadavg line 3100.
189
+ # The "--watch" values need to be quoted:
190
+ # # mk-loadavg --watch "Server:vmstat:swpd:>:0"
191
+ # Status
192
+ # # Watch SHOW STATUS, SHOW INNODB STATUS, and SHOW SLAVE STATUS values. The value argument is case-
193
+ # # sensitive.
194
+ # # # --watch Status:[status|innodb|slave]:value:[><=]:N
195
+ # # Examples:
196
+ # # # --watch "Status:status:Threads_connected:>:16"
197
+ # # # --watch "Status:innodb:Innodb_buffer_pool_hit_rate:<:0.98"
198
+ # # # --watch "Status:slave:Seconds_behind_master:>:300"
199
+ # # You can easily see what values are available for SHOW STATUS and SHOW SLAVE STATUS, but the values
200
+ # # for SHOW INNODB STATUS are not apparent. Some common values are:
201
+ # # # Innodb_buffer_pool_hit_rate
202
+ # # # Innodb_buffer_pool_pages_created_sec
203
+ # # # Innodb_buffer_pool_pages_dirty
204
+ # # # Innodb_buffer_pool_pages_read_sec
205
+ # # # Innodb_buffer_pool_pages_written_sec
206
+ # # # Innodb_buffer_pool_pending_data_writes
207
+ # # # Innodb_buffer_pool_pending_dirty_writes
208
+ # # # Innodb_buffer_pool_pending_fsyncs
209
+ # # # Innodb_buffer_pool_pending_reads
210
+ # # # Innodb_buffer_pool_pending_single_writes
211
+ # # # Innodb_common_memory_allocated
212
+ # # # Innodb_data_fsyncs_sec
213
+ # # # Innodb_data_pending_fsyncs
214
+ # # # Innodb_data_pending_preads
215
+ # # # Innodb_data_pending_pwrites
216
+ # # # Innodb_data_reads_sec
217
+ # # # Innodb_data_writes_sec
218
+ # # # Innodb_insert_buffer_pending_reads
219
+ # # # Innodb_rows_read_sec
220
+ # # # Innodb_rows_updated_sec
221
+ # # # lock_wait_time
222
+ # # # mysql_tables_locked
223
+ # # # mysql_tables_used
224
+ # # # row_locks
225
+ # # # io_avg_wait
226
+ # # # io_wait
227
+ # # # max_io_wait
228
+ # # Several of those values can appear multiple times in the SHOW INNODB STATUS output. The value used
229
+ # # for comparison is always the higest value. So the value for io_wait is the highest io_wait value
230
+ # # for all the IO threads.
231
+ # Processlist
232
+ # # Watch aggregated SHOW PROCESSLIST values.
233
+ # # # --watch Processlist:[db|user|host|state|command]:value:[count|time]:[><=]:N
234
+ # # Examples:
235
+ # # # --watch "Processlist:state:Locked:count:>:5"
236
+ # # # --watch "Processlist:command:Query:time:<:1"
237
+ # Server
238
+ # # Watch server values.
239
+ # # # --watch Server:loadavg:[1|5|15]:[><=]:N
240
+ # # # --watch Server:vmstat:[r|b|swpd|free|buff|cache|si|so|bi|bo|in|cs|us|sy|id|wa]:[><=]:N
241
+ # # Examples:
242
+ # # # --watch "Server:loadavg:5:>:4.00"
243
+ # # # --watch "Server:vmstat:swpd:>:0"
244
+ # # # --watch "Server:vmstat:free:=:0"
245
+ # # See "--vmstat".
246
+ attr_accessor :watch # (No value)
247
+
248
+ #
249
+ # Sets the executable path, otherwise the environment path will be used.
250
+ #
251
+ attr_accessor :path_to_mk_loadavg
252
+
253
+ #
254
+ # Returns a new LoadAvg Object
255
+ #
256
+ def initialize()
257
+ end
258
+
259
+ #
260
+ # Execute the command
261
+ #
262
+ def start(options = nil)
263
+ tmp = Tempfile.new('tmp')
264
+ command = option_string() + options.to_s + " 2> " + tmp.path
265
+ success = system(command)
266
+ if success
267
+ begin
268
+ while (line = tmp.readline)
269
+ line.chomp
270
+ selected_string = line
271
+ end
272
+ rescue EOFError
273
+ tmp.close
274
+ end
275
+ return selected_string
276
+ else
277
+ tmp.close!
278
+ return success
279
+ end
280
+ end
281
+
282
+ def config
283
+ option_string()
284
+ end
285
+
286
+ private
287
+
288
+ def option_string()
289
+
290
+ unless @path_to_mk_loadavg
291
+ ostring = "mk-loadavg "
292
+ else
293
+ ostring = @path_to_mk_loadavg + " "
294
+ end
295
+
296
+ self.instance_variables.each do |i|
297
+ tmp_value = self.instance_variable_get "#{i}"
298
+ tmp_string = i.gsub("_", "-").gsub("@", "--")
299
+ unless tmp_string == "--path-to-mk-loadavg"
300
+ if (tmp_value.is_a? TrueClass) || (tmp_value.is_a? FalseClass)
301
+ ostring += "#{tmp_string} "
302
+ else
303
+ ostring += "#{tmp_string} #{tmp_value} "
304
+ end
305
+ end
306
+ end
307
+
308
+ return ostring
309
+
310
+ end
311
+
312
+ end
313
+
@@ -0,0 +1,316 @@
1
+ # = maatkit-ruby - A maatkit gem for Ruby
2
+ #
3
+ # Homepage:: http://github.com/jjuliano/maatkit-ruby
4
+ # Author:: Joel Bryan Juliano
5
+ # Copyright:: (cc) 2011 Joel Bryan Juliano
6
+ # License:: MIT
7
+
8
+ #
9
+ # Replay MySQL query logs.
10
+ #
11
+ # Maatkit::LogPlayer.new( array, str, array)
12
+ #
13
+ class Maatkit::LogPlayer
14
+
15
+ #
16
+ # group: Play
17
+ # Prompt for a password when connecting to MySQL.
18
+ attr_accessor :ask_pass # FALSE
19
+
20
+ #
21
+ # type: string; default: ./
22
+ # Base directory for "--split" session files and "--play" result file.
23
+ attr_accessor :base_dir # ./
24
+
25
+ #
26
+ # type: string; default: session
27
+ # Base file name for "--split" session files and "--play" result file.
28
+ # Each "--split" session file will be saved as <base-file-name>-N.txt, where N is a four digit, zero-
29
+ # padded session ID. For example: session-0003.txt.
30
+ # Each "--play" result file will be saved as <base-file-name>-results-PID.txt, where PID is the process
31
+ # ID of the executing thread.
32
+ # All files are saved in "--base-dir".
33
+ attr_accessor :base_file_name # session
34
+
35
+ #
36
+ # group: Play
37
+ # short form: -A; type: string
38
+ # Default character set. If the value is utf8, sets Perl's binmode on STDOUT to utf8, passes the
39
+ # mysql_enable_utf8 option to DBD::mysql, and runs SET NAMES UTF8 after connecting to MySQL. Any other
40
+ # value sets binmode on STDOUT without the utf8 layer, and runs SET NAMES after connecting to MySQL.
41
+ attr_accessor :charset # FALSE
42
+
43
+ #
44
+ # type: Array
45
+ # Read this comma-separated list of config files; if specified, this must be the first option on the
46
+ # command line.
47
+ attr_accessor :config # /etc/maatkit/maatkit.conf,/etc/maatkit/mk_log_player.conf,/home/joel/.maatkit.conf,/home/joel/.mk_log_player.conf
48
+
49
+ #
50
+ # short form: -F; type: string
51
+ # Only read mysql options from the given file.
52
+ attr_accessor :defaults_file # (No # value)
53
+
54
+ #
55
+ # Print which processes play which session files then exit.
56
+ attr_accessor :dry_run # FALSE
57
+
58
+ #
59
+ # type: string; group: Split
60
+ # Discard "--split" events for which this Perl code doesn't return true.
61
+ # This option only works with "--split".
62
+ # This option is a string of Perl code or a file containing Perl code that gets compiled into a
63
+ # subroutine with one argument: $event. This is a hashref. If the given value is a readable file, then
64
+ # mk-log-player reads the entire file and uses its contents as the code. The file should not contain a
65
+ # shebang (#!/usr/bin/perl) line.
66
+ # If the code returns true, the query is split; otherwise it is discarded. The code is the last
67
+ # statement in the subroutine other than "return $event". The subroutine template is:
68
+ # sub { $event = shift; filter && return $event; }
69
+ # Filters given on the command line are wrapped inside parentheses like like "( filter )". For complex,
70
+ # multi-line filters, you must put the code inside a file so it will not be wrapped inside parentheses.
71
+ # Either way, the filter must produce syntactically valid code given the template. For example, an if-
72
+ # else branch given on the command line would not be valid:
73
+ # --filter 'if () { } else { }' # WRONG
74
+ # Since it's given on the command line, the if-else branch would be wrapped inside parentheses which is
75
+ # not syntactically valid. So to accomplish something more complex like this would require putting the
76
+ # code in a file, for example filter.txt:
77
+ # my $event_ok; if (...) { $event_ok=1; } else { $event_ok=0; } $event_ok
78
+ # Then specify "--filter filter.txt" to read the code from filter.txt.
79
+ # If the filter code won't compile, mk-log-player will die with an error. If the filter code does
80
+ # compile, an error may still occur at runtime if the code tries to do something wrong (like pattern
81
+ # match an undefined value). mk-log-player does not provide any safeguards so code carefully!
82
+ # An example filter that discards everything but SELECT statements:
83
+ # --filter '$event->{arg} =~ m/^select/i'
84
+ # This is compiled into a subroutine like the following:
85
+ # sub { $event = shift; ( $event->{arg} =~ m/^select/i ) && return $event; }
86
+ # You can find an explanation of the structure of $event at
87
+ # <http://code.google.com/p/maatkit/wiki/EventAttributes>.
88
+ attr_accessor :filter # (No # value)
89
+
90
+ #
91
+ # Show help and exit.
92
+ attr_accessor :help # TRUE
93
+
94
+ #
95
+ # short form: -h; type: string; group: Play
96
+ # Connect to host.
97
+ attr_accessor :host # (No # value)
98
+
99
+ #
100
+ # type: int; default: 1; group: Play
101
+ # How many times each thread should play all its session files.
102
+ attr_accessor :iterations # 1
103
+
104
+ #
105
+ # type: int; default: 5000000; group: Split
106
+ # Maximum number of sessions to "--split".
107
+ # By default, "mk-log-player" tries to split every session from the log file. For huge logs, however,
108
+ # this can result in millions of sessions. This option causes only the first N number of sessions to be
109
+ # saved. All sessions after this number are ignored, but sessions split before this number will continue
110
+ # to have their queries split even if those queries appear near the end of the log and after this number
111
+ # has been reached.
112
+ attr_accessor :max_sessions # 5000000
113
+
114
+ #
115
+ # group: Play
116
+ # Play only SELECT and USE queries; ignore all others.
117
+ attr_accessor :only_select # FALSE
118
+
119
+ #
120
+ # short form: -p; type: string; group: Play
121
+ # Password to use when connecting.
122
+ attr_accessor :password # (No # value)
123
+
124
+ #
125
+ # type: string
126
+ # Create the given PID file. The file contains the process ID of the script. The PID file is removed
127
+ # when the script exits. Before starting, the script checks if the PID file already exists. If it does
128
+ # not, then the script creates and writes its own PID to it. If it does, then the script checks the
129
+ # following: if the file contains a PID and a process is running with that PID, then the script dies; or,
130
+ # if there is no process running with that PID, then the script overwrites the file with its own PID and
131
+ # starts; else, if the file contains no PID, then the script dies.
132
+ attr_accessor :pid # (No # value)
133
+
134
+ #
135
+ # type: string; group: Play
136
+ # Play (execute) session files created by "--split".
137
+ # The argument to play must be a commaxn-separated list of session files created by "--split" or a
138
+ # directory. If the argument is a directory, ALL files in that directory will be played.
139
+ attr_accessor :play # (No # value)
140
+
141
+ #
142
+ # short form: -P; type: int; group: Play
143
+ # Port number to use for connection.
144
+ attr_accessor :port # (No # value)
145
+
146
+ #
147
+ # group: Play
148
+ # Print queries instead of playing them; requires "--play".
149
+ # You must also specify "--play" with "--print". Although the queries will not be executed, "--play" is
150
+ # required to specify which session files to read.
151
+ attr_accessor :print # FALSE
152
+
153
+ #
154
+ # Do not print anything; disables "--verbose".
155
+ attr_accessor :quiet # FALSE
156
+
157
+ #
158
+ # default: yes
159
+ # Print "--play" results to files in "--base-dir".
160
+ attr_accessor :results # TRUE
161
+
162
+ #
163
+ # type: int; default: 8; group: Split
164
+ # Number of session files to create with "--split".
165
+ # The number of session files should either be equal to the number of "--threads" you intend to "--play"
166
+ # or be an even multiple of "--threads". This number is important for maximum performance because it:
167
+ # * allows each thread to have roughly the same amount of sessions to play
168
+ # * avoids having to open/close many session files
169
+ # * avoids disk IO overhead by doing large sequential reads
170
+ # You may want to increase this number beyond "--threads" if each session file becomes too large. For
171
+ # example, splitting a 20G log into 8 sessions files may yield roughly eight 2G session files.
172
+ # See also "--max-sessions".
173
+ attr_accessor :session_files # 8
174
+
175
+ #
176
+ # type: string; group: Play; default: wait_timeout=10000
177
+ # Set these MySQL variables. Immediately after connecting to MySQL, this string will be appended to SET
178
+ # and executed.
179
+ attr_accessor :set_vars # wait_timeout=10000
180
+
181
+ #
182
+ # short form: -S; type: string; group: Play
183
+ # Socket file to use for connection.
184
+ attr_accessor :socket # (No # value)
185
+
186
+ #
187
+ # type: string; group: Split
188
+ # Split log by given attribute to create session files.
189
+ # Valid attributes are any which appear in the log: Thread_id, Schema, etc.
190
+ attr_accessor :split # (No # value)
191
+
192
+ #
193
+ # group: Split
194
+ # Split log without an attribute, write queries round-robin to session files.
195
+ # This option, if specified, overrides "--split" and causes the log to be split query-by-query, writing
196
+ # each query to the next session file in round-robin style. If you don't care about "sessions" and just
197
+ # want to split a lot into N many session files and the relation or order of the queries does not matter,
198
+ # then use this option.
199
+ attr_accessor :split_random # FALSE
200
+
201
+ #
202
+ # type: int; default: 2; group: Play
203
+ # Number of threads used to play sessions concurrently.
204
+ # Specifies the number of parallel processes to run. The default is 2. On GNU/Linux machines, the
205
+ # default is the number of times 'processor' appears in /proc/cpuinfo. On Windows, the default is read
206
+ # from the environment. In any case, the default is at least 2, even when there's only a single
207
+ # processor.
208
+ # See also "--session-files".
209
+ attr_accessor :threads # 2
210
+
211
+ #
212
+ # type: string; group: Split
213
+ # The type of log to "--split" (default slowlog). The permitted types are
214
+ # binlog
215
+ # # Split a binary log file.
216
+ # genlog
217
+ # # Split a general log file.
218
+ # slowlog
219
+ # # Split a log file in any varation of MySQL slow-log format.
220
+ attr_accessor :type # slowlog
221
+
222
+ #
223
+ # short form: -u; type: string; group: Play
224
+ # User for login if not current user.
225
+ attr_accessor :user # (No # value)
226
+
227
+ #
228
+ # short form: -v; cumulative: yes; default: 0
229
+ # Increase verbosity; can specifiy multiple times.
230
+ # This option is disabled by "--quiet".
231
+ attr_accessor :verbose # 0
232
+
233
+ #
234
+ # Show version and exit.
235
+ attr_accessor :version # FALSE
236
+
237
+ #
238
+ # type: array; default: 0; group: Play
239
+ # Not implemented yet.
240
+ # The wait time is given in seconds with microsecond precision and can be either a single value or a
241
+ # range. A single value causes an exact wait; example: 0.010 = wait 10 milliseconds. A range causes a
242
+ # random wait between the given value times; example: 0.001,1 = random wait from 1 millisecond to 1
243
+ # second.
244
+ attr_accessor :wait_between_sessions # (No # value)
245
+
246
+ #
247
+ # default: no; group: Play
248
+ # Print warnings about SQL errors such as invalid queries to STDERR.
249
+ attr_accessor :warnings # TRUE
250
+
251
+ #
252
+ # Sets the executable path, otherwise the environment path will be used.
253
+ #
254
+ attr_accessor :path_to_mk_log_player
255
+
256
+ #
257
+ # Returns a new LogPlayer Object
258
+ #
259
+ def initialize()
260
+ end
261
+
262
+ #
263
+ # Execute the command
264
+ #
265
+ def start(options = nil)
266
+ tmp = Tempfile.new('tmp')
267
+ command = option_string() + options.to_s + " 2> " + tmp.path
268
+ success = system(command)
269
+ if success
270
+ begin
271
+ while (line = tmp.readline)
272
+ line.chomp
273
+ selected_string = line
274
+ end
275
+ rescue EOFError
276
+ tmp.close
277
+ end
278
+ return selected_string
279
+ else
280
+ tmp.close!
281
+ return success
282
+ end
283
+ end
284
+
285
+ def config
286
+ option_string()
287
+ end
288
+
289
+ private
290
+
291
+ def option_string()
292
+
293
+ unless @path_to_mk_log_player
294
+ ostring = "mk-log-player "
295
+ else
296
+ ostring = @path_to_mk_log_player + " "
297
+ end
298
+
299
+ self.instance_variables.each do |i|
300
+ tmp_value = self.instance_variable_get "#{i}"
301
+ tmp_string = i.gsub("_", "-").gsub("@", "--")
302
+ unless tmp_string == "--path-to-mk-log-player"
303
+ if (tmp_value.is_a? TrueClass) || (tmp_value.is_a? FalseClass)
304
+ ostring += "#{tmp_string} "
305
+ else
306
+ ostring += "#{tmp_string} #{tmp_value} "
307
+ end
308
+ end
309
+ end
310
+
311
+ return ostring
312
+
313
+ end
314
+
315
+ end
316
+