On Thu, Dec 4, 2014 at 9:05 AM, Etsuro Fujita <fujita.ets...@lab.ntt.co.jp>
wrote:

> (2014/12/03 19:35), Ashutosh Bapat wrote:
>
>> On Tue, Dec 2, 2014 at 8:29 AM, Etsuro Fujita
>> <fujita.ets...@lab.ntt.co.jp <mailto:fujita.ets...@lab.ntt.co.jp>> wrote:
>>
>
>  This is not exactly extension of non-inheritance case. non-inheritance
>> case doesn't show two remote SQLs under the same plan node. May be you
>> can rename the label Remote SQL as Remote UPDATE/INSERT/DELETE (or
>> something to that effect) for the DML command and the Foreign plan node
>> should be renamed to Foreign access node or something to indicate that
>> it does both the scan as well as DML. I am not keen about the actual
>> terminology, but I think a reader of plan shouldn't get confused.
>>
>> We can leave this for committer's judgement.
>>
>
> Thanks for the proposal!  I think that would be a good idea.  But I think
> there would be another idea.  An example will be shown below.  We show the
> update commands below the ModifyTable node, not above the corresponding
> ForeignScan nodes, so maybe less confusing.  If there are no objections of
> you and others, I'll update the patch this way.
>
> postgres=# explain verbose update parent set a = a * 2 where a = 5;
>                                      QUERY PLAN
> ------------------------------------------------------------
> -------------------------
>  Update on public.parent  (cost=0.00..280.77 rows=25 width=10)
>    On public.ft1
>      Remote SQL: UPDATE public.mytable_1 SET a = $2 WHERE ctid = $1
>    On public.ft2
>      Remote SQL: UPDATE public.mytable_2 SET a = $2 WHERE ctid = $1
>    ->  Seq Scan on public.parent  (cost=0.00..0.00 rows=1 width=10)
>          Output: (parent.a * 2), parent.ctid
>          Filter: (parent.a = 5)
>    ->  Foreign Scan on public.ft1  (cost=100.00..140.38 rows=12 width=10)
>          Output: (ft1.a * 2), ft1.ctid
>          Remote SQL: SELECT a, ctid FROM public.mytable_1 WHERE ((a = 5))
> FOR UPDATE
>    ->  Foreign Scan on public.ft2  (cost=100.00..140.38 rows=12 width=10)
>          Output: (ft2.a * 2), ft2.ctid
>          Remote SQL: SELECT a, ctid FROM public.mytable_2 WHERE ((a = 5))
> FOR UPDATE
> (12 rows)
>
>
Looks better.


>      IIUC, even the transactions over the local and the *single* remote
>>     server are not guaranteed to be executed atomically in the current
>>     form.  It is possible that the remote transaction succeeds and the
>>     local one fails, for example, resulting in data inconsistency
>>     between the local and the remote.
>>
>
>  IIUC, while committing transactions involving a single remote server,
>> the steps taken are as follows
>> 1. the local changes are brought to PRE-COMMIT stage, which means that
>> the transaction *will* succeed locally after successful completion of
>> this phase,
>> 2. COMMIT message is sent to the foreign server
>> 3. If step two succeeds, local changes are committed and successful
>> commit is conveyed to the client
>> 4. if step two fails, local changes are rolled back and abort status is
>> conveyed to the client
>> 5. If step 1 itself fails, the remote changes are rolled back.
>> This is as per one phase commit protocol which guarantees ACID for
>> single foreign data source. So, the changes involving local and a single
>> foreign server seem to be atomic and consistent.
>>
>
> Really?  Maybe I'm missing something, but I don't think the current
> implementation for committing transactions has such a mechanism stated in
> step 1.  So, I think it's possible that the local transaction fails in
> step3 while the remote transaction succeeds, as mentioned above.
>
>
PFA a script attached which shows this. You may want to check the code in
pgfdw_xact_callback() for actions taken by postgres_fdw on various events.
CommitTransaction() for how those events are generated. The code there
complies with the sequence above.


>
> Thanks,
>
> Best regards,
> Etsuro Fujita
>



-- 
Best Wishes,
Ashutosh Bapat
EnterpriseDB Corporation
The Postgres Database Company

Reply via email to