O comando CREATE DATABASE realmente funciona
copiando um banco de dados existente.
Por padrão, copia o banco de dados padrão do sistema chamado
template1.
Assim, este banco de dados é o “modelo” a partir
do qual os novos bancos de dados são criados.
Se forem adicionados objetos ao banco de dados
template1, estes objetos serão copiados para
os bancos de dados do usuário criados posteriormente.
Este comportamento permite modificações locais da instalação
no conjunto padrão de objetos nos bancos de dados.
Por exemplo, se for instalada a linguagem procedural
PL/Perl no banco de dados
template1, esta linguagem estará automaticamente
disponível nos bancos de dados do usuário, sem que nenhuma ação extra
precise ser executada quando estes bancos de dados forem criados.
Entretanto, o comando CREATE DATABASE não copia
as permissões GRANT no nível de banco de dados
associadas ao banco de dados de origem.
O novo banco de dados possui as permissões padrão no nível de
banco de dados.
Existe também um segundo banco de dados padrão do sistema chamado
template0.
Este banco de dados contém os mesmos dados do conteúdo inicial
do banco de dados template1, ou seja, apenas os
objetos padrão predefinidos pela versão corrente do
PostgreSQL.
O banco de dados template0 nunca deve ser
alterado após a inicialização da instância.
Ao instruir o comando CREATE DATABASE para copiar
o banco de dados template0, em vez de copiar o
banco de dados template1 pode-se criar um banco
de dados de usuário
prístino
(aquele onde não existem objetos definidos pelo usuário, e onde os
objetos do sistema não foram alterados),
que não contém nenhuma das adições locais da instalação feitas no
banco de dados template1.
É particularmente útil ao recuperar uma cópia de segurança feita pelo
pg_dump: o script da cópia de segurança deve ser
recuperado em um banco de dados original, para garantir que o conteúdo
correto do banco de dados salvo seja recriado, sem entrar em conflito
com objetos que possam ter sido adicionados ao banco de dados
template1 posteriormente.
Outro motivo comum para se copiar o banco de dados
template0 em vez do banco de dados
template1, é que podem ser especificadas novas
configurações de codificação e localidade ao copiar o
banco de dados template0, enquanto uma cópia do
banco de dados template1 deve usar as mesmas
configurações que ele usa.
Isto ocorre porque o banco de dados template1
pode conter dados específicos de codificação ou localidade, enquanto
o banco de dados template0 é conhecido por não
os conter.
Para criar um banco de dados copiando o banco de dados
template0, deve-se usar o comando
CREATE DATABASE nome_do_banco_de_dados TEMPLATE template0;
a partir do ambiente SQL, ou
createdb -T template0 nome_do_banco_de_dados
a partir do interpretador de comandos.
É possível criar bancos de dados modelo adicionais e, de fato,
pode-se copiar qualquer banco de dados de uma instância
especificando seu nome como modelo para o comando
CREATE DATABASE.
Porém, é importante notar que este comando não foi (ainda) planejado
como uma ferramenta tipo “COPY DATABASE
de propósito geral”.
A principal limitação é que nenhuma outra sessão pode ser conectada
ao banco de dados de origem enquanto ele está sendo copiado.
O comando CREATE DATABASE irá falhar se qualquer
outra conexão existir ao iniciar; durante a operação de cópia,
são impedidas novas conexões com o banco de dados de origem.
Existem dois sinalizadores úteis para cada banco de dados no
catálogo do sistema pg_database:
as colunas
datistemplate e datallowconn.
A coluna datistemplate pode ser definida
indicando que o banco de dados é um modelo para o comando
CREATE DATABASE.
Se este sinalizador estiver definido, o banco de dados pode ser clonado
por qualquer usuário com o privilégio CREATEDB;
se não estiver definido, apenas os superusuários e o dono do banco
de dados poderão cloná-lo.
Se a coluna dataallowconn for definida como falso,
nenhuma nova conexão com este banco de dados será permitida
(mas as sessões existentes não são terminadas simplesmente definindo
este sinalizador como falso).
O banco de dados template0 é normalmente marcado
com dataallowconn = false, para impedir a sua
modificação.
Tanto template0 quanto template1
devem sempre ser marcados com datistemplate = true.
Os nomes template1 e template0
não possuem nenhum status especial, além do fato do nome
template1 ser o nome do banco de dados de origem
padrão para o comando CREATE DATABASE.
Por exemplo, pode-se remover template1 e
recriá-lo a partir de template0, sem nenhum
efeito nocivo.
Este tipo de ação pode ser aconselhável se for adicionado
descuidadamente um monte de lixo no template1.
(Para remover o banco de dados template1, ele
deve estar com pg_database.datistemplate = false.)
Também é criado o banco de dados postgres quando
a instância é inicializada.
Este banco de dados é um banco de dados padrão para os usuários e
aplicações se conectarem.
É simplesmente uma cópia do banco de dados
template1, podendo ser removido e recriado
se necessário.