PostgreSQL快取
目錄[-]
快取.... !!, 它很難在一篇文章中解釋清楚。但是我會努力分享我從Heikki, Robert Haas, Bruce Momjian那裡學到的知識。在PostgreSQL裡有兩層:PG共享緩衝和作業系統頁面快取,任何讀寫都會通過作業系統快取(迄今為止還沒有其它途徑)。Postgres把資料寫在作業系統頁面快取,使用者覺得資料好像回寫到了磁碟,之後作業系統快取才會寫到對應的物理磁碟位置。PG共享緩衝無法控制系統頁面快取,甚至連繫統快取是什麼都不知道。所以,Postgres DBA或者專家給出的大多數建議都是更快的磁碟讀寫或者更好的快取。
PostgreSQL的快取/緩衝和其它資料庫十分相像並且十分複雜。因為我有Oracle和mindset背景,所以我使用怎麼樣/什麼時候/什麼/為什麼等提問方式,關於資料庫的緩衝快取,固定的緩衝,重新整理資料庫快取,以及預載入資料庫等方面,我都是從這種方式獲得答案的,然而這種方式有點與眾不同。儘管我的問題很煩人,但是他們總是耐心的回答,使我明白擴充套件我的知識,反過來,你才能閱讀這篇博文... :) ..
在一些學習上,我畫了一幅Postgres中資料在記憶體和磁碟之間傳遞的,以及一些重要的工具和Robert Hass提供的新補丁(pg_prewarm).
pg_buffercache
它是一個contrib模組,它會告訴你什麼是PostgreSQL快取。像下面安裝:
1 | postgres=# CREATE EXTENSION pg_buffercache |
pgfincore
它有一個顯示資料在作業系統頁面快取中資訊的功能。Pgfincore和pg_buffercache聯合會十分方便的。現在,它可以同時獲得PG緩衝和作業系統頁面快取資訊。感謝Cerdic Villemain。Pgfincore的主幹是fadvise,fincore,它倆是linux ftools。你可以使用原始碼安裝fincore/fadvise。你可以使用pgfincore contrib模組或者ftools,都會產生同樣的結果。我試了兩者,它們都十分簡單優秀。
安裝:
下載最新版本:
- http://pgfoundry.org/frs/download.php/3186/pgfincore-v1.1.1.tar.gz
使用root使用者:
1 2 3 4 5 6 | export PATH= /usr/local/pgsql91/bin :$PATH // 設定執行pg_config的路徑 tar -xvf pgfincore-v1.1.1. tar .gz cd pgfincore-1.1.1 make clean make make install |
1 | postgres=# CREATE EXTENSION pgfincore; |
pg_prewarm
預載入關係/索引到PG快取中,在PostgreSQL中可能嗎?當然可以了,感謝Robert Hass,他提交一些補丁到社群,期待它能夠在PG 9.2或者PG 9.3中可行。然而,你可以使用這個補丁在PG 9.1做一些測試。
pg_prewarm
有三種模式:
- PREFETCH: 非同步獲取資料塊到作業系統快取中,而不是PG緩衝(提示只是作業系統快取)
- READ:讀取所有的資料塊到虛擬快取中,然後寫到作業系統快取中(提示只是作業系統快取)
- BUFFER:讀取所有的或者一些資料塊到資料庫緩衝中。
我把pg_prewarm補丁加入到PG原始碼安裝中,你需要調整你的每步安裝。
- 解壓PG原始碼路徑: /usr/local/src/postgresql-9.1.3
- PG安裝路徑: /usr/local/pgsql91
- 所有下載路徑: /usr/local/src
1. 下載補丁,放在/usr/local/src
http://archives.postgresql.org/pgsql-hackers/2012-03/binRVNreQMnK4.bin
補丁附加郵件地址
2. 在下載之後,到PG原始碼目錄,然後執行下面幾步。
1 2 3 4 | # cd /usr/local/src/postgresql-9.1.3 # patch -p1 < ../pg_prewarm.bin (在下載之後我重新命名了pg_prewarm) # make -C contrib/pg_prewarm # make -C contrib/pg_prewarm instal |
3. 上面的命令會在$PGPATH/contrib/extension目錄裡建立檔案。現在準備新增contrib模組了。
1 2 3 4 5 6 7 8 9 10 11 | postgres=# create EXTENSION pg_prewarm; CREATE EXTENSION postgres=# \dx List of installed extensions Name | Version | Schema | Description ----------------+---------+------------+---------------------------------------- pg_buffercache | 1.0 | public | examine the shared buffer cache pg_prewarm | 1.0 | public | prewarm relation data pgfincore | 1.1.1 | public | examine and manage the os buffer cache plpgsql | 1.0 | pg_catalog | PL/pgSQL procedural language (4 rows ) |
1 2 3 | <span>/usr/ local /src/postgres-9.1.3/doc/src/sqml [root@localhost sgml]# ll pgpre* -rw-r --r-- 1 root root 2481 Apr 10 10:15 pgprewarm.sgml</span> |
dstat
它是vmstat, netstat, top等工具的組合到一起成了一個"dstat"linux命令。當資料庫表現不正常時,從作業系統級別瞭解語句,我們會開啟好幾個終端來顯示程式,記憶體,磁碟讀寫,網路資訊,但是在這些視窗切換是十分痛苦的。所以,dstat有幾個選項來幫助顯示所有的命令在一個輸出視窗中。
安裝:
Dstat下載連線:(RHEL 6)
- wget http://pkgs.repoforge.org/dstat/dstat-0.7.2-1.el6.rfx.noarch.rpm
或者
- <span style="padding:0px; margin:0px">yum install dstat</span>
Linux ftools
在被設計在現代的linux作業系統中用來呼叫像mincore, fallocate, fadivse等的工具。Ftools它會幫助你找出那些檔案在作業系統快取中。使用perl/python指令碼,你可以獲得作業系統頁面快取資訊在pg_class.relfilenode物件中。pg_fincore就是建立在它之上的。你可以使用pgfincore或者ftools指令碼。安裝:
- 從這個連線下載.tar.gz
- https://github.com/david415/python-ftools
- cd python-ftools
- python setup.py build
- export PYTHONPATH=build/lib.linux-x86_64-2.5
- python setup.py install
- 注意:你應該在安裝python-ftools之前就已經安裝好了。
現在,我使用例子來檢驗這些工具。在這個例子中,有一個表,它有一個索引和序列(sequence),大小為100多MB。
- postgres=# \d+ cache
- Table "public.cache"
- Column | Type | Modifiers | Storage | Description
- --------+---------+-----------------------------------------+----------+-------------
- name | text | | extended |
- code | integer | | plain |
- id | integer | default nextval('icache_seq'::regclass) | plain |
- Indexes:
- "icache" btree (code)
- Has OIDs: no
- postgres=# SELECT c.relname AS object_name,
- CASE when c.relkind='r' then 'table'
- when c.relkind='i' then 'index'
- when c.relkind='S' then 'sequence'
- else 'others'
- END AS type,pg_relation_size(c.relname::text) AS size, pg_size_pretty(pg_relation_size(c.relname::text)) AS pretty_size
- FROM pg_class c
- JOIN pg_roles r ON r.oid = c.relowner
- LEFT JOIN pg_namespace n ON n.oid = c.relnamespace
- WHERE (c.relkind = ANY (ARRAY['r'::"char", 'i'::"char", 'S'::"char",''::"char"])) AND n.nspname = 'public';
- object_name | type | size | pretty_size
- -------------+----------+----------+-------------
- icache_seq | sequence | 8192 | 8192 bytes
- cache | table | 83492864 | 80 MB
- icache | index | 35962880 | 34 MB
- (3 rows)
- Total object size 'cache'
- postgres=# select pg_size_pretty(pg_total_relation_size('cache'));
- pg_size_pretty
- ----------------
- 114 MB
- (1 row)
- select rpad(c.relname,30,' ') as Object_Name,
- case when c.relkind='r' then 'Table' when c.relkind='i' then 'Index' else 'Other' end as Object_Type,
- rpad(count(*)::text,5,' ') as "PG_Buffer_Cache_usage(8KB)",
- split_part(pgfincore(c.relname::text)::text,','::text,5) as "OS_Cache_usage(4KB)"
- from pg_class c inner join pg_buffercache b on b.relfilenode=c.relfilenode
- inner join pg_database d on (b.reldatabase=d.oid and d.datname=current_database() and c.relnamespace=(select oid from pg_namespace where nspname='public'))
- group by c.relname,c.relkind
- order by "PG_Buffer_Cache_usage(8KB)"
- desc limit 10;
- object_name | object_type | PG_Buffer_Cache_usage(8KB) | OS_Cache_usage(4KB)
- -------------+-------------+----------------------------+---------------------
- (0 rows)
- 注意: 我已經重新整理PG緩衝和作業系統頁面快取。所以,快取/緩衝沒有任何資料.
使用pg_prewarm預載入關係/索引:
在之前,我重新整理整個"Cache"表的順序遍歷查詢和之前預載入關係/索引的時間。- postgres=# explain analyze select * from cache ;
- QUERY PLAN
- ------------------------------------------------------------------------------------------------------------------
- Seq Scan on cache (cost=0.00..26192.00 rows=1600000 width=19) (actual time=0.033..354.691 rows=1600000 loops=1)
- Total runtime: 427.769 ms
- (2 rows)
- postgres=# select pg_prewarm('cache','main','buffer',null,null);
- pg_prewarm
- ------------
- 10192
- (1 row)
- postgres=# select pg_prewarm('icache','main','buffer',null,null);
- pg_prewarm
- ------------
- 4390
- (1 row)
- Output of combined buffers:
- object_name | object_type | PG_Buffer_Cache_usage(8KB) | OS_Cache_usage(4KB)
- -------------+-------------+----------------------------+---------------------
- icache | Index | 4390 | 8780
- cache | Table | 10192 | 20384
- (2 rows)
pgfincore 輸出:
- postgres=# select relname,split_part(pgfincore(c.relname::text)::text,','::text,5) as "In_OS_Cache" from pg_class c where relname ilike '%cache%';
- relname | In_OS_Cache
- ------------+-------------
- icache_seq | 2
- cache | 20384
- icache | 8780
- (3 rows)
- or for each object.
- postgres=# select * from pgfincore('cache');
- relpath | segment | os_page_size | rel_os_pages | pages_mem | group_mem | os_pages_free | databit
- ------------------+---------+--------------+--------------+-----------+-----------+---------------+---------
- base/12780/16790 | 0 | 4096 | 20384 | 20384 | 1 | 316451 |
- (1 row)
使用python-ftools指令碼也會獲得相似的資訊,你應該知道relfilenode物件的編號。像下面一樣檢視。
- postgres=# select relfilenode,relname from pg_class where relname ilike '%cache%';
- relfilenode | relname
- -------------+----------------
- 16787 | icache_seq /// 你執行的序列
- 16790 | cache /// 表
- 16796 | icache /// 索引
- (3 rows)
有趣吧....!!!!.
現在比較一下預載入表到緩衝之後的explain plan
- postgres=# explain analyze select * from cache ;
- QUERY PLAN
- ------------------------------------------------------------------------------------------------------------------
- Seq Scan on cache (cost=0.00..26192.00 rows=1600000 width=19) (actual time=0.016..141.804 rows=1600000 loops=1)
- Total runtime: 215.100 ms
- (2 rows)
怎樣重新整理在作業系統快取中的關係/索引 ?
使用pgfadvise,你可以預載入或者重新整理關係到作業系統快取。獲得更多資訊,在終端中使用\df pgfadvise*來顯示所有與pgfadvise相關的函式。下面是重新整理作業系統快取的一個例子。- postgres=# select * from pgfadvise_dontneed('cache');
- relpath | os_page_size | rel_os_pages | os_pages_free
- ------------------+--------------+--------------+---------------
- base/12780/16790 | 4096 | 20384 | 178145
- (1 row)
- postgres=# select * from pgfadvise_dontneed('icache');
- relpath | os_page_size | rel_os_pages | os_pages_free
- ------------------+--------------+--------------+---------------
- base/12780/16796 | 4096 | 8780 | 187166
- (1 row)
- postgres=# select relname,split_part(pgfincore(c.relname::text)::text,','::text,5) as "In_OS_Cache" from pg_class c where relname ilike '%cache%';
- relname | In_OS_Cache
- ------------+-------------
- icache_seq | 0
- cache | 0
- icache | 0
- (3 rows)
dstat -s --top-io --top-bio --top-mem
使用pg_prewarm的range功能預載入隨機塊.
假設,因為一些原因,你想重新整理伺服器,但是有一個很大的表它在快取中,而且執行的很好。在重新整理中,快取 中就沒有了你的表了,要回到重新整理前的狀態,你不得不知道多少表塊在快取中以及使用pg_prewarm的range選項來預載入它。我通過pg_buffercache來查詢已建立的表,然後我使用pg_prewarm的range選項來傳送塊。通過這樣,共享快取就像先前載入到快取中一樣回來了。請看例子
- select c.relname,count(*) as buffers from pg_class c
- inner join pg_buffercache b on b.relfilenode=c.relfilenode and c.relname ilike '%cache%'
- inner join pg_database d on (b.reldatabase=d.oid and d.datname=current_database())
- group by c.relname
- order by buffers desc;
- relname | buffers
- ---------+---------
- cache | 10192
- icache | 4390
- (2 rows)
- Note: These are the blocks in buffer.
- postgres=# create table blocks_in_buff (relation, fork, block) as select c.oid::regclass::text, case b.relforknumber when 0 then 'main' when 1 then 'fsm' when 2 then 'vm' end, b.relblocknumber from pg_buffercache b, pg_class c, pg_database d where b.relfilenode = c.relfilenode and b.reldatabase = d.oid and d.datname = current_database() and b.relforknumber in (0, 1, 2);
- SELECT 14716
- postgres=# select sum(pg_prewarm(relation, fork, 'buffer', block, block)) from blocks_in_buff;
- sum
- -------
- 14716
- (1 row)
- postgres=# select c.relname,count(*) as buffers from pg_class c
- inner join pg_buffercache b on b.relfilenode=c.relfilenode and c.relname ilike '%cache%'
- inner join pg_database d on (b.reldatabase=d.oid and d.datname=current_database())
- group by c.relname
- order by buffers desc;
- relname | buffers
- ---------+---------
- cache | 10192
- icache | 4390
- (2 rows)
目錄[-]
快取.... !!, 它很難在一篇文章中解釋清楚。但是我會努力分享我從Heikki, Robert Haas, Bruce Momjian那裡學到的知識。在PostgreSQL裡有兩層:PG共享緩衝和作業系統頁面快取,任何讀寫都會通過作業系統快取(迄今為止還沒有其它途徑)。Postgres把資料寫在作業系統頁面快取,使用者覺得資料好像回寫到了磁碟,之後作業系統快取才會寫到對應的物理磁碟位置。PG共享緩衝無法控制系統頁面快取,甚至連繫統快取是什麼都不知道。所以,Postgres DBA或者專家給出的大多數建議都是更快的磁碟讀寫或者更好的快取。
PostgreSQL的快取/緩衝和其它資料庫十分相像並且十分複雜。因為我有Oracle和mindset背景,所以我使用怎麼樣/什麼時候/什麼/為什麼等提問方式,關於資料庫的緩衝快取,固定的緩衝,重新整理資料庫快取,以及預載入資料庫等方面,我都是從這種方式獲得答案的,然而這種方式有點與眾不同。儘管我的問題很煩人,但是他們總是耐心的回答,使我明白擴充套件我的知識,反過來,你才能閱讀這篇博文... :) ..
在一些學習上,我畫了一幅Postgres中資料在記憶體和磁碟之間傳遞的,以及一些重要的工具和Robert Hass提供的新補丁(pg_prewarm).
pg_buffercache
它是一個contrib模組,它會告訴你什麼是PostgreSQL快取。像下面安裝:
1 | postgres=# CREATE EXTENSION pg_buffercache |
pgfincore
它有一個顯示資料在作業系統頁面快取中資訊的功能。Pgfincore和pg_buffercache聯合會十分方便的。現在,它可以同時獲得PG緩衝和作業系統頁面快取資訊。感謝Cerdic Villemain。Pgfincore的主幹是fadvise,fincore,它倆是linux ftools。你可以使用原始碼安裝fincore/fadvise。你可以使用pgfincore contrib模組或者ftools,都會產生同樣的結果。我試了兩者,它們都十分簡單優秀。
安裝:
下載最新版本:
- http://pgfoundry.org/frs/download.php/3186/pgfincore-v1.1.1.tar.gz
使用root使用者:
1 2 3 4 5 6 | export PATH= /usr/local/pgsql91/bin :$PATH // 設定執行pg_config的路徑 tar -xvf pgfincore-v1.1.1. tar .gz cd pgfincore-1.1.1 make clean make make install |
1 | postgres=# CREATE EXTENSION pgfincore; |
pg_prewarm
預載入關係/索引到PG快取中,在PostgreSQL中可能嗎?當然可以了,感謝Robert Hass,他提交一些補丁到社群,期待它能夠在PG 9.2或者PG 9.3中可行。然而,你可以使用這個補丁在PG 9.1做一些測試。
pg_prewarm
有三種模式:
- PREFETCH: 非同步獲取資料塊到作業系統快取中,而不是PG緩衝(提示只是作業系統快取)
- READ:讀取所有的資料塊到虛擬快取中,然後寫到作業系統快取中(提示只是作業系統快取)
- BUFFER:讀取所有的或者一些資料塊到資料庫緩衝中。
我把pg_prewarm補丁加入到PG原始碼安裝中,你需要調整你的每步安裝。
- 解壓PG原始碼路徑: /usr/local/src/postgresql-9.1.3
- PG安裝路徑: /usr/local/pgsql91
- 所有下載路徑: /usr/local/src
1. 下載補丁,放在/usr/local/src
http://archives.postgresql.org/pgsql-hackers/2012-03/binRVNreQMnK4.bin
補丁附加郵件地址
2. 在下載之後,到PG原始碼目錄,然後執行下面幾步。
1 2 3 4 | # cd /usr/local/src/postgresql-9.1.3 # patch -p1 < ../pg_prewarm.bin (在下載之後我重新命名了pg_prewarm) # make -C contrib/pg_prewarm # make -C contrib/pg_prewarm instal |
3. 上面的命令會在$PGPATH/contrib/extension目錄裡建立檔案。現在準備新增contrib模組了。
1 2 3 4 5 6 7 8 9 10 11 | postgres=# create EXTENSION pg_prewarm; CREATE EXTENSION postgres=# \dx List of installed extensions Name | Version | Schema | Description ----------------+---------+------------+---------------------------------------- pg_buffercache | 1.0 | public | examine the shared buffer cache pg_prewarm | 1.0 | public | prewarm relation data pgfincore | 1.1.1 | public | examine and manage the os buffer cache plpgsql | 1.0 | pg_catalog | PL/pgSQL procedural language (4 rows ) |
1 2 3 | <span>/usr/ local /src/postgres-9.1.3/doc/src/sqml [root@localhost sgml]# ll pgpre* -rw-r --r-- 1 root root 2481 Apr 10 10:15 pgprewarm.sgml</span> |
dstat
它是vmstat, netstat, top等工具的組合到一起成了一個"dstat"linux命令。當資料庫表現不正常時,從作業系統級別瞭解語句,我們會開啟好幾個終端來顯示程式,記憶體,磁碟讀寫,網路資訊,但是在這些視窗切換是十分痛苦的。所以,dstat有幾個選項來幫助顯示所有的命令在一個輸出視窗中。
安裝:
Dstat下載連線:(RHEL 6)
- wget http://pkgs.repoforge.org/dstat/dstat-0.7.2-1.el6.rfx.noarch.rpm
或者
- <span style="padding:0px; margin:0px">yum install dstat</span>
Linux ftools
在被設計在現代的linux作業系統中用來呼叫像mincore, fallocate, fadivse等的工具。Ftools它會幫助你找出那些檔案在作業系統快取中。使用perl/python指令碼,你可以獲得作業系統頁面快取資訊在pg_class.relfilenode物件中。pg_fincore就是建立在它之上的。你可以使用pgfincore或者ftools指令碼。安裝:
- 從這個連線下載.tar.gz
- https://github.com/david415/python-ftools
- cd python-ftools
- python setup.py build
- export PYTHONPATH=build/lib.linux-x86_64-2.5
- python setup.py install
- 注意:你應該在安裝python-ftools之前就已經安裝好了。
現在,我使用例子來檢驗這些工具。在這個例子中,有一個表,它有一個索引和序列(sequence),大小為100多MB。
- postgres=# \d+ cache
- Table "public.cache"
- Column | Type | Modifiers | Storage | Description
- --------+---------+-----------------------------------------+----------+-------------
- name | text | | extended |
- code | integer | | plain |
- id | integer | default nextval('icache_seq'::regclass) | plain |
- Indexes:
- "icache" btree (code)
- Has OIDs: no
- postgres=# SELECT c.relname AS object_name,
- CASE when c.relkind='r' then 'table'
- when c.relkind='i' then 'index'
- when c.relkind='S' then 'sequence'
- else 'others'
- END AS type,pg_relation_size(c.relname::text) AS size, pg_size_pretty(pg_relation_size(c.relname::text)) AS pretty_size
- FROM pg_class c
- JOIN pg_roles r ON r.oid = c.relowner
- LEFT JOIN pg_namespace n ON n.oid = c.relnamespace
- WHERE (c.relkind = ANY (ARRAY['r'::"char", 'i'::"char", 'S'::"char",''::"char"])) AND n.nspname = 'public';
- object_name | type | size | pretty_size
- -------------+----------+----------+-------------
- icache_seq | sequence | 8192 | 8192 bytes
- cache | table | 83492864 | 80 MB
- icache | index | 35962880 | 34 MB
- (3 rows)
- Total object size 'cache'
- postgres=# select pg_size_pretty(pg_total_relation_size('cache'));
- pg_size_pretty
- ----------------
- 114 MB
- (1 row)
- select rpad(c.relname,30,' ') as Object_Name,
- case when c.relkind='r' then 'Table' when c.relkind='i' then 'Index' else 'Other' end as Object_Type,
- rpad(count(*)::text,5,' ') as "PG_Buffer_Cache_usage(8KB)",
- split_part(pgfincore(c.relname::text)::text,','::text,5) as "OS_Cache_usage(4KB)"
- from pg_class c inner join pg_buffercache b on b.relfilenode=c.relfilenode
- inner join pg_database d on (b.reldatabase=d.oid and d.datname=current_database() and c.relnamespace=(select oid from pg_namespace where nspname='public'))
- group by c.relname,c.relkind
- order by "PG_Buffer_Cache_usage(8KB)"
- desc limit 10;
- object_name | object_type | PG_Buffer_Cache_usage(8KB) | OS_Cache_usage(4KB)
- -------------+-------------+----------------------------+---------------------
- (0 rows)
- 注意: 我已經重新整理PG緩衝和作業系統頁面快取。所以,快取/緩衝沒有任何資料.
使用pg_prewarm預載入關係/索引:
在之前,我重新整理整個"Cache"表的順序遍歷查詢和之前預載入關係/索引的時間。- postgres=# explain analyze select * from cache ;
- QUERY PLAN
- ------------------------------------------------------------------------------------------------------------------
- Seq Scan on cache (cost=0.00..26192.00 rows=1600000 width=19) (actual time=0.033..354.691 rows=1600000 loops=1)
- Total runtime: 427.769 ms
- (2 rows)
- postgres=# select pg_prewarm('cache','main','buffer',null,null);
- pg_prewarm
- ------------
- 10192
- (1 row)
- postgres=# select pg_prewarm('icache','main','buffer',null,null);
- pg_prewarm
- ------------
- 4390
- (1 row)
- Output of combined buffers:
- object_name | object_type | PG_Buffer_Cache_usage(8KB) | OS_Cache_usage(4KB)
- -------------+-------------+----------------------------+---------------------
- icache | Index | 4390 | 8780
- cache | Table | 10192 | 20384
- (2 rows)
pgfincore 輸出:
- postgres=# select relname,split_part(pgfincore(c.relname::text)::text,','::text,5) as "In_OS_Cache" from pg_class c where relname ilike '%cache%';
- relname | In_OS_Cache
- ------------+-------------
- icache_seq | 2
- cache | 20384
- icache | 8780
- (3 rows)
- or for each object.
- postgres=# select * from pgfincore('cache');
- relpath | segment | os_page_size | rel_os_pages | pages_mem | group_mem | os_pages_free | databit
- ------------------+---------+--------------+--------------+-----------+-----------+---------------+---------
- base/12780/16790 | 0 | 4096 | 20384 | 20384 | 1 | 316451 |
- (1 row)
使用python-ftools指令碼也會獲得相似的資訊,你應該知道relfilenode物件的編號。像下面一樣檢視。
- postgres=# select relfilenode,relname from pg_class where relname ilike '%cache%';
- relfilenode | relname
- -------------+----------------
- 16787 | icache_seq /// 你執行的序列
- 16790 | cache /// 表
- 16796 | icache /// 索引
- (3 rows)
有趣吧....!!!!.
現在比較一下預載入表到緩衝之後的explain plan
- postgres=# explain analyze select * from cache ;
- QUERY PLAN
- ------------------------------------------------------------------------------------------------------------------
- Seq Scan on cache (cost=0.00..26192.00 rows=1600000 width=19) (actual time=0.016..141.804 rows=1600000 loops=1)
- Total runtime: 215.100 ms
- (2 rows)
怎樣重新整理在作業系統快取中的關係/索引 ?
使用pgfadvise,你可以預載入或者重新整理關係到作業系統快取。獲得更多資訊,在終端中使用\df pgfadvise*來顯示所有與pgfadvise相關的函式。下面是重新整理作業系統快取的一個例子。- postgres=# select * from pgfadvise_dontneed('cache');
- relpath | os_page_size | rel_os_pages | os_pages_free
- ------------------+--------------+--------------+---------------
- base/12780/16790 | 4096 | 20384 | 178145
- (1 row)
- postgres=# select * from pgfadvise_dontneed('icache');
- relpath | os_page_size | rel_os_pages | os_pages_free
- ------------------+--------------+--------------+---------------
- base/12780/16796 | 4096 | 8780 | 187166
- (1 row)
- postgres=# select relname,split_part(pgfincore(c.relname::text)::text,','::text,5) as "In_OS_Cache" from pg_class c where relname ilike '%cache%';
- relname | In_OS_Cache
- ------------+-------------
- icache_seq | 0
- cache | 0
- icache | 0
- (3 rows)
dstat -s --top-io --top-bio --top-mem
使用pg_prewarm的range功能預載入隨機塊.
假設,因為一些原因,你想重新整理伺服器,但是有一個很大的表它在快取中,而且執行的很好。在重新整理中,快取 中就沒有了你的表了,要回到重新整理前的狀態,你不得不知道多少表塊在快取中以及使用pg_prewarm的range選項來預載入它。我通過pg_buffercache來查詢已建立的表,然後我使用pg_prewarm的range選項來傳送塊。通過這樣,共享快取就像先前載入到快取中一樣回來了。請看例子
- select c.relname,count(*) as buffers from pg_class c
- inner join pg_buffercache b on b.relfilenode=c.relfilenode and c.relname ilike '%cache%'
- inner join pg_database d on (b.reldatabase=d.oid and d.datname=current_database())
- group by c.relname
- order by buffers desc;
- relname | buffers
- ---------+---------
- cache | 10192
- icache | 4390
- (2 rows)
- Note: These are the blocks in buffer.
- postgres=# create table blocks_in_buff (relation, fork, block) as select c.oid::regclass::text, case b.relforknumber when 0 then 'main' when 1 then 'fsm' when 2 then 'vm' end, b.relblocknumber from pg_buffercache b, pg_class c, pg_database d where b.relfilenode = c.relfilenode and b.reldatabase = d.oid and d.datname = current_database() and b.relforknumber in (0, 1, 2);
- SELECT 14716
- postgres=# select sum(pg_prewarm(relation, fork, 'buffer', block, block)) from blocks_in_buff;
- sum
- -------
- 14716
- (1 row)
- postgres=# select c.relname,count(*) as buffers from pg_class c
- inner join pg_buffercache b on b.relfilenode=c.relfilenode and c.relname ilike '%cache%'
- inner join pg_database d on (b.reldatabase=d.oid and d.datname=current_database())
- group by c.relname
- order by buffers desc;
- relname | buffers
- ---------+---------
- cache | 10192
- icache | 4390
- (2 rows)
相關文章
- 利用系統快取提高PostgreSQL操作效率快取SQL
- 使用PostgreSQL_Notify實現多例項快取同步SQL快取
- 快取穿透、快取擊穿、快取雪崩、快取預熱快取穿透
- 快取穿透、快取擊穿、快取雪崩快取穿透
- 快取穿透、快取雪崩、快取擊穿快取穿透
- Redis快取擊穿、快取穿透、快取雪崩Redis快取穿透
- HTTP快取——協商快取(快取驗證)HTTP快取
- [Redis]快取穿透/快取擊穿/快取雪崩Redis快取穿透
- 快取穿透 快取雪崩快取穿透
- 快取問題(一) 快取穿透、快取雪崩、快取併發 核心概念快取穿透
- 快取穿透、快取擊穿、快取雪崩區別快取穿透
- 快取問題(四) 快取穿透、快取雪崩、快取併發 解決案例快取穿透
- ServiceWorker 快取與 HTTP 快取快取HTTP
- mybatis快取-二級快取MyBatis快取
- MyBatis快取機制(一級快取,二級快取)MyBatis快取
- 快取、快取演算法和快取框架簡介快取演算法框架
- 快取淘汰、快取穿透、快取擊穿、快取雪崩、資料庫快取雙寫一致性快取穿透資料庫
- Redis詳解(十二)------ 快取穿透、快取擊穿、快取雪崩Redis快取穿透
- 面試總結 —— Redis “快取穿透”、“快取擊穿”、“快取雪崩”面試Redis快取穿透
- 快取穿透,快取擊穿,快取雪崩解決方案分析快取穿透
- 快取穿透、快取雪崩和快取擊穿是什麼?快取穿透
- Redis——快取穿透、快取擊穿、快取雪崩、分散式鎖Redis快取穿透分散式
- Redis快取穿透、快取雪崩、快取擊穿好好說說Redis快取穿透
- 分散式快取 - 快取簡介,常用快取演算法分散式快取演算法
- 什麼是redis快取雪崩、快取穿透、快取擊穿Redis快取穿透
- Web快取 – HTTP協議快取Web快取HTTP協議
- 快取工廠之Redis快取快取Redis
- 快取最佳化(快取穿透)快取穿透
- 如何設計快取系統:快取穿透,快取擊穿,快取雪崩解決方案分析快取穿透
- 快取快取
- flutter 獲取應用快取以及清除快取Flutter快取
- 快取專題:HTML5離線快取與HTTP快取快取HTMLHTTP
- http快取策略以及強快取和協商快取淺析HTTP快取
- 快取穿透、快取擊穿、快取雪崩概念及解決方案快取穿透
- REDIS快取穿透,快取擊穿,快取雪崩原因+解決方案Redis快取穿透
- Redis的快取穿透、快取雪崩、快取擊穿的區別Redis快取穿透
- 【Redis】快取穿透,快取擊穿,快取雪崩及解決方案Redis快取穿透
- 快取穿透、快取擊穿、快取雪崩區別和解決方案快取穿透