PostgreSQL语句缓存干扰预期结果

2024-03-29 00:44:16 发布

您现在位置:Python中文网/ 问答频道 /正文

我们已经编写了一个PL/pgSQL函数来将时间戳记录到审计表中。 然而,PostgresSQL语句缓存并没有在每个 调用,这将导致过时(意味着旧的)时间戳记录在审计表中。你知道吗

我们正在运行Postgres9.2。根据文件 http://www.postgresql.org/docs/9.2/static/plpgsql-implementation.html#PLPGSQL-PLAN-CACHING(滚动到文章底部),建议依赖于对now()的调用。你知道吗

此功能未按预期工作:

CREATE OR REPLACE FUNCTION save(txd integer) RETURNS void AS $$
BEGIN
    INSERT INTO audit (id, mtime) VALUES (txd,now());
END;$$

表定义为:

CREATE TABLE audit (
  id integer NOT NULL,
  mtime timestamp without time zone NOT NULL,
  CONSTRAINT audit_pkey PRIMARY KEY (id)
  )

可以使用一个使用psycopg2的简单python 2.7脚本来演示这个问题:

import datetime, psycopg2, time
def tm():
    # connect and clear contents
    con = psycopg2.connect('dbname=postgres user=postgres')
    cur = con.cursor()
    cur.execute('TRUNCATE audit')

    # Add a record, wait a second, add another
    cur.execute('SELECT save(1)')
    time.sleep(1.0)
    cur.execute('SELECT save(2)')

    # List the contents
    cur.execute('SELECT * FROM audit')
    for row in cur.fetchall():
        print("modified %s" % row[1])
    cur.close()
    con.close()

如果运行这个脚本,您会注意到modified times的两个实例将报告完全相同的值,即使我们在插入之间插入了一个小的1秒睡眠

>>> tm()
modified 2016-05-10 11:05:21.766005
modified 2016-05-10 11:05:21.766005

注意:我们甚至尝试了postgres在linked中提供的例子 文章。使用他们的示例,输出没有差别:

CREATE OR REPLACE FUNCTION save(txd integer) RETURNS void AS $$
DECLARE
    curtime timestamp;
BEGIN
    curtime = 'now';
    INSERT INTO audit (id, mtime) VALUES (txd,curtime);
END;$$

有人能告诉我们哪里出了问题吗?你知道吗


Tags: idexecutetimesavecreatepostgresintegeraudit