PostgreSQL数据库锁查询;锁兼容性模式;sql查看阻塞别人/被阻塞进程;通过pid查询sql具体信息;sql结束阻塞会话;锁的等级;pg慢查询,pg_stat_activity,pg_lock

PG锁 postgresql数据库锁

PostgreSQL数据库锁查询;锁兼容性模式;sql查看阻塞别人/被阻塞进程;通过pid查询sql具体信息;sql结束阻塞会话;锁的等级;pg慢查询,pg_stat_activity,pg_lock_第1张图片

锁的等级

/* NoLock is not a lock mode, but a flag value meaning "don't get a lock" */
#define NoLock					0
#define AccessShareLock			1		/* SELECT */
#define RowShareLock			2		/* SELECT FOR UPDATE/FOR SHARE */
#define RowExclusiveLock		3		/* INSERT, UPDATE, DELETE */
#define ShareUpdateExclusiveLock 4		/* VACUUM (non-FULL),ANALYZE, CREATE INDEX CONCURRENTLY */
#define ShareLock				5		/* CREATE INDEX (WITHOUT CONCURRENTLY) */
#define ShareRowExclusiveLock	6		/* like EXCLUSIVE MODE, but allows ROW SHARE */
#define ExclusiveLock			7		/* blocks ROW SHARE/SELECT...FOR UPDATE */
#define AccessExclusiveLock		8		/* ALTER TABLE, DROP TABLE, VACUUM FULL, and unqualified LOCK TABLE */

postgresql锁兼容性模式

PostgreSQL数据库锁查询;锁兼容性模式;sql查看阻塞别人/被阻塞进程;通过pid查询sql具体信息;sql结束阻塞会话;锁的等级;pg慢查询,pg_stat_activity,pg_lock_第2张图片

通过PostgreSQL提供的视图检查或监控锁

1. pg_locks展示锁信息,每一个被锁或者等待锁的对象一条记录
2. pg_stat_activity,每个会话一条记录,显示会话状态信息

sql查看阻塞别人/被阻塞进程

-- 查看阻塞别人/被阻塞进程

select 
locktype,
mode,
relation::regclass as rel,
page||','||tuple as ctid,
virtualxid as vxid,
transactionid as xid,
virtualtransaction as vxid2,
pid,
granted
from pg_locks
where granted in ('t','f');

--granted=t是阻塞别人的,f是被阻塞的

PostgreSQL数据库锁查询;锁兼容性模式;sql查看阻塞别人/被阻塞进程;通过pid查询sql具体信息;sql结束阻塞会话;锁的等级;pg慢查询,pg_stat_activity,pg_lock_第3张图片

PostgreSQL死锁进程及慢查询处理

1、死锁进程查看:

SELECT * FROM pg_stat_activity WHERE datname='数据库名称' and waiting=true;

pid 进程id。

2、慢查询SQL:

select datname, pid, usename, application_name, 
client_addr, client_port, xact_start, query_start, 
state_change, waiting, state, 
backend_xid, backend_xmin, query, xact_start,now()-xact_start 
from pg_stat_activity 
where state<>'idle' 
and (backend_xid is not null or backend_xmin is not null) 
order by now()-xact_start;  

now()-xact_start 是指事务截至当前已运行时间。
now() - query_start query 截至当前已运行时间。
pid 进程ID。
query 慢查询的sql,可explian分析下具体原因。

通过pid查询sql具体信息

--通过pid查询sql具体信息
SELECT 
xact_start, 
query_start, 
backend_start, 
state_change, 
state 
FROM pg_stat_activity WHERE pid IN (已知的阻塞pid);

sql结束阻塞会话

kill 会话
方式1 SELECT pg_cancel_backend(阻塞的pid);

方式2 SELECT pg_terminate_backend(阻塞的pid);

查询当前锁等待、持锁的sql信息

with t_wait as (
select
	a.mode,
	a.locktype,
	a.database,
	a.relation,
	a.page,
	a.tuple,
	a.classid,
	a.granted,
	a.objid,
	a.objsubid,
	a.pid,
	a.virtualtransaction,
	a.virtualxid,
	a.transactionid,
	a.fastpath,
	b.state,
	b.query,
	b.xact_start,
	b.query_start,
	b.usename,
	b.datname,
	b.client_addr,
	b.client_port,
	b.application_name
from
	pg_locks a,
	pg_stat_activity b
where
	a.pid = b.pid
	and not a.granted ),
t_run as (
select
	a.mode,
	a.locktype,
	a.database,
	a.relation,
	a.page,
	a.tuple,
	a.classid,
	a.granted,
	a.objid,
	a.objsubid,
	a.pid,
	a.virtualtransaction,
	a.virtualxid,
	a.transactionid,
	a.fastpath,
	b.state,
	b.query,
	b.xact_start,
	b.query_start,
	b.usename,
	b.datname,
	b.client_addr,
	b.client_port,
	b.application_name
from
	pg_locks a,
	pg_stat_activity b
where
	a.pid = b.pid
	and a.granted ),
t_overlap as (
select
	r.*
from
	t_wait w
join t_run r on
	( r.locktype is not distinct
from
	w.locktype
	and r.database is not distinct
from
	w.database
	and r.relation is not distinct
from
	w.relation
	and r.page is not distinct
from
	w.page
	and r.tuple is not distinct
from
	w.tuple
	and r.virtualxid is not distinct
from
	w.virtualxid
	and r.transactionid is not distinct
from
	w.transactionid
	and r.classid is not distinct
from
	w.classid
	and r.objid is not distinct
from
	w.objid
	and r.objsubid is not distinct
from
	w.objsubid
	and r.pid <> w.pid ) ),
t_unionall as (
select
	r.*
from
	t_overlap r
union all
select
	w.*
from
	t_wait w )
select
	locktype,
	datname,
	relation::regclass,
	page,
	tuple,
	virtualxid,
	transactionid::text,
	classid::regclass,
	objid,
	objsubid,
	string_agg( 'Pid: ' || case when pid is null then 'NULL' else pid::text end || chr(10)|| 'Lock_Granted: ' || case when granted is null then 'NULL' else granted::text end || ' , Mode: ' || case when mode is null then 'NULL' else mode::text end || ' , FastPath: ' || case when fastpath is null then 'NULL' else fastpath::text end || ' , VirtualTransaction: ' || case when virtualtransaction is null then 'NULL' else virtualtransaction::text end || ' , Session_State: ' || case when state is null then 'NULL' else state::text end || chr(10)|| 'Username: ' || case when usename is null then 'NULL' else usename::text end || ' , Database: ' || case when datname is null then 'NULL' else datname::text end || ' , Client_Addr: ' || case when client_addr is null then 'NULL' else client_addr::text end || ' , Client_Port: ' || case when client_port is null then 'NULL' else client_port::text end || ' , Application_Name: ' || case when application_name is null then 'NULL' else application_name::text end || chr(10)|| 'Xact_Start: ' || case when xact_start is null then 'NULL' else xact_start::text end || ' , Query_Start: ' || case when query_start is null then 'NULL' else query_start::text end || ' , Xact_Elapse: ' || case when (now()-xact_start) is null then 'NULL' else (now()-xact_start)::text end || ' , Query_Elapse: ' || case when (now()-query_start) is null then 'NULL' else (now()-query_start)::text end || chr(10)|| 'SQL (Current SQL in Transaction): ' || chr(10)|| case when query is null then 'NULL' else query::text end, chr(10)|| '--------' || chr(10) order by ( case mode when 'INVALID' then 0 when 'AccessShareLock' then 1 when 'RowShareLock' then 2 when 'RowExclusiveLock' then 3 when 'ShareUpdateExclusiveLock' then 4 when 'ShareLock' then 5 when 'ShareRowExclusiveLock' then 6 when 'ExclusiveLock' then 7 when 'AccessExclusiveLock' then 8 else 0 end ) desc, (case when granted then 0 else 1 end) ) as lock_conflict
from
	t_unionall
group by
	locktype,
	datname,
	relation,
	page,
	tuple,
	virtualxid,
	transactionid::text,
	classid,
	objid,
	objsubid ;

with t_wait as  (    
  select a.mode,a.locktype,a.database,a.relation,a.page,a.tuple,a.classid,a.granted,   
  a.objid,a.objsubid,a.pid,a.virtualtransaction,a.virtualxid,a.transactionid,a.fastpath,    
  b.state,b.query,b.xact_start,b.query_start,b.usename,b.datname,b.client_addr,b.client_port,b.application_name   
    from pg_locks a,pg_stat_activity b where a.pid=b.pid and not a.granted   
),   
t_run as  (   
  select a.mode,a.locktype,a.database,a.relation,a.page,a.tuple,a.classid,a.granted,   
  a.objid,a.objsubid,a.pid,a.virtualtransaction,a.virtualxid,a.transactionid,a.fastpath,   
  b.state,b.query,b.xact_start,b.query_start,b.usename,b.datname,b.client_addr,b.client_port,b.application_name   
    from pg_locks a,pg_stat_activity b where a.pid=b.pid and a.granted   
),   
t_overlap as  (   
  select r.* from t_wait w join t_run r on   (   
    r.locktype is not distinct from w.locktype and   
    r.database is not distinct from w.database and   
    r.relation is not distinct from w.relation and   
    r.page is not distinct from w.page and   
    r.tuple is not distinct from w.tuple and   
    r.virtualxid is not distinct from w.virtualxid and   
    r.transactionid is not distinct from w.transactionid and   
    r.classid is not distinct from w.classid and   
    r.objid is not distinct from w.objid and   
    r.objsubid is not distinct from w.objsubid and   
    r.pid <> w.pid   )    
),    
t_unionall as  (    
  select r.* from t_overlap r  union all  select w.* from t_wait w    
)    
select locktype,datname,relation::regclass,page,tuple,virtualxid,transactionid::text,classid::regclass,objid,objsubid,   
string_agg(   
'Pid: '||case when pid is null then 'NULL' else pid::text end||chr(10)||   
'Lock_Granted: '||case when granted is null then 'NULL' else granted::text end||' , Mode: '||case when mode is null then 'NULL' else mode::text end||' , FastPath: '||case when fastpath is null then 'NULL' else fastpath::text end||' , VirtualTransaction: '||case when virtualtransaction is null then 'NULL' else virtualtransaction::text end||' , Session_State: '||case when state is null then 'NULL' else state::text end||chr(10)||   
'Username: '||case when usename is null then 'NULL' else usename::text end||' , Database: '||case when datname is null then 'NULL' else datname::text end||' , Client_Addr: '||case when client_addr is null then 'NULL' else client_addr::text end||' , Client_Port: '||case when client_port is null then 'NULL' else client_port::text end||' , Application_Name: '||case when application_name is null then 'NULL' else application_name::text end||chr(10)||    
'Xact_Start: '||case when xact_start is null then 'NULL' else xact_start::text end||' , Query_Start: '||case when query_start is null then 'NULL' else query_start::text end||' , Xact_Elapse: '||case when (now()-xact_start) is null then 'NULL' else (now()-xact_start)::text end||' , Query_Elapse: '||case when (now()-query_start) is null then 'NULL' else (now()-query_start)::text end||chr(10)||    
'SQL (Current SQL in Transaction): '||chr(10)||  
case when query is null then 'NULL' else query::text end,    
chr(10)||'--------'||chr(10)    
order by    
  (  case mode    
    when 'INVALID' then 0   
    when 'AccessShareLock' then 1   
    when 'RowShareLock' then 2   
    when 'RowExclusiveLock' then 3   
    when 'ShareUpdateExclusiveLock' then 4   
    when 'ShareLock' then 5   
    when 'ShareRowExclusiveLock' then 6   
    when 'ExclusiveLock' then 7   
    when 'AccessExclusiveLock' then 8   
    else 0   
  end  ) desc,   
  (case when granted then 0 else 1 end)  
) as lock_conflict  
from t_unionall   
group by   
locktype,datname,relation,page,tuple,virtualxid,transactionid::text,classid,objid,objsubid ; 

锁分析

被锁的行 page和tuple字段(它们的组合即是表上系统字段ctid的值)

假设查出ctid=(0,1),执行下面语句,查出的行既是被锁的行。
select * from 被锁表名 where ctid=’(0,1)’;

你可能感兴趣的:(数据库,系统运维,PostgreSQL,数据库,postgresql,json)