Espacio de tecnologia, software libre y sus derivados. Una horda de monos entrenados escriben de vez en cuando por aqui algunas noticias, opiniones e incluso alguna que otra cosa fuera del tema. Maqueros, favor de abstenerse que no somos lo suficientemente guapos.

Piano daemon

Tunning PostgreSQL 8.2 sobre GNU/LINUX

Autor: Ing.Edwin Plauchu
mail to: j4nusx@gmail.com

Instalando Postgresql
Antes de instalar “postgresql 8.2″ , verifiquemos que este, no este ya instalado, si esto no fuese asi utilice descargue las fuentes de postgresql de la ftp de postgres:


wget -c http://ftp7.de.postgresql.org/pub/ftp.postgresql.org/latest/postgresql-8.2.5.tar.bz2

Compilando Postgresql 8.2

Procedemos a desempaquetar nuestras fuentes

pianodaemon@pianodaemon:~> tar -xvjf ./postgresql-8.2.5.tar.bz2

Aplicaremos las opciones de compilacion que aqui se muestran:

./configure --prefix=/home/postgresql/ --without-zlib && make && make install

Explicacion de los parametros anteriormente citados:

–prefix=/home/postgresql/ <---- Instalara postgresql en el home del usuario del sistema "postgresql"

–without-zlib <---- Desactiva el uso de compresion en nuestras tablas, sacrificando espacio, pero ganando velocidad de lectura en archivo de disco.

El usuario postgresql

Postgresql solo podra ser ejecutado por el usuario postgresql, mismo que debera de pertenecer al grupo postgresql.
Asi que procederemos a la creacion del mismo y de su grupo, posteriormente asignaremos el directorio /home/postgresql, solo al usuario y grupo postgresql:

pianodaemon@pianodaemon:~> groupadd postgresql
pianodaemon@pianodaemon:~> useradd -d /home/postgresql/ -g postgresql -s /bin/bash postgresql
pianodaemon@pianodaemon:~> chown -R postgresql:postgresql /home/postgresql/

Configuración Post-Instalación

Vamos a crear un directorio data (directorio de archivos en disco que almancenan las tablas de nuestras bases de datos), esto lo haremos logeados como el usuario postgresql:

pianodaemon@pianodaemon:~> su - postgresql
postgresql@pianodaemon:~> pwd
/home/postgresql/
postgresql@pianodaemon:~> mkdir ./DATA

Inicializando el directorio data:

postgresql@pianodaemon:~> ./bin/initdb -D ./DATA/
The files belonging to this database system will be owned by user "postgresql".
This user must also own the server process.

The database cluster will be initialized with locale es_ES.UTF-8.
The default database encoding has accordingly been set to UTF8.

fixing permissions on existing directory ./DATA ... ok
creating subdirectories ... ok
selecting default max_connections ... 100
selecting default shared_buffers/max_fsm_pages ... 32MB/204800
creating configuration files ... ok
creating template1 database in ./DATA/base/1 ... ok
initializing pg_authid ... ok
initializing dependencies ... ok
creating system views ... ok
loading system objects' descriptions ... ok
creating conversions ... ok
setting privileges on built-in objects ... ok
creating information schema ... ok
vacuuming database template1 ... ok
copying template1 to template0 ... ok
copying template1 to postgres ... ok

WARNING: enabling "trust" authentication for local connections
You can change this by editing pg_hba.conf or using the -A option the
next time you run initdb.

Success. You can now start the database server using:

    ./bin/postgres -D ./DATA
or
    ./bin/pg_ctl -D ./DATA -l logfile start

Si obtuviste la pantalla anterior, el directorio data fue inicializado con exito.

Shell Script requerido para el arranque y parada de Postgresql

El siguiente shell script, esta realizado en bash, para llevar a cabo su ejecucion:

#!/bin/sh
# Start/stop/restart postgresql.
#
# To start PostgreSQL automatically at boot, be sure this script is executable:
# chmod 755 /etc/rc.d/rc.postgres

# --> Before you can run PostgreSQL, you must have a database.  Use initd.
#
# Note that step one is becoming the 'postgres' user. It's important to do this
# before making any changes to the database, or postgres won't be able to write
# to it later

# Set up variables
PGROOT=/home/postgresql
PGDATA=/home/postgresql/DATA
PGUSER=postgresql
PGLOG="$PGDATA/postgres.log"
PGDAEMON="$PGROOT/bin/postmaster"
PGCTL="$PGROOT/bin/pg_ctl"

if echo 'c' | grep -s c >/dev/null 2>%1; then
  ECHO_N="echo -n"
  ECHO_C=""
else
  ECHO_N="echo"
  ECHO_C='c'
fi

set -e

# Start postgresql:
postgresql_start() {
  $ECHO_N "Starting PostgreSQL: "$ECHO_C
  su - $PGUSER -c "$PGDAEMON -D '$PGDATA' &" >>$PGLOG 2>&1
  echo "ok"
}

# Stop postgresql:
postgresql_stop() {
  $ECHO_N "Stopping PostgreSQL: "$ECHO_C
  su - $PGUSER -c "$PGCTL stop -D '$PGDATA' -s -m fast" >>$PGLOG 
2>&1
  echo "ok"
}

# Restart postgreSQL:
postgresql_restart() {
  $ECHO_N "Restarting PostgreSQL: "$ECHO_C
  su - $PGUSER -c "$PGCTL stop -D '$PGDATA' -s -m fast" >>$PGLOG 
2>&1
  echo "ok"
  su - $PGUSER -c "$PGDAEMON -D '$PGDATA' &" >>$PGLOG 2>&1
  echo "ok"
}

case "$1" in
  'start')
  postgresql_start
  ;;
  'stop')
  postgresql_stop
  ;;
  'restart')
  postgresql_restart
  ;;
  *)
  echo "Usage $0 {start|stop|restart}" 1>&2
  exit 1
  ;;
esac
exit 0

Optimizando PostgreSQL

El reto de nuestra afinación va a consistir en optimizar el uso de memoria para postgres, minimizando en lo posible el número de intercambios con la swap (pagein). El mejor ajuste de los parámetros de configuración será aquél que obtenga la máxima disponibilidad en memoria para la BD, sin perjudicar al resto de elementos, que también deben permanecer en memoria.

SHARED_BUFFERS

El número de shared_buffers es el parámetro que más afecta al rendimiento de PostgreSQL. Este valor, de tipo entero, indica el número de bloques de memoria o buffers de 8KB (8192 bytes) que postgres reservará, como zona de trabajo, en el momento del arranque para procesar las consultas. De forma predeterminada (en postgresql.conf), su valor es de 1000. Un número claramente insuficiente para conseguir un rendimiento mínimamente aceptable.

Estos buffers se ubican dentro de los denominados segmentos de memoria compartida. Es importante saber que el espacio ocupado por el número de buffers que pretendamos asignar, nunca podrá exceder al tamaño máximo que tengan los segmentos de memoria. En caso contrario, postgres se negará a arrancar avisando con un error que no puede reservar el espacio solicitado.

Una buena recomendación (lee el artículo de B. Momjian[1]) es la de empezar asignando un 10% del total de la memoria RAM para shared_buffers y a partir de ahí, ir aumentando o disminuyendo dicho porcentaje en función del rendimiento y la paginación.

Comenzamos:

El 10% de 1 GB: (1048576 KB/10) = 104857 KB
shared_buffers: (104857 KB/8 KB) = 13107

Asignamos este valor a la variable shared_buffers (postgresql.conf)

En Linux, de forma predeterminada, el tamaño de un segmento de memoria compartida es de 32MB. Podemos comprobarlo haciendo (el resultado es en nº de bytes):

postgresql@pianodaemon:~> cat /proc/sys/kernel/shmmax
33554432

El espacio que requiere el número de buffers, es superior al tamaño del segmento:

13107 buffers ocupan 107372544 bytes (13107 * 8192 bytes/bloque)
107372544 > 33554432

Asi que asignaremos al kernel de linux un nuevo tamaño de segmento por default(agregue esta linea en /etc/sysctl.conf).

kernel.shmmax=107372544

Para comprobar el rendimiento, aplica EXPLAIN[2] a tus consultas. Para ver la paginación del servidor, puedes usar herramientas como vmstat o ipcs (consulta sus páginas man).
[editar] WORK_MEM

Este parámetro configura el espacio de memoria que postgres utiliza para realizar ordenaciones de tablas o de resultados parciales de consultas, sobre todo en cláusulas ORDER BY, CREATE INDEX o MERGE JOIN.

Este valor es más dificil de configurar porque depende, por un lado, de lo grande que sean las tablas o resultados que hay que ordenar, y por otro, del número de peticiones simultáneas para esa misma consulta (para cada una se empleará la misma cantidad de memoria).

Una buen comienzo es asignar entre un 2% y un 4% del total de la memoria si prevemos pocos accesos simultáneos a grandes sesiones de ordenación y mucho menor, si esperamos muchos accesos simultáneos a sesiones de ordenación pequeñas. Como antes, lo mejor es ir probando distintos valores y ver en qué pueden afectar a la paginación adversa. El valor hay que expresarlo en KB.

En nuestro ejemplo, hemos optado por usar un 4% de la memoria:

El 4% de 1 GB: 41943 KB   (1048576 KB*4)/100
work_men = 41943

Comenta