23.6. Espaços de tabelas

Os espaços de tabelas no PostgreSQL permitem que os administradores de banco de dados definam localizações no sistema de arquivos onde os arquivos que representam os objetos do banco de dados podem ser armazenados. Após ser criado, o espaço de tabelas pode ser referido pelo nome ao criar objetos de banco de dados.

Usando espaços de tabelas, o administrador pode controlar a disposição em disco de uma instalação do PostgreSQL. É útil de pelo menos duas maneiras:

Atenção

Embora estejam localizados fora do diretório de dados principal do PostgreSQL, os espaços de tabelas são parte integrante do agrupamento de bancos de dados, não podendo ser tratados como uma coleção autônoma de arquivos de dados. Esses dados dependem dos metadados contidos no diretório de dados principal e, portanto, não podem ser anexados a um agrupamento de bancos de dados diferente, ou ser feita cópia de segurança a parte. Da mesma forma, se for perdido um espaço de tabelas (exclusão de arquivo, falha de disco, etc.), o agrupamento de bancos de dados poderá ficar ilegível, ou incapaz de iniciar. Colocar um espaço de tabelas em um sistema de arquivos temporário, como um disco RAM, arrisca a confiabilidade de todo a instância.

Para definir um espaço de tabelas, deve-se usar o comando CREATE TABLESPACE. Por exemplo:

CREATE TABLESPACE fastspace LOCATION '/ssd1/postgresql/data';

O local deve ser um diretório vazio existente, pertencente ao usuário do sistema operacional do PostgreSQL. Todos os objetos criados depois nesse espaço de tabelas serão armazenados em arquivos sob esse diretório. O local não deverá estar em armazenamento removível ou transitório, porque a instância poderá falhar ao funcionar, se o espaço de tabelas estiver ausente ou perdido.

Nota

Normalmente, não faz muito sentido criar mais de um espaço de tabelas por sistema de arquivos lógico, porque não é possível controlar a localização dos arquivos individuais em um sistema de arquivos lógico. Entretanto, o PostgreSQL não impõe nenhuma limitação e, na verdade, não está diretamente ciente dos limites do sistema de arquivos no sistema. Ele apenas irá armazenar arquivos nos diretórios que se disser para usar.

A criação do próprio espaço de tabelas deve ser feita por um superusuário do banco de dados, mas depois disso pode-se permitir que usuários comuns do banco de dados o usem. Para fazer isso, deve ser concedido a eles o privilégio CREATE no espaço de tabelas.

Tabelas, índices e bancos de dados inteiros podem ser atribuídos a espaços de tabelas específicos. Para fazer isso, um usuário com o privilégio CREATE em um determinado espaço de tabelas deve passar o nome do espaço de tabelas como parâmetro para o comando relevante. Por exemplo, o comando a seguir cria uma tabela no espaço de tabelas space1:

CREATE TABLE foo(i int) TABLESPACE space1;

Como alternativa, pode ser usado o parâmetro default_tablespace:

SET default_tablespace = space1;
CREATE TABLE foo(i int);

Quando default_tablespace é definido como qualquer coisa, menos uma cadeia de caracteres vazia, ele fornece uma cláusula TABLESPACE implícita para os comandos CREATE TABLE e CREATE INDEX que não possuem uma cláusula explícita.

Há também o parâmetro temp_tablespaces, que determina o posicionamento de tabelas e índices temporários, bem como arquivos temporários usados ​​para fins de classificação de grandes conjuntos de dados. Pode ser uma lista de nomes de espaços de tabela, em vez de apenas um, para que a carga associada a objetos temporários possa ser distribuída por vários espaços de tabela. Um membro aleatório da lista é selecionado cada vez que um objeto temporário é criado.

O espaço de tabelas associado a um banco de dados é usado para armazenar os catálogos do sistema desse banco de dados. Além disso, é o espaço de tabelas padrão usado para tabelas, índices e arquivos temporários criados no banco de dados, se nenhuma cláusula TABLESPACE for fornecida, e nenhuma outra indicação for especificada por default_tablespace ou temp_tablespaces (conforme apropriado). Se um banco de dados for criado sem especificar um espaço de tabelas para ele, ele usará o mesmo espaço de tabelas do banco de dados modelo do qual está sendo copiado.

Dois espaços de tabelas são criados automaticamente quando o agrupamento de banco de dados é inicializado. O espaço de tabelas pg_global é usado para os catálogos de sistemas compartilhados. O espaço de tabelas pg_default é o espaço de tabelas padrão dos bancos de dados template1 e template0 (e, portanto, também o espaço de tabelas padrão para os demais bancos de dados, a menos que seja alterado por uma cláusula TABLESPACE no comando CREATE DATABASE).

Após ser criado, o espaço de tabelas pode ser usado de qualquer banco de dados, desde que o usuário solicitante tenha os privilégios suficientes. Isso significa que o espaço de tabelas não pode ser removido até que todos os objetos de todos os bancos de dados que usam o espaço de tabelas tenham sido removidos.

Para remover um espaço de tabelas vazio, é usado o comando DROP TABLESPACE.

Para determinar o conjunto de espaços de tabelas existente, deve-se consultar o catálogo do sistema pg_tablespace. Por exemplo:

SELECT spcname FROM pg_tablespace;

  spcname
------------
 pg_default
 pg_global
(2 linhas)

O meta-comando \db do programa psql também serve para listar os espaços de tabelas existentes.

O PostgreSQL faz uso de links simbólicos para simplificar a implementação de espaços de tabelas. Isso significa que os espaços de tabelas podem ser usados ​​somente em sistemas que suportam links simbólicos.

O diretório $PGDATA/pg_tblspc contém links simbólicos que apontam para cada um dos espaços de tabelas não integrados definidos na instância. Embora não seja recomendado, é possível ajustar manualmente a disposição do espaço de tabelas redefinindo esses links. Sob nenhuma circunstância essa operação deverá ser executada enquanto o servidor estiver ativo. Note que no PostgreSQL 9.1 e anteriores, também será necessário atualizar o catálogo do sistema pg_tablespace com os novos locais. (Se não for feito, o pg_dump continuará a usar os locais antigos do espaço de tabelas.)

Exemplo 23.1. Uso de espaço de tabelas

Nesse exemplo é criado o diretório /var/pgts, o espaço de tabelas pgts usando esse diretório, e a tabela foo usando esse espaço de tabelas. No final o diretório é listado, mostrando um subdiretório criado nele.

$ sudo mkdir /var/pgts
$ sudo chown postgres:postgres /var/pgts
$ psql
=# CREATE TABLESPACE pgts LOCATION '/var/pgts';
CREATE TABLESPACE
=# \db
        List of tablespaces
    Name    |  Owner   | Location
------------+----------+-----------
 pg_default | postgres |
 pg_global  | postgres |
 pgts       | postgres | /var/pgts
(3 linhas)
=# CREATE TABLE foo(i int) TABLESPACE pgts;
CREATE TABLE
=# \q
$ sudo ls -l /var/pgts/
total 0
drwx------. 1 postgres postgres 10 mai 27 12:13 PG_14_202107181

Nota.  Exemplo escrito pelo tradutor, não fazendo parte da documentação original.