Может ли Postgres запускать "сценарии" для обслуживания данных?

В нашей производственной базе данных Aurora RDS Postgres мне нужно создать новую таблицу, используя данные из исходной таблицы с 2 миллиардами строк.

Мне нужно будет использовать функцию pgplsql для создания данных для новой таблицы.

Поскольку каждая функция является транзакцией, я предполагаю, что выполнение этого с одним вызовом функции не будет работать.

Я собираюсь сделать следующее:

  1. Создайте функцию, которая будет создавать и вставлять небольшой пакет данных.
  2. Повторно вызывайте функцию с помощью Java-сервиса или лямбды, пока не будут созданы все данные.
    - К сожалению, использование pg_cron не вариант, так как он не поддерживается Aurora Postgres

Создание java-сервиса или лямбды (или чего-то еще, просто вызывающего функцию) - это то, чего я бы хотел избежать.

Для наших баз данных MS SQL мы просто запускаем скрипт из SSMS, который будет создавать и фиксировать данные небольшими партиями в цикле. Нечто похожее на это, кажется, не вариант в Postgres.

Есть ли другие варианты, которые вы можете предложить?

Спасибо за ваши идеи!

1 ответ

Решение

Другой вариант - использовать Powershell для повторного вызова функции с использованием psql.

Я создал функцию postgres, которая возвращает идентификатор статуса, который сообщает вызывающей стороне, завершена она или нет. Он всегда возвращает сообщение о состоянии, чтобы можно было отслеживать ход выполнения функции.

Логически функция работает так:

  • создать таблицу (если она не существует) и заполнить ее метаданными, определяющими, сколько раз должна вызываться функция

  • прочитайте контрольную таблицу, чтобы определить, осталась ли какая-либо работа, если не осталось работы, верните 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
*/
Другие вопросы по тегам