Está en la página 1de 66

PostgreSQL

Capacitacin Nivel 1
Da 3

Agenda

Estructura del PGDATA.

Configuracin

Transacciones y bloqueos.

Control de concurrencia.

Catalogo. Estadsticas.

Consultas y lenguaje SQL para DBA.

Entendiendo el Explain.

Administracin de ndices.

Administracin de Large Objects.

Objetos del gestor.



Estructura del PGDATA

Foto del PGDATA

Archivos y Directorios

Archivos de configuracin

PG_VERSON

Otros Ficheros:

postmaster.pid: contiene el numero del PD del


servidor que pega al cluster.

postmaster.opts: opciones con las cuales arranca el


servidor.

Archivos y Directorios (2)

Base
Bases de datos y plantillas (Template0 y 1). Dentro se
encuentran las tablas e indices con sus
correspondientes ODs.

Global

Tablas e ndices comunes a todas las bases.


Catlogo compartido: pg_shadow (usuarios),
pg_database...
pgstat.stat (usado por el monitor de estadsticas)
pg_control: arch. Con param del Cluster.

pg_log

Generalmente es esta carpeta la que contiene los


logs del servidor.

Archivos y Directorios (3)

pg_xlog (WAL):

Diarios de escritura adelantada. Utilizada para


recuperaciones.

Conjunto de segmentos de un tamao de 16 MB y


divididos en pginas de 8KB.

Se van creando de acuerdo a las necesidades.

pg_clog

Ficheros de confirmacin

Guarda los estados de las transacciones.

pg_multixact

Utilizado para estados multitransaccionales, bloqueos


compartidos de filas.

Archivos y Directorios (4)

pg_twophase

Ficheros para el control de transacciones preparadas.

pg_subtrans

Para realizar savepoints dentro de transacciones.

pg_tblspc

nformacin de los tablespaces.

*nix contienen los links a los directorios.



Configuracin

postgresql.conf

General

shared_buffers

max_connections

temp_buffers

work_mem

max_fsm_pages y max_fsm_relations

WAL

Fsync

wal_buffers

archive_mode archive_command

postgresql.conf (2)

Query Tuning

Planner method (peuden ser seteados en


caliente)

Constantes de costo (para evaluar el Qpath)

Geqo

Loggin (opciones de log)

Runtime statistics

track_activities, log_parser_stats,
log_planner_stats, log_statement_stats, etc.

postgresql.conf (3)

Autovacuum (on -off)

Valores por defecto de coneccin cliente

search_path = '$user, schema'

Bloqueos

deadlock_timeout

max_locks_per_transaction
tener en cuenta que cada bloqueo consume ~270
bytes del shared_buffer por lo que existen
max_locks_per_transaction * (max_connections +
max_prepared_transactions)

pg_hba.conf

Database puede ser:


all, sameuser, samerole, un nombre de una base o un
listado separado por coma.

Usuario puede ser:


All, un nombre, un nombre de grupo (+ como prefijo) o
unlistado separado por coma. Puede incluir el nomre de
un archivo con @ para un listado.

CDR-Address puede ser:


Expresin que haga concordar con el host solicitante.
Esta compuesta por una P + CDR (numero entre 0 y 32
para pv4 y 0 a 128 para pv6) que especifica el numero
significativo de la mscara.

pg_hba.conf (2)

METHOD (mtodo) puede ser:


Trust (confiable), reject (rechazar), md5 (checksum),
crypt, password, gss, sspi, krb5 (kerberos), ident
(utiliza el archivo ident), pam, ldap. Password envia
en texto plano, por lo que no se recomienda. Md5
envia los passwords encriptados.

Option es el mapa de identificacin o el


nombre del servicio PAM, dependiendo el
mtodo.

Requiere reload para los cambios.



Todos en pg_hba.conf
Desde afuera con Pv4:
Host all all 0.0.0.0/0 trust
Desde afuera con pv6:
Host all all ::1/128 trust
Desde localhost:
Host all all 127.0.0.1/32 trust

Recomendacin

Tener en cuenta que:

Generalmente en aplicaciones web,


utilizamos 1 servidor o un cluster que se
conecta a la base. Conviene especificar esos
servidores uno por uno en vez de utilizar una
expresin.

Preferiblemente, asignar conexin usuario-


base, evitando 'all'. De esta manera
podremos tener superusuarios, sin acceso a
otras bases para visin de datos.

pg_ident.conf

Compuesto de MAPNAME, DENT-


USERNAME, PG-USERNAME.

MAPNAME es el nombre utilizado en el


pg_hba.conf

DENT-USERNAME el nombre del


usuario.

PG-USERNAME es el usuario en la base


de datos.

Requiere un reload para los cambios.



Transacciones y bloqueos

Que debe prevenirse:

Lectura sucia

La transaccin lee un dato que an no fue


comprometido por otra transaccin.

Lectura no repetida

Una transaccin relee un datos y encuentra que


este fue modificado por otra transaccin (y que fue
comprometida desde la lectura inicial).

Lectura fantasma

Una transaccin reejecuta una consulta


retornando un set de registros que satisfacen una
condicin y encuentran que ese set ha sido
modificado por otra reciente transaccin.

Niveles transaccionales de SQL
Isolation Level Dirty Read Nonrepeatable Read Phantom Read
R. uncommitted Possible Possible Possible
Read committed Not possible Possible Possible
Repeatable read Not possible Not possible Possible
Serializable Not possible Not possible Not possible
En Postgres se puede llamar a cual!uiera de estos pero solo dos tienen
e"ecto# Read commited y Serializable.
Por cuestiones de costo postgres!l no soporta blo!ueos en predicado
para el modo serializable.

Update perdido

Bloqueos explcitos: LOCK
(Nivel de tabla)
descripcin: Bloquea una tabla
Sintaxis:
LOCK [ TABLE ] name [, ...] [ N lockmode MODE ] [ NOWAT ]
Modo de bloqueo peude ser uno de los siguientes:
ACCESS SHARE | ROW SHARE | ROW EXCLUSVE | SHARE
UPDATE EXCLUSVE | SHARE | SHARE ROW EXCLUSVE |
EXCLUSVE | ACCESS EXCLUSVE

Modos de bloqueo
Es el que bloquea obsolutamente todos los modos de acceso.

Bloqueos explcitos:
Nivel de tupla

Automticamente se bloquea ante cualquier


modificacin. No afecta a las consultas, solo a
las actualizaciones.

SELECT . FOR SHARE [OF tabla NOWAT]

SELECT . FOR UPDATE [OF tabla NOWAT]



Deadlocks
Bloqueo mutuo entre dos transacciones.
Resultan a partir del bloqueo a nivel de tupla.
La mejor defensa contra este tipo de bloqueos es generalmente
evitarlos cerciorando que todas las aplicaciones udquieran los
bloqueos de varios objetos en orden consistente.
UPDATE accounts
SET balance = balance + 100.00
WHERE acctnum = 11111;
UPDATE accounts
SET balance = balance + 100.00
WHERE acctnum = 22222;
UPDATE accounts
SET balance = balance + 100.00
WHERE acctnum = 22222;
UPDATE accounts
SET balance = balance + 100.00
WHERE acctnum = 11111;

Advisory Locks

Duran hasta finalizar la sesin o ser liberados explcitamente.

Pueden ser vistas en la vista de sistema pg_locks.

Se configura a traves de max_locks_per_transaction y


max_connections
SELECT pg_advisory_lock(id) FROM foo WHERE id = 12345; -- ok
SELECT pg_advisory_lock(id) FROM foo WHERE id > 12345 LMT 100; -- danger!
SELECT pg_advisory_lock(q.id) FROM
(
SELECT id FROM foo WHERE id > 12345 LMT 100;
) q; -- ok

Bloqueos e ndices

Los ndices B-tree ofrecen la mejor


performance para aplicaciones
concurrentes

Tienen mayores prestaciones que los


ndices por hash.

Para datos NO escalares, es preferible


utilizar GiST o GN.

Catalogo y estadsticas.

System tables

System tables pg_catalog

Todas comienzan con pg_


pg_aggregate pg_index pg_shdepend pg_stat_user_indexes
pg_am pg_indexes pg_shdescription pg_stat_user_tables
pg_amop pg_inherits pg_stat_activity pg_tables
pg_amproc pg_language pg_stat_all_indexes pg_tablespace
pg_attrdef pg_largeobject pg_stat_all_tables pg_temp_1.
pg_attribute pg_listener pg_stat_bgwriter pg_timezone_abbrevs
pg_authid pg_locks pg_stat_database pg_timezone_names
pg_auth_members pg_namespace pg_statio_all_indexes pg_toast.
pg_autovacuum pg_opclass pg_statio_all_sequences pg_toast_temp_1.
pg_cast pg_operator pg_statio_all_tables pg_trigger
pg_catalog. pg_opfamily pg_statio_sys_indexes pg_ts_config
pg_class pg_pltemplate pg_statio_sys_sequences pg_ts_config_map
pg_constraint pg_prepared_statements pg_statio_sys_tables pg_ts_dict
pg_conversion pg_prepared_xacts pg_statio_user_indexes pg_ts_parser
pg_cursors pg_proc pg_statio_user_sequences pg_ts_template
pg_database pg_rewrite pg_statio_user_tables pg_type
pg_depend pg_roles pg_statistic pg_user
pg_description pg_rules pg_stats pg_views
pg_enum pg_settings pg_stat_sys_indexes
pg_group pg_shadow pg_stat_sys_tables

nformation Schema

Se incluye para compatibilidad con el


standart.

Explain es tu amigo

Permite ir ms all de ejecutar consultas.

Ayuda a comprender que es lo que puede


estar fallando del servidor.

No siempre la consulta ms elegante es la


ms performante :)

Este comando permite visualizar y


entender cual es la forma en que el
optimizador analiza y devuelve los
resultados.

Es de gran ayuda cuando queremos ver


posibles defectos en la arquitectura de
nuestra base de datos.
EXPLAN - Resume

Sintxis
# EXPLAN [ANALYZE] [VERBOSE] <query>
nsert
Update
select

Conceptos bsicos

Coste

Operador

Tiempo (no vamos a entrar en explicaciones filosficas de que es esto :)

Tamao de datos (esto podra tener una explicacin ms extensa , pero es


entendible de solo pensar en ella)

Cost

Cost( 1ra fila . ultima) de acuerdo a


valores de coste explcitos en el
postgresql.conf

Operadores

Seq Scan

ndex scan

Sort (*work_mem)

Unique

Limit

Aggregate

Append

Result

Nested Loop

Merge Join

Hash and Hash Join

Group

Subquery Scan and


Subplan

Tid Scan (raro)

Materialize

EXPLAN vs EXPLAN ANALYZE

+ operadores
select *
from accounts a, history h
where a.aid = h.aid;

Manipulando el optimizador

Desactivamos la bsqueda por escaneo de


ndices?

Estadsticas

El catlogo contiene las estadsticas de


acceso , campos frecuentes y dems de todos
los objetos del CLUSTER.

Ejemplo de uso de
estadsticas

Tener en cuenta de tener las estadsticas bien


actualizadas (ANALYZE y VACUUM).

Frecuencia de valores
A mayor frecuencia de aparicin,
favorecer que el
optimizador opte por el seqscan
Por sobre otros operadores :O

Cantidad de valores
distintos

Tunning estadsticas

Permite mayor recoleccin de estadsticas


para una determinada columna.

De esta forma, campos nmericos pueden


ser medidos de manera ms detallada.
ALTER TABLE chares ALTER COLUMN texto SET STATSTCS
10;

/O por objeto
pg_statio_all_indexes
pg_statio_sys_indexes
pg_statio_user_indexes
pg_statio_all_sequences
pg_statio_sys_sequences
pg_statio_user_sequences
pg_statio_all_tables
pg_statio_sys_tables
pg_statio_user_tables

Administracin de ndices

ndices tipos

Btree (rbol balanceado)

Gin (mejor para texto, ex R-


tree)

GST (datos complejos)

Hash (con algunos


problemas an |
recomendado para
columnas UNQUE)

Comunes

Por expresion o
funcionales
CREATE NDEX ix_accounts1 ON accounts
USNG hash (aid) tablespace ts_indices;
CREATE NDEX ix_accounts1 ON accounts
USNG hash (aid) tablespace ts_indices;

ndices funcionales
CREATE NDEX ix_chares_func ON chares
(hashtext(texto));

ncidencia de NULLs en ndices
parapruebas$% update chares set te&to $ N'LL (here te&to ) *+,-,./.01*2

Performance

Tablespaces dedicados a objetos.

RAD si o si en servidores.

Economa? RAD0 con PTR.

Bases chicas, normalizar en buen nivel y


redundar informacin con vistas materializadas.

Despus de grandes cambios en los datos,


correr VACCUM y ANALYZE.

CREATE TABLE AS o CLUSTER permitir que


las lecturas en los ndices ms rpida.

Performance (2)

nfluencie el optimizador para detectar posibles


discrepancias en el resultado a travs de las
variables CPU_NDEX_TUPLE,
CPU_OPERATOR_COST, CPU_TUPLE_COST,
EFFECTVE_CACHE_SZE,
RANDOM_PAGE_COST.

Minimice la carga de red y de las mquinas locales


haciendo la mayor parte del trabajo en el servidor.
Esto incluye los procedimientos, funciones,
disparadores.

Performance (3)

Prefiera utilizar multinucleos para Postgres, el


sistema de forks permite una distribucin en
los recursos.

Si utiliza 'large objects' realice seguido


vacuum_lo (incluido en los contrib).

Trate de utilizar FreeBSD para sistemas


medianos y Solaris para sistemas de buenos
recursos.

PL/Perl es un exelente lenguaje para realizar


tareas complejas y eficientes.

PGBENCH

PyTest (por Mariano Reingart y ecFranco)
import psycopg2
import MySQLdb
from threading import Thread
from time import time
import sys
class Benchmarknsert(Thread):
"Hilo para timing de NSERT"
def __init__(self, connect, nro):
Thread.__init__(self)
self.nro = nro # nro de thread
self.connect = connect # funcion de conexin (mysql o pg)

def run(self):
cn = self.connect()
cur = cn.cursor()
for x in range(10000):
cur.execute("NSERT NTO prueba (texto, entero, flotante) VALUES (%s,%s,%s)", ("hola %s" % x, int(x), float(x/100.0)))
cn.commit()
cn.close()
class BenchmarkSelect(Thread):
"Hilo para timing de SELECT"
def __init__(self, connect, nro):
Thread.__init__(self)
self.nro = nro # nro de thread
self.connect = connect # funcion de conexin (mysql o pg)

def run(self):
cn = self.connect()
cur = cn.cursor()
cur.execute("SELECT * FROM prueba")
for row in cur:
#print self.nro, row
pass
cn.close()

PyTest (2)
class BenchmarkSelectJoin(Thread):
"Hilo para timing de SELECT"
def __init__(self, connect, nro):
Thread.__init__(self)
self.nro = nro # nro de thread
self.connect = connect # funcion de conexin (mysql o pg)

def run(self):
cn = self.connect()
cur = cn.cursor()
for x in xrange(10000):
cur.execute("SELECT * FROM prueba as p1 NNER JON prueba as p2 WHERE p1.id=p2.flotante WHERE p1.text ", ("hola %s" % x,))
for row in cur:
#print self.nro, row
pass
cn.close()
def bench(cant,connect, benchmark):
"Funcion de benchmark, recibe cantidad de threads a crear, funcin de conexion y clase benchmark"
threads = []
for i in range(cant):
thread = benchmark(connect, i) # creo el thread de test
threads.append(thread)
thread.start()
#print "Threads startedok"
for thread in threads:
# wait until it terminates
thread.join()
#print "Threads killed ok"

PyTest (3)
myconnect = lambda: MySQLdb.connect(db="benchmark", user="root", passwd="m" ,host="localhost")
pgconnect = lambda: psycopg2.connect(database="benchmark", user="postgres", password="m", host="localhost")
tests = (
('mysql-select', BenchmarkSelect, myconnect),
('pgsql-select', BenchmarkSelect, pgconnect),
# ('mysql-insert', Benchmarknsert, myconnect),
# ('pgsql-insert', Benchmarknsert, pgconnect),
)
for db, benchmark, connect in tests:
print "populando para benchmark %s" % db
cn = connect()
cur = cn.cursor()
cur.execute("DELETE FROM prueba")
for x in range(1000):
cur.execute("NSERT NTO prueba (texto, entero, flotante) VALUES (%s,%s,%s)", ("hola %s" % x, int(x), float(x)))
print "ejecutando benchmark %s" % db
cn.commit()
cn.close()
out = open("%s.csv" % db,"w")
for i in range(1,int(sys.argv[1])):
t0 = time()
bench(i, connect, benchmark)
t1 = time()
print "%s,%d,%f" % (db, i, t1-t0)
out.write("%s,%d,%f\n" % (db, i, t1-t0))
#create table prueba (id serial primary key, texto text, flotante float, entero integer, fecha timestamp DEFAULT now());
#create table prueba (id integer auto_increment primary key,
# texto text, flotante float, entero integer, fecha timestamp DEFAULT now()) engine=innodb;
#create index prueba_float on prueba(flotante);
#create index prueba_text on prueba(texto);

Administracin de Large Objects

Funciones para LO
List of functions
Schema | Name | Result data type | Argument data types
------------+-------------+------------------+---------------------------
pg_catalog | lo_close | integer | integer
pg_catalog | lo_creat | oid | integer
pg_catalog | lo_create | oid | oid
pg_catalog | lo_export | integer | oid, text
pg_catalog | lo_import | oid | text
pg_catalog | lo_lseek | integer | integer, integer, integer
pg_catalog | lo_open | integer | oid, integer
pg_catalog | lo_tell | integer | integer
pg_catalog | lo_truncate | integer | integer, integer
pg_catalog | lo_unlink | integer | oid

Vacuum_lo

Existe un contrib para realizar vaciamiento


de LO hurfanos.

vacuumlo -Uuser base



En detalle
-- Tabla de imgenes
CREATE TABLE misimagenes (
title TEXT NOT NULL primary key,
picture OD);

-- magen de rosas rojas est en el servidor. Cargar y exportar una copia al servidor.
NSERT NTO misimagenes (title, picture)
VALUES ('Rosas Rojas', lo_import('/tmp/rosas_rojas.jpg'));
SELECT lo_export(picture, '/tmp/rosas_rojas_copia.jpg') FROM misimagenes
WHERE title = 'Rosas Rojas';

-- magen de rosas blancas est en el cliente
-- Cargar y exportar una copia al cliente.
\lo_import '/tmp/rosas_blancas.jpg'
NSERT NTO misimagenes (title, picture) VALUES ('Rosas Blancas', :LASTOD);

SELECT * from misimagenes;
-- title | picture
-- -------------+---------
-- Red Roses | 3715516
-- White Roses | 3715518
-- (2 rows)

\lo_export 3715518 '/tmp/rosas_blancas_copia.jpg'

En detalle ++
CREATE RULE droppicture AS ON DELETE TO misimagenes
DO SELECT lo_unlink( OLD.picture );
CREATE RULE reppicture AS ON UPDATE TO misimagenes
DO SELECT lo_unlink( OLD.picture ) where OLD.picture <> NEW.picture;
Como listo los objetos? lo_list desde el psql!
CREATE TABLE image (
name text,
raster oid );
SELECT lo_creat(-1); -- returns OD of new, empty large object
SELECT lo_create(43213); -- attempts to create large object with OD 43213
SELECT lo_unlink(173454); -- deletes large object with OD 173454
NSERT NTO image (name, raster)
VALUES ('beautiful image', lo_import('/etc/motd'));
SELECT lo_export(image.raster, '/tmp/motd') FROM image
WHERE name = 'beautiful image';

bytea
CREATE TABLE connectby_bytea(keyid bytea, parent_keyid bytea, pos int);
copy connectby_bytea from stdin;
row\\001 \N 0
row\\002 row\\001 0
row\\003 row\\001 0
row\\004 row\\002 1
row\\005 row\\002 0
row\\006 row\\004 0
row\\007 row\\003 0
row\\010 row\\006 0
row\\011 row\\005 0
\.
Create table foo (d bytea);
nsert into foo('asdfasfasdf23523#$&%/$%#$%!#/&%UYT//');
BLOB'S ---> USE TOAST!!!!

Objetos del motor

Links

explain.depesz.com

</Da 3>
Gracias!

También podría gustarte