我在centos-5.8上的pgsql-9.1上测试postgresql锁机制。
我想知道的是如何从<IDLE> in transaction
未提及的postgres=# create table test_table(col1 char);
CREATE TABLE
postgres=# begin;
BEGIN
postgres=# insert into test_table values('1');
INSERT 0 1
--uncommited
引起的独占锁定的表中进行选择。
案件如下......
在session1中
postgres=# alter table test_table add column c2 char;
-- It has been locked....
在session2中
postgres=# select t.relname, l.locktype,page,pid,virtualtransaction,mode,granted from pg_locks l, pg_stat_all_tables t where l.relation=t.relid order by relation asc;
relname | locktype | page | pid | virtualtransaction | mode | granted
--------------+----------+------+------+--------------------+---------------------+---------
pg_class | relation | | 9940 | 2/715754 | AccessShareLock | t
pg_index | relation | | 9940 | 2/715754 | AccessShareLock | t
pg_namespace | relation | | 9940 | 2/715754 | AccessShareLock | t
test_table | relation | | 9660 | 9/671042 | RowExclusiveLock | t
test_table | relation | | 9639 | 7/707191 | AccessExclusiveLock | f
(5 rows)
postgres=# select col1 from test_table;
--It's not possible to select from exclusively locked table
会话3中的
set transaction isolation level
我需要的是获得关系的大小而不管发生的锁定。 我在{{1}}附近徘徊,但到目前为止我还没有找到任何解决办法。
非常感谢任何建议。
提前致谢。
答案 0 :(得分:1)
您的表不是独占锁定的访问权限,它在已授予的AccessShareLock后面具有待处理但未授予的AccessExclusiveLock。虽然它确实具有相同的效果,但新的AccessShareLock排在后面。从理论上讲,它们可以跳过队列并被授予,但这可能会导致AccessExclusiveLock请求的饥饿,从而无法完成。
如果估计值足够好,您可以
select reltuples from pg_class where oid='test_table'::regclass;
否则,关于唯一的选择是杀死持有表锁人质的两个进程之一,即持有AccessShare的进程或想要AccessExclusive的进程。 (或者破解PostgreSQL源代码。)