#! /usr/bin/perl use strict; use IPC::Open2; use Time::HiRes qw (gettimeofday tv_interval); my $tupperpage = 226; my @time = (); sub bench { my ($header, $nprocs, $ntups, $threshold) = @_; my @result = (); my @rds = (); for (my $ip = 0 ; $ip < $nprocs ; $ip++) { pipe(my $rd, my $wr); $rds[$ip] = $rd; my $pid = fork(); die "fork failed: $!\n" if ($pid < 0); if ($pid == 0) { close($rd); my $pid = open2(my $psqlrd, my $psqlwr, "psql postgres"); print $psqlwr "SET wal_skip_threshold to $threshold;\n"; print $psqlwr "DROP TABLE IF EXISTS t$ip;"; print $psqlwr "CREATE TABLE t$ip (a int);\n"; my @st = gettimeofday(); for (my $i = 0 ; $i < 10 ; $i++) { print $psqlwr "BEGIN;"; print $psqlwr "TRUNCATE t$ip;"; print $psqlwr "INSERT INTO t$ip (SELECT a FROM generate_series(1, $ntups) a);"; print $psqlwr "COMMIT;"; } close($psqlwr); waitpid($pid, 0); print $wr $ip, " ", 1000 * tv_interval(\@st, [gettimeofday]), "\n"; exit; } close($wr); } my $rpid; while (($rpid = wait()) == 0) {} my $sum = 0; for (my $ip = 0 ; $ip < $nprocs ; $ip++) { my $ret = readline($rds[$ip]); die "format? $ret\n" if ($ret !~ /^([0-9]+) ([0-9.]+)$/); $sum += $2; } printf "$header: procs $nprocs: time %.0f\n", $sum / $nprocs; } sub log10 { return log($_[0]) / log(10); } # benchmark for wal_level = replica, the third parameter of bench # doesn't affect sub bench1 { print "benchmark for wal_level = replica\n"; for (my $s = 0 ; $s <= 4 ; $s += 0.25) { my $ss = int(10 ** $s); bench("size $ss", 1, $ss * $tupperpage, $ss * 8); } } # benchmark for wal_level = minimal. sub bench2 { print "benchmark for wal_level = minimal\n"; for (my $s = 0 ; $s <= 3.5 ; $s += 0.25) { my $ss = int(10 ** $s); bench("size $ss: SYNC ", 1, $ss * $tupperpage, $ss * 8); bench("size $ss: WAL ", 1, $ss * $tupperpage, ($ss + 1) * 8); } } # find crossing point of WAL and SYNC by bisecting sub bench3 { print "find crossing point of WAL and SYNC by bisecting\n"; bench("SYNC: size 0", 1, 1, 8); bench("WAL : size 0", 1, 1, 16); my $s = 1; my $st = 10000; while (1) { my $ts = bench("SYNC: size $s", $tupperpage * $s, $s * 8); my $tw = bench("WAL : size $s", $tupperpage * $s, ($s + 1) * 8); if ($st < 1.0){ print "DONE\n"; exit(0); } if ($ts > $tw) { $s += $st; $st /= 2; } else { $s -= $st; $st /= 2; } } } # benchmark with multiple processes sub bench4 { my $nprocs = $ARGV[1]; print "benchmark for wal_level = minimal, $nprocs processes\n"; for (my $s = 1.0 ; $s <= 3.5 ; $s += 0.25) { my $ss = int(10 ** $s); bench("size $ss: SYNC ", $nprocs, $ss * $tupperpage, $ss * 8); bench("size $ss: WAL ", $nprocs, $ss * $tupperpage, ($ss + 1) * 8); } } bench1() if ($ARGV[0] == 1); bench2() if ($ARGV[0] == 2); bench3() if ($ARGV[0] == 3); bench4() if ($ARGV[0] == 4);