I just dusted off this code and brought it back to current again.
Basically a lot of reformatting the new performance farm parts to
minimize their diff. Once that was done, all of the other buildfarm
client updates since then applied cleanly.
The result is now sitting as a fork of Andrew's client code repo at
https://github.com/greg2ndQuadrant/client-code , replacing the repo
Scott published at https://github.com/slux/PostgreSQL-Performance-Farm ;
much easier to avoid future bit-rot with this structure.
The main changes made here are now pretty easy to read on github:
https://github.com/greg2ndQuadrant/client-code/commit/d0339a59ceb4711a6b042d3f1d053c77f07720f4
and I've attached the code as a patch here. It also uses some scripts
from pgbench-tools that aren't the interesting part.
I got a nibble from Endpoint at PGEast about interest in hacking the
buildfarm server code to add support for a new test type, so this may
start moving forward again if that works out.
--
Greg Smith 2ndQuadrant US g...@2ndquadrant.com Baltimore, MD
PostgreSQL Training, Services, and 24x7 Support www.2ndQuadrant.us
diff --git a/build-farm.conf b/build-farm.conf
index 77ff694..fc4b103 100644
--- a/build-farm.conf
+++ b/build-farm.conf
@@ -39,6 +39,16 @@ my $branch;
build_root => '/path/to/buildroot',
use_vpath => undef, # set true to do vpath builds
+ # Performance farm testing
+ make_perf => 1, # set true to make performance farms, must keep on if not doing a build farm
+ clients => [qw(8 12 24)],
+ maxworkers => '12',
+ sets => '1',
+ scale => [qw(1 10)],
+ scriptvar => '-S',
+ transvar => '-T 60',
+ pgopts => '-l',
+
# path to directory with auxiliary web script
# if relative, the must be relative to buildroot/branch
# possibly only necessary now on WIndows, if at all
@@ -150,6 +160,18 @@ my $branch;
--with-openssl
)],
+ # Options for performance tests
+ perf_opts =>
+ [qw(
+ --enable-nls
+ --enable-integer-datetimes
+ --with-perl
+ --with-python
+ --with-tcl
+ --with-krb5 --with-includes=/usr/include/et
+ --with-openssl
+ )],
+
# per-branch contents of extra config for check stage
# each branch has an array of setting lines (no \n required)
extra_config =>
diff --git a/run_build.pl b/run_build.pl
index 666268f..81487af 100755
--- a/run_build.pl
+++ b/run_build.pl
@@ -139,6 +139,14 @@ my ($buildroot,$target,$animal, $print_success, $aux_path, $trigger_filter,
my $scm_timeout_secs =
$PGBuild::conf{scm_timeout_secs} || $PGBuild::conf{cvs_timeout_secs};
+my $make_perf = $PGBuild::conf{make_perf};
+my $clients = $PGBuild::conf{clients};
+my $maxworkers = $PGBuild::conf{maxworkers};
+my $sets = $PGBuild::conf{sets};
+my $scale = $PGBuild::conf{scale};
+my $scriptvar= $PGBuild::conf{scriptvar};
+my $pgopts = $PGBuild::conf {pgopts};
+
print scalar(localtime()),": buildfarm run for $animal:$branch starting\n"
if $verbose;
@@ -152,6 +160,7 @@ if (ref($force_every) eq 'HASH')
}
my $config_opts = $PGBuild::conf{config_opts};
+my $perf_opts = $PGBuild::conf{perf_opts};
my $scm = new PGBuild::SCM \%PGBuild::conf;
my $buildport;
@@ -261,6 +270,9 @@ chdir $buildroot || die "chdir to $buildroot: $!";
mkdir $branch unless -d $branch;
+my $bench ="$branch/bench";
+mkdir $bench unless -d $bench;
+
chdir $branch || die "chdir to $buildroot/$branch";
# rename legacy status files/directories
@@ -542,6 +554,15 @@ set_last('run.snap',$current_snap) unless $nostatus;
my $started_times = 0;
+# Additional setup for performance farm
+my $perf_farm = 0;
+my $time = time;
+my $benchpath = "$bench/$time";
+if($make_perf)
+{
+ $perf_farm = 1;
+}
+
# each of these routines will call send_result, which calls exit,
# on any error, so each step depends on success in the previous
# steps.
@@ -593,6 +614,13 @@ foreach my $locale (@locales)
make_install_check($locale);
+ if($perf_farm)
+ {
+ system("mkdir $buildroot/$benchpath");
+ print time_str(),"running pgbench analysis ...\n" if $verbose;
+ benchmark();
+ }
+
# releases 8.0 and earlier don't support the standard method for testing
# PLs so only check them for later versions
@@ -739,6 +767,218 @@ sub check_make
return 'OK';
}
+sub benchmark
+{
+ return if $skip_steps{benchmark};
+ my $script;
+ my @scripts;
+ my @path;
+ chdir "$installdir/bin/";
+ system("./createdb pgbench");
+ my ($scount,$setcount,$ccount,$workers);
+ my $shorthost;
+ foreach $scount (@$scale)
+ {
+ my @benchout = `./pgbench -i -s $scount pgbench >$devnull 2>&1`;
+ for($setcount = 0; $setcount<$sets; $setcount++)
+ {
+ foreach $ccount (@$clients)
+ {
+ my $transvar = $PGBuild::conf{transvar};
+ if($ccount > $maxworkers)
+ {
+ $workers = $maxworkers;
+ }
+ else
+ {
+ $workers = $ccount;
+ }
+ my ($trans,$tps,$dbs);
+ $trans = 0;
+ if($transvar =~ m/-t/)
+ {
+ $trans = substr $transvar,3;
+ my $trans2 = $trans/$ccount;
+ $transvar = "-t $trans2";
+ }
+ system("./pgbench $scriptvar $pgopts $transvar -c $ccount -j $workers pgbench > results.txt 2>&1");
+ system("mv results.txt $buildroot/$benchpath/results.txt");
+ system("mv pgbench_log* $buildroot/$benchpath");
+ chdir "$buildroot/$benchpath";
+ system("cat pgbench_log* > pgbench.log");
+ open(DAT,"pgbench.log");
+ my @raw_data = <DAT>;
+ close(DAT);
+ my $hostname = qx{hostname};
+ chomp $hostname;
+ $shorthost = $hostname;
+ if ($shorthost =~ m{^(\w+\d\.\w+)\.\w+\.\w+$}) {
+ $shorthost = $1;
+ }
+ else {
+ $shorthost =~ s/^(.+?)\..+/$1/;
+ }
+ open(CSV,">timing.csv");
+ open(CSV2,">>../$shorthost.csv");
+ my ($line, $client, $transa, $latency, $filenum, $sec, $usec);
+ my $max = 0;
+ my $avg = 0;
+ my $start = "0";
+ my $end;
+ my $num = 0;
+ $dbs = `$installdir/bin/psql -p $buildport -d pgbench -A -t -c "select pg_database_size('pgbench')"`;
+ if($trans == 0)
+ {
+ $trans=`grep "number of transactions actually processed: " results.txt | cut -d " " -f 6`;
+ }
+ $tps=`grep "(including connections establishing)" results.txt | cut -d " " -f 3`;
+ chomp($dbs);
+ chomp($trans);
+ chomp($tps);
+ if(!$trans)
+ {
+ $trans = 0;
+ }
+ if(!$tps)
+ {
+ $tps = 0;
+ }
+ foreach $line (@raw_data)
+ {
+ chomp($line);
+ ($client,$transa,$latency,$filenum,$sec,$usec)=split(/ /,$line);
+ $latency = $latency/1000;
+ $avg = $avg + $latency;
+ $num++;
+ if($latency > $max)
+ {
+ $max = $latency;
+ }
+ my $localtime = $sec+$usec/1000000; # or any other epoch timestamp
+ my ($sec, $min, $hour, $day,$month,$year) = (localtime($localtime))[0,1,2,3,4,5,6];
+ if($start eq "0")
+ {
+ $start = sprintf("%d-%02d-%02d %02d:%02d:%02d.%02d",($year+1900),($month+1),$day,$hour,$min,$sec,$usec);
+ }
+ $end = sprintf("%d-%02d-%02d %02d:%02d:%02d.%02d",($year+1900),($month+1),$day,$hour,$min,$sec,$usec);
+ print CSV "$start,$filenum,$latency\n";
+ }
+ print CSV2 "$ccount,$scount,$dbs,$tps\n";
+ if($scriptvar eq "-S")
+ {
+ $script = "select-only";
+ }
+ elsif($scriptvar eq "-N")
+ {
+ $script = "no-update";
+ }
+ elsif($scriptvar =~ m/-f/)
+ {
+ $script = substr $scriptvar,3;
+ @scripts = split(/-f /, $scriptvar);
+ @path = split(/\//, $scripts[$filenum]);
+ $script = $path[$#path];
+ }
+ else
+ {
+ $script = "TCP-B";
+ }
+ $avg = $avg/$num;
+ close(CSV);
+ close(CSV2);
+ if(-e "../$shorthost.txt")
+ {
+ open(FH,">>../$shorthost.txt");
+ }
+ else
+ {
+ open(FH,">../$shorthost.txt");
+ print FH "| hostname | scale | dbsize | start_time | end_time | tps | script | clients | workers | trans | avg_latency | max_latency |\n";
+ };
+ printf FH "|%12s|%7d|%14d|%28s|%28s|%18f|%15s|%9d|%9d| %11d| %14f|%13f|\n",$shorthost,$scount,$dbs,$start,$end,$tps,$script,$ccount,$workers,$trans,$avg,$max;
+ close(FH);
+ unlink "pgbench.log";
+ unlink "results.txt";
+ unlink glob "pgbench_log.*";
+ chdir "$installdir/bin/";
+ $max = 0;
+ $avg = 0;
+ }
+ }
+ }
+ chdir "$buildroot/$bench";
+ open(CSV,"$shorthost.csv");
+ my @graph_data = <CSV>;
+ my ($clist,$slist);
+ my $counter;
+ my $tpscounter;
+ open(TX1,">clients.txt");
+ my ($gclient,$gscale,$gdbs,$gtps);
+ my $line2;
+ foreach $clist (@$clients)
+ {
+ $counter = 0;
+ $tpscounter = 0;
+ foreach $line2 (@graph_data)
+ {
+ chomp($line2);
+ ($gclient,$gscale,$gdbs,$gtps)=split(/,/,$line2);
+ if($gclient == $clist)
+ {
+ $counter++;
+ $tpscounter+=$gtps;
+ }
+ }
+ $tpscounter/=$counter;
+ print TX1 "$clist $tpscounter\n";
+ }
+ open(CSV,"$shorthost.csv");
+ @graph_data = <CSV>;
+ my $dbcounter;
+ open(TX2,">scaling.txt");
+ foreach $slist (@$scale)
+ {
+ $counter = 0;
+ $tpscounter = 0;
+ $dbcounter = 0;
+ foreach $line2 (@graph_data)
+ {
+ chomp($line2);
+ ($gclient,$gscale,$gdbs,$gtps)=split(/,/,$line2);
+ if($gscale == $slist)
+ {
+ $counter++;
+ $tpscounter+=$gtps;
+ $dbcounter = $gdbs;
+ }
+ }
+ $tpscounter/=$counter;
+ $dbcounter/=(1024*1024);
+ print TX2 "$slist $dbcounter $tpscounter\n";
+ }
+ close(TX2);
+ close(CSV);
+ system("gnuplot $buildroot/plots/clients.plot");
+ system("gnuplot $buildroot/plots/scaling.plot");
+ system("cp clients.png $buildroot/$benchpath/clients.png");
+ system("cp scaling.png $buildroot/$benchpath/scaling.png");
+ unlink "clients.txt";
+ unlink "scaling.txt";
+ chdir "$installdir/bin/";
+ system("./dropdb pgbench");
+}
+
+sub make_clean
+{
+ return if $skip_steps{clean};
+ my (@makeout);
+ @makeout = `cd $pgsql && $make clean 2>&1`;
+ my $status = $? >>8;
+ writelog('clean',\@makeout);
+ print "======== clean log ===========\n",@makeout if ($verbose > 1);
+ send_result('clean',$status,\@makeout) if $status;
+ $steps_completed .= " Clean";
+}
sub make
{
@@ -1310,6 +1550,12 @@ sub configure
);
my $handle;
+
+ if($perf_farm == 1)
+ {
+ $lconfig = { %$perf_opts, "--with-pgport" => $buildport };
+ }
+
open($handle,">$pgsql/src/tools/msvc/config.pl");
print $handle @text;
close($handle);
@@ -1336,6 +1582,16 @@ sub configure
}
}
+ if($perf_farm)
+ {
+ # minimizing the diff by putting all new logic here
+ @quoted_opts=();
+ foreach my $c_opt (@$perf_opts)
+ {
+ push(@quoted_opts,"'$c_opt'");
+ }
+ }
+
my $confstr = join(" ",@quoted_opts,
"--prefix=$installdir",
"--with-pgport=$buildport");
--
Sent via pgsql-hackers mailing list (pgsql-hackers@postgresql.org)
To make changes to your subscription:
http://www.postgresql.org/mailpref/pgsql-hackers