25

我创建了一个名为 的新表空间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_upgrade 工具从 Pg 8.4 迁移到 Pg 9.0。

表空间如下所示:

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

/data/pgindex84 的内容包括所有旧的 8.4 索引,加上 pg_upgrade 自动创建的这个新的 9.0 索引

# 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
4

6 回答 6

18

检查 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';
于 2011-02-11T15:59:10.590 回答
11

在 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;
于 2011-02-11T15:53:58.053 回答
4

在 PG 10 和可能更早的版本中,这似乎已经演变为:

SELECT tablename from pg_tables WHERE tablespace = 'foo';
于 2017-11-04T18:42:51.380 回答
2

不幸的是,所有数据库都有“全局”视图。但是,这可以使用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');
于 2018-04-27T09:14:08.590 回答
1

十年后,我遇到了这个问题,上面的一个小评论帮助我找到了解决方案。select * from pg_tables where tablespace = 'my_tablespace';仅列出当前数据库中使用该表空间的表。您必须循环浏览您尝试使用该命令的每个数据库,以找到使用该表空间的数据库。

于 2020-05-16T01:23:00.343 回答
-6

我们在谈论 PgSQL 接口吗?

像这样列出模式(表空间):

\dn

列出架构(表空间)中的所有表,如下所示:

\dn <table_space>.*

采用

\?

更多选择

于 2011-10-17T10:23:49.470 回答