VACUUM 不能从函数或多命令字符串执行
Posted
技术标签:
【中文标题】VACUUM 不能从函数或多命令字符串执行【英文标题】:VACUUM cannot be executed from a function or multi-command string 【发布时间】:2014-03-12 20:35:44 【问题描述】:我使用 PL/pgSQL 编写了一个脚本,在 pgAdmin III 中运行。该脚本删除现有的数据库内容,然后为所需的测试场景(通常是各种类型的负载测试)添加一堆“样本”数据。加载数据后,我想对受影响的表进行“真空分析”,以从已删除的记录中恢复空间并准确反映新内容。
我可以使用各种解决方法(例如,手动执行 VACUUM ANALYZE,在脚本中包含用于各种结构的 drop/create 语句等)但是,我真正想做的是:
DO $$
BEGIN
-- parent table
FOR i IN 1..10000 LOOP
INSERT INTO my_parent_table( ... ) VALUES ...;
END LOOP;
VACUUM ANALYZE my_parent_table;
-- child table
FOR i IN 1..50000 LOOP
INSERT INTO my_child_table( ... ) VALUES ...;
END LOOP;
VACUUM ANALYZE my_child_table;
END;
$$;
当我运行它时,我得到:
ERROR: VACUUM cannot be executed from a function or multi-command string
然后我尝试像这样将真空语句移到末尾:
DO $$
BEGIN
-- parent table
FOR i IN 1..10000 LOOP
INSERT INTO my_parent_table( ... ) VALUES ...;
END LOOP;
-- child table
FOR i IN 1..50000 LOOP
INSERT INTO my_child_table( ... ) VALUES ...;
END LOOP;
END;
$$;
VACUUM ANALYZE my_parent_table;
VACUUM ANALYZE my_child_table;
这给了我同样的错误。有什么方法可以将真空分析合并到添加数据的同一脚本中?
我正在使用 PostgreSQL v 9.2。
【问题讨论】:
批量insert 之后就不需要真空了。仅当您删除或更新大量数据时才需要vacuum(因为它会回收不再需要的空间)。在您的情况下,analyze
本身就足够了。
谢谢,但我真的想要“真空分析”;在为所需的测试场景添加新数据之前,脚本首先删除所有现有数据。我已经编辑了这个问题以明确这一点。
如果您的脚本首先删除所有现有数据,也许您应该截断表,从而避免需要清理。
除了 jjanes 答案之外,在delete
(或truncate
)之后执行vacuum analyze
before insert
将是瞬间的。
This answer on dba.stackexchange 为我解决了这个问题:在您的函数中调用 ANALYZE
,但将其留给 autovacuum 以优雅地释放空间(只需确保您已为您的大桌子)。
【参考方案1】:
如果您从 pgAdmin3 查询窗口中使用“执行查询”按钮运行此程序,则会将整个脚本作为一个字符串发送到服务器。
如果您从查询窗口的“执行 pgScript”按钮执行它,它会单独发送命令,因此会起作用,但它不容忍匿名块的 DO 语法。您必须创建一个执行当前匿名工作的函数,然后使用以下内容调用“执行 pgScript”:
select inserts_function();
VACUUM ANALYZE my_parent_table;
VACUUM ANALYZE my_child_table;
【讨论】:
pgAdmin4中没有“执行pgScript”按钮 pgAdmin4 那时还不存在。【参考方案2】:我实施的最终解决方案是 a_horse_with_no_name 和 xzilla 在 cmets 中提出的建议的综合:
使用 TRUNCATE 代替 DELETE 避免了对 VACUUM 的需要 ANALYZE 可以根据需要在脚本期间单独使用【讨论】:
以上是关于VACUUM 不能从函数或多命令字符串执行的主要内容,如果未能解决你的问题,请参考以下文章
如何从使用 pg_cron 运行的清除例程中链接 VACUUM?
来自 SQLiteOpenHelper 的 VACUUM sqlite 数据库
Postgresql之VACUUM和VACUUM FULL对比