1
0
mirror of https://gitlab.com/depesz/explain.depesz.com.git synced 2024-11-24 08:42:27 +02:00

Dont use cursor for getting plans

Cursors cause bug in Pg15
This commit is contained in:
Hubert depesz Lubaczewski 2022-03-07 13:15:51 +01:00
parent 23f69af2d8
commit 5492f6a2b8

View File

@ -68,11 +68,12 @@ for my $partno ( 0 .. $#{ $partitions } ) {
my $errors = 0; my $errors = 0;
my $interesting = 0; my $interesting = 0;
my $query = sprintf "select id, plan FROM %s WHERE is_public and NOT is_deleted and NOT is_anonymized and plan ~ 'actual time=[0-9]'", $part; my $prev_id = '';
$dbh->do( "DECLARE csr CURSOR FOR $query" ); my $query = sprintf "select id, plan FROM %s WHERE is_public and NOT is_deleted and NOT is_anonymized and plan ~ 'actual time=[0-9]' AND id > ? order by ID ASC LIMIT 100", $part;
while ( 1 ) { while ( 1 ) {
my $rows = $dbh->selectall_arrayref( 'FETCH 100 FROM csr', { 'Slice' => {} } ); my $rows = $dbh->selectall_arrayref( $query, { 'Slice' => {} }, $prev_id );
last if 0 == scalar @{ $rows }; last if 0 == scalar @{ $rows };
$prev_id = $rows->[ -1 ]->{ 'id' };
for my $row ( @{ $rows } ) { for my $row ( @{ $rows } ) {
$seen++; $seen++;
my $explain; my $explain;
@ -88,8 +89,8 @@ for my $partno ( 0 .. $#{ $partitions } ) {
my $is_interesting = 0; my $is_interesting = 0;
for my $line ( @{ output_lines( $row->{'id'}, $explain ) } ) { for my $line ( @{ output_lines( $row->{ 'id' }, $explain ) } ) {
print $out join("\t", @{$line}) . "\n"; print $out join( "\t", @{ $line } ) . "\n";
$is_interesting = 1; $is_interesting = 1;
} }
@ -111,7 +112,8 @@ exit;
sub output_lines { sub output_lines {
my ( $id, $plan ) = @_; my ( $id, $plan ) = @_;
my $ret = []; my $ret = [];
my $plan_len = length( $plan->source );
for my $node ( $plan->top_node, $plan->top_node->all_recursive_subnodes ) { for my $node ( $plan->top_node, $plan->top_node->all_recursive_subnodes ) {
next unless $node->estimated_row_width; next unless $node->estimated_row_width;
@ -120,16 +122,17 @@ sub output_lines {
next unless $node->extra_info; next unless $node->extra_info;
# At least 3 pages worth of data is returned # At least 3 pages worth of data is returned
next unless $node->total_rows * $node->estimated_row_width > 3 * 8192; next unless ( $node->total_rows + $node->total_rows_removed ) * $node->estimated_row_width > 3 * 8192;
# At least 90% of rows were removed # At least 90% of rows were removed
next unless $node->total_rows_removed > 9 * $node->total_rows; next unless $node->total_rows_removed > 2 * $node->total_rows;
my @filter_lines = grep { /^Filter:/ } @{ $node->extra_info }; my @filter_lines = grep { /^Filter:/ } @{ $node->extra_info };
# There are filter expressions # There are filter expressions
next if 0 == scalar @filter_lines; next if 0 == scalar @filter_lines;
push @{ $ret }, map { [ $id, $node->id, $node->type, $node->estimated_row_width, $node->total_rows, $node->total_rows_removed, $_ ] } @filter_lines; push @{ $ret }, map { [ $id, $plan_len, $node->type, $_ ] } @filter_lines;
} }
return $ret; return $ret;
} }