AW: AW: AW: Issue NOTICE for attempt to raise lock leve l?

Started by Zeugswetter Andreas SBabout 25 years ago4 messages
#1Zeugswetter Andreas SB
ZeugswetterA@wien.spardat.at

For a "select colname from tablename" we do not currently hold any lock
until end of tx. This is the situation you described, and I am worried about.

That's a bug in itself, because the executor's read lock is grabbed by
heap_beginscan and released by heap_endscan, which means it may be
grabbed and released multiple times during a single query (think
nested-loop join). There is nothing to stop someone from, say, dropping
the entire table between scans. I intend to fix that.

Yes, that needs to be fixed.

I am not nearly as worried about long-running transactions that delay
admin actions as I am about admin actions that crash other
transactions.
I do not believe it is safe to drop read locks intra-transaction, and
I am unwilling to take a chance on it being safe so close to 7.1 beta.

I think that this is a substantial modification that bears all sorts of application
side riscs. I absolutely do not think that you do not take chances when keeping
the lock. If you think it is too close to beta, then the least risk is to release the lock
after each statement, because that is a lot more like current behavior.

Andreas

#2Mikheev, Vadim
vmikheev@SECTORBASE.COM
In reply to: Zeugswetter Andreas SB (#1)
RE: AW: AW: Issue NOTICE for attempt to raise lock leve l?

Will we still have readers-dont-block-writers behaviour?

Sure. The only thing this really affects is VACUUM and
schema-altering
commands, which will now have to wait until reader
transactions commit.
In other words

Session 1 Session 2

BEGIN;
SELECT * FROM foo;

ALTER TABLE foo ...

...

COMMIT;

Session 2 will have to wait for session 1 to commit; before it didn't.

Not only, Tom -:)
Unfortunately, session 3 with just SELECT * FROM foo will also wait
for session 1 & session 2 commit.

Vadim

#3Tom Lane
tgl@sss.pgh.pa.us
In reply to: Mikheev, Vadim (#2)
Re: AW: AW: Issue NOTICE for attempt to raise lock leve l?

"Mikheev, Vadim" <vmikheev@SECTORBASE.COM> writes:

Unfortunately, session 3 with just SELECT * FROM foo will also wait
for session 1 & session 2 commit.

Session 3 would wait for session 2 in any case, no?

This is all irrelevant unless someone can make a convincing case that
it's safe to release read locks early. In the words of the ancient
sage, "I can make this program arbitrarily fast ... if it doesn't have
to give the right answer". I have already pointed out several cases
where releasing locks early is clearly *not* safe. I don't think I
need to produce more examples. The burden of proof is on the other
side to show how it can be done safely (and with an amount of work
that's reasonable for 7.1, which is not too darn much at this point).

regards, tom lane

#4Zeugswetter Andreas SB
ZeugswetterA@wien.spardat.at
In reply to: Mikheev, Vadim (#2)

Will we still have readers-dont-block-writers behaviour?

Sure. The only thing this really affects is VACUUM and schema-altering
commands, which will now have to wait until reader transactions commit.

And "lock table ...", which would need some deadlock resolution code,
because two sessions with select * from foo; lock table foo; should not need
to deadlock, since one of the two could get the lock without breaking anything.

In other words

Session 1 Session 2

BEGIN;
SELECT * FROM foo;

ALTER TABLE foo ...

...

COMMIT;

Session 2 will have to wait for session 1 to commit; before it didn't.
An example of why this is a good idea is

The below is a completely different thing than the above. In the below
it is clear that a shared lock is needed until the last row from c is fetched,
since the statement is still active.
In this particular example there would be two different behaviors in my proposal
depending on how many rows are in foo (1 or many).
If 0 or 1 row -> relese lock after fetch, if more rows release at commit.

Session 1 Session 2

BEGIN;
DECLARE c CURSOR FOR
SELECT * FROM foo;

ALTER TABLE foo ...

FETCH FROM c;

COMMIT;

Without a held read lock on foo, session 1 is in deep trouble,
because its cursor is no longer correctly planned.

Andreas