Anda di halaman 1dari 21

Desmistificando o PostgreSQL

- Alterar o Cdigo Fonte de um SGBD Coisa pra Macho???-

1. O PostgreSQL O PostgreSQL , em suma, um sistema de gerenciamento de banco de dados objeto-relacional (SGBDOR) desenvolvido com base nos cdigos do projeto Postgres, encabeado e mantido pelo Departamento de Cincia da Computao da Universidade da Califrnia em Berkeley, desde 1985, coordenado pelo professor Michael Stonebraker. Seu grande diferencial consiste em disponibilizar seu cdigo, o que permite que muitos programadores, espalhados por vrios pases, contribuam para sua evoluo constante. O PostgreSQL possui verses tanto para ambientes Unix quanto para Windows; o presente trabalho baseia-se no primeiro, na distribuio Fedora. Atualmente, o PostgreSQL um dos SGBD de cdigo aberto mais avanado, seus principais recursos so: Consultas complexas. Chaves estrangeiras. Integridade transacional. Controle de concorrncia multi-verso. Suporte ao modelo hbrido objeto-relacional. Trigger. Views. Stored procedures em vrias linguagens.

2. Histrico O PostgreSQL um dos resultados de uma ampla evoluo que se iniciou com o projeto Ingres, desenvolvido na Universidade de Berkeley, Califrnia. O lider do projeto, Michael Stonebraker, um dos pioneiros dos bancos de dados relacionais, deixou a universidade em 1982 para comercializar o Ingres, porm retornou a ela logo em seguida. Aps seu retorno a Berkeley, em 1985, Stonebraker comeou um projeto ps-Ingres com o objetivo de resolver problemas com o modelo de banco de dados relacional. O principal problema era a incapacidade do modelo relacional compreender tipos (atualmente, chamados de objetos), ou seja, combinaes de dados simples que formam uma nica unidade. O projeto resultante, chamado Postgres, era orientado a introduzir a menor quantidade possvel de funcionalidades para completar o suporte a tipos. Estas funcionalidades incluam a habilidade de definir tipos, mas tambm a habilidade de descrever relaes - as quais at este momento eram

amplamente utilizadas, mas completamente mantidas pelo usurio. No Postgres, o banco de dados "compreendia" as relaes e podia obter informaes de tabelas relacionadas utilizando regras. Iniciando em 1986, a equipe divulgou uma srie de documentos descrevendo a base do sistema e em 1988 o projeto possua um prottipo funcional. A verso 1 foi liberada para um grupo pequeno de usurios em junho de 1989, seguida pela verso 2 com um sistema de regras reescrito em junho de 1990. Para a verso 3, liberada em 1991, o sistema de regras foi reescrito novamente, mas tambm foram adicionados suporte para mltiplos gerenciadores de armazenamento e um melhorado motor de consultas. J em 1993, Postgres havia crescido imensamente em popularidade e possua uma grande demanda por suporte e por novas funcionalidades. Aps a liberao da verso 4, a qual era uma simples verso de limpeza, o projeto foi oficialmente abandonado pela Universidade de Berkeley. Entretanto, devido ao fato do seu cdigo fonte estar sob uma licena BSD, o seu desenvolvimento foi continuado. Em 1994, dois estudantes de Berkeley, Andrew Yu e Jolly Chen, adicionaram um interpretador SQL para substituir a linguagem QUEL (desenvolvida para o Ingres) e o projeto foi renomeado para Postgres95. Com a divulgao de seu cdigo pela Internet, Postgres95 iniciou uma nova vida como software open source. Em agosto de 1996, Marc Fournier, Bruce Momjian e Vadim B. Mikheev lanaram a primeira verso externa da Universidade de Berkeley e deram incio tarefa de estabilizar o cdigo herdado. Tambm em 1996, o projeto foi renomeado para PostgreSQL a fim de refletir a nova linguagem de consulta ao banco de dados: SQL. A primeira verso de PostgreSQL, a 6.0, foi liberada em janeiro de 1997. Desde ento, um grupo de desenvolvedores e de voluntrios de todo o mundo, coordenados pela Internet, tm mantido o software e desenvolvido novas funcionalidades. As principais caractersticas acrescentadas nas verses 6.x so o MVCC (Multiversion Concurrency Control Controle de Concorrncia Multiverses), melhorias no SQL e novos tipos de dados nativos (novos tipos de datas e hora e tipos geomtricos). Em maio de 2000 foi liberada a verso 7.0. As verses 7.x trouxeram as seguintes novas funcionalidades: Write-Ahead Log (WAL), esquemas SQL, outer joins, suporte a IPv6, indexao por texto, suporte melhorado a SSL e informaes estatsticas do banco de dados. A verso 8.0 foi lanada em janeiro de 2005 e entre outras novidades, foi a primeira a ter suporte nativo para Microsoft Windows (tradicionalmente, o PostgreSQL s rodava de forma nativa em sistemas Unix e, em sistemas Windows - atravs da biblioteca Cygwin). Dentre as muitas novidades da verso 8.x, pode-se destacar o suporte a tablespaces, save points, point-in-time recovery, roles e Two-Phase Commit (2PC). Em dezembro de 2006 foi lanada a verso mais recente: 8.2. Desenvolvimento do Projeto O PostgreSQL um projeto open source coordenado pelo PostgreSQL Global Development Group. Embora as atividades do grupo sejam patrocinadas por diversas organizaes de todo o mundo, seu modelo de desenvolvimento o modelo Bazar (originalmente apresentado em A Catedral e o Bazar de Eric S. Raymond). Portanto, o desenvolvimento do PostgreSQL feito por um grupo de desenvolvedores, em sua maioria voluntrios, espalhados por todo o mundo e que se comunicam via Internet. Logo, trata-se, de um projeto direcionado pela comunidade de desenvolvedores e de usurios, a qual qualquer pessoa pode se juntar, bastando se inscrever em listas de discusso e delas participar. Voluntrios interessados em contribuir com o projeto tambm podem consultar as sugestes de tarefas de desenvolvimento de novas funes e de correes de erros que so publicadas na lista

TODO ou apresentar suas prprias sugestes. O cdigo desenvolvido submetido equipe do projeto que pode aceit-lo e inclu-lo nas novas verses ou recus-lo. Voluntrios tambm podem colaborar gerando documentao ou realizando tradues. As ferramentas utilizadas para o apoio ao desenvolvimento so o sistema de gesto de fontes CVS (Concurrent Version System), listas de discusso, servidor de news e salas de bate-papo (IRC). Estruturas de Deciso O Projeto PostgreSQL desenvolvido e direcionado pela sua comunidade de desenvolvedores e de usurios. Para coordenar o projeto h uma equipe central (core team) composta por sete desenvolvedores e um grupo de committers CVS. O cdigo fornecido por voluntrios avaliado e aceito ou rejeitado pelos committers. Este modelo de desenvolvimento de software, baseado no modelo Bazar originalmente apresentado em A Catedral e o Bazar de Eric S. Raymond, possibilita o desenvolvimento de software com qualidade devido, principalmente, a permitir: Tratar usurios como parceiros e/ou desenvolvedores. Eles contribuem diretamente com o desenvolvimento do software apresentando os problemas enfrentados, suas necessidades, suas sugestes de soluo e, at mesmo, seu prprio cdigo fonte de soluo. Assim, usurios auxiliam de forma pr-ativa nas melhorias e na depurao do software. Reutilizar cdigo fonte. Lanar rapidamente e freqentemente novas verses. Com uma base ampla de usurios testadores do software, os eventuais problemas so rapidamente identificados e sugestes de soluo tambm aparecem com rapidez. Por exemplo, no Projeto PostgreSQL, a verso 8.2.0 foi lanada exatamente 50 dias depois da verso anterior e apresentou 180 acrscimos ou alteraes em cdigo fonte implementadas por 71 programadores diferentes.

Estado Atual Inicialmente desenvolvido na Universidade de Berkeley, Califrnia, a partir de 1996, o PostgreSQL firmou-se como um projeto de software open source desenvolvido por uma comunidade de voluntrios sob a coordenao do PostgreSQL Global Development Group. Alm de doaes, o projeto PostgreSQL se sustenta pelo patrocnio de diversas empresas, entre as quais se destacam: Fujitsu, Hub.Org, NTT Group, Red Hat, Skype, SRA e Sun Microsystems. O software tem adquirido prestgio na comunidade Linux, tendo recebido diversas vezes o prmio Linux Journal Editor's Choice de melhor sistema de gerenciamento de banco de dados (SGBD). Alm da comunidade Linux, a aceitao do PostgreSQL tambm tem se ampliado. H entre os seus usurios grandes empresas internacionais, rgos governamentais de vrios pases e universidades de prestgio mundial. Uma lista dos principais usurios pode ser vista em www.postgresql.org/about/users. Em www.postgresql.org/about/casestudies podem ser vistos estudos de caso de aplicaes do PostgreSQL.

3. Estrutura dos Arquivos Diretrio Principal: /etc/postgresql/8.1/main/ Diretrio de Executveis: /usr/postgresql/lib/8.1/Bin Diretorio de Dados: /var/lib/postgresql/8.1/main /etc/postgresql/8.1/main/pgdata(link) Diretorio de Log: /var/log/postgresql/ /etc/postgresql/8.1/main/log(link) Subdiretrios de pgdata: base: bases de dados blobal: data acessveis para todo o cluster pg_clog: status das transaes pg_subtrans: status de sub-transaes pg_multixact: status de transao para shared row lock pg_tblspc: links simblicos de tablespace pg_xlog: arquivos do wal pg_twophase: status dos procedimentos preparados.

4. Arquivos e Pastas Interessantes

backend/parser/keywords.c backend/parser/gramy .c backend/parser/analyze.c include/nodes/parsenodes.h include/nodes/execnodes.h backend/catalog/index.c backend/catalog/indexing.c include/catalog/pg_index.h

backend/commands/indexcmds.c backend/commands/copy.c include/executor/executor.h

5. Guia Rpido de Instalao Esta seo visa apresentar um roteiro simplificado que auxilie o processo de instalao do SGBD PostgreSQL em Linux. Mais detalhes devem ser obtidos na documentao oficial, em http://www.postgresql.org/docs. 3.1 Obteno dos fontes Realize download do arquivo compactado possuindo o cdigo fonte do PostgreSQL em: ftp://ftp.postgresql.org/pub/source/v7.4.13/postgresql-7.4.13.tar.gz. Uma vez concludo o processo de cpia, descompacte:

gunzip -c postgresql-7.4.13.tar.gz | tar -xvf Esse comando criar o diretrio postgresql-7.4.13 sob o diretrio corrente. Ele deve ser o corrente daqui em diante. 3.2 Configurao Aps fazer do diretrio postgresql-7.4.13 o diretrio corrente, execute o comando:

./configure O comando acima somente precisa ser executado na fase de instalao, isto , aps alterar o cdigo, no mais necessrio realizar esta etapa de configurao. Em princpio, os arquivos dos futuros bancos a serem criados vo para /usr/local/pgsql. Isto pode ser alterado da seguinte forma:

./configure --prefix=outro caminho

3.3 Construo Concluda a etapa de configurao, deve-se compilar os arquivos fonte. Ainda no diretrio postgresql-7.4.13, execute o comando:

make Cada vez que algum arquivo fonte (extenses .c, .h) sofrer alteraes deve-se repetir a etapa de construo executando o comando acima. Se no houver erros de compilao, a ltima mensagem deve ser esta:

All of PostgreSQL successfully made. Ready to install. Para reverter os efeitos desta etapa, deve-se executar o comando:

make clean

3.4 Instalao Concluda a etapa de construo, deve-se instalar o PostgreSQL. Ainda no diretrio postgresql-7.4.13 , execute o comando:

make install Caso o usurio corrente no possua plenos direitos para criar arquivos no Servidor em questo, deve-se executar a tarefa acima conectado como root. Se no houver erros de instalao, a ltima mensagem deve ser esta:

Thank you for choosing PostgreSQL, the most advanced open source database engine. Para reverter os efeitos desta etapa, deve-se executar o comando:

make uninstall Deve-se ressaltar, entretanto, que, uma vez concluda a primeira instalao e realizadas alteraes em arquivos fonte, no necessrio desinstalar o PostgreSQL. 3.5 Variveis de ambiente Para evitar longos caminhos de diretrios em comandos que interajam com PostgreSQL, recomenda-se a criao de algumas variveis de ambiente: export export export export LD_LIBRARY_PATH=/usr/local/pgsql/lib PATH=/usr/local/pgsql/bin:$PATH MANPATH=/usr/local/pgsql/man:$MANPATH PGDATA=/usr/local/pgsql/data

Os caminhos de diretrios utilizados devem ser coerentes com a etapa de configurao. Assim, caso tenha-se decidido utilizar outro destino que no o padro, deve-se substituir /usr/local pelo novo caminho.

Os comandos acima podem constar em um arquivo que seja executado automaticamente uma vez carregado o Sistema Operacional, como por exemplo, o arquivo /etc/profile. Deve-se garantir, entretanto, que os comandos acima sero executados, pelo menos uma vez, antes de utilizar o PostgreSQL. Recomenda-se tambm criar um usurio Linux especfico para lidar com PostgreSQL. Geralmente, chama-se postgres. Para criar o usurio administrador para o postgresql use: sudo adduser postgres Em seguida fornea uma senha de acesso para ele.

3.6 Criao de Bancos de Sistema Antes de criar Bancos de Dados regulares, deve-se construir o database cluster (grupo de Bancos de Sistema) . Conectado como o usurio Linux responsvel pelo PostgreSQL (geralmente postgres) e tendo criado as variveis de ambiente citadas no item anterior, basta executar o comando:

initdb Ser criado e preenchido o diretrio data sob PGDATA (varivel de ambiente definida no item 5).

3.6 Disponibilizao Conexes somente podem acontecer caso o PostgreSQL esteja disponibilizado. Isto ocorre via comando: pg_ctl start -l /home/postgres/saida.txt O sucesso do comando acima pode ser verificado investigando o arquivo de logs, neste caso, /home/postgres/saida.txt, bem como checando se os trs processos bsicos esto na memria, cada um identificado por um process identifier (pid). Suas descries podem ser visualizadas graas ao comando ps C postmaster: postmaster postgres : stat buffer process postgres: stats collector

O primeiro processo, postmaster, desempenha o papel mais importante pois a partir dele outros processos, chamados postgres, sero disparados. Inclusive, cada conexo criada tambm ocasionar um novo processo postgres.

Outra forma alternativa seria: postmaster -i Obs: O argumento -i para que o banco aceite conexes tcp/ip, caso o argumento S fosse acrescentado depois do i a execuo do banco seria em modo silencioso, ou seja, o log no mostraria no console corrente. 3.7 Criao de um Banco Regular A criao de um banco de dados concretiza-se graas ao comando createdb. Na verdade, trata-se de um script semelhante a initdb e pg_ctl. Eles residem no diretrio: pgsql/bin. Exemplo: createdb teste

3.8 Conexo Finalmente, para que conexes possam acontecer a um banco de dados, deve-se utilizar o comando psql: psql d teste onde o parmetro d indica o banco ao qual deseja conectar-se.

3.9 Indisponibilizao Uma vez encerradas as conexes, pode-se retirar o PostgreSQL da memria via: pg_ctl stop -m s

6. FAQ 4.1. Antes de tudo necessrio verificar se o compilador da linguagem C (GCC) j est instalado. Abra o console e digite: sudo apt-get install gcc,build-essential Caso j esteja instalado ele vai indicar que j est instalado, caso contrrio o gerenciador de pacotes padro vai instalar tudo automaticamente para voc. Caso o seu sistema no seja o ubuntu (debian), o gerenciador de pacotes provavelmente no vai ser o apt-get, vai ser outro por exemplo: yum , yast.

No Ubuntu, esse passo de instalao do gcc pode ser feito tambm atravs da interface grfica, basta entrar em Sistema > Administrao > Gerenciador de Pacotes Synaptic. Ento basta pesquisar pelos pacotes gcc e build-essential, caso eles estejam instalados j vai aparecer marcado o checkbox caso contrrio marque os checkboxs e clique no boto aplicar para que o compilador seja instalado automaticamente. 4.2. Obtendo o pgadmin O pgadmin pode ser obtido da mesma maneira que foi obtido o gcc, atravs de um gerenciador de pacotes atravs do comando: sudo apt-get install pgadmin3 Caso este pacote no esteja na sua lista de pacotes v at o site oficial do postgres e na seo download baixe o instalador e instale.

4.3. Ambiente de desenvolvimento Para que o desenvolvimento dentro do cdigo fonte do projeto PostgreSQL se torne produtivo, fundamental que uma IDE seja utilizada para otimizar tarefas como edio de cdigo,compilao, instalao. Grande parte dos desenvolvedores da linguagem utilizam uma ide chamada eclipse, mas eu particularmente prefiro usar o netbeans. Para baixar o netbeans para desenvolvimento em C entre na sua pgina oficial http://www.netbeans.org/ e na seo de download baixe o netbeans voltado para c/c++.

4.4. Parar o processo que est rodando em background: kill `cat /usr/local/pgsql/data/postmaster.pid` ps -a kill -9 pid

4.5. Troca de usurio para root: su root 4.6. Troca de usurio para o postgres: su postgres 4.7. Criar os diretrios onde os dados sero armazenados:

mkdir /usr/local/pgsql/data chown postgres /usr/local/pgsql/data

7. Utilizando o GDB O primeiro passo consiste em configurar o postgres com a opo --enable-debug. No meu caso, executo o seguinte comando no diretrio do postgres: ./configure --prefix=diretorio_de_instalacao --enable-debug --enable-cassert --enable-depend Aps a compilao (gmake), instalao (gmake install) e ajuste das variveis de ambiente (PATH, PGDATA, LD_LIBRARY_PATH, etc), conforme a documentao, j possvel executar o postgres. A maneira mais fcil de utiliz-lo com o gdb criando um banco de dados com o nome do usuario do linux (createdb nome_usuario) e executando os comandos "gdb postmaster" ou "gdb postgres". Deste modo, o postgres ser executado com o gdb no modo de "interactive backend", onde apenas um processo servidor/cliente criado, e o cliente logado automaticamente no banco de dados com o nome do usurio. possvel debugar tambm executando o postgres no modo normal, com a criao de um processo "postmaster" e processos servidores para cada cliente, mas o mecanismo bem mais complicado e no nosso caso no ser necessrio. Comandos importantes do gdb: "b nome_funcao" - criacao de breakpoints "run" - inicio da execucao do postgres, o qual so sera interrompido quando passar por um breakpoint ou quando o usuario digitar "CTRL+C" "next" - executa a proxima instrucao "step" - entra na funcao "print variavel" - mostra o valor de uma variavel "bt" - mostra um trace do programa, com as funcoes chamadas "cont" - continua a execucao do postgres apos a interrupcao "kill" - finaliza a execucao "help" - ajuda do gdb Outra dica: sempre que o "enter" for apertado o comando anterior ser executado novamente no gdb. 8. Referncias Bibliogrficas http://www.postgres.org http://developers.sun.com/tools/cc/articles/mixing.html

Alterando a Poltica de Substituio de Pginas de Memria do PostgreSQL

1. O Gerenciador de Memria
O desempenho de consultas em sistemas gerenciadores de bancos de dados um dos indicadores mais importantes de sua qualidade, e a maior parte da pesquisa em bancos de dados est direcionada para este objetivo. Um dos fatores crticos para o desempenho de consultas o bom gerenciamento da informao em memria, j que o que geralmente determina o tempo de execuo de uma consulta a quantidade de operaes de entrada e sada (E/S), do disco para a memria. Os sistemas operacionais possuem um gerenciador de memria (buffer manager), o qual poderia teoricamente ser usado para controlar as pginas dos SGBDs em memria, porm este mecanismo seria muito ineficiente, devido s particularidades de acessos informao em SGBDs. Logo, necessria a existncia de um gerenciador de memria exclusivo em um SGBD para acelerar as consultas feitas por este. Alm disto, o gerenciador de memria possibilita a implementao de polticas de recuperao, como a Write Ahead Logging, e um melhor controle de bloqueios. O gerenciador de memria o componente do SGBD responsvel pelo gerenciamento de um espao limitado de memria para armazenar pginas de dados reduzindo o nmero de operaes de leitura a disco por transao. Funciona como uma interface entre a memria principal e o disco. O papel principal do gerenciador de memria consiste em responder a pedidos de acesso em memria de pginas do disco. Quando a memria completamente preenchida, uma pgina deve ser removida para que outra seja alocada. Se a pgina em memria tiver sido modificada, esta deve ser armazenada em disco antes de ser removida. A escolha de qual pgina deve ser removida da memria de grande importncia, pois h grande chance de que uma pgina removida tenha que ser utilizada novamente e retornar memria no futuro. O gerenciador de memria tenta ento prever quais pginas em memria no devero ser utilizadas novamente no futuro prximo para selecionar as que devero ser removidas da memria. Para isso, diferentes polticas de substituio de pginas podem ser adotadas. Neste trabalho apresentamos algumas polticas de substituio de pginas da memria (buffer) mais populares, e suas vantagens e desvantagens. Em seguida descrevemos a implementao existente da poltica de LRU (Least Recently Used) no PostgreSQL e a implementao feita da poltica de MRU (Most Recently Used). Finalmente, apresentaremos os resultados dos testes realizados para comparar o desempenho das duas polticas e as concluses obtidas.

2. Polticas de Substituio de Pginas


As polticas de substituio de pginas utilizadas para gerenciar uma rea de memria podem ser classificadas de acordo com as consideraes seguidas por uma poltica: Idade da pgina: contada desde a primeira referncia ou desde a ltima; Contabilizar todas as referncias; Contabilizar somente a referncia mais recente.

A poltica FIFO, por exemplo, substitui a pgina mais antiga sem levar em considerao a freqncia de acesso nem a idade da pgina, contada desde a primeira referencia o nico critrio de deciso. Esta poltica tem bons resultados para acesso seqencial. Um dos algoritmos mais utilizados, o LRU, substitui as pginas do buffer que foram utilizadas menos recentemente. A deciso de substituio determinada pela idade de cada pgina do buffer desde a sua mais recente referncia. Esta poltica leva em considerao o Princpio da localidade Temporal, j que as pginas acessadas recentemente costumam ter maior chance de serem acessadas novamente e, neste caso, no so retiradas da memria. A poltica LRU usada para gerenciar o buffer do PostgreSQL, que apresenta vantagens como melhor aproveitamento das pginas mais usadas em memria, mas em contra partida apresenta um algoritmo muito mais complexo em relao s outras polticas de gerenciamento de buffer. J a poltica MRU substitui as pginas do buffer que foram utilizadas mais recentemente. Escolhemos implementar a poltica MRU no PostgreSQL por questo de simplicidade.

3. Implementao
Para podermos implementar uma poltica alternativa de gerncia de buffer, foi necessrio uma anlise no cdigo fonte do PostgreSQL. Foi observado que o PostgreSQL implementa a poltica LRU de gerncia de Buffer. O PostgreSQL utiliza uma estrutura em lista chamada de BufferDesc para organizar o Buffer em memria e uma serie de funes para manipul-la. Essa estrutura possui uma srie de atributos que auxiliam no gerenciamento do Buffer, como o exemplo do atributo refcount que informa se a pgina que est sendo referenciada por esse n da estrutura est pinned, ou seja, se a pgina esta bloqueada ou no e quantos bloqueios ela possui. Alm dos atributos essa estrutura possui dois ponteiros (freeNext e freePrev) para uma outra estruturas de dados. Esses dois ponteiros apontam para uma lista encadeada que possui os endereos das prximas pginas candidatas a serem retiradas da memria. Essa lista auxiliar essencial para implementar o LRU, pois cada vez que uma pgina acessada ela inserida no final desta lista. Logo, a pgina mais recentemente utilizada est no final da lista e menos recentemente utilizada est no incio da lista.

Estrutura do BufferDesc:
typedef struct sbufdesc { Buffer freeNext; Buffer freePrev; SHMEM_OFFSET data;

/* links for freelist chain */ /* pointer to data in buf pool */

/* tag and id must be together for table lookup (still true?) */ BufferTag tag; /* file/block identifier */ In buf_id; /* buffer's index number (from 0) */ BufFlags flags; /* see bit definitions above */ unsigned refcount; /* # of backends holding pins on buffer */ LWLockId io_in_progress_lock; /* to wait for I/O to complete */ LWLockId cntx_lock; /* to lock access to page context */ Bool cntxDirty; /* new way to mark block as dirty */ /* * We can't physically remove items from a disk page if another * backend has the buffer pinned. Hence, a backend may need to wait * for all other pins to go away. This is signaled by setting its own * backend ID into wait_backend_id and setting flag bit * BM_PIN_COUNT_WAITER. At present, there can be only one such waiter * per buffer. */ BackendId wait_backend_id; /* backend ID of pin-count waiter */ } BufferDesc;

Para que pudssemos colocar em prtica a poltica Gerncia de Buffer MRU foi preciso modificar apenas uma linha de cdigo. No momento de retirar uma pgina, ao invs de escolher a pgina que est no incio da lista (menos recentemente utilizada) escolhemos a pgina que est no final da lista (mais recentemente utilizada).

Para a visualizao durante a execuo de testes, cada vez que uma pgina acessada, escrita, removida ou inserida na memria, impresso na tela o nmero do buffer em questo, o seu contador de referncias e o identificador da relao que possui a pgina. A verso original da implementao da poltica de LRU tambm foi modificada para imprimir em tela o nmero do buffer e o identificador da relao nas mesmas situaes, facilitando a comparao entre as duas polticas.
if (freeBuf == NULL) { elog(LOG, "Nao foi encontrado buffer livre!!!"); } else { elog(LOG, "Buffer %d livre, contador %d, relacao antiga %d", freeBuf->buf_id, freeBuf>counter, freeBuf->tag.rnode.relNode);

A modificao mais importante feita no cdigo foi na funo GetFreeBuffer, que est no arquivo src/backend/storage/buffer/freelist.c, onde removida a pagina menos referenciada da memria. Esta funo mostrada a seguir:

* GetFreeBuffer() -- get the 'next' buffer from the freelist. */ BufferDesc * GetFreeBuffer(void) { BufferDesc *buf; if (Free_List_Descriptor == SharedFreeList->freeNext) { /* queue is empty. All buffers in the buffer pool are pinned. */ ereport(ERROR, (errcode(ERRCODE_INSUFFICIENT_RESOURCES), errmsg("out of free buffers"))); return NULL; } buf = &(BufferDescriptors[SharedFreeList->freeNext]); /* remove from freelist queue */ BufferDescriptors[buf->freeNext].freePrev = buf->freePrev; BufferDescriptors[buf->freePrev].freeNext = buf->freeNext; buf->freeNext = buf->freePrev = INVALID_DESCRIPTOR; buf->flags &= ~(BM_FREE); return buf; }

Observe que:
buf = &(BufferDescriptors[SharedFreeList->freeNext]);

Atribui varivel buf a pgina que est no incio da lista (ou seja, a pgina utilizada menos recentemente). Como a lista duplamente encadeada
buf->freePrev

Representa a pgina que est no final da lista (ou seja, a pgina utilizada mais recentemente). Logo, para implementar o MRU e exclui a pgina mais recentemente utilizada (final da lista) basta fazer:
Buf = buf->freePrev

Assim, apontamos para a pgina que est no final da lista (mais recentemente utilizada).

O cdigo alterado ficar ento da seguinte forma:


* GetFreeBuffer() -- get the 'next' buffer from the freelist. */ BufferDesc * GetFreeBuffer(void) { BufferDesc *buf;

if (Free_List_Descriptor == SharedFreeList->freeNext) { /* queue is empty. All buffers in the buffer pool are pinned. */ ereport(ERROR, (errcode(ERRCODE_INSUFFICIENT_RESOURCES), errmsg("out of free buffers"))); return NULL; } buf = &(BufferDescriptors[SharedFreeList->freeNext]); Buf = buf->freePrev /* remove from freelist queue */ BufferDescriptors[buf->freeNext].freePrev = buf->freePrev; BufferDescriptors[buf->freePrev].freeNext = buf->freeNext; buf->freeNext = buf->freePrev = INVALID_DESCRIPTOR;

buf->flags &= ~(BM_FREE);

return buf; }

4. Referncias
[1] Principles of Database Buffer Management Wolfgang Effelsberg IBM Scientific Center, Heidelberg THEO HAERDE University of Kaiserslautern PostgreSQL - Manual de referncia www.postgresql.org

[2]