Question: How can I identify what is blocking a query on a DB instance that is running Amazon RDS PostgreSQL or Aurora PostgreSQL?

I tried to run a query on a DB instance that is running Amazon Relational Database Service (Amazon RDS) PostgreSQL or Amazon Aurora PostgreSQL. But the query was blocked, even though no other queries were executing at the same time. Why was the query blocked, and how do I resolve this issue?ResolutionMost often, blocked queries are caused by uncommitted transactions. Uncommitted transactions can cause new queries to be blocked, to sleep, and to eventually fail when they exceed the lock wait timeout or the statement timeout. To resolve this issue, first identify the blocking transaction, and then stop the blocking transaction.1.    Identify the current state of the blocked transaction by running the following query against the pg_stat_activity table:SELECT * FROM pg_stat_activity WHERE query iLIKE '%TABLE NAME%' ORDER BY state;Note: Replace TABLE NAME with your own table name or condition.If the value of the wait_event_type column is Lock, the query is blocked by other transactions or queries. If the wait_event_type column has any other value, there is a performance bottleneck with resources such as CPU, storage, or network capacity. To resolve performance bottlenecks, tune the performance of your database, for example, by adding indexes, rewriting queries, or executing vacuum and analyze. For more information, see Best Practices for Working with PostgreSQL.If you enabled Performance Insights on your DB instance, you can also identify blocked transactions by viewing the DB load that is grouped by wait event, hosts, SQL queries, or users. For more information, see Using Amazon RDS Performance Insights.2.    If the value of the wait_event_type column is Lock, then you can identify the cause of the blocked transaction by running the following:SELECT blocked_locks.pid     AS blocked_pid,       blocked_activity.usename  AS blocked_user,       blocked_activity.client_addr as blocked_client_addr,       blocked_activity.client_hostname as blocked_client_hostname,       blocked_activity.client_port as blocked_client_port,       blocked_activity.application_name as blocked_application_name,       blocked_activity.wait_event_type as blocked_wait_event_type,       blocked_activity.wait_event as blocked_wait_event,       blocked_activity.query    AS blocked_statement,       blocking_locks.pid     AS blocking_pid,       blocking_activity.usename AS blocking_user,       blocking_activity.client_addr as blocking_user_addr,       blocking_activity.client_hostname as blocking_client_hostname,       blocking_activity.client_port as blocking_client_port,       blocking_activity.application_name as blocking_application_name,       blocking_activity.wait_event_type as blocking_wait_event_type,       blocking_activity.wait_event as blocking_wait_event,       blocking_activity.query   AS current_statement_in_blocking_process 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 ORDER BY blocked_activity.pid;3.    Review the columns that have a blocking prefix. In the following example table that was generated by this query, you can see that the blocked transaction is running on the 27.0.3.146 host and using psql:blocked_pid                           | 9069blocked_user                          | masterblocked_client_addr                   | 27.0.3.146blocked_client_hostname               |blocked_client_port                   | 50035blocked_application_name              | psqlblocked_wait_event_type               | Lockblocked_wait_event                    | transactionidblocked_statement                     | UPDATE test_tbl SET name = 'Jane Doe' WHERE id = 1;blocking_pid                          | 8740blocking_user                         | masterblocking_user_addr                    | 27.0.3.146blocking_client_hostname              |blocking_client_port                  | 26259blocking_application_name             | psqlblocking_wait_event_type              | Clientblocking_wait_event                   | ClientReadcurrent_statement_in_blocking_process | UPDATE tset_tbl SET name = 'John Doe' WHERE id = 1;Tip: Use blocking_user, blocking_user_addr, and blocking_client_port to help identify which sessions are blocking transactions.Important: Before terminating transactions, evaluate the potential impact that each transaction has on the state of your database and your application.4.    After reviewing the potential impact of each transaction, stop the transactions by running the following query:SELECT pg_terminate_backend(PID);Note: Replace PID with blocking_pid of the process that you identified in step 3.

Related informationPostgreSQL documentation for Viewing locksPostgreSQL documentation for Server signaling functionsPostgreSQL documentation for wait_event descriptionPostgreSQL Wiki for Lock monitoringAmazon Aurora PostgreSQL events