~percona-toolkit-dev/percona-toolkit/fix-password-comma-bug-886077

« back to all changes in this revision

Viewing changes to lib/SlowLogParser.pm

  • Committer: Daniel Nichter
  • Date: 2012-02-07 20:10:11 UTC
  • mfrom: (174 2.0)
  • mto: This revision was merged to the branch mainline in revision 189.
  • Revision ID: daniel@percona.com-20120207201011-sok2c1f2ay9qr3gm
Merge trunk r174.

Show diffs side-by-side

added added

removed removed

Lines of Context:
25
25
use strict;
26
26
use warnings FATAL => 'all';
27
27
use English qw(-no_match_vars);
28
 
use constant MKDEBUG => $ENV{MKDEBUG} || 0;
 
28
use constant PTDEBUG => $ENV{PTDEBUG} || 0;
29
29
 
30
30
use Data::Dumper;
31
31
$Data::Dumper::Indent    = 1;
111
111
      if ( $stmt =~ s/$slow_log_hd_line//go ){ # Throw away header lines in log
112
112
         my @chunks = split(/$INPUT_RECORD_SEPARATOR/o, $stmt);
113
113
         if ( @chunks > 1 ) {
114
 
            MKDEBUG && _d("Found multiple chunks");
 
114
            PTDEBUG && _d("Found multiple chunks");
115
115
            $stmt = shift @chunks;
116
116
            unshift @$pending, @chunks;
117
117
         }
139
139
      while ( $stmt =~ m/^(.*)$/mg ) { # /g is important, requires scalar match.
140
140
         $pos     = pos($stmt);  # Be careful not to mess this up!
141
141
         my $line = $1;          # Necessary for /g and pos() to work.
142
 
         MKDEBUG && _d($line);
 
142
         PTDEBUG && _d($line);
143
143
 
144
144
         # Handle meta-data lines.  These are case-sensitive.  If they appear in
145
145
         # the log with a different case, they are from a user query, not from
152
152
            # construct.  So if this line looks "hot" then profile each
153
153
            # condition separately.
154
154
            if ( !$got_ts && (my ( $time ) = $line =~ m/$slow_log_ts_line/o)) {
155
 
               MKDEBUG && _d("Got ts", $time);
 
155
               PTDEBUG && _d("Got ts", $time);
156
156
               push @properties, 'ts', $time;
157
157
               ++$got_ts;
158
158
               # The User@Host might be concatenated onto the end of the Time.
159
159
               if ( !$got_uh
160
160
                  && ( my ( $user, $host, $ip ) = $line =~ m/$slow_log_uh_line/o )
161
161
               ) {
162
 
                  MKDEBUG && _d("Got user, host, ip", $user, $host, $ip);
 
162
                  PTDEBUG && _d("Got user, host, ip", $user, $host, $ip);
163
163
                  push @properties, 'user', $user, 'host', $host, 'ip', $ip;
164
164
                  ++$got_uh;
165
165
               }
170
170
            elsif ( !$got_uh
171
171
                  && ( my ( $user, $host, $ip ) = $line =~ m/$slow_log_uh_line/o )
172
172
            ) {
173
 
               MKDEBUG && _d("Got user, host, ip", $user, $host, $ip);
 
173
               PTDEBUG && _d("Got user, host, ip", $user, $host, $ip);
174
174
               push @properties, 'user', $user, 'host', $host, 'ip', $ip;
175
175
               ++$got_uh;
176
176
            }
178
178
            # A line that looks like meta-data but is not:
179
179
            # # administrator command: Quit;
180
180
            elsif (!$got_ac && $line =~ m/^# (?:administrator command:.*)$/) {
181
 
               MKDEBUG && _d("Got admin command");
 
181
               PTDEBUG && _d("Got admin command");
182
182
               $line =~ s/^#\s+//;  # string leading "# ".
183
183
               push @properties, 'cmd', 'Admin', 'arg', $line;
184
184
               push @properties, 'bytes', length($properties[-1]);
190
190
            # such as that... they typically look like this:
191
191
            # # Query_time: 2  Lock_time: 0  Rows_sent: 1  Rows_examined: 0
192
192
            elsif ( $line =~ m/^# +[A-Z][A-Za-z_]+: \S+/ ) { # Make the test cheap!
193
 
               MKDEBUG && _d("Got some line with properties");
 
193
               PTDEBUG && _d("Got some line with properties");
194
194
 
195
195
               # http://code.google.com/p/maatkit/issues/detail?id=1104
196
196
               if ( $line =~ m/Schema:\s+\w+: / ) {
197
 
                  MKDEBUG && _d('Removing empty Schema attrib');
 
197
                  PTDEBUG && _d('Removing empty Schema attrib');
198
198
                  $line =~ s/Schema:\s+//;
199
 
                  MKDEBUG && _d($line);
 
199
                  PTDEBUG && _d($line);
200
200
               }
201
201
 
202
202
               # I tried using split, but coping with the above bug makes it
208
208
            # Include the current default database given by 'use <db>;'  Again
209
209
            # as per the code in sql/log.cc this is case-sensitive.
210
210
            elsif ( !$got_db && (my ( $db ) = $line =~ m/^use ([^;]+)/ ) ) {
211
 
               MKDEBUG && _d("Got a default database:", $db);
 
211
               PTDEBUG && _d("Got a default database:", $db);
212
212
               push @properties, 'db', $db;
213
213
               ++$got_db;
214
214
            }
223
223
               # Note: this assumes settings won't be complex things like
224
224
               # SQL_MODE, which as of 5.0.51 appears to be true (see sql/log.cc,
225
225
               # function MYSQL_LOG::write(THD, char*, uint, time_t)).
226
 
               MKDEBUG && _d("Got some setting:", $setting);
 
226
               PTDEBUG && _d("Got some setting:", $setting);
227
227
               push @properties, split(/,|\s*=\s*/, $setting);
228
228
               ++$got_set;
229
229
            }
234
234
            # in $stmt. Profiling shows this is an expensive if() so we do
235
235
            # this only if we've seen the user/host line.
236
236
            if ( !$found_arg && $pos == $len ) {
237
 
               MKDEBUG && _d("Did not find arg, looking for special cases");
 
237
               PTDEBUG && _d("Did not find arg, looking for special cases");
238
238
               local $INPUT_RECORD_SEPARATOR = ";\n";
239
239
               if ( defined(my $l = $next_event->()) ) {
240
240
                  chomp $l;
241
241
                  $l =~ s/^\s+//;
242
 
                  MKDEBUG && _d("Found admin statement", $l);
 
242
                  PTDEBUG && _d("Found admin statement", $l);
243
243
                  push @properties, 'cmd', 'Admin', 'arg', $l;
244
244
                  push @properties, 'bytes', length($properties[-1]);
245
245
                  $found_arg++;
249
249
                  # for example, if someone does something like "head -c 10000
250
250
                  # /path/to/slow.log | mk-log-parser".  Or if there was a
251
251
                  # server crash and the file has no newline.
252
 
                  MKDEBUG && _d("I can't figure out what to do with this line");
 
252
                  PTDEBUG && _d("I can't figure out what to do with this line");
253
253
                  next EVENT;
254
254
               }
255
255
            }
261
261
            # Note that if this line really IS the query but we skip in
262
262
            # the 'if' above because it looks like meta-data, later
263
263
            # we'll remedy that.
264
 
            MKDEBUG && _d("Got the query/arg line");
 
264
            PTDEBUG && _d("Got the query/arg line");
265
265
            my $arg = substr($stmt, $pos - length($line));
266
266
            push @properties, 'arg', $arg, 'bytes', length($arg);
267
267
            # Handle embedded attributes.
276
276
 
277
277
      # Don't dump $event; want to see full dump of all properties, and after
278
278
      # it's been cast into a hash, duplicated keys will be gone.
279
 
      MKDEBUG && _d('Properties of event:', Dumper(\@properties));
 
279
      PTDEBUG && _d('Properties of event:', Dumper(\@properties));
280
280
      my $event = { @properties };
281
281
      if ( $args{stats} ) {
282
282
         $args{stats}->{events_read}++;