1 |
#!/opt/perl/bin/perl |
---|
2 |
|
---|
3 |
use strict; |
---|
4 |
use DBI; |
---|
5 |
use Getopt::Long; |
---|
6 |
|
---|
7 |
my %filecache; |
---|
8 |
my %filerel; |
---|
9 |
my %pgname; |
---|
10 |
|
---|
11 |
my $pid; |
---|
12 |
my $verbose; |
---|
13 |
my $stop; |
---|
14 |
|
---|
15 |
GetOptions( |
---|
16 |
"p=i" => \$pid, |
---|
17 |
"v" => \$verbose, |
---|
18 |
"s" => \$stop, |
---|
19 |
); |
---|
20 |
|
---|
21 |
if(!$pid) { |
---|
22 |
print STDERR "$0 [-s] [-v] -p <pid>\n"; |
---|
23 |
exit -1; |
---|
24 |
} |
---|
25 |
|
---|
26 |
# -s implies -v |
---|
27 |
$verbose = $stop if $stop; |
---|
28 |
|
---|
29 |
sub maprels { |
---|
30 |
my $cnt = 0; |
---|
31 |
print STDERR "Mapping open files to db objects...\n" if $verbose; |
---|
32 |
my $dbh = DBI->connect("dbi:Pg:dbname=pgods", "statsreader", "datamuncher"); |
---|
33 |
my $sql = "SELECT relfilenode, relname FROM pg_class WHERE relfilenode IN (". |
---|
34 |
join(',', values %filerel).")"; |
---|
35 |
my $q = $dbh->prepare($sql); |
---|
36 |
$q->execute(); |
---|
37 |
while(my($relfilenode, $relname) = $q->fetchrow()) { |
---|
38 |
$pgname{$relfilenode} = $relname; |
---|
39 |
print STDERR "$relfilenode => $relname\n" if $verbose; |
---|
40 |
$cnt++; |
---|
41 |
} |
---|
42 |
$q->finish(); |
---|
43 |
$dbh->disconnect(); |
---|
44 |
print STDERR "mapped $cnt files\n" if $verbose; |
---|
45 |
} |
---|
46 |
|
---|
47 |
sub cache_files { |
---|
48 |
my $cnt = 0; |
---|
49 |
print STDERR "finding open files\n" if $verbose; |
---|
50 |
local($/) = undef; |
---|
51 |
open(PFILES, "pfiles $pid|"); |
---|
52 |
my $pfiles = <PFILES>; |
---|
53 |
close(PFILES); |
---|
54 |
|
---|
55 |
# 135: S_IFREG mode:0600 dev:181,65543 ino:7834 uid:5432 gid:5432 size:1302528 |
---|
56 |
# O_RDWR|O_LARGEFILE |
---|
57 |
# /pgods/slowdata1/pgdata/base/43516/803134 |
---|
58 |
|
---|
59 |
while($pfiles =~ m/^\s*(\d+):\s*S_IFREG.*?(?:O_\S+)\s*(\/\S+)/smg) { |
---|
60 |
my($fd, $path) = ($1, $2); |
---|
61 |
next if $path =~ /pg_xlog/; |
---|
62 |
$filecache{$fd} = $path; |
---|
63 |
($filerel{$fd} = $path) =~ s/^.+\/(\d+).*/$1/; |
---|
64 |
$cnt++; |
---|
65 |
} |
---|
66 |
print STDERR "found $cnt files\n" if $verbose; |
---|
67 |
maprels(); |
---|
68 |
} |
---|
69 |
|
---|
70 |
cache_files(); |
---|
71 |
exit if $stop; |
---|
72 |
|
---|
73 |
open(TRUSS, "truss -p $pid 2>&1 |"); |
---|
74 |
while(<TRUSS>) { |
---|
75 |
s/^(read|write|lseek|close)\((\d+)/"$1(".($pgname{$filerel{$2}}||$2)/eg; |
---|
76 |
print; |
---|
77 |
} |
---|
78 |
close(TRUSS); |
---|