<?xml version='1.0' encoding='UTF-8'?><?xml-stylesheet href="http://www.blogger.com/styles/atom.css" type="text/css"?><feed xmlns='http://www.w3.org/2005/Atom' xmlns:openSearch='http://a9.com/-/spec/opensearchrss/1.0/' xmlns:georss='http://www.georss.org/georss' xmlns:gd='http://schemas.google.com/g/2005' xmlns:thr='http://purl.org/syndication/thread/1.0'><id>tag:blogger.com,1999:blog-5950429174584838030</id><updated>2011-11-15T09:13:28.038-03:00</updated><title type='text'>caerices</title><subtitle type='html'>Este blog esta desarrollado para entregar información relevante de la informatica.</subtitle><link rel='http://schemas.google.com/g/2005#feed' type='application/atom+xml' href='http://caerices.blogspot.com/feeds/posts/default'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5950429174584838030/posts/default?max-results=100'/><link rel='alternate' type='text/html' href='http://caerices.blogspot.com/'/><link rel='hub' href='http://pubsubhubbub.appspot.com/'/><author><name>caerices</name><uri>http://www.blogger.com/profile/17494035119607034630</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='24' height='32' src='http://3.bp.blogspot.com/_w44tDpxaU14/SjfWwlmjQ_I/AAAAAAAAAAY/GCvAuqbqu0o/S220/Cesar.jpg'/></author><generator version='7.00' uri='http://www.blogger.com'>Blogger</generator><openSearch:totalResults>17</openSearch:totalResults><openSearch:startIndex>1</openSearch:startIndex><openSearch:itemsPerPage>100</openSearch:itemsPerPage><entry><id>tag:blogger.com,1999:blog-5950429174584838030.post-5152928307846925545</id><published>2009-10-19T23:44:00.003-03:00</published><updated>2009-10-19T23:49:08.244-03:00</updated><title type='text'>Instalando Clamav en Fedora 11</title><content type='html'>Esta noche (19 de octubre del 2009) se me ocurre instalar el antivirus clamav en fedora 11, pero no sabia como se llamaba el paquete a instalar asi que decidi hacer un yum list clam* y aparecio lo siguiente:&lt;br /&gt;&lt;br /&gt;clamav.i586&lt;br /&gt;&lt;br /&gt;Una vez encontrado esto se debe hacer lo siguiente&lt;br /&gt;&lt;br /&gt;[root@cev caerices]# yum install clamav.i586&lt;br /&gt;Complementos cargados:refresh-packagekit&lt;br /&gt;Configurando el proceso de instalación&lt;br /&gt;Resolviendo dependencias&lt;br /&gt;--&gt; Ejecutando prueba de transacción&lt;br /&gt;---&gt; Paquete clamav.i586 0:0.95.2-3.fc11 definido para ser actualizado&lt;br /&gt;--&gt; Procesando dependencias: clamav-lib = 0.95.2-3.fc11 para el paquete: clamav-0.95.2-3.fc11.i586&lt;br /&gt;--&gt; Procesando dependencias: libclamav.so.6 para el paquete: clamav-0.95.2-3.fc11.i586&lt;br /&gt;--&gt; Procesando dependencias: data(clamav) para el paquete: clamav-0.95.2-3.fc11.i586&lt;br /&gt;--&gt; Procesando dependencias: libclamav.so.6(CLAMAV_PRIVATE) para el paquete: clamav-0.95.2-3.fc11.i586&lt;br /&gt;--&gt; Procesando dependencias: libclamav.so.6(CLAMAV_PUBLIC) para el paquete: clamav-0.95.2-3.fc11.i586&lt;br /&gt;--&gt; Ejecutando prueba de transacción&lt;br /&gt;---&gt; Paquete clamav-data.noarch 0:0.95.2-3.fc11 definido para ser actualizado&lt;br /&gt;--&gt; Procesando dependencias: clamav-filesystem = 0.95.2-3.fc11 para el paquete: clamav-data-0.95.2-3.fc11.noarch&lt;br /&gt;--&gt; Procesando dependencias: clamav-filesystem = 0.95.2-3.fc11 para el paquete: clamav-data-0.95.2-3.fc11.noarch&lt;br /&gt;---&gt; Paquete clamav-lib.i586 0:0.95.2-3.fc11 definido para ser actualizado&lt;br /&gt;--&gt; Ejecutando prueba de transacción&lt;br /&gt;---&gt; Paquete clamav-filesystem.noarch 0:0.95.2-3.fc11 definido para ser actualizado&lt;br /&gt;--&gt; Resolución de dependencias finalizada&lt;br /&gt;&lt;br /&gt;Dependencias resueltas&lt;br /&gt;&lt;br /&gt;================================================================================&lt;br /&gt; Paquete                 Arquitectura Versión               Repositorio   Tamaño&lt;br /&gt;================================================================================&lt;br /&gt;Instalando:&lt;br /&gt; clamav                  i586         0.95.2-3.fc11         updates       814 k&lt;br /&gt;Instalando para las dependencias:&lt;br /&gt; clamav-data             noarch       0.95.2-3.fc11         updates        21 M&lt;br /&gt; clamav-filesystem       noarch       0.95.2-3.fc11         updates        10 k&lt;br /&gt; clamav-lib              i586         0.95.2-3.fc11         updates       380 k&lt;br /&gt;&lt;br /&gt;Resumen de la transacción&lt;br /&gt;================================================================================&lt;br /&gt;Instalar       4 Paquete(s)&lt;br /&gt;Actualizar       0 Paquete(s)&lt;br /&gt;&lt;br /&gt;Tamaño total: 22 M&lt;br /&gt;Tamaño total de la descarga: 814 k&lt;br /&gt;Está de acuerdo [s/N]:s&lt;br /&gt;Descargando paquetes:&lt;br /&gt;clamav-0.95.2-3.fc11.i586.rpm                            | 814 kB     00:02     &lt;br /&gt;Ejecutando el rpm_check_debug&lt;br /&gt;Ejecutando prueba de transacción&lt;br /&gt;Prueba de transacción finalizada&lt;br /&gt;La prueba de transacción ha sido exitosa&lt;br /&gt;Ejecutando transacción&lt;br /&gt;  Instalando     : clamav-filesystem-0.95.2-3.fc11.noarch                   1/4 &lt;br /&gt;  Instalando     : clamav-data-0.95.2-3.fc11.noarch                         2/4 &lt;br /&gt;  Instalando     : clamav-lib-0.95.2-3.fc11.i586                            3/4 &lt;br /&gt;  Instalando     : clamav-0.95.2-3.fc11.i586                                4/4 &lt;br /&gt;&lt;br /&gt;Instalado:&lt;br /&gt;  clamav.i586 0:0.95.2-3.fc11                                                   &lt;br /&gt;&lt;br /&gt;Dependencia(s) instalada(s):&lt;br /&gt;  clamav-data.noarch 0:0.95.2-3.fc11  clamav-filesystem.noarch 0:0.95.2-3.fc11 &lt;br /&gt;  clamav-lib.i586 0:0.95.2-3.fc11    &lt;br /&gt;&lt;br /&gt;¡Listo!&lt;br /&gt;&lt;br /&gt;Ok eso estodo por hoy suerte&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5950429174584838030-5152928307846925545?l=caerices.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://caerices.blogspot.com/feeds/5152928307846925545/comments/default' title='Enviar comentarios'/><link rel='replies' type='text/html' href='http://caerices.blogspot.com/2009/10/instalando-clamav-en-centos.html#comment-form' title='0 comentarios'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5950429174584838030/posts/default/5152928307846925545'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5950429174584838030/posts/default/5152928307846925545'/><link rel='alternate' type='text/html' href='http://caerices.blogspot.com/2009/10/instalando-clamav-en-centos.html' title='Instalando Clamav en Fedora 11'/><author><name>caerices</name><uri>http://www.blogger.com/profile/17494035119607034630</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='24' height='32' src='http://3.bp.blogspot.com/_w44tDpxaU14/SjfWwlmjQ_I/AAAAAAAAAAY/GCvAuqbqu0o/S220/Cesar.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-5950429174584838030.post-1291278665350334891</id><published>2009-10-06T13:47:00.001-04:00</published><updated>2009-10-06T13:47:42.492-04:00</updated><title type='text'>Control Parental con Squid, DansGuardian y  SARG</title><content type='html'>Edwind Richzendy Contreras Soto &lt;Richzendy[at]gmail[dot]com&gt;&lt;br /&gt;blog: http://www.Richzendy.org&lt;br /&gt;&lt;br /&gt;*Sustituye el [at] por el simbolo @ y el [dot] por un punto&lt;br /&gt;&lt;br /&gt; v0.1, 9 de Septiembre del 2007 Este mini HowTo, no pretende ser una guia completa sobre estas 3 herramientas, ya que cada una tiene muchisima tela que cortar, simplemente esta guia relatara la manera de fusionarlas para lograr una función en especifico de ellas, debe estar claro que si desea un documento más detallado o una aplicación diferente a la tratada acá, debe referirse a otra documentación ( incluida la documentación propia de cada una de estas herramientas ), además debo indicar que se pueden usar otros tipos de proxys y probablemente se obtenga el mismo resultado e incluso estas herramientas no son la unica manera de implementar un filtro de contenido, por último aclaro que no me hago responsable de lo que hagas con  tus /dev/hands asi que te recomiendo conectes tu /dev/brain al intentar hacer algo de lo que acá se explica. &lt;br /&gt;&lt;br /&gt; &lt;br /&gt;&lt;br /&gt;Indice&lt;br /&gt; &lt;br /&gt;Que es un control parental?&lt;br /&gt;Que es Squid?&lt;br /&gt;Que es DansGuardian?&lt;br /&gt;Que es SARG?&lt;br /&gt;Escenario&lt;br /&gt;Recomendaciones para la instalación de paquetes&lt;br /&gt;Instalación de Squid&lt;br /&gt;Instalación de DansGuardian&lt;br /&gt;Instalación de SARG&lt;br /&gt;Post-Configuración y uso del Control Parental&lt;br /&gt;Personalización y mantenimiento de Dansguardian&lt;br /&gt;Consideraciones finales&lt;br /&gt;Direcciones Útiles&lt;br /&gt;Copyleft&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;Que es un control parental?&lt;br /&gt;&lt;br /&gt;    Un control parental como su nombre lo indica, literalmente es "control ejercido por los padres", sin embargo acá se ve aplicado directamente a las aplicaciones que pueden permitirle a los padres ejercer control sobre lo que ven sus hijos a través de Internet, Internet es una tecnologia de muy reciente creación por lo cual cualquier persona que tenga hijos con edad para usar una computadora probablemente poco conocimiento tenga de que acciones tomar para controlar el uso de este.&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;    El Internet es una amplia fuente de conocimiento pero por lo general este se encuentra desatado y sin control y así como encontramos una fuente inmensa de conocimiento, cultura, educación y noticias, tambien encontramos cosas realmente dañinas para un niño, cosas que a su edad probablemente no este preparado para asimilar, tales como: pornografía, sitios violentos, sitios de uso de lenguaje violento y sin moderación, sitios con imágenes impactantes, sitios con virus, sitios de chat sin moderación, sitios de pishing y muchas otras cosas más.&lt;br /&gt;&lt;br /&gt;Que es Squid?&lt;br /&gt;&lt;br /&gt;    Squid es un programa que sirve de proxy, es decir, hace cache de las páginas visitadas. Al navegar a través de internet Squid va grabando el contenido de las páginas web que visita ( texto, imágenes, css, etc ...) y lo almacena en el disco duro para que la proxima vez que alguien visite esa página, el navegador usara dicha cache y en vez de volverla a descargar desde internet, la verá mucho más rapido ya que algunas cosas ya las ha descargado y se tienen grabadas en el disco duro.&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;    Por lo general Squid se aprovecha mejor como cache para toda una red, en donde hay varios clientes, sin embargo no hay ninguna limitante para que pueda ser usado en un computador personal ( como por ejemplo el que se tratará acá ).&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;Que es DansGuardian?&lt;br /&gt;&lt;br /&gt;    DansGuardian es un programa que permite hacer un filtrado del contenido que se visita en internet a través del navegador, este programa en especifico, es uno de los más completos en su estilo ya que no se basa simplemente en listados de sitios bloqueados, si no que también puede evaluar el contenido de algún sitio web basado en palabras claves y expresiones regulares ( incluso de imágenes ), además su personalización y/o configuración esta basada en archivos de texto plano, lo que facilita enormemente el trabajar con esta herramienta.&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;Que es SARG?&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;    SARG es una aplicación que genera estadisticas en formato html usando como datos los logs de Squid, de toda la navegación realizada a través del proxy en un intervalo de tiempo, es una de las herramientas más completas en ese sentido.&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;Escenario:&lt;br /&gt;&lt;br /&gt;    Tenemos un computador personal en la casa, la cual usa Fedora GNU/Linux como sistema operativo y es usado por varios miembros de la casa (incluidos varios niños y menores de edad ) cada uno con su cuenta de usuario, con acceso a internet, sin embargo no se tiene ningún tipo de supervisión por parte de un adulto en las horas en que navegan los niños y adolescentes.&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;    Se desea poder controlar en lo posible lo que ellos pueden ver a través de internet, a su vez poder tener registro de lo que navegan para posteriormente evaluar en que gastan su tiempo cuando estan usando el computador.&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;    Sobre todo se desea que la solución basada en Squid+DansGuardian+SARG sea segura e infranqueable para que realmente pueda cumplir su cometido, es decir, que el usuario o el grupo de ellos que se planea controlar, no puedan tener manera de saltarse la restricción impuesta.&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;Recomendaciones para la instalación de paquetes:&lt;br /&gt;&lt;br /&gt;    Todas las instrucciones de ahora en adelante se harán pensando en que el usuario esta usando fedora como distribución de GNU/Linux, sin embargo el lector de este how to, podrá aplicar todos los pasos a su distribución propia si conoce su manejador de paquetes y la forma de instalar estos, de todas maneras se harán algunas pequeñas referencias para las personas que usan ubuntu o debian, como por ejemplo en vez de usar "yum install" deben usar su equivalente "apt-get install" ó "aptitude install".&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;    A pesar de que en este how to se mayoritariamente la consola de comandos, se recomienda altamente si el lector no es un usuario avanzado o no tiene experiencia con la consola que use el equivalente de herramientas gráficas que permiten la mismas funciones, por ejemplo si se es usuario de fedora, use pupplet o yumex para instalar y remover paquetes o si se es usuario de ubuntu o debian use synaptic o gdebi. Si se quiere editar un archivo  en vez de usar vim o nano como editores de texto use gedit, kwrite o kate.&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;Instalación de Squid:&lt;br /&gt;&lt;br /&gt;    Abrir un terminal como root y escribir:&lt;br /&gt;&lt;br /&gt;[root@andromeda ~]# yum install squid&lt;br /&gt;&lt;br /&gt;    Este comando te instalará la versión más reciente de Squid disponible en los repositorios de fedora, luego de esto el paquete se encuentra instalado y preconfigurado adecuadamante para el uso que necesitamos, asi que por los momentos no necesitamos editar su archivo de configuración.&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;    Si deseas probar que Squid esta funcionando, solo ejecute el siguiente comando para iniciarlo:&lt;br /&gt;&lt;br /&gt; [root@andromeda ]# service squid start&lt;br /&gt;Nota 1: Si usa ubuntu o debian use el comando: /etc/init.d/squid start&lt;br /&gt;Nota 2: Si usas ubuntu,debian o suse deberás editar el archivo /etc/squid/squid.conf para agregar la linea visible_hostname y de argumento&lt;br /&gt;colocas el nombre de la máquina ( si no sabes cual es, ejecuta el comando hostname ), ejemplo visible_hostname localhost.localdomain&lt;br /&gt;&lt;br /&gt;    Y luego configure su navegador para que navegue a través del proxy, si usa firefox, ejecute en el menú "Editar -&gt; Preferencias y en la ventana que se abre dar click en el botón de "Avanzado", luego en la pestaña de "red" -&gt; Conexión y le da click en el botón "Configuración", en donde debe seleccionar la opción "Configuración manual del proxy"; Donde dice "Proxy HTTP:" coloca la dirección del proxy, que para nosotros sera localhost y el puerto será el 3128 que es el de defecto de squid, aceptas, cierras y pruebas si puedes navegar normalmente en internet.&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;Instalación de DansGuardian:&lt;br /&gt;&lt;br /&gt;    DansGuardian por los momentos aún no es parte de los repositorios oficiales de fedora, desconozco los motivos, sin embargo puedes instalarlo via yum si tienes los repositorios de dries configurados ( es la mejor manera si se quiere tener las últimas actualizaciones del programa ), yo prefiero instalarlo a mano, ya que este paquete no pide ninguna dependencia importante que yo sepa, para instalarlo ejecuta el siguiente comando:&lt;br /&gt;&lt;br /&gt;[root@andromeda ]# rpm -Uvh http://ftp.belnet.be/packages/dries.ulyssis.org/fedora/fc7/i386/dries/RPMS/dansguardian-2.8.0.6-1.2.fc7.rf.i386.rpm&lt;br /&gt;&lt;br /&gt;*Nota 1: Si el link anterior le da error probablemente el link no esta disponible debido a que el paquete cambio de versión, simplemente navegue el repositorio en la siguiente dirección: http://ftp.belnet.be/packages/dries.ulyssis.org/fedora/fc7/i386/dries/RPMS/ y ubique a dansguardian allí, luego ejecute el comando rpm -Uvh con dicho link como argumento.&lt;br /&gt;*Nota 2: El paquete si se encuentra en los repositorios de ubuntu y de debian, para instalarlo ejecuta "aptitude install dansguardian".&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;    Realmente DansGuardian, no ofrece ningún tipo de problema al momento de instalar en Fedora, ni necesita una post-configuración realmente importante por los momentos, luego de instalar SARG, procederemos a probar todo y a explicar el mantenimiento y post-configuración que requiere cada una de estas herramientas.&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;Instalación de SARG:&lt;br /&gt;&lt;br /&gt;    Realmente SARG en su configuración más tradicional requiere de un webserver para poder funcionar, sin embargo esto no es obligatorio, ya que se pueden visualizar sus páginas webs directamente de forma local abriendolas desde un browser ( firefox ) como cualquier tipo de archivo, si se desea tener SARG para poder visualizar las estadisticas desde cualquier lado remotamente se debe instalar un webserver y se recomienda para ello lighttpd o thttpd ya que ambos son muy livianos y casi no consumen recursos además de ser ideales para servir páginas web que estan realizadas enteramente en html.&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;    Para instalar SARG, por comodidad usaremos el paquete en formato rpm construido para Fedora Core 6, no hay ningún inconveniente del tipo de vista tecnico que impida dicha acción, sin embargo debido a que SARG no está directamente empaquetado y mantenido por la comunidad de Fedora no tenemos una versión disponible en los repositorios oficiales para Fedora 7,  que es la versión actual de Fedora. Sin embargo si desea un paquete más actualizado y construido especificamente para su arquitectura y versión de Fedora, pueda agarrar el source rpm desde:&lt;br /&gt;&lt;br /&gt;http://dag.wieers.com/rpm/packages/sarg/sarg-2.2.3-1.rf.src.rpm&lt;br /&gt;&lt;br /&gt;    Y usar rpmbuild para generar su propio rpm, el proceso siguiente es opcional, recuerde que pare efectos de este how to, usaremos el rpm para Fedora Core 6.&lt;br /&gt;&lt;br /&gt;[root@andromeda ]# rpm -ivh http://dag.wieers.com/rpm/packages/sarg/sarg-2.2.3-1.rf.src.rpm&lt;br /&gt;&lt;br /&gt;[root@andromeda ]# rpmbuild -ba /usr/src/redhat/SPECS/sarg.spec&lt;br /&gt;*Nota: Puede editar el archivo SPEC y cambiar la versión de Fedora y la arquitectura, de ser necesario, también debe disponer del paquete rpmbuild ( yum install rpm-build ).&lt;br /&gt;&lt;br /&gt;    Luego instale el rpm que encontrara en algún directorio dentro de /usr/src/redhat/RPMS/&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;    Para instalar SARG ( el rpm de Fedora Core 6 ), simplemente ejecute el siguiente comando:&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;[root@andromeda ]# rpm -ivh http://ftp.belnet.be/packages/dries.ulyssis.org/fedora/fc6/i386/RPMS.dries/sarg-2.2.1-1.fc6.rf.i386.rpm&lt;br /&gt;&lt;br /&gt;    Este rpm, viene realmente completo, el comando ejecutable es "sarg", deberá ejecutarlo cada vez que desee un reporte al instante, sin embargo sarg  en este rpm, contiene algunos archivos para el crontab, los cuales permiten a sarg hacer reportes, diarios, semanales y mensuales de las actividades de proxy.&lt;br /&gt;&lt;br /&gt;    SARG, por los momentos no requiere ningún tipo de post-configuración, si se desea probar el funcionamiento de SARG, debe anteriormente haber navegado algo usando el proxy Squid, para tener algunos logs generados y ejececutar el siguiente comando:&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;[root@andromeda ]# sarg&lt;br /&gt;&lt;br /&gt;    Luego simplemente colocamos la siguiente dirección en el navegador firefox: /var/www/sarg/ONE-SHOT/ y observaremos un pequeño reporte estadistico generado.&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;Imagen de SARG&lt;br /&gt;&lt;br /&gt;Post-Configuración y uso del Control Parental&lt;br /&gt;&lt;br /&gt;    Bueno si hemos llegado a este punto sin ningún tipo de problema, ya debemos tener las 3 herramientas instaladas, las cuales no han llevado ningún tipo de configuración de parte nuestra, esto es debido a que los archivos de configuración que traen por defecto estas aplicaciones estan realizados para funcionar al menos para un entorno local, como el que planeamos darle acá, si deseamos que por ejemplo SARG nos muestre los reportes en castellano, o DansGuardian nos muestre la página de redirección ( o bloqueo ) en castellano, debemos editar dichos archivos, estos se encuentran en:&lt;br /&gt;&lt;br /&gt;/etc/squid/squid.conf para Squid&lt;br /&gt;/etc/dansguardian/dansguardian.conf para DansGuardian&lt;br /&gt;/etc/sarg/sarg.conf para SARG ( en otras distribuciones puede estar en /etc/squid/ )&lt;br /&gt;&lt;br /&gt;    Una de las cosas a tomar en cuenta en la post-configuración es la de no dejar el puerto del Squid y el de DansGuardian libres, o visibles desde el exterior ( Internet ), aunque no esten configurados para aceptar peticiones desde allí, para evitar esto, debemos agregar las siguientes linea al archivo de configuración del firewall, que se encuentra en /etc/sysconfig/iptables&lt;br /&gt;&lt;br /&gt;-A RH-Firewall-1-INPUT -p tcp --dport 3128 -j DROP&lt;br /&gt;-A RH-Firewall-1-INPUT -p tcp --dport 8080 -j DROP&lt;br /&gt;&lt;br /&gt;Nota: Asegurate de colocar dicha linea antes de: -A RH-Firewall-1-INPUT -j REJECT --reject-with icmp-host-prohibited COMMIT&lt;br /&gt;&lt;br /&gt;    Si usted no dispone de dicho archivo, generelo con una configuración minima, con el siguiente utilitario:&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;[root@andromeda ]# system-config-securitylevel&lt;br /&gt;&lt;br /&gt;    Otra cosa a tener en cuenta, es que ahora el puerto para usar el proxy será el 8080, es decir el puerto del DansGuardian, ya que de esta manera estaremos usando el filtro de contenido, si seguimos usando el puerto 3128 el de defecto de Squid, nos estaremos saltando el filtro de contenido, por lo tanto modifique el puerto del proxy en la configuración del firefox.&lt;br /&gt;&lt;br /&gt;    Así que debemos asegurarnos que los chicos de la casa, no intenten burlar el filtro de contenido al usar squid a través del puerto 3128 directamente, hay varias maneras de hacerlo, pero para mi, la más inmediata es evitar que ellos puedan modificar la configuración del firefox o generar un nuevo perfil de usuario en firefox, para esto, simplemente cambiamos la permisología y el dueño de dichos archivos:&lt;br /&gt;&lt;br /&gt;Suponiendo que el usuario se llama fulanito&lt;br /&gt;&lt;br /&gt;[root@andromeda ]# chown root:root /home/fulanito/.mozilla/firefox&lt;br /&gt;&lt;br /&gt;[root@andromeda ]# chmod 775 /home/fulanito/.mozilla/firefox&lt;br /&gt;El directorio donde se encuentra el perfil de firefox por lo general tiene un nombre aleatoreo, en mi caso:&lt;br /&gt;&lt;br /&gt;[root@andromeda ]# chown root:root /home/fulanito/.mozilla/firefox/kht9gpwh.default/prefs.js&lt;br /&gt;&lt;br /&gt;[root@andromeda ]# chmod 775 /home/fulanito/.mozilla/firefox/kht9gpwh.default/prefs.js&lt;br /&gt;De esta manera el usuario no podrá modificar las configuraciones acerca del proxy, en el navegador firefox.&lt;br /&gt;&lt;br /&gt;Personalización y mantenimiento de Dansguardian&lt;br /&gt;&lt;br /&gt;    Ahora DansGuardian y las demás herramientas se encuentran listas para ser usadas, la configuración minima de DansGuardian ofrece cierto nivel de protección sin embargo a medida que lo estemos usando, nos daremos cuenta que necesita cierta personalización, a tal efecto explicaremos un poco como hacerlas.&lt;br /&gt;&lt;br /&gt;    Dansguardian se compone de una serie de archivos de texto, en donde se especifica una serie de parametros que el toma en cuenta para hacer el bloqueo, dichos archivos estan plenamente documentados ( basta con abrirlos y leerlos ) y se encuentran dentro del directorio /etc/dansguardian , entre los cuales tenemos:&lt;br /&gt;&lt;br /&gt;   1. bannedextensionlist: Este archivo contiene un listado de extensiones de archivos a ser bloqueadas, probablemente usted quiera comentar, las lineas correspondientes a archivos de documentos como .doc, .xls y .ppt&lt;br /&gt;   2. bannediplist: Este archivo contiene un listado de direcciones ips a ser evitadas de usar nuestro proxy, debido a que estamos usando el mismo localmente, este archivo no lo utilizaremos&lt;br /&gt;   3. bannedmimetypelist: Un truco muy común para saltarse las restricciones de bannedextensionlist es cambiando las extensiones de los archivos, pero si usamos los Mime Types de los archivos ( la metadata del archivo no cambia asi cambiemos la extensión ), no podrán saltar el filtro, si desea conseguir Mime Types para algún tipo de archivo en especifico revise el archivo /etc/mime.types&lt;br /&gt;   4. bannedphraselist: Este archivo mantiene una lista de frases a ser baneadas.&lt;br /&gt;   5. bannedregexpurllist: Este archivo es uno de los más importantes de DansGuardian, ya que permite bloquear sitios basado en expresiones regulares, una de ellas por ejemplo ( que no se encuentra allí ) para banear sitios de invite y azar es la siguiente: (poker|casino|kasino|poquer|blackjack)&lt;br /&gt;   6. bannedsitelist: Cual dirección ip o dominio que coloquemos aca será bloqueado inmediatamente ( no es necesario colocar www. ó http:// )&lt;br /&gt;   7. bannedurllist: En este archivo especificamos url's o direcciones en especifico de un sitio, el cual será baneado, pero dejando el resto el sitio intacto&lt;br /&gt;   8. banneduserlist: Este archivo puede contener un listado de usuarios del proxy baneados, solo es util si tenemos autenticación de usuarios en el proxy.&lt;br /&gt;   9. contentregexplist: Este archivo contiene algunas expresiones regulares más complejas, pero que no hacen que el sitio sea baneado, si no más bien reemplazan la expresión encontrada por otra cosa, frase o palabra   ( adentro hay un ejemplo interesante para remover pop-ups ).&lt;br /&gt;  10. exceptioniplist: Este archivo debe contener un listado de direcciones ips ( de usuarios de una red LAN ), a las cuales el filtro de contenido no afectará, como estamos usandolo localmente, esta función no es útil.&lt;br /&gt;  11. exceptionphraselist: Este archivo debe contener un listado de palabras que si son encontradas en el mismo sitio junto con alguna de bannedphraselist, el sitio no podrá ser baneado, por ejemplo si se consigue la palabra sex en el mismo sitio web que education o medical.&lt;br /&gt;  12. exceptionsitelist: Acá se especificarán un listado de sitios webs, que no deberán ser baneados, probablemente quiera que cualquier sitio .edu ó .gob no sea bloqueado por el filtro de contenido.&lt;br /&gt;  13. exceptionurllist: si se tiene algún sitio baneado completamente, podrás especificar acá un área en especifico de este, para que pueda ser visualizada ( manteniendo el ban al resto del sitio ).&lt;br /&gt;  14. exceptionuserlist: Cualquier usuario que coloques acá no será afectado por el filtro de contenido.&lt;br /&gt;  15. greysitelist: Es muy similar a exceptionsitelist, la unica diferencia es que exceptionsitelist desbanea un sitio por completo, en cambio greysitelist desbanea si el sitio se encuentra bloqueado directamente, pero deja que pueda ser analizado por DansGuardian en sistaxis de contenido. &lt;br /&gt;  16. greyurllist: Parecido a greysitelist pero en vez de ser a un sitio completo es a un área de el, definido por un url.&lt;br /&gt;  17. pics: Esto habilita filtraddo de contenido de imágenes basado en sus colores RGB y determinando el nivel de desnudez de la imágen ( en caso de ser una persona ), por razones de rendimiento y que esta funcionabilidad esta considerada aún como experimental, desactivarla colocando el valor enablePICS = off&lt;br /&gt;  18. weightedphraselist: En este archivo se expecifican las rutas a otros archivos en donde se encuentran listados de palabras y porcentajes de ponderación de ellas, debido a estos niveles DansGuardian encuentra conveniente banear o no cierta página, es decir si se encuentra la palabra sexo en una página web, esta no es baneada inmediatamente, debe repetirse cierto numero de veces en dicha página para que pueda ocurrir, esto evita que muchos sitios puedan ser baneados accidentalmente, es válido ir modificando estos valores según nuestra necesidad a medida que vamos usando el filtro de contenido.&lt;br /&gt;&lt;br /&gt;    Como recomendación el archivo que más se usa es el de bannedsitelist, para mantener ordenados los sitios baneados  en este archivo se especifican las rutas a otros archivos de texto, los cuales son leidos ( dichos sitios son baneados directamente ), estos archivos pueden ser enriquecidos con tablas de sitios ya establecidas o blacklist ( que otras personas han recopilado ), de esta manera se agiliza el trabajo de DansGuardian, ya que este no tiene que "leer" cada página visitada, si no que ya cuenta con algunos listados ya pre-establecidos.&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;    Un sitio donde se pueden conseguir estos listados de archivos ( e incluso un script para actualizar el listado automáticamente ) o blacklist es:&lt;br /&gt;&lt;br /&gt;http://urlblacklist.com/?sec=download&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;Consideraciones finales&lt;br /&gt;&lt;br /&gt;    Podrán haber otras maneras de implementar un filtro de contenido con otros programas, incluso otras maneras de implementarlo con las herramientas acá descritas, si encuentra una mejor, por favor comparta y ayude a mejorar este pequeño manual.&lt;br /&gt;&lt;br /&gt; Si desea un mejor control de lo que hacen los usuarios de su computador, debería investigar la herramienta sabayon, la cual mezclada con gconf-editor&lt;br /&gt;podrá ayudarlo a generar perfiles de usuario para gnome, puede conseguir información acerca de sabayon en los siguientes links:&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;http://www.gnome.org/projects/sabayon/&lt;br /&gt;http://www.gnome.org/~seth/blog/sabayon&lt;br /&gt;&lt;br /&gt;    Podrá encontrar información de las cadenas modificables de un perfil de gnome a través de gconf-editor en:&lt;br /&gt;&lt;br /&gt;http://www.gnome.org/~bmsmith/gconf-docs/es/index.html&lt;br /&gt;&lt;br /&gt;    No explicamos estas herramientas acá debido a que no es la finalidad de este documento, probablemente me anime a escribir algo sobre estas herramientas en el futuro.&lt;br /&gt;&lt;br /&gt;    Si usted encuentra algún error ortografico, de sintaxis, desea hacer alguna corrección de este manual o simplemente quiere hacer una sugerencia, por favor no dude en comunicarse a mi correo electronico para hacermelo saber.&lt;br /&gt;&lt;br /&gt;Direcciones útiles:&lt;br /&gt;&lt;br /&gt;   1. http://www.zensur.freerk.com/index-es.htm#1.1  | Como evitar la censura en Internet&lt;br /&gt;   2. http://linsec.ca/bin/view/Main/DansGuardian | Tutorial de DansGuardian en Ingles&lt;br /&gt;   3. http://dansguardian.org/downloads/DG2.9.7.1_Squid_Slackware_10.2.pdf | Tutorial en Castellano de DansGuardian en pdf&lt;br /&gt;   4. http://dansguardian.org/?page=documentation | Documentación sobre DansGuardian en el sitio oficial del mismo&lt;br /&gt;   5. http://mirrors.evis.net.ph/dansguardian/downloads/detailedinstallation2-spanish.html | Otra guia de DansGuardian en Castellano&lt;br /&gt;   6. http://tech.groups.yahoo.com/group/dansguardian/ | Grupo de discusión a través de lista de correo de DansGuardian&lt;br /&gt;   7. http://www.squid-cache.org/ | Sitio oficial de Squid&lt;br /&gt;   8. http://bulma.net/impresion.phtml?nIdNoticia=441 | Tutorial sobre Squid en castellano&lt;br /&gt;   9. http://www2.idesoft.com/squid/manual.php | Otro Tutorial sobre Squid&lt;br /&gt;  10. http://sarg.sourceforge.net/pt-sarg.php | Sitio oficial de SARG&lt;br /&gt;  11. http://ferrolmoda.com/ficheros/final/sarg/sarg-0.1-es-ES.pdf | Tutorial sobre SARG en castellano en formato pdf&lt;br /&gt;  12. http://www.cantv.net/ciencia/seguridadeninternet/control_parental_info.asp | Control Parental ( Link Informativo )&lt;br /&gt;  13. http://www.el-carabobeno.com/p_pag_not.aspx?art=a120907c07&amp;id=t120907-c07 | Venezuela exige mediante decreto el uso de filtro de contenido en cibers&lt;br /&gt;&lt;br /&gt;Copyleft:&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;    Puedes copiar parte o todo este tutorial en tu web site o donde quieras con la intención o fin que mejor te parezca, con tal que dejes el contenido tal cual como esta, si en planeas usar solo alguna parte, por favor en alguna parte menciona el link original de donde se puede descargar este documento para que las personas que lo lean puedan conseguir versiones actualizadas del mismo, con el debido credito de los autores y si lo usas, me sentiría agradecido de que me informaras al respecto, para tener una idea de la difusión de este material.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5950429174584838030-1291278665350334891?l=caerices.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://caerices.blogspot.com/feeds/1291278665350334891/comments/default' title='Enviar comentarios'/><link rel='replies' type='text/html' href='http://caerices.blogspot.com/2009/10/control-parental-con-squid-dansguardian.html#comment-form' title='0 comentarios'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5950429174584838030/posts/default/1291278665350334891'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5950429174584838030/posts/default/1291278665350334891'/><link rel='alternate' type='text/html' href='http://caerices.blogspot.com/2009/10/control-parental-con-squid-dansguardian.html' title='Control Parental con Squid, DansGuardian y  SARG'/><author><name>caerices</name><uri>http://www.blogger.com/profile/17494035119607034630</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='24' height='32' src='http://3.bp.blogspot.com/_w44tDpxaU14/SjfWwlmjQ_I/AAAAAAAAAAY/GCvAuqbqu0o/S220/Cesar.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-5950429174584838030.post-5230395424192554302</id><published>2009-09-09T13:53:00.002-04:00</published><updated>2009-09-09T13:57:36.687-04:00</updated><title type='text'>Actualizaciones de Seguridad Postgres</title><content type='html'>El proyecto PostgreSQL ha liberado el dia de hoy versiones de&lt;br /&gt;actualizacion para todas sus ramas activas, estas incluyen las&lt;br /&gt;siguientes: 8.4.1; 8.3.8; 8.2.14; 8.1.18; 8.0.22 y 7.4.26. Estas&lt;br /&gt;versiones corrigen un problema de seguridad "moderado" y otros dos de&lt;br /&gt;"bajo riesgo": uno en la autenticacion, un riesgo de ataque de&lt;br /&gt;denegacion de servicio y un riesgo de escalacion de privilegios. Todos&lt;br /&gt;los usuarios deberian actualizar sus instalaciones de base de datos&lt;br /&gt;tan rapido como sea razonablemente posible.&lt;br /&gt;&lt;br /&gt;Esta version de actualizacion tambien arregla un problema que ha&lt;br /&gt;molestado a muchos usuarios de PostgreSQL en Windows: el problema de&lt;br /&gt;"could not reattach shared memory" ("no se puede readjuntar la memoria&lt;br /&gt;compartida"), y actualiza los archivos de las zonas horarias para&lt;br /&gt;varios paises. Hay tambien otros 23 arreglos menores, algunos de ellos&lt;br /&gt;afectan solo a la version 8.4. Vea las notas de version para los&lt;br /&gt;detalles completos.&lt;br /&gt;&lt;br /&gt;Al igual que con otras versiones menores, no es necesario respaldar y&lt;br /&gt;restaurar la base de datos para realizar la actualizacion; solo es&lt;br /&gt;necesario bajar el servicio de PostgreSQL y actualizar los binarios.&lt;br /&gt;Usuarios que se hayan saltado mas de una version de actualizacion&lt;br /&gt;deberian chequear las notas de version para pasos adicionales&lt;br /&gt;post-actualizacion.&lt;br /&gt;&lt;br /&gt;* Notas de la version:&lt;br /&gt;&lt;a href="http://www.postgresql.org/docs/current/static/release.html"&gt;http://www.postgresql.org/docs/current/static/release.html&lt;/a&gt;&lt;br /&gt;* Paquetes de instalacion: &lt;a href="http://www.postgresql.org/download/"&gt;http://www.postgresql.org/download/&lt;/a&gt;&lt;br /&gt;* Codigo fuente: &lt;a href="http://www.postgresql.org/ftp/source/"&gt;http://www.postgresql.org/ftp/source/&lt;/a&gt;&lt;br /&gt;* Detalle de los problemas de seguridad arreglados:&lt;br /&gt;&lt;a href="http://www.postgresql.org/support/security"&gt;http://www.postgresql.org/support/security&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;Traducido por Jaime Casanova&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5950429174584838030-5230395424192554302?l=caerices.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://caerices.blogspot.com/feeds/5230395424192554302/comments/default' title='Enviar comentarios'/><link rel='replies' type='text/html' href='http://caerices.blogspot.com/2009/09/actualizaciones-de-seguridad-postgres.html#comment-form' title='0 comentarios'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5950429174584838030/posts/default/5230395424192554302'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5950429174584838030/posts/default/5230395424192554302'/><link rel='alternate' type='text/html' href='http://caerices.blogspot.com/2009/09/actualizaciones-de-seguridad-postgres.html' title='Actualizaciones de Seguridad Postgres'/><author><name>caerices</name><uri>http://www.blogger.com/profile/17494035119607034630</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='24' height='32' src='http://3.bp.blogspot.com/_w44tDpxaU14/SjfWwlmjQ_I/AAAAAAAAAAY/GCvAuqbqu0o/S220/Cesar.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-5950429174584838030.post-8734895688375114251</id><published>2009-08-26T11:46:00.002-04:00</published><updated>2009-08-26T11:49:33.392-04:00</updated><title type='text'>Balanceo de Carga de Aplicaciones Web y Replicación de Sesiones en memoria con Tomcat y Apache</title><content type='html'>Posted in Aplicaciones Web&lt;br /&gt;&lt;br /&gt;La combinación de Tomcat, Apache y mod_jk puede ser una buena opción para una solución escalable y robusta para aplicaciones web basadas en JSPs / Servlets.&lt;br /&gt;&lt;br /&gt;Escalabilidad y tolerancia a caidas de sesión HTTP se pueden conseguir de una manera sencilla con un contenedor ligero de servlets como Tomcat, que ofrece funcionalidades de grupo (cluster).&lt;br /&gt;&lt;br /&gt;El Balanceo de carga se consigue mediante el módulo mod_jk apache, que distribuye las peticiones HTTP con un simple mecanismo round robin a través del protocolo AJP.&lt;br /&gt;&lt;br /&gt;(mod_jk parece ser el mejor y más extendido conector Tomcat - Apache)&lt;br /&gt;&lt;br /&gt;Con el fin de ofrecer una tolerancia a caídas de la sesión HTTP (evitar la pérdida de la sesión HTTP en caso de fallo de la instancia de Tomcat donde se creó la sesión), la replicación de sesiones puede ser utilizada.&lt;br /&gt;&lt;br /&gt;Tomcat puede compartir sesiones a través de una base de datos, un archivo o en memoria.&lt;br /&gt;&lt;br /&gt;La arquitectura global se podría resumir de la siguiente forma:&lt;br /&gt;&lt;br /&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://3.bp.blogspot.com/_w44tDpxaU14/SpVZQ8QEADI/AAAAAAAAACQ/43KYN1fB0F0/s1600-h/gg.png"&gt;&lt;img style="display:block; margin:0px auto 10px; text-align:center;cursor:pointer; cursor:hand;width: 320px; height: 179px;" src="http://3.bp.blogspot.com/_w44tDpxaU14/SpVZQ8QEADI/AAAAAAAAACQ/43KYN1fB0F0/s320/gg.png" border="0" alt=""id="BLOGGER_PHOTO_ID_5374299877922832434" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;Balanceo de Carga de Aplicaciones Web y Replicación de Sesiones en memoria con Tomcat y Apache&lt;br /&gt;&lt;br /&gt;Tomcat utiliza un mecanismo muy simple de agrupación (clustering):&lt;br /&gt;&lt;br /&gt;La agrupación de miembros se establece utilizando pings multicast. Una vez que un ping multicast es recibido, el miembro es agregado a la agrupación. Cuando se produce la próxima solicitud de replicación, la instancia que envió la petición utilizará la información de host y puerto para establecer un socket TCP. Los datos de sesión son entonces serializados y enviados a través del socket.&lt;br /&gt;&lt;br /&gt;Es posible establecer un primer punto de partida para esta arquitectura de forma rápida y sencilla, como se muestra a continuación, usando el servidor HTTP Apache 2.2.11, el módulo mod_jk 1.2.28, Apache Tomcat 6.0.18 y Mac OS X 10.5 .6 (Darwin 9.6.0).&lt;br /&gt;&lt;br /&gt;En este ejemplo, un Servidor Apache HTTP aplicará un balanceo de carga entre dos instancias de Tomcat, a través del módulo mod_jk.&lt;br /&gt;&lt;br /&gt;(dependiendo de los derechos de tu usuario, algunos comandos sudo y chmod pueden ser necesarios)&lt;br /&gt;1. JDK&lt;br /&gt;&lt;br /&gt;Toda versión de Mac OS X viene con Java de fábrica, y las nuevas versiones de Java se pueden obtener a través de Actualización de Software.&lt;br /&gt;&lt;br /&gt;Java está instalado como un framework en Mac OS X, y todas las versiones instaladas se puede encontrar en / System / Library / Frameworks / JavaVM.framework / Versions (Mac OS X 10.5) y se gestionan a través de las Preferencias de Java.&lt;br /&gt;&lt;br /&gt;En Mac OS X, la variable de entorno JAVA_HOME debe apuntar siempre a / Library / Java / Home.&lt;br /&gt;&lt;br /&gt;Esto se puede establecer a través del comando setenv (csh) o export (bash), y se puede ejecutar en el arranque para un usuario específico a través de la herramienta PropertyListEditor.&lt;br /&gt;&lt;br /&gt;export JAVA_HOME=/Library/Java/Home&lt;br /&gt;&lt;br /&gt;Java ya debería ser parte de la variable de entorno PATH, si no:&lt;br /&gt;&lt;br /&gt;export PATH=${PATH}:${JAVA_HOME}/bin&lt;br /&gt;&lt;br /&gt;2. Xcode&lt;br /&gt;&lt;br /&gt;La instalación de Xcode es una solución simple para obtener todas las herramientas necesarias para la compilación de Apache y Tomcat.&lt;br /&gt;3. Apache Ant&lt;br /&gt;&lt;br /&gt;Apache Ant es necesario para construir Tomcat, y puede ser instalado primeramente descargando el código fuente y, a continuación, simplemente:&lt;br /&gt;&lt;br /&gt;cd &lt; directorio_de_la_distribución_Ant &gt;&lt;br /&gt;sh build.sh -Ddist.dir=&lt; directorio_de_la_distribución_Ant &gt; dist&lt;br /&gt;&lt;br /&gt;Esto creará los archivos binarios en &lt; directorio_de_la_distribución_Ant &gt; directorio / bin.&lt;br /&gt;&lt;br /&gt;(Yo tuve que descargar el archivo jar de JUnit y copiarlo en &lt; directorio_de_la_distribución_Ant &gt; / lib / optativo para la compilación)&lt;br /&gt;&lt;br /&gt;Recuerda configurar la variable de entorno:&lt;br /&gt;&lt;br /&gt;export ANT_HOME=&lt; ant_home &gt;&lt;br /&gt;&lt;br /&gt;y configurar la ruta:&lt;br /&gt;&lt;br /&gt;export PATH=${PATH}:${ANT_HOME}/bin&lt;br /&gt;&lt;br /&gt;4. Apache Tomcat&lt;br /&gt;&lt;br /&gt;Después de descargar la distribución de Tomcat, simplemente:&lt;br /&gt;&lt;br /&gt;    cd &lt; directorio_de_la_distribución_Tomcat &gt;&lt;br /&gt;    ant download&lt;br /&gt;    ant&lt;br /&gt;&lt;br /&gt;Después de esto, los binarios pueden ser encontrados en &lt; directorio_de_la_distribución_Tomcat &gt; / ouput /build y se pueden copiar a dos directorios tomcat1 y tomcat2.&lt;br /&gt;&lt;br /&gt;Después de aplicar el comando chmod a los archivos bin / *.sh para que sean ejecutables, y crear el directorio /logs, el archivo de configuración tomcat conf / server.xml debe ser modificado (para tomcat1 y tomcat2):&lt;br /&gt;# El puerto shutdown debe ser diferente para ambos tomcats:&lt;br /&gt;&lt;br /&gt;&lt; Server port="8005" shutdown="SHUTDOWN" &gt;&lt;br /&gt;&lt;br /&gt;# El conector HTTP puede ser comentado, ya que será el Servidor Apache HTTP que gestionará el tráfico HTTP:&lt;br /&gt;&lt;br /&gt;&lt; !--&lt; Connector port="8081" protocol="HTTP/1.1" connectionTimeout="20000"      redirectPort="8443" / &gt; -- &gt;&lt;br /&gt;&lt;br /&gt;# El Puerto del conector AJP debe ser diferente para cada tomcat:&lt;br /&gt;&lt;br /&gt;    &lt; Connector port="8009" protocol="AJP/1.3" redirectPort="8443" / &gt;&lt;br /&gt;&lt;br /&gt;# El atributo jvmRoute deben añadirse al elemento engine, y debe ser diferente para cada tomcat:&lt;br /&gt;&lt;br /&gt;    &lt; Engine name="Catalina" defaultHost="localhost" jvmRoute="tomcat1" &gt;&lt;br /&gt;&lt;br /&gt;# Descomente elemento cluster:&lt;br /&gt;&lt;br /&gt;&lt; Cluster className="org.apache.catalina.ha.tcp.SimpleTcpCluster"/ &gt;&lt;br /&gt;&lt;br /&gt;Por último, una pequeña aplicación Web de test puede ser copiada en el directorio webapps de cada tomcat.&lt;br /&gt;&lt;br /&gt;La aplicación web contiene una jsp que muestra el identificador de sesión y la instancia tomcat donde se está ejecutando, y debe ser modificada para cada tomcat:&lt;br /&gt;&lt;br /&gt;&lt;%@page contentType="text/html"%&gt; &lt;html&gt; &lt;head&gt;&lt;br /&gt;&lt;title&gt;Session Example: session.jsp&lt;/title&gt;&lt;/head&gt;&lt;br /&gt;&lt;body&gt; TOMCAT 1: This is the session id &lt;STRONG&gt;&lt;%= session.getId()%&gt;&lt;/STRONG&gt; &lt;BR&gt; &lt;% if ( session.isNew() )&lt;br /&gt; { %&gt;    This is a new session ! &lt;BR&gt; &lt;%} else { %&gt;    This is an&lt;br /&gt;existing session&lt;BR&gt; &lt;%}%&gt; &lt;/body&gt; &lt;/html&gt;&lt;br /&gt;&lt;br /&gt;5. Servidor Apache HTTP&lt;br /&gt;&lt;br /&gt;Mac OS X trae un Apache HTTP Server de fábrica, que puede ser lanzado por / usr / sbin / apachectl y configurado en / etc / apache / httpd.conf.&lt;br /&gt;&lt;br /&gt;En caso de que no quieras modificar el servidor por defecto de Mac OS X (probablemente una buena idea), es bastante fácil de instalar Apache HTTP Server.&lt;br /&gt;&lt;br /&gt;Basta con descargar el código fuente de Unix y ejecutar los siguientes comandos:&lt;br /&gt;&lt;br /&gt;     $ ./configure --prefix=PREFIX&lt;br /&gt;     $ make&lt;br /&gt;     $ make install&lt;br /&gt;     $ PREFIX/bin/apachectl start&lt;br /&gt;&lt;br /&gt;(donde PREFIX es el directorio donde será instalado Apache)&lt;br /&gt;&lt;br /&gt;Cuando lances bin / apachectl, recuerda usar la ruta completa, si no, será el Servidor Apache HTTP de Mac OS X el que se lanzará.&lt;br /&gt;6. mod_jk&lt;br /&gt;&lt;br /&gt;Con el fin de compilar e instalar mod_jk, simplemente descarga el código fuente, y a continuación, aplica los siguientes comandos:&lt;br /&gt;&lt;br /&gt;./configure –with-apxs=&lt;apache_home&gt;/bin/apxs&lt;br /&gt; cp ./apache-2.0/mod_jk.so &lt;apache_home&gt;/modules&lt;br /&gt;&lt;br /&gt;Una vez instalado, podemos modificar el fichero de configuración httpd.conf del Servidor Apache HTTP y añadir las siguientes líneas:&lt;br /&gt;&lt;br /&gt;LoadModule    jk_module  modules/mod_jk.so&lt;br /&gt;JkWorkersFile "/conf/workers.properties"&lt;br /&gt;JkLogFile     "/logs/mod_jk.log"&lt;br /&gt;JkLogLevel    info&lt;br /&gt;JkMount /test/* loadbalancer&lt;br /&gt;&lt;br /&gt;Estas líneas básicamente cargan el módulo mod_jk, configuran el log, y redirigen todas las solicitudes HTTP con URLs / test / * a la instancia de Tomcat “loadbalancer”, que se define en el archivo workers.properties.&lt;br /&gt;&lt;br /&gt;El archivo Workers.properties puede ser creado en / conf:&lt;br /&gt;&lt;br /&gt;(Los identificadores de instancias tomcat en la propiedad worker.list deben ser las mismas que las anteriormente especificadas en el atributo jvmRoute del archivo de configuración Tomcat)&lt;br /&gt;&lt;br /&gt;worker.list=tomcat1,tomcat2,loadbalancer&lt;br /&gt;&lt;br /&gt;worker.tomcat1.port=8009&lt;br /&gt;worker.tomcat1.host=localhost&lt;br /&gt;worker.tomcat1.type=ajp13&lt;br /&gt;worker.tomcat1.lbfactor=1&lt;br /&gt;&lt;br /&gt;worker.tomcat2.port=8010&lt;br /&gt;worker.tomcat2.host=localhost&lt;br /&gt;worker.tomcat2.type=ajp13&lt;br /&gt;worker.tomcat2.lbfactor=1&lt;br /&gt;&lt;br /&gt;worker.loadbalancer.type=lb&lt;br /&gt;worker.loadbalancer.balanced_workers=tomcat1,tomcat2&lt;br /&gt;worker.loadbalancer.sticky_session=0&lt;br /&gt;&lt;br /&gt;El archivo workers.properties define las diferentes instancias tomcat disponibles, y una instancia especial llamada “loadbalancer” que agrupa las diferentes instancias de tomcat que se utilizarán para el balanceo de carga.&lt;br /&gt;&lt;br /&gt;Otra propiedad importante es el « sticky sessions ». Si se configura a 0 (falso) las sesiones serán balanceadas entre las instancias tomcat, a diferencia de quedarse en la instancia tomcat donde fueron creadas.&lt;br /&gt;7. Pruebas&lt;br /&gt;&lt;br /&gt;Una vez que todo esté en marcha y funcionando (las dos instancias tomcat y apache), un navegador que apunte a http://localhost/test/test.jsp mostrará la aplicación web de test, que muestra el identificador de sesión y la instancia de tomcat en el que se está ejecutando.&lt;br /&gt;&lt;br /&gt;La primera vez que se accede a la página, una sesión se crea.&lt;br /&gt;&lt;br /&gt;Si la página se recarga, la sesión se conserva (el mismo identificador de sesión se muestra) y la solicitud se redirige a la segunda instancia de tomcat.&lt;br /&gt;&lt;br /&gt;Para cada recarga, se redirige la solicitud siguiendo un round robin.&lt;br /&gt;&lt;br /&gt;Si paramos una de las instancias de tomcat, en efecto la sesión se conserva, y las solicitudes se redirigen a la única instancia tomcat que queda.&lt;br /&gt;&lt;br /&gt;Si se arranca de nuevo la segunda instancia de tomcat, volverá a formar parte del agrupamiento, y recibirá peticiones HTTP.&lt;br /&gt;Conclusiones&lt;br /&gt;&lt;br /&gt;Obviamente, el ejemplo que aquí se explica es sólo la punta del iceberg, y no se sumerge en temas que se deben discutir cuando se considera la agrupación de instancias Tomcat.&lt;br /&gt;&lt;br /&gt;Algunas cuestiones abiertas que deben ser respondidas, pueden ser las siguientes:&lt;br /&gt;&lt;br /&gt;¿La replicación de sesión en memoria es la adecuada para tu escenario?&lt;br /&gt;&lt;br /&gt;Dependiendo del tamaño de tus datos en sesión, otros tipos de almacenamiento pueden ser considerados, como almacenamiento en archivo o una base de datos.&lt;br /&gt;&lt;br /&gt;¿Tu aplicación web es distribuible? ¿Si no es así, cuál es el coste de la adaptación del código?&lt;br /&gt;&lt;br /&gt;El simple hecho de añadir el elemento distributable al deployment descriptor de tu aplicación Web no la convertirá por arte de magia y al instante en adecuada para la distribución de sesiones.&lt;br /&gt;&lt;br /&gt;Este elemento simplemente indica que la aplicación web está programada adecuadamente para instalarse en un contenedor de servlets distribuido: es la responsabilidad de los ingenieros de software asegurar que el código se comporta correctamente en un escenario de agrupamiento (clustering).&lt;br /&gt;&lt;br /&gt;Las especificaciones Java Servlet (sección SRV.7.7.2 entornos distribuidos) y este gran artículo hablan de algunos de los principales puntos a verificar:&lt;br /&gt;&lt;br /&gt;    * Variables de instancia y variables estáticas no deben ser utilizadas para almacenar el estado de la aplicación&lt;br /&gt;    * ServletContext no debe ser utilizado para almacenar el estado de de la aplicación&lt;br /&gt;    * Cualquier objeto colocado en una HttpSession debe Serializable&lt;br /&gt;    * Hay que considerar la posibilidad de que algunos archivos pueden no existir en todas las instancias Tomcat, se debe asegurar que todos los archivos necesarios sean replicados en todas las máquinas&lt;br /&gt;    * Hay que considerar que la sincronización no es global y sólo funciona para la JVM local&lt;br /&gt;&lt;br /&gt;¿Se debe usar una replicación de todos-a-todos o solo al nodo backup?&lt;br /&gt;&lt;br /&gt;Tomcat puede realizar una replicación de sesión todos-a-todos o realizar copias a un solo nodo. Dependiendo del número de nodos, uno u otro será más eficiente.&lt;br /&gt;&lt;br /&gt;¿Hay algo más a tener en cuenta?&lt;br /&gt;&lt;br /&gt;Aunque los principios básicos de la agrupación de Tomcat son bastante simples, parece claro que no hay ninguna configuración única que se adapte a cualquier escenario: un gran trabajo de investigación y de lectura, testeo, experimentación y de ajuste, probablemente tendrá que hacerse antes de encontrar la combinación que se ajuste a las necesidades de la arquitectura del sistema.&lt;br /&gt;&lt;br /&gt;&lt;a href="http://dvrom.eu/es/2009/05/11/application-load-balancing-and-in-memory-session-sharing-with-tomcat-and-apache/"&gt;Fuente&lt;/a&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5950429174584838030-8734895688375114251?l=caerices.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://caerices.blogspot.com/feeds/8734895688375114251/comments/default' title='Enviar comentarios'/><link rel='replies' type='text/html' href='http://caerices.blogspot.com/2009/08/balanceo-de-carga-de-aplicaciones-web-y.html#comment-form' title='0 comentarios'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5950429174584838030/posts/default/8734895688375114251'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5950429174584838030/posts/default/8734895688375114251'/><link rel='alternate' type='text/html' href='http://caerices.blogspot.com/2009/08/balanceo-de-carga-de-aplicaciones-web-y.html' title='Balanceo de Carga de Aplicaciones Web y Replicación de Sesiones en memoria con Tomcat y Apache'/><author><name>caerices</name><uri>http://www.blogger.com/profile/17494035119607034630</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='24' height='32' src='http://3.bp.blogspot.com/_w44tDpxaU14/SjfWwlmjQ_I/AAAAAAAAAAY/GCvAuqbqu0o/S220/Cesar.jpg'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://3.bp.blogspot.com/_w44tDpxaU14/SpVZQ8QEADI/AAAAAAAAACQ/43KYN1fB0F0/s72-c/gg.png' height='72' width='72'/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-5950429174584838030.post-5141934390752972694</id><published>2009-08-26T08:45:00.002-04:00</published><updated>2009-08-26T10:36:31.928-04:00</updated><title type='text'>La primera version alpha de PostgreSQL 8.5</title><content type='html'>La primera version alpha de PostgreSQL 8.5, 8.5alpha1; esta ahora&lt;br /&gt;disponible. Esta version "inestable" incluye 36 parches agregados en&lt;br /&gt;el primer "commitfest" de este año. Descarguenlo ahora y prueben&lt;br /&gt;algunas de las nuevas caracteristicas por venir en el 8.5!&lt;br /&gt;&lt;br /&gt;Esta es la primera version alpha que hace el proyecto PostgreSQL. Se&lt;br /&gt;decidio empezar a hacer versiones alpha bajo el principio de "liberar&lt;br /&gt;temprano, liberar seguido", de modo que usuarios avanzados puedan&lt;br /&gt;probar las nuevas caracteristicas y el nuevo codigo tan pronto como&lt;br /&gt;sea posible para descubrir rapidamente como ajustar mejor las opciones&lt;br /&gt;y encontrar posibles problemas. Estas versiones alpha no son estables&lt;br /&gt;y no deberian ser usadas en produccion "nunca"; son solo para que&lt;br /&gt;desarrolladores prueben las nuevas caracteristicas. Por eso, solo se&lt;br /&gt;esta liberando la version 8.5alpha1 en forma de codigo fuente.&lt;br /&gt;&lt;br /&gt;Habran tres o cuatro alphas mas, aproximadamente cada 2 meses, antes&lt;br /&gt;de que haya una version 8.5beta. No hay ninguna garantia de que las&lt;br /&gt;caracteristicas o API's en los alphas esten presentes o se mantengan&lt;br /&gt;igual en la version final. Incluido en este alpha estan:&lt;br /&gt;&lt;br /&gt;* Restricciones unicas aplazables.&lt;br /&gt;* DROP COLUMN/CONSTRAINT IF EXISTS&lt;br /&gt;* EXPLAIN en formato XML y JSON&lt;br /&gt;* Entrada y salida de BYTEA como cadenas hex&lt;br /&gt;* pgbench multi-hilo&lt;br /&gt;* Mejoras al crear los ejecutables y documentacion&lt;br /&gt;&lt;br /&gt;Mas detalles estan disponibles en las Notas de Version incluidas en cada alpha:&lt;br /&gt;&lt;a href="http://developer.postgresql.org/pgdocs/postgres/release-8.5.html"&gt;Aqui&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;Pagina de informacion del Alpha:&lt;br /&gt;&lt;a href="http://www.postgresql.org/developer/alpha"&gt;Aqui.&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;Descargue el primer alpha aqui:&lt;br /&gt;&lt;a href="http://www.postgresql.org/ftp/source/8.5alpha1/"&gt;Aqui.&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;El Alpha1 actualmente solo esta disponible como codigo fuente.&lt;br /&gt;Paquetes binarios para algunos sistemas operativos estaran preparados&lt;br /&gt;en los siguientes dias.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5950429174584838030-5141934390752972694?l=caerices.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://caerices.blogspot.com/feeds/5141934390752972694/comments/default' title='Enviar comentarios'/><link rel='replies' type='text/html' href='http://caerices.blogspot.com/2009/08/la-primera-version-alpha-de-postgresql.html#comment-form' title='0 comentarios'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5950429174584838030/posts/default/5141934390752972694'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5950429174584838030/posts/default/5141934390752972694'/><link rel='alternate' type='text/html' href='http://caerices.blogspot.com/2009/08/la-primera-version-alpha-de-postgresql.html' title='La primera version alpha de PostgreSQL 8.5'/><author><name>caerices</name><uri>http://www.blogger.com/profile/17494035119607034630</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='24' height='32' src='http://3.bp.blogspot.com/_w44tDpxaU14/SjfWwlmjQ_I/AAAAAAAAAAY/GCvAuqbqu0o/S220/Cesar.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-5950429174584838030.post-5254987696043404888</id><published>2009-08-24T17:26:00.002-04:00</published><updated>2009-08-24T17:29:55.928-04:00</updated><title type='text'>Replicacion y Alta Disponibilidad en Postgres</title><content type='html'>Ua vez más la &lt;a href="http://www.postgresql-es.org/principal"&gt;lista de postgres en español&lt;/a&gt; ha traducido un documento muy interesante para nuestra Comunidad.&lt;br /&gt;&lt;br /&gt;En este artículo se muestra cómo instalar, configurar y mantener un clúster de servidores de bases de datos PostgreSQL gestionados mediante un middleware llamado pgpool-II sobre el sistema operativo Debian GNU/Linux.&lt;br /&gt;&lt;br /&gt;Dicho clúster ofrece capacidades de replicación, balanceo de carga y un pool de conexiones, y es capaz de realizar failover o degeneración de un nodo que deje de funcionar y de recuperar nodos caídos en línea (sin dejar de dar servicio). Se trata de un clúster activo-pasivo, si bien se hace uso del nodo pasivo para lectura con el propósito de mejorar la productividad del sistema.&lt;br /&gt;Índice&lt;br /&gt;&lt;br /&gt;  1. Introducción&lt;br /&gt;        1. Failover cluster&lt;br /&gt;        2. Sobre PostgreSQL&lt;br /&gt;        3. Sobre pgpool-II&lt;br /&gt;        4. Sobre Debian GNU/Linux&lt;br /&gt;  2. Arquitectura del sistema&lt;br /&gt;  3. Instalación de paquetes y configuración de dependencias&lt;br /&gt;  4. Configuración de PostgreSQL&lt;br /&gt;  5. Configuración de pgpool-II&lt;br /&gt;  6. Pruebas de replicación&lt;br /&gt;  7. Recuperación en línea&lt;br /&gt;  8. El Write-Ahead Log&lt;br /&gt;        1. Procedimiento completo&lt;br /&gt;        2. Primera fase&lt;br /&gt;        3. Segunda fase&lt;br /&gt;        4. Tercera fase&lt;br /&gt;        5. Pasos finales&lt;br /&gt;        6. Scripts necesarios&lt;br /&gt;              1. wal_archiving&lt;br /&gt;              2. pgpool-failover&lt;br /&gt;              3. pgpool-failback&lt;br /&gt;              4. base-backup&lt;br /&gt;              5. pgpool-recovery-pitr&lt;br /&gt;              6. pgpool_remote_start&lt;br /&gt;  9. Comandos de PCP&lt;br /&gt; 10. Simulación de caída y recuperación de un nodo&lt;br /&gt; 11. Alta disponibilidad de pgpool-II&lt;br /&gt;        1. El proyecto Linux High Availability&lt;br /&gt;        2. Instalación de Heartbeat&lt;br /&gt;        3. Configuración de Heartbeat&lt;br /&gt;        4. Simulación de la caída del servicio&lt;br /&gt; 12. Herramientas de monitorización&lt;br /&gt;        1. pg_osmem y pg_buffercache&lt;br /&gt;        2. pg_top&lt;br /&gt;        3. ps&lt;br /&gt;        4. pgd&lt;br /&gt;        5. iotop&lt;br /&gt; 13. Optimización de PostgreSQL&lt;br /&gt;        1. Autovacuum y cargas de datos&lt;br /&gt;        2. Procesos errantes&lt;br /&gt; 14. FAQ (Frequently Asked Question)&lt;br /&gt; 15. Bibliografía&lt;br /&gt;&lt;br /&gt;Introducción&lt;br /&gt;&lt;br /&gt;Failover cluster&lt;br /&gt;&lt;br /&gt;Un failover cluster (o clúster activo-pasivo) es un grupo de ordenadores independientes que trabajan conjuntamente para incrementar la disponibilidad de diversas aplicaciones y servicios. Los servidores en el clúster (llamados nodos) están interconectados mediante cables físicos y por software. Si uno de los nodos cae, otro empieza a dar servicio (proceso conocido como failover) sin necesidad de intervención humana. Esta guía describe los pasos para instalar y configurar un failover clúster con dos o más nodos.&lt;br /&gt;&lt;br /&gt;Sobre PostgreSQL&lt;br /&gt;&lt;br /&gt;PostgreSQL es la base de datos relacional de código abierto más avanzada del mundo. Distribuida bajo licencia BSD (del inglés, Berkeley Software Distribution), lleva más de 15 años desarrollándose y su arquitectura goza de una excelente reputación por su fiabilidad, integridad de datos y correctitud.&lt;br /&gt;&lt;br /&gt;PostgreSQL dispone de versiones para prácticamente todos los sistemas operativos y cumple totalmente con ACID (del inglés, Atomicity, Consistency, Isolation, Durability). Tiene soporte para claves extranjeras, joins, vistas, disparadores y procedimientos almacenados (en múltiples lenguajes de programación). Incluye la mayoría de los tipos de datos de SQL92 y SQL99 y, asimismo, soporta el almacenamiento de grandes objetos binarios, como imágenes, sonidos y vídeos. Tiene interfaces de programación nativas para C/C++, Java, .Net, Perl, PHP, Python, Ruby, Tcl y ODBC, entre otros, y una excepcional documentación.&lt;br /&gt;&lt;br /&gt;PostgreSQL ofrece sofisticadas características tales como control concurrente multiversión (MVCC), point in time recovery (PITR), tablespaces, replicación asíncrona, transacciones anidadas (savepoints), copias de seguridad en caliente/en línea, un sofisticado planificador/optimizador de consultas y write ahead logging para ser tolerante a fallos de hardware. Soporta juegos de caracteres internacionales, codificaciones de caracteres multibyte, Unicode y realiza ordenaciones dependiendo de la configuración de idioma local, de la diferenciación de mayúsculas y minúsculas y del formato. Es altamente escalable tanto en la cantidad bruta de datos que puede manejar como en el número de usuarios concurrentes que puede atender. Hay sistemas activos en producción con PostgreSQL que manejan más de 4 terabytes de datos.&lt;br /&gt;&lt;br /&gt;Sobre pgpool-II&lt;br /&gt;&lt;br /&gt;pgpool-II habla los protocolos de frontend y backend de PostgreSQL, y pasa las conexiones entre ellos. De ese modo, una aplicación de base de datos (frontend) cree que pgpool-II es el verdadero servidor de PostgreSQL, y el servidor (backend) ve a pgpool-II como uno de sus clientes. Debido a que pgpool-II es transparente tanto para el servidor como para el cliente, una aplicación de base de datos existente puede empezar a usarse con pgpool-II casi sin ningún cambio en su código fuente.&lt;br /&gt;&lt;br /&gt;pgpool-II funciona sobre Linux, Solaris, FreeBSD y la mayoría de las arquitecturas UNIX. Windows no está soportado. Las versiones de PostgreSQL soportadas son de la 6.4 para arriba. Para usar la paralelización de consultas es necesaria la versión 7.4 o superior.&lt;br /&gt;&lt;br /&gt;pgpool-II proporciona las siguientes características:&lt;br /&gt;&lt;br /&gt;   * Limita el excedente de conexiones. PostgreSQL soporta un cierto número de conexiones concurrentes y rechaza las que superen dicha cifra. Aumentar el límite máximo de conexiones incrementa el consumo de recursos y afecta al rendimiento del sistema. pgpool-II tiene también un límite máximo de conexiones, pero las conexiones extras se mantienen en una cola en lugar de devolver un error inmediatamente.&lt;br /&gt;   * Pool de conexiones. pgpool-II mantiene abiertas las conexiones a los servidores PostgreSQL y las reutiliza siempre que se solicita una nueva conexión con las mismas propiedades (nombre de usuario, base de datos y versión del protocolo). Ello reduce la sobrecarga en las conexiones y mejora la productividad global del sistema.&lt;br /&gt;   * Replicación. pgpool-II puede gestionar múltiples servidores PostgreSQL. El uso de la función de replicación permite crear una copia en dos o más discos físicos, de modo que el servicio puede continuar sin parar los servidores en caso de fallo en algún disco.&lt;br /&gt;   * Balanceo de carga. Si se replica una base de datos, la ejecución de una consulta SELECT en cualquiera de los servidores devolverá el mismo resultado. pgpool-II se aprovecha de la característica de replicación para reducir la carga en cada uno de los servidores PostgreSQL distribuyendo las consultas SELECT entre los múltiples servidores, mejorando así la productividad global del sistema. En el mejor caso, el rendimiento mejora proporcionalmente al número de servidores PostgreSQL. El balanceo de carga funciona mejor en la situación en la cuál hay muchos usuarios ejecutando muchas consultas al mismo tiempo.&lt;br /&gt;   * Paralelización de consultas. Al usar la función de paralelización de consultas, los datos pueden dividirse entre varios servidores, de modo que la consulta puede ejecutarse en todos los servidores de manera concurrente para reducir el tiempo total de ejecución. La paralelización de consultas es una solución adecuada para búsquedas de datos a gran escala.&lt;br /&gt;&lt;br /&gt;Sobre Debian GNU/Linux&lt;br /&gt;&lt;br /&gt;Debian GNU/Linux es un sistema operativo libre (el conjunto de programas básicos y utilidades que hacen que un ordenador funcione). Debian utiliza el núcleo Linux y las herramientas básicas de GNU. Para esta instalación se utilizará el sistema operativo Debian Lenny para la arquitectura x86_64 (AMD64/EM64T), partiendo de una instalación básica, sin ninguna tarea seleccionada en el selector de tareas del instalador. El sistema de ficheros elegido será XFS. La misma instalación puede obtenerse con Debian Etch y el repositorio de backports.&lt;br /&gt;&lt;br /&gt;Arquitectura del sistema&lt;br /&gt;&lt;br /&gt;El término clúster hace referencia a un conjunto de sistemas informáticos trabajando conjuntamente por un objetivo común. Como puede apreciarse, esta definición es muy genérica. No es, sino, un reflejo de la gran variedad y diversidad de acercamientos posibles a la hora de configurar un clúster y, por lo tanto, prueba de que el lector no debe tomar la arquitectura utilizada en el artículo más que como referencia y base para sus futuros trabajos.&lt;br /&gt;&lt;br /&gt;En el clúster de este artículo se persiguen dos objetivos: uno, la alta disponibilidad, y dos, el rendimiento. La funcionalidad que persigue el clúster es únicamente la de servidor de base de datos, pero lo hace a través de tres aplicaciones:&lt;br /&gt;&lt;br /&gt;   * PostgreSQL, el sistema gestor de bases de datos (S.G.B.D.)&lt;br /&gt;   * pgpool-II, el middleware que gestiona la alta disponibilidad de los servidores de PostgreSQL.&lt;br /&gt;   * Heartbeat, un software que usaremos para dar alta disponibilidad a pgpool-II y a la dirección IP de servicio.&lt;br /&gt;&lt;br /&gt;Esta configuración nos permite obtener alta disponibilidad de todos los servicios y recursos en las dos máquinas destinadas a este clúster. El diagrama de la arquitectura resultante sería el siguiente:&lt;br /&gt;Diagrama de la arquitectura del sistema&lt;br /&gt;&lt;br /&gt;Instalación de paquetes y configuración de dependencias&lt;br /&gt;&lt;br /&gt;Se toma como punto de inicio un sistema x86_64 con Debian GNU/Linux Etch o Lenny instalado. Se utilizarán las siguientes versiones de software:&lt;br /&gt;&lt;br /&gt;   * PostgreSQL 8.3.x&lt;br /&gt;   * pgpool-II 2.2.x&lt;br /&gt;   * Heartbeat 2.x&lt;br /&gt;&lt;br /&gt;Antes de empezar, instalaremos un conjunto de paquetes básico para cualquier sistema, así como una serie de utilidades que nos harán falta para la gestión y el mantenimiento del clúster:&lt;br /&gt;&lt;br /&gt;apt-get install ntp openssl file psmisc sysstat bzip2 unzip nmap dstat rsync wget ccze tcpdump pciutils dnsutils host&lt;br /&gt;&lt;br /&gt;rsync lo usaremos para la recuperación en línea de nodos, ntp para mantener el reloj del sistema sincronizado. El prototipo inicial de este clúster se probó en una máquina con dos instancias de Xen y una base de datos de prueba creada con pgbench. Más tarde se configuró una versión de preproducción sobre sendos Intel Quad Core con 8 GB de RAM y la versión final del clúster se configuró sobre dos nodos con doble Intel Quad Core cada uno y 16 GB de RAM. La base de datos final ocupa algo más de 30 GB y se encuentra sobre dos discos SAS de 15.000 RPM en RAID 1.&lt;br /&gt;&lt;br /&gt;A efectos de este artículo, a continuación se presenta un resumen de los datos de configuración que se usarán:&lt;br /&gt;&lt;br /&gt;   * Nodo 1&lt;br /&gt;         o Hostname: pgsql1.dominio.com&lt;br /&gt;         o Dirección IP de administración: 192.168.0.3&lt;br /&gt;   * Nodo 2&lt;br /&gt;         o Hostname: pgsql2.dominio.com&lt;br /&gt;         o Dirección IP de administración: 192.168.0.4&lt;br /&gt;   * Máscara de red de 24 bits.&lt;br /&gt;   * Dirección IP del router: 192.168.0.1&lt;br /&gt;   * pgpool-II&lt;br /&gt;         o Dirección IP de servicio: 192.168.0.2&lt;br /&gt;         o Puerto de gestión: 9898&lt;br /&gt;         o Puerto de servicio: 9999&lt;br /&gt;&lt;br /&gt;Los conceptos utilizados en esta descripción se irán explicando a lo largo del artículo. Es preciso que las entradas correspondientes a los datos anteriores existan en el fichero /etc/hosts:&lt;br /&gt;&lt;br /&gt;127.0.0.1      localhost.localdomain    localhost&lt;br /&gt;192.168.0.1    router.dominio.com       router&lt;br /&gt;192.168.0.2    pgpool2.dominio.com      pgpool2&lt;br /&gt;192.168.0.3    pgsql1.dominio.com       pgsql1&lt;br /&gt;192.168.0.4    pgsql2.dominio.com       pgsql2&lt;br /&gt;&lt;br /&gt;Empezaremos configurando PostgreSQL en ambos nodos pero pgpool-II sólo en el nodo pgsql1. Los comandos deberán ejecutarse como root o mediante sudo, a menos que se indique lo contrario (normalmente comandos que se ejecutarán con el usuario postgres).&lt;br /&gt;&lt;br /&gt;Las dependencias de compilación de pgpool-II (las cabeceras de la librería de PostgreSQL, el paquete de desarrollo de PostgreSQL para pogramación de servidores y las utilidades de compilación de GNU) las resolveremos mediante la instalación de los siguientes paquetes:&lt;br /&gt;&lt;br /&gt;apt-get install libpq-dev postgresql-server-dev-8.3 bison build-essential&lt;br /&gt;&lt;br /&gt;Una vez resueltas las dependencias, empezaremos instalando PostgreSQL en ambos nodos:&lt;br /&gt;&lt;br /&gt;apt-get install postgresql-8.3 postgresql-contrib-8.3 postgresql-doc-8.3 uuid libdbd-pg-perl&lt;br /&gt;&lt;br /&gt;La instalación por defecto de PostgreSQL en Debian ya nos deja un sistema gestor de base de datos funcionando. Finalmente, descargamos pgpool-II, lo descomprimimos e instalamos en /opt/pgpool2:&lt;br /&gt;&lt;br /&gt;cd /usr/local/src&lt;br /&gt;wget http://pgfoundry.org/frs/download.php/2191/pgpool-II-2.2.2.tar.gz&lt;br /&gt;tar --extract --gzip --file pgpool-II-2.2.2.tar.gz&lt;br /&gt;cd pgpool-II-2.2.2&lt;br /&gt;./configure --prefix=/opt/pgpool2&lt;br /&gt;make&lt;br /&gt;make install&lt;br /&gt;cd /usr/local/src/pgpool-II-2.2.2/sql/pgpool-recovery&lt;br /&gt;make&lt;br /&gt;make install&lt;br /&gt;su - postgres -c "psql -f /usr/local/src/pgpool-II-2.2.2/sql/pgpool-recovery/pgpool-recovery.sql template1"&lt;br /&gt;&lt;br /&gt;A partir de aquí, todas las bases de datos que creemos heredarán las funciones existentes en template1.&lt;br /&gt;&lt;br /&gt;Configuración de PostgreSQL&lt;br /&gt;&lt;br /&gt;Tal y como se ha dicho anteriormente, los siguientes pasos aplican a ambas instancias de PostgreSQL en los nodos pgsql1 y pgsql2.&lt;br /&gt;&lt;br /&gt;Empezaremos editando la configuración de PostgreSQL para permitir el acceso incondicional del usuario pgpool2, que será nuestro usuario de base de datos del clúster. Por incondicional nos referimos al uso del modo trust, que permite la validación del usuario sin necesidad de contraseña. Esto es un requerimiento de pgpool-II para el tipo de configuración del clúster que tendremos al final del artículo, por lo cuál deberemos prestar especial atención a los filtros de acceso por IP que configuremos tanto en los servidores PostgreSQL como en el cortafuegos de los nodos.&lt;br /&gt;&lt;br /&gt;Comenzaremos, como usuario postgres, añadiendo el usuario de base de datos (role) pgpool2, sin contraseña:&lt;br /&gt;&lt;br /&gt;su - postgres&lt;br /&gt;createuser --superuser pgpool2&lt;br /&gt;&lt;br /&gt;Para facilitar el trabajo en este artículo lo hemos dado de alta como superusuario. En realidad, si creamos la base de datos en todos los nodos como superadministrador postgres y le otorgamos propiedad al usuario pgpool2, éste puede ser un usuario con el role más básico (no superusuario, sin capacidad de crear bases de datos).&lt;br /&gt;&lt;br /&gt;Editamos ahora el fichero /etc/postgresql/8.3/main/pg_hba.conf y añadimos el acceso para el usuario pgpool2 desde la dirección IP donde se ejecutará pgpool-II (en estos momentos 192.168.0.3):&lt;br /&gt;&lt;br /&gt;# TYPE  DATABASE    USER        CIDR-ADDRESS          METHOD&lt;br /&gt;local   all         all                               ident sameuser&lt;br /&gt;host    all         all         127.0.0.1/32          md5&lt;br /&gt;host    all         pgpool2     192.168.0.3/32        trust&lt;br /&gt;host    all         all         ::1/128               md5&lt;br /&gt;&lt;br /&gt;Al igual que durante la creación del usuario pgpool2, para facilitar este artículo se permite el acceso a todas las bases de datos a dicho usuario. En un entorno de producción sería preciso restringir dicho acceso a la base de datos que se vaya a usar.&lt;br /&gt;&lt;br /&gt;Asimismo, si se quiere acceder directamente a la base de datos sin pasar por pgpool-II, por ejemplo para realizar pruebas de rendimiento o para su monitorización, deberán añadirse las direcciones IP de los clientes desde los que se conecten dichas aplicaciones. En este caso, si se desea, y siempre y cuando las direcciones IP de origen sean diferentes, puede cambiarse el método de autenticación a MD5 y crearse el usuario pgpool2 con contraseña.&lt;br /&gt;&lt;br /&gt;A continuación activamos el archivado del Write-Ahead Log (WAL) de PostgreSQL, pues nos hará falta para poder usar PITR (Point-In-Time Recovery) desde pgpool-II. Editamos el fichero de configuración /etc/postgresql/8.3/main/postgresql.conf y cambiamos los dos siguientes parámetros:&lt;br /&gt;&lt;br /&gt;archive_mode = on&lt;br /&gt;archive_command = 'exit 0'&lt;br /&gt;&lt;br /&gt;Ya que sólo haremos uso de la característica de PITR cuando vayamos a recuperar un nodo caído o añadir uno nuevo, por defecto hemos configurado el parámetro archive_command para que no haga nada (exit 0). Esto lo hacemos debido a que la activación o desactivación del archivado de ficheros WAL requiere de un reinicio del servidor, pero la alteración del comando o script que realiza la tarea de archivar el fichero WAL rotado por PostgreSQL tan sólo requiere de una recarga de la configuración.&lt;br /&gt;&lt;br /&gt;Así, PostgreSQL se comportará como si no estuviera archivando ficheros de log, generando dichos ficheros (de 16 MB cada uno) con normalidad en /var/lib/postgresql/8.3/main/pg_xlog y rotándolos a partir del octavo que almacene.&lt;br /&gt;Acto seguido crearemos el directorio /var/lib/postgresql/pg_xlog_archive, directorio donde archivaremos (copiaremos) los ficheros WAL cuando lo necesitemos, y le daremos permisos para el usuario postgres:&lt;br /&gt;&lt;br /&gt;mkdir --mode=700 /var/lib/postgresql/pg_xlog_archive&lt;br /&gt;chown postgres:postgres /var/lib/postgresql/pg_xlog_archive&lt;br /&gt;&lt;br /&gt;Por último, indicaremos a PostgreSQL que escuche en todas las interfaces pues, por defecto, sólo lo hace en el localhost. Editamos el fichero /etc/postgresql/8.3/main/postgresql.conf y cambiamos la siguiente directiva:&lt;br /&gt;&lt;br /&gt;listen_addresses = '*'&lt;br /&gt;&lt;br /&gt;También podemos restringirlo a 127.0.0.1 y la dirección IP administrativa del nodo (192.168.0.3 en el primer nodo, 192.168.0.4 en el segundo) para asegurarnos de que no esté escuchando en la dirección IP de servicio del clúster (la 192.168.0.2, que queremos utilizar únicamente para pgpool-II).&lt;br /&gt;&lt;br /&gt;Y reiniciamos PostgreSQL para activar los cambios:&lt;br /&gt;&lt;br /&gt;/etc/init.d/postgresql-8.3 restart&lt;br /&gt;&lt;br /&gt;Configuración de pgpool-II&lt;br /&gt;&lt;br /&gt;La configuración de pgpool-II la realizaremos únicamente en el nodo pgsql1, pues sólo en ese host lo tenemos instalado.&lt;br /&gt;&lt;br /&gt;pgpool-II proporciona una interfaz de gestión desde la cuál el administrador puede recoger el estado de pgpool-II y finalizar los procesos de pgpool-II a través de la red. El fichero pcp.conf es un fichero de nombres de usuario y contraseñas usado para autenticarse con la interfaz. Todos los comandos requieren que pcp.conf se haya configurado. Tras la instalación de pgpool-II se crea un fichero /opt/pgpool2/etc/pcp.conf.sample de ejemplo. Configurar ese fichero es tan sencillo como cambiarle el nombre al fichero y añadir el usuario y contraseña deseados.&lt;br /&gt;&lt;br /&gt;Por lo tanto, copiaremos el fichero de ejemplo a fichero deseado:&lt;br /&gt;&lt;br /&gt;cp --archive /opt/pgpool2/etc/pcp.conf.sample /opt/pgpool2/etc/pcp.conf&lt;br /&gt;&lt;br /&gt;Y lo editaremos para añadir nuestro usuario y contraseña en el formato:&lt;br /&gt;&lt;br /&gt;usuario:&lt;br /&gt;&lt;br /&gt;En este artículo se usará root como nombre de usuario. Para generar la suma MD5 de nuestra contraseña podemos usar la utilidad pg_md5:&lt;br /&gt;&lt;br /&gt;/opt/pgpool2/bin/pg_md5 -p&lt;br /&gt;password: &lt;password&gt;&lt;br /&gt;34b339799d540a72bf1c408c0e68afdd&lt;br /&gt;&lt;br /&gt;Luego creamos un fichero de configuración para pgpool-II a partir del que viene como ejemplo:&lt;br /&gt;&lt;br /&gt;cp --archive /opt/pgpool2/etc/pgpool.conf.sample /opt/pgpool2/etc/pgpool.conf&lt;br /&gt;&lt;br /&gt;Deberemos editar el fichero para configurarlo a nuestra medida. Para este artículo se configurarán las siguientes funcionalidades:&lt;br /&gt;&lt;br /&gt;   * Pool de conexiones.&lt;br /&gt;   * Replicación.&lt;br /&gt;   * Balanceo de carga.&lt;br /&gt;&lt;br /&gt;Empezaremos con una configuración básica para arrancar pgpool-II e iremos añadiendo funcionalidades. Editamos el fichero /opt/pgpool2/etc/pgpool.conf para dejarlo tal y como sigue:&lt;br /&gt;&lt;br /&gt;listen_addresses = '*'&lt;br /&gt;port = 9999&lt;br /&gt;pcp_port = 9898&lt;br /&gt;socket_dir = '/var/run/postgresql'&lt;br /&gt;pcp_socket_dir = '/var/run/postgresql'&lt;br /&gt;backend_socket_dir = '/var/run/postgresql'&lt;br /&gt;pcp_timeout = 10&lt;br /&gt;num_init_children = 32&lt;br /&gt;max_pool = 4&lt;br /&gt;child_life_time = 300&lt;br /&gt;connection_life_time = 0&lt;br /&gt;child_max_connections = 0&lt;br /&gt;client_idle_limit = 0&lt;br /&gt;authentication_timeout = 60&lt;br /&gt;logdir = '/var/run/postgresql'&lt;br /&gt;replication_mode = false&lt;br /&gt;load_balance_mode = false&lt;br /&gt;replication_stop_on_mismatch = false&lt;br /&gt;replicate_select = false&lt;br /&gt;reset_query_list = 'ABORT; RESET ALL; SET SESSION AUTHORIZATION DEFAULT'&lt;br /&gt;print_timestamp = true&lt;br /&gt;master_slave_mode = false&lt;br /&gt;connection_cache = true&lt;br /&gt;health_check_timeout = 20&lt;br /&gt;health_check_period = 60&lt;br /&gt;health_check_user = 'pgpool2'&lt;br /&gt;failover_command = ''&lt;br /&gt;failback_command = ''&lt;br /&gt;insert_lock = false&lt;br /&gt;ignore_leading_white_space = true&lt;br /&gt;log_statement = false&lt;br /&gt;log_connections = false&lt;br /&gt;log_hostname = false&lt;br /&gt;parallel_mode = false&lt;br /&gt;enable_query_cache = false&lt;br /&gt;pgpool2_hostname = 'pgsql1'&lt;br /&gt;system_db_hostname = 'localhost'&lt;br /&gt;system_db_port = 5432&lt;br /&gt;system_db_dbname = 'pgpool'&lt;br /&gt;system_db_schema = 'pgpool_catalog'&lt;br /&gt;system_db_user = 'pgpool'&lt;br /&gt;system_db_password = ''&lt;br /&gt;backend_hostname0 = '192.168.0.3'&lt;br /&gt;backend_port0 = 5432&lt;br /&gt;backend_weight0 = 1&lt;br /&gt;backend_hostname1 = '192.168.0.4'&lt;br /&gt;backend_port1 = 5432&lt;br /&gt;backend_weight1 = 1&lt;br /&gt;enable_pool_hba = false&lt;br /&gt;recovery_user = 'pgpool2'&lt;br /&gt;recovery_password = ''&lt;br /&gt;recovery_1st_stage_command = ''&lt;br /&gt;recovery_2nd_stage_command = ''&lt;br /&gt;recovery_timeout = 90&lt;br /&gt;&lt;br /&gt;Todas las directivas de configuración vienen explicadas en la página web de pgpool-II. Como aspectos a destacar de la anterior configuración tenemos los siguientes:&lt;br /&gt;&lt;br /&gt;   * Mediante la directiva listen_addresses hacemos que, inicialmente, pgpool-II escuche en todas las interfaces.&lt;br /&gt;   * Mediante las directivas logdir, socket_dir, pcp_socket_dir y backend_socket_dir, configuramos, respectivamente, que el pid y todos los sockets de los diferentes procesos que forman pgpool-II se guarden en el directorio por defecto de Debian para PostgreSQL, /var/run/postgresql.&lt;br /&gt;   * Activamos el pool de conexiones (directiva connection_cache) pero dejamos todas las demás funcionalidades desactivadas (replication_mode, load_balance_mode, replicate_select y master_slave_mode).&lt;br /&gt;   * Mediante las directivas health_check_timeout, health_check_period y health_check_user, configuramos la comprobación de estado de los servidores PostgreSQL para que se haga con el usuario de base de datos pgpool2, cada 60 segundos y con un tiempo máximo de espera de 20 segundos.&lt;br /&gt;   * Dejamos todos los límites de conexiones, número de procesos, tiempos de espera y similares a sus valores por defecto.&lt;br /&gt;&lt;br /&gt;El siguiente paso será crear el script de arranque de pgpool-II, que situaremos en /opt/pgpool2/etc/init.d/pgpool2. A continuación se muestra un típico script, basado en el original del paquete pgpool de Debian:&lt;br /&gt;&lt;br /&gt;#! /bin/sh&lt;br /&gt;&lt;br /&gt;PATH=/opt/pgpool2/bin:/sbin:/bin:/usr/sbin:/usr/bin&lt;br /&gt;DAEMON=/opt/pgpool2/bin/pgpool&lt;br /&gt;PIDFILE=/var/run/postgresql/pgpool.pid&lt;br /&gt;&lt;br /&gt;test -x $DAEMON || exit 0&lt;br /&gt;&lt;br /&gt;# Include pgpool defaults if available&lt;br /&gt;if [ -f /opt/pgpool2/etc/default/pgpool2 ] ; then&lt;br /&gt;	. /opt/pgpool2/etc/default/pgpool2&lt;br /&gt;fi&lt;br /&gt;&lt;br /&gt;OPTS=""&lt;br /&gt;if [ x"$PGPOOL_LOG_DEBUG" = x"yes" ]; then&lt;br /&gt;	OPTS="$OPTS -d"&lt;br /&gt;fi&lt;br /&gt;&lt;br /&gt;. /lib/lsb/init-functions&lt;br /&gt;&lt;br /&gt;is_running() {&lt;br /&gt;	pidofproc -p $PIDFILE $DAEMON &gt;/dev/null&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;d_start() {&lt;br /&gt;	if is_running; then&lt;br /&gt;		:&lt;br /&gt;	else&lt;br /&gt;		su -c "$DAEMON -n $OPTS 2&amp;gt;&amp;amp;1 &amp;lt;/dev/null | logger -t pgpool -p ${PGPOOL_SYSLOG_FACILITY:-local0}.info &amp;gt;/dev/null 2&amp;gt;&amp;amp;1 &amp;amp;" - postgres&lt;br /&gt;	fi&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;d_stop() {&lt;br /&gt;	killproc -p $PIDFILE $DAEMON -INT&lt;br /&gt;	status=$?&lt;br /&gt;	[ $status -eq 0 ] || [ $status -eq 3 ]&lt;br /&gt;	return $?&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;case "$1" in&lt;br /&gt;   start)&lt;br /&gt;	log_daemon_msg "Starting pgpool-II" pgpool&lt;br /&gt;	d_start&lt;br /&gt;	log_end_msg $?&lt;br /&gt;	;;&lt;br /&gt;   stop)&lt;br /&gt;	log_daemon_msg "Stopping pgpool-II" pgpool&lt;br /&gt;	d_stop&lt;br /&gt;	log_end_msg $?&lt;br /&gt;	;;&lt;br /&gt;   status)&lt;br /&gt;	is_running&lt;br /&gt;	status=$?&lt;br /&gt;	if [ $status -eq 0 ]; then&lt;br /&gt;		log_success_msg "pgpool-II is running."&lt;br /&gt;	else&lt;br /&gt;		log_failure_msg "pgpool-II is not running."&lt;br /&gt;	fi&lt;br /&gt;	exit $status&lt;br /&gt;	;;&lt;br /&gt;   restart|force-reload)&lt;br /&gt;	log_daemon_msg "Restarting pgpool-II" pgpool&lt;br /&gt;	d_stop &amp;amp;&amp;amp; sleep 1 &amp;amp;&amp;amp; d_start&lt;br /&gt;	log_end_msg $?&lt;br /&gt;	;;&lt;br /&gt;   try-restart)&lt;br /&gt;	if $0 status &amp;gt;/dev/null; then&lt;br /&gt;		$0 restart&lt;br /&gt;	else&lt;br /&gt;		exit 0&lt;br /&gt;	fi&lt;br /&gt;	;;&lt;br /&gt;   reload)&lt;br /&gt;	exit 3&lt;br /&gt;	;;&lt;br /&gt;   *)&lt;br /&gt;	log_failure_msg "Usage: $0 {start|stop|status|restart|try-restart|reload|force-reload}"&lt;br /&gt;	exit 2&lt;br /&gt;	;;&lt;br /&gt;esac&lt;br /&gt;&lt;br /&gt;Siguiendo el estándar Debian, crearemos el fichero /opt/pgpool2/etc/default/pgpool2 con los valores de configuración de arranque del daemon. Opcionalmente, aprovechamos para ponerlo en modo debug al arrancar:&lt;br /&gt;&lt;br /&gt;# Defaults for pgpool initscript&lt;br /&gt;# sourced by /opt/pgpool2/etc/init.d/pgpool2&lt;br /&gt;&lt;br /&gt;# syslog facility for pgpool; see logger(1)&lt;br /&gt;PGPOOL_SYSLOG_FACILITY=local0&lt;br /&gt;&lt;br /&gt;# set to "yes" if you want to enable debugging messages to the log&lt;br /&gt;PGPOOL_LOG_DEBUG=no&lt;br /&gt;&lt;br /&gt;Ahora ya deberíamos de ser capaces de arrancar pgpool-II:&lt;br /&gt;&lt;br /&gt;/opt/pgpool2/etc/init.d/pgpool2 start&lt;br /&gt;&lt;br /&gt;Podremos observar el correcto arranque del daemon (o los errores en caso contrario) monitorizando el syslog, por ejemplo mediante el uso del comando tail:&lt;br /&gt;&lt;br /&gt;/usr/bin/tail -f /var/log/syslog | ccze&lt;br /&gt;&lt;br /&gt;A partir de este momento deberíamos de ser capaces de conectarnos al puerto 9999 de la dirección IP de administración del nodo pgsql1 (la dirección IP de servicio no estará disponible hasta que configuremos la alta disponibilidad con Heartbeat):&lt;br /&gt;&lt;br /&gt;/usr/bin/psql -h pgsql1 -p 9999 -U pgpool2 -d postgres&lt;br /&gt;&lt;br /&gt;Si deseamos monitorizar las conexiones a los nodos de PostgreSQL, podemos activar las directivas log_connections y log_disconnections en los ficheros de configuración /etc/postgresql/8.3/main/postgresql.conf de cada nodo, reiniciando PostgreSQL para que los cambios surjan efecto.&lt;br /&gt;&lt;br /&gt;Debido a que no tenemos ni replicación ni balanceo de carga activados , pgpool-II sólo se habrá conectado al servidor PostgreSQL del nodo maestro, hecho que habremos podido comprobar monitorizando el fichero de log de PostgreSQL en /var/log/postgresql/postgresql-8.3-main.log.&lt;br /&gt;&lt;br /&gt;Tras haber comprobado que ya podemos conectarnos, vamos a proceder a activar la replicación y el balanceo de carga editando el fichero /opt/pgpool2/etc/pgpool.conf y cambiando las directivas siguientes:&lt;br /&gt;&lt;br /&gt;replication_mode = true&lt;br /&gt;load_balance_mode = true&lt;br /&gt;replication_stop_on_mismatch = true&lt;br /&gt;&lt;br /&gt;Para activar los cambios reiniciaremos pgpool-II:&lt;br /&gt;&lt;br /&gt;/opt/pgpool2/etc/init.d/pgpool2 restart&lt;br /&gt;&lt;br /&gt;Pruebas de replicación&lt;br /&gt;&lt;br /&gt;En el paquete postgresql-contrib-8.3 podemos encontrar una utilidad llamada pgbench. Esta utilidad permite, en primer lugar, inicializar una base de datos con una serie de tablas sencillas y, en segundo lugar, realizar pruebas de rendimiento sobre servidores PostgreSQL mediante la ejecución de una cierta cantidad de consultas de varios tipos y con una concurrencia parametrizable.&lt;br /&gt;&lt;br /&gt;A partir de este momento trabajaremos desde un tercer equipo, actuando ya como cliente del clúster. Por comodidad, daremos de alta las entradas del fichero /etc/hosts mencionadas anteriormente en el artículo, igual que hicimos en ambos nodos del clúster. El primer paso consistirá en crear la base de datos bench_replication:&lt;br /&gt;&lt;br /&gt;createdb -h pgsql1 -p 9999 -U pgpool2 bench_replication&lt;br /&gt;createlang -h pgsql1 -p 9999 -U pgpool2 -d bench_replication plpgsql&lt;br /&gt;&lt;br /&gt;Con log_statement y log_connections activados en /opt/pgpool2/etc/pgpool2.conf, ésto nos mostrará entradas en /var/log/syslog similares a las siguientes:&lt;br /&gt;&lt;br /&gt;LOG: pid 4365: connection received: host=192.168.0.5 port=38024&lt;br /&gt;LOG: pid 4365: statement: CREATE DATABASE bench_replication;&lt;br /&gt;LOG: pid 4365: statement:  RESET ALL&lt;br /&gt;LOG: pid 4365: statement:  SET SESSION AUTHORIZATION DEFAULT&lt;br /&gt;&lt;br /&gt;Con log_statement = 'all' en /etc/postgresql/8.3/main/postgresql.conf, en el log de cualquiera de los PostgreSQL nos aparecerán las siguientes líneas:&lt;br /&gt;&lt;br /&gt;LOG:  connection received: host=192.168.0.3 port=33690&lt;br /&gt;LOG:  connection authorized: user=pgpool2 database=postgres&lt;br /&gt;LOG:  statement: CREATE DATABASE bench_replication;&lt;br /&gt;LOG:  statement:  RESET ALL&lt;br /&gt;LOG:  statement:  SET SESSION AUTHORIZATION DEFAULT&lt;br /&gt;&lt;br /&gt;Como usuario postgres, en ambos nodos podremos usar psql para ver las bases de datos y verificar que se han creado:&lt;br /&gt;&lt;br /&gt;$ su - postgres&lt;br /&gt;$ psql -l&lt;br /&gt;           List of databases&lt;br /&gt;      Name        |  Owner   | Encoding &lt;br /&gt;-------------------+----------+-----------&lt;br /&gt;bench_replication | pgpool2  | SQL_ASCII&lt;br /&gt;postgres          | postgres | SQL_ASCII&lt;br /&gt;template0         | postgres | SQL_ASCII&lt;br /&gt;template1         | postgres | SQL_ASCII&lt;br /&gt;(4 rows)&lt;br /&gt;&lt;br /&gt;Vamos a proceder ahora a rellenar las bases de datos con tablas e información de pruebas mediante el uso de pgbench:&lt;br /&gt;&lt;br /&gt;/usr/lib/postgresql/8.3/bin/pgbench -i -h pgsql1 -p 9999 -U pgpool2 -d bench_replication&lt;br /&gt;&lt;br /&gt;En el syslog podremos ver la siguiente información:&lt;br /&gt;&lt;br /&gt;LOG: pid 4363: connection received: host=192.168.0.5 port=38124&lt;br /&gt;LOG: pid 4363: statement: SET search_path = public&lt;br /&gt;LOG: pid 4363: statement: drop table if exists branches&lt;br /&gt;LOG: pid 4363: statement: create table branches(bid int not null,bbalance int,filler char(88)) with (fillfactor=100)&lt;br /&gt;LOG: pid 4363: statement: drop table if exists tellers&lt;br /&gt;LOG: pid 4363: statement: create table tellers(tid int not null,bid int,tbalance int,filler char(84)) with (fillfactor=100)&lt;br /&gt;LOG: pid 4363: statement: drop table if exists accounts&lt;br /&gt;LOG: pid 4363: statement: create table accounts(aid int not null,bid int,abalance int,filler char(84)) with (fillfactor=100)&lt;br /&gt;LOG: pid 4363: statement: drop table if exists history&lt;br /&gt;LOG: pid 4363: statement: create table history(tid int,bid int,aid int,delta int,mtime timestamp,filler char(22))&lt;br /&gt;LOG: pid 4363: statement: begin&lt;br /&gt;LOG: pid 4363: statement: insert into branches(bid,bbalance) values(1,0)&lt;br /&gt;LOG: pid 4363: statement: insert into tellers(tid,bid,tbalance) values (1,1,0)&lt;br /&gt;LOG: pid 4363: statement: insert into tellers(tid,bid,tbalance) values (2,1,0)&lt;br /&gt;LOG: pid 4363: statement: insert into tellers(tid,bid,tbalance) values (3,1,0)&lt;br /&gt;LOG: pid 4363: statement: insert into tellers(tid,bid,tbalance) values (4,1,0)&lt;br /&gt;LOG: pid 4363: statement: insert into tellers(tid,bid,tbalance) values (5,1,0)&lt;br /&gt;LOG: pid 4363: statement: insert into tellers(tid,bid,tbalance) values (6,1,0)&lt;br /&gt;LOG: pid 4363: statement: insert into tellers(tid,bid,tbalance) values (7,1,0)&lt;br /&gt;LOG: pid 4363: statement: insert into tellers(tid,bid,tbalance) values (8,1,0)&lt;br /&gt;LOG: pid 4363: statement: insert into tellers(tid,bid,tbalance) values (9,1,0)&lt;br /&gt;LOG: pid 4363: statement: insert into tellers(tid,bid,tbalance) values (10,1,0)&lt;br /&gt;LOG: pid 4363: statement: commit&lt;br /&gt;LOG: pid 4363: statement: begin&lt;br /&gt;LOG: pid 4363: statement: truncate accounts&lt;br /&gt;LOG: pid 4363: statement: copy accounts from stdin&lt;br /&gt;LOG: pid 4363: statement: commit&lt;br /&gt;LOG: pid 4363: statement: alter table branches add primary key (bid)&lt;br /&gt;LOG: pid 4363: statement: alter table tellers add primary key (tid)&lt;br /&gt;LOG: pid 4363: statement: alter table accounts add primary key (aid)&lt;br /&gt;LOG: pid 4363: statement: vacuum analyze&lt;br /&gt;LOG: pid 4363: statement:  RESET ALL&lt;br /&gt;LOG: pid 4363: statement:  SET SESSION AUTHORIZATION DEFAULT&lt;br /&gt;&lt;br /&gt;Con un sencillo script vamos a contar el número de registros insertados en cada instancia de PostgreSQL sin pasar por pgpool-II, de modo que podamos verificar que la replicación se ha realizado correctamente:&lt;br /&gt;&lt;br /&gt;#!/bin/sh&lt;br /&gt;&lt;br /&gt;PGSQL=/usr/bin/psql&lt;br /&gt;HEAD=/usr/bin/head&lt;br /&gt;TAIL=/usr/bin/tail&lt;br /&gt;CUT=/usr/bin/cut&lt;br /&gt;IP_LIST="192.168.0.3 192.168.0.4"&lt;br /&gt;PORT=5432&lt;br /&gt;&lt;br /&gt;for ip in $IP_LIST&lt;br /&gt;do&lt;br /&gt;   echo "ip address: $ip"&lt;br /&gt;   for t in branches tellers accounts history&lt;br /&gt;   do&lt;br /&gt;       echo -n "table $t: "&lt;br /&gt;       COUNT=`$PGSQL -h $ip -p $PORT -U pgpool2 -d bench_replication -c "SELECT count(*) FROM $t" | $HEAD -n 3 | $TAIL -n 1`&lt;br /&gt;	echo $COUNT&lt;br /&gt;   done&lt;br /&gt;done&lt;br /&gt;&lt;br /&gt;exit 0&lt;br /&gt;&lt;br /&gt;Para poder ver cómo se balancean las consultas, teniendo activada la directiva log_statement = 'all' en /etc/postgresql/8.3/main/postgresql.conf de ambos PostgreSQL, podemos utilizar el siguiente script para ver qué consultas aparecen en el log de cada nodo:&lt;br /&gt;&lt;br /&gt;#!/bin/sh&lt;br /&gt;&lt;br /&gt;PGSQL=/usr/bin/psql&lt;br /&gt;HEAD=/usr/bin/head&lt;br /&gt;TAIL=/usr/bin/tail&lt;br /&gt;CUT=/usr/bin/cut&lt;br /&gt;IP_LIST="192.168.0.3"&lt;br /&gt;PORT=9999&lt;br /&gt;&lt;br /&gt;for ip in $IP_LIST&lt;br /&gt;do&lt;br /&gt;   echo "ip address: $ip"&lt;br /&gt;   for t in branches tellers accounts history&lt;br /&gt;   do&lt;br /&gt;       echo -n "table $t: "&lt;br /&gt;       COUNT=`$PGSQL -h $ip -p $PORT -U pgpool2 -d bench_replication -c "SELECT count(*) FROM $t" | $HEAD -n 3 | $TAIL -n 1`&lt;br /&gt;       echo $COUNT&lt;br /&gt;   done&lt;br /&gt;done&lt;br /&gt;&lt;br /&gt;exit 0&lt;br /&gt;&lt;br /&gt;En media, deberían haberse ejecutado dos (de las cuatro) consultas SELECT en cada una de las bases de datos, si bien esto no tiene porqué ser siempre así.&lt;br /&gt;&lt;br /&gt;A continuación pasaremos a ejecutar el benchmark básico de pgbench, de modo que podamos apreciar el comportamiento del clúster bajo continuas inserciones, actualizaciones y consultas. Desde la consola ejecutaremos:&lt;br /&gt;&lt;br /&gt;/usr/lib/postgresql/8.3/bin/pgbench -h pgsql1 -p 9999 -U pgpool2 -d bench_replication -c 10 -t 1000&lt;br /&gt;&lt;br /&gt;El resultado obtenido será similar al siguiente:&lt;br /&gt;&lt;br /&gt;[..]&lt;br /&gt;transaction type: TPC-B (sort of)&lt;br /&gt;scaling factor: 1&lt;br /&gt;number of clients: 1&lt;br /&gt;number of transactions per client: 10&lt;br /&gt;number of transactions actually processed: 10/10&lt;br /&gt;tps = 119.105754 (including connections establishing)&lt;br /&gt;tps = 126.179781 (excluding connections establishing)&lt;br /&gt;&lt;br /&gt;Si monitorizamos el log de pgpool-II en /var/log/syslog y los logs de ambas instancias de PostgreSQL, veremos como en el primer nodo se ejecutan todas las consultas (update, select, update, update, insert) mientras que en el segundo sólo las insert y las update. Esto se debe a que cada transacción está explícitamente declarada (BEGIN...END) y, en ese caso, pgpool-II no hace uso más que del nodo principal.&lt;br /&gt;&lt;br /&gt;Recuperación en línea&lt;br /&gt;&lt;br /&gt;El procedimiento de recuperación en línea de un nodo (del inglés, online recovery) permite volver a conectar nodos caídos al clúster. Es requisito, por lo tanto, que el nodo esté desconectado o caído (del inglés, dettached) antes de ejecutar este procedimiento (ver comandos pcp más adelante).&lt;br /&gt;&lt;br /&gt;En términos generales, el proceso de recuperación sigue los siguientes pasos:&lt;br /&gt;&lt;br /&gt;   * Activar el comando de archivado de ficheros WAL.&lt;br /&gt;   * Modificar el fichero /etc/postgresql/8.3/main/postgresql.conf.&lt;br /&gt;   * Recargar la configuración de PostgreSQL.&lt;br /&gt;   * Ejecución de /opt/pgpool2/bin/pcp_recovery_node.&lt;br /&gt;         o Primera fase: copia del directorio base.&lt;br /&gt;         o Segunda fase: sincronización de cambios.&lt;br /&gt;         o Tercera fase: arranque del nuevo servidor.&lt;br /&gt;&lt;br /&gt;El Write-Ahead Log&lt;br /&gt;&lt;br /&gt;A partir de su versión 8, PostgreSQL almacena todas las operaciones que alteran los datos y los metadatos de la base de datos en forma de logs binarios en el directorio /var/lib/postgresql/8.3/pg_xlog. Estos logs se escriben y sincronizan en disco antes de que se alteren los ficheros de las tablas (de ahí su nombre, Write-Ahead Log o WAL) y su función principal es la recuperación a un estado consistente de forma automática (de ahí su nombre, Point-In-Time Recovery o PITR) en caso de fallo del sistema por rotura de un disco, muerte de un proceso, etc. Su funcionamiento es análogo al del journaling de un sistema de ficheros. Cada uno de estos ficheros tiene un tamaño de 16 MB y PostgreSQL los rota y reutiliza automáticamente (almacena un máximo de 8 ficheros por defecto). El uso de estos logs binarios viene activado por defecto en PostgreSQL, pero no su archivado (copia a otra ubicación).&lt;br /&gt;&lt;br /&gt;Debido a la forma en que se realiza la recuperación en línea de un nodo con pgpool-II, en realidad no es necesario tener una copia de todos los ficheros del WAL que se vayan generando, de ahí que se use un comando nulo durante la operación rutinaria del servidor. Además, el archivado de ficheros del WAL habitualmente supone un importante impacto en el rendimiento del servidor.&lt;br /&gt;&lt;br /&gt;Para este artículo suponemos suficiente el uso de pg_dump una vez al día como mecanismo de copias de seguridad de los datos, luego no se estará haciendo uso de WAL y PITR como mecanismo de backup, sino que se utilizará únicamente para la recuperación online de un nodo. Por lo tanto, durante la operación normal del clúster, éste debe estar activo pero con un comando de archivado nulo que no haga copia alguna de los ficheros de log rotados, tal que:&lt;br /&gt;&lt;br /&gt;archive_mode = on&lt;br /&gt;archive_command = 'exit 0'&lt;br /&gt;# archive_command = '/bin/cp %p /var/lib/postgresql/pg_xlog_archive/%f'&lt;br /&gt;&lt;br /&gt;Ésto es así debido a que no puede activarse o desactivarse el uso de ficheros WAL por parte de PostgreSQL sin reiniciar el servicio (acción que queremos evitar en la medida de lo posible), mientras que cambiar el comando que se usa para el archivado de dichos ficheros requiere tan sólo una solicitud de recarga de la configuración al daemon de PostgreSQL. Según se especifica en la documentación en línea de PostgreSQL, es necesario que todo comando de archivado devuelva el valor 0 en caso de ejecución correcta y cualquier otro valor en caso contrario, de ahí que se haya optado por un simple "exit 0".&lt;br /&gt;&lt;br /&gt;Procedimiento completo&lt;br /&gt;&lt;br /&gt;Una vez introducidos los conceptos a utilizar, acto seguido se detalla el procedimiento completo de restauración de un nodo caído. Como paso previo activaremos el comando de archivado de ficheros WAL en el nodo maestro. Para ello, editaremos el fichero de configuración /etc/postgresql/8.3/main/postgresql.conf y cambiaremos el valor de la directiva archive_command, según sigue:&lt;br /&gt;&lt;br /&gt;archive_mode = on&lt;br /&gt;# archive_command = 'exit 0'&lt;br /&gt;archive_command = '/bin/cp %p /var/lib/postgresql/pg_xlog_archive/%f'&lt;br /&gt;&lt;br /&gt;Luego solicitaremos al daemon de PostgreSQL que recargue la configuración mediante el siguiente comando:&lt;br /&gt;&lt;br /&gt;/etc/init.d/postgresql-8.3 reload&lt;br /&gt;&lt;br /&gt;En el nodo a recuperar, donde PostgreSQL debe estar parado, dejaremos la configuración original (comando de archivado nulo), pues no es necesario para una PITR. El siguiente paso es hacer una llamada al comando pcp_recovery_node, tal que:&lt;br /&gt;&lt;br /&gt;/opt/pgpool2/bin/pcp_recovery_node 5 pgsql1 9898 root  1&lt;br /&gt;&lt;br /&gt;En este ejemplo, la llamada se efectúa con los siguientes parámetros:&lt;br /&gt;&lt;br /&gt;   * Un timeout de 5 segundos.&lt;br /&gt;   * Sobre el puerto 9898.&lt;br /&gt;   * Al primer nodo del clúster, "pgsql1", actuando en estos momentos como maestro.&lt;br /&gt;   * Solicitando la recuperación del segundo nodo (el conteo empieza por el 0).&lt;br /&gt;&lt;br /&gt;Debido a que parten de una llamada a un procedimiento almacenado de base de datos, todas las acciones que se realizan a raíz de esta llamada se ejecutan como usuario de sistema postgres. Divididas en tres fases, se detallan a continuación.&lt;br /&gt;&lt;br /&gt;Primera fase&lt;br /&gt;&lt;br /&gt;pgpool-II ejecuta SELECT pgpool_recovery('recovery_1st_stage_command', 'target', 'PGDATA') en un nodo maestro. Esto produce una llamada al script /var/lib/postgresql/8.3/main/base-backup. Durante la ejecución de este script se siguen atendiendo peticiones de los clientes (que PostgreSQL irá almacenando en su bitácora).&lt;br /&gt;&lt;br /&gt;Los valores de los tres parámetros de la llamada se obtienen del fichero /opt/pgpool2/etc/pgpool.conf. El primero de la directiva recovery_1st_stage_command; el segundo de la directiva backend_hostname correspondiente al nodo a recuperar; y el tercero de la directiva backend_data_directory correspondiente al nodo a recuperar.&lt;br /&gt;&lt;br /&gt;En primer lugar, este script genera un fichero llamado recovery.conf, que sitúa dentro del directorio PG_DATA (/var/lib/postgresql/8.3/main en Debian). Este fichero se crea en esa ubicación para que sea transferido al nodo a recuperar más adelante en este mismo script. Cuando el servidor PostgreSQL del nodo a recuperar arranque y realice una recuperación PITR, leerá ese fichero y ejecutará el valor de la variable restore_command tantas veces como sea necesario para obtener los ficheros WAL que le permitirán llegar desde el punto en la bitácora donde finalizó la copia de seguridad online hasta el momento en el cual se dejaron de atender peticiones (segunda fase de la recuperación online de un nodo). El origen de esos ficheros WAL será el directorio /var/lib/postgresql/pg_xlog_archive del nodo maestro, que es donde el comando de la directiva archive_command copia los ficheros WAL que se van rotando.&lt;br /&gt;&lt;br /&gt;Durante la ejecución de este script, pgpool-II sigue antendiendo peticiones de los clientes, de ahí que se inicie un backup online de PostgreSQL antes de empezar la copia. De este modo, las diferencias entre ambos nodos cuando el script haya terminado su ejecución serán tan sólo los ficheros WAL generados durante su ejecución, que habrán sido archivados en un directorio aparte (/var/lib/postgresql/pg_xlog_archive) para evitar que más de 8 rotaciones de logs durante la ejecución del script sobreescriban ficheros WAL (en el caso de mucha actividad en el servidor o de tener un volumen de datos a copiar muy grande, o de ambas).&lt;br /&gt;&lt;br /&gt;En segundo lugar, este script indica a PostgreSQL que se va a iniciar una copia de seguridad online mediante la ejecución de la consulta SELECT pg_start_backup('etiqueta') en un nodo maestro. Esto, a su vez, fuerza un CHECKPOINT. Un checkpoint es un punto en la secuencia del log de transacciones a partir del cual todos los ficheros de datos han sido actualizados para reflejar la información en el log o bitácora. Todos los ficheros de datos serán escritos en disco. Un checkpoint actúa como punto de inicio para una recuperación PITR. Es decir, un checkpoint más un conjunto de ficheros WAL es todo lo que se necesita para recuperar una base de datos PostgreSQL a un estado consistente, mediante el mecanismo de PITR.&lt;br /&gt;&lt;br /&gt;En tercer lugar, el script realiza una copia del directorio /var/lib/postgresql/8.3/main desde el nodo maestro al nodo a recuperar mediante el uso de varias sentencias rsync.&lt;br /&gt;&lt;br /&gt;Por último, el script indica a PostgreSQL que ya ha terminado el backup online mediante la ejecución de la sentencia SELECT pg_stop_backup(). Tras la anotación del punto donde finaliza el backup, el puntero de inserción del fichero de log actual se desplaza al siguiente fichero de log, de modo que el fichero actual puede rotarse y archivarse, completándose así la copia de seguridad.&lt;br /&gt;&lt;br /&gt;Segunda fase&lt;br /&gt;&lt;br /&gt;Una vez finalizada la copia del directorio base, pgpool-II deja de atender las peticiones de los clientes, quedando éstas acumuladas en una cola de peticiones pendientes de atender, y finaliza las que estuvieran en ejecución (durante un tiempo máximo definido en la directiva client_idle_limit_in_recovery).&lt;br /&gt;&lt;br /&gt;Luego pgpool-II ejecuta SELECT pgpool_recovery('recovery_2nd_stage_command', 'target', 'PGDATA') en un nodo maestro. Esto produce una llamada al script /var/lib/postgresql/8.3/main/pgpool-recovery-pitr. Los valores de los tres parámetros de la llamada se obtienen del fichero /opt/pgpool2/etc/pgpool.conf. El primero de la directiva recovery_2nd_stage_command; el segundo de la directiva backend_hostname correspondiente al nodo a recuperar; y el tercero de la directiva backend_data_directory correspondiente al nodo a recuperar.&lt;br /&gt;&lt;br /&gt;Este script fuerza una rotación de ficheros WAL mediante la ejecución de la sentencia SQL SELECT pg_switch_xlog(). Esta rotación de ficheros WAL se realiza en este instante (tras haber dejado de atender peticiones de clientes) a fin de generar un estado inalterado de la base de datos que pueda ser recuperado por el nuevo nodo a partir del backup del directorio base más los ficheros WAL generados por sucesivas rotaciones desde el inicio del backup hasta esta última rotación explícita).&lt;br /&gt;&lt;br /&gt;Tercera fase&lt;br /&gt;&lt;br /&gt;pgpool-II ejecuta SELECT pgpool_remote_start('target', 'PGDATA') en el nodo maestro. Esto produce una llamada al script /var/lib/postgresql/8.3/main/pgpool_remote_start. Los valores de los dos parámetros de la llamada se obtienen del fichero /opt/pgpool2/etc/pgpool.conf. El primero de la directiva backend_hostname correspondiente al nodo a recuperar; y el segundo de la directiva backend_data_directory correspondiente al nodo a recuperar. El nombre del script a recuperar está incluido en el código fuente del fichero /usr/local/src/pgpool-II-2.2.2/sql/pgpool-recovery y, si se desea cambiar, debe alterarse antes de compilar e instalar.&lt;br /&gt;&lt;br /&gt;Este script arranca PostgreSQL en el nodo que se está recuperando mediante una llamada al binario /usr/bin/pg_ctlcluster, y PostgreSQL hace una recuperación PITR al arrancar. El tiempo de espera para el arranque no será superior a lo que indique la directiva recovery_timeout (en segundos) del fichero /opt/pgpool2/etc/pgpool.conf.&lt;br /&gt;&lt;br /&gt;Una vez finalizado el proceso de PITR, el nodo de PostgreSQL recuperado acepta conexiones de nuevo. pgpool-II se conecta al nuevo nodo y, a partir de este momento, el nodo forma parte del clúster de nuevo. El clúster opera de nuevo con normalidad, todas las bases de datos son accesibles de nuevo y se procesan las peticiones acumuladas durante la segunda y tercera fases de la recuperación en línea.&lt;br /&gt;&lt;br /&gt;Pasos finales&lt;br /&gt;&lt;br /&gt;Una vez finalizada la recuperación, y habiendo comprobado el correcto funcionamiento del clúster con su nuevo nodo, procederemos a desactivar el comando de archivado de ficheros WAL del nodo maestro, alterando el fichero de configuración /etc/postgresql/8.3/main/postgresql.conf y dejando el valor nulo exit 0 del parámetro, tal y como estaba antes de iniciar el procedimiento y solicitaremos una recarga de la configuración.&lt;br /&gt;&lt;br /&gt;En este momento, nuestro clúster acaba de finalizar la operación llamada failback, es decir, se ha recuperado de una operación de failover que se inició al detectar que uno de los nodos no estaba disponible. pgpool-II permite configurar sendos scripts para que sean ejecutados al iniciarse y finalizar, respectivamente, los eventos de failover y failback. Estas directivas se encuentran en el fichero de configuración /opt/pgpool2/etc/pgpool.conf y son las siguientes:&lt;br /&gt;&lt;br /&gt;failover_command = ''&lt;br /&gt;failback_command = ''&lt;br /&gt;&lt;br /&gt;En el apartado siguiente se ofrecen ejemplos de scripts que realizan todas las tareas descritas anteriormente.&lt;br /&gt;&lt;br /&gt;Scripts necesarios&lt;br /&gt;&lt;br /&gt;En este apartado se muestran varios scripts que son necesarios para realizar la recuperación en línea de un nodo. La documentación de pgpool-II describe los pasos específicos a seguir, que varían dependiendo de la versión de PostgreSQL que estemos usando y de las herramientas de sistema de que dispongamos, pero deja a discreción del administrador de sistemas su implementación. Como en muchos casos, no hay una única solución que se ajuste a todos los casos.&lt;br /&gt;&lt;br /&gt;Listados en orden de ejecución, los scripts necesarios son los siguientes:&lt;br /&gt;&lt;br /&gt;   * pgpool-failover&lt;br /&gt;   * wall_archiving&lt;br /&gt;   * base-backup&lt;br /&gt;   * pgpool-recovery-pitr&lt;br /&gt;   * pgpool_remote_start&lt;br /&gt;   * pgpool-failback&lt;br /&gt;&lt;br /&gt;Todos ellos deben residir en el directorio de datos de PostgreSQL (/var/lib/postgresql/8.3/main) de todos los nodos.&lt;br /&gt;&lt;br /&gt;El script wall_archiving lo ejecutaremos manualmente antes de empezar la recuperación del nodo y tras finalizar la misma, bien como usuario root, bien como usuario postgres.&lt;br /&gt;&lt;br /&gt;Los scripts base-backup y pgpool-recovery-pitr reciben tres parámetros, en este orden:&lt;br /&gt;&lt;br /&gt;  1. Directorio de datos de origen ($PG_DATA).&lt;br /&gt;  2. Nombre del host a recuperar ($PG_HOST).&lt;br /&gt;  3. Directorio de datos de destino ($PG_DATA).&lt;br /&gt;&lt;br /&gt;El script pgpool_remote_start recibe sólo los dos últimos. Los tres scripts se ejecutan en algún nodo maestro del cual pgpool-II tenga constancia y esté activo (conste como attached), y corren como usuario postgres.&lt;br /&gt;&lt;br /&gt;Por último, los scripts pgpool-failover y pgpool-failback, también ejecutados como usuario postgres, reciben un conjunto de parámetros, en el orden elegido por el usuario, de entre los siguientes:&lt;br /&gt;&lt;br /&gt;   * %d: identificador de nodo.&lt;br /&gt;   * %h: nombre del host.&lt;br /&gt;   * %p: puerto.&lt;br /&gt;   * %D: ruta al directorio de datos del clúster&lt;br /&gt;   * %m: identificador del nuevo nodo maestro.&lt;br /&gt;   * %M: identificador del nodo maestro antiguo.&lt;br /&gt;&lt;br /&gt;Para escapar el carácter de porcentaje (%) se usa otro porcentaje (%%).&lt;br /&gt;&lt;br /&gt;Estos parámetros se configuran en la propia llamada al script deseado en la configuración de pgpool-II (fichero /opt/pgpool2/etc/pgpool.conf). Por ejemplo, para este artículo se configuraron de la siguiente manera:&lt;br /&gt;&lt;br /&gt;failover_command = '/var/lib/postgresql/8.3/main/pgpool-failover %d %h %p %D %m %M'&lt;br /&gt;failback_command = '/var/lib/postgresql/8.3/main/pgpool-failback %d %h %p %D %m %M'&lt;br /&gt;&lt;br /&gt;Los valores %m (identificador del nuevo nodo maestro) y %M (identificador del nodo maestro antiguo) tienen mucho valor cuando el nodo que cae (durante un failover) es el nodo maestro y pgpool-II decide, a partir de aquel momento, considerar otro nodo (antes esclavo) como nuevo nodo maestro.&lt;br /&gt;&lt;br /&gt;En todos los casos, los parámetros pasados por pgpool-II al script que se esté llamando se reciben como parámetros de la manera habitual, tratándose como en cualquier otro caso y de la forma pertinente dependiendo del lenguage de scripting utilizado.&lt;br /&gt;&lt;br /&gt;wal_archiving&lt;br /&gt;&lt;br /&gt;El proceso de activación y desactivación del comando de archivado puede automatizarse mediante scripts de Bash, Perl o similar, e incluso integrarse dentro de la primera y última fases de la recuperación. En realidad, es una cuestión de gustos más que otra cosa. Personalmente, prefiero tenerlos por separado y ejecutarlos manualmente. A continuación se muestra un script de Bash que realiza dicha función:&lt;br /&gt;&lt;br /&gt;#!/bin/sh&lt;br /&gt;&lt;br /&gt;SED=/bin/sed&lt;br /&gt;PSQL=/usr/bin/psql&lt;br /&gt;PGDIR="/etc/postgresql/8.3/main"&lt;br /&gt;PGCONF="postgresql.conf"&lt;br /&gt;UNAME=/bin/uname&lt;br /&gt;HOST=`$UNAME -n`&lt;br /&gt;&lt;br /&gt;test -x $PSQL || exit 0&lt;br /&gt;test -f $PGDIR/$PGCONF || exit 0&lt;br /&gt;&lt;br /&gt;case "$1" in&lt;br /&gt;   start)&lt;br /&gt;       echo -n "Activating WAL archiving: "&lt;br /&gt;       $SED -r -e "s/\s*archive_command\s*=.*/archive_command = '\/bin\/cp %p \/var\/lib\/postgresql\/pg_xlog_archive\/%f'/" $PGDIR/$PGCONF &gt; /tmp/$PGCONF&lt;br /&gt;       chmod 644 /tmp/$PGCONF&lt;br /&gt;       mv --force /tmp/$PGCONF $PGDIR/&lt;br /&gt;       /etc/init.d/postgresql-8.3 reload 2&gt;&amp;amp;1 &gt; /dev/null&lt;br /&gt;       echo "done."&lt;br /&gt;       ;;&lt;br /&gt;&lt;br /&gt;   stop)&lt;br /&gt;       echo -n "Deactivating WAL archiving: "&lt;br /&gt;       $SED -r -e "s/\s*archive_command\s*=.*/archive_command = 'exit 0'/" $PGDIR/$PGCONF &gt; /tmp/$PGCONF&lt;br /&gt;       chmod 644 /tmp/$PGCONF&lt;br /&gt;       mv --force /tmp/$PGCONF $PGDIR/&lt;br /&gt;       /etc/init.d/postgresql-8.3 reload 2&gt;&amp;amp;1 &gt; /dev/null&lt;br /&gt;       echo "done."&lt;br /&gt;       ;;&lt;br /&gt;&lt;br /&gt;   status)&lt;br /&gt;       # Alternate way: SELECT setting FROM pg_settings WHERE name = 'archive_command'&lt;br /&gt;       am=`$PSQL -t -U pgpool2 -h $HOST -d postgres -c 'SHOW archive_mode' | $SED -r -e 's/^\s*//;s/\s*$//'`&lt;br /&gt;       ac=`$PSQL -t -U pgpool2 -h $HOST -d postgres -c 'SHOW archive_command' | $SED -r -e 's/^\s*//;s/\s*$//'`&lt;br /&gt;       echo "archive_mode = $am"&lt;br /&gt;       echo "archive_command = '$ac'"&lt;br /&gt;       ;;&lt;br /&gt;&lt;br /&gt;   *)&lt;br /&gt;       echo "Usage: $0 {start|stop|status}"&lt;br /&gt;       exit 1&lt;br /&gt;       ;;&lt;br /&gt;esac&lt;br /&gt;&lt;br /&gt;exit 0&lt;br /&gt;&lt;br /&gt;Este script podría crearse en /var/lib/postgresql/8.3/main/wall_archiving (propiedad del usuario y grupo postgres y permisos 755) sería llamado como usuario root o postgres pasándole por parámetro start, stop o status. Por ejemplo:&lt;br /&gt;&lt;br /&gt;$ /var/lib/postgresql/8.3/main/wall_archiving&lt;br /&gt;Usage: /var/lib/postgresql/8.3/main/wall_archiving {start|stop|status}&lt;br /&gt;$ /var/lib/postgresql/8.3/main/wal_archiving status&lt;br /&gt;archive_mode = on&lt;br /&gt;archive_command = 'exit 0'&lt;br /&gt;$ /var/lib/postgresql/8.3/main/wal_archiving start&lt;br /&gt;Activating WAL archiving: done.&lt;br /&gt;$ /var/lib/postgresql/8.3/main/wal_archiving stop&lt;br /&gt;Deactivating WAL archiving: done.&lt;br /&gt;$ tail -n 2 /var/log/postgresql/postgresql-8.3-main.log | ccze -A&lt;br /&gt;LOG:  incomplete startup packet&lt;br /&gt;LOG:  received SIGHUP, reloading configuration files&lt;br /&gt;&lt;br /&gt;pgpool-failover&lt;br /&gt;&lt;br /&gt;En términos generales, el mecanismo de failover permite asegurar la alta disponibilidad de diversos recursos críticos (como un sistema informático o un servicio de un sistema) incluyendo un sistema de respaldo paralelo que se mantiene en ejecución en todo momento, de modo que, en caso de detectarse un fallo en el sistema primario, las tareas a procesar puedan ser automáticamente desviadas hacia el sistema de respaldo, que seguirá dando servicio a los clientes.&lt;br /&gt;&lt;br /&gt;En este artículo se configura un clúster activo-pasivo (primario-secundario), con la salvedad de que se hace uso también del nodo secundario de forma parcial para acelerar las consultas de tipo SELECT (balanceo de carga). El procedimiento de failover en pgpool-II puede suponer tanto un failover hacia el nodo secundario (si ha fallado el primario) como una degeneración del nodo secundario (desactivación del nodo de respaldo).&lt;br /&gt;&lt;br /&gt;En el caso de haber más de un nodo secundario, lo arriba expuesto no varía pues sólo hay un nodo maestro. El siguiente script envía dos entradas al syslog, que luego pueden ser capturadas por una herramienta de monitorización como Zabbix o Nagios, las cuales enviarían las alertas pertinentes. Este es un acercamiento que utilizo normalmente, alternativo al tradicional envío de una notificación por correo electrónico.&lt;br /&gt;&lt;br /&gt;#! /bin/sh&lt;br /&gt;&lt;br /&gt;LOGGER="/usr/bin/logger -i -p local0.info -t pgpool"&lt;br /&gt;BASENAME=`/usr/bin/basename $0`&lt;br /&gt;ID=`/usr/bin/id -un`&lt;br /&gt;&lt;br /&gt;# $1 = node id&lt;br /&gt;# $2 = host name&lt;br /&gt;# $3 = port number&lt;br /&gt;# $4 = database cluster path&lt;br /&gt;# $5 = new master node id&lt;br /&gt;# $6 = old master node id&lt;br /&gt;&lt;br /&gt;$LOGGER "Executing $BASENAME as user $ID"&lt;br /&gt;$LOGGER "Failover of node $1 at hostname $2. New master node is $5. Old master node was $6."&lt;br /&gt;&lt;br /&gt;exit 0&lt;br /&gt;&lt;br /&gt;pgpool-II ejecuta este script como usuario postgres al final del proceso, una vez se ha completado la degeneración del nodo.&lt;br /&gt;&lt;br /&gt;pgpool-failback&lt;br /&gt;&lt;br /&gt;Análogamente, failback es el proceso mediante el cual se devuelve un sistema, componente o servicio en un estado de failover a su estado original (antes del fallo).&lt;br /&gt;&lt;br /&gt;pgpool-II ejecuta el script configurado como usuario postgres una vez concluido el procedimiento de failback, es decir, la recuperación en línea de un nodo en tres pasos. Del mismo modo que el caso del failover, a continuación se muestra un sencillo script de Bash que añade una entrada al syslog, de modo que pueda ser capturada por una herramienta de monitorización de logs que envíe las alertas pertinentes.&lt;br /&gt;&lt;br /&gt;#! /bin/sh&lt;br /&gt;&lt;br /&gt;LOGGER="/usr/bin/logger -i -p local0.info -t pgpool"&lt;br /&gt;BASENAME=`/usr/bin/basename $0`&lt;br /&gt;ID=`/usr/bin/id -un`&lt;br /&gt;&lt;br /&gt;# $1 = node id&lt;br /&gt;# $2 = host name&lt;br /&gt;# $3 = port number&lt;br /&gt;# $4 = database cluster path&lt;br /&gt;# $5 = new master node id&lt;br /&gt;# $6 = old master node id&lt;br /&gt;&lt;br /&gt;$LOGGER "Executing $BASENAME as user $ID"&lt;br /&gt;$LOGGER "Failback of node $1 at hostname $2. New master node is $5. Old master node was $6."&lt;br /&gt;&lt;br /&gt;exit 0&lt;br /&gt;&lt;br /&gt;base-backup&lt;br /&gt;&lt;br /&gt;De entre todas las tareas a realizar por parte del script base-backup, la única que está sujeta a variación en su implementación es la copia inicial de todo el directorio de datos de PostgreSQL ($PG_DATA, que en Debian es /var/lib/postgresql/8.3/main) desde el nodo maestro al nodo a recuperar.&lt;br /&gt;&lt;br /&gt;En el caso del script que se presenta a continuación, la herramienta elegida es rsync sobre un túnel SSH con un par de claves pública/privada DSA de 1024 bits sin contraseña. Esta elección se basa en dos puntos:&lt;br /&gt;&lt;br /&gt;   * La eficiencia de rsync (impacto sobre los discos frente al tiempo necesario), si bien el uso de un canal cifrado ralentiza el proceso.&lt;br /&gt;   * La mayor parte de los datos a copiar ya existirán en el nodo a recuperar. Podemos considerar que esta premisa será falsa únicamente en el caso de que el motivo de la caída del nodo hubiera sido la rotura de los discos.&lt;br /&gt;&lt;br /&gt;A continuación se presenta un script de ejemplo:&lt;br /&gt;&lt;br /&gt;#!/bin/sh&lt;br /&gt;&lt;br /&gt;PSQL=/usr/bin/psql&lt;br /&gt;SCP=/usr/bin/scp&lt;br /&gt;SSH=/usr/bin/ssh&lt;br /&gt;LOGGER="/usr/bin/logger -i -p local0.info -t pgpool"&lt;br /&gt;RSYNC="/usr/bin/rsync --archive --quiet --compress --rsh=$SSH --delete"&lt;br /&gt;BASENAME=`/usr/bin/basename $0`&lt;br /&gt;HOSTNAME=`/bin/hostname`&lt;br /&gt;ID=`/usr/bin/id -un`&lt;br /&gt;&lt;br /&gt;# $1 = Database cluster path of a master node.&lt;br /&gt;# $2 = Hostname of a recovery target node.&lt;br /&gt;# $3 = Database cluster path of a recovery target node.&lt;br /&gt;&lt;br /&gt;PG_HOME=/var/lib/postgresql&lt;br /&gt;SRC_DATA=$1&lt;br /&gt;DST_HOST=$2&lt;br /&gt;DST_DATA=$3&lt;br /&gt;&lt;br /&gt;$LOGGER "Executing $BASENAME as user $ID"&lt;br /&gt;&lt;br /&gt;$LOGGER "Executing pg_start_backup"&lt;br /&gt;$PSQL -d postgres -c "select pg_start_backup('pgpool-recovery')"&lt;br /&gt;&lt;br /&gt;$LOGGER "Creating file recovery.conf"&lt;br /&gt;echo "restore_command = '$SCP $HOSTNAME:$PG_HOME/pg_xlog_archive/%f %p'" &gt; $SRC_DATA/recovery.conf&lt;br /&gt;&lt;br /&gt;$LOGGER "Rsyncing directory base"&lt;br /&gt;$RSYNC $SRC_DATA/base/ $DST_HOST:$DST_DATA/base/&lt;br /&gt;$LOGGER "Rsyncing directory global"&lt;br /&gt;$RSYNC $SRC_DATA/global/ $DST_HOST:$DST_DATA/global/&lt;br /&gt;$LOGGER "Rsyncing directory pg_clog"&lt;br /&gt;$RSYNC $SRC_DATA/pg_clog/ $DST_HOST:$DST_DATA/pg_clog/&lt;br /&gt;$LOGGER "Rsyncing directory pg_multixact"&lt;br /&gt;$RSYNC $SRC_DATA/pg_multixact/ $DST_HOST:$DST_DATA/pg_multixact/&lt;br /&gt;$LOGGER "Rsyncing directory pg_subtrans"&lt;br /&gt;$RSYNC $SRC_DATA/pg_subtrans/ $DST_HOST:$DST_DATA/pg_subtrans/&lt;br /&gt;$LOGGER "Rsyncing directory pg_tblspc"&lt;br /&gt;$RSYNC $SRC_DATA/pg_tblspc/ $DST_HOST:$DST_DATA/pg_tblspc/&lt;br /&gt;$LOGGER "Rsyncing directory pg_twophase"&lt;br /&gt;$RSYNC $SRC_DATA/pg_twophase/ $DST_HOST:$DST_DATA/pg_twophase/&lt;br /&gt;$LOGGER "Rsyncing directory pg_xlog"&lt;br /&gt;$RSYNC $SRC_DATA/pg_xlog/ $DST_HOST:$DST_DATA/pg_xlog/&lt;br /&gt;$LOGGER "Rsyncing file recovery.conf (with source deletion)"&lt;br /&gt;$RSYNC --remove-source-files $SRC_DATA/recovery.conf $DST_HOST:$DST_DATA/&lt;br /&gt;&lt;br /&gt;$LOGGER "Executing pg_stop_backup"&lt;br /&gt;$PSQL -d postgres -c 'select pg_stop_backup()'&lt;br /&gt;&lt;br /&gt;exit 0&lt;br /&gt;&lt;br /&gt;pgpool-recovery-pitr&lt;br /&gt;&lt;br /&gt;El único propósito de este script es forzar la rotación de un fichero WAL (y su consecuente archivado al directorio /var/lib/postgresql/pg_xlog_archive). El script pgpool-recovery-pitr se ejecuta una vez se han dejado de atender nuevas peticiones de clientes (que quedan en una cola de peticiones pendientes de atender) y se han atendido las que estaban en curso (o se ha llegado al timeout y se han desechado).&lt;br /&gt;&lt;br /&gt;A continuación se presenta un script de ejemplo:&lt;br /&gt;&lt;br /&gt;#! /bin/sh&lt;br /&gt;&lt;br /&gt;PSQL=/usr/bin/psql&lt;br /&gt;LOGGER="/usr/bin/logger -i -p local0.info -t pgpool"&lt;br /&gt;BASENAME=`/usr/bin/basename $0`&lt;br /&gt;ID=`/usr/bin/id -un`&lt;br /&gt;&lt;br /&gt;$LOGGER "Executing $BASENAME as user $ID"&lt;br /&gt;$LOGGER "Executing pg_switch_xlog"&lt;br /&gt;$PSQL -d postgres -c 'select pg_switch_xlog()'&lt;br /&gt;&lt;br /&gt;exit 0&lt;br /&gt;&lt;br /&gt;pgpool_remote_start&lt;br /&gt;&lt;br /&gt;La función del script pgpool_remote_start es la de arrancar remotamente la instancia de PostgreSQL en el nodo a recuperar. Para poder utilizar el mismo usuario postgres y su par de claves pública/privada, he optado por hacer una llamada a través de SSH directamente al binario /usr/bin/pg_ctlcluster. Nótese que el script de arranque sito en /etc/init.d/postgresql-8.3 realiza la misma llamada, pero precedida de una serie de verificaciones que, en este caso, asumimos como correctas (básicamente que se dispone de todos los binarios y librerías necesarios y que no hay una instancia ya ejecutándose):&lt;br /&gt;&lt;br /&gt;#! /bin/sh&lt;br /&gt;&lt;br /&gt;SSH=/usr/bin/ssh&lt;br /&gt;LOGGER="/usr/bin/logger -i -p local0.info -t pgpool"&lt;br /&gt;BASENAME=`/usr/bin/basename $0`&lt;br /&gt;ID=`/usr/bin/id -un`&lt;br /&gt;&lt;br /&gt;DST_HOST=$1&lt;br /&gt;DST_DIR=$2&lt;br /&gt;&lt;br /&gt;$LOGGER "Executing $BASENAME as user $ID"&lt;br /&gt;$LOGGER "Starting remote PostgreSQL server"&lt;br /&gt;$SSH -T $DST_HOST '/usr/bin/pg_ctlcluster 8.3 main start' 2&gt;/dev/null 1&gt;/dev/null&lt;br /&gt;&lt;br /&gt;exit 0&lt;br /&gt;&lt;br /&gt;Comandos de PCP&lt;br /&gt;&lt;br /&gt;pgpool-II proporciona una interfaz de control desde la consola mediante la cual el administrador puede recoger el estado de pgpool-II y gestionar sus procesos a través de la red. Todos los comandos PCP siguen el mismo patrón:&lt;br /&gt;&lt;br /&gt;&lt;comando_pcp&gt; &lt;timeout&gt; &lt;hostname&gt; &lt;puerto&gt; &lt;username&gt; &lt;password&gt; [&lt;núm_nodo&gt;]&lt;br /&gt;&lt;br /&gt;El número de nodo es necesario sólo en algunos comandos. Todos los comandos se encuentran en /opt/pgpool2/bin, por lo que se eliminará esta ruta en todos los ejemplos (queda a discreción del usuario añadir dicho directorio al PATH o preceder los comandos con la misma). El hostname será siempre el de la máquina donde se esté ejecutando pgpool-II y el puerto el 9898. El usuario y la contraseña serán los definidos en el fichero /opt/pgpool2/etc/pcp.conf.&lt;br /&gt;&lt;br /&gt;A continuación se muestra el funcionamiento de algunos de estos comandos, utilizados para la gestión del clúster explicado en el artículo.&lt;br /&gt;&lt;br /&gt;Para saber el número de nodos controlados por pgpool-II (activos o no), podemos ejecutar el siguiente comando:&lt;br /&gt;&lt;br /&gt;pcp_node_count 5 pgsql1 9898 root &lt;password&gt;&lt;br /&gt;&lt;br /&gt;Nos devolverá un número entero mayor o igual que cero. Es útil a la hora de crear scripts. Para saber el estado de un nodo podemos usar el siguiente comando:&lt;br /&gt;&lt;br /&gt;pcp_node_info 5 pgsql1 9898 root &lt;password&gt; &lt;núm_nodo&gt;&lt;br /&gt;&lt;br /&gt;El último parámetro será el número de nodo del cuál se desea información. Téngase en cuenta que se empieza a contar por el cero. La salida del comando ofrece cuatro campos, en este orden:&lt;br /&gt;&lt;br /&gt;  1. Nombre del host&lt;br /&gt;  2. Número de puerto&lt;br /&gt;  3. Estado&lt;br /&gt;  4. Peso en el balanceo de carga&lt;br /&gt;&lt;br /&gt;El estado viene representado por un dígito de 0 a 3:&lt;br /&gt;&lt;br /&gt;  0. Este estado se usa únicamente durante la inicialización y PCP no lo mostrará nunca.&lt;br /&gt;  1. El nodo está activo pero no ha recibido conexiones todavía.&lt;br /&gt;  2. El nodo está activo y hay conexiones activas (en el pool o fondo común).&lt;br /&gt;  3. El nodo está caído.&lt;br /&gt;&lt;br /&gt;Para iniciar la recuperación de un nodo usaremos el siguiente comando:&lt;br /&gt;&lt;br /&gt;pcp_recovery_node 5 pgsql1 9898 root &lt;password&gt; &lt;núm_nodo&gt;&lt;br /&gt;&lt;br /&gt;El último parámetro será el número de nodo a recuperar. Téngase en cuenta que se empieza a contar por el cero. El comando pcp_node_info nos permitirá conocer el estado de cada nodo (nos interesan los nodos en estado 3).&lt;br /&gt;Todos los comandos PCP finalizan con un código de salida 0 si todo va sobre ruedas. Si ha ocurrido algún error, deberá consultarse la siguiente tabla de códigos de error:&lt;br /&gt;Nombre 	Código 	Descripción&lt;br /&gt;unknownerr 	1 	error desconocido (no debería ocurrir)&lt;br /&gt;eoferr 	2 	error de fin de fichero (end of file)&lt;br /&gt;nomemerr 	3 	memoria insuficiente&lt;br /&gt;readerr 	4 	error durante la lectura de datos del servidor&lt;br /&gt;writeerr 	5 	error durante la escritura de datos al servidor&lt;br /&gt;timeouterr 	6 	timeout&lt;br /&gt;invalerr 	7 	parámetros del comando pcp incorrectos&lt;br /&gt;connerr 	8 	error de conexión con el servidor&lt;br /&gt;noconnerr 	9 	no existe ninguna conexión&lt;br /&gt;sockerr 	10 	error de socket&lt;br /&gt;hosterr 	11 	error de resolución del nombre de host&lt;br /&gt;backenderr 	12 	error de proceso de pcp en el servidor (se especificó un id inválido, etc.)&lt;br /&gt;autherr 	13 	error de autorización&lt;br /&gt;&lt;br /&gt;Simulación de caída y recuperación de un nodo&lt;br /&gt;&lt;br /&gt;Para simular la caída de un nodo, vamos a apagar el servidor PostgreSQL del nodo secundario:&lt;br /&gt;&lt;br /&gt;/etc/init.d/postgresql-8.3 stop&lt;br /&gt;&lt;br /&gt;En estos instantes, lo más probable es que pgpool-II aún no se haya dado cuenta de que ese nodo está caído. Bien podemos esperar a que se ejecute un health check (cada 60 segundos o según se haya configurado la directiva health_check_period) o podemos forzarlo manualmente lanzando una consulta SQL de tipo INSERT, UPDATE o DELETE. En cualquier caso, veremos aparecer las siguientes líneas en el /var/log/syslog:&lt;br /&gt;&lt;br /&gt;ERROR: pid 27928: connect_inet_domain_socket: connect() failed: Connection refused&lt;br /&gt;ERROR: pid 27928: health check failed. 1 th host 192.168.0.4 at port 5432 is down&lt;br /&gt;LOG:   pid 27928: set 1 th backend down status&lt;br /&gt;LOG:   pid 27928: starting degeneration. shutdown host 192.168.0.4(5432)&lt;br /&gt;LOG:   pid 27928: failover_handler: do not restart pgpool. same master node 0 was selected&lt;br /&gt;LOG:   pid 27928: failover done. shutdown host 192.168.0.4(5432)&lt;br /&gt;&lt;br /&gt;Con la consulta SQL siguiente obtendremos el mismo resultado:&lt;br /&gt;&lt;br /&gt;psql -h 192.168.0.4 -p 9999 -U pgpool2 -d bench_replication -c "UPDATE ACCOUNTS SET abalance = 1009 WHERE aid = 10"&lt;br /&gt;&lt;br /&gt;Como puede observarse en el log, para llevar a cabo el proceso de failover, pgpool-II tan sólo tiene que degenerar el nodo caído y, tal y como informa, no es necesario reinicio alguno. A efectos prácticos, lo único que se ha perdido es la capacidad de balancear la carga. Éste es el caso más sencillo posible al que podemos enfrentarnos.&lt;br /&gt;Ahora, para iniciar la recuperación del nodo pgsql2, realizaremos los siguientes pasos (según lo explicado anteriormente en este artículo):&lt;br /&gt;&lt;br /&gt;  1. Activar el archivado de ficheros WAL.&lt;br /&gt;  2. Ejecutar el comando pcp_recovery_node en el nodo 0 (pgsql1) o en algún cliente con autorización en el fichero pg_hba.conf.&lt;br /&gt;  3. Desactivar el archivado de ficheros WAL y borrar aquellos que se hayan copiado al directorio /var/lib/postgresql/pg_xlog_archive del nodo maestro durante el proceso.&lt;br /&gt;&lt;br /&gt;El siguiente comando instruye a pgpool-II que inicie el proceso de recuperación del nodo 1 (pgsql2):&lt;br /&gt;&lt;br /&gt;/opt/pgpool2/bin/pcp_recovery_node 5 pgsql1 9898 root &lt;password&gt; 1&lt;br /&gt;&lt;br /&gt;Éste es el log de pgpool-II (/var/log/syslog) producido por la ejecución del anterior comando (los comandos de failover y failback no estaban configurados en el fichero de configuración durante la ejecución):&lt;br /&gt;&lt;br /&gt;LOG:   pid 27964: starting recovering node 1&lt;br /&gt;LOG:   pid 27964: CHECKPOINT in the 1st stage done&lt;br /&gt;LOG:   pid 27964: starting recovery command: "SELECT pgpool_recovery('base-backup', '192.168.0.4', '/var/lib /postgresql/8.3/main')"&lt;br /&gt;pgpool[28094]: Executing base-backup as user postgres&lt;br /&gt;pgpool[28095]: Executing pg_start_backup&lt;br /&gt;pgpool[28098]: Creating file recovery.conf&lt;br /&gt;pgpool[28099]: Rsyncing directory base&lt;br /&gt;pgpool[28103]: Rsyncing directory global&lt;br /&gt;pgpool[28106]: Rsyncing directory pg_clog&lt;br /&gt;pgpool[28109]: Rsyncing directory pg_multixact&lt;br /&gt;pgpool[28112]: Rsyncing directory pg_subtrans&lt;br /&gt;pgpool[28115]: Rsyncing directory pg_tblspc&lt;br /&gt;pgpool[28118]: Rsyncing directory pg_twophase&lt;br /&gt;pgpool[28121]: Rsyncing directory pg_xlog&lt;br /&gt;pgpool[28124]: Rsyncing file recovery.conf (with source deletion)&lt;br /&gt;pgpool[28127]: Executing pg_stop_backup&lt;br /&gt;LOG:   pid 27964: 1st stage is done&lt;br /&gt;LOG:   pid 27964: starting 2nd stage&lt;br /&gt;LOG:   pid 27964: all connections from clients have been closed&lt;br /&gt;LOG:   pid 27964: CHECKPOINT in the 2nd stage done&lt;br /&gt;LOG:   pid 27964: starting recovery command: "SELECT pgpool_recovery('pgpool-recovery-pitr', '192.168.0.4', '/var/lib/postgresql/8.3/main')"&lt;br /&gt;pgpool[28138]: Executing pgpool-recovery-pitr as user postgres&lt;br /&gt;pgpool[28147]: Executing pgpool_remote_start as user postgres&lt;br /&gt;pgpool[28148]: Starting remote PostgreSQL server&lt;br /&gt;LOG:   pid 27964: 1 node restarted&lt;br /&gt;LOG:   pid 27964: send_failback_request: fail back 1 th node request from pid 27964&lt;br /&gt;LOG:   pid 27964: recovery done&lt;br /&gt;LOG:   pid 27928: starting fail back. reconnect host 192.168.0.4(5432)&lt;br /&gt;LOG:   pid 27928: failover_handler: do not restart pgpool. same master node 0 was selected&lt;br /&gt;LOG:   pid 27928: failback done. reconnect host 192.168.0.4(5432)&lt;br /&gt;&lt;br /&gt;Tal y como podemos ver en el log, pgpool-II realiza las siguientes acciones:&lt;br /&gt;&lt;br /&gt;   * Hace un checkpoint de la base de datos. Este checkpoint en realidad no es necesario, pues ya lo lanza el propio pg_start_backup que se ejecuta al principio del script base-backup, pero está aquí por compatibilidad con PostgreSQL 7.4.&lt;br /&gt;   * Ejecuta el script base-backup (primera fase de la recuperación en línea) mediante la ejecución de la función pgpool_recovery añadida durante la configuración de pgpool-II. Durante la ejecución de este fichero, sigue aceptando y atendiendo peticiones de los clientes.&lt;br /&gt;   * Corta las nuevas conexiones de clientes, que quedan encoladas, a la espera de poder ser atendidas.&lt;br /&gt;   * Espera a que se hayan atendido las peticiones que ya estaban en marcha.&lt;br /&gt;   * Realiza un checkpoint en la base de datos (pone fin al backup online).&lt;br /&gt;   * Ejecuta el script pgpool-recovery-pitr (segunda fase de la recuperación en línea), también mediante la función pgpool_recovery. Esto fuerza la rotación del fichero WAL actual.&lt;br /&gt;   * Ejecuta el script pgpool_remote_start.&lt;br /&gt;   * Reconoce el nuevo nodo y lo añade al clúster.&lt;br /&gt;   * Vuelve a operar con normalidad, atendiendo a las peticiones que se habían ido encolando durante la segunda fase y el inicio remoto del nuevo nodo.&lt;br /&gt;   * En el caso de que se hayan producido variaciones de los datos durante la primera fase de la recuperación (se hayan atendido consultas INSERT, UPDATE o DELETE), será necesario ejecutar REINDEX sobre todos los índices de la base de datos afectados una vez recuperado el nodo, puesto que las operaciones sobre índices de tipo tablas de dispersión (hash) no se guardan en el WAL.&lt;br /&gt;   * Si realizamos la misma operación con el nodo principal, el proceso de failover consistirá en la degeneración del nodo principal y en cambiar el papel de maestro al nodo pasivo del clúster (a partir de ahora el nodo maestro será el 1). Tras realizar la recuperación online, pgpool-II mantendrá al nodo secundario como maestro.&lt;br /&gt;&lt;br /&gt;Alta disponibilidad de pgpool-II&lt;br /&gt;&lt;br /&gt;Gracias a pgpool-II tenemos la posibilidad de seguir dando servico tras el fallo de N-1 servidores de PostgreSQL en nuestro clúster. Ahora bien, si la alta disponibilidad completa es uno de los requerimientos (u objetivos) de nuestro sistema, debemos garantizar la continuidad del servicio en caso de caída del middleware.&lt;br /&gt;&lt;br /&gt;Para ello, instalaremos otra copia de pgpool-II en el nodo pgsql2, con una configuración casi idéntica a la del ya instalado, y utilizaremos Heartbeat para detectar la caída completa de un nodo (no sólo del servidor de PostgreSQL en dicho nodo) y la gestión de dicho evento. A partir de este momento, entra en juego una nueva dirección IP, la 192.168.0.2, que es la dirección IP que ambos nodos compartirán y que Heartbeat se encargará de gestionar, de modo que sólo uno de los nodos (aquel actuando como maestro) tenga configurada dicha dirección IP en un momento dado. Esta dirección IP es conocida como dirección IP de servicio.&lt;br /&gt;&lt;br /&gt;Los pasos a seguir para instalar pgpool-II en pgsql2 son los mismos que en pgsql1:&lt;br /&gt;&lt;br /&gt;   * Bajar los fuentes al directorio /usr/local/src.&lt;br /&gt;   * Instalar las dependencias de compilación.&lt;br /&gt;   * Descomprimir, compilar e instalar.&lt;br /&gt;   * Compilar e instalar la función y la librería&lt;br /&gt;   * pgpool-recovery&lt;br /&gt;&lt;br /&gt;     .&lt;br /&gt;   * Crear los ficheros de configuración y el script de arranque.&lt;br /&gt;&lt;br /&gt;Los ficheros de configuración y el script de arranque pueden copiarse desde pgsql1 a pgsql2. El único fichero que precisará algunas modificaciones será /opt/pgpool2/etc/pgpool.conf. A continuación se presentan los valores que habrá que cambiar en pgsql2:&lt;br /&gt;&lt;br /&gt;listen_addresses = '192.168.0.2'&lt;br /&gt;pgpool2_hostname = 'pgsql2'&lt;br /&gt;backend_hostname0 = '192.168.0.4'&lt;br /&gt;backend_hostname1 = '192.168.0.3'&lt;br /&gt;&lt;br /&gt;Y en el nodo pgsql1 tan sólo habrá que cambiar la dirección IP de servicio:&lt;br /&gt;&lt;br /&gt;[código 58]&lt;br /&gt;&lt;br /&gt;Hay que tener en cuenta que, si en algún momento el nodo pgsql2 pasase a ser el nodo maestro, entonces los índices de los nodos se invertirían, ya que en el pgpool-II de pgsql2 los nodos están configurados al revés (pgsql1 pasaría a ser el nodo 1 y pgsql2 sería el nodo 0).&lt;br /&gt;&lt;br /&gt;El proyecto Linux High Availability&lt;br /&gt;&lt;br /&gt;El objetivo fundamental del proyecto Linux-HA es desarrollar una solución de alta disponibilidad (clustering) para Linux que proporcione y promocione la fiabilidad, la disponibilidad y la calidad de servicio o usabilidad (RAS, en sus siglas en inglés) a través del esfuerzo de una comunidad de desarrolladores.&lt;br /&gt;&lt;br /&gt;El programa Heartbeat es uno de los componentes principales del proyecto. Fácilmente portable, corre en todos los Linux conocidos, así como en FreeBSD y Solaris. Heartbeat es una de las implementaciones principales del estándar Open Cluster Framework (OCF).&lt;br /&gt;&lt;br /&gt;Heartbeat fue la primera pieza de software que se escribió para el proyecto Linux-HA. Puede llevar a cabo la detección de la caída de nodos, las comunicaciones y la gestión del clúster en un solo proceso. Actualmente soporta un modelo de dependencias muy sofisticado para clústeres de N nodos, y es muy útil y estable. La unidad de gestión de Heartbeat es el recurso. Los recursos pueden ser, por ejemplo, direcciones IP o servicios (aplicaciones). Los siguientes tipos de aplicaciones son típicos ejemplos:&lt;br /&gt;&lt;br /&gt;   * Servidores de bases de datos.&lt;br /&gt;   * Servidores web.&lt;br /&gt;   * Aplicaciones ERP.&lt;br /&gt;   * Servidores de correo electrónico.&lt;br /&gt;   * Cortafuegos.&lt;br /&gt;   * Servidores de ficheros.&lt;br /&gt;   * Servidores de DNS.&lt;br /&gt;   * Servidores de DHCP.&lt;br /&gt;   * Servidores de proxy-caché.&lt;br /&gt;&lt;br /&gt;Un recurso es la unidad básica de la alta disponibilidad. Un recurso es un servicio o facility el cuál pasa a tener alta disponibilidad mediante el gestor de recursos del clúster de alta disponibilidad.&lt;br /&gt;&lt;br /&gt;Un recurso es una abstracción que puede ser de diferentes tipos. Puede ser algo muy concreto, como un volumen de disco o un lector de tarjetas, o puede ser más abstracto, como una dirección IP, un conjunto de reglas de firewall o un servicio de software (como un servidor web o un servidor de base de datos).&lt;br /&gt;&lt;br /&gt;Las operaciones básicas que los recursos deben soportar son las siguientes:&lt;br /&gt;&lt;br /&gt;   * start: iniciar o adquirir el control del recurso.&lt;br /&gt;   * stop: finalizar o ceder el control del recurso.&lt;br /&gt;   * status: consultar si el recurso está iniciado o parado.&lt;br /&gt;   * monitor: consultar de manera más detallada si el recurso está operando correctamente.&lt;br /&gt;&lt;br /&gt;Nótese que los recursos del tipo R1 (versión 1 de Linux-HA) deben soportar status, mientras que los del tipo R2 (versión 2) deben soportar la operación monitor.&lt;br /&gt;&lt;br /&gt;El gestor de recursos del clúster de alta disponibilidad intenta conseguir que todos los recursos estén disponibles para los usuarios asegurándose de que estén ejecutándose en alguno de los nodos del clúster.&lt;br /&gt;&lt;br /&gt;El gestor de recursos de Heartbeat R1 (y muchos otros gestores de recursos en clúster) aúna diversos recursos en grupos, llamados ResourceGroups. En ese caso, cada grupo es iniciado, detenido o movido en su conjunto por el gestor de recursos del clúster.&lt;br /&gt;&lt;br /&gt;Instalación de Heartbeat&lt;br /&gt;&lt;br /&gt;Pasamos ahora a la instalación y configuración de la alta disponibilidad con Heartbeat. El primer paso será instalarlo en ambos nodos:&lt;br /&gt;&lt;br /&gt;apt-get install heartbeat&lt;br /&gt;&lt;br /&gt;Los ficheros de configuración de Heartbeat están en /etc/ha.d. Necesitamos crear tres ficheros:&lt;br /&gt;&lt;br /&gt;   * ha.cf: fichero de configuración principal.&lt;br /&gt;   * haresources: fichero de configuración de recursos.&lt;br /&gt;   * authkeys: información de autenticación.&lt;br /&gt;&lt;br /&gt;Llegados a este punto, es preciso introducir dos nuevos conceptos de uso frecuente con Heartbeat, dirección IP de servicio y dirección IP de administración.&lt;br /&gt;&lt;br /&gt;Una dirección de servicio es una dirección que es gestionada por el sistema de HA, y que es movida por el clúster allí donde los servicios correspondientes se estén ejecutando. Estas direcciones de servicio son direcciones a través de las cuales los clientes y usuarios de los servicios en HA acceden a dichos servicios. Típicamente se almacenan en DNS con nombres conocidos.&lt;br /&gt;&lt;br /&gt;Es importante que la dirección de servicio no sea gestionada por el sistema operativo, sino que sea el software de HA el único que la maneje. Si se le da una dirección administrativa al sistema de HA para que la gestione, ésto causará problemas pues se confundirá al sistema de HA y el sistema operativo y el sistema de HA se pelearán por el control de esta dirección.&lt;br /&gt;&lt;br /&gt;El agente de recursos IPaddr2 es capaz de levantar una interfaz desde cero, incluso si no se ha establecido ninguna dirección base (la versión anterior necesitaba de una dirección base en cualquier interfaz, pues tan sólo era capaz de añadir o eliminar direcciones a interfaces ya levantados). Además, no existe límite en el número de direcciones IP por interfaz que IPaddr2 puede gestionar.&lt;br /&gt;&lt;br /&gt;En cambio, una dirección administrativa es una dirección que está permanentemente asociada a un nodo específico del clúster.&lt;br /&gt;&lt;br /&gt;Tales direcciones son muy útiles, y se recomienda encarecidamente que una dirección de este tipo sea reservada para cada nodo del clúster, de manera que el administrador de sistemas pueda acceder al nodo del clúster incluso si no hay servicios ejecutándose. Para la mayoría de sistemas, una dirección de este tipo es obligatoria.&lt;br /&gt;&lt;br /&gt;Asimismo, se recomienda que se reserve una de estas direcciones para cada interfaz, de modo que se puedan testear las interfaces incluso cuando no estén activas.&lt;br /&gt;&lt;br /&gt;Tal y como se ha especificado al inicio de este artículo, la configuración de direcciones administrativas y de servicio es la siguiente:&lt;br /&gt;&lt;br /&gt;   * Dirección de servicio (inicialmente en pgsql1): 192.168.0.2&lt;br /&gt;   * Dirección administrativa de pgsql1: 192.168.0.3&lt;br /&gt;   * Dirección administrativa de pgsql2: 192.168.0.4&lt;br /&gt;&lt;br /&gt;Si lo deseamos, para facilitar las pruebas o en vistas al futuro, podemos configurar la dirección de servicio en el fichero /etc/network/interfaces siempre y cuando no incluyamos su autoconfiguración (en forma de directiva auto o allow-hotplug). El fichero /etc/network/interfaces del nodo pgsql1 podría quedar tal y como sigue:&lt;br /&gt;&lt;br /&gt;auto lo&lt;br /&gt;iface lo inet loopback&lt;br /&gt;&lt;br /&gt;# Dirección administrativa&lt;br /&gt;allow-hotplug eth0&lt;br /&gt;iface eth0 inet static&lt;br /&gt;   address 192.168.0.3&lt;br /&gt;   netmask 255.255.255.0&lt;br /&gt;   network 192.168.0.0&lt;br /&gt;   broadcast 192.168.0.255&lt;br /&gt;   gateway 192.168.0.1&lt;br /&gt;&lt;br /&gt;# Dirección de servicio&lt;br /&gt;iface eth0:0 inet static&lt;br /&gt;   address 192.168.0.2&lt;br /&gt;   netmask 255.255.255.0&lt;br /&gt;   network 192.168.0.0&lt;br /&gt;   broadcast 192.168.0.255&lt;br /&gt;&lt;br /&gt;De nuevo, nótese que la declaración de la dirección de servicio en el fichero /etc/network/interfaces es completamente prescindible al usar el agente de recursos IPaddr2. El único propósito es dejar constancia de ella en el sistema fuera de la configuración de Heartbeat.&lt;br /&gt;&lt;br /&gt;Configuración de Heartbeat&lt;br /&gt;&lt;br /&gt;Vamos ahora a editar los tres ficheros de configuración de Heartbeat. Tomaremos los ficheros de ejemplo de /usr/share/doc/heartbeat y los modificaremos a nuestro gusto. Empezaremos con el fichero ha.cf:&lt;br /&gt;&lt;br /&gt;cd /etc/ha.d/&lt;br /&gt;cp /usr/share/doc/heartbeat/ha.cf.gz /etc/ha.d/&lt;br /&gt;gunzip ha.cf.gz&lt;br /&gt;&lt;br /&gt;Editamos el fichero /etc/ha.d/ha.cf y lo configuramos a nuestro gusto, por ejemplo tal y como sigue:&lt;br /&gt;&lt;br /&gt;logfacility local0&lt;br /&gt;keepalive 2&lt;br /&gt;deadtime 30&lt;br /&gt;warntime 10&lt;br /&gt;initdead 120&lt;br /&gt;udpport 694&lt;br /&gt;bcast eth0&lt;br /&gt;auto_failback off&lt;br /&gt;node pgsql1 # uname -n&lt;br /&gt;node pgsql2 # uname -n&lt;br /&gt;ping 192.168.0.1 # router&lt;br /&gt;respawn hacluster /usr/lib/heartbeat/ipfail&lt;br /&gt;&lt;br /&gt;Nos aseguramos, una vez más, de que los nodos pgsql1 y pgsql2 existen en el fichero /etc/hosts de ambos hosts pgsql1 y pgsql2:&lt;br /&gt;&lt;br /&gt;127.0.0.1      localhost.localdomain localhost&lt;br /&gt;192.168.0.1    router.dominio.com       router&lt;br /&gt;192.168.0.2    pgpool2.dominio.com      pgpool2&lt;br /&gt;192.168.0.3    pgsql1.dominio.com       pgsql1&lt;br /&gt;192.168.0.4    pgsql2.dominio.com       pgsql2&lt;br /&gt;&lt;br /&gt;Editamos el fichero /etc/ha.d/haresources y añadimos la siguiente línea:&lt;br /&gt;&lt;br /&gt;pgsql1 192.168.0.2 pgpool2&lt;br /&gt;&lt;br /&gt;Esto indica a Heartbeat que el nodo maestro es pgsql1 y que debe gestionar dos recursos:&lt;br /&gt;&lt;br /&gt;   * La dirección IP de servicio 192.168.0.2.&lt;br /&gt;   * El servicio pgpool2.&lt;br /&gt;&lt;br /&gt;El orden es muy importante. Primero se especifica el hostname del nodo que consideramos maestro. Segundo, los recursos. El orden de los recursos también es crítico, pues Heartbeat los iniciará en orden de izquierda a derecha, y los detendrá en orden de derecha a izquierda (y no queremos que intente arrancar el servicio pgpool2 antes de disponer de la dirección IP en la cual pgpool-II debe escuchar).&lt;br /&gt;&lt;br /&gt;Heartbeat buscará el script de arranque del servicio que debe gestionar en /etc/init.d y en /etc/ha.d/resource.d. Siempre y cuando no creemos los enlaces en los directorios /etc/rcX.d, tanto da que lo coloquemos en uno u otro, pues el sistema operativo no lo arrancará automáticamente. Entonces, creamos un enlace débil al script de arranque pgpool2 para que Heartbeat pueda encontrarlo:&lt;br /&gt;&lt;br /&gt;cd /etc/ha.d/resource.d&lt;br /&gt;ln --symbolic /opt/pgpool2/etc/init.d/pgpool2&lt;br /&gt;&lt;br /&gt;De este modo pgpool2 no se arrancará al iniciarse el nodo, sino que será Heartbeat quien lo arranque si detecta que así tiene que hacerlo, es decir, si decide que éste nodo debe asumir el papel de maestro.&lt;br /&gt;&lt;br /&gt;A continuación editamos el fichero /etc/ha.d/authkeys:&lt;br /&gt;&lt;br /&gt;auth 1&lt;br /&gt;1 sha1 57ef7ac02cf6aef7e13131622598f94778fb07d6&lt;br /&gt;&lt;br /&gt;Para obtener la clave SHA1 de la contraseña en texto plano que querramos usar, utilizaremos el comando sha1sum:&lt;br /&gt;&lt;br /&gt;$ echo -n "&lt;password&gt;" | sha1sum&lt;br /&gt;57ef7ac02cf6aef7e13131622598f94778fb07d6  -&lt;br /&gt;&lt;br /&gt;Authkeys es obligatorio que sea accesible sólo por el usuario root y que tenga permisos 600. Los demás, 664. Les damos los permisos adecuados a los ficheros:&lt;br /&gt;&lt;br /&gt;chown root:root /etc/ha.d/authkeys /etc/ha.d/haresources /etc/ha.d/ha.cf&lt;br /&gt;chmod 600 /etc/ha.d/authkeys&lt;br /&gt;chmod 664 /etc/ha.d/haresources /etc/ha.d/ha.cf&lt;br /&gt;&lt;br /&gt;Finalmente, configuraremos el logger daemon, específico de Heartbeat. Tomamos el fichero de ejemplo en /usr/share/doc/heartbeat:&lt;br /&gt;&lt;br /&gt;cp --archive /usr/share/doc/heartbeat/logd.cf /etc/&lt;br /&gt;&lt;br /&gt;Editamos el fichero /etc/logd.cf:&lt;br /&gt;&lt;br /&gt;debugfile /var/log/ha-debug&lt;br /&gt;logfile /var/log/ha-log&lt;br /&gt;logfacility daemon&lt;br /&gt;entity logd&lt;br /&gt;useapphbd no&lt;br /&gt;sendqlen 256&lt;br /&gt;recvqlen 256&lt;br /&gt;&lt;br /&gt;Repetiremos los anteriores pasos para el nodo pgsql2. Los ficheros de configuración serán idénticos en ambos nodos, sin diferencia alguna, por lo que podemos copiar los ficheros de configuración desde pgsql1 a pgsql2 sin problemas.&lt;br /&gt;&lt;br /&gt;Ahora ya estamos listos para iniciar la alta disponibilidad. Debido a que el logd puede estar iniciado con una configuración por defecto, vamos a asegurarnos primero de que Heartbeat está completamente parado en ambos nodos:&lt;br /&gt;&lt;br /&gt;/etc/init.d/heartbeat stop&lt;br /&gt;&lt;br /&gt;Es posible que debamos esperar a algún timeout. Ahora, con una diferencia máxima de 120 segundos (directiva initdead en /etc/ha.d/ha.cf), ejecutaremos el script de inicio, primero en pgsql1 y después en pgsql2:&lt;br /&gt;&lt;br /&gt;/etc/init.d/heartbeat start&lt;br /&gt;&lt;br /&gt;Podemos monitorizar el arranque de ambos Heartbeats a través del fichero de log /var/log/ha-log. En el nodo pgsql1 debería aparecernos la siguiente (o parecida) información en dicho log:&lt;br /&gt;&lt;br /&gt;logd[4197]: info: logd started with /etc/logd.cf.&lt;br /&gt;logd[4197]: WARN: Core dumps could be lost if multiple dumps occur.&lt;br /&gt;logd[4197]: WARN: Consider setting non-default value in /proc/sys/kernel/core_pattern (or equivalent) for maximum supportability&lt;br /&gt;logd[4197]: WARN: Consider setting /proc/sys/kernel/core_uses_pid (or equivalent) to 1 for maximum supportability&lt;br /&gt;logd[4197]: info: G_main_add_SignalHandler: Added signal handler for signal 15&lt;br /&gt;logd[4197]: info: G_main_add_SignalHandler: Added signal handler for signal 15&lt;br /&gt;heartbeat[4272]: info: Enabling logging daemon&lt;br /&gt;heartbeat[4272]: info: logfile and debug file are those specified in logd config file (default /etc/logd.cf)&lt;br /&gt;heartbeat[4272]: WARN: Core dumps could be lost if multiple dumps occur.&lt;br /&gt;heartbeat[4272]: WARN: Consider setting non-default value in /proc/sys/kernel/core_pattern (or equivalent) for maximum supportability&lt;br /&gt;heartbeat[4272]: WARN: Consider setting /proc/sys/kernel/core_uses_pid (or equivalent) to 1 for maximum supportability&lt;br /&gt;heartbeat[4272]: info: Version 2 support: false&lt;br /&gt;heartbeat[4272]: WARN: logd is enabled but logfile/debugfile/logfacility is still configured in ha.cf&lt;br /&gt;heartbeat[4272]: info: **************************&lt;br /&gt;heartbeat[4272]: info: Configuration validated. Starting heartbeat 2.1.3&lt;br /&gt;heartbeat[4273]: info: heartbeat: version 2.1.3&lt;br /&gt;heartbeat[4273]: info: Heartbeat generation: 1225899638&lt;br /&gt;heartbeat[4273]: info: glib: UDP Broadcast heartbeat started on port 694 (694) interface eth0&lt;br /&gt;heartbeat[4273]: info: glib: UDP Broadcast heartbeat closed on port 694 interface eth0 - Status: 1&lt;br /&gt;heartbeat[4273]: info: glib: ping heartbeat started.&lt;br /&gt;heartbeat[4273]: info: G_main_add_TriggerHandler: Added signal manual handler&lt;br /&gt;heartbeat[4273]: info: G_main_add_TriggerHandler: Added signal manual handler&lt;br /&gt;heartbeat[4273]: info: G_main_add_SignalHandler: Added signal handler for signal 17&lt;br /&gt;heartbeat[4273]: info: Local status now set to: 'up'&lt;br /&gt;heartbeat[4273]: info: Link 192.168.0.1:192.168.0.1 up.&lt;br /&gt;heartbeat[4273]: info: Status update for node 192.168.0.1: status ping&lt;br /&gt;heartbeat[4273]: info: Link pgsql1:eth0 up.&lt;br /&gt;heartbeat[4273]: info: Link pgsql2:eth0 up.&lt;br /&gt;heartbeat[4273]: info: Status update for node pgsql2: status up&lt;br /&gt;harc[4283][4289]: info: Running /etc/ha.d/rc.d/status status&lt;br /&gt;heartbeat[4273]: info: Comm_now_up(): updating status to active&lt;br /&gt;heartbeat[4273]: info: Local status now set to: 'active'&lt;br /&gt;heartbeat[4273]: info: Starting child client "/usr/lib/heartbeat/ipfail" (107,111)&lt;br /&gt;heartbeat[4273]: info: Starting "/usr/lib/heartbeat/ipfail" as uid 107  gid 111 (pid 4294)&lt;br /&gt;heartbeat[4273]: info: Status update for node pgsql2: status active&lt;br /&gt;harc[4298][4303]: info: Running /etc/ha.d/rc.d/status status&lt;br /&gt;ipfail[4294]: info: Status update: Node pgsql2 now has status active&lt;br /&gt;ipfail[4294]: info: Asking other side for ping node count.&lt;br /&gt;heartbeat[4273]: info: remote resource transition completed.&lt;br /&gt;heartbeat[4273]: info: remote resource transition completed.&lt;br /&gt;heartbeat[4273]: info: Initial resource acquisition complete (T_RESOURCES(us))&lt;br /&gt;IPaddr[4346][4374]: INFO:  Resource is stopped&lt;br /&gt;heartbeat[4311]: info: Local Resource acquisition completed.&lt;br /&gt;harc[4378][4383]: info: Running /etc/ha.d/rc.d/ip-request-resp ip-request-resp&lt;br /&gt;ip-request-resp[4378][4388]: received ip-request-resp 192.168.0.2 OK yes&lt;br /&gt;ResourceManager[4389][4399]: info: Acquiring resource group: pgsql1 192.168.0.2 pgpool2&lt;br /&gt;IPaddr[4411][4439]: INFO:  Resource is stopped&lt;br /&gt;ResourceManager[4389][4455]: info: Running /etc/ha.d/resource.d/IPaddr 192.168.0.2 start&lt;br /&gt;IPaddr[4472][4502]: INFO: Using calculated nic for 192.168.0.2: eth0&lt;br /&gt;IPaddr[4472][4507]: INFO: Using calculated netmask for 192.168.0.2: 255.255.255.0&lt;br /&gt;IPaddr[4472][4529]: INFO: eval ifconfig eth0:0 192.168.0.2 netmask 255.255.255.0 broadcast 192.168.0.255&lt;br /&gt;IPaddr[4457][4548]: INFO:  Success&lt;br /&gt;ResourceManager[4389][4574]: info: Running /etc/ha.d/resource.d/pgpool2  start&lt;br /&gt;ipfail[4294]: info: No giveup timer to abort.&lt;br /&gt;&lt;br /&gt;En el nodo pgsql2 veremos información similar a la que sigue en el fichero de log:&lt;br /&gt;&lt;br /&gt;logd[3793]: info: logd started with /etc/logd.cf.&lt;br /&gt;logd[3793]: WARN: Core dumps could be lost if multiple dumps occur.&lt;br /&gt;logd[3793]: WARN: Consider setting non-default value in /proc/sys/kernel/core_pattern (or equivalent) for maximum supportability&lt;br /&gt;logd[3793]: WARN: Consider setting /proc/sys/kernel/core_uses_pid (or equivalent) to 1 for maximum supportability&lt;br /&gt;logd[3794]: info: G_main_add_SignalHandler: Added signal handler for signal 15&lt;br /&gt;logd[3793]: info: G_main_add_SignalHandler: Added signal handler for signal 15&lt;br /&gt;heartbeat[3868]: info: Enabling logging daemon&lt;br /&gt;heartbeat[3868]: info: logfile and debug file are those specified in logd config file (default /etc/logd.cf)&lt;br /&gt;heartbeat[3868]: WARN: Core dumps could be lost if multiple dumps occur.&lt;br /&gt;heartbeat[3868]: WARN: Consider setting non-default value in /proc/sys/kernel/core_pattern (or equivalent) for maximum supportability&lt;br /&gt;heartbeat[3868]: WARN: Consider setting /proc/sys/kernel/core_uses_pid (or equivalent) to 1 for maximum supportability&lt;br /&gt;heartbeat[3868]: info: Version 2 support: false&lt;br /&gt;heartbeat[3868]: WARN: logd is enabled but logfile/debugfile/logfacility is still configured in ha.cf&lt;br /&gt;heartbeat[3868]: info: **************************&lt;br /&gt;heartbeat[3868]: info: Configuration validated. Starting heartbeat 2.1.3&lt;br /&gt;heartbeat[3869]: info: heartbeat: version 2.1.3&lt;br /&gt;heartbeat[3869]: info: Heartbeat generation: 1225899699&lt;br /&gt;heartbeat[3869]: info: glib: UDP Broadcast heartbeat started on port 694 (694) interface eth0&lt;br /&gt;heartbeat[3869]: info: glib: UDP Broadcast heartbeat closed on port 694 interface eth0 - Status: 1&lt;br /&gt;heartbeat[3869]: info: glib: ping heartbeat started.&lt;br /&gt;heartbeat[3869]: info: G_main_add_TriggerHandler: Added signal manual handler&lt;br /&gt;heartbeat[3869]: info: G_main_add_TriggerHandler: Added signal manual handler&lt;br /&gt;heartbeat[3869]: info: G_main_add_SignalHandler: Added signal handler for signal 17&lt;br /&gt;heartbeat[3869]: info: Local status now set to: 'up'&lt;br /&gt;heartbeat[3869]: info: Link 192.168.0.1:192.168.0.1 up.&lt;br /&gt;heartbeat[3869]: info: Status update for node 192.168.0.1: status ping&lt;br /&gt;heartbeat[3869]: info: Link pgsql2:eth0 up.&lt;br /&gt;heartbeat[3869]: info: Link pgsql1:eth0 up.&lt;br /&gt;heartbeat[3869]: info: Status update for node pgsql1: status up&lt;br /&gt;heartbeat[3869]: info: Status update for node pgsql1: status active&lt;br /&gt;heartbeat[3869]: info: Comm_now_up(): updating status to active&lt;br /&gt;heartbeat[3869]: info: Local status now set to: 'active'&lt;br /&gt;heartbeat[3869]: info: Starting child client "/usr/lib/heartbeat/ipfail" (107,111)&lt;br /&gt;heartbeat[3881]: info: Starting "/usr/lib/heartbeat/ipfail" as uid 107  gid 111 (pid 3881)&lt;br /&gt;harc[3880][3889]: info: Running /etc/ha.d/rc.d/status status&lt;br /&gt;harc[3894][3899]: info: Running /etc/ha.d/rc.d/status status&lt;br /&gt;heartbeat[3869]: info: local resource transition completed.&lt;br /&gt;heartbeat[3869]: info: Initial resource acquisition complete (T_RESOURCES(us))&lt;br /&gt;heartbeat[3904]: info: No local resources [/usr/share/heartbeat/ResourceManager listkeys pgsql2] to acquire.&lt;br /&gt;heartbeat[3869]: info: remote resource transition completed.&lt;br /&gt;ipfail[3881]: info: Ping node count is balanced.&lt;br /&gt;&lt;br /&gt;Podemos observar como Heartbeat se ha encargado de asociar la dirección IP 192.168.0.2 al primer alias disponible de la interfaz eth0, es decir, eth0:0. También podremos observar como pgpool-II está levantado y es capaz de servir conexiones.&lt;br /&gt;&lt;br /&gt;En el syslog podremos observar que ha establecido la conexión con ambos servidores de PostgreSQL y está esperando peticiones:&lt;br /&gt;&lt;br /&gt;$ tail -n 500 /var/log/syslog | grep pgpool | ccze -A&lt;br /&gt;pgsql1 pgpool: LOG: pid 4594: pgpool successfully started&lt;br /&gt;&lt;br /&gt;Simulación de la caída del servicio&lt;br /&gt;&lt;br /&gt;A continuación vamos a simular la caída del nodo maestro, pgsql1. Si estamos trabajando con dos máquinas, esto es tan sencillo como desconectar dicho nodo de la red. En el caso de este artículo, se usó Xen Hypervisor para crear las dos máquinas virtuales dentro de la misma máquina física, por lo que se ejecutó el siguiente comando (las máquinas virtuales se habían creado con las xen-tools de Steve Kemp):&lt;br /&gt;&lt;br /&gt;xm destroy pgsql1&lt;br /&gt;&lt;br /&gt;Al cabo de un máximo de 30 segundos, deberíamos ver información parecida a la siguiente en el fichero de log de Heartbeat del nodo pgsql2:&lt;br /&gt;&lt;br /&gt;heartbeat[3869] WARN: node pgsql1: is dead&lt;br /&gt;ipfail[3881] 2008/11/05_17:08:10 info: Status update: Node pgsql1 now has status dead&lt;br /&gt;heartbeat[3869] WARN: No STONITH device configured.&lt;br /&gt;heartbeat[3869] WARN: Shared disks are not protected.&lt;br /&gt;heartbeat[3869] info: Resources being acquired from pgsql1.&lt;br /&gt;heartbeat[3869] info: Link pgsql1:eth0 dead.&lt;br /&gt;harc[3942][3954] info: Running /etc/ha.d/rc.d/status status&lt;br /&gt;heartbeat[3943] info: No local resources [/usr/share/heartbeat/ResourceManager listkeys pgsql2] to acquire.&lt;br /&gt;mach_down[3964][3984] info: Taking over resource group 192.168.0.2&lt;br /&gt;ResourceManager[3985][3995] info: Acquiring resource group: pgsql1 192.168.0.2 pgpool2&lt;br /&gt;IPaddr[4007][4035] INFO:  Resource is stopped&lt;br /&gt;ResourceManager[3985][4051] info: Running /etc/ha.d/resource.d/IPaddr 192.168.0.2 start&lt;br /&gt;IPaddr[4068][4098] INFO: Using calculated nic for 192.168.0.2: eth0&lt;br /&gt;IPaddr[4068][4103] INFO: Using calculated netmask for 192.168.0.2: 255.255.255.0&lt;br /&gt;IPaddr[4068][4125] INFO: eval ifconfig eth0:0 192.168.0.2 netmask 255.255.255.0 broadcast 192.168.0.255&lt;br /&gt;IPaddr[4053][4144] INFO:  Success&lt;br /&gt;ResourceManager[3985][4172] info: Running /etc/ha.d/resource.d/pgpool2  start&lt;br /&gt;mach_down[3964][4199] info: /usr/share/heartbeat/mach_down: nice_failback: foreign resources acquired&lt;br /&gt;mach_down[3964][4203] info: mach_down takeover complete for node pgsql1.&lt;br /&gt;heartbeat[3869] info: mach_down takeover complete.&lt;br /&gt;ipfail[3881] info: NS: We are still alive!&lt;br /&gt;ipfail[3881] info: Link Status update: Link pgsql1/eth0 now has status dead&lt;br /&gt;ipfail[3881] info: Asking other side for ping node count.&lt;br /&gt;ipfail[3881] info: Checking remote count of ping nodes.&lt;br /&gt;&lt;br /&gt;Vemos como ahora el nodo pgsql2 tiene la dirección IP 192.168.0.2 (podemos verificarlo con el comando ifconfig) y como pgpool-II está arrancado (podemos verificarlo con el comando ps xua |grep ^postgres). Asimismo, podemos observar como pgpool-II ha realizado un health check nada más iniciarse y, al ver que el servidor de PostgreSQL del nodo 192.168.0.3 no estaba disponible, ha realizado la pertinente degeneración de ese nodo (que, recordemos, a efectos del nuevo pgpool-II, es un nodo secundario):&lt;br /&gt;&lt;br /&gt;$ tail -n 500 /var/log/syslog | grep pgpool | ccze -A&lt;br /&gt;pgsql2 pgpool: LOG:   pid 4195: pgpool successfully started&lt;br /&gt;pgsql2 pgpool: ERROR: pid 4195: connect_inet_domain_socket: connect() failed: No route to host&lt;br /&gt;pgsql2 pgpool: ERROR: pid 4195: health check failed. 1 th host 192.168.0.3 at port 5432 is down&lt;br /&gt;pgsql2 pgpool: LOG:   pid 4195: set 1 th backend down status&lt;br /&gt;pgsql2 pgpool: LOG:   pid 4195: starting degeneration. shutdown host 192.168.0.3(5432)&lt;br /&gt;pgsql2 pgpool: LOG:   pid 4195: failover_handler: do not restart pgpool. same master node 0 was selected&lt;br /&gt;pgsql2 pgpool: LOG:   pid 4195: failover done. shutdown host 192.168.0.3(5432)&lt;br /&gt;pgsql2 pgpool: LOG:   pid 4195: execute command: /var/lib/postgresql/8.3/main/pgpool-failover 1 192.168.0.3 5432 /var/lib/postgresql/8.3/main 0 0&lt;br /&gt;pgsql2 pgpool[4243]: Executing pgpool-failover as user postgres&lt;br /&gt;pgsql2 pgpool: /var/lib/postgresql/8.3/main/pgpool-failover: 15: Failover of node 1 at hostname 192.168.0.3. New master node is 0. Old master node was 0.: not found&lt;br /&gt;&lt;br /&gt;Nótese que, a raíz de la instalación de Heartbeat, pgpool-II está ahora escuchando en la IP 192.168.0.2, por lo cual hay que mandar al puerto 9898 de esa IP los comandos de PCP. La ventaja es que siempre lanzaremos nuestros comandos PCP contra esa dirección IP, pues Heartbeat se encargará de llevarla de un nodo a otro según sea necesario. Además, las peticiones de pgpool-II a PostgreSQL vienen ahora desde esa dirección IP, por lo que es conveniente revisar que nuestros ficheros /etc/postgresql/8.3/main/pg_hba.conf permiten las conexiones desde ambas con el usuario pgpool2.&lt;br /&gt;&lt;br /&gt;Por otra parte, los comandos que nuestros clientes quieran mandar contra el clúster usarán, a partir de ahora, la dirección IP 192.168.0.2 y el puerto 9999. Al igual que antes, dado que Heartbeat se encargará de mover esta dirección IP y el servicio pgpool2 de nodo a nodo, nuestros clientes siempre funcionarán de la misma manera. Este es uno de los propósitos principales de la alta disponibilidad que acabamos de configurar (además de la alta disponibilidad de la que gozamos, por supuesto).&lt;br /&gt;&lt;br /&gt;Podemos probar nuestro clúster con un simple comando como el que sigue:&lt;br /&gt;&lt;br /&gt;psql -h 192.168.0.2 -p 9999 -U pgpool2 -d bench_replication -c "UPDATE ACCOUNTS SET abalance = 1009 WHERE aid = 10"&lt;br /&gt;&lt;br /&gt;Herramientas de monitorización&lt;br /&gt;&lt;br /&gt;En Internet pueden encontrarse un gran número de herramientas de gestión y monitorización de PostgreSQL, tanto de código abierto como propietarias. A continuación se presenta una lista de algunas de ellas que, personalmente, me resultan de gran utilidad.&lt;br /&gt;&lt;br /&gt;pg_osmem y pg_buffercache&lt;br /&gt;&lt;br /&gt;pg_osmem es un script hecho en Python por Kenny Gorman que permite obtener información sobre la memoria caché que un sistema Linux está dedicando al servidor PostgreSQL. Utiliza un script en Perl llamado fincore (pronunciado en inglés eff in core), creado por David Plonka, Archit Gupta y Dale Carder de la universidad de Wisconsin-Madison y que fue presentado en la LISA '07.&lt;br /&gt;&lt;br /&gt;Su instalación y uso son muy sencillos:&lt;br /&gt;&lt;br /&gt;   * Crear el directorio /root/bin y cambiarse a él.&lt;br /&gt;   * Descargar fincore desde http://net.doit.wisc.edu/~plonka/fincore/fincore&lt;br /&gt;   * Crear el fichero /root/pg_osmem/pg_osmem a partir del script que hay en la página web de Kenny Gorman.&lt;br /&gt;   * Crear el directorio /root/pg_osmem/data.&lt;br /&gt;   * Instalar la dependencia psycopg2 (paquete python-psycopg2 en Debian).&lt;br /&gt;   * Instalar la dependiencia inline (paquete libinline-perl en Debian).&lt;br /&gt;   * Modificar el script /root/pg_osmem/pg_osmem para adecuarlo a nuestro sistema:&lt;br /&gt;         o Cambiar /home/postgres/python/bin/python por /usr/bin/python.&lt;br /&gt;         o Cambiar la variable fincore por /root/bin/fincore.&lt;br /&gt;         o Cambiar la variable mydir por /var/lib/postgresql/8.3/main/base.&lt;br /&gt;   * Ejecutar con la siguiente sentencia (suponemos que /root/bin está en el PATH del usuario root): pg_osmem --username=pgpool2 --password='' --machine=pgsql1 --dbname=bench_replication&lt;br /&gt;&lt;br /&gt;El fichero de configuración /etc/postgresql/8.3/main/pg_hba.conf deberá estar configurado adecuadamente.&lt;br /&gt;&lt;br /&gt;pg_buffercache es un módulo de PostgreSQL, habitualmente hallado en el paquete postgresql-contrib-8.3, que proporciona maneras de examinar lo que está ocurriendo en la cache de memoria compartida de PostgreSQL en tiempo real (no a nivel de sistema operativo, pues para eso necesitamos pg_osmem). Su instalación es muy sencilla:&lt;br /&gt;&lt;br /&gt;$ psql -d bench_replication &lt; /usr/share/postgresql/8.3/contrib/pg_buffercache.sql SET CREATE FUNCTION CREATE VIEW REVOKE REVOKE  Entonces, mediante el script pg_osmem podemos obtener una salida similar a la siguiente:  $ pg_osmem --username=pgpool2 --password='' --machine=pgsql1 --dbname=bench_replication OS Cache Usage: bench_replication:accounts_pkey:566272 bench_replication:pg_proc:102400 bench_replication:pg_proc_proname_args_nsp_index:79872 bench_replication:pg_depend:79872 bench_replication:pg_depend_reference_index:65536 [..]  Luego, gracias al módulo pg_buffercache, podemos lanzar la siguiente consulta SQL:  psql -d bench_replication # SELECT current_database(),c.relname, count(*)*8192 as bytes     FROM pg_buffercache b INNER JOIN pg_class c       ON b.relfilenode = c.relfilenode      AND b.reldatabase IN (0, (          SELECT oid FROM pg_database           WHERE datname = current_database())) GROUP BY c.relname ORDER BY 3 DESC LIMIT 25;  current_database  |    relname    |  bytes -------------------+---------------+----------  bench_replication | accounts      | 13434880  bench_replication | accounts_pkey |   262144  bench_replication | pg_attribute  |   155648  bench_replication | pg_statistic  |   122880  bench_replication | pg_operator   |   106496 [..] (25 rows)  Gracias a estos dos códigos, podemos ver el conjunto de buffers más utilizado en la caché del sistema operativo y compararlo con la caché de PostgreSQL. La salida de ambos comandos es en bytes.  pg_top  pg_top es un top para PostgreSQL, derivado del top de UNIX. Similar a top, pg_top permite monitorizar los procesos de PostgreSQL y, además, ofrece estas otras funcionalidades:      * Ver las consultas SQL que está ejecutando un proceso.     * Ver el query plan de una consulta SQL que se está ejecutando.     * Ver los bloqueos realizados por un proceso.     * Ver la estadística de las tablas.     * Ver la estadística de los índices.  Los fuentes de pg_top pueden descargarse de su página web en PgFoundry. También podemos bajarnos la última versión de desarrollo del repositorio Git de pgFoundry mediante el siguiente comando:  cd /usr/local/src git clone git://git.postgresql.org/git/pg_top.git cd pg_top ./autogen.sh  Podemos instalar Git mediante el siguiente comando:  apt-get install git-cvs  Instalaremos las dependencias de compilación con el siguiente comando:  apt-get install libncurses5-dev  Los paquetes build-essential, linux-headers-server, libpq-dev, libpq5 y postgresql-server-dev-8.3 ya los habíamos instalado durante la instalación de pgpool-II y de PostgreSQL.  pg_top se instala por defecto en /usr/local/bin, pero podemos cambiar la ruta mediante el parámetro --prefix del script configure:  cd /usr/local/src wget http://pgfoundry.org/frs/download.php/1780/pg_top-3.6.2.tar.bz2 tar -xjf pg_top-3.6.2.tar.bz2 cd pg_top-3.6.2 ./configure --prefix=/opt/pg_top make make install  El uso de pg_top es análogo al de top. Tan sólo hay que invocar el ejecutable y usar las teclas para obtener diferentes vistas e información de los procesos deseados. El ejecutable requiere tres parámetros:      * La base de datos (parámetro -d).     * El usuario (parámetro -U).     * La contraseña, si es necesaria (parámetro -W).  Entonces, la ejecución de pg_top sería tal y como sigue:  /opt/pg_top/bin/pg_top -U pgpool2 -d bench_replication  pg_top asume localhost como hostname y 5432 como puerto por defecto. Usa el usuario de sistema como medio de autenticación por defecto, por lo cual deberemos pasarle datos de usuario y contraseña o ejecutarlo como usuario postgres, dependiendo de la configuración que tengamos en /etc/postgresql/8.3/main/pg_hba.conf.  Podemos crearnos un script /opt/pg_top/pg_top donde hacer la llamada completa con todos los datos y hacernos el trabajo más sencillo, por ejemplo:  #!/bin/bash /usr/bin/sudo /bin/su - postgres -c '/opt/pg_top/bin/pg_top'  Y luego añadir la ruta al PATH del sistema en /etc/profile.  ps  ps, o process status, la famosa utilidad presente en todos los UNIX, es una útil herramienta para tener una primera impresión de qué está haciendo PostgreSQL. Un sencillo comando tal que el que sigue será suficiente:  $ ps auxww | grep ^postgres postgres   960  0.0  1.1  6104 1480 pts/1    SN   13:17   0:00 postgres -i postgres   963  0.0  1.1  7084 1472 pts/1    SN   13:17   0:00 postgres: writer process postgres   965  0.0  1.1  6152 1512 pts/1    SN   13:17   0:00 postgres: stats collector process    postgres   998  0.0  2.3  6532 2992 pts/1    SN   13:18   0:00 postgres: tgl runbug 127.0.0.1 idle postgres  1003  0.0  2.4  6532 3128 pts/1    SN   13:19   0:00 postgres: tgl regression [local] SELECT waiting postgres  1016  0.1  2.4  6532 3080 pts/1    SN   13:19   0:00 postgres: tgl regression [local] idle in transaction		  pgd  pgstat, otra utilidad desarrollada por Kenny Gorman, es muy similar a iostat pero orientada a bases de datos. Es una utilidad muy útil para realizar diagnósticos rápidos, tests de rendimiento, etc. La salida es adecuada para ser importada en hojas de cálculo o en programas que puedan generar gráficas.  En la página web de Kenny Gorman se explica cómo obtener gráficas de la salida de pgd usando gnuplot. Ver la bibliografía para el enlace.  La instalación de pgd es muy sencilla:      * Descargar pgstat desde pgFoundry.     * Descomprimirlo en /root/bin o donde consideremos oportuno.     * Editar el fichero y cambiar los valores por defecto de los parámetros en la línea 16. De esta forma podremos llegar a no tener que especificar ningún parámetro o, como máximo, la base de datos.  La utilidad la llamaremos con un sencillo pgstat -d bench_replication.  iotop  Iotop es un script de Python con una interfaz de usuario similar a la de top que sirve para mostrar qué proceso está originando qué carga de lecturas y escrituras de disco (E/S). Requiere Python 2.5 o superior y un kernel de Linux versión 2.6.20 o superior. Este script muestra la misma información que el comando vmstat, pero asociando la carga al proceso que la genera y mostrando la información de una forma mucho más útil para el administrador de sistemas.  Su instalación es muy sencilla pues, a partir de Lenny, viene como paquete Debian:  apt-get install iotop python-pkg-resources  Optimización de PostgreSQL  Para un sistema inicial de pruebas, tanto pgsql1 como pgsql2 tienen 1 GB de memoria RAM. Teniendo en cuenta esta situación, se configurarán los siguientes parámetros en el fichero de configuración de PostgreSQL /etc/postgresql/8.3/main/postgresql.conf:  max_connections = 100 shared_buffers = 256MB work_mem = 2MB effective_cache_size = 512MB  Work Memory es por conexión, por lo que hay que calcular un máximo de 2 * 100 = 200 MB para el total de conexiones. Effective Cache Size debería ser entre el 50 y el 75% de la memoria RAM física, dependiendo de si hay otros servicios ejecutándose en la máquina o no.  Respecto del kernel, para poder reservar 512 MB de shared buffers necesitaremos un tamaño máximo de un segmento compartido igual al valor que nos devuelva el error de PostgreSQL al arrancar, 279.134.208 bytes, unos 266 MB.  La variable SHMMAX del kernel indica el tamaño máximo de los segmentos de memoria compartida, y debe ser de, al menos, varios megabytes. La variable de kernel SHMALL indica el número total de páginas de memoria compartida disponibles. SHMALL es igual a SHMMAX dividido por PAGE_SIZE, redondeado hacia arriba. PAGE_SIZE es, por defecto, de 4 kilobytes.  Ejecutaremos los siguientes comandos en la consola para alterar los valores:  sysctl -w kernel.shmmax=279134208 sysctl -w kernel.shmall=2097152  El primero son bytes, el segundo páginas. Para asegurarnos que los valores permanezcan tras un reinicio, añadiremos las siguientes dos líneas al fichero /etc/sysctl.conf:  kernel.shmmax=556212224 kernel.shmall=2097152  El valor actual de estos parámetros se puede obtener con:  cat /proc/sys/kernel/shmmax cat /proc/sys/kernel/shmall   El valor por defecto de SHMMAX suele ser 33.554.432 bytes. El valor por defecto del número de páginas que un segmento compartido puede tener ya es mayor que lo que necesitamos (553.607.168 / 4096 = 135.158 &lt; procpid =" &lt;pid"&gt;&lt;br /&gt;&lt;br /&gt;Una vez hayamos confirmado que, efectivamente, el proceso se encuentra en un estado errante y no ejecutando una consulta realmente larga de la cual los directivos de nuestra empresa obtienen sus informes, podemos matarlo de forma segura mediante la siguiente consulta:&lt;br /&gt;&lt;br /&gt;SELECT pg_cancel_backend(&lt;pid&gt;)&lt;br /&gt;&lt;br /&gt;FAQ (Frequently Asked Question)&lt;br /&gt;&lt;br /&gt;   * Para que el daemon de autovacuum pueda realizar correctamente su trabajo necesitará un número suficiente de páginas. Una buena regla es configurar fsm_pages en postgresql.conf con un valor de 65536 por GB que ocupe la base de datos más grande que tengamos.&lt;br /&gt;   * Cómo obtener el tamaño de las bases de datos en PostgreSQL?&lt;br /&gt;&lt;br /&gt;     SELECT datname,pg_size_pretty(pg_database_size(oid)) FROM pg_database ORDER BY pg_database_size(oid) DESC;&lt;br /&gt;   * ¿Cómo obtener el tamaño de las tablas y los índices?&lt;br /&gt;&lt;br /&gt;     SELECT relname,pg_size_pretty(pg_relation_size(oid)) FROM pg_class WHERE relname NOT LIKE 'pg_%' ORDER BY pg_relation_size(oid) DESC;&lt;br /&gt;   * ¿Cómo obtener el tamaño sólo de las tablas?&lt;br /&gt;&lt;br /&gt;     SELECT pg_tables.tablename, pg_tables.schemaname, pg_size_pretty(pg_relation_size((pg_tables.schemaname::text || '.'::text) || pg_tables.tablename::text)) AS pg_size_pretty, pg_relation_size((pg_tables.schemaname::text || '.'::text) || pg_tables.tablename::text) AS rs FROM pg_tables ORDER BY pg_relation_size((pg_tables.schemaname::text || '.'::text) || pg_tables.tablename::text) DESC;&lt;br /&gt;   * ¿Y de los índices solamente?&lt;br /&gt;&lt;br /&gt;     SELECT pg_indexes.indexname, pg_size_pretty(pg_relation_size((pg_indexes.schemaname::text || '.'::text) || pg_indexes.indexname::text)) AS pg_size_pretty, pg_relation_size((pg_indexes.schemaname::text || '.'::text) || pg_indexes.indexname::text) AS rs FROM pg_indexes ORDER BY pg_relation_size((pg_indexes.schemaname::text || '.'::text) || pg_indexes.indexname::text) DESC;&lt;br /&gt;&lt;br /&gt;Fuente :http://www.postgresql-es.org/principal&lt;br /&gt;&lt;/pid&gt;&lt;/pid&gt;&lt;/password&gt;&lt;/password&gt;&lt;/núm_nodo&gt;&lt;/password&gt;&lt;/núm_nodo&gt;&lt;/password&gt;&lt;/password&gt;&lt;/núm_nodo&gt;&lt;/password&gt;&lt;/username&gt;&lt;/puerto&gt;&lt;/hostname&gt;&lt;/timeout&gt;&lt;/comando_pcp&gt;&lt;/password&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5950429174584838030-5254987696043404888?l=caerices.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://caerices.blogspot.com/feeds/5254987696043404888/comments/default' title='Enviar comentarios'/><link rel='replies' type='text/html' href='http://caerices.blogspot.com/2009/08/replicacion-y-alta-disponibilidad-en.html#comment-form' title='0 comentarios'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5950429174584838030/posts/default/5254987696043404888'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5950429174584838030/posts/default/5254987696043404888'/><link rel='alternate' type='text/html' href='http://caerices.blogspot.com/2009/08/replicacion-y-alta-disponibilidad-en.html' title='Replicacion y Alta Disponibilidad en Postgres'/><author><name>caerices</name><uri>http://www.blogger.com/profile/17494035119607034630</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='24' height='32' src='http://3.bp.blogspot.com/_w44tDpxaU14/SjfWwlmjQ_I/AAAAAAAAAAY/GCvAuqbqu0o/S220/Cesar.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-5950429174584838030.post-4263240994943598335</id><published>2009-07-29T15:00:00.002-04:00</published><updated>2009-07-29T15:03:41.452-04:00</updated><title type='text'>Instalar WebAdmin Centos 5</title><content type='html'>WebAdmin es un Panel de Control Libre que permite administrar los servidores Linux de manera Grafica y sencilla. Buscando información al respecto e encontre con una pagina que entregaba la informaciónn necesaria para instalara dicha herramienta.&lt;br /&gt;&lt;br /&gt;Esto es posible de la siguiente forma:&lt;br /&gt;&lt;br /&gt;    yum -y install perl-Net-SSLeay&lt;br /&gt;&lt;br /&gt;    wget http://superb-east.dl.sourceforge.net/sourceforge/webadmin/webmin-1.430-1.noarch.rpm&lt;br /&gt;&lt;br /&gt;    rpm -i webmin-1.430-1.noarch.rpm&lt;br /&gt;&lt;br /&gt;Ya tiene acceso a tu Servidor, solo debes digitar:&lt;br /&gt;&lt;br /&gt;    https://(your.ip):10000/&lt;br /&gt;&lt;br /&gt;Es todo, Facil NO&lt;br /&gt;&lt;br /&gt;Fuente: http://www.crucialp.com/blog/2008/09/11/how-to-install-webmin-on-centos-45-the-easy-way/&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5950429174584838030-4263240994943598335?l=caerices.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://caerices.blogspot.com/feeds/4263240994943598335/comments/default' title='Enviar comentarios'/><link rel='replies' type='text/html' href='http://caerices.blogspot.com/2009/07/instalar-webadmin-centos-5.html#comment-form' title='0 comentarios'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5950429174584838030/posts/default/4263240994943598335'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5950429174584838030/posts/default/4263240994943598335'/><link rel='alternate' type='text/html' href='http://caerices.blogspot.com/2009/07/instalar-webadmin-centos-5.html' title='Instalar WebAdmin Centos 5'/><author><name>caerices</name><uri>http://www.blogger.com/profile/17494035119607034630</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='24' height='32' src='http://3.bp.blogspot.com/_w44tDpxaU14/SjfWwlmjQ_I/AAAAAAAAAAY/GCvAuqbqu0o/S220/Cesar.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-5950429174584838030.post-1641864792635416715</id><published>2009-07-01T15:14:00.000-04:00</published><updated>2009-07-01T15:17:12.710-04:00</updated><title type='text'>Liberación Postgresql 8.4</title><content type='html'>&lt;div style="text-align: justify;"&gt;1 de julio, 2009: El Grupo Global de Desarrollo de PostgreSQL ha&lt;br /&gt;liberado la versión 8.4, continuando con el rápido desarrollo de la&lt;br /&gt;base de datos de código abierto más avanzada del mundo.  Esta versión&lt;br /&gt;contiene una gran cantidad de mejoras para hacer la administración,&lt;br /&gt;consulta y programación en PostgreSQL mucho más fácil que nunca.  Con&lt;br /&gt;las 293 funcionalidades nuevas o mejoradas en la versión 8.4, hay aún&lt;br /&gt;más motivos para escoger PostgreSQL para sus futuros proyectos.&lt;br /&gt;&lt;br /&gt;La mayoría de los cambios en PostgreSQL 8.4 son herramientas y órdenes&lt;br /&gt;de administración y monitoreo, nuevas o mejoradas.  Cada usuario tiene&lt;br /&gt;su funcionalidad favorita que hace su trabajo cotidiano con PostgreSQL&lt;br /&gt;más fácil y productivo.&lt;br /&gt;&lt;br /&gt;“Hemos usado PostgreSQL durante siete años, y estamos entusiasmados&lt;br /&gt;con varias funcionalidades de 8.4, especialmente los privilegios por&lt;br /&gt;columna, configuración regional en cada base de datos, búsquedas&lt;br /&gt;parciales en índices GIN y excepciones definidas por usuario”, dice&lt;br /&gt;Jeffrey Webster, CTO de ZooLoo.com. “PostgreSQL nos ha permitido&lt;br /&gt;crecer sin sacrificar la integridad de nuestros datos”.&lt;br /&gt;&lt;br /&gt;Entre las mejoras más populares están:&lt;br /&gt;&lt;br /&gt;* Restauración de bases de datos en procesos paralelos, que acelera&lt;br /&gt;recuperación de un respaldo hasta 8 veces.&lt;br /&gt;* Privilegios por columna, que permiten un control más granular de&lt;br /&gt;datos confidenciales.&lt;br /&gt;* Configuración de ordenamiento configurable por base de datos, lo&lt;br /&gt;cual hace a PostgreSQL más útil en entornos con múltiples idiomas.&lt;br /&gt;* Actualizaciones “en el lugar” desde 8.3 a 8.4 con muy bajo&lt;br /&gt;downtime, gracias al uso de pg_migrator beta.&lt;br /&gt;* Nuevas herramientas de monitoreo de consultas que le otorgan a los&lt;br /&gt;administradores mayor información sobre la actividad del sistema.&lt;br /&gt;&lt;br /&gt;La versión 8.4 hace el análisis de datos mucho más sencillo a través&lt;br /&gt;de funcionalidades avanzadas de ANSI SQL:2003, como las funciones&lt;br /&gt;window, expresiones comunes de tabla y joins recursivos.  “Estas&lt;br /&gt;estructuras de consulta aumentan sustancialmente la expresividad del&lt;br /&gt;dialecto SQL de PostgreSQL, permitiendo a los usuarios hacer preguntas&lt;br /&gt;interesantes en una sola consulta, que habría sido imposible de&lt;br /&gt;construir antes”, explica Sailesh Krishnamurthy, fundador de Truviso.&lt;br /&gt;Las mejoras en los procedimientos almacenados, como los valores por&lt;br /&gt;omisión para los argumentos y los argumentos de largo variable hacen&lt;br /&gt;más simple y compacta la programación en la base de datos.&lt;br /&gt;&lt;br /&gt;La nueva versión además mejora el rendimiento de las aplicaciones,&lt;br /&gt;como comenta Kevin Grittner, Administrador de base de datos del&lt;br /&gt;Sistema de Cortes de Wisconsin: “PostgreSQL continúa mejorando el&lt;br /&gt;rendimiento en cada versión. La versión 8.4 ha añadido muchas&lt;br /&gt;optimizaciones, como semi-joins y anti-joins, que otorgan una notable&lt;br /&gt;mejora en el tiempo de ejecución de algunas de nuestras consultas más&lt;br /&gt;exigentes”.&lt;br /&gt;&lt;br /&gt;Debido a estas nuevas características PostgreSQL 8.4 podrá atender a&lt;br /&gt;muchos más usuarios que antes, como el proyecto OpenStreetMap.  “A&lt;br /&gt;medida que diseñábamos la nueva versión de la API de OpenStreetMap,&lt;br /&gt;estuvo claro que necesitábamos una base de datos de clase mundial que&lt;br /&gt;no sólo dijera que tenía las funcionalidades deseadas, sino que&lt;br /&gt;realmente corriera bien en la escala que nosotros necesitábamos.&lt;br /&gt;Aunque existen varias bases de datos de código abierto, PostgreSQL era&lt;br /&gt;la elección obvia”, dice Tom Hughes, administrador de sistemas de&lt;br /&gt;OpenStreetMap.&lt;br /&gt;&lt;br /&gt;* Descargue PostgreSQL 8.4: &lt;a href="http://www.postgresql.org/download/" target="_blank"&gt;http://www.postgresql.org/&lt;wbr&gt;download/&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;* Lista completa de características de 8.4 (en inglés):&lt;br /&gt;&lt;a href="http://www.postgresql.org/about/press/features84" target="_blank"&gt;http://www.postgresql.org/&lt;wbr&gt;about/press/features84&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;* Notas de versión (inglés):&lt;br /&gt;&lt;a href="http://www.postgresql.org/docs/8.4/static/release.html" target="_blank"&gt;http://www.postgresql.org/&lt;wbr&gt;docs/8.4/static/release.html&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;* Nota extendida de lanzamiento:&lt;br /&gt;&lt;a href="http://www.postgresql.org/about/press/presskit84.html" target="_blank"&gt;http://www.postgresql.org/&lt;wbr&gt;about/press/presskit84.html&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;Acerca de PostgreSQL: PostgreSQL es el trabajo colectivo de cientos de&lt;br /&gt;desarrolladores, basado en el trabajo de más de veinte años de&lt;br /&gt;desarrollo que comenzaron en la Universidad de Berkeley, California.&lt;br /&gt;Con su soporte de larga data de un conjunto de características de&lt;br /&gt;bases de datos transaccionales de nivel empresarial y su&lt;br /&gt;escalabilidad, PostgreSQL está siendo usado por muchas de las más&lt;br /&gt;exigentes empresas y agencias de gobierno. PostgreSQL se distribuye&lt;br /&gt;bajo licencia BSD, lo cual permite el uso y distribución sin costo,&lt;br /&gt;tanto para aplicaciones comerciales como no comerciales. Para obtener&lt;br /&gt;más información, visite nuestro sitio web, &lt;a href="http://www.postgresql.org/" target="_blank"&gt;http://www.postgresql.org&lt;/a&gt;.&lt;br /&gt;&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5950429174584838030-1641864792635416715?l=caerices.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://caerices.blogspot.com/feeds/1641864792635416715/comments/default' title='Enviar comentarios'/><link rel='replies' type='text/html' href='http://caerices.blogspot.com/2009/07/liberacion-postgresql-84-liberada.html#comment-form' title='0 comentarios'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5950429174584838030/posts/default/1641864792635416715'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5950429174584838030/posts/default/1641864792635416715'/><link rel='alternate' type='text/html' href='http://caerices.blogspot.com/2009/07/liberacion-postgresql-84-liberada.html' title='Liberación Postgresql 8.4'/><author><name>caerices</name><uri>http://www.blogger.com/profile/17494035119607034630</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='24' height='32' src='http://3.bp.blogspot.com/_w44tDpxaU14/SjfWwlmjQ_I/AAAAAAAAAAY/GCvAuqbqu0o/S220/Cesar.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-5950429174584838030.post-8638053864232132586</id><published>2009-07-01T13:24:00.000-04:00</published><updated>2009-07-02T09:22:26.763-04:00</updated><title type='text'>Diferencia Diagrama Proceso - Diagrama Flujo - Diagrama de Datos</title><content type='html'>&lt;br /&gt;Más de una vez me han preguntado cual es la diferencia entre el Diagrama de Proceso y un Diagrama de Datos&lt;br /&gt;Para empezar entregaré una definición de ambos, junto con ello un ejemplo para que pueda quedar más clara dicha diferencia.&lt;br /&gt;&lt;br /&gt;según wikimedia esta seria la definiciónes:&lt;br /&gt;&lt;span style="font-weight: bold; font-style: italic;"&gt;Diagrama de Flujo o Proceso&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;"Un diagrama de flujo es una forma de representar gráficamente los detalles algorítmicos de un proceso multifactorial. Se utiliza principalmente en programación, economía y procesos industriales, pasando también a partir de estas disciplinas a formar parte fundamental de otras, como la psicología cognitiva. Estos diagramas utilizan una serie de símbolos con significados especiales y son la representación gráfica de los pasos de un proceso. En computación, son modelos tecnológicos utilizados para comprender los rudimentos de la programación lineal."&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold; font-style: italic;"&gt;Diagrama de Flujo de Datos&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;“diagrama de flujo de datos (DFD por sus siglas en español e inglés) es una representación gráfica del "flujo" de datos a través de un sistema de información. Un diagrama de flujo de datos también se puede utilizar para la visualización de procesamiento de datos (diseño estructurado). Es una práctica común para un diseñador dibujar un contexto a nivel de DFD que primero muestra la interacción entre el sistema y la entidades externas. Este contexto a nivel de DFD se "explotó" para mostrar más detalles del sistema que se está modelando.”&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;De acuerdo solo a esta definición se puede ver la gran diferencia que existe entre estos dos terminos, el primero es más limitado, pero permite hacer una representación más global del software o Sistema; En cambio el segundo permite obtener un desglose mejor de cada uno de los subprocesos, con las limitancias que eso conlleva.&lt;br /&gt;Nosotros nos centraremos en esta oportunidad, en los Diagramas de Flujos de Datos, haciendo una representacion y definición un poco más entendible para los lectores.&lt;br /&gt;&lt;br /&gt;&lt;div style="text-align: center;"&gt;&lt;span style="font-size:180%;"&gt;&lt;span style="font-weight: bold;"&gt;Definición&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;/div&gt;El diagrama de flujo de datos permite definir el estado, flujo y transformación de un determinado dato, permitiendo con ello representar de una manera más grafica un sistema informatico, el uso de  este tipo de Diagrama es recomendable acompañarlo con un Diccionario de Datos y su Modelo Entidad Relación.   La interfaz grafica del DFD favorece el trabajo con otros diagramas y se debe presentar de la siguiente manera&lt;br /&gt;&lt;br /&gt;&lt;span style="font-style: italic; font-weight: bold;"&gt;Proceso&lt;/span&gt;: Es la primera parte de un diagrama de flujo de datos, esta presenta una parte del sistema que transforman Entrada – Proceso – Salida&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://2.bp.blogspot.com/_w44tDpxaU14/SkyyaxqQ80I/AAAAAAAAABo/nym6t-XxojA/s1600-h/Image26497.gif"&gt;&lt;img style="margin: 0px auto 10px; display: block; text-align: center; cursor: pointer; width: 320px; height: 89px;" src="http://2.bp.blogspot.com/_w44tDpxaU14/SkyyaxqQ80I/AAAAAAAAABo/nym6t-XxojA/s320/Image26497.gif" alt="" id="BLOGGER_PHOTO_ID_5353850230113628994" border="0" /&gt;&lt;/a&gt;&lt;span style="font-weight: bold; font-style: italic;"&gt;Flujo:&lt;/span&gt; Se utiliza para describir el movimiento de la información de una parte del sistema a otra, además se muestra la dirección del movimiento, indicando si esta se estará movimiento hacia adentro o hacia afuera  del proceso.&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://3.bp.blogspot.com/_w44tDpxaU14/SkyyCZhjPhI/AAAAAAAAABg/RBycK_CppZw/s1600-h/Image26498.gif"&gt;&lt;img style="margin: 0px auto 10px; display: block; text-align: center; cursor: pointer; width: 320px; height: 270px;" src="http://3.bp.blogspot.com/_w44tDpxaU14/SkyyCZhjPhI/AAAAAAAAABg/RBycK_CppZw/s320/Image26498.gif" alt="" id="BLOGGER_PHOTO_ID_5353849811317767698" border="0" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;span style="font-weight: bold; font-style: italic;"&gt;Almacén:&lt;/span&gt; Se utiliza para representar la colección de paquete de datos en reposo. Estos se denotan  por dos lineas paralelas. En este punto los pedidos de información son representados como un flujo desde o hacia un almacén.&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold; font-style: italic;"&gt;Terminador:&lt;/span&gt; Estas son entidades externas con las cuales el sistema se comunica, estas pueden ser personas, grupos u organizaciones.&lt;br /&gt;El enfoque de flujo de datos tiene cuatro ventajas principales sobre la explicación narrativa de la forma en que se mueven los datos a traves del sistema.&lt;br /&gt;Las ventajas son:&lt;br /&gt;&lt;ol&gt;&lt;li&gt;Libertad 	para realizar en forma muy temprana la implementación de técnicas 	de sistema.  	 	Una 	mayor comprensión de las interrelaciones de los sistemas 	y subsistemas.  	 	&lt;/li&gt;&lt;li&gt;Comunicación del conocimiento 	del sistema actual a los usuarios por medio de diagramas de flujo de 	datos.  	 	&lt;/li&gt;&lt;li&gt;Análisis de un sistema 	propuesto para determinar si han sido definidas los datos y procesos 	necesarios.  	&lt;/li&gt;&lt;/ol&gt;&lt;br /&gt;Sus Caracteristicas:&lt;ol&gt;&lt;li&gt;Representa 	lo que debe hacer el sistema sin referencias. 	&lt;/li&gt;&lt;li&gt;Son 	faciles y comprensibles 	&lt;/li&gt;&lt;li&gt;Dan 	la posibilidad de representar un sistema en todos sus niveles de 	complejidad, desde lo más detallado. 	Son 	facil de mantener&lt;/li&gt;&lt;/ol&gt;Sus Limitaciones:&lt;br /&gt;&lt;ol&gt;&lt;li&gt;No permite recoger el comportamiento que deban responder a eventos 	(Diagrama de transición)&lt;br /&gt;&lt;/li&gt;&lt;li&gt;No 	permite dar cuenta de la relación de datos (Diagrama Entidad – 	Relación) 	&lt;/li&gt;&lt;li&gt;No 	permite representar situaciones que involucren a un proceso 	(Diagrama de Proceso) &lt;/li&gt;&lt;li&gt;	No 	permite reflejar el contenido de datos (Diccionario de Datos)&lt;/li&gt;&lt;/ol&gt;&lt;br /&gt;&lt;br /&gt;En un proximo capitulo explicaremos la UML&lt;br /&gt;&lt;br /&gt;UML (Unified Modeling Language ) Es una herramienta de modelado (simplificación de la realidad que recoge aquellos aspectos de relevancia para las intenciones del modelador )  de Software&lt;br /&gt;&lt;br /&gt;&lt;ul&gt;&lt;li&gt;&lt;span style="font-weight: bold; font-style: italic;"&gt;Diagrama de Casos de Uso:&lt;/span&gt; representa las actividades o pasos que se van desarrollando desde el inicio al final del proyecto, simpre hay un actor quien es el que inicia, un proceso o desarrollo y luego otro actor (que puede ser el mismo que inicia) que es el que recibe respuesta del sistema&lt;/li&gt;&lt;li&gt;&lt;span style="font-weight: bold; font-style: italic;"&gt;Diagrama de Clases&lt;/span&gt;:&lt;br /&gt;&lt;/li&gt;&lt;li&gt;&lt;span style="font-weight: bold; font-style: italic;"&gt;Diagrama de Objetos:&lt;/span&gt;&lt;br /&gt;&lt;/li&gt;&lt;li&gt;&lt;span style="font-weight: bold; font-style: italic;"&gt;Diagrama de Secuencia:&lt;/span&gt;&lt;br /&gt;&lt;/li&gt;&lt;li&gt;&lt;span style="font-weight: bold; font-style: italic;"&gt;Diagrama de  Colaboración:&lt;/span&gt;&lt;br /&gt;&lt;/li&gt;&lt;li&gt;&lt;span style="font-weight: bold; font-style: italic;"&gt;Diagrama de Estados:&lt;/span&gt; Determina como interactua los usuarios y con otros sistemas&lt;br /&gt;&lt;/li&gt;&lt;li&gt;&lt;span style="font-weight: bold; font-style: italic;"&gt;Diagrama de Actividades:&lt;/span&gt;&lt;br /&gt;&lt;/li&gt;&lt;li&gt;&lt;span style="font-weight: bold; font-style: italic;"&gt;Diagrama de Componentes:&lt;/span&gt;&lt;br /&gt;&lt;/li&gt;&lt;li style="font-weight: bold; font-style: italic;"&gt;Diagrama de Implementación:&lt;/li&gt;&lt;/ul&gt;&lt;p style="margin-bottom: 0cm;"&gt;&lt;span style="font-family:Arial,sans-serif;"&gt;&lt;/span&gt;&lt;/p&gt; &lt;style type="text/css"&gt; 	&lt;!-- 		@page { margin: 2cm } 		P { margin-bottom: 0.21cm } 		A:link { so-language: zxx } 	-&lt;/style&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5950429174584838030-8638053864232132586?l=caerices.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://caerices.blogspot.com/feeds/8638053864232132586/comments/default' title='Enviar comentarios'/><link rel='replies' type='text/html' href='http://caerices.blogspot.com/2009/07/diferencia-diagrama-proceso-diagrama.html#comment-form' title='0 comentarios'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5950429174584838030/posts/default/8638053864232132586'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5950429174584838030/posts/default/8638053864232132586'/><link rel='alternate' type='text/html' href='http://caerices.blogspot.com/2009/07/diferencia-diagrama-proceso-diagrama.html' title='Diferencia Diagrama Proceso - Diagrama Flujo - Diagrama de Datos'/><author><name>caerices</name><uri>http://www.blogger.com/profile/17494035119607034630</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='24' height='32' src='http://3.bp.blogspot.com/_w44tDpxaU14/SjfWwlmjQ_I/AAAAAAAAAAY/GCvAuqbqu0o/S220/Cesar.jpg'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://2.bp.blogspot.com/_w44tDpxaU14/SkyyaxqQ80I/AAAAAAAAABo/nym6t-XxojA/s72-c/Image26497.gif' height='72' width='72'/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-5950429174584838030.post-211812165601985033</id><published>2009-06-24T18:49:00.001-04:00</published><updated>2009-06-25T11:34:42.222-04:00</updated><title type='text'>Tablespaces postgres</title><content type='html'>&lt;meta equiv="CONTENT-TYPE" content="text/html; charset=utf-8"&gt;&lt;title&gt;&lt;/title&gt;&lt;meta name="GENERATOR" content="OpenOffice.org 3.0  (Win32)"&gt;&lt;style type="text/css"&gt; 	&lt;!-- 		@page { margin: 2cm } 		P { margin-bottom: 0.21cm } 	--&gt;&lt;/style&gt;&lt;div style="text-align: justify;"&gt;&lt;span style="font-weight: bold;"&gt;Tablespace &lt;/span&gt;en &lt;span style="font-weight: bold;"&gt;PostgreSQL&lt;/span&gt; permiten a los administradores definir los lugares, en el sistema de archivos, donde los archivos de la base de datos se pueden almacenar. Una vez creado, un &lt;span style="font-style: italic;"&gt;Tablespace &lt;/span&gt;puede ser referenciado por su nombre a la hora de crear objetos de base de datos.&lt;br /&gt;&lt;/div&gt;&lt;p style="margin-bottom: 0cm; text-align: justify;"&gt;&lt;br /&gt;Mediante el uso de &lt;span style="font-style: italic;"&gt;Tablespace&lt;/span&gt;, un administrador puede controlar la estructura del disco de instalación de PostgreSQL. Esto es útil por lo menos en dos formas. En primer lugar, si la partición o volumen en el que el grupo se ha inicializado se queda sin espacio y no puede extenderse, un espacio de &lt;span style="font-style: italic;"&gt;Tablespace &lt;/span&gt;se pueden crear en una partición diferente y se utiliza hasta que el sistema puede ser reconfigurado.&lt;br /&gt;&lt;br /&gt;En segundo lugar, permitir a un administrador el uso acerca del conocimiento de los patrones de uso de objetos de base de datos para optimizar el rendimiento. Por ejemplo, un índice que es muy usado puede ser colocado en una forma muy rápida, altamente disponible en disco, como un costoso dispositivo de estado sólido. Al mismo tiempo, una tabla para almacenar datos que rara vez se utiliza o los resultados no son críticos podrían estar almacenados en un sistema de disco menos costoso o más lento.&lt;br /&gt;&lt;br /&gt;Para definir un &lt;span style="font-style: italic;"&gt;tablespace&lt;/span&gt;, utilice la sentencia CREATE TABLESPACE comando, por ejemplo::&lt;br /&gt;&lt;br /&gt;CREATE TABLESPACE fastspace LOCATION  '/ mnt/sda1/postgresql/data';&lt;br /&gt;&lt;br /&gt;La ubicación debe ser una existente, directorio vacío que es de propiedad del usuario del sistema de PostgreSQL. Posteriormente, todos los objetos creados dentro de tablas se almacenan en los archivos bajo este directorio.&lt;br /&gt;&lt;br /&gt; Nota: Por lo general no tiene mucho sentido en la toma de más de una lógica de tablas por sistema de archivos, ya que no puede controlar la ubicación de los archivos individuales dentro de un sistema lógicode archivos. Sin embargo, PostgreSQL no garantice el cumplimiento de cualquier limitación de este tipo y, de hecho, no es directamente consciente de los límites del sistema de archivos en su sistema. Sólo almacena los archivos en los directorios que decirle que para su uso.&lt;br /&gt;&lt;br /&gt;Creación de TABLESPACES debe hacerse como una base de datos de superusuario, pero después de que se puede permitir que la base de datos común a los usuarios hacer uso de ella. Para ello, les concedan el permiso CREATE en él.&lt;br /&gt;&lt;br /&gt;Tablas, índices, bases de datos enteras puede ser asignado a los TABLESPACES. Para ello, un usuario con el privilegio de CREATE en un determinado tablespace deben aprobar el nombre de tablas como un parámetro al comando. Por ejemplo, la siguiente crea una tabla en la tablespace space1:&lt;br /&gt;&lt;br /&gt;CREATE TABLE foo (i int)  TABLESPACE space1;&lt;br /&gt;&lt;br /&gt;Como alternativa, utilice el parámetro default_tablespace:&lt;br /&gt;&lt;br /&gt;SET default_tablespace = space1;&lt;br /&gt;CREATE TABLE foo (i int);&lt;br /&gt;&lt;br /&gt;Cuando se establece default_tablespace a nada, pero una cadena vacía, que suministra una cláusula implícita TABLESPACE para CREATE TABLE y CREATE INDEX comandos que no tienen una explícita.&lt;br /&gt;&lt;br /&gt;También hay un parámetro &lt;u&gt;temp_tablespaces&lt;/u&gt;, que determina la colocación temporal de tablas e índices, así como los archivos temporales que se utilizan para fines tales como la clasificación de grandes conjuntos de datos. Esto puede ser una lista de nombre de tablespace, en lugar de uno sólo, de modo que la carga asociada a los objetos temporales se puede propagar a través de múltiples tablaspaces&lt;/p&gt; &lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5950429174584838030-211812165601985033?l=caerices.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://caerices.blogspot.com/feeds/211812165601985033/comments/default' title='Enviar comentarios'/><link rel='replies' type='text/html' href='http://caerices.blogspot.com/2009/06/tablespaces-postgres.html#comment-form' title='0 comentarios'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5950429174584838030/posts/default/211812165601985033'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5950429174584838030/posts/default/211812165601985033'/><link rel='alternate' type='text/html' href='http://caerices.blogspot.com/2009/06/tablespaces-postgres.html' title='Tablespaces postgres'/><author><name>caerices</name><uri>http://www.blogger.com/profile/17494035119607034630</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='24' height='32' src='http://3.bp.blogspot.com/_w44tDpxaU14/SjfWwlmjQ_I/AAAAAAAAAAY/GCvAuqbqu0o/S220/Cesar.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-5950429174584838030.post-2711726970641476599</id><published>2009-06-16T22:26:00.000-04:00</published><updated>2009-06-16T22:37:19.006-04:00</updated><title type='text'>cmd no funciona en windows vista</title><content type='html'>Hace mucho tiempo atras, tuve un problema con mi equipo windows vista.&lt;br /&gt;Al ejecutar el comando &lt;span style="font-weight: bold; font-style: italic;"&gt;cmd&lt;/span&gt; para visualizar el inteprete de comando de windows y digito "ipconfig" me salia el siguiente mensaje&lt;br /&gt;&lt;meta equiv="CONTENT-TYPE" content="text/html; charset=utf-8"&gt;&lt;title&gt;&lt;/title&gt;&lt;meta name="GENERATOR" content="OpenOffice.org 3.0  (Win32)"&gt;&lt;style type="text/css"&gt; 	&lt;!-- 		@page { margin: 2cm } 		P { margin-bottom: 0.21cm } 	--&gt; 	&lt;/style&gt; &lt;p style="font-weight: bold; font-style: italic;"&gt;&lt;span style="text-decoration: none;"&gt;no se reconoce como un comando interno o externo, programa o archivo por lotes ejecutable&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span style="text-decoration: none;"&gt;que paso? dije, que habre hecho, bueno la verdad es que windows perdio una variable path&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;span style="text-decoration: none;"&gt;&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span style="text-decoration: none;"&gt;gogleando encontre la siguiente solución al problema.&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;meta equiv="CONTENT-TYPE" content="text/html; charset=utf-8"&gt;&lt;title&gt;&lt;/title&gt;&lt;meta name="GENERATOR" content="OpenOffice.org 3.0  (Win32)"&gt;&lt;style type="text/css"&gt; 	&lt;!-- 		@page { margin: 2cm } 		P { margin-bottom: 0.21cm } 	--&gt; 	&lt;/style&gt; &lt;/p&gt;&lt;p style="margin-bottom: 0cm;"&gt;&lt;a name="SPELLING_ERROR_12"&gt;&lt;/a&gt;&lt;a name="SPELLING_ERROR_13"&gt;&lt;/a&gt;&lt;a name="SPELLING_ERROR_14"&gt;&lt;/a&gt;&lt;a name="SPELLING_ERROR_15"&gt;&lt;/a&gt;&lt;a name="BLOGGER_PHOTO_ID_5099405516941785202"&gt;&lt;/a&gt;&lt;a name="SPELLING_ERROR_21"&gt;&lt;/a&gt;&lt;a name="SPELLING_ERROR_22"&gt;&lt;/a&gt;&lt;a name="SPELLING_ERROR_23"&gt;&lt;/a&gt;&lt;a name="SPELLING_ERROR_24"&gt;&lt;/a&gt;&lt;a name="SPELLING_ERROR_25"&gt;&lt;/a&gt;&lt;a name="SPELLING_ERROR_26"&gt;&lt;/a&gt;&lt;a name="SPELLING_ERROR_27"&gt;&lt;/a&gt;&lt;a name="SPELLING_ERROR_28"&gt;&lt;/a&gt;&lt;a name="SPELLING_ERROR_29"&gt;&lt;/a&gt;&lt;a name="SPELLING_ERROR_30"&gt;&lt;/a&gt;&lt;a name="SPELLING_ERROR_31"&gt;&lt;/a&gt;&lt;a name="SPELLING_ERROR_32"&gt;&lt;/a&gt;&lt;a name="SPELLING_ERROR_33"&gt;&lt;/a&gt;&lt;a name="SPELLING_ERROR_34"&gt;&lt;/a&gt;&lt;a name="SPELLING_ERROR_35"&gt;&lt;/a&gt;&lt;a name="SPELLING_ERROR_36"&gt;&lt;/a&gt;&lt;a name="BLOGGER_PHOTO_ID_5099405435337406562"&gt;&lt;/a&gt;&lt;a name="SPELLING_ERROR_37"&gt;&lt;/a&gt;&lt;a name="SPELLING_ERROR_38"&gt;&lt;/a&gt;&lt;a name="SPELLING_ERROR_39"&gt;&lt;/a&gt;&lt;a name="SPELLING_ERROR_40"&gt;&lt;/a&gt;&lt;a name="SPELLING_ERROR_41"&gt;&lt;/a&gt;&lt;a name="SPELLING_ERROR_42"&gt;&lt;/a&gt;&lt;a name="SPELLING_ERROR_43"&gt;&lt;/a&gt;&lt;a name="SPELLING_ERROR_44"&gt;&lt;/a&gt;&lt;a name="SPELLING_ERROR_45"&gt;&lt;/a&gt;&lt;a name="SPELLING_ERROR_46"&gt;&lt;/a&gt;&lt;a name="SPELLING_ERROR_47"&gt;&lt;/a&gt;&lt;a name="SPELLING_ERROR_48"&gt;&lt;/a&gt;&lt;a name="SPELLING_ERROR_49"&gt;&lt;/a&gt;&lt;a name="SPELLING_ERROR_50"&gt;&lt;/a&gt;&lt;a name="SPELLING_ERROR_51"&gt;&lt;/a&gt;&lt;br /&gt;&lt;b&gt;¿Que son las variables que maneja windows?&lt;/b&gt;&lt;br /&gt;Son una serie de valores, que maneja windows, las cuales usa para sus funciones propias.&lt;br /&gt;Si queremos ver las variables que tiene nuestro sistema, simplemente debemos de ejecutar el comando set desde la consola de comandos y nos encontraremos con algo parecido a esto:&lt;br /&gt;&lt;br /&gt;&lt;a href="http://bp1.blogger.com/_Zp5xZQi7TTw/RsS6TML7eHI/AAAAAAAAAWo/sZItBU_I9nE/s1600-h/set.gif"&gt;&lt;img src="http://bp1.blogger.com/_Zp5xZQi7TTw/RsS6TML7eHI/AAAAAAAAAWo/sZItBU_I9nE/s400/set.gif" name="gráficos2" align="bottom" border="0" height="38" vspace="5" width="75" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;Si nos damos cuenta hay una variable la cual se llama Path, la cual nada mas instalar un sistema operativo, nos encontraremos que como minino incluye estos valores:&lt;br /&gt;&lt;b&gt;Path=c:\windows\system32;c:\windows&lt;br /&gt;&lt;/b&gt;Si analizamos un poco esta situación, y pensamos un poco en lo que está pasando, nos daremos cuenta de un pequeño detalle.&lt;br /&gt;Los comandos que no nos reconocía la consola de comandos, están todos dentro de estos directorios.&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;b&gt;¿Como modificamos las variables del path?&lt;/b&gt;&lt;br /&gt;Es muy sencillo, debemos de entrar en lo siguiente:&lt;br /&gt;-botón derehco sobre &lt;b&gt;mi pc&lt;/b&gt;&lt;br /&gt;-Pestaña &lt;b&gt;opciones avanzadas&lt;/b&gt;&lt;br /&gt;-&lt;b&gt;Variables de entorno&lt;/b&gt;&lt;br /&gt;&lt;b&gt;-Path&lt;/b&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;a href="http://bp2.blogger.com/_Zp5xZQi7TTw/RsS6OcL7eGI/AAAAAAAAAWg/4A2v7xCaJ7c/s1600-h/Path.gif"&gt;&lt;img src="http://bp2.blogger.com/_Zp5xZQi7TTw/RsS6OcL7eGI/AAAAAAAAAWg/4A2v7xCaJ7c/s400/Path.gif" name="gráficos3" align="bottom" border="0" height="38" vspace="5" width="75" /&gt;&lt;/a&gt;&lt;br /&gt;Y aquí podemos añadir los directorios que queramos que estén en el path.&lt;br /&gt;En este caso que no nos encontraba los comandos del sistema asi que debemos añadir, los directorios &lt;b&gt;Path=c:\windows\system32;c:\windows&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;¿Que conclusión sacamos?&lt;/b&gt;&lt;br /&gt;En el path están incluidos los comandos que el sistema reconoce como propios, y los ejecuta directamente, aunque no estemos en el directorio donde están propiamente los ficheros.&lt;br /&gt;Ej, si yo tengo un directorio el cual es&lt;br /&gt;c:\mi_programa&lt;br /&gt;y dento hay un fichero que se llama "lo_ejecuto_cuando_quiero.exe"&lt;br /&gt;Con añadir a la linea de path , el directorio "c:\mi_programa", podre lanzar el fichero ejecutable, desde cualquier ruta, de mi sistema.&lt;br /&gt;&lt;br /&gt;Espero que todas vuestras variables tengan buena salud, y nos os vuelvan locos&lt;/p&gt; &lt;p style="margin-bottom: 0cm;"&gt;&lt;br /&gt;&lt;/p&gt; &lt;p&gt;&lt;/p&gt;&lt;br /&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5950429174584838030-2711726970641476599?l=caerices.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://caerices.blogspot.com/feeds/2711726970641476599/comments/default' title='Enviar comentarios'/><link rel='replies' type='text/html' href='http://caerices.blogspot.com/2009/06/cmd-no-funciona-en-windows-vista.html#comment-form' title='0 comentarios'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5950429174584838030/posts/default/2711726970641476599'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5950429174584838030/posts/default/2711726970641476599'/><link rel='alternate' type='text/html' href='http://caerices.blogspot.com/2009/06/cmd-no-funciona-en-windows-vista.html' title='cmd no funciona en windows vista'/><author><name>caerices</name><uri>http://www.blogger.com/profile/17494035119607034630</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='24' height='32' src='http://3.bp.blogspot.com/_w44tDpxaU14/SjfWwlmjQ_I/AAAAAAAAAAY/GCvAuqbqu0o/S220/Cesar.jpg'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://bp1.blogger.com/_Zp5xZQi7TTw/RsS6TML7eHI/AAAAAAAAAWo/sZItBU_I9nE/s72-c/set.gif' height='72' width='72'/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-5950429174584838030.post-3758438648360295577</id><published>2009-06-16T15:09:00.001-04:00</published><updated>2009-06-16T22:05:47.689-04:00</updated><title type='text'>ENCODING en Postgres</title><content type='html'>&lt;div style="text-align: justify;"&gt;Muchas veces nos hemos encontrado con problemas de codificación distinta entre nuestras aplicaciones y la presentada por el el Gestor de Base de Datos. Postgres no es la excepción de la regla y en innumerable casos hemos tenidos que  (haciendo mención a la lista de postgres) responder la siguiente consulta "&lt;span style="font-weight: bold; font-style: italic;"&gt;Problema con los Acentos y las eñe&lt;/span&gt;"&lt;br /&gt;&lt;br /&gt;Este caso tipico no es algo fortuito, más bien en por desconocimiento de las codigicaciones existente en la web (para ver tipo 866 de encoding &lt;a href="http://en.wikipedia.org/wiki/Code_page_866"&gt;aqui&lt;/a&gt;, encoding ISO-8859-1 &lt;a href="http://en.wikipedia.org/wiki/ISO/IEC_8859-1"&gt;aqui&lt;/a&gt; como por ejemplo)  pueden ver el siguiente link&lt;br /&gt;&lt;br /&gt;Hace mucho tiempo atras en el foro de postgres Gabriel Ferro presento parte de un texto enviado por Gunnar Wolf en relación al tema&lt;br /&gt;&lt;br /&gt;"El caracter 186 en ISO 8859-1 es Âº, y el mismo caracter en CP866 es&lt;br /&gt;â•‘. Claro, en Unicode son caracteres diferentes (U+00BA y U+2551&lt;br /&gt;respectivamente). Tu base de datos seguramente contiene â•‘, porque&lt;br /&gt;partiÃ³ del supuesto que la aplicaciÃ³n estaba hablando en CP866."&lt;br /&gt;&lt;br /&gt;lo cual encontre muy intersante para demostrar lo caotico que puede ser el no definir bien los encoding para nuestro desarrollo.&lt;br /&gt;&lt;br /&gt;Para evitar este tipo de problemas es necesario codificar la Base de Datos en UTF-8 por que este tipo de codificación permite cualquier tipo de caracter&lt;br /&gt;&lt;br /&gt;crear base de datos con encoding UTF8&lt;br /&gt;&lt;br /&gt;initdb --locale=es_PE.utf8 -D /usr/local/pgsql/data&lt;br /&gt;&lt;br /&gt;Otra cosa necesaria es conocer que no se puede cambiar el encode a una Base de Datos existente, para ello debemos respaldar la actual y crear nuestra base de Datos con la nueva codificacion&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;consideraciones:&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;/div&gt;&lt;ul style="text-align: justify;"&gt;&lt;li&gt;La codificación de la Base de Datos ( # SHOW SERVER_ENCODING;)&lt;/li&gt;&lt;li&gt; La codificación Cliente (#SHOW CLIENT_ENCODING;)&lt;/li&gt;&lt;li&gt; la configuracion de tu maquina server (creo que los LOCATE)&lt;/li&gt;&lt;li&gt;Por ultimo la codificación de tu aplicación&lt;/li&gt;&lt;/ul&gt;&lt;div style="text-align: justify;"&gt;Otra cosa a considerar es que para los de windows&lt;br /&gt;&lt;br /&gt;WIN1252 es el equivalente de LATIN1 en Windows&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5950429174584838030-3758438648360295577?l=caerices.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://caerices.blogspot.com/feeds/3758438648360295577/comments/default' title='Enviar comentarios'/><link rel='replies' type='text/html' href='http://caerices.blogspot.com/2009/06/cambiar-encode-postgres.html#comment-form' title='3 comentarios'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5950429174584838030/posts/default/3758438648360295577'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5950429174584838030/posts/default/3758438648360295577'/><link rel='alternate' type='text/html' href='http://caerices.blogspot.com/2009/06/cambiar-encode-postgres.html' title='ENCODING en Postgres'/><author><name>caerices</name><uri>http://www.blogger.com/profile/17494035119607034630</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='24' height='32' src='http://3.bp.blogspot.com/_w44tDpxaU14/SjfWwlmjQ_I/AAAAAAAAAAY/GCvAuqbqu0o/S220/Cesar.jpg'/></author><thr:total>3</thr:total></entry><entry><id>tag:blogger.com,1999:blog-5950429174584838030.post-2520733414375386804</id><published>2009-06-16T13:59:00.000-04:00</published><updated>2009-06-16T14:00:23.442-04:00</updated><title type='text'>scrip para leer estructura</title><content type='html'>&lt;span style="font-weight: bold;"&gt;Script para leer estructura en una Base de Datos Postgres&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;SELECT   z.relname,  a.attname,    pg_catalog.format_type(a.atttypid, a.atttypmod) as type,&lt;br /&gt;  a.attnotnull,  adef.adsrc,    pg_catalog.col_description(a.attrelid, a.attnum) AS comment&lt;br /&gt;&lt;br /&gt;FROM&lt;br /&gt;   pg_catalog.pg_attribute a LEFT JOIN pg_catalog.pg_attrdef adef&lt;br /&gt;   ON a.attrelid=adef.adrelid&lt;br /&gt;   AND a.attnum=adef.adnum&lt;br /&gt;   LEFT JOIN pg_catalog.pg_type t ON a.atttypid=t.oid&lt;br /&gt;&lt;br /&gt;   join pg_catalog.pg_class z on a.attrelid = z.oid and z.relnamespace = (SELECT oid FROM pg_catalog.pg_namespace WHERE&lt;br /&gt;       nspname = 'public')&lt;br /&gt;&lt;br /&gt;WHERE&lt;br /&gt;a.attnum &gt; 0 AND NOT a.attisdropped and (z.relname not ilike '%_seq' and z.relname not ilike '%_pk')&lt;br /&gt;ORDER BY z.relname, a.attnum&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5950429174584838030-2520733414375386804?l=caerices.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://caerices.blogspot.com/feeds/2520733414375386804/comments/default' title='Enviar comentarios'/><link rel='replies' type='text/html' href='http://caerices.blogspot.com/2009/06/scrip-para-leer-estructura.html#comment-form' title='0 comentarios'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5950429174584838030/posts/default/2520733414375386804'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5950429174584838030/posts/default/2520733414375386804'/><link rel='alternate' type='text/html' href='http://caerices.blogspot.com/2009/06/scrip-para-leer-estructura.html' title='scrip para leer estructura'/><author><name>caerices</name><uri>http://www.blogger.com/profile/17494035119607034630</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='24' height='32' src='http://3.bp.blogspot.com/_w44tDpxaU14/SjfWwlmjQ_I/AAAAAAAAAAY/GCvAuqbqu0o/S220/Cesar.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-5950429174584838030.post-7171521561414721932</id><published>2009-06-16T13:48:00.000-04:00</published><updated>2009-06-16T22:06:24.438-04:00</updated><title type='text'>Instalar Postgres 8.3.7 con CENTOS 5.3</title><content type='html'>&lt;meta equiv="CONTENT-TYPE" content="text/html; charset=utf-8"&gt;&lt;title&gt;&lt;/title&gt;&lt;meta name="GENERATOR" content="OpenOffice.org 3.0  (Win32)"&gt;&lt;style type="text/css"&gt; 	&lt;!-- 		@page { margin: 2cm } 		P { margin-bottom: 0.21cm } 		H2 { margin-bottom: 0.21cm } 		A:link { so-language: zxx } 	--&lt;/style&gt;&lt;div style="text-align: justify;"&gt;La versión de Postgres para CentOS es la 8.1.x, lo que necesito es instalar la ultima version estable hasta la fecha (8.3.7), para hacerlo realizé lo siguiente: &lt;/div&gt;&lt;ul style="text-align: justify;"&gt;&lt;li&gt;&lt;p&gt;Excluir postgres del repositorio Base de Centos:  	&lt;/p&gt; &lt;/li&gt;&lt;/ul&gt;&lt;div style="text-align: justify;"&gt; &lt;blockquote&gt;# vi /etc/yum.repos.d/CentOS-Base.repo&lt;br /&gt;&lt;em&gt;[base]&lt;br /&gt;name=CentOS-$releasever – Base&lt;br /&gt;mirrorlist=http://mirrorlist.centos.org/?release=$releasever&amp;amp;arch=$basearch&amp;amp;repo=os&lt;br /&gt;#baseurl=http://mirror.centos.org/centos/$releasever/os/$basearch/&lt;br /&gt;gpgcheck=1&lt;br /&gt;gpgkey=file:///etc/pki/rpm-gpg/RPM-GPG-KEY-CentOS-5&lt;br /&gt;# Excluir postgres&lt;br /&gt;exclude=postgresql*&lt;/em&gt;&lt;/blockquote&gt; &lt;blockquote&gt;&lt;em&gt;#released updates&lt;br /&gt;[updates]&lt;br /&gt;name=CentOS-$releasever – Updates&lt;br /&gt;mirrorlist=http://mirrorlist.centos.org/?release=$releasever&amp;amp;arch=$basearch&amp;amp;repo=updates&lt;br /&gt;#baseurl=http://mirror.centos.org/centos/$releasever/updates/$basearch/&lt;br /&gt;gpgcheck=1&lt;br /&gt;gpgkey=file:///etc/pki/rpm-gpg/RPM-GPG-KEY-CentOS-5&lt;br /&gt;# Excluir postgres&lt;br /&gt;exclude=postgresql*&lt;/em&gt;&lt;/blockquote&gt; &lt;/div&gt;&lt;ul style="text-align: justify;"&gt;&lt;li&gt;&lt;p&gt;Añadir el nuevo repositorio de postgres desde 	http://yum.pgsqlrpms.org/reporpms/repoview/pgdg-centos.html, un 	nivel mas arriba de esta página estan los repositorios para Fedora 	y Red Hat  	&lt;/p&gt; &lt;/li&gt;&lt;/ul&gt;&lt;div style="text-align: justify;"&gt; &lt;blockquote&gt;# wget http://yum.pgsqlrpms.org/reporpms/8.3/pgdg-centos-8.3-6.noarch.rpm&lt;br /&gt;# rpm -ivh pgdg-centos-8.3-6.noarch.rpm&lt;/blockquote&gt; &lt;/div&gt;&lt;ul style="text-align: justify;"&gt;&lt;li&gt;&lt;p&gt;Instalación de PostgreSQL server:  	&lt;/p&gt; &lt;/li&gt;&lt;/ul&gt;&lt;div style="text-align: justify;"&gt; &lt;blockquote&gt;# yum install postgresql postgresql-server&lt;br /&gt;&lt;em&gt;… lot of output ….&lt;/em&gt;&lt;/blockquote&gt; &lt;/div&gt;&lt;p style="text-align: justify;"&gt;despúes de la instalación necesito cambiar la ubicación de las bases de datos para una partición mayor, en mi caso ‘/home’, antes debo iniciar el servidor:&lt;/p&gt;&lt;div style="text-align: justify;"&gt; &lt;blockquote&gt;# service initdb postgresql -&gt; Crea los archivos necesario e inicia el servidor&lt;br /&gt;# su – postgres -c psql -&gt; inicia sesión como postgres para poder cambiar la ubicación&lt;br /&gt;Digite:  \copyright para ver los términos de distribución&lt;br /&gt;\h para ayuda de órdenes SQL&lt;br /&gt;\? para ayuda de órdenes psql&lt;br /&gt;\g o punto y coma («;») para ejecutar la consulta&lt;br /&gt;\q para salir&lt;br /&gt;postgres=# initdb -D /home/postgres -&gt; Esta carpeta debe existir y el dueño debe ser el usuario postgres&lt;br /&gt;postgres=# \q -&gt; Salir&lt;/blockquote&gt; &lt;/div&gt;&lt;p style="text-align: justify;"&gt;Ahora los datos se guardan en /home/postgres, al hacer initdb -D /home/postgres los archivos necesario se crean allí.&lt;/p&gt; &lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5950429174584838030-7171521561414721932?l=caerices.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://caerices.blogspot.com/feeds/7171521561414721932/comments/default' title='Enviar comentarios'/><link rel='replies' type='text/html' href='http://caerices.blogspot.com/2009/06/instalar-postgres-centos.html#comment-form' title='0 comentarios'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5950429174584838030/posts/default/7171521561414721932'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5950429174584838030/posts/default/7171521561414721932'/><link rel='alternate' type='text/html' href='http://caerices.blogspot.com/2009/06/instalar-postgres-centos.html' title='Instalar Postgres 8.3.7 con CENTOS 5.3'/><author><name>caerices</name><uri>http://www.blogger.com/profile/17494035119607034630</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='24' height='32' src='http://3.bp.blogspot.com/_w44tDpxaU14/SjfWwlmjQ_I/AAAAAAAAAAY/GCvAuqbqu0o/S220/Cesar.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-5950429174584838030.post-3031936428364916657</id><published>2009-06-16T13:43:00.000-04:00</published><updated>2009-06-26T11:20:01.674-04:00</updated><title type='text'>Comandos Basicos Postgres</title><content type='html'>&lt;span style="font-weight: bold;font-size:180%;" &gt;Comandos Basicos para la Administración de Postgres&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;meta equiv="CONTENT-TYPE" content="text/html; charset=utf-8"&gt;&lt;title&gt;&lt;/title&gt;&lt;meta name="GENERATOR" content="OpenOffice.org 3.0  (Win32)"&gt;&lt;style type="text/css"&gt; 	&lt;!-- 		@page { margin: 2cm } 		P { margin-bottom: 0.21cm } 		H2 { margin-bottom: 0.21cm } 	--&gt; 	&lt;/style&gt; &lt;h2 style="font-weight: bold;"&gt;&lt;span style="font-size:100%;"&gt;Cómo cambiar la clave del usuario root (&lt;strong&gt;postgres) &lt;/strong&gt;en PostgreSQL&lt;/span&gt;&lt;/h2&gt; &lt;p&gt;En primera instancia accedemos a la shell de postgreSQL:&lt;/p&gt; &lt;pre&gt;$ /usr/local/pgsql/bin/psql postgres postgres Password: (antiguo password)&lt;br /&gt;# ALTER USER postgres WITH PASSWORD ‘nuevopassword’;&lt;/pre&gt;&lt;p&gt; Ya podemos acceder con la nueva clave:&lt;/p&gt; &lt;pre&gt;$ /usr/local/pgsql/bin/psql postgres postgres Password: (nuevopassword)&lt;/pre&gt;&lt;h2&gt; &lt;span style="font-size:100%;"&gt;Cómo configurar el script PostgreSQL SysV de inicio&lt;/span&gt;&lt;/h2&gt; &lt;p&gt;Si no has instalado PostgreSQL desde un gestor de paquetes probablemente te servirá este apartado, este script contendrá los típicos comandos de arranque, parar, reiniciar y estado del servidor PostgreSQL:&lt;/p&gt; &lt;pre&gt;$ su - root&lt;br /&gt;# tar xvfz postgresql-8.3.7.tar.gz&lt;br /&gt;# cd postgresql-8.3.7&lt;br /&gt;# cp contrib/start-scripts/linux /etc/rc.d/init.d/postgresql&lt;br /&gt;# chmod a+x /etc/rc.d/init.d/postgresql&lt;/pre&gt;&lt;h2&gt; &lt;span style="font-size:100%;"&gt;Cómo revisar si PostgreSQL está funcionando&lt;/span&gt;&lt;/h2&gt; &lt;pre&gt;$ /etc/init.d/postgresql status Password:&lt;br /&gt;pg_ctl: server is running (PID: 6171)&lt;br /&gt;/usr/local/pgsql/bin/postgres “-D” “/usr/local/pgsql/data”&lt;/pre&gt;&lt;p&gt; En el anterior ejemplo PostgreSQL está funcionando correctamente.&lt;/p&gt; &lt;pre&gt;$ /etc/init.d/postgresql status Password: pg_ctl: no server running [Note: The status above indicates the server is down]&lt;/pre&gt;&lt;p&gt; En el anterior ejemplo PostgreSQL no está funcionando correctamente.&lt;/p&gt; &lt;h2&gt;&lt;span style="font-size:100%;"&gt;Cómo iniciar, parar, reiniciar el servidor de base de datos PostgreSQL&lt;/span&gt;&lt;/h2&gt; &lt;pre&gt;# service postgresql stop Stopping PostgreSQL: server stopped ok&lt;br /&gt;# service postgresql start Starting PostgreSQL: ok&lt;br /&gt;# service postgresql restart Restarting PostgreSQL: server stopped ok&lt;/pre&gt;&lt;h2&gt;&lt;span style="font-size:100%;"&gt; Cómo saber qué versión de PostgreSQL está instalada&lt;/span&gt;&lt;/h2&gt; &lt;pre&gt;$ /usr/local/pgsql/bin/psql test Welcome to psql 8.3.7,&lt;br /&gt;the PostgreSQL interactive terminal.&lt;br /&gt;Type:  \copyright for distribution terms&lt;br /&gt;   \h for help with SQL commands&lt;br /&gt;   \? for help with psql commands&lt;br /&gt;   \g or terminate with semicolon to execute query&lt;br /&gt;   \q to quit&lt;br /&gt;test=# select version();&lt;br /&gt;version —————————————————————————————————-&lt;br /&gt;PostgreSQL 8.3.7 on i686-pc-linux-gnu,compiled by GCC gcc (GCC) 4.1.2 20071124 (Red Hat 4.1.2-42) (1 row)&lt;br /&gt;test=#&lt;/pre&gt;&lt;span style="font-weight: bold;"&gt;Cómo Conectarse con una Base de Datos determinada&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;# su postgres&lt;br /&gt;bash-3.2$ psql drupal&lt;br /&gt;could not change directory to "/home/cerices"&lt;br /&gt;Welcome to psql 8.3.5, the PostgreSQL interactive terminal.&lt;br /&gt;&lt;br /&gt;Type:  \copyright for distribution terms&lt;br /&gt;  \h for help with SQL commands&lt;br /&gt;  \? for help with psql commands&lt;br /&gt;  \g or terminate with semicolon to execute query&lt;br /&gt;  \q to quit&lt;br /&gt;&lt;br /&gt;drupal=#&lt;br /&gt;&lt;br /&gt;&lt;h3 class="title"&gt;Como Usar una Base de Datos&lt;br /&gt;&lt;/h3&gt;&lt;p&gt;Puede emplear &lt;span&gt;&lt;strong class="command"&gt;psql&lt;/strong&gt;&lt;/span&gt;, la interfaz texto que 	acepta comandos SQL y que se distribuye con PostgreSQL.  	Para esto, entre a una base (digamos &lt;code class="literal"&gt;b1908&lt;/code&gt;)          como un usuario (digamos &lt;code class="literal"&gt;u1908&lt;/code&gt;) 	con: &lt;/p&gt;&lt;pre class="screen"&gt;psql -U u1908 -d b1908&lt;br /&gt;&lt;/pre&gt;&lt;p&gt; 	En esta interfaz puede dar comandos SQL y algunos comandos internos  	que puede listar con &lt;span&gt;&lt;strong class="command"&gt;\h&lt;/strong&gt;&lt;/span&gt;. 	Algunos ejemplos de operaciones útiles son:       &lt;/p&gt;&lt;div class="variablelist"&gt;&lt;dl&gt;&lt;dt&gt;&lt;span class="term"&gt;&lt;code class="literal"&gt;\dt&lt;/code&gt;&lt;/span&gt;&lt;/dt&gt;&lt;dd&gt;&lt;p&gt;para ver tablas disponibles.&lt;/p&gt;&lt;/dd&gt;&lt;dt&gt;&lt;span class="term"&gt;&lt;code class="literal"&gt;\d usuarios&lt;/code&gt;&lt;/span&gt;&lt;/dt&gt;&lt;dd&gt;&lt;p&gt;Describe la estructura de la tabla 	      &lt;code class="literal"&gt;usuarios&lt;/code&gt;&lt;/p&gt;&lt;/dd&gt;&lt;dt&gt;&lt;span class="term"&gt;&lt;code class="literal"&gt;SELECT victim_nombre,victim_apellido FROM victimas WHERE victim_edad&lt;=12;&lt;/code&gt;&lt;/span&gt;&lt;/dt&gt;&lt;dd&gt;&lt;p&gt;Que muestre los nombres de niños de 12 años o menos listados en la tabla &lt;code class="literal"&gt;victimas&lt;/code&gt;&lt;/p&gt;&lt;/dd&gt;&lt;dt&gt;&lt;span class="term"&gt;&lt;code class="literal"&gt;\h update&lt;/code&gt;&lt;/span&gt;&lt;/dt&gt;&lt;dd&gt;&lt;p&gt;Da ayuda sobre el comando {\tt update} (que permite  	actualizar registros de una tabla.) &lt;/p&gt;&lt;/dd&gt;&lt;/dl&gt;&lt;/div&gt;&lt;p&gt;  &lt;/p&gt;&lt;div class="sect2" lang="es"&gt;&lt;div class="titlepage"&gt;&lt;div&gt;&lt;div&gt;&lt;h3 class="title"&gt;&lt;a name="respaldo-postgresql"&gt;&lt;/a&gt; Copias de respaldo&lt;/h3&gt;&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;&lt;p&gt;Para sacar una copia de respaldo de todas las  		  base de datos manejadas con PostgreSQL (y suponiendo 		  que el socket está en &lt;code class="filename"&gt;/var/www/tmp&lt;/code&gt;): 		  &lt;/p&gt;&lt;pre class="screen"&gt;pg_dumpall -U postgres -h /var/www/tmp/ \&lt;br /&gt;   --inserts --attribute-inserts &gt; /respaldos/pgdump.sql&lt;br /&gt;		  &lt;/pre&gt;&lt;p&gt;  		  Puede restablecer una copia con 		  &lt;/p&gt;&lt;pre class="screen"&gt;psql -U postgres -h /var/www/tmp/ \&lt;br /&gt;	-f /respaldos/pgdump.sql template1&lt;br /&gt;&lt;br /&gt;&lt;/pre&gt;&lt;h3&gt;Configuración Post-Instalación&lt;/h3&gt; &lt;p&gt;Vamos&lt;br /&gt;     a crear un directorio data y asignamos los directorios a sus propietarios:&lt;/p&gt; &lt;div class="codigo"&gt; &lt;pre&gt;[shell]# mkdir /usr/locl/pgsql/data&lt;br /&gt;[shell]# chown postgres /usr/local/pgsql/data&lt;/pre&gt; &lt;/div&gt; &lt;p&gt;Ahora&lt;br /&gt;     nos ponemos como postgres para instalar la BD:&lt;/p&gt; &lt;div class="codigo"&gt; &lt;pre&gt;[shell]# su - postgres&lt;br /&gt;[shell]$ /usr/local/pgsql/bin/initdb -D /usr/local/pgsql/data&lt;/pre&gt; &lt;/div&gt; &lt;p&gt;Ahora&lt;br /&gt;     iniciamos la BD:&lt;/p&gt; &lt;div class="codigo"&gt; &lt;pre&gt;[shell]$ /usr/local/pgsql/bin/postmaster&lt;br /&gt;-D /usr/local/pgsql/data&lt;br /&gt;&lt;br /&gt;&lt;span style="font-size:130%;"&gt;&lt;span style="font-weight: bold; font-family: arial;"&gt;Otras&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;SELECT datname FROM pg_database;&lt;br /&gt;&lt;/pre&gt; &lt;/div&gt;&lt;pre class="screen"&gt;&lt;br /&gt;&lt;/pre&gt;&lt;/div&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5950429174584838030-3031936428364916657?l=caerices.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://caerices.blogspot.com/feeds/3031936428364916657/comments/default' title='Enviar comentarios'/><link rel='replies' type='text/html' href='http://caerices.blogspot.com/2009/06/comandos-basicos.html#comment-form' title='2 comentarios'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5950429174584838030/posts/default/3031936428364916657'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5950429174584838030/posts/default/3031936428364916657'/><link rel='alternate' type='text/html' href='http://caerices.blogspot.com/2009/06/comandos-basicos.html' title='Comandos Basicos Postgres'/><author><name>caerices</name><uri>http://www.blogger.com/profile/17494035119607034630</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='24' height='32' src='http://3.bp.blogspot.com/_w44tDpxaU14/SjfWwlmjQ_I/AAAAAAAAAAY/GCvAuqbqu0o/S220/Cesar.jpg'/></author><thr:total>2</thr:total></entry><entry><id>tag:blogger.com,1999:blog-5950429174584838030.post-5184413836735321396</id><published>2009-06-16T12:26:00.000-04:00</published><updated>2009-07-09T13:38:25.628-04:00</updated><title type='text'>Trucos básicos</title><content type='html'>&lt;span style="font-family:arial;"&gt;&lt;span style="font-weight: bold;"&gt;Listado de Comando por Consola&lt;/span&gt;&lt;br /&gt;cas=# \?&lt;br /&gt;General&lt;br /&gt;  \copyright      mostrar tÚrminos de uso y distribuci¾n de PostgreSQL&lt;br /&gt;  \g [ARCH] o ;   enviar b·fer de consulta al servidor&lt;br /&gt;                  (y resultados a archivo u |orden)&lt;br /&gt;  \h [NOMBRE]     mostrar ayuda de sintaxis de ¾rdenes SQL;&lt;br /&gt;                  use ½*╗ para todas las ¾rdenes&lt;br /&gt;  \q              salir de psql&lt;br /&gt;&lt;br /&gt;B·fer de consulta&lt;br /&gt;  \e [ARCHIVO]    editar el b·fer de consulta (o archivo) con editor externo&lt;br /&gt;  \ef [ARCHIVO]   editar una funci¾n con editor externo&lt;br /&gt;  \p              mostrar el contenido del b·fer de consulta&lt;br /&gt;  \r              reiniciar (limpiar) el b·fer de consulta&lt;br /&gt;  \w ARCHIVO      escribir b·fer de consulta a archivo&lt;br /&gt;&lt;br /&gt;Entrada/Salida&lt;br /&gt;  \copy ...       ejecutar orden SQL COPY con flujo de datos al cliente&lt;br /&gt;  \echo [CADENA]  escribir cadena a salida estßndar&lt;br /&gt;  \i ARCHIVO      ejecutar ¾rdenes desde archivo&lt;br /&gt;  \o [ARCHIVO]    envÝar resultados de consultas a archivo u |orden&lt;br /&gt;  \qecho [CADENA] escribir cadena a salida de consultas (ver \o)&lt;br /&gt;&lt;br /&gt;Informativo&lt;br /&gt;   (opciones: S = desplegar objectos de sistema, + = agregar mßs detalle)&lt;br /&gt;  \d[S+]            listar tablas, vistas y secuencias&lt;br /&gt;  \d[S+]  NOMBRE    describir tabla, Ýndice, secuencia o vista&lt;br /&gt;  \da[+]  [PATRËN]  listar funciones de agregaci¾n&lt;br /&gt;  \db[+]  [PATRËN]  listar tablespaces&lt;br /&gt;  \dc[S]  [PATRËN]  listar conversiones&lt;br /&gt;  \dC     [PATRËN]  listar conversiones de tipo (casts)&lt;br /&gt;  \dd[S]  [PATRËN]  listar comentarios de objetos&lt;br /&gt;  \dD[S]  [PATRËN]  listar dominios&lt;br /&gt;  \des[+] [PATRËN]  listar servidores forßneos&lt;br /&gt;  \deu[+] [PATRËN]  listar mapeos de usuario&lt;br /&gt;  \dew[+] [PATRËN]  listar conectores de datos externos&lt;br /&gt;  \df[antw][S+] [PATRËN]  listar funciones de agregaci¾n&lt;br /&gt;  \dF[+]  [PATRËN]  listar configuraciones de b·squeda en texto&lt;br /&gt;  \dFd[+] [PATRËN]  listar diccionarios de b·squeda en texto&lt;br /&gt;  \dFp[+] [PATRËN]  listar analizadores (parsers) de b·sq. en texto&lt;br /&gt;  \dFt[+] [PATRËN]  listar plantillas de b·squeda en texto&lt;br /&gt;  \dg     [PATRËN]  listar roles (grupos)&lt;br /&gt;  \di[S+] [PATRËN]  listar Ýndices&lt;br /&gt;  \dl               listar objetos grandes, lo mismo que \lo_list&lt;br /&gt;  \dn[+]  [PATRËN]  listar esquemas&lt;br /&gt;  \do[S]  [PATRËN]  listar operadores&lt;br /&gt;  \dp     [PATRËN]  listar privilegios de acceso a tablas, vistas y secuencias&lt;br /&gt;  \ds[S+] [PATRËN]  listar secuencias&lt;br /&gt;  \dt[S+] [PATRËN]  listar tablas&lt;br /&gt;  \dT[S+] [PATRËN]  listar tipos de dato&lt;br /&gt;  \du     [PATRËN]  listar roles (usuarios)&lt;br /&gt;  \dv[S+] [PATRËN]  listar vistas&lt;br /&gt;  \l[+]             listar bases de datos&lt;br /&gt;  \z      [PATRËN]  lo mismo que \dp&lt;br /&gt;&lt;br /&gt;Formato&lt;br /&gt;  \a              cambiar entre modo de salida alineado y sin alinear&lt;br /&gt;  \C [CADENA]     definir tÝtulo de tabla, o indefinir si es vacÝo&lt;br /&gt;  \f [CADENA]     mostrar o definir separador de campos para&lt;br /&gt;                  modo de salida sin alinear&lt;br /&gt;  \H              cambiar modo de salida HTML (actualmente desactivado)&lt;br /&gt;  \pset NOMBRE [VALOR]&lt;br /&gt;                  define opci¾n de salida de tabla&lt;br /&gt;                  (NOMBRE = format,border,expanded,fieldsep,footer,null,&lt;br /&gt;                  numericlocale,recordsep,tuples_only,title,tableattr,pager})&lt;br /&gt;  \t [on|off]     mostrar s¾lo filas (actualmente desactivado)&lt;br /&gt;  \T [CADENA]     definir atributos HTML de &lt;table&gt;, o indefinir si es vacÝo&lt;br /&gt;  \x [on|off]     cambiar modo expandido (actualmente desactivado)&lt;br /&gt;&lt;br /&gt;Conexiones&lt;br /&gt;  \c[onnect] [BASE-DE-DATOS|- USUARIO|- ANFITRIËN|- PUERTO|-]&lt;br /&gt;                  conectar a una nueva base de datos (actual: ½cas╗)&lt;br /&gt;  \encoding [CODIFICACIËN]&lt;br /&gt;                  mostrar o definir codificaci¾n del cliente&lt;br /&gt;  \password [USUARIO]&lt;br /&gt;                  cambiar la contrase±a para un usuario en forma segura&lt;br /&gt;&lt;br /&gt;Sistema Operativo&lt;br /&gt;  \cd [DIR]        cambiar el directorio de trabajo actual&lt;br /&gt;  \timing [on|off] mostrar tiempo de ejecuci¾n de ¾rdenes&lt;br /&gt;                   (actualmente desactivado)&lt;br /&gt;  \! [ORDEN]       ejecutar orden en intÚrprete de ¾rdenes (shell),&lt;br /&gt;                   o iniciar intÚrprete interactivo&lt;br /&gt;&lt;br /&gt;Variables&lt;br /&gt;  \prompt [TEXTO] NOMBRE  preguntar al usuario el valor de la variable&lt;br /&gt;  \set [NOMBRE [VALOR]]   definir variables internas,&lt;br /&gt;                          listar todas si no se dan parßmetros&lt;br /&gt;  \unset NOMBRE           indefinir (eliminar) variable interna&lt;br /&gt;&lt;br /&gt;Objetos Grandes&lt;br /&gt;  \lo_export LOBOID ARCHIVO&lt;br /&gt;  \lo_import ARCHIVO [COMENTARIO]&lt;br /&gt;  \lo_list&lt;br /&gt;  \lo_unlink LOBOID   operaciones con objetos grandes&lt;br /&gt;&lt;/span&gt;&lt;span style="font-weight: bold;font-family:arial;" &gt;&lt;br /&gt;&lt;br /&gt;listar usuarios postgres&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:arial;"&gt;select * from pg_user;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;font-family:arial;" &gt;crear usuario&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:arial;"&gt;createuser -A -d -P -h host -U usuario nuevo_usuario&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;font-family:arial;" &gt;cambiar contraseña usuarios&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:arial;"&gt;ALTER USER &lt;/span&gt;&lt;nombre usuarios=""&gt;&lt;span style="font-family:arial;"&gt; WITH PASSWORD &lt;/span&gt;&lt;nueva_contraseña&gt;&lt;span style="font-family:arial;"&gt;;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;font-family:arial;" &gt;borrar usuarios&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:arial;"&gt;$ dropuser -h host -U usuario usuario_borrar&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;font-family:arial;" &gt;crear base de datos&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-family:arial;"&gt;CREATE DATABASE nombre_base de datos WITH OWNER= nombre_usuario&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;a style="font-family: arial;" href="http://wiki.postgresql.org/wiki/Espa%C3%B1ol"&gt;wiki postgres español&lt;/a&gt;&lt;br /&gt;&lt;/nueva_contraseña&gt;&lt;/nombre&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5950429174584838030-5184413836735321396?l=caerices.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://caerices.blogspot.com/feeds/5184413836735321396/comments/default' title='Enviar comentarios'/><link rel='replies' type='text/html' href='http://caerices.blogspot.com/2009/06/trucos-basicos.html#comment-form' title='0 comentarios'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5950429174584838030/posts/default/5184413836735321396'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5950429174584838030/posts/default/5184413836735321396'/><link rel='alternate' type='text/html' href='http://caerices.blogspot.com/2009/06/trucos-basicos.html' title='Trucos básicos'/><author><name>caerices</name><uri>http://www.blogger.com/profile/17494035119607034630</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='24' height='32' src='http://3.bp.blogspot.com/_w44tDpxaU14/SjfWwlmjQ_I/AAAAAAAAAAY/GCvAuqbqu0o/S220/Cesar.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-5950429174584838030.post-7676017173488864804</id><published>2009-06-16T12:22:00.000-04:00</published><updated>2009-06-16T22:26:15.330-04:00</updated><title type='text'>Aumentar el rendimiento Postgres</title><content type='html'>&lt;meta equiv="CONTENT-TYPE" content="text/html; charset=utf-8"&gt;&lt;title&gt;&lt;/title&gt;&lt;meta name="GENERATOR" content="OpenOffice.org 3.0  (Win32)"&gt;&lt;style type="text/css"&gt; 	&lt;!-- 		@page { margin: 2cm } 		P { margin-bottom: 0.21cm } 	--&gt; 	&lt;/style&gt; &lt;p style="text-align: justify;"&gt;Muchas personas piensan que el aumento de rendimiento de una Base de Datos es sinonimo de CPU, es decir mientras mejor es la CPU mejor es el rendimiento. Esto no es cierto porque existen variantes más importantes que considerar al momento de tratar de sacar el mejor provecho a nuestra Base de Datos.&lt;br /&gt;&lt;/p&gt;&lt;ul style="text-align: justify;"&gt;&lt;li&gt;Para empezar se debe usar &lt;span style="font-style: italic; font-weight: bold;"&gt;Servidores Dedicados&lt;/span&gt; para Bases de Datos, muchas &lt;span style="font-style: italic;"&gt;pymes&lt;/span&gt; utilizan los Servidores como equipos de almaceanamiento, lo cual hace que un servidor llegue a ser Servidor de Archivo, Correo y Base de Datos al mismo tiempo, cuando fallan los sistemas siempre el culpable es la Base de Datos.&lt;/li&gt;&lt;/ul&gt;&lt;ul style="text-align: justify;"&gt;&lt;li&gt;Actualizar a la ultima version de postgres, siempre es importante ir actualizando los sistemas a la ultima version de Postgres (8.3 para produccion y 8.4 beta 2), para obtener un mejor rendimiento, superara lo bug y no tener que lamentar problema indeseados.&lt;/li&gt;&lt;/ul&gt;&lt;ul style="text-align: justify;"&gt;&lt;li&gt;Levantar un Servidor en linux, esta comprobado que Postgres obtiene el mejor rendimiento con los Sistemas Operativos LINUX, eso no quiere decir que en Windows esto funcione mal.&lt;/li&gt;&lt;/ul&gt;&lt;ul style="text-align: justify;"&gt;&lt;li&gt;La selección del tipo de disco a utilizar, es recomendable discos Duros de alto rendimiento ojalas en RAID o para las empresas pequeñas SATA.&lt;/li&gt;&lt;/ul&gt;&lt;ul style="text-align: justify;"&gt;&lt;li&gt;Utilizar la major cantidad de Memoria RAM posible.&lt;/li&gt;&lt;/ul&gt;&lt;ul style="text-align: justify;"&gt;&lt;li&gt;Separar el fichero de Datos y Log, en unidades de Disco diferentes.&lt;/li&gt;&lt;/ul&gt;&lt;ul style="text-align: justify;"&gt;&lt;li&gt;Para concluir es necesario que revisen los siguientes parametros&lt;/li&gt;&lt;/ul&gt;&lt;ol style="text-align: justify;"&gt;&lt;li&gt;&lt;span style="font-weight: bold;"&gt;max_connections&lt;/span&gt;: aplica la cantidad máxima de conexiones de clientes&lt;/li&gt;&lt;li&gt;&lt;span style="font-weight: bold;"&gt;shared_buffers&lt;/span&gt;: determina cuanta memoria está dedicada a PostgreSQL para datos en caché&lt;/li&gt;&lt;li&gt;&lt;span style="font-weight: bold;"&gt;effective_cache_size&lt;/span&gt;:Este debe ser establecido en un monto estimado de cuanta memoria está disponible para memoria intermedia en el disco para el sistema operativo&lt;/li&gt;&lt;li&gt;&lt;span style="font-weight: bold;"&gt;checkpoint_segments&lt;/span&gt;:PostgreSQL escribe las nuevas transacciones a la Base de Datos en un archivo llamado segmentos del WAL que son de 16MB de tamaño&lt;/li&gt;&lt;li&gt;&lt;span style="font-weight: bold;"&gt;autovacuum&lt;/span&gt;:Vaccum significa 'vaciar' literalmente hablando. El proceso de VACUUM lo que realiza es una limpieza de tuplas muertas que han sido marcadas como borradas o modificadas, ya que el motor de base de datos no las borra inmediatamente de la parte física para no sobrecargar las operaciones normales&lt;/li&gt;&lt;/ol&gt;&lt;div style="text-align: justify;"&gt;      &lt;br /&gt;para major informaión sobre estos parametros, diriguirse a &lt;a href="http://wiki.postgresql.org/wiki/Mejorando_el_rendimiento_de_tu_Postgresql_Server"&gt;wiki de postgres&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;Otros consejos para lograr una mejor optimización &lt;a href="http://www.postgresql.org/docs/8.3/interactive/populate.html#POPULATE-RM-INDEXES"&gt;aqui&lt;/a&gt; (esta en ingles)&lt;br /&gt;&lt;/div&gt;&lt;p style="font-weight: bold; text-align: justify;"&gt;&lt;span style="font-size:100%;"&gt;link interesantes:&lt;/span&gt;&lt;/p&gt;&lt;p style="text-align: justify;"&gt;&lt;a href="http://wiki.postgresql.org/wiki/Encontrando_consultas_que_consumen_recursos"&gt;Encontrando consultas que Consumen Recursos&lt;/a&gt;&lt;/p&gt;&lt;p style="text-align: justify;"&gt;&lt;a href="http://wiki.postgresql.org/wiki/Performance_Optimization"&gt;Optimización del rendimiento&lt;/a&gt; (esta en ingles)&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt; &lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5950429174584838030-7676017173488864804?l=caerices.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://caerices.blogspot.com/feeds/7676017173488864804/comments/default' title='Enviar comentarios'/><link rel='replies' type='text/html' href='http://caerices.blogspot.com/2009/06/algunos-consejos-generales-para.html#comment-form' title='0 comentarios'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5950429174584838030/posts/default/7676017173488864804'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5950429174584838030/posts/default/7676017173488864804'/><link rel='alternate' type='text/html' href='http://caerices.blogspot.com/2009/06/algunos-consejos-generales-para.html' title='Aumentar el rendimiento Postgres'/><author><name>caerices</name><uri>http://www.blogger.com/profile/17494035119607034630</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='24' height='32' src='http://3.bp.blogspot.com/_w44tDpxaU14/SjfWwlmjQ_I/AAAAAAAAAAY/GCvAuqbqu0o/S220/Cesar.jpg'/></author><thr:total>0</thr:total></entry></feed>
