提交 d8663cce 编写于 作者: H Heikki Linnakangas

Don't acquire lock on XID twice.

There's no reason to believe that the lock on the XID would not be
available, and if for reason it's not, it seems dangerous to just
continue as if nothing happened. So remove the GPDB-added code that
checked for that, reverting the function to the way it is in the upstream.

Because of the way the check was written, LockAcquire() always got called
twice, so we actually acquired the lock on the XID twice. That's usually
harmless, since both locks are released at the end of the transaction
anyway, except for one scenario: If you created a savepoint, and committed
it (e.g. with RELEASE SAVEPOINT), we would release the lock on the
subtransaction's XID only once, leaving the other lock still in place. So
we kept the lock on every committed subtransaction 'till the end of the
top transaction. That too was mostly harmless, the only ill effect was
that the locks would take some space in the global lock table, which is
limited in size, so you could run out of shared memory more easily if you
used subtransactions heavily.

Fixes github issue https://github.com/greenplum-db/gpdb/issues/7819
上级 81d025eb
...@@ -548,13 +548,6 @@ XactLockTableInsert(TransactionId xid) ...@@ -548,13 +548,6 @@ XactLockTableInsert(TransactionId xid)
SET_LOCKTAG_TRANSACTION(tag, xid); SET_LOCKTAG_TRANSACTION(tag, xid);
if (LockAcquire(&tag, ExclusiveLock, false, true) == LOCKACQUIRE_NOT_AVAIL)
{
elog(LOG,"XactLockTableInsert lock for xid = %u is not available!", xid);
return;
}
(void) LockAcquire(&tag, ExclusiveLock, false, false); (void) LockAcquire(&tag, ExclusiveLock, false, false);
} }
......
...@@ -809,3 +809,39 @@ reindex table pg_class; ...@@ -809,3 +809,39 @@ reindex table pg_class;
ERROR: REINDEX of a catalog table cannot run inside a transaction block ERROR: REINDEX of a catalog table cannot run inside a transaction block
commit; commit;
\c regression \c regression
--
-- Check that committing a subtransaction releases the lock on the
-- subtransaction's XID.
--
-- It's not too bad if it doesn't, because if anyone wants to wait for the
-- subtransaction and sees that it's been committed already, they will wait
-- for the top transaction XID instead. So even though the lock on the sub-XID
-- is released at RELEASE SAVEPOINT, logically it's held until the end of
-- the top transaction anyway. But releasing the lock early saves space in
-- the lock table. (We had a silly bug once upon a time in GPDB where we failed
-- to release the lock.)
--
BEGIN;
CREATE TEMPORARY TABLE foo (i integer);
DO $$
declare
i int;
begin
for i in 1..100 loop
begin
insert into foo values (i);
exception
when others then raise 'got error';
end;
end loop;
end;
$$;
SELECT CASE WHEN count(*) < 50 THEN 'not many XID locks'
ELSE 'lots of XID locks: ' || count(*) END
FROM pg_locks WHERE locktype='transactionid';
case
--------------------
not many XID locks
(1 row)
ROLLBACK;
...@@ -552,3 +552,35 @@ begin; ...@@ -552,3 +552,35 @@ begin;
reindex table pg_class; reindex table pg_class;
commit; commit;
\c regression \c regression
--
-- Check that committing a subtransaction releases the lock on the
-- subtransaction's XID.
--
-- It's not too bad if it doesn't, because if anyone wants to wait for the
-- subtransaction and sees that it's been committed already, they will wait
-- for the top transaction XID instead. So even though the lock on the sub-XID
-- is released at RELEASE SAVEPOINT, logically it's held until the end of
-- the top transaction anyway. But releasing the lock early saves space in
-- the lock table. (We had a silly bug once upon a time in GPDB where we failed
-- to release the lock.)
--
BEGIN;
CREATE TEMPORARY TABLE foo (i integer);
DO $$
declare
i int;
begin
for i in 1..100 loop
begin
insert into foo values (i);
exception
when others then raise 'got error';
end;
end loop;
end;
$$;
SELECT CASE WHEN count(*) < 50 THEN 'not many XID locks'
ELSE 'lots of XID locks: ' || count(*) END
FROM pg_locks WHERE locktype='transactionid';
ROLLBACK;
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册