perf-farm-v2.patch
text/x-patch
Patch
Same data as JSON:
GET /api/v1/attachments/:id/patch
the parsed metadata as JSON — format, series position, per-file stats; never the diff bytes.
API reference →
Format: unified
Series: patch v2
| File | + | − |
|---|---|---|
| build-farm.conf | 22 | 0 |
| run_build.pl | 256 | 0 |
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");