Merge lp:~percona-toolkit-dev/percona-toolkit/fix-1082104-pt-deadlock-logger-username-dash into lp:percona-toolkit/2.1

Proposed by Brian Fraser
Status: Merged
Approved by: Daniel Nichter
Approved revision: 468
Merged at revision: 508
Proposed branch: lp:~percona-toolkit-dev/percona-toolkit/fix-1082104-pt-deadlock-logger-username-dash
Merge into: lp:percona-toolkit/2.1
Diff against target: 173 lines (+115/-4)
3 files modified
bin/pt-deadlock-logger (+8/-3)
t/pt-deadlock-logger/bugs.t (+54/-1)
t/pt-deadlock-logger/samples/bug_1082104.txt (+53/-0)
To merge this branch: bzr merge lp:~percona-toolkit-dev/percona-toolkit/fix-1082104-pt-deadlock-logger-username-dash
Reviewer Review Type Date Requested Status
Daniel Nichter Approve
Brian Fraser (community) Approve
Review via email: mp+136091@code.launchpad.net
To post a comment you must log in.
Revision history for this message
Daniel Nichter (daniel-nichter) wrote :

Why not just $w = qr/([\w-]+)/ ?

Revision history for this message
Brian Fraser (fraserbn) wrote :

That would leave pt-deadlock-logger still broken for a bunch of valid usernames, ala イウサネイム, or some—user (em dash, not hyphen-minus), or a bunch of stuff you can imagine. `&%$!!%·` is totally valid, and the kind of thing someone mischievous might use to deadlock a server. The \S version is pretty broad, but I think only broken for usernames with whitespace in them.

Revision history for this message
Daniel Nichter (daniel-nichter) wrote :

Need to bzr add t/pt-deadlock-logger/samples/bug_1082104.txt

Revision history for this message
Daniel Nichter (daniel-nichter) wrote :

Why the (?!pat) in qr/((?!\b[0-9]+\b)\S+)/? Is there a case where the next thing might be numbers, so the negative look-ahead prevents matching that?

Revision history for this message
Brian Fraser (fraserbn) wrote :

I don't really know -- I can't find docs for the deadlock output anywhere -- but usernames can never be all numbers, so should there be numbers somewhere in that line, pt-dl won't get confused.

Revision history for this message
Daniel Nichter (daniel-nichter) wrote :

I think the extra check for number isn't needed. Right now we're doing:

 m/$ip $u(?: (.*))?$/;

So the user patter is already anchored on the IP, and the IP won't change. So all we need is the next item after that IP. I think \S+ is fine and we'll probably never support `user name` because MySQL would have to quote that but, like you noted, InnoDB output does whatever it wants, and it doesn't seem to quote stuff, so we'd never be able to know that user name is actually `user name`. Thus we can just document this limitation: user names with spaces will not be logged properly; only the first "word" in the username will be logged.

468. By Brian Fraser

Added t/pt-deadlock-logger/samples/bug_1082104.txt & changed the username regex per Daniel's comments

Revision history for this message
Brian Fraser (fraserbn) wrote :

Alright, sounds good. I changed the regex & added some lines in the limitations. Also added the missing logfile.

Revision history for this message
Brian Fraser (fraserbn) :
review: Approve
Revision history for this message
Daniel Nichter (daniel-nichter) :
review: Approve

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1=== modified file 'bin/pt-deadlock-logger'
2--- bin/pt-deadlock-logger 2012-12-03 03:48:11 +0000
3+++ bin/pt-deadlock-logger 2012-12-12 05:45:24 +0000
4@@ -3757,7 +3757,8 @@
5 my $t = qr/((?:\d+ \d+)|(?:[A-Fa-f0-9]+))/; # Transaction ID
6 my $i = qr/((?:\d{1,3}\.){3}\d+)/; # IP address
7 my $n = qr/([^`\s]+)/; # MySQL object name
8-my $w = qr/(\w+)/; # Words
9+my $u = qr/(\S+)/; # Username. This is somewhat wrong, but
10+ # usernames with spaces are rare enough.
11 my $s = qr/(\d{6} .\d:\d\d:\d\d)/; # InnoDB timestamp
12
13 # A thread's proc_info can be at least 98 different things I've found in the
14@@ -4082,7 +4083,7 @@
15 # the most useful marker for where I have to start guessing.
16 ( $hostname, $ip ) = $thread_line =~ m/query id \d+(?: ([A-Za-z]\S+))? $i/m;
17 if ( defined $ip ) {
18- ($user, $query_status) = $thread_line =~ m/$ip $w(?: (.*))?$/;
19+ ($user, $query_status) = $thread_line =~ m/$ip $u(?: (.*))?$/;
20 }
21 else {
22 # OK, there wasn't an IP address.
23@@ -4094,7 +4095,7 @@
24 # query_status.
25 # It's basically impossible to know which is which.
26 ( $hostname, $user, $query_status ) = $thread_line
27- =~ m/query id \d+(?: ([A-Za-z]\S+))?(?: $w(?: (.*))?)?$/m;
28+ =~ m/query id \d+(?: ([A-Za-z]\S+))?(?: $u(?: (.*))?)?$/m;
29 }
30 else {
31 $user = 'system user';
32@@ -4387,6 +4388,10 @@
33 both wait-for locks and get more information. If the two waited-for locks are
34 not on the same table, more than two transactions were involved in the deadlock.
35
36+Finally, keep in mind that, because usernames with spaces are not quoted by
37+InnoDB, the tool will generally misreport the second word of these usernames
38+as the hostname.
39+
40 =head1 OPTIONS
41
42 This tool accepts additional command-line arguments. Refer to the
43
44=== modified file 't/pt-deadlock-logger/bugs.t'
45--- t/pt-deadlock-logger/bugs.t 2012-06-03 18:47:00 +0000
46+++ t/pt-deadlock-logger/bugs.t 2012-12-12 05:45:24 +0000
47@@ -9,7 +9,7 @@
48 use strict;
49 use warnings FATAL => 'all';
50 use English qw(-no_match_vars);
51-use Test::More tests => 1;
52+use Test::More;
53
54 use PerconaTest;
55 use Sandbox;
56@@ -68,6 +68,59 @@
57 );
58
59 # #############################################################################
60+# https://bugs.launchpad.net/percona-toolkit/+bug/1082104
61+# pt-deadlock-logger problem when the user have a dash in the name
62+# #############################################################################
63+
64+$innodb_status_sample = load_file("t/pt-deadlock-logger/samples/bug_1082104.txt");
65+
66+is_deeply(
67+ pt_deadlock_logger::parse_deadlocks($innodb_status_sample),
68+ {
69+ '1' => {
70+ db => 'test',
71+ hostname => 'localhost',
72+ id => 1,
73+ idx => 'PRIMARY',
74+ ip => '',
75+ lock_mode => 'X',
76+ lock_type => 'RECORD',
77+ query => 'update a set movie_id=96 where id =2',
78+ server => '',
79+ tbl => 'a',
80+ thread => '19',
81+ ts => '2011-12-12T22:52:42',
82+ txn_id => 0,
83+ txn_time => '161',
84+ user => 'ro-ot',
85+ victim => 0,
86+ wait_hold => 'w'
87+ },
88+ '2' => {
89+ db => 'test',
90+ hostname => 'localhost',
91+ id => 2,
92+ idx => 'PRIMARY',
93+ ip => '',
94+ lock_mode => 'X',
95+ lock_type => 'RECORD',
96+ query => 'update a set movie_id=98 where id =4',
97+ server => '',
98+ tbl => 'a',
99+ thread => '18',
100+ ts => '2011-12-12T22:52:42',
101+ txn_id => 0,
102+ txn_time => '1026',
103+ user => 'ro-ot',
104+ victim => 1,
105+ wait_hold => 'w'
106+ }
107+ },
108+ "Bug 1082104: pt-deadlock-logger shows host as user when the username has a dash in the name",
109+);
110+
111+# #############################################################################
112 # Done.
113 # #############################################################################
114+done_testing;
115 exit;
116
117=== added file 't/pt-deadlock-logger/samples/bug_1082104.txt'
118--- t/pt-deadlock-logger/samples/bug_1082104.txt 1970-01-01 00:00:00 +0000
119+++ t/pt-deadlock-logger/samples/bug_1082104.txt 2012-12-12 05:45:24 +0000
120@@ -0,0 +1,53 @@
121+=====================================
122+070915 15:34:37 INNODB MONITOR OUTPUT
123+=====================================
124+Per second averages calculated from the last 24 seconds
125+------------------------
126+LATEST DETECTED DEADLOCK
127+------------------------
128+111212 22:52:42
129+*** (1) TRANSACTION:
130+TRANSACTION 3405, ACTIVE 161 sec starting index read
131+mysql tables in use 1, locked 1
132+LOCK WAIT 3 lock struct(s), heap size 376, 3 row lock(s), undo log entries 2
133+MySQL thread id 19, OS thread handle 0x7fac301e4700, query id 180 localhost ro-ot Updating
134+update a set movie_id=96 where id =2
135+*** (1) WAITING FOR THIS LOCK TO BE GRANTED:
136+RECORD LOCKS space id 0 page no 307 n bits 72 index `PRIMARY` of table `test`.`a` trx id 3405 lock_mode X locks rec but not gap waiting
137+Record lock, heap no 3 PHYSICAL RECORD: n_fields 6; compact format; info bits 0
138+ 0: len 4; hex 80000002; asc ;;
139+ 1: len 6; hex 000000003404; asc 4 ;;
140+ 2: len 7; hex 040000163b2515; asc ;% ;;
141+ 3: len 4; hex 80000063; asc c;;
142+ 4: len 1; hex 01; asc ;;
143+ 5: len 8; hex 8000124a7c1acb8c; asc J| ;;
144+
145+*** (2) TRANSACTION:
146+TRANSACTION 3404, ACTIVE 1026 sec starting index read
147+mysql tables in use 1, locked 1
148+3 lock struct(s), heap size 376, 2 row lock(s), undo log entries 1
149+MySQL thread id 18, OS thread handle 0x7fac30225700, query id 181 localhost ro-ot Updating
150+update a set movie_id=98 where id =4
151+*** (2) HOLDS THE LOCK(S):
152+RECORD LOCKS space id 0 page no 307 n bits 72 index `PRIMARY` of table `test`.`a` trx id 3404 lock_mode X locks rec but not gap
153+Record lock, heap no 3 PHYSICAL RECORD: n_fields 6; compact format; info bits 0
154+ 0: len 4; hex 80000002; asc ;;
155+ 1: len 6; hex 000000003404; asc 4 ;;
156+ 2: len 7; hex 040000163b2515; asc ;% ;;
157+ 3: len 4; hex 80000063; asc c;;
158+ 4: len 1; hex 01; asc ;;
159+ 5: len 8; hex 8000124a7c1acb8c; asc J| ;;
160+
161+*** (2) WAITING FOR THIS LOCK TO BE GRANTED:
162+RECORD LOCKS space id 0 page no 307 n bits 72 index `PRIMARY` of table `test`.`a` trx id 3404 lock_mode X locks rec but not gap waiting
163+Record lock, heap no 5 PHYSICAL RECORD: n_fields 6; compact format; info bits 0
164+ 0: len 4; hex 80000004; asc ;;
165+ 1: len 6; hex 000000003405; asc 4 ;;
166+ 2: len 7; hex 0500000e7017e8; asc p ;;
167+ 3: len 4; hex 80000062; asc b;;
168+ 4: len 1; hex 01; asc ;;
169+ 5: len 8; hex 8000124a7c1acbb6; asc J| ;;
170+
171+*** WE ROLL BACK TRANSACTION (2)
172+END OF INNODB MONITOR OUTPUT
173+============================

Subscribers

People subscribed via source and target branches