(unnamed)

text/plain

Filename: (unnamed)
Type: text/plain
Part: 0
Message: Re: [HACKERS] WAL logging problem in 9.4.3?
#! /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);