软件下载吧文章资讯

分类分类

PostgreSQL长事务与失效的索引查询浅析介绍

2024-02-09 10:40作者:下载吧

最近刚写了一篇文章介绍了下长事务,以及一些长事务常见的危害,如无法及时的垃圾回收导致表膨胀之类的问题,最近刚好又碰到一个问题也是长事务所导致的。

上周六早上接到同事电话,说某个库CPU一直很高,看了下全是某张大表的全表扫描导致,但是奇怪的是相关的查询都有用到索引列,不知道为啥查询全部都没走索引。

当我连上去查看时发现确实如此,如果只是某个查询不走索引那可能是SQL本身写的有问题,但是这张表相关的所有SQL都不走索引,那自然会想到是索引本身的原因了。那是不是索引失效了呢?经过检查发现这张表上的索引状态均正常,并且我还将索引重建了,可仍然没起作用。

正当我迷茫的时候,偶然间再去执行相关SQL的时候发现竟然又都走索引了,这又是啥情况。。

我啥都没做你就自己恢复了,那不是显得我很呆?不行,必须得搞清楚啥原因。

当我再去查看相关索引的时候发现,该索引的pg_index中的indcheckxmin列均为true,这个字段我之前有写过一篇索引失效的文章里介绍过。那么什么情况下索引的该属性会被设置为true呢?两种情况:

  1. 当前事务中表上存在broken HOT chains;
  2. 当old_snapshot_threshold被设置时。

之前我们也介绍过,如果索引的该属性为true那么在创建索引的事务中该索引是不可用的,不过这种场景我们基本不太会遇到,因为在实际应用中我们基本不会在事务中创建完索引然后不提交该事务直接去使用。

而关于indcheckxmin的详细解释是:直到此pg_index行的xmin低于查询的TransactionXmin之前,查询都不能使用此索引。那么什么情况下会出现这种问题呢?长事务!

当我们创建索引的时候如果索引的indcheckxmin被设置为true,且数据库中此时存在长事务,那么直到该长事务提交前,该索引会一直不可用。

下面我们来模拟这种情况:

–会话一:打开一个长事务

bill=# begin;
BEGIN
bill=*# delete from t;
DELETE 1000
bill=*#
展开全部

相关文章

说两句网友评论
    我要跟贴
    取消