当前位置:网站首页>How PostgreSQL quickly locate blocking SQL

How PostgreSQL quickly locate blocking SQL

2022-06-23 20:29:00 Tencent cloud database tencentdb

| Introduction In the process of database execution, there are often SQL The execution time is too long , The problem of blocking each other . How to quickly find out the culprit , And kill such statements to let the process continue , This article will briefly explain .

When we come across a simple statement but the execution time is too long SQL When the sentence is , Not necessarily because SQL Poorly written , It is probably because of the database wait event , How to determine why a statement is blocked ?

We use a test scenario to conduct a simulation exercise , First create a table , And then insert some data , The create transaction is displayed again , Construct a lock waiting scenario .

create table t1(id int primary key); insert into t1 select generate_series(1,10000);

begin;delete from t1;

# Open another one session Execute the same statement : begin;delete from t1;

At this point, it can be found that when the second transaction is executed ,SQL It is obviously impossible to carry out , Because the first transaction was not committed .

Of course, we can directly view the lock information through some ready-made statements , Such as :

SELECT blocking_activity.datname as " database ", blocking_activity.application_name as " Lock session program name ", blocking_activity.client_addr as " Lock Session address ", now()-blocking_activity.query_start as " The duration of the blockage (s)", blocked_locks.pid AS " Blocking a session ID", blocked_activity.usename AS " Blocked users ", blocking_locks.pid AS " Locked session ID", blocking_activity.usename AS " Locked user ", blocked_activity. QUERY AS " Locked SQL", blocking_activity. QUERY AS " Lock holding SQL" FROM pg_catalog.pg_locks blocked_locks JOIN pg_catalog.pg_stat_activity blocked_activity ON blocked_activity.pid = blocked_locks.pid JOIN pg_catalog.pg_locks blocking_locks ON blocking_locks.locktype = blocked_locks.locktype AND blocking_locks. DATABASE IS NOT DISTINCT FROM blocked_locks. DATABASE AND blocking_locks.relation IS NOT DISTINCT FROM blocked_locks.relation AND blocking_locks.page IS NOT DISTINCT FROM blocked_locks.page AND blocking_locks.tuple IS NOT DISTINCT FROM blocked_locks.tuple AND blocking_locks.virtualxid IS NOT DISTINCT FROM blocked_locks.virtualxid AND blocking_locks.transactionid IS NOT DISTINCT FROM blocked_locks.transactionid AND blocking_locks.classid IS NOT DISTINCT FROM blocked_locks.classid AND blocking_locks.objid IS NOT DISTINCT FROM blocked_locks.objid AND blocking_locks.objsubid IS NOT DISTINCT FROM blocked_locks.objsubid AND blocking_locks.pid != blocked_locks.pid JOIN pg_catalog.pg_stat_activity blocking_activity ON blocking_activity.pid = blocking_locks.pid WHERE NOT blocked_locks.GRANTED;

But we also need to know how it works . When it is found that a business is stuck and cannot be carried out smoothly , We entered the database for the first time , Execute a statement to see what is currently available SQL Statement is executing :

select * from pg_stat_activity;

select pid,now()-query_start as " execution time ",wait_event_type,wait_event,query from pg_stat_activity; The top two SQL The effect of execution is consistent , It is more complete to directly view the information of the whole view , But more , You can use the second view , among ,wait_event wait_event_type Field represents the wait event . Different waiting events mean different things .

You can see our execution time column , Found some session The execution time of has 6 Minutes. . also session There is a type of waiting event in the lock, It illustrates the current session The executing statement takes a long time because of the lock , What kind of lock is that , What operation blocks the execution of this statement ?

Now we can go through pg_locks This view to find the culprit . First , Just now we know from this view The blocked one session Of course pid How much is it . So we were pg_locks Find the corresponding pid, As shown in the figure above 31365.

Execute statement :

select * from locks;

From the above results, we need to find pid by 31365 The entry of , Then check it out granted Field , If this field The value is true, It means that the current lock entry will block others sql function , If granted yes false Then represent , The current lock is blocked . This can also be used to prove that 31365 A process is a blocked session . So find out now pid by 31365 What is the locked operation object , You can see database and relation Field , You can find , What is locked is databse:19498 and relation:19499 and 19502.

therefore , We found something else granted Field is true Of , And the corresponding lock object is databse:19498 and relation:19499 and 19502 Of process pid How much is the , You can clearly see pid by 30539 Which holds the current two objects RowExclusiveLock The lock caused PID by 31365 session Normal execution of the statement .

At this point, you can determine how to change according to the specific situation of the business , Generally, it is to deal with problems urgently , We need to kill the blocked session . So PostgreSQL Two statements are provided to kill Conversation or sql.

Namely pg_cancel_backend() and pg_terminate_backend() Two functions , The input parameter of the function is pid.

pg_cancel_backend() The function of is to shut down session Executing statement , Rollback all uncommitted operations ; But don't close the whole session.pg_terminate_backend() The function of is to close the whole session directly , Rollback all uncommitted operations .

As shown below :

select pg_cacanl_backend(31365);

select pg_terminate_backend(31365);

Click the link to jump to the video address :https://cloud.tencent.com/developer/video/29376

原网站

版权声明
本文为[Tencent cloud database tencentdb]所创,转载请带上原文链接,感谢
https://yzsam.com/2021/12/202112311452555384.html