AW: AW: AW: Issue NOTICE for attempt to raise lock leve l?
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
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 wordsSession 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
Import Notes
Resolved by subject fallback
"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
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
Import Notes
Resolved by subject fallback