【问题标题】:Can Postgres run data maintenance 'scripts'?Postgres 可以运行数据维护“脚本”吗?
【发布时间】:2018-12-21 05:52:00
【问题描述】:

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

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

由于每个函数都是一个事务,我假设只用一个函数调用来做这件事是行不通的。

我正在考虑做的是:

  1. 创建一个函数来创建和插入一小批数据。
  2. 使用 java 服务或 lambda 重复调用该函数,直到所有 数据已创建。
    - 不幸的是,使用 pg_cron 不是一个选项,因为 Aurora Postgres 不支持它

我希望避免创建 java 服务或 lambda(或其他任何调用函数)。

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

您还有其他建议吗?

感谢您的想法!

【问题讨论】:

  • 将“批量大小”作为函数的参数。使用参数调用它并在调用后提交。但通常在一个大事务中做某事比许多小事务要快。
  • @a_horse_with_no_name 感谢您的评论。我想在一项大交易中执行此操作,但数据库将承受其他服务的负载。我假设转换 20 亿行将占用所有可用资源。

标签: postgresql performance function dml amazon-aurora


【解决方案1】:

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

我创建了一个 postgres 函数,它返回一个状态 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
*/

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-04-02
    • 1970-01-01
    • 2015-10-13
    • 1970-01-01
    • 2015-09-06
    • 1970-01-01
    相关资源
    最近更新 更多