postgres中表列中的奇怪行为

时间:2011-05-26 13:58:46

标签: postgresql

我目前正在使用postgres 8.3。我创建了一个表,作为另一个表中存在的成员的脏标志表。我在成员表上插入或更新后应用了触发器,它将在修改表上插入/更新值为true的记录。触发器似乎有效,但是我注意到某些东西正在翻转boolean is_modified值。我不知道如何试图找出可以翻转它的东西。

触发功能:

 BEGIN;
     CREATE OR REPLACE FUNCTION set_member_as_modified() RETURNS TRIGGER AS $set_member_as_modified$
  BEGIN
LOOP
  -- first try to update the key
  UPDATE member_modification SET is_modified = TRUE, updated = current_timestamp WHERE "memberID" = NEW."memberID";
  IF FOUND THEN
    RETURN NEW;
  END IF;
  --member doesn't exist in modification table, so insert them
  -- if someone else inserts the same key conncurrently, raise a unique-key failure
  BEGIN
    INSERT INTO  member_modification("memberID",is_modified,updated) VALUES(NEW."memberID", TRUE,current_timestamp);
    RETURN NEW;
  EXCEPTION WHEN unique_violation THEN
    -- do nothing, and loop to try the update again
  END;
END LOOP;
  END;
$set_member_as_modified$ LANGUAGE plpgsql;
COMMIT;

CREATE TRIGGER set_member_as_modified AFTER INSERT OR UPDATE ON members FOR EACH ROW EXECUTE PROCEDURE set_member_as_modified();

这是我运行的sql和结果:

     $CREATE TRIGGER set_member_as_modified AFTER INSERT OR UPDATE ON members FOR EACH ROW EXECUTE PROCEDURE set_member_as_modified(); 

结果:

     UPDATE 1
     bluesky=# select * from member_modification;
    -[ RECORD 1 ]---+---------------------------
 modification_id | 14
 is_modified     | t
 updated         | 2011-05-26 09:49:47.992241
 memberID        | 182346

bluesky=# select * from member_modification;
-[ RECORD 1 ]---+---------------------------
modification_id | 14
is_modified     | f
updated         | 2011-05-26 09:49:47.992241
memberID        | 182346

正如您所看到的,有些东西会翻转is_modified值。我可以使用postgres中的任何内容来确定哪些查询/进程正在对此表进行操作?

1 个答案:

答案 0 :(得分:1)

你确定你发布了所需的一切吗? member_modification上的两个查询建议在两者之间运行一个单独的查询,将is_modified设置为false。

您可以向text[]添加member_modification字段,例如query_trace text[] not null default '{}',然后在该表的每一行上插入/更新触发器之前的内容类似于:

NEW.query_trace := NEW.query_trace || current_query();

如果8.3中没有current_query(),请参阅:

http://www.postgresql.org/docs/8.3/static/monitoring-stats.html

SELECT pg_stat_get_backend_pid(s.backendid) AS procpid,
       pg_stat_get_backend_activity(s.backendid) AS current_query
    FROM (SELECT pg_stat_get_backend_idset() AS backendid) AS s;

然后,您可以获取影响它的后续查询列表:

select query_trace[i] from generate_series(1, array_length(query_trace, 1)) as i