10.PostgreSQL锁的处理

1.现象描述

遇到一个问题,select和delete表时正常执行,但truncate和drop表时会一直运行而且不报错。

2.分析

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

3.模拟会话

会话1:update itpux set id=1 where name='xsq1';
会话2:update itpux set name='xsq3' where id=1;
会话3:update itpux set id=3 where id=1;
会话4:update itpux set name='xsq4' where id=1;

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;
 datid | datname  | pid  | usename  |          query_start          | wait_event_type |     wait_event      |        state        | backend_xid | backend_xmin |query                                                        
-------+----------+------+----------+-------------------------------+-----------------+---------------------+---------------------+-------------+--------------+-----------------------------------------------------------------------------------------------------------------------------------------
       |          | 2363 |          |                               | Activity        | AutoVacuumMain      |                     |             |              | 
       |          | 2366 | postgres |                               | Activity        | LogicalLauncherMain |                     |             |              | 
 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';
 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;
 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;
 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;
 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;

(10 rows)


state=idle in transaction 说明开始了事物,但是没有提交。
backend_xid  事物id;525 
backend_xmin:  造成锁的事物id; 
wait_event_type=Lock;  说明它被锁。

4.查询对象是否锁表了

(1)
postgres=# select oid from pg_class where relname='itpux';
  oid  
-------
 16405
(1 row)

postgres=# select database,relation,pid,mode,granted,transactionid from pg_locks;
 database | relation | pid  |       mode       | granted | transactionid 
----------+----------+------+------------------+---------+---------------
    13593 |    16405 | 3362 | RowExclusiveLock | t       |              
          |          | 3362 | ExclusiveLock    | t       |              
    13593 |    16405 | 3049 | RowExclusiveLock | t       |              
          |          | 3049 | ExclusiveLock    | t       |              
    13593 |    12143 | 2636 | AccessShareLock  | t       |              
          |          | 2636 | ExclusiveLock    | t       |              
    13593 |    16405 | 2506 | RowExclusiveLock | t       |              
          |          | 2506 | ExclusiveLock    | t       |              
    13593 |    16405 | 2379 | AccessShareLock  | t       |              
    13593 |    16405 | 2379 | RowExclusiveLock | t       |              
          |          | 2379 | ExclusiveLock    | t       |              
    13593 |    16405 | 3049 | ExclusiveLock    | f       |              
          |          | 2379 | ExclusiveLock    | t       |           525
          |          | 3049 | ExclusiveLock    | t       |           527
          |          | 2506 | ShareLock        | f       |           525
          |          | 2506 | ExclusiveLock    | t       |           526
          |          | 3362 | ExclusiveLock    | t       |           528
    13593 |    16405 | 2506 | ExclusiveLock    | t       |              
    13593 |    16405 | 3362 | ExclusiveLock    | f       |   

(2)如果查询到了结果,表示该表被锁 则需要释放锁定
select pg_cancel_backend(3362);

(3)再次检查。
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;
 datname  | pid  | usename  |          query_start          | wait_event_type |  wait_event   |        state        | backend_xid | backend_xmin |                                                                                                  query     
                                                                                              
----------+------+----------+-------------------------------+-----------------+---------------+---------------------+-------------+--------------+------------------------------------------------------------------------------------------------------------
 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';
 postgres | 2506 | postgres | 2021-12-30 05:58:06.966698+08 | Lock            | transactionid | active              |         526 |          525 | update itpux set name='xsq3' where id=1;
 postgres | 3049 | postgres | 2021-12-30 06:11:35.725454+08 | Lock            | tuple         | active              |         527 |          525 | update itpux set id=3 where id=1;
 postgres | 2636 | postgres | 2021-12-30 06:36:57.656019+08 |                 |               | active              |             |          525 | 
 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;



(4)
select pg_cancel_backend(3049);
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;
 datname  | pid  | usename  |          query_start          | wait_event_type |  wait_event   |        state        | backend_xid | backend_xmin |                                                                                                  query                                                                                        
----------+------+----------+-------------------------------+-----------------+---------------+---------------------+-------------+--------------+------------------------------------------------------------------------------------------------------------
 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';
 postgres | 2506 | postgres | 2021-12-30 05:58:06.966698+08 | Lock            | transactionid | active              |         526 |          525 | update itpux set name='xsq3' where id=1;
 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
om pg_stat_activity where state='active' or state='idle in transaction' order by query_start;

(5)
select pg_cancel_backend(2379); ---没有能够杀死锁的肇事者。
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;
 datname  | pid  | usename  |          query_start          | wait_event_type |  wait_event   |        state        | backend_xid | backend_xmin |                                                                                                  query                                                                                           
----------+------+----------+-------------------------------+-----------------+---------------+---------------------+-------------+--------------+------------------------------------------------------------------------------------------------------------
 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';
 postgres | 2506 | postgres | 2021-12-30 05:58:06.966698+08 | Lock            | transactionid | active              |         526 |          525 | update itpux set name='xsq3' where id=1;
 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
om pg_stat_activity where state='active' or state='idle in transaction' order by query_start;

(6)
select pg_cancel_backend(2379);--不能杀锁的肇事者,只能杀死被锁的事务。
select pg_terminate_backend(2379);  --这个语句可以杀死锁的肇事者。

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;
 datname  | pid  | usename  |          query_start          | wait_event_type | wait_event |        state        | backend_xid | backend_xmin |                                                                                                  query        
                                                                                           
----------+------+----------+-------------------------------+-----------------+------------+---------------------+-------------+--------------+---------------------------------------------------------------------------------------------------------------
 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;
 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 
pg_stat_activity where state='active' or state='idle in transaction' order by query_start;

5.总结

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

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
12306的数据库设计 原⽂地址:http://blog.csdn.net/hnkontecna/article/details/61672983 标签 标签 PostgreSQL , 12306 , 春节 , ⼀票难求 , 门禁⼴告 , 数组 , 范围类型 , 抢购 , 排他约束 , ⼤盘分析 , ⼴告查询 , ⽕车票 背景 背景 马上春节了,⼜到了⽕车票的销售旺季,⼀票难求的问题依旧存在吗? 还记得10年前春节前买⽕车票得在放票前1天搬个⼩板凳去排队,对于热门路线,排⼀个晚上都有可能买不到票。 随着互联⽹的发展,⼏年前建设了12306⽹上购票系统,可以从电脑上买票,但是不要以为在电脑上就能买到票。 我记得12306刚推出时,经常发⽣12306⽹站打不开,⽆法付款的问题。 为什么呢? 原因很简单,春节期间⽹上购票的⼈可能达到⼏亿的级别,⽽且放票⽇期是同⼀天同⼀个时间点,也就是说同⼀时刻12306要接受⼏亿⽤ 户的访问。 处理能⼒和实际的访问需求更不上,带来的结果就是⽹站打不开,系统不稳定的现象。 后来12306想了分线路分时段开启的办法,想办法把不同线路的⽤户错开时间来访问12306的⽹站,但是这个⽅法起初的效果不明显,并 不是所有⽤户都知道的(就好像你临时通知今天不上班,但还是有⽤户会来单位的),所以⼤多数⽤户还是集中在⼀个点去访问12306的 ⽹站。 随着硬件的发展,技术的演进,12306的系统越来越趋于成熟,稳定性和响应速度也越来越好。 据说现在很多商家还开通了云抢票业务,本质上是让你不要冲击12306系统了,把需求提前收集,在放票时,这些系统会进⾏排队与合并 购买,这种⼿段可以减少12306的访问并发。 抢⽕车票是很有意思的⼀个课题,对IT⼈的智商以及IT系统的健壮性,尤其是数据库的功能和性能都是⼀种挑战。 接下来我们⼀起来缕⼀缕有哪些难点,⼜有怎样的解决⼿段。 ⼀、铁路售票系统 ⼀、铁路售票系统 - 西天取经之路开始啦 西天取经之路开始啦 铁路售票系统最基本的功能包括 查询余票、余票统计、购票、车次变化、退票、改签、中转乘车规划 等。 每个需求都有各⾃的特点,例如 1. 查询余票,⽤户在购票前通常会查⼀下到达⽬的地有哪些余票,它属于⼀个⾼并发的操作,同时需要统计余票张数,需要很强的CPU来 ⽀撑实时的查询。 2. 购票,购票和查询不⼀样,购票是会改变库存的,所以对数据库来说是更新的操作。 ⽽且购票很可能发⽣冲突,例如很多⼈要买同⼀趟车的票,那就出现冲突了,到底卖给谁呢? 需要考虑冲突,尽量的让不同的⼈购买时可并⾏,或者可以合并多⼈的购票请求,来减少数据库的更新操作。 3. 中转乘车,当⽤户需要购买的起点和到达站⽆票时,需要计算中转的搭乘⽅案。 ⽐如从北京到上海,如果没有直达车,是不是该转车呢?转哪趟,在哪⾥转就成了问题,简单⼀点就是买票的⼈⾃⼰想。 ⾼级⼀点的话,可以让12306给你推荐路线,这个涉及的是数据库的路径规划功能。 我们来逐⼀分析⼀下这些需求的特点。 1 查询余票 查询余票 1. 普通的余票查询需求 你如果要买从北京到上海的⽕车票,通常会查⼀下哪些车次还有余票。 查询的过滤条件可能很多,⽐如 1.1. 上车站、下车站、中转站 1.2. 车次类型(⾼铁、动车、直达、快速、普客、...) 1.3. 出发⽇期、时段 1.4. 到达⽇期、时段 1.5. 席别(硬座、硬卧、...站票) 1.6. 过滤掉没有余票的车次 展⽰给⽤时还要考虑到怎么排序(是按始发时间排呢,还是按票价,或者按余票数量排?),怎么分页。 眼见不⼀定为实 查询余票通常不是实时的、或者说不⼀定是准确的,有可能是后台异步统计的结果。 即使是实时统计的结果,在⾼并发的抢票期间,你看到的信息对你来说也许很快就会失效。 ⽐如你看到某趟车还有100张票,很可能等你付款的时候,已经卖光了。 所以在⾼峰期,余票信息的参考价值并不⼤,不要被迷惑了。 2. 查询余票的另⼀个更⾼级的需求是路径规划, ⾃动适配(根据⽤户输⼊的中转站点s) 这个功能以前可能没有,但是总有⼀天会暴露出来,特别是车票很紧张的情况下。 就⽐如从北京到上海,直达的没有了,系统可以帮你看看转⼀趟车的,转2趟车的,转N趟车的。(当然,转的越多越复杂)。 从中转这个⾓度来讲,实际上已经扯上路径规划的技术了。 怎么中转是时间最短的、价格最低的、中转次数最少的等等。(⾥⾯还涉及转车的输⼊要求(⽐如⽤户要求在⼀线城市转车,或者必须要转 ⾼铁))。 关于路径规划,可以参考⼀下PostgreSQL pgrouting,已⽀持多种路径规划算法,⽀持算法的⾃定义扩展。 简直是居家旅⾏,杀⼈灭⼝的必备良药。 师⽗⼩⼼,有妖怪。。。 师⽗⼩⼼,有妖怪。。。 1. ⼤多数⽤户是有选择综合症的,通常来说,⽤户可能会查
鸣谢 首先要感谢linus,给了我们一个可以自由翱翔的平台; 其次,要感谢网络上千万的linux/windows先行者,给予的有意或无意的指点和帮助; 再次,感谢陈皓兄的《跟我一起写makefile》,引导我走过了makefile的迷雾。后来发现于凤昌兄译的《GNU Make使用手册》,也有颇多受益。 背景 从2004年,我在一个公司作服务端软件的开发,要支持linux/windows平台,主要是为了容易维护,就设计、开发了这一套比较常用的类。 2005一直在windows下作IPTV的开发,在2006年底,又回到linux下作IPV6下IPTV的开发。在空闲时间,看看两年前的那些零散类文件,开始整理这些类成库,并写了简单的使用和测试范例,放在网上和朋友们共享。 由于早期的平台从windows98和VC6.0,redhat8.0,经历了些变迁,没有太多的时间再一一仔细测试,就用现在的windowsXP和VS.2003,Fedaro Core4.0作的测试。 主要是为了相互学习,希望能和朋友们共同进步!如有引用,请标明出处,会不胜感激!禁止商业性的书籍的引用!很多不良的作者,完全是在骗钱。 功能简介 通用于linux/windows平台C++的应用。 主要是对一些系统功能,进行了简洁封装。 主要有读写类, 线程类, 线程池类, 定时器类, socket1.1的封装类, ini文件类, txt文件类, 可删除内容的文件类, 查找文件类, 调试输出类, 字符串类, 同步的普通队列和优先级队列类, 智能指针和内存自动管理类,数据库类. 特别声明:因为环境限制,这次测试代码中,没有测试数据库类。我以前也只是在PostgreSQLSQL Server2000和Acess2000中实际用过。如有朋友用到,请自行修改、测试。 这些类的风格,与个人习惯密切相关。推荐QT,跨平台的类库,还是不错的;ACE就太难使用了! 编译和运行: 1. windwos下,用vs2003打开pub下的test.sln文件,所有的测试程序和类库文件就载入,编译即可。其它程序引用库时,请选中/MDd选项。 2. linux下,执行pub下的Makefile文件,编译即可。如果没有安装PostgreSql数据库部分会编译不过。 关于inline函数 我写的这些类的函数,大部分是可以写成inline函数的,对性能提高也有很大的帮助。但是,GCC和VC的不同版本编译器的支持程度不同,可能会编译不过,所以就都没有为提高效率而写inline函数。依赖于编译器,对跨平台的程序来说,也比较麻烦! 不过,现在的硬件系统,对这些小小的性能提升,也感觉不出来的。 如有需要,请自行改写! 关于异常和错误处理 也是仁者见仁,智者见智! 习惯于C开发的朋友,大概喜欢函数错误时返回错误码。函数有返回值,就要处理,就使程序逻辑较为复杂,看去也比较的混乱。 我则喜欢用异常代替,主要是代码简洁和逻辑清晰。异常抛掷,会使流程很简洁,只显示执行正确时的流程,错误集中处理 对于那些失败即意味着中止的一个操作,我让其抛掷异常。如果是正常的分支流程,则用返回失败值。就我遇到的情况,大部分则为操作失败,调用的流程一般都要中止的。 这个判断也是比较难下的。放在一个局部,异常可能导致操作中止;但放在更上一层,则异常又可能是正确程序流程处理。 bug的反馈和修改支持 如果有重大的错误需要偶修正,请发到[email protected]的邮箱,尽量说明问题的现象,我会在一周内解决的(如果工作比较紧急的时候,不能即时就处理的)。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值