欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

PostgreSQL長事務與失效的索引查詢淺析介紹

 更新時間:2022年09月16日 10:35:38   作者:foucus、  
pg中的長事務會影響表中垃圾回收,導致表的年齡增長無法freeze。能消耗事務的只有當執(zhí)行了一些DML或者DDL操作后才能算是我們通常說的長事務。否則只能算是我們常說的長連接,當然長連接也有很多弊端,例如占用內存、cpu等資源

最近剛寫了一篇文章介紹了下長事務,以及一些長事務常見的危害,如無法及時的垃圾回收導致表膨脹之類的問題,最近剛好又碰到一個問題也是長事務所導致的。

上周六早上接到同事電話,說某個庫CPU一直很高,看了下全是某張大表的全表掃描導致,但是奇怪的是相關的查詢都有用到索引列,不知道為啥查詢全部都沒走索引。

當我連上去查看時發(fā)現(xiàn)確實如此,如果只是某個查詢不走索引那可能是SQL本身寫的有問題,但是這張表相關的所有SQL都不走索引,那自然會想到是索引本身的原因了。那是不是索引失效了呢?經(jīng)過檢查發(fā)現(xiàn)這張表上的索引狀態(tài)均正常,并且我還將索引重建了,可仍然沒起作用。

正當我迷茫的時候,偶然間再去執(zhí)行相關SQL的時候發(fā)現(xiàn)竟然又都走索引了,這又是啥情況。。

我啥都沒做你就自己恢復了,那不是顯得我很呆?不行,必須得搞清楚啥原因。

當我再去查看相關索引的時候發(fā)現(xiàn),該索引的pg_index中的indcheckxmin列均為true,這個字段我之前有寫過一篇索引失效的文章里介紹過。那么什么情況下索引的該屬性會被設置為true呢?兩種情況:

  1. 當前事務中表上存在broken HOT chains;
  2. 當old_snapshot_threshold被設置時。

之前我們也介紹過,如果索引的該屬性為true那么在創(chuàng)建索引的事務中該索引是不可用的,不過這種場景我們基本不太會遇到,因為在實際應用中我們基本不會在事務中創(chuàng)建完索引然后不提交該事務直接去使用。

而關于indcheckxmin的詳細解釋是:直到此pg_index行的xmin低于查詢的TransactionXmin之前,查詢都不能使用此索引。那么什么情況下會出現(xiàn)這種問題呢?長事務!

當我們創(chuàng)建索引的時候如果索引的indcheckxmin被設置為true,且數(shù)據(jù)庫中此時存在長事務,那么直到該長事務提交前,該索引會一直不可用。

下面我們來模擬這種情況:

--會話一:打開一個長事務

bill=# begin;
BEGIN
bill=*# delete from t;
DELETE 1000
bill=*#

--會話二:創(chuàng)建索引

由于old_snapshot_threshold參數(shù)被設置,所以創(chuàng)建的索引indcheckxmin被設置為true了。

bill=# show old_snapshot_threshold ;
 old_snapshot_threshold
------------------------
 1h
(1 row)
bill=# create index idx_t1 on t1(id);
CREATE INDEX
bill=# select indisvalid,indcheckxmin,indisready,indislive from pg_index where indexrelid = 'idx_t1'::regclass;
 indisvalid | indcheckxmin | indisready | indislive
------------+--------------+------------+-----------
 t          | t            | t          | t
(1 row)

使用該索引列進行查詢:

索引的確無法使用。

bill=# explain analyze select * from t1  where id = 100;
                                           QUERY PLAN
-------------------------------------------------------------------------------------------------
 Seq Scan on t1  (cost=0.00..209.00 rows=51 width=37) (actual time=0.010..0.692 rows=51 loops=1)
   Filter: (id = 100)
   Rows Removed by Filter: 9949
 Planning Time: 0.150 ms
 Execution Time: 0.706 ms
(5 rows)
bill=# set enable_seqscan = off;
SET
bill=# explain analyze select * from t1  where id = 100;
                                                    QUERY PLAN
-------------------------------------------------------------------------------------------------------------------
 Seq Scan on t1  (cost=10000000000.00..10000000209.00 rows=51 width=37) (actual time=0.063..0.732 rows=51 loops=1)
   Filter: (id = 100)
   Rows Removed by Filter: 9949
 Planning Time: 0.089 ms
 Execution Time: 0.796 ms
(5 rows)

提交該長事務后再次查詢:

索引變得可用了。

bill=# explain analyze select * from t1  where id = 100;
                                                  QUERY PLAN
---------------------------------------------------------------------------------------------------------------
 Index Scan using idx_t1 on t1  (cost=0.29..54.48 rows=51 width=37) (actual time=0.013..0.052 rows=51 loops=1)
   Index Cond: (id = 100)
 Planning Time: 0.061 ms
 Execution Time: 0.067 ms
(4 rows)

果然是長事務的坑啊!

由于我們的庫中基本都打開了old_snapshot_threshold參數(shù),導致創(chuàng)建的索引的indcheckxmin一定是true。但這其實并不會有什么太大影響,問題在于在創(chuàng)建索引的同時數(shù)據(jù)庫中存在長事務,這就導致了索引在創(chuàng)建完之后第一時間變得不可用了,需要直到該長事務被提交后才可用。

后來和同事求證發(fā)現(xiàn)他們之前也經(jīng)常碰到這種CPU變高然后又自己降下來的情況,之前并沒有注意是這張表的全表掃描導致的。由于該表是由pg_pathman創(chuàng)建的自動分區(qū),每天都會自己去創(chuàng)建一個新的分區(qū),因此如果每天自動創(chuàng)建分區(qū)的時候存在長事務,那么創(chuàng)建完之后相關的分區(qū)上的索引均是不可用的,這也是為什么查詢不走索引然后又自己恢復的原因了。

這個案例其實我們在實際生產(chǎn)中遇到的可能性還是很大的,如果你的數(shù)據(jù)庫打開了old_snapshot_threshold參數(shù),同時沒有做好長事務的監(jiān)控,那么創(chuàng)建的索引就會出現(xiàn)這種不可用的情況。長事務危害不淺?。?/p>

到此這篇關于PostgreSQL長事務與失效的索引查詢淺析介紹的文章就介紹到這了,更多相關PostgreSQL長事務內容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關文章希望大家以后多多支持腳本之家!

相關文章

  • Mybatis調用PostgreSQL存儲過程實現(xiàn)數(shù)組入?yún)鬟f

    Mybatis調用PostgreSQL存儲過程實現(xiàn)數(shù)組入?yún)鬟f

    這篇文章主要介紹了mybatis調用postgresql自定義函數(shù)傳遞數(shù)組參數(shù)的解決方案,具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2016-11-11
  • Postgresql查詢效率計算初探

    Postgresql查詢效率計算初探

    這篇文章主要給大家介紹了關于Postgresql查詢效率計算的相關資料,文中通過示例代碼介紹的非常詳細,對大家學習或者使用Postgresql具有一定的參考學習價值,需要的朋友們下面來一起學習學習吧
    2019-05-05
  • PostgreSQL:string_agg?多列值聚合成一列的操作示例

    PostgreSQL:string_agg?多列值聚合成一列的操作示例

    PostgreSQL中的STRING_AGG()函數(shù)是一個聚合函數(shù),用于連接字符串列表并在字符串之間放置分隔符,這篇文章主要介紹了PostgreSQL:string_agg多列值聚合成一列,需要的朋友可以參考下
    2023-08-08
  • PostgreSQL中ON?CONFLICT的使用及一些擴展用法

    PostgreSQL中ON?CONFLICT的使用及一些擴展用法

    Postgres?ON?CONFLICT是PostgreSQL數(shù)據(jù)庫中的一個功能,用于處理插入或更新數(shù)據(jù)時的沖突情況,下面這篇文章主要給大家介紹了關于PostgreSQL中ON?CONFLICT的使用及一些擴展用法的相關資料,需要的朋友可以參考下
    2024-06-06
  • PostgreSQL WAL日志膨脹的處理過程

    PostgreSQL WAL日志膨脹的處理過程

    PostgreSQL由于WAL日志的機制,導致其在不正確配置的情況下會出現(xiàn)磁盤空間暴漲的情況,本文檔就此情景寫一般處理辦法,感興趣的小伙伴跟著小編一起來看看吧
    2024-12-12
  • PostgreSQL自定義函數(shù)并且調用方式

    PostgreSQL自定義函數(shù)并且調用方式

    這篇文章主要介紹了PostgreSQL如何自定義函數(shù)并且調用,本文通過示例代碼給大家介紹的非常詳細,對大家的學習或工作具有一定的參考借鑒價值,需要的朋友可以參考下
    2023-06-06
  • postgresql 補齊空值、自定義查詢字段并賦值操作

    postgresql 補齊空值、自定義查詢字段并賦值操作

    這篇文章主要介紹了postgresql 補齊空值、自定義查詢字段并賦值操作,具有很好的參考價值,希望對大家有所幫助。一起跟隨小編過來看看吧
    2021-01-01
  • PGSQL 實現(xiàn)把字符串轉換成double類型(to_number())

    PGSQL 實現(xiàn)把字符串轉換成double類型(to_number())

    這篇文章主要介紹了PGSQL 實現(xiàn)把字符串轉換成double類型(to_number()),具有很好的參考價值,希望對大家有所幫助。一起跟隨小編過來看看吧
    2020-12-12
  • PostgreSQL標準建表語句分享

    PostgreSQL標準建表語句分享

    這篇文章主要介紹了PostgreSQL標準建表語句分享,具有很好的參考價值,希望對大家有所幫助。一起跟隨小編過來看看吧
    2020-12-12
  • postgresql常用日期函數(shù)使用整理

    postgresql常用日期函數(shù)使用整理

    在開發(fā)過程中經(jīng)常要取日期的年,月,日,小時等值,下面這篇文章主要給大家介紹了關于postgresql常用日期函數(shù)使用整理的相關資料,文中通過代碼及圖文介紹的非常詳細,需要的朋友可以參考下
    2024-02-02

最新評論