Question

J'ai créé un nouveau tablespace appelé indexes, et j'essaie de supprimer l'ancien tablespace indexes_old, qui contenait des tables et des index.Lorsque j'essaie de supprimer le tablespace, j'obtiens :

=> drop tablespace indexes_old;
ERROR:  tablespace "indexes_old" is not empty

Mais lorsque j'essaie de voir ce qu'il y a dedans, il semble qu'aucune table ne réside dans cet espace de table :

=> select * from pg_tables where tablespace = 'indexes_old';
schemaname | tablename | tableowner | tablespace | hasindexes | hasrules | hastriggers
------------+-----------+------------+------------+------------+----------+-------------
(0 rows)

=> select * from pg_indexes where tablespace = 'indexes_old';
schemaname | tablename | indexname | tablespace | indexdef
------------+-----------+-----------+------------+----------
(0 rows)

Alors, qu'y a-t-il dans cet espace de table qui m'empêche de le supprimer ?

Au cas où cela serait important, je viens de migrer de la page 8.4 vers la page 9.0 à l'aide de l'outil pg_upgrade.

Les tablespaces ressemblent à ceci :

    Name     |  Owner   |    Location     | Access privileges | Description 
-------------+----------+-----------------+-------------------+-------------
 indexes     | nobody   | /data/pgindex90 |                   | 
 indexes_old | nobody   | /data/pgindex84 |                   | 

et le contenu de /data/pgindex84 inclut tous les anciens index 8.4, plus ce nouvel index 9.0 créé automatiquement par pg_upgrade

# sudo ls -al /data/pgindex84/PG_9.0_201008051/11874
total 8280
drwx------ 2 postgres postgres    4096 Feb  9 14:58 .
drwx------ 3 postgres postgres    4096 Feb 11 09:28 ..
-rw------- 1 postgres postgres   40960 Feb  9 14:58 10462602
-rw------- 1 postgres postgres   40960 Feb  9 14:58 10462604
-rw------- 1 postgres postgres 4644864 Feb  9 14:58 10462614
-rw------- 1 postgres postgres 3727360 Feb  9 14:58 10462616
Était-ce utile?

La solution

Vérifiez pg_class pour voir ce qui se trouve où :

SELECT 
  c.relname, 
  t.spcname 
FROM 
  pg_class c 
    JOIN pg_tablespace t ON c.reltablespace = t.oid 
WHERE 
  t.spcname = 'indexes_old';

Autres conseils

Dans PostgreSQL, un tablespace peut être utilisé par n'importe quelle base de données PostgreSQL.(Tant que l'utilisateur demandeur dispose de privilèges suffisants, bien sûr.) Je pense que cette requête

SELECT spcname, spclocation FROM pg_tablespace;

vous montrera le répertoire qu'index_old utilise dans le système de fichiers dans la version PostgreSQL jusqu'à 9.1.Rôdez là-dedans pour voir si quelque chose de réel vous gêne.Cependant, je serais très prudent avant d'essayer de supprimer quoi que ce soit en dehors de l'utilisation de l'interface de PostgreSQL.

Dans 9.2+, essayez

select spcname, pg_tablespace_location(oid) from pg_tablespace;

Dans PG 10 et peut-être un peu plus tôt, cela semble s'être transformé en :

SELECT tablename from pg_tables WHERE tablespace = 'foo';

Malheureusement, il existe une vue « globale » sur toutes les bases de données.Cependant, cela peut être fait en utilisant le clignoter extension avec la fonction suivante :

create or replace function show_tablespace_objects(p_tablespace text, p_user text, p_password text) 
  returns table (db_name text, schema_name text, object_name text, object_type text, tablespace_name text)
as
$func$
declare
  l_stmt text;
  l_con_name text := 'tbs_check_conn';
  l_con_string text;
  l_rec record;  
begin
  l_stmt := $query$SELECT current_database(), 
           n.nspname as schema_name, 
           c.relname as object_name,
           case c.relkind 
             when 'r' then 'table'
             when 'i' then 'index'
             when 't' then 'TOAST table'
             when 'm' then 'materialized view'
             when 'f' then 'foreign table'
             when 'p' then 'partitioned table'
             else c.relkind::text
           end as object_type,
           t.spcname as tablespace_name
    FROM pg_class c 
      JOIN pg_namespace n on n.oid = c.relnamespace
      JOIN pg_tablespace t ON c.reltablespace = t.oid$query$;

  if p_tablespace is not null then 
    l_stmt := l_stmt || format(' WHERE t.spcname=%L', p_tablespace);
  end if;

  for l_rec in (select * from pg_database where datallowconn) loop

     l_con_string := format('dbname=%L user=%L password=%L',
                             l_rec.datname, p_user, p_password);
     return query 
        select * 
        from dblink(l_con_string, l_stmt) 
             as t(db_name text, schema_name text, object_name text, object_type text, tablespace_name text);
  end loop;
end;
$func$
language plpgsql;

La fonction accepte un nom d'espace table ainsi qu'un nom d'utilisateur et un mot de passe valides pour toutes les bases de données du serveur actuel.

Si le nom du tablespace est passé comme null tous les objets qui ne sont pas dans le tablespace par défaut sont répertoriés (ce serait pg_global dans une installation par défaut sans aucun tablespace supplémentaire)

Cela peut être utilisé comme ceci :

select *
from show_tablespace_objects('indexes_old', 'postgres', 'verysecretpassword');

Parlons-nous de l’interface PgSQL ?

Répertoriez les schémas (tablespaces) comme ceci :

\dn

Répertoriez toutes les tables d'un schéma (tablespace) comme ceci :

\dn <table_space>.*

Utiliser

\?

pour plus d'options

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top