how many objects can be locked per transaction

在Postgresql中,通过pg_locks这个视图可以查看到当前被跟踪的锁状态。
或者直接通过如下SQL查询:
SELECT l.locktype,l.database,l.relation,l.page,l.tuple,l.virtualxid,l.transactionid,l.classid,l.objid,l.objsubid,l.virtualtransaction,l.pid,l.mode,l.granted FROM pg_lock_status() l(locktype,database,relation,page,tuple,virtualxid,transactionid,classid,objid,objsubid,virtualtransaction,pid,mode,granted);
这些锁的信息被存储在System V的共享内存中,理论上只要共享内存足够,就可以继续获得锁。
但是文档却是这么描述的(实际上不是精确的描述,但是这个参数是会影响System V的分配的,所以间接的影响了可以持有锁的数量):
max_locks_per_transaction (integer) -- 注意这是一个平均数,并不是用于限制单个事务的锁对象数量

The shared lock table tracks locks on max_locks_per_transaction * (max_connections + max_prepared_transactions) objects (e.g.,tables); hence,no more than this many distinct objects can be locked at any one time. This parameter controls the average number of object locks allocated for each transaction; individual transactions can lock more objects as long as the locks of all transactions fit in the lock table. This is not the number of rows that can be locked; that value is unlimited. The default,64,has historically proven sufficient,but you might need to raise this value if you have clients that touch many different tables in a single transaction. This parameter can only be set at server start.

Increasing this parameter might cause Postgresql to request more System V shared memory than your operating system's default configuration allows. See Section 17.4.1 for information on how to adjust those parameters,if necessary.

When running a standby server,you must set this parameter to the same or higher value than on the master server. Otherwise,queries will not be allowed in the standby server.

例:
假设 max_locks_per_transaction = 10 max_prepared_transactions = 0 max_connections = 40 按照文档的说明,整个数据库集群在同一时刻可以被锁的对象数应该等于400.但是实际上不只这个数量,(实际受到System V共享内存的限制) 创建两个测试函数一个用于批量创建表,一个用于批量锁表。 CREATE OR REPLACE FUNCTION digoal.f_create_table(i_min integer,i_max integer) RETURNS void LANGUAGE plpgsql AS $function$ declare begin for i in i_min..i_max loop execute 'create table tbl_user_'||i||' (like tbl_user);'; end loop; return; end; $function$ CREATE OR REPLACE FUNCTION digoal.f_lock_table(i_min integer,i_max integer) RETURNS void LANGUAGE plpgsql AS $function$ declare begin for i in i_min..i_max loop execute 'lock table tbl_user_'||i||' in exclusive mode;'; end loop; return; end; $function$ digoal=> begin; BEGIN digoal=> select * from f_create_table(756,1857); f_create_table ---------------- (1 row) digoal=> select count(distinct (database,relation)),count(*) from pg_locks; count | count -------+------- 1106 | 1107 (1 row) 此时数据库集群中被锁对象已经达到1106个,锁插槽使用1107个.已经超出400的限制, 继续申请锁看看会发生什么? digoal=> select * from f_lock_table(1,4); WARNING: out of shared memory CONTEXT: sql statement "lock table tbl_user_4 in exclusive mode;" PL/pgsql function "f_lock_table" line 4 at EXECUTE statement ERROR: out of shared memory HINT: You might need to increase max_locks_per_transaction. CONTEXT: sql statement "lock table tbl_user_4 in exclusive mode;" PL/pgsql function "f_lock_table" line 4 at EXECUTE statement 再开连接的话也会有 out of shared memory 的报错. postgres@db-172-16-3-33-> psql -h 127.0.0.1 postgres postgres WARNING: out of shared memory psql: FATAL: out of shared memory HINT: You might need to increase max_locks_per_transaction. 通 过增加max_locks_per_transaction或max_connections都可以达到加大System V共享内存的效果,但是具体能锁多少个对象不能使用max_locks_per_transaction * (max_connections + max_prepared_transactions)来精确计算,只是一个大概值。 当然,由于每一个连接都会消耗部分System V共享内存,因此当连接达到max_connections的时候,文档给出的公式会更加接近精确值。

相关文章

项目需要,有个数据需要导入,拿到手一开始以为是mysql,结果...
本文小编为大家详细介绍“怎么查看PostgreSQL数据库中所有表...
错误现象问题原因这是在远程连接时pg_hba.conf文件没有配置正...
因本地资源有限,在公共测试环境搭建了PGsql环境,从数据库本...
wamp 环境 这个提示就是说你的版本低于10了。 先打印ph...
psycopg2.OperationalError: SSL SYSCALL error: EOF detect...