我目前正在使用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中的任何内容来确定哪些查询/进程正在对此表进行操作?
答案 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