最近写了一篇介绍长事务和长事务的一些常见危害,比如垃圾回收不及时导致的扩表等问题。刚刚又遇到了一个同样是长时间office导致的问题。上周六早上,接到同事的电话,说某图书馆的CPU一直很高。看了下,原来是某个大表全表扫描导致的,但是奇怪的是,所有相关查询都使用了索引列。不知道为什么查询All没有索引。我查了一下,发现确实是这样。如果只是某个查询没有用到索引,可能是SQL本身的问题,但是所有和这张表相关的SQL都没有用到索引,我自然而然的认为是索引本身的问题。向上。是因为索引无效吗?检查后发现这个表上的索引状态是正常的,我也重建了索引,但是还是不行。就在我一头雾水的时候,不小心执行了相关的SQL,发现又用到了索引。现在是什么状况?.我什么都没做,你自己恢复了。这不是让我看起来很蠢吗?不,你必须弄清楚为什么。再次查看相关索引时,发现索引的pg_index中的indcheckxmin列为真。这个字段在我之前写的一篇关于索引失败的文章中有介绍。那么什么情况下索引的这个属性会被设置为true呢?两种情况:当前交易的表上存在断链HOT;当设置old_snapshot_threshold时。之前我们也介绍过,如果索引的属性为true,那么在创建索引的事务中索引是不可用的,但是我们很少遇到这种场景,因为在实际应用中我们基本不会在事务中使用它创建索引后直接使用,无需提交事务。indcheckxmin的详细解释是:直到这个pg_index行的xmin低于查询的TransactionXmin,查询才能使用这个索引。那么在什么情况下会出现这个问题呢?长期业务!当我们创建索引时,如果索引的indcheckxmin设置为true,此时数据库中有一个长事务,那么在长事务提交之前,索引将一直不可用。让我们模拟一下这种情况:--Session1:开启一个多头交易?
