Merge lp:~percona-toolkit-dev/percona-toolkit/raw-log-parser-percona-22371 into lp:percona-toolkit/2.1
- raw-log-parser-percona-22371
- Merge into 2.1
Proposed by
Brian Fraser
Status: | Merged |
---|---|
Approved by: | Daniel Nichter |
Approved revision: | 303 |
Merged at revision: | 409 |
Proposed branch: | lp:~percona-toolkit-dev/percona-toolkit/raw-log-parser-percona-22371 |
Merge into: | lp:percona-toolkit/2.1 |
Diff against target: |
390 lines (+339/-1) 6 files modified
bin/pt-query-digest (+82/-1) lib/RawLogParser.pm (+95/-0) t/lib/RawLogParser.t (+52/-0) t/lib/samples/rawlogs/rawlog001.txt (+2/-0) t/pt-query-digest/rawlog_analyses.t (+48/-0) t/pt-query-digest/samples/rawlog001.txt (+60/-0) |
To merge this branch: | bzr merge lp:~percona-toolkit-dev/percona-toolkit/raw-log-parser-percona-22371 |
Related bugs: |
Reviewer | Review Type | Date Requested | Status |
---|---|---|---|
Brian Fraser (community) | Approve | ||
Daniel Nichter | Approve | ||
Review via email:
|
Commit message
Description of the change
To post a comment you must log in.
Revision history for this message
![](/+icing/build/overlay/assets/skins/sam/images/close.gif)
Daniel Nichter (daniel-nichter) wrote : | # |
Revision history for this message
![](/+icing/build/overlay/assets/skins/sam/images/close.gif)
Daniel Nichter (daniel-nichter) : | # |
review:
Approve
Revision history for this message
![](/+icing/build/overlay/assets/skins/sam/images/close.gif)
Brian Fraser (fraserbn) : | # |
review:
Approve
Preview Diff
[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1 | === modified file 'bin/pt-query-digest' | |||
2 | --- bin/pt-query-digest 2012-09-24 19:24:36 +0000 | |||
3 | +++ bin/pt-query-digest 2012-10-01 14:30:45 +0000 | |||
4 | @@ -9757,6 +9757,86 @@ | |||
5 | 9757 | # ########################################################################### | 9757 | # ########################################################################### |
6 | 9758 | 9758 | ||
7 | 9759 | # ########################################################################### | 9759 | # ########################################################################### |
8 | 9760 | # RawLogParser package | ||
9 | 9761 | # This package is a copy without comments from the original. The original | ||
10 | 9762 | # with comments and its test file can be found in the Bazaar repository at, | ||
11 | 9763 | # lib/RawLogParser.pm | ||
12 | 9764 | # t/lib/RawLogParser.t | ||
13 | 9765 | # See https://launchpad.net/percona-toolkit for more information. | ||
14 | 9766 | # ########################################################################### | ||
15 | 9767 | { | ||
16 | 9768 | package RawLogParser; | ||
17 | 9769 | |||
18 | 9770 | use strict; | ||
19 | 9771 | use warnings FATAL => 'all'; | ||
20 | 9772 | use English qw(-no_match_vars); | ||
21 | 9773 | use constant PTDEBUG => $ENV{PTDEBUG} || 0; | ||
22 | 9774 | |||
23 | 9775 | use Data::Dumper; | ||
24 | 9776 | $Data::Dumper::Indent = 1; | ||
25 | 9777 | $Data::Dumper::Sortkeys = 1; | ||
26 | 9778 | $Data::Dumper::Quotekeys = 0; | ||
27 | 9779 | |||
28 | 9780 | sub new { | ||
29 | 9781 | my ( $class ) = @_; | ||
30 | 9782 | my $self = { | ||
31 | 9783 | }; | ||
32 | 9784 | return bless $self, $class; | ||
33 | 9785 | } | ||
34 | 9786 | |||
35 | 9787 | sub parse_event { | ||
36 | 9788 | my ( $self, %args ) = @_; | ||
37 | 9789 | my @required_args = qw(next_event tell); | ||
38 | 9790 | foreach my $arg ( @required_args ) { | ||
39 | 9791 | die "I need a $arg argument" unless $args{$arg}; | ||
40 | 9792 | } | ||
41 | 9793 | my ($next_event, $tell) = @args{@required_args}; | ||
42 | 9794 | |||
43 | 9795 | my $line; | ||
44 | 9796 | my $pos_in_log = $tell->(); | ||
45 | 9797 | LINE: | ||
46 | 9798 | while ( defined($line = $next_event->()) ) { | ||
47 | 9799 | PTDEBUG && _d($line); | ||
48 | 9800 | chomp($line); | ||
49 | 9801 | my @properties = ( | ||
50 | 9802 | 'pos_in_log', $pos_in_log, | ||
51 | 9803 | 'cmd', 'Query', | ||
52 | 9804 | 'bytes', length($line), | ||
53 | 9805 | 'Query_time', 0, | ||
54 | 9806 | 'arg', $line, | ||
55 | 9807 | ); | ||
56 | 9808 | |||
57 | 9809 | $pos_in_log = $tell->(); | ||
58 | 9810 | |||
59 | 9811 | PTDEBUG && _d('Properties of event:', Dumper(\@properties)); | ||
60 | 9812 | my $event = { @properties }; | ||
61 | 9813 | if ( $args{stats} ) { | ||
62 | 9814 | $args{stats}->{events_read}++; | ||
63 | 9815 | $args{stats}->{events_parsed}++; | ||
64 | 9816 | } | ||
65 | 9817 | |||
66 | 9818 | return $event; | ||
67 | 9819 | } | ||
68 | 9820 | |||
69 | 9821 | $args{oktorun}->(0) if $args{oktorun}; | ||
70 | 9822 | return; | ||
71 | 9823 | } | ||
72 | 9824 | |||
73 | 9825 | sub _d { | ||
74 | 9826 | my ($package, undef, $line) = caller 0; | ||
75 | 9827 | @_ = map { (my $temp = $_) =~ s/\n/\n# /g; $temp; } | ||
76 | 9828 | map { defined $_ ? $_ : 'undef' } | ||
77 | 9829 | @_; | ||
78 | 9830 | print STDERR "# $package:$line $PID ", join(' ', @_), "\n"; | ||
79 | 9831 | } | ||
80 | 9832 | |||
81 | 9833 | 1; | ||
82 | 9834 | } | ||
83 | 9835 | # ########################################################################### | ||
84 | 9836 | # End RawLogParser package | ||
85 | 9837 | # ########################################################################### | ||
86 | 9838 | |||
87 | 9839 | # ########################################################################### | ||
88 | 9760 | # ProtocolParser package | 9840 | # ProtocolParser package |
89 | 9761 | # This package is a copy without comments from the original. The original | 9841 | # This package is a copy without comments from the original. The original |
90 | 9762 | # with comments and its test file can be found in the Bazaar repository at, | 9842 | # with comments and its test file can be found in the Bazaar repository at, |
91 | @@ -13227,7 +13307,7 @@ | |||
92 | 13227 | my $review_dsn = $o->get('review'); | 13307 | my $review_dsn = $o->get('review'); |
93 | 13228 | my @groupby = @{$o->get('group-by')}; | 13308 | my @groupby = @{$o->get('group-by')}; |
94 | 13229 | my @orderby; | 13309 | my @orderby; |
96 | 13230 | if ( (grep { $_ eq 'genlog' || $_ eq 'GeneralLogParser' } @{$o->get('type')}) | 13310 | if ( (grep { $_ =~ m/genlog|GeneralLogParser|rawlog|RawLogParser/ } @{$o->get('type')}) |
97 | 13231 | && !$o->got('order-by') ) { | 13311 | && !$o->got('order-by') ) { |
98 | 13232 | @orderby = 'Query_time:cnt'; | 13312 | @orderby = 'Query_time:cnt'; |
99 | 13233 | } | 13313 | } |
100 | @@ -13668,6 +13748,7 @@ | |||
101 | 13668 | 'MemcachedEvent'], | 13748 | 'MemcachedEvent'], |
102 | 13669 | http => ['TcpdumpParser','HTTPProtocolParser'], | 13749 | http => ['TcpdumpParser','HTTPProtocolParser'], |
103 | 13670 | pglog => ['PgLogParser'], | 13750 | pglog => ['PgLogParser'], |
104 | 13751 | rawlog => ['RawLogParser'], | ||
105 | 13671 | ); | 13752 | ); |
106 | 13672 | my $type = $o->get('type'); | 13753 | my $type = $o->get('type'); |
107 | 13673 | $type = $alias_for{$type->[0]} if $alias_for{$type->[0]}; | 13754 | $type = $alias_for{$type->[0]} if $alias_for{$type->[0]}; |
108 | 13674 | 13755 | ||
109 | === added file 'lib/RawLogParser.pm' | |||
110 | --- lib/RawLogParser.pm 1970-01-01 00:00:00 +0000 | |||
111 | +++ lib/RawLogParser.pm 2012-10-01 14:30:45 +0000 | |||
112 | @@ -0,0 +1,95 @@ | |||
113 | 1 | # This program is copyright 2012 Percona Inc. | ||
114 | 2 | # Feedback and improvements are welcome. | ||
115 | 3 | # | ||
116 | 4 | # THIS PROGRAM IS PROVIDED "AS IS" AND WITHOUT ANY EXPRESS OR IMPLIED | ||
117 | 5 | # WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF | ||
118 | 6 | # MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. | ||
119 | 7 | # | ||
120 | 8 | # This program is free software; you can redistribute it and/or modify it under | ||
121 | 9 | # the terms of the GNU General Public License as published by the Free Software | ||
122 | 10 | # Foundation, version 2; OR the Perl Artistic License. On UNIX and similar | ||
123 | 11 | # systems, you can issue `man perlgpl' or `man perlartistic' to read these | ||
124 | 12 | # licenses. | ||
125 | 13 | # | ||
126 | 14 | # You should have received a copy of the GNU General Public License along with | ||
127 | 15 | # this program; if not, write to the Free Software Foundation, Inc., 59 Temple | ||
128 | 16 | # Place, Suite 330, Boston, MA 02111-1307 USA. | ||
129 | 17 | # ########################################################################### | ||
130 | 18 | # RawLogParser package | ||
131 | 19 | # ########################################################################### | ||
132 | 20 | { | ||
133 | 21 | # Package: RawLogParser | ||
134 | 22 | # RawLogParser parses logs with nothing but one query per line. | ||
135 | 23 | package RawLogParser; | ||
136 | 24 | |||
137 | 25 | use strict; | ||
138 | 26 | use warnings FATAL => 'all'; | ||
139 | 27 | use English qw(-no_match_vars); | ||
140 | 28 | use constant PTDEBUG => $ENV{PTDEBUG} || 0; | ||
141 | 29 | |||
142 | 30 | use Data::Dumper; | ||
143 | 31 | $Data::Dumper::Indent = 1; | ||
144 | 32 | $Data::Dumper::Sortkeys = 1; | ||
145 | 33 | $Data::Dumper::Quotekeys = 0; | ||
146 | 34 | |||
147 | 35 | sub new { | ||
148 | 36 | my ( $class ) = @_; | ||
149 | 37 | my $self = { | ||
150 | 38 | }; | ||
151 | 39 | return bless $self, $class; | ||
152 | 40 | } | ||
153 | 41 | |||
154 | 42 | sub parse_event { | ||
155 | 43 | my ( $self, %args ) = @_; | ||
156 | 44 | my @required_args = qw(next_event tell); | ||
157 | 45 | foreach my $arg ( @required_args ) { | ||
158 | 46 | die "I need a $arg argument" unless $args{$arg}; | ||
159 | 47 | } | ||
160 | 48 | my ($next_event, $tell) = @args{@required_args}; | ||
161 | 49 | |||
162 | 50 | my $line; | ||
163 | 51 | my $pos_in_log = $tell->(); | ||
164 | 52 | LINE: | ||
165 | 53 | while ( defined($line = $next_event->()) ) { | ||
166 | 54 | PTDEBUG && _d($line); | ||
167 | 55 | chomp($line); | ||
168 | 56 | my @properties = ( | ||
169 | 57 | 'pos_in_log', $pos_in_log, | ||
170 | 58 | 'cmd', 'Query', | ||
171 | 59 | 'bytes', length($line), | ||
172 | 60 | 'Query_time', 0, | ||
173 | 61 | 'arg', $line, | ||
174 | 62 | ); | ||
175 | 63 | |||
176 | 64 | $pos_in_log = $tell->(); | ||
177 | 65 | |||
178 | 66 | # Don't dump $event; want to see full dump of all properties, | ||
179 | 67 | # and after it's been cast into a hash, duplicated keys will | ||
180 | 68 | # be gone. | ||
181 | 69 | PTDEBUG && _d('Properties of event:', Dumper(\@properties)); | ||
182 | 70 | my $event = { @properties }; | ||
183 | 71 | if ( $args{stats} ) { | ||
184 | 72 | $args{stats}->{events_read}++; | ||
185 | 73 | $args{stats}->{events_parsed}++; | ||
186 | 74 | } | ||
187 | 75 | |||
188 | 76 | return $event; | ||
189 | 77 | } | ||
190 | 78 | |||
191 | 79 | $args{oktorun}->(0) if $args{oktorun}; | ||
192 | 80 | return; | ||
193 | 81 | } | ||
194 | 82 | |||
195 | 83 | sub _d { | ||
196 | 84 | my ($package, undef, $line) = caller 0; | ||
197 | 85 | @_ = map { (my $temp = $_) =~ s/\n/\n# /g; $temp; } | ||
198 | 86 | map { defined $_ ? $_ : 'undef' } | ||
199 | 87 | @_; | ||
200 | 88 | print STDERR "# $package:$line $PID ", join(' ', @_), "\n"; | ||
201 | 89 | } | ||
202 | 90 | |||
203 | 91 | 1; | ||
204 | 92 | } | ||
205 | 93 | # ########################################################################### | ||
206 | 94 | # End RawLogParser package | ||
207 | 95 | # ########################################################################### | ||
208 | 0 | 96 | ||
209 | === added file 't/lib/RawLogParser.t' | |||
210 | --- t/lib/RawLogParser.t 1970-01-01 00:00:00 +0000 | |||
211 | +++ t/lib/RawLogParser.t 2012-10-01 14:30:45 +0000 | |||
212 | @@ -0,0 +1,52 @@ | |||
213 | 1 | #!/usr/bin/perl | ||
214 | 2 | |||
215 | 3 | BEGIN { | ||
216 | 4 | die "The PERCONA_TOOLKIT_BRANCH environment variable is not set.\n" | ||
217 | 5 | unless $ENV{PERCONA_TOOLKIT_BRANCH} && -d $ENV{PERCONA_TOOLKIT_BRANCH}; | ||
218 | 6 | unshift @INC, "$ENV{PERCONA_TOOLKIT_BRANCH}/lib"; | ||
219 | 7 | }; | ||
220 | 8 | |||
221 | 9 | use strict; | ||
222 | 10 | use warnings FATAL => 'all'; | ||
223 | 11 | use English qw(-no_match_vars); | ||
224 | 12 | use Test::More tests => 3; | ||
225 | 13 | |||
226 | 14 | use RawLogParser; | ||
227 | 15 | use PerconaTest; | ||
228 | 16 | |||
229 | 17 | my $p = new RawLogParser(); | ||
230 | 18 | |||
231 | 19 | my $oktorun = 1; | ||
232 | 20 | my $sample = "t/lib/samples/rawlogs/"; | ||
233 | 21 | |||
234 | 22 | test_log_parser( | ||
235 | 23 | parser => $p, | ||
236 | 24 | file => $sample.'rawlog001.txt', | ||
237 | 25 | oktorun => sub { $oktorun = $_[0]; }, | ||
238 | 26 | result => [ | ||
239 | 27 | { pos_in_log => 0, | ||
240 | 28 | args => 'SELECT c FROM t WHERE id=1', | ||
241 | 29 | bytes => 26, | ||
242 | 30 | cmd => 'Query', | ||
243 | 31 | Query_time => 0, | ||
244 | 32 | }, | ||
245 | 33 | { pos_in_log => 27, | ||
246 | 34 | args => '/* Hello, world! */ SELECT * FROM t2 LIMIT 1', | ||
247 | 35 | bytes => 44, | ||
248 | 36 | cmd => 'Query', | ||
249 | 37 | Query_time => 0, | ||
250 | 38 | } | ||
251 | 39 | ] | ||
252 | 40 | ); | ||
253 | 41 | |||
254 | 42 | is( | ||
255 | 43 | $oktorun, | ||
256 | 44 | 0, | ||
257 | 45 | 'Sets oktorun' | ||
258 | 46 | ); | ||
259 | 47 | $oktorun = 1; | ||
260 | 48 | |||
261 | 49 | # ############################################################################# | ||
262 | 50 | # Done. | ||
263 | 51 | # ############################################################################# | ||
264 | 52 | exit; | ||
265 | 0 | 53 | ||
266 | === added directory 't/lib/samples/rawlogs' | |||
267 | === added file 't/lib/samples/rawlogs/rawlog001.txt' | |||
268 | --- t/lib/samples/rawlogs/rawlog001.txt 1970-01-01 00:00:00 +0000 | |||
269 | +++ t/lib/samples/rawlogs/rawlog001.txt 2012-10-01 14:30:45 +0000 | |||
270 | @@ -0,0 +1,2 @@ | |||
271 | 1 | SELECT c FROM t WHERE id=1 | ||
272 | 2 | /* Hello, world! */ SELECT * FROM t2 LIMIT 1 | ||
273 | 0 | 3 | ||
274 | === added file 't/pt-query-digest/rawlog_analyses.t' | |||
275 | --- t/pt-query-digest/rawlog_analyses.t 1970-01-01 00:00:00 +0000 | |||
276 | +++ t/pt-query-digest/rawlog_analyses.t 2012-10-01 14:30:45 +0000 | |||
277 | @@ -0,0 +1,48 @@ | |||
278 | 1 | #!/usr/bin/env perl | ||
279 | 2 | |||
280 | 3 | BEGIN { | ||
281 | 4 | die "The PERCONA_TOOLKIT_BRANCH environment variable is not set.\n" | ||
282 | 5 | unless $ENV{PERCONA_TOOLKIT_BRANCH} && -d $ENV{PERCONA_TOOLKIT_BRANCH}; | ||
283 | 6 | unshift @INC, "$ENV{PERCONA_TOOLKIT_BRANCH}/lib"; | ||
284 | 7 | }; | ||
285 | 8 | |||
286 | 9 | use strict; | ||
287 | 10 | use warnings FATAL => 'all'; | ||
288 | 11 | use English qw(-no_match_vars); | ||
289 | 12 | use Test::More tests => 2; | ||
290 | 13 | |||
291 | 14 | use PerconaTest; | ||
292 | 15 | |||
293 | 16 | # See 101_slowlog_analyses.t or http://code.google.com/p/maatkit/wiki/Testing | ||
294 | 17 | shift @INC; # our unshift (above) | ||
295 | 18 | shift @INC; # PerconaTest's unshift | ||
296 | 19 | |||
297 | 20 | require "$trunk/bin/pt-query-digest"; | ||
298 | 21 | |||
299 | 22 | # ############################################################################# | ||
300 | 23 | # Issue 172: Make mk-query-digest able to read raweral logs | ||
301 | 24 | # ############################################################################# | ||
302 | 25 | |||
303 | 26 | my @args = ('--report-format', 'header,query_report,profile', '--type', 'rawlog'); | ||
304 | 27 | my $sample = "$trunk/t/lib/samples/rawlogs/"; | ||
305 | 28 | |||
306 | 29 | # --help exists so don't run mqd as a module else --help's exit will | ||
307 | 30 | # exit this test script. | ||
308 | 31 | like( | ||
309 | 32 | `$trunk/bin/pt-query-digest --type rawlog rawlog001.txt --help`, | ||
310 | 33 | qr/--order-by\s+Query_time:cnt/, | ||
311 | 34 | '--order-by defaults to Query_time:cnt for --type rawlog', | ||
312 | 35 | ); | ||
313 | 36 | |||
314 | 37 | ok( | ||
315 | 38 | no_diff( | ||
316 | 39 | sub { pt_query_digest::main(@args, $sample.'rawlog001.txt') }, | ||
317 | 40 | "t/pt-query-digest/samples/rawlog001.txt" | ||
318 | 41 | ), | ||
319 | 42 | 'Analysis for rawlog001', | ||
320 | 43 | ); | ||
321 | 44 | |||
322 | 45 | # ############################################################################# | ||
323 | 46 | # Done. | ||
324 | 47 | # ############################################################################# | ||
325 | 48 | exit; | ||
326 | 0 | 49 | ||
327 | === added file 't/pt-query-digest/samples/rawlog001.txt' | |||
328 | --- t/pt-query-digest/samples/rawlog001.txt 1970-01-01 00:00:00 +0000 | |||
329 | +++ t/pt-query-digest/samples/rawlog001.txt 2012-10-01 14:30:45 +0000 | |||
330 | @@ -0,0 +1,60 @@ | |||
331 | 1 | |||
332 | 2 | # Overall: 2 total, 2 unique, 0 QPS, 0x concurrency ______________________ | ||
333 | 3 | # Attribute total min max avg 95% stddev median | ||
334 | 4 | # ============ ======= ======= ======= ======= ======= ======= ======= | ||
335 | 5 | # Exec time 0 0 0 0 0 0 0 | ||
336 | 6 | # Query size 70 26 44 35 44 12.73 35 | ||
337 | 7 | |||
338 | 8 | # Query 1: 0 QPS, 0x concurrency, ID 0xCB5621E548E5497F at byte 0 ________ | ||
339 | 9 | # This item is included in the report because it matches --limit. | ||
340 | 10 | # Scores: Apdex = 1.00 [1.0]*, V/M = 0.00 | ||
341 | 11 | # Query_time sparkline: | | | ||
342 | 12 | # Attribute pct total min max avg 95% stddev median | ||
343 | 13 | # ============ === ======= ======= ======= ======= ======= ======= ======= | ||
344 | 14 | # Count 50 1 | ||
345 | 15 | # Exec time 0 0 0 0 0 0 0 0 | ||
346 | 16 | # Query size 37 26 26 26 26 26 0 26 | ||
347 | 17 | # Query_time distribution | ||
348 | 18 | # 1us | ||
349 | 19 | # 10us | ||
350 | 20 | # 100us | ||
351 | 21 | # 1ms | ||
352 | 22 | # 10ms | ||
353 | 23 | # 100ms | ||
354 | 24 | # 1s | ||
355 | 25 | # 10s+ | ||
356 | 26 | # Tables | ||
357 | 27 | # SHOW TABLE STATUS LIKE 't'\G | ||
358 | 28 | # SHOW CREATE TABLE `t`\G | ||
359 | 29 | # EXPLAIN /*!50100 PARTITIONS*/ | ||
360 | 30 | SELECT c FROM t WHERE id=1\G | ||
361 | 31 | |||
362 | 32 | # Query 2: 0 QPS, 0x concurrency, ID 0x774B2B0B59EBAC2C at byte 27 _______ | ||
363 | 33 | # This item is included in the report because it matches --limit. | ||
364 | 34 | # Scores: Apdex = 1.00 [1.0]*, V/M = 0.00 | ||
365 | 35 | # Query_time sparkline: | | | ||
366 | 36 | # Attribute pct total min max avg 95% stddev median | ||
367 | 37 | # ============ === ======= ======= ======= ======= ======= ======= ======= | ||
368 | 38 | # Count 50 1 | ||
369 | 39 | # Exec time 0 0 0 0 0 0 0 0 | ||
370 | 40 | # Query size 62 44 44 44 44 44 0 44 | ||
371 | 41 | # Query_time distribution | ||
372 | 42 | # 1us | ||
373 | 43 | # 10us | ||
374 | 44 | # 100us | ||
375 | 45 | # 1ms | ||
376 | 46 | # 10ms | ||
377 | 47 | # 100ms | ||
378 | 48 | # 1s | ||
379 | 49 | # 10s+ | ||
380 | 50 | # Tables | ||
381 | 51 | # SHOW TABLE STATUS LIKE 't2'\G | ||
382 | 52 | # SHOW CREATE TABLE `t2`\G | ||
383 | 53 | # EXPLAIN /*!50100 PARTITIONS*/ | ||
384 | 54 | /* Hello, world! */ SELECT * FROM t2 LIMIT 1\G | ||
385 | 55 | |||
386 | 56 | # Profile | ||
387 | 57 | # Rank Query ID Response time Calls R/Call Apdx V/M Item | ||
388 | 58 | # ==== ================== ============= ===== ====== ==== ===== ========= | ||
389 | 59 | # 1 0xCB5621E548E5497F 0.0000 0.0% 1 0.0000 1.00 0.00 SELECT t | ||
390 | 60 | # 2 0x774B2B0B59EBAC2C 0.0000 0.0% 1 0.0000 1.00 0.00 SELECT t? |
Create a quick blueprint and target to 2.1.6.