微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

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的时候,文档给出的公式会更加接近精确值。

原文地址:https://www.jb51.cc/postgresql/196924.html

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。

相关推荐