Thread: Re: [Re] Re: PREPARE and transactions

Re: [Re] Re: PREPARE and transactions

From
"Merlin Moncure"
Date:
Jeroen wrote:
> Granted, that's probably going to force the issue.  I do wonder
though:
> one of the arguments in favour of the current semantics is that the
> problems can be worked around using nested transactions.  Then what
were
> people doing before nested transactions, in Tom's scenario where the
> programmer doesn't know where transactions begin?

The trick is that with the current semantics, you don't have to watch
transaction activity, just the prepare statements.  You know if and when
(from the client/driver's point of view) a prepared statement exists
because you created it and don't have to be concerned about the
lifetime.

If you guys change the lifetime, it becomes difficult or impossible to
set a flag on the client which guarantees prepared statement existence.
This means I have to wrap the statement execution with a subtransaction
or run the risk of bouncing a current transaction.  Currently in the
applications I write 70% of all I/O goes through prepared
statements...the reason to do this was to reduce statement turnaround
latency, which is the main driving performance factor in COBOL
applications.

I would be fine with changing the lifetime if an EXECUTE failure did not
abort the current transaction.  Then I could simply watch the return
code of the statement execution and prepare the statement on
demand...from my point of view, this would actually be the most elegant
scenario.

Merlin


Re: [Re] Re: PREPARE and transactions

From
Alvaro Herrera
Date:
On Fri, Jun 25, 2004 at 08:54:57AM -0400, Merlin Moncure wrote:

> I would be fine with changing the lifetime if an EXECUTE failure did not
> abort the current transaction.  Then I could simply watch the return
> code of the statement execution and prepare the statement on
> demand...from my point of view, this would actually be the most elegant
> scenario.

BEGIN;... do something ... ;SUBBEGIN;    EXECUTE ...;    -- if it fails:    -- SUBABORT;    -- PREPARE ...;    --
SUBBEGIN;   -- EXECUTE ...;    -- can continue as if nothing happenedSUBCOMMIT;
 
COMMIT;

-- 
Alvaro Herrera (<alvherre[a]dcc.uchile.cl>)
"Acepta los honores y aplausos y perderás tu libertad"



Re: [Re] Re: PREPARE and transactions

From
"Merlin Moncure"
Date:
Jeroen wrote:
> I see how making PREPARE obey rollbacks would be inconvenient for some
> existing code, but frankly I'm getting a bit worried about the "why
should
> I care whether what I do is committed or not?" argument.  I guess one
> could
> say that about lots of statements: "I don't really want this to be
subject
> to the transaction but it happens convenient for me to write it inside
the
> transaction, and then I have this problem that it's affected by
> rollbacks."
> If it's that important, come up with a generic
"session-not-transaction"
> syntax to temporarily escape bracketing.

The big picture here is that with the current behavior, it is possible
to keep track of existence of prepared statements without wrapping or
even being aware of transaction activity.  This is tremendously useful
for handling them in a generic way because transactions and prepared
statements are handled on different levels of my (and others')
technology stack.  If you change that behavior, that is no longer
possible, period, and I will be forced to stop using them.

On the conceptual side of things, I submit that the creation and
deletion of prepared statements are much closer to session variables
than to normal imperative SQL (that normally has a transactional
lifetime).  They are an optimization hack (albeit a very handy one) much
the same as turning off sequential scans.  I tend to think of them more
as macros that I can create and destroy (and in implementation, that is
really close to what they are).

Merlin


Re: [Re] Re: PREPARE and transactions

From
"Jeroen T. Vermeulen"
Date:
On Thu, Jul 01, 2004 at 04:06:06PM -0400, Merlin Moncure wrote:
> The big picture here is that with the current behavior, it is possible
> to keep track of existence of prepared statements without wrapping or
> even being aware of transaction activity.  This is tremendously useful
> for handling them in a generic way because transactions and prepared
> statements are handled on different levels of my (and others')
> technology stack.  If you change that behavior, that is no longer
> possible, period, and I will be forced to stop using them.
But then how can you be sure that other layers in your stack won't try to
re-establish a broken connection, multiplex sessions, pool connections,
parallellize transactions or prepare their own statements?


> On the conceptual side of things, I submit that the creation and
> deletion of prepared statements are much closer to session variables
> than to normal imperative SQL (that normally has a transactional
> lifetime).  They are an optimization hack (albeit a very handy one) much
> the same as turning off sequential scans.  I tend to think of them more
> as macros that I can create and destroy (and in implementation, that is
> really close to what they are).

Here lies the real problem: if only they were _designed_ as an optimization
hack, things would be fine.  Just make them anonymous and let the server
pattern-match them; no need to change your code to keep it working.

In fact...

What if we allowed the backend to match queries to the patterns of
prepared statements without actually naming them?  You'd then have two
ways of executing a prepared query:

1. EXECUTE, as we do now, which involves naming the statement and that's
where the trouble begins.  So probably best to avoid this approach, unless
you PREPARE and EXECUTE in the same transaction and so know exactly what's
going on.

2. Issue your query as normal; the backend will find that it matches a
prepared query (regardless of what it's called) and use the plan stored
there.  Optimizing a program to use prepared queries is a mere matter of
adding the PREPARE, and no other program statements need to be changed. 
The worst that can happen is that you accidentally lose an opportunity
to apply the prepared plan somewhere.

The great benefit of 2 would be that the server can cache & reuse prepared
statements across transactions, _without transferring any semantic state_
in these strange and exotic ways.  In other words, no matter what happens to
the prepared statement, your code will still run.  And probably still
benefit from the optimization; you get the freedom to tweak that further as
you like, but it needn't affect existing code.  Middleware writers won't
even need to parse SQL statements to replace them with EXECUTEs anymore.

Other benefits we could eventually get out of this would be dynamic
garbage collection; reuse across sessions; dynamic, server-side choice
between multiple overlapping ("specialized") prepared statements; quietly
accepted redefinitions that make syntactic sense.

Of course this would take some work, both in developer time and execution
time, but it would allow us to have sensible transaction semantics on the
one hand, and optimization (and simplified at that!) on the other.

Am I making things too simple here?


Jeroen



Re: [Re] Re: PREPARE and transactions

From
"Merlin Moncure"
Date:
> > The big picture here is that with the current behavior, it is
possible
> > to keep track of existence of prepared statements without wrapping
or
> > even being aware of transaction activity.  This is tremendously
useful
> > for handling them in a generic way because transactions and prepared
> > statements are handled on different levels of my (and others')
> > technology stack.  If you change that behavior, that is no longer
> > possible, period, and I will be forced to stop using them.
>
> But then how can you be sure that other layers in your stack won't try
to
> re-establish a broken connection, multiplex sessions, pool
connections,
> parallellize transactions or prepare their own statements?

Because the prepared statement and the connection are handled on the
same level, and will always be.  If and when I decide to implement
multiplexing/pooling, this has to be handled a level above my driver.
Since the applications my driver is serving are written in COBOL,
prepared statement creation is highly unlikely (plus the statement names
are well mangled).  My driver wraps the SQL interface and exposes some
of it as COBOL file I/O statements and some as library commands.

> What if we allowed the backend to match queries to the patterns of
> prepared statements without actually naming them?  You'd then have two
> ways of executing a prepared query:

I would not necessarily be opposed to this type of optimization but it
seems more complicated.  It would be up to smarter people than me to
judge it's value vs. implementation cost :).  ISTM you are losing a
slight advantage in parsing time vs. a more general query plan
generation time speedup.

Right now, I'm transitioning to ExexPrepared to skip the string escaping
step on the client side.  I would hate to lose that ability.  ExecParams
is a little more work to set up (doable, though).

> Am I making things too simple here?

Unfortunately, I think the answer is yes.  Being able to roll back
prepared statements would exclude them from a narrow but important class
of use.

With the introduction of nested x into the code base, your original
problem can be guarded against (albeit somewhat clumsily) by careful use
of wrapping PREPARE/DEALLOCATE.  If you switch things up, every EXECUTE
has to be wrapped to guarantee safety in a transaction agnostic
scenario.

Now, which would you rather do: wrap PREPARE, or wrap EXECUTE?

Merlin





Re: [Re] Re: PREPARE and transactions

From
"Jeroen T. Vermeulen"
Date:
On Fri, Jul 02, 2004 at 08:51:05AM -0400, Merlin Moncure wrote:
> Right now, I'm transitioning to ExexPrepared to skip the string escaping
> step on the client side.  I would hate to lose that ability.  ExecParams
> is a little more work to set up (doable, though).
OTOH, if you're taking client code queries and replacing them with
EXECUTEs (which I sort of gathered some people were doing), all it should
really do is move the matching activity to the server...

> > Am I making things too simple here?
> 
> Unfortunately, I think the answer is yes.  Being able to roll back
> prepared statements would exclude them from a narrow but important class
> of use.  

Wait, wait, wait!  I'm talking about the pattern-matching proposal there.
The proposal means that prepared statement introduction would _not_ have
to be rolled back; only the _names_ would obey different rules.  In effect
it would separate the names from the plans, and make the plans do what you
want and more.  The names would be effectively obsolete.


> With the introduction of nested x into the code base, your original
> problem can be guarded against (albeit somewhat clumsily) by careful use
> of wrapping PREPARE/DEALLOCATE.  If you switch things up, every EXECUTE
> has to be wrapped to guarantee safety in a transaction agnostic
> scenario.

But why should anyone insist on a "transaction agnostic scenario" yet 
play with prepared statements?  That seems backwards to me.  Transactions
are a correctness issue, which you think about first.  Prepared statements
are optimization, which though important is undoubtedly a lesser concern.
If you're deep enough into the SQL stream to analyze the client's demands
and prepare statements based on it, just knowing what happens to bracketing
(unlike prepared statements, you don't even need to control that) should be
relatively easy.

In any case, AFAICS my proposal does away with the need to wrap anything,
or keep track of transactions and/or prepared statements.  Would it work
for you?


Jeroen



Re: [Re] Re: PREPARE and transactions

From
"Merlin Moncure"
Date:
> > Right now, I'm transitioning to ExexPrepared to skip the string
escaping
> > step on the client side.  I would hate to lose that ability.
ExecParams
> > is a little more work to set up (doable, though).
>
> OTOH, if you're taking client code queries and replacing them with
> EXECUTEs (which I sort of gathered some people were doing), all it
should
> really do is move the matching activity to the server...

There is one subtle difference, and that the type resolution gets moved
from the server to the client.  ExecParams() requires a list of type
OIDs to be sent along with the statement whereas ExecPrepared() does
not.  To me, this is an inconsistent interface is set up with the
parameter name, not the oid of the parameter.  To me, it makes much more
sense to resolve by type name in all cases, but this may have some
performance implications.

> But why should anyone insist on a "transaction agnostic scenario" yet
> play with prepared statements?  That seems backwards to me.
Transactions

Because it improved statement turnaround by about 33%, and that's all I
really care about.  The conceptual case seems outweighed by practical
matters (if you move to a transactional lifetime first, that is).  This
performance difference is like having an extra processor.

> In any case, AFAICS my proposal does away with the need to wrap
anything,
> or keep track of transactions and/or prepared statements.  Would it
work
> for you?

Yes, it would.  It would actually make my life a lot easier
(notwithstanding my minor gripe with ExecParams) because I would no
longer have to deal with all the complexities surrounding prepared
statements.  This is A Good Thing, because the optimization is generic
and thus will benefit a lot more people.

It is also more a more complex optimization model; and I think you would
have to justifiably prove that it is in the same performance league as
the current prepared statement model.  Also the current prepared
statement behavior should be retained for 7.5 and perhaps deprecated if
your viewpoint wins out (and it should).

Merlin








Re: [Re] Re: PREPARE and transactions

From
"Jeroen T. Vermeulen"
Date:
On Fri, Jul 02, 2004 at 11:18:44AM -0400, Merlin Moncure wrote:
> Yes, it would.  It would actually make my life a lot easier
> (notwithstanding my minor gripe with ExecParams) because I would no
> longer have to deal with all the complexities surrounding prepared
> statements.  This is A Good Thing, because the optimization is generic
> and thus will benefit a lot more people.  
Okay, off I go into the source code then.  :-)

(Which is not to say "I'll have it ready next week" but I can get an idea
of how hard it would be)


> It is also more a more complex optimization model; and I think you would
> have to justifiably prove that it is in the same performance league as
> the current prepared statement model.  Also the current prepared

True, there is a cost.  OTOH I think the added advantages could pay off
as well, e.g. sharing plans between backends (if there's not too much
locking.


> statement behavior should be retained for 7.5 and perhaps deprecated if
> your viewpoint wins out (and it should).

I guess so.  My timing isn't exactly impeccable...


Jeroen