Как я могу определить, что находится в табличном пространстве Postgresql? - PullRequest
19 голосов
/ 11 февраля 2011

Я создал новое табличное пространство с именем indexes и пытаюсь удалить старое табличное пространство indexes_old, которое раньше содержало некоторые таблицы и индексы. Когда я пытаюсь отбросить табличное пространство, я получаю:

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

Но когда я пытаюсь увидеть, что там, кажется, что в этом табличном пространстве нет таблиц:

=> 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)

Так, что в том табличном пространстве, которое мешает мне бросить это?

В случае, если это имеет значение, я только что перешел с Pg 8.4 на Pg 9.0, используя инструмент pg_upgrade.

Табличные пространства выглядят так:

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

и содержимое / data / pgindex84 включает все старые индексы 8.4, плюс этот новый индекс 9.0, который автоматически создается 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

Ответы [ 5 ]

13 голосов
/ 11 февраля 2011

Проверьте pg_class, чтобы увидеть, что и где находится:

SELECT 
  c.relname, 
  t.spcname 
FROM 
  pg_class c 
    JOIN pg_tablespace t ON c.reltablespace = t.oid 
WHERE 
  t.spcname = 'indexes_old';
9 голосов
/ 11 февраля 2011

В PostgreSQL табличное пространство может использоваться любой базой данных PostgreSQL. (Пока запрашивающий пользователь имеет достаточные привилегии, то есть.) Я думаю, что этот запрос

SELECT spcname, spclocation FROM pg_tablespace;

покажет вам каталог, который index_old использует в файловой системе в версии PostgreSQL до 9.1. Бродите там, чтобы увидеть, не является ли что-то реальное на вашем пути. Однако я бы очень осторожно пытался удалить что-либо там, кроме использования интерфейса PostgreSQL.

В 9.2+ попробуйте

select spcname, pg_tablespace_location(oid) from pg_tablespace;
3 голосов
/ 04 ноября 2017

В PG 10 и, возможно, немного раньше, это, похоже, перешло в:

SELECT tablename from pg_tables WHERE tablespace = 'foo';
1 голос
/ 27 апреля 2018

К сожалению, существует "глобальный" вид для всех баз данных. Однако это можно сделать с помощью расширения dblink вместе со следующей функцией:

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;

Функция принимает имя табличного пространства, а также имя пользователя и пароль, действительные для всех баз данных на текущем сервере.

Если имя табличного пространства передается как null, отображаются все объекты, которые не находятся в табличном пространстве по умолчанию (это будет pg_global в установке по умолчанию без каких-либо дополнительных табличных пространств)

Это можно использовать так:

select *
from show_tablespace_objects('indexes_old', 'postgres', 'verysecretpassword');
0 голосов
/ 17 октября 2011

Мы говорим об интерфейсе PgSQL?

Список схем (табличных пространств) выглядит так:

\dn

Список всех таблиц внутри схемы (табличного пространства) выглядит следующим образом:

\dn <table_space>.*

Используйте

\?

для дополнительных опций

...