#!/bin/bash # usage: page_split_bench.sh [ ...] # # Inserts of random keys into a btree (many page splits), 50 rows per # transaction, with pgbench: # A: read committed, no serializable transaction around # B: the same inside BEGIN ISOLATION LEVEL SERIALIZABLE (--max-tries 50) # One cluster per prefix (release builds), run round-robin, median TPS. # The clusters live in $WORKDIR (default ./psbench, on disk): millions of # inserted rows and their WAL would fill a tmpfs /tmp. C=$1; T=$2; R=$3; shift 3 W=${WORKDIR:-$PWD/psbench}; rm -rf $W; mkdir -p $W cat > $W/A.sql <<'EOF' INSERT INTO t (k) SELECT (random() * 2000000000)::int FROM generate_series(1, 50); EOF cat > $W/B.sql <<'EOF' BEGIN ISOLATION LEVEL SERIALIZABLE; INSERT INTO t (k) SELECT (random() * 2000000000)::int FROM generate_series(1, 50); COMMIT; EOF i=0 for P in "$@"; do i=$((i + 1)); port=$((56500 + i)) $P/bin/initdb -D $W/d$i -U postgres --no-sync >/dev/null 2>&1 cat >> $W/d$i/postgresql.conf </dev/null done trap 'i=0; for P in "$@"; do i=$((i + 1)); $P/bin/pg_ctl -D $W/d$i -m immediate -w stop >/dev/null 2>&1; done; rm -rf $W' EXIT for w in A B; do for r in $(seq 1 $R); do i=0 for P in "$@"; do i=$((i + 1)); port=$((56500 + i)) $P/bin/psql -X -q -h /tmp -p $port -U postgres postgres \ -c "DROP TABLE IF EXISTS t" -c "CREATE TABLE t (k int)" -c "CREATE INDEX ON t (k)" -c "CHECKPOINT" $P/bin/pgbench -n -h /tmp -p $port -U postgres -c $C -j $C -T $T --max-tries=50 \ -f $W/$w.sql postgres > $W/pgbench.out 2>&1 tps=$(grep -oE 'tps = [0-9.]+' $W/pgbench.out | grep -oE '[0-9.]+') [ -n "$tps" ] || { echo "pgbench failed ($w, $P):" >&2; tail -3 $W/pgbench.out >&2; } echo "$w $i $tps" | tee -a $W/raw done done done echo "TPS ($C clients, $T s, $R runs): median [min - max]" for w in A B; do i=0 for P in "$@"; do i=$((i + 1)) awk -v w=$w -v n=$i '$1==w && $2==n && $3 != "" {print $3}' $W/raw | sort -n | awk -v w=$w -v p=$P '{a[NR]=$1} END {printf " %s %-40s %8.0f [%.0f - %.0f] (%d runs)\n", w, p, a[int((NR+1)/2)], a[1], a[NR], NR}' done done