Friday, May 16, 2014

Estamos quase lá... 9.4 beta 1

Ontem (15/05) foi anunciado o lançamento da primeira versão beta do PostgreSQL 9.4. Uma versão beta do PostgreSQL é quase a versão final. Ainda falta aparar algumas arestas... Daqui a alguns meses, a porteira se fecha (ou melhor dizendo, se abre). Se você se interessar por algumas das novas funcionalidades, agora é a hora de começar a descobrir as suas potencialidades. Se você já estiver planejando uma mudança de versão, esta é a hora de descobrir o que mudou (e se for o caso, adequar suas aplicações) ou mesmo reportar alguma regressão de performance de alguma consulta.

As principais funcionalidades são:
  • JSONB: um novo tipo de dados para armazenar JSON. Espere aí... o Postgres já tem um tipo JSON? Sim, mas este novo tipo usa um formato de armazenamento que é performático e ainda vem com suporte a indexação e contém vários operadores e funções;
  • Replicação: uma nova API para decodificação e transformação das mudanças ocorridas no banco de dados. Trocando em miúdos, uma API que permite a construção de um plugin para replicação lógica. Espera-se que algumas das soluções de replicação que utilizam comandos passem a adotar essa API por ser mais performática e não precisar de objetos adicionais (ex.: gatilhos). Eu fiz o plugin wal2jon (monta objetos JSON com dados das mudanças realizadas) para demonstrar as funcionalidades da API e também ouvi rumores que o Slony-I passará a utilizar tal API;
  • Visão Materializada: o REFRESH não mais bloqueia as leituras;
  • ALTER SYSTEM: um novo comando SQL que permite alterar o postgresql.conf. Os desenvolvedores de aplicativos que precisam alterar parâmetros em dezenas, centenas ou mesmo milhares de servidores vão adorar esta facilidade;
  • background worker: uma nova API que permite ter processos filho do processo principal. Podemos registrar, iniciar e parar esses processos. Com isso, poderemos escrever um agendador ou alguma rotina de consolidação periódica que trabalha "anexado" ao serviço do postgres.
Algumas melhorias que também merecem destaque são:
  • acelerar buscas e redução do tamanho de índices GIN;
  • melhorar performance de funções de agregação;
  • melhorar escalabilidade de escrita;
  • diminuir nível de bloqueio em alguns comandos ALTER TABLE;
  • novo parâmetro autovacuum_work_mem para controlar memória utilizada por um processo do autovacuum (antigamente era utilizado o maintenance_work_mem);
  • os parâmetros work_mem, maintenance_work_mem e effective_cache_size sofreram aumento em seus valores padrão;
  • atrasar replicação (foi uma das funcionalidades que o Fabrizio tirou do forno);
  • EXPLAIN ANALYZE apresenta tempo gasto para planejamento da consulta;
  • ALTER TABLESPACE ... MOVE move objetos de uma tablespace para outra;
  • opção --analyze-in-stages do vacuumdb executa ANALYZE em três estágios com diferentes configurações para produzir estatísticas úteis rapidamente (útil para colocar o banco rapidamente em produção);
  • pg_basebackup permite realocar o diretório do pg_xlog;
  • pg_basebackup permite controlar a taxa de transferência do cópia física;
  • aplicativo pg_prewarm carrega dados de tabelas na cache do postgres (shared buffers);
  • pg_stat_statements passa a armazenar consultas em um arquivo reduzindo a limitação do tamanho das consultas e permitindo um número maior de consultas únicas.
A cada versão há inúmeras mudanças internas, portanto, é de fundamental importância que você nos ajude a ter a versão 9.4 (quase) sem bugs. Leia as notas de lançamento para saber das novidades e, principalmente, das incompatibilidades. Faça o download do beta 1 e teste-o no seu ambiente. Reporte os sucessos e os insucessos. Quanto mais erros conseguirmos corrigir durante o beta melhor será a primeira versão da série 9.4. Já existe até pacotes para Debian e derivados disponíveis.

Bons testes!

Monday, September 9, 2013

O que esperar da versão 9.3

A aproximadamente 4 meses atrás eu anunciei a primeira versão beta da versão 9.3. De lá para cá, a versão foi polida para que a primeira versão (9.3.0) chegasse ao mercado com o mínimo de bugs possível. Hoje foi o dia do laçamento desse tão esperada versão. Confira o kit de impressa (*) sobre as funcionalidades mais esperadas dessa nova versão.

Eu gostaria de ressaltar aqui algumas funcionalidades que vão turbinar o desenvolvimento de novas aplicações e/ou facilitar a vida dos DBAs:

1) junções laterais: é uma funcionalidade do padrão SQL que permite que uma subconsulta prefixada com LATERAL possa referenciar colunas de tabelas que estão a esquerda da subconsulta. No exemplo abaixo, m.departamento só pode ser utilizado graças ao LATERAL.

euler=# SELECT nome,salario, media_salario FROM instrutor AS m, LATERAL(SELECT avg(salario) AS media_salario FROM instrutor n WHERE m.departamento = n.departamento) x;
  nome  | salario | media_salario
--------+---------+---------------
 euler  | 5023.58 |       3842.04
 joao   | 1058.21 |       1308.21
 maria  | 1558.21 |       1308.21
 jose   | 3758.82 |       3842.04
 marcos | 2743.72 |       3842.04
(5 registros)
2) adaptadores de dados externos graváveis: a funcionalidade conhecida como FDW (abreviação de Foreign Data Wrappers) está presente no Postgres desde a versão 9.1. No entanto, tabelas externas não podiam receber modificações (eram somente leitura). Nesta versão foi implementado a escrita e também um novo módulo (postgres_fdw) que vem para substituir o bom e velho dblink. Vale ressaltar que o postgres_fdw em relação ao dblink, possui mais funcionalidades, é mais robusto e transparente além de possuir sintaxe compatível com padrão SQL. Esta funcionalidade vem para facilitar de uma vez por todas o trabalho com bases de dados federadas, ou seja, o desenvolvedor não precisa se preocupar com API de acesso aos seus n SGBDS, basta que ele se conecte ao Postgres que o mesmo fará o acesso aos dados externos para você.

3) memória compartilhada: é comum que novatos no Postgres se deparem com aquele erro clássico "could not create shared memory segment" (principalmente no Linux cuja quantidade de memória compartilhada padrão por usuário é muito baixa -- cerca de 32MB) que aparece quando se tenta aumentar o número de conexões ou o parâmetro shared_buffers. Com uma nova implementação, raramente você precisará fazer o ajuste dos parâmetros do kernel (SHMMAX, SHMALL).

4) gatilhos de eventos: era comum a queixa sobre gatilhos em comandos DDL (CREATE, ALTER, DROP). Principalmente por aqueles interessados em replicação por comandos. A partir de agora, eventos poderão ser diparados ao executar DDLs. Veja um exemplo abaixo:

euler=# CREATE OR REPLACE FUNCTION mensagem() RETURNS event_trigger AS $$
euler$# BEGIN
euler$#     RAISE NOTICE 'msg: % %', tg_event, tg_tag;
euler$# END;
euler$# $$ LANGUAGE plpgsql;
CREATE FUNCTION
euler=# CREATE EVENT TRIGGER mensagem ON ddl_command_start EXECUTE PROCEDURE mensagem();
CREATE EVENT TRIGGER
euler=# create table foo (a int);
NOTA:  msg: ddl_command_start CREATE TABLE
CREATE TABLE
euler=# drop table foo;
NOTA:  msg: ddl_command_start DROP TABLE
DROP TABLE
5) bloqueios: um novo parâmetro (lock_timeout) permite especificar quanto tempo uma sessão esperará por um bloqueio (lock) antes de cancelar o comando. Uma outra funcionalidade importante para concorrência, é permitir que verificações de chave estrangeira não sejam bloqueadas por comandos UPDATE que não atualizam a chave primária da tabela referenciada (não é necessário configurar nada para que isso ocorra).

6) monitoramento: o arquivo contendo as estatísticas do Postgres foi dividido para reduzir a quantidade de I/O em agrupamentos de banco de dados que possuem milhares de objetos. Foi adicionado uma nova opção (só pode ser definida ao criar o agrupamento e não pode ser desabilitada) para fazer a verificação de páginas de dados (também conhecido como checksum); a ideia é detectar rapidamente falha de discos ou hardware com problemas (memória, controladora, etc).

7) replicação: uma das funcionalidades mais esperadas nesta área é a habilidade em detectar mudança de linha do tempo e seguí-la. Explico, se você possui 3 servidores (A, B e C) com o cenário no qual A envia dados para B e B envia dados para C (A -> B -> C). Se ocorrer uma falha em A e você tiver que promover B a servidor principal, você não precisará refazer o servidor C. Isso diminui a complexidade em ambientes de alta disponibilidade.

8) visões: visões materializadas. Isso mesmo! A tão esperada funcionalidade foi implementada com algumas limitações (não suporta atualizações automáticas e as atualizações descartam todos os dados ao invés de atualizações incrementais). Apesar das limitações, a funcionalidade é bastante útil em vários cenários de data warehouse. Melhorias virão nas próximas versões.

9) JSON: o suporte a esse tipo de dado foi incluída na versão 9.2 com promessa de melhorias nas versões subsequentes. Algumas das melhorias já vieram na 9.3 com a adição de várias funções e operadores para facilitar a manipulação de dados nesse formato.

10) psql: duas funcionalidades chamaram a minha atenção. A primeira delas é o novo comando \watch que torna possível a execução do último comando a cada n segundos (útil para algum monitoramento). A segunda é a saída formatada em LaTeX utilizando o pacote longtable (os meus relatórios esperavam ansiosamente por esta funcionalidade :-).

11) pg_dump: o pg_restore já suportava o paralelismo desde a versão 8.4; esta foi a vez do pg_dump. Pela falta de um mecanismo para exportar a snapshot (para que todos os processos de trabalho possam "enxergar" os mesmos dados) e um formato (de diretório) que pudesse armazenar objetos individuais (vários arquivos), o pg_dump tinha que ser executado por somente um processo. Como no pg_restore, você poderá especificar a opção --jobs para distribuir a carga do pg_dump entre vários processos auxiliares e realizar cópias de segurança em um tempo menor.

12) processos de trabalho: conhecido como background workers, permitirá o desenvolvimento de processsos auxiliares (que são processos filho do postgres). Isso quer dizer que podemos desenvolver um agendador, manipulador de requisições e quaisquer outras tarefas auxiliares ao PostgreSQL. A ideia ter algo integrado ao SGBD.

(*) se alguém da impressa estiver interessado em produzir algum texto ou mesmo pedir orientação/revisão sobre o lançamento da 9.3, entre em contato comigo (que sou o contato regional).

Monday, May 13, 2013

PostgreSQL 9.3beta1 foi lançado

Hoje foi lançado o primeiro beta1 da versão 9.3. Esta fase de pré-lançamento é muito importante para a comunidade. Com testes de milhares de pessoas (incluindo você), os desenvolvedores podem ter um retorno das novas funcionalidades bem como das modificações que foram feitas. Eventualmente, alguns bugs e/ou regressões de performance serão reportados. Quanto mais testes vocês fizerem mais estável será a primeira versão da série 9.3.

É importante que vocês façam testes dos seus sistemas com a 9.3 para se certificar que nenhuma regressão foi introduzida nessa nova versão. Não se esqueça de testar as novas funcionalidades tais como visões materializadas, funções para manipulação de JSON e pg_dump paralelo para cópia de segurança mais rápida. A lista completa de funcionalidades está disponível nas notas de lançamento.

Se você possui um hardware/sistema operacional diferente daqueles que estão na PostgreSQL BuildFarm, teste a versão 9.3 e reporte isso na pgsql-hackers.

A cópia do código-fonte ou binário pode ser feito na página de downloads ou no repositório de sua distribuição preferida (caso ela já tenha disponibilizado). A documentação completa sobre cada funcionalidade já está disponível.


A partir de agora, não haverá mudanças substanciais (nenhuma funcionalidade nova será introduzida) na versão 9.3 então é seguro começar a desenvolver uma aplicação com as funcionalidades disponíveis.


É claro que ainda não é seguro utilizar esta versão beta1 em produção.

Bons testes!

Wednesday, February 20, 2013

PGBR 2013: Call for Papers

PGBR is the major portuguese-speaking PostgreSQL conference. It is the biggest PostgreSQL event in Americas. We're in the fifth edition. This year the conference will be outside Sao Paulo State. It will take place at Amazon Area (Porto Velho, Rondônia). It is scheduled to be held from August 15 to 17, 2013.

I was at Porto Velho for a PGDay 2009 -- invited by Luis Bueno. It was a unique opportunity to meet people that I've never imagined that was using Postgres in their projects. Of course, I can't miss a ride in Rio Madeira waters and relish a typical fish in a sauce.

Be sure to submit your proposals until March, 15, 2013 at 23:59 BRST (for foreigners) and May, 3, 2013 (for residents). Check the CFP at http://pgbr.postgresql.org.br/2013/chamada.en.php. The proposals could be in three languages: Portuguese, English or Spanish  Also, you can choose among lecture, tutorial, hacker talk, lighting talk and academic panel (only in Portuguese).

New this year, we are having training courses taught by well-known community members.

Stay tuned!

Wednesday, November 9, 2011

Understanding WAL nomenclature

There are some PostgreSQL functions that reports an information such as 68A/16E1DA8. But what does it mean? The documentation states that it is a transaction log location. Let me try to explain it in details.

What is WAL? WAL is an abbreviation of Write-Ahead Log. That is how PostgreSQL named the transaction log (also known as REDO log). Every modern database system has one. It is basically a history of operations that was executed by a DBMS. It improves performance (you only need to flush one file per transaction) and guarantees ACID properties (if the DBMS was in an inconsistent state -- because of software crash, for example -- it reapplies all transactions that are committed but whose changes are not in the database files). PostgreSQL introduced the transaction log in version 7.1 (2001). It opted to implement only REDO log (there is no UNDO log on PostgreSQL).

The transaction log files are stored in $PGDATA/pg_xlog directory. They are named as 000000020000070A0000008E. They are all hexadecimal digits (0123456789ABCDEF). The first 8 digits identifies the timeline, the following 8 digits identifies the (logical) xlog file and the last ones represents the (physical) xlog file (aka segment). The physical files in pg_xlog directory are not actually the xlog files; PostgreSQL calls it segments. By default, a logical xlog file has 255 segments (16 MB each, 4080 MB in total) So in our example, the 0000070A and 0000008E are the logical xlog file and segment file, respectively. When segment file 000000FE is filled up the logical xlog file is incremented by 1 (i.e. 0000070B) and the segment file sequence starts up again (i.e. 00000000) -- 000000020000070B00000000.

What means 68A/16E1DA8? 68A is the (logical) xlog file and 16E1DA8 is the offset inside the logical xlog file. It means that the offset goes from 00000000 to FF000000 (4278190080 bytes = 4080 MB). When it reaches FF000000, it means we are in the last segment (aka physical xlog file) and the xlog file number will be incremented by 1 (i.e. 68B) and the offset will be restarted (00000000).

PostgreSQL provides a set of functions [1] [2] that deals with the transaction log location. For example, converting transaction log location to segment file name:

postgres=# select pg_xlogfile_name('68A/16E1DA8');
     pg_xlogfile_name  
--------------------------
 000000020000068A00000001
(1 row)

Converting transaction log location to segment file name and the offset inside that segment.

postgres=# select * from pg_xlogfile_name_offset('68A/16E1DA8');
        file_name         | file_offset
--------------------------+-------------
 000000020000068A00000001 |     7216552
(1 row)


If I want to know which segment file the PostgreSQL server is writing the transaction log now:

postgres=# select pg_xlogfile_name(pg_current_xlog_location());
     pg_xlogfile_name  
--------------------------
 000000020000074B000000E4
(1 row)


If you have a replication scenario, you can obtain the receive and replay lags. It is a simple hexadecimal math: master transaction log location minus replica transaction log location.

In the replica:

postgres=# select pg_last_xlog_receive_location();
 pg_last_xlog_receive_location
-------------------------------
 74B/E4D1C628
(1 row)

postgres=# select pg_last_xlog_replay_location();
 pg_last_xlog_replay_location
------------------------------
 74B/E4D1C628
(1 row)

In the master:

postgres=# select pg_current_xlog_location();
 pg_current_xlog_location
--------------------------
 74B/E4D3B070
(1 row)

If they report the same xlog file (74B), it is a matter of E4D3B070E4D1C628 = 1EA48 (125512 bytes). It means that the replica is roughly 123 kB behind the master. Receive and replay locations aren't the same all the time; if the replica can't keep up with writing receive location > replay location.

What about different xlog files? Some tools use the following formula:

(FFFFFFFF * xlog_master + offset_master) - (FFFFFFFF * xlog_replica + offset_replica)

It's wrong ¹. Why? Because the offset goes up to FF000000 (and not FFFFFFFF). It means that the above formula reports 16 MB times the difference between xlog numbers when the xlog numbers aren't the same. The correct formula is:

(FF000000 * xlog_master + offset_master) - (FF000000 * xlog_replica + offset_replica)

Let's suppose the master and replica transaction location are 67E/AFE198 and 67D/FECFA308, respectively. The correct lag is 14696080 bytes and not 31473295 bytes (the difference between results is 16 MB!).


¹ I will send patches to fix check_postgres and Munin. If you know another tool that is using the wrong formula, let me know or even better, the tool's author. FYI, both tools were fixed in a few hours. Thanks, Greg and Magnus!

Tuesday, November 8, 2011

PGBR 2011 is over

PGBR 2011 is over. It was a challenge to organize an event after 2 years and with a budget 50% higher than the last conference. Yes, we did it! It was an event organized by the community to the community. Thanks to our Kahunas (Fabio Telles and Flavio Gurgel) and our sponsors.

This year we had participants from another countries (Argentina, Peru, and USA). We are planning a better support from website and registration next year (sorry Joe). Also, some foreign speakers: Alvaro (Chile), Bruce Momjian (USA), Dave Page (UK), Greg Smith (USA), Jaime Casanova (Ecuador), and Koichi Suzuki (Japan).

I don't have the definitive numbers yet but we had roughly 250 participants from the 5 regions of Brazil. I talked to a lot of participants that bring to me interesting success stories from their companies. One of the many interested success cases I heard of was from Locaweb (hosting company) that migrated its DNS infrastructure from M$ database to PostgreSQL.

We had three rooms, 29 sessions (4 sessions from Timbira) and a lot of new speakers. In the first day I was at room 1 because I was coordinating the sessions along the day. I had the opportunity to listen Alvaro and Greg talking about locks and benchmarks, respectively. Also, I was in the round table about PostgreSQL service opportunities in Brazil. In the second day, I attended to Jaime's talk (repmgr) and Dickson's (extensions). At this year, I decided to submit a newbie tutorial that answers the frequently asked questions in the PostgreSQL mailing lists. Title is Everything you want to know about PostgreSQL but were afraid to ask. It was a challenge to keep the audience awake (1 hour and a half) after the lunch but I think I got it. Oh, I lost the Dojo (because it conflicted with my session). :( The last session I attended was that of Lucio. After that the awards. For the first time, brazilian community has decided to reward prominent members of the community. We had 5 categories (I was nominated in 4) and got one. Thanks for reconnaissance! The last session was the always-funny-session: lightning talks. 8 LTs with speak^H^H^H^H^Hstand-up comedians who entertained the participants (@lhcezar will stop working with databases and will start a career as singer).

Thumbs up to: local (hotel), coffee-break and beer (200 liters).

Hope to see you again next year!

Wednesday, September 14, 2011

Hora de considerar a versão 9.1?

Ao ler o post do Greg, resolvi apresentar a minha opinião sobre o $TITULO. É bom ser cauteloso quando estamos lidando com nossos dados. Mas será que devemos esperar quanto tempo antes de considerar uma atualização para uma versão mais nova?

Quando estamos lidando com versões antigas de uma tecnologia sempre nos deparamos com desenvolvedores de aplicações que estão tentando utilizar as últimas funcionalidades que o software oferece. No universo do PostgreSQL, isso não é diferente; há sempre uma nova função, uma sintaxe diferente, a otimização de um tipo de consulta, um novo tipo de índice e por aí vai.

Além disso, os DBAs enfrentam no dia-a-dia as limitações de uma versão que vai se tornando obsoleta ao longo dos anos (tenho clientes utilizando a versão 8.1 e que ainda sofrem dos picos de escrita durante o checkpoint). Os DBAs são os profissionais mais cautelosos dentre aqueles que administram serviços; mesmo assim, consideram atualizar entre versões para (i) diminuírem a dor de cabeça com as limitações pré-existentes e (ii) beneficiarem das novas otimizações e oportunidades (de ajuste e monitoramento).

Voltando a questão da versão, o PostgreSQL sempre considera novas versões aquelas que mudam o X e/ou Y em X.Y.Z (o Z é reservado para correção de bugs). Assim, os primeiros lançamentos das novas versões são 7.4.0, 8.0.0, 8.1.0, 8.2.0, 8.3.0, 8.4.0, 9.0.0, 9.1.0 (preferem omitir o .0 pois afinal de contas, uma vez na versão X.Y os binários podem ser atualizados para Z+n sem precisar fazer uma migração entre versões -- cópia de segurança -> restauração ou pg_upgrade). Dentre os lançamentos mencionados há uma diferença: aqueles que mudam o X e os que não mudam. É uma diferença na qualidade? Não. A mudança no X ocorre quando há um grande número de funcionalidades impactantes em uma nova versão com relação as anteriores. Foi assim da 7.4 -> 8.0 (suporte a Windows, tablespaces, PITR, savepoints) e da 8.4 -> 9.0 (replicação embutida, Hot Standby, bloco de código anônimo aka DO).

Olhando do ponto de vista de evolução de um software, mais mudanças código geram mais bugs! Então para aqueles DBAs mais cautelosos eu não aconselho que migrem rapidamente quando o X mudar. Costumo aconselhar que esperem alguns lançamentos de versões de correção (talvez 3 ou 4) para pensar em adotá-las. Quando quem muda é o Y, o conselho é esperar 1 ou duas versões de correção. Geralmente, logo após o lançamento de uma versão (como foi o caso da 9.1 recentemente), o grupo de desenvolvimento lança versões corretivas pouco tempo depois para corrigir aqueles bugs que passaram despercebidos durante o longo ciclo de testes (beta e RC -- 6 meses).

Como estamos na 9.1, se você estiver considerando uma atualização de versão, faça um planejamento com a 9.1 ao invés da 9.0 (por exemplo). Apesar de ser uma nova versão, o tempo que as suas aplicações ficarem em teste é exatamente aquele em que o grupo de desenvolvimento terá lançado 1 ou 2 versões corretivas.

Seja feliz com 9.1 até que o 9.2 ou 9.3 saia do forno e você considere atualizar novamente. ;)