【发布时间】:2013-04-12 00:33:35
【问题描述】:
简短的故事: 我有一个带有表的分区 postgres 数据库来跟踪分区和触发器。触发器需要更改分区表上的约束(它们的valid_date [daterange] 会根据另一个分区的valid_date 更改)并且最好能够删除表,但这会导致错误,因为触发器链正在使用这些表。
cannot ALTER TABLE "core_geometryrecord_8_2" because it is being used by active queries in this session
完整问题: 我正在对我的架构和触发器架构进行彻底的解释,以防万一,或者有人想知道为什么我觉得需要一个“复杂”的系统,尽管这可能没有必要。 p>
我正在重构一个包含几何数据的大型数据库,以使其更易于使用且更快捷。旧系统具有保存相关几何的“几何表”(即美国的县)。数据实际上应该按“date_valid”和“geometrytable_id”分组。
我们决定使用带有 date_valid(日期范围)和 geometrytable_id(外键)约束的 postgres 分区。
因为日期很敏感,并且需要大量记账才能保持正确,所以我亲自尝试使用触发器管理大部分数据库(我已经知道我需要为分区表添加一个插入触发器,所以为什么不这样做) .
我设计了一组触发器,用于管理分区列表并在您插入或删除几何图形时进行所有记账。他们就是这样做的。
- 在插入分区列表表时,创建分区表并应用约束。如果某个日期的 partitionvalid 与这个新的日期重叠(呼叫更新触发器),则修剪它。如果有一个分区在该日期之后的某个日期有效,则将新分区的结束日期修剪为下一个分区的开始日期(保持连续的时间轴)。
- 从分区列表表中删除时,删除分区表。重新计算已删除分区(如果有)周围的 partition_list 条目(调用更新触发器)的日期范围,以使日期连续。
- 在更新分区列表表时,DROP OLD DATE CONSTRAINT,将分区表中所有行的 date_valid 更改为分区的新 date_valid 值,然后 CREATE DATE CONSTRAINT 与新日期(约束是项目具有完全相同的date_valid 作为分区)。
- 在插入到geometryrecord(分区表)时,找到应该使用的分区,或者插入到分区列表表中(TRIGGERS ON INSERT)。将 NEW 插入正确的分区。
- 在从几何记录中删除时,如果分区表现在为空,则从分区列表表中删除分区条目 (CALLS DELETE TRIGGER)。
如果我在链中的任何触发器中完全触摸过它,它就会因为我试图以任何方式改变桌子而生气。如果我直接插入到该表中,则分区列表表的触发器可以完美地工作,但是从几何表中删除(调用相同的触发器)会翻转,即使它所做的只是一个选择(查看分区表是否为空)。插入分区几何表也可能导致问题,因为我必须删除约束才能更改行的 date_valid。
必须有一种我不明白的方法来做到这一点。 (我还必须使删除表变得更加被动,“将其标记为通过 cron 作业删除”,因为我无法从源自我要删除的表的触发器调用中删除该表。)
非常欢迎任何建议。我简直不敢相信没有人需要做这样的事情,所以我想我只是不知道自己在做什么:)。
【问题讨论】:
-
您是从触发器内部执行 DDL 吗?
-
哇,我想我刚刚了解了 DDL 和 DML 之间的区别(主要是有区别)。是的,我需要从触发器中进行更改或删除。
标签: postgresql triggers plpgsql database-partitioning postgresql-9.2