Re: parallel mode and parallel contexts

Поиск
Список
Период
Сортировка
От Andres Freund
Тема Re: parallel mode and parallel contexts
Дата
Msg-id 20150318231036.GB9495@alap3.anarazel.de
обсуждение исходный текст
Ответ на Re: parallel mode and parallel contexts  (Robert Haas <robertmhaas@gmail.com>)
Ответы Re: parallel mode and parallel contexts  (Robert Haas <robertmhaas@gmail.com>)
Список pgsql-hackers
On 2015-03-18 12:02:07 -0400, Robert Haas wrote:
> diff --git a/src/backend/access/heap/heapam.c b/src/backend/access/heap/heapam.c
> index cb6f8a3..173f0ba 100644
> --- a/src/backend/access/heap/heapam.c
> +++ b/src/backend/access/heap/heapam.c
> @@ -2234,6 +2234,17 @@ static HeapTuple
>  heap_prepare_insert(Relation relation, HeapTuple tup, TransactionId xid,
>                      CommandId cid, int options)
>  {
> +    /*
> +     * For now, parallel operations are required to be strictly read-only.
> +     * Unlike heap_update() and heap_delete(), an insert should never create
> +     * a combo CID, so it might be possible to relax this restrction, but
> +     * not without more thought and testing.
> +     */
> +    if (IsInParallelMode())
> +        ereport(ERROR,
> +                (errcode(ERRCODE_INVALID_TRANSACTION_STATE),
> +                 errmsg("cannot insert tuples during a parallel operation")));
> +

Minor nitpick: Should we perhaps move the ereport to a separate
function? Akin to PreventTransactionChain()? Seems a bit nicer to not
have the same message everywhere.

> +void
> +DestroyParallelContext(ParallelContext *pcxt)
> +{
> +    int        i;
> +
> +    /*
> +     * Be careful about order of operations here!  We remove the parallel
> +     * context from the list before we do anything else; otherwise, if an
> +     * error occurs during a subsequent step, we might try to nuke it again
> +     * from AtEOXact_Parallel or AtEOSubXact_Parallel.
> +     */
> +    dlist_delete(&pcxt->node);

Hm. I'm wondering about this. What if we actually fail below? Like in
dsm_detach() or it's callbacks? Then we'll enter abort again at some
point (during proc_exit at the latest) but will not wait for the child
workers. Right?
> +/*
> + * End-of-subtransaction cleanup for parallel contexts.
> + *
> + * Currently, it's forbidden to enter or leave a subtransaction while
> + * parallel mode is in effect, so we could just blow away everything.  But
> + * we may want to relax that restriction in the future, so this code
> + * contemplates that there may be multiple subtransaction IDs in pcxt_list.
> + */
> +void
> +AtEOSubXact_Parallel(bool isCommit, SubTransactionId mySubId)
> +{
> +    while (!dlist_is_empty(&pcxt_list))
> +    {
> +        ParallelContext *pcxt;
> +
> +        pcxt = dlist_head_element(ParallelContext, node, &pcxt_list);
> +        if (pcxt->subid != mySubId)
> +            break;
> +        if (isCommit)
> +            elog(WARNING, "leaked parallel context");
> +        DestroyParallelContext(pcxt);
> +    }
> +}

> +/*
> + * End-of-transaction cleanup for parallel contexts.
> + */
> +void
> +AtEOXact_Parallel(bool isCommit)
> +{
> +    while (!dlist_is_empty(&pcxt_list))
> +    {
> +        ParallelContext *pcxt;
> +
> +        pcxt = dlist_head_element(ParallelContext, node, &pcxt_list);
> +        if (isCommit)
> +            elog(WARNING, "leaked parallel context");
> +        DestroyParallelContext(pcxt);
> +    }
> +}

Is there any reason to treat the isCommit case as a warning? To me that
sounds like a pretty much guaranteed programming error. If your're going
to argue that a couple resource leakage warnings do similarly: I don't
think that counts for that much. For one e.g. a leaked tupdesc has much
less consequences, for another IIRC those warnings were introduced
after the fact.

> + * When running as a parallel worker, we place only a single
> + * TransactionStateData is placed on the parallel worker's
> + * state stack,

'we place .. is placed'

>  /*
> + *    EnterParallelMode
> + */
> +void
> +EnterParallelMode(void)
> +{
> +    TransactionState s = CurrentTransactionState;
> +
> +    Assert(s->parallelModeLevel >= 0);
> +
> +    ++s->parallelModeLevel;
> +}
> +
> +/*
> + *    ExitParallelMode
> + */
> +void
> +ExitParallelMode(void)
> +{
> +    TransactionState s = CurrentTransactionState;
> +
> +    Assert(s->parallelModeLevel > 0);
> +    Assert(s->parallelModeLevel > 1 || !ParallelContextActive());
> +
> +    --s->parallelModeLevel;
> +
> +    if (s->parallelModeLevel == 0)
> +        CheckForRetainedParallelLocks();
> +}

Hm. Is it actually ok for nested parallel mode to retain locks on their
own? Won't that pose a problem? Or did you do it that way just because
we don't have more state? If so that deserves a comment explaining that
htat's the case and why that's acceptable.
> @@ -1769,6 +1904,9 @@ CommitTransaction(void)
>  {
>      TransactionState s = CurrentTransactionState;
>      TransactionId latestXid;
> +    bool        parallel;
> +
> +    parallel = (s->blockState == TBLOCK_PARALLEL_INPROGRESS);

> +    /* If we might have parallel workers, clean them up now. */
> +    if (IsInParallelMode())
> +    {
> +        CheckForRetainedParallelLocks();
> +        AtEOXact_Parallel(true);
> +        s->parallelModeLevel = 0;
> +    }

'parallel' looks strange when we're also, rightly so, do stuff like
checking IsInParallelMode(). How about naming it is_parallel_worker or
something?


Sorry, ran out of concentration here. It's been a long day.

Greetings,

Andres Freund

-- Andres Freund                       http://www.2ndQuadrant.com/PostgreSQL Development, 24x7 Support, Training &
Services



В списке pgsql-hackers по дате отправления:

Предыдущее
От: Peter Geoghegan
Дата:
Сообщение: Re: Using 128-bit integers for sum, avg and statistics aggregates
Следующее
От: Andreas Karlsson
Дата:
Сообщение: Re: Using 128-bit integers for sum, avg and statistics aggregates