当前位置:   article > 正文

10.PostgreSQL锁的处理_pgsql 锁表

pgsql 锁表

1.现象描述

遇到一个问题,selectdelete表时正常执行,但truncatedrop表时会一直运行而且不报错。

2.分析

  1. "drop table " 和 "truncate table " 需要申请排它锁 "ACCESS EXCLUSIVE ", 执行这个命令卡住时,
  2. 说明此时这张表上还有操作正在进行,比如查询等,那么只有等待这个查询操作完成,
  3. "drop table" 或"truncate table"或者增加字段的SQL 才能获取这张表上的
  4. "ACCESS EXCLUSIVE" 锁 ,操作才能进行下去。

3.模拟会话

  1. 会话1:update itpux set id=1 where name='xsq1';
  2. 会话2:update itpux set name='xsq3' where id=1;
  3. 会话3:update itpux set id=3 where id=1;
  4. 会话4:update itpux set name='xsq4' where id=1;
  5. select datname,pid ,usename,query_start,wait_event_type,wait_event,state,backend_xid,backend_xmin,query from pg_stat_activity where state='active' or state='idle in transaction' order by query_start;
  6. datid | datname | pid | usename | query_start | wait_event_type | wait_event | state | backend_xid | backend_xmin |query
  7. -------+----------+------+----------+-------------------------------+-----------------+---------------------+---------------------+-------------+--------------+-----------------------------------------------------------------------------------------------------------------------------------------
  8. | | 2363 | | | Activity | AutoVacuumMain | | | |
  9. | | 2366 | postgres | | Activity | LogicalLauncherMain | | | |
  10. 13593 | postgres | 2379 | postgres | 2021-12-30 05:57:28.134777+08 | Client | ClientRead | idle in transaction | 525 | | update itpux set id=1 where name='xsq1';
  11. 13593 | postgres | 2506 | postgres | 2021-12-30 05:58:06.966698+08 | Lock | transactionid | active | 526 | 525 | update itpux set name='xsq3' where id=1;
  12. 13593 | postgres | 2636 | postgres | 2021-12-30 06:15:49.946071+08 | | | active | | 525 | select datid , datname,pid ,usename,query_start,wait_event_type,wait_event,state,backend_xid,backend_xmin,query from pg_stat_activity;
  13. 13593 | postgres | 3049 | postgres | 2021-12-30 06:11:35.725454+08 | Lock | tuple | active | 527 | 525 | update itpux set id=3 where id=1;
  14. 13593 | postgres | 3362 | postgres | 2021-12-30 06:15:39.426266+08 | Lock | tuple | active | 528 | 525 | update itpux set name='xsq4' where id=1;
  15. (10 rows)
  16. state=idle in transaction 说明开始了事物,但是没有提交。
  17. backend_xid 事物id;525
  18. backend_xmin: 造成锁的事物id;
  19. wait_event_type=Lock; 说明它被锁。

4.查询对象是否锁表了

  1. (1)
  2. postgres=# select oid from pg_class where relname='itpux';
  3. oid
  4. -------
  5. 16405
  6. (1 row)
  7. postgres=# select database,relation,pid,mode,granted,transactionid from pg_locks;
  8. database | relation | pid | mode | granted | transactionid
  9. ----------+----------+------+------------------+---------+---------------
  10. 13593 | 16405 | 3362 | RowExclusiveLock | t |
  11. | | 3362 | ExclusiveLock | t |
  12. 13593 | 16405 | 3049 | RowExclusiveLock | t |
  13. | | 3049 | ExclusiveLock | t |
  14. 13593 | 12143 | 2636 | AccessShareLock | t |
  15. | | 2636 | ExclusiveLock | t |
  16. 13593 | 16405 | 2506 | RowExclusiveLock | t |
  17. | | 2506 | ExclusiveLock | t |
  18. 13593 | 16405 | 2379 | AccessShareLock | t |
  19. 13593 | 16405 | 2379 | RowExclusiveLock | t |
  20. | | 2379 | ExclusiveLock | t |
  21. 13593 | 16405 | 3049 | ExclusiveLock | f |
  22. | | 2379 | ExclusiveLock | t | 525
  23. | | 3049 | ExclusiveLock | t | 527
  24. | | 2506 | ShareLock | f | 525
  25. | | 2506 | ExclusiveLock | t | 526
  26. | | 3362 | ExclusiveLock | t | 528
  27. 13593 | 16405 | 2506 | ExclusiveLock | t |
  28. 13593 | 16405 | 3362 | ExclusiveLock | f |
  29. (2)如果查询到了结果,表示该表被锁 则需要释放锁定
  30. select pg_cancel_backend(3362);
  31. (3)再次检查。
  32. select datname,pid ,usename,query_start,wait_event_type,wait_event,state,backend_xid,backend_xmin,query from pg_stat_activity where state='active' or state='idle in transaction' order by query_start;
  33. datname | pid | usename | query_start | wait_event_type | wait_event | state | backend_xid | backend_xmin | query
  34. ----------+------+----------+-------------------------------+-----------------+---------------+---------------------+-------------+--------------+------------------------------------------------------------------------------------------------------------
  35. postgres | 2379 | postgres | 2021-12-30 05:57:28.134777+08 | Client | ClientRead | idle in transaction | 525 | | update itpux set id=1 where name='xsq1';
  36. postgres | 2506 | postgres | 2021-12-30 05:58:06.966698+08 | Lock | transactionid | active | 526 | 525 | update itpux set name='xsq3' where id=1;
  37. postgres | 3049 | postgres | 2021-12-30 06:11:35.725454+08 | Lock | tuple | active | 527 | 525 | update itpux set id=3 where id=1;
  38. postgres | 2636 | postgres | 2021-12-30 06:36:57.656019+08 | | | active | | 525 |
  39. select datname,pid ,usename,query_start,wait_event_type,wait_event,state,backend_xid,backend_xmin,query
  40. from pg_stat_activity where state='active' or state='idle in transaction' order by query_start;
  41. (4)
  42. select pg_cancel_backend(3049);
  43. select datname,pid ,usename,query_start,wait_event_type,wait_event,state,backend_xid,backend_xmin,query from pg_stat_activity where state='active' or state='idle in transaction' order by query_start;
  44. datname | pid | usename | query_start | wait_event_type | wait_event | state | backend_xid | backend_xmin | query
  45. ----------+------+----------+-------------------------------+-----------------+---------------+---------------------+-------------+--------------+------------------------------------------------------------------------------------------------------------
  46. postgres | 2379 | postgres | 2021-12-30 05:57:28.134777+08 | Client | ClientRead | idle in transaction | 525 | | update itpux set id=1 where name='xsq1';
  47. postgres | 2506 | postgres | 2021-12-30 05:58:06.966698+08 | Lock | transactionid | active | 526 | 525 | update itpux set name='xsq3' where id=1;
  48. postgres | 2636 | postgres | 2021-12-30 06:38:16.176023+08 | | | active | | 525 | select datname,pid ,usename,query_start,wait_event_type,wait_event,state,backend_xid,backend_xmin,query fr
  49. om pg_stat_activity where state='active' or state='idle in transaction' order by query_start;
  50. (5)
  51. select pg_cancel_backend(2379); ---没有能够杀死锁的肇事者。
  52. select datname,pid ,usename,query_start,wait_event_type,wait_event,state,backend_xid,backend_xmin,query from pg_stat_activity where state='active' or state='idle in transaction' order by query_start;
  53. datname | pid | usename | query_start | wait_event_type | wait_event | state | backend_xid | backend_xmin | query
  54. ----------+------+----------+-------------------------------+-----------------+---------------+---------------------+-------------+--------------+------------------------------------------------------------------------------------------------------------
  55. postgres | 2379 | postgres | 2021-12-30 05:57:28.134777+08 | Client | ClientRead | idle in transaction | 525 | | update itpux set id=1 where name='xsq1';
  56. postgres | 2506 | postgres | 2021-12-30 05:58:06.966698+08 | Lock | transactionid | active | 526 | 525 | update itpux set name='xsq3' where id=1;
  57. postgres | 2636 | postgres | 2021-12-30 06:38:48.706315+08 | | | active | | 525 | select datname,pid ,usename,query_start,wait_event_type,wait_event,state,backend_xid,backend_xmin,query fr
  58. om pg_stat_activity where state='active' or state='idle in transaction' order by query_start;
  59. (6)
  60. select pg_cancel_backend(2379);--不能杀锁的肇事者,只能杀死被锁的事务。
  61. select pg_terminate_backend(2379); --这个语句可以杀死锁的肇事者。
  62. select datname,pid ,usename,query_start,wait_event_type,wait_event,state,backend_xid,backend_xmin,query from pg_stat_activity where state='active' or state='idle in transaction' order by query_start;
  63. datname | pid | usename | query_start | wait_event_type | wait_event | state | backend_xid | backend_xmin | query
  64. ----------+------+----------+-------------------------------+-----------------+------------+---------------------+-------------+--------------+---------------------------------------------------------------------------------------------------------------
  65. postgres | 2506 | postgres | 2021-12-30 05:58:06.966698+08 | Client | ClientRead | idle in transaction | 526 | | update itpux set name='xsq3' where id=1;
  66. postgres | 2636 | postgres | 2021-12-30 06:41:32.672638+08 | | | active | | 526 | select datname,pid ,usename,query_start,wait_event_type,wait_event,state,backend_xid,backend_xmin,query from
  67. pg_stat_activity where state='active' or state='idle in transaction' order by query_start;

5.总结

  1. 紧急情况下如果要杀死锁的肇事者,只能使用pg_terminate_backend函数,
  2. 而pg_cancel_backend函数只能取消被阻塞的事务。

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/繁依Fanyi0/article/detail/236743
推荐阅读
相关标签
  

闽ICP备14008679号