Как я могу узнать, что находится в табличном пространстве Postgresql?

17

Я создал новое табличное пространство, называемое 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
    
задан Andy Lester 11.02.2011 в 16:39
источник
  • У меня была эта проблема в Windows, и оказалось, что я открыл соединение с базой данных. –  Neoheurist 24.06.2017 в 18:30

5 ответов

11

Проверьте 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';
    
ответ дан Frank Heikens 11.02.2011 в 16:59
  • Также возвращает 0 строк. Я начинаю думать, что это проблема с тем, как pg_upgrade меня мигрировал. –  Andy Lester 11.02.2011 в 17:01
  • Затем откройте проводник (Windows) или командную строку, чтобы увидеть, какие файлы остались в этом табличном пространстве. Используйте oid в качестве входных данных для ваших запросов, чтобы они соответствовали объектам PostgreSQL. –  Frank Heikens 11.02.2011 в 17:03
  • Я добавил список каталогов в исходном вопросе. Один из файлов - 10462602, который, как я полагаю, является OID? Как я могу сказать, где это используется? –  Andy Lester 11.02.2011 в 17:05
  • Да, это и есть. С этим номером должен быть какой-то объект базы данных (таблица, индекс, что-то еще). –  Frank Heikens 11.02.2011 в 17:29
  • это может быть relfilenode (столбец pg_class), а не oid, если таблица была переписана в какой-то момент –  araqnid 11.02.2011 в 19:52
9

В 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;
    
ответ дан Mike Sherrill 'Cat Recall' 11.02.2011 в 16:53
  • Postgres удалил spclocation с версии 9.2 –  Alvin 07.07.2014 в 21:58
  • @ Алвин: Спасибо. Обновлен ответ. –  Mike Sherrill 'Cat Recall' 07.07.2014 в 22:27
2

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

SELECT tablename from pg_tables WHERE tablespace = 'foo';
    
ответ дан Shorthand 04.11.2017 в 19:42
  • У вас, кажется, есть некоторые умные цитаты. –  Fake Name 27.04.2018 в 06:34
1

К сожалению, существует «глобальный» вид во всех базах данных. Однако это можно сделать, используя расширение 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');
    
ответ дан a_horse_with_no_name 27.04.2018 в 11:14
-5

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

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

\dn

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

\dn <table_space>.*

Использование

\?

для дополнительных параметров

    
ответ дан Philluminati 17.10.2011 в 12:23
  • Прошу прощения, но я думаю, что вы ошибаетесь: табличное пространство и схема - это две разные вещи в postgresql. –  alfonx 15.01.2012 в 12:42