#!/usr/bin/env bash # #4681: el rendimiento es LA preocupacion que tiene trabado este hilo. # # Lo que cambia v3 en el camino de los formatos built-in esta en # ProcessCopyOptions(), que corre UNA VEZ POR COMANDO, no por fila. Asi que # se miden las dos cosas: # # A) COPY grande (1M filas): mide el bucle de filas. Si v3 no lo toca, # aca no deberia verse nada. # B) muchos COPY chicos (N comandos de 1 fila): mide el costo POR COMANDO, # que es el unico lugar donde el cambio podria aparecer. # # Las corridas se ALTERNAN master/v3 para que la deriva de la maquina no se # le cargue a uno de los dos, y todo corre pineado al mismo core. set -u BASE=$HOME/pg4681 CORE=${CORE:-3} REPS=${REPS:-7} FILAS=${FILAS:-1000000} CHICOS=${CHICOS:-3000} OUT=$BASE/bench.csv arranca() { # $1=arbol $2=puerto local w=$1 p=$2 rm -rf "$BASE/data_$w" "$BASE/i-$w/bin/initdb" -D "$BASE/data_$w" -U postgres --no-sync -A trust > /dev/null 2>&1 taskset -c "$CORE" "$BASE/i-$w/bin/pg_ctl" -D "$BASE/data_$w" \ -o "-p $p -c fsync=off -c synchronous_commit=off -c full_page_writes=off -c max_wal_size=8GB -c shared_buffers=2GB" \ -l "$BASE/log_$w.log" -w start > /dev/null 2>&1 } para() { "$BASE/i-$1/bin/pg_ctl" -D "$BASE/data_$1" -w stop > /dev/null 2>&1; } psql_() { local w=$1 p=$2; shift 2; taskset -c "$CORE" "$BASE/i-$w/bin/psql" -p "$p" -U postgres -qtAX "$@"; } # $1=arbol $2=puerto $3=ncols $4=formato $5=op -> ms mide() { local w=$1 p=$2 n=$3 fmt=$4 op=$5 local f="$BASE/dump_${n}_${fmt}.dat" if [ "$op" = TO ]; then psql_ "$w" "$p" -c "\\timing on" -c "COPY t$n TO '$f' WITH (FORMAT $fmt)" 2>/dev/null \ | grep -oP 'Time: \K[0-9.]+' | tail -1 else psql_ "$w" "$p" -c "TRUNCATE t${n}_in" -c "\\timing on" \ -c "COPY t${n}_in FROM '$f' WITH (FORMAT $fmt)" 2>/dev/null \ | grep -oP 'Time: \K[0-9.]+' | tail -1 fi } prepara() { # tablas y datos local w=$1 p=$2 for n in 1 10 100; do local cols="" vals="" for i in $(seq 1 "$n"); do cols="$cols,c$i int"; vals="$vals,(random()*1000000)::int"; done cols=${cols#,}; vals=${vals#,} psql_ "$w" "$p" -c "DROP TABLE IF EXISTS t$n, t${n}_in" \ -c "CREATE TABLE t$n ($cols)" -c "CREATE TABLE t${n}_in ($cols)" \ -c "INSERT INTO t$n SELECT $vals FROM generate_series(1,$FILAS)" > /dev/null done psql_ "$w" "$p" -c "DROP TABLE IF EXISTS chico" -c "CREATE TABLE chico (a int)" > /dev/null } echo "arbol,rep,ncols,formato,op,ms" > "$OUT" arranca master 55501; prepara master 55501 arranca v3 55502; prepara v3 55502 for r in $(seq 1 "$REPS"); do for w in master v3; do p=55501; [ "$w" = v3 ] && p=55502 for n in 1 10 100; do for fmt in text csv binary; do for op in TO FROM; do ms=$(mide "$w" "$p" "$n" "$fmt" "$op") echo "$w,$r,$n,$fmt,$op,${ms:-NA}" >> "$OUT" done done done # B) costo POR COMANDO: N copys de una fila ini=$(date +%s.%N) psql_ "$w" "$p" -c "DO \$\$ BEGIN FOR i IN 1..$CHICOS LOOP EXECUTE 'COPY chico FROM PROGRAM ''echo 1'' WITH (FORMAT text)'; END LOOP; END \$\$" > /dev/null fin=$(date +%s.%N) echo "$w,$r,0,percmd,FROM,$(echo "($fin-$ini)*1000" | bc)" >> "$OUT" done echo " rep $r/$REPS listo" done para master; para v3 echo "-> $OUT" #!/usr/bin/env bash # Control del sesgo de ORDEN. # # En bench.sh, dentro de cada repeticion master corre siempre ANTES que v3. # Si la maquina se calienta, o el cache de archivos favorece a quien corre # segundo, ese efecto se le carga siempre al mismo arbol y aparece como si # fuera del patch. # # Aca se corren los casos sospechosos (100 columnas, COPY FROM) en las DOS # ordenes. Si el signo del delta se mantiene, es del patch; si se da vuelta, # es del orden. set -u BASE=$HOME/pg4681 CORE=${CORE:-3} REPS=${REPS:-10} OUT=$BASE/orden.csv arranca() { local w=$1 p=$2 rm -rf "$BASE/dord_$w" "$BASE/i-$w/bin/initdb" -D "$BASE/dord_$w" -U postgres --no-sync -A trust > /dev/null 2>&1 taskset -c "$CORE" "$BASE/i-$w/bin/pg_ctl" -D "$BASE/dord_$w" \ -o "-p $p -c fsync=off -c synchronous_commit=off -c full_page_writes=off -c max_wal_size=8GB -c shared_buffers=2GB" \ -l "$BASE/logord_$w.log" -w start > /dev/null 2>&1 } psql_() { local w=$1 p=$2; shift 2; taskset -c "$CORE" "$BASE/i-$w/bin/psql" -p "$p" -U postgres -qtAX "$@"; } prep() { local w=$1 p=$2 cols="" vals="" for i in $(seq 1 100); do cols="$cols,c$i int"; vals="$vals,(random()*1000000)::int"; done psql_ "$w" "$p" -c "CREATE TABLE t100 (${cols#,})" -c "CREATE TABLE t100_in (${cols#,})" \ -c "INSERT INTO t100 SELECT ${vals#,} FROM generate_series(1,1000000)" > /dev/null for fmt in text binary; do psql_ "$w" "$p" -c "COPY t100 TO '$BASE/ord_$fmt.dat' WITH (FORMAT $fmt)" > /dev/null done } mide() { # $1=arbol $2=puerto $3=formato -> ms de COPY FROM psql_ "$1" "$2" -c "TRUNCATE t100_in" -c "\\timing on" \ -c "COPY t100_in FROM '$BASE/ord_$3.dat' WITH (FORMAT $3)" 2>/dev/null \ | grep -oP 'Time: \K[0-9.]+' | tail -1 } arranca master 55521; prep master 55521 arranca v3 55522; prep v3 55522 echo "orden,arbol,rep,formato,ms" > "$OUT" for r in $(seq 1 "$REPS"); do for fmt in text binary; do # orden A: master primero a=$(mide master 55521 "$fmt"); echo "A,master,$r,$fmt,$a" >> "$OUT" b=$(mide v3 55522 "$fmt"); echo "A,v3,$r,$fmt,$b" >> "$OUT" # orden B: v3 primero c=$(mide v3 55522 "$fmt"); echo "B,v3,$r,$fmt,$c" >> "$OUT" d=$(mide master 55521 "$fmt"); echo "B,master,$r,$fmt,$d" >> "$OUT" done echo " rep $r/$REPS" done "$BASE/i-master/bin/pg_ctl" -D "$BASE/dord_master" -w stop > /dev/null 2>&1 "$BASE/i-v3/bin/pg_ctl" -D "$BASE/dord_v3" -w stop > /dev/null 2>&1 echo "-> $OUT"