Postgres可以运行数据维护“脚本”吗?

时间:2018-07-12 22:05:21

标签: postgresql performance function dml amazon-rds-aurora

在生产的Aurora RDS Postgres数据库中,我需要使用20亿行源表中的数据创建一个新表。

我将需要使用pgplsql函数为新表创建数据。

由于每个函数都是事务,因此我认为仅通过一个函数调用即可完成此操作。

我正在考虑做的是:

  1. 创建一个函数,该函数将创建并插入一小批数据。
  2. 使用Java服务或Lambda重复调用该函数,直到全部 数据已创建。
        -不幸的是,不能使用pg_cron,因为Aurora Postgres不支持它。

我想避免创建Java服务或lambda(或其他任何仅调用该函数的事情)。

对于我们的MS SQL数据库,我们只需运行来自SSMS的脚本,该脚本将在循环中小批量创建和提交数据。在Postgres中似乎没有类似的选择。

您还有其他建议吗?

感谢您的想法!

1 个答案:

答案 0 :(得分:0)

另一个选择是使用Powershell使用psql重复调用该函数。

我创建了一个postgres函数,该函数返回一个状态ID,该状态ID告诉调用方是否已完成。它总是返回状态消息,以便可以跟踪功能的进度。

逻辑上,该函数的工作方式如下:

  • 创建一个表(如果不存在),并用元数据填充该表,该元数据控制应调用该函数的次数

  • 读取控制表以确定是否有剩余工作,如果没有剩余工作,则返回0

  • 如果还有工作,请进行批处理,更新控制表并返回1

这是脚本和功能签名:

PowerShell脚本:

Clear-Host;
Set-Location 'C:\Program Files\PostgreSQL\10\bin\';
$status_id = 1;
$env:PGPASSWORD = 'password';
While ($status_id -eq 1) {
    # call the function
    $results = & .\psql --% -h end-point.rds.amazonaws.com -p 5432 -U postgres -d dbname-t -q -c "select o_status_id, o_status from maint.maintainence_function();"

    # split the return value that contains a status id and an array of messages
    $status_id, $status = $results.split("|",2)

    # trim the status id so -eq can properly evaluate it
    $status_id = $status_id.Trim()

    # remove the double quote and curly braces from the array of messages.  The array of one or more messages is returned as a string in this standard postgres format:
    # {"07/18/2018 11:07:01: Message 1"}
    # {"07/18/2018 11:07:01: Message 1","07/18/2018 11:07:01: Message 2"}
    $status = $status.Replace('"','');
    $status = $status.Replace("}","");
    $status = $status.Replace("{","");
    $status = $status.Trim();

    # split the messages and output to console
    $status.Split(",");
    Start-Sleep -Seconds 2;
}

Postgres函数签名:

CREATE OR REPLACE FUNCTION maint.maintainence_function (
    OUT o_status_id SMALLINT,
    OUT o_status VARCHAR(300)[]
)
RETURNS RECORD
AS $$
/*
RETURNS
    o_status_id
        0: SUCCESS: Function called successfully, all work is completed.  Service should NOT call function again.
        1: IN PROGRESS: Function called successfully, all work is NOT completed.  Service should call function again.
        2: Failed: Function called failed.  Service should NOT call function again.

    o_status
        Array of progress messages to be displayed in console
*/