损坏的pg_class数据?不存在的表上的ghost索引

时间:2015-01-20 16:04:51

标签: database postgresql indexing postgresql-9.3

我在创建/删除索引时遇到了一些问题。 最初我有

DROP INDEX IF EXISTS ros_tmp_schoolid_IX;

然后

CREATE INDEX ros_tmp_schoolid_IX on ros.sometable USING btree (somecolumn);

它抱怨索引已经存在

然后我将方法改为

IF EXISTS (SELECT 1
            FROM   pg_class c
            JOIN   pg_namespace n ON n.oid = c.relnamespace
            WHERE  c.relname = 'ros_tmp_schoolid_IX'
            AND    n.nspname = 'ros')
THEN
    DROP INDEX ros_tmp_schoolid_IX;
END IF;

但是我仍然没有得到索引错误...所以我查看了pg_class表,我能够找到该索引的记录。

我也尝试了以下所有内容,但都没有效果:

  1. 放下桌子;
  2. 重新索引/分析/清空整个数据库
  3. reindex table pg_class
  4. 我使用Postgresql 9.3和Rails(4.1.5)。这在运行我的测试套件时随机发生...当处理大块数据时,我使用临时表并在作业完成后删除它们。

    我不确定可能导致此问题的原因。还有什么我应该研究的吗?

    谢谢!

    ======

    另外,我在pg_class中发现了几个,我想我需要一种方法来清理它。

    所以我尝试在不同的表上创建具有相同名称的索引,并且它成功了。 但是......当我试图再次放弃它时......我得到的关系不存在错误。我试图在此之后运行CREATE INDEX查询,然后它说这种关系已经存在... postgres无法决定......

1 个答案:

答案 0 :(得分:1)

简短版:您想要包含架构的名称:

 DROP INDEX IF EXISTS ros.ros_tmp_schoolid_IX;

<强>解释

创建索引时,它会自动进入与指定表相同的模式。甚至不允许使用模式名称,因为doc表示:

  

此处不能包含架构名称;索引总是在。中创建的   与其父表相同的模式

但是,在删除索引时,如果架构不在搜索路径中,则需要指定架构。在您的情况下,大概ros不在search_path

同样如评论中所述,带有大写字母但未用双引号括起来的索引名称将转换为小写,因此在CREATE INDEX ros_tmp_schoolid_IX ...后,您会在{{ros_tmp_schoolid_ix中找到pg_class.relname 1}}