PostgreSQL में कैश/बफर अन्य डेटाबेस की तरह मजबूत और अत्यधिक परिष्कृत हैं। जैसा कि ओरेकल बैकग्राउंड (माइंडसेट भी… :)) से है, इसलिए, मेरे प्रश्न से मैंने सीखा कि कैसे/कब/क्या/क्यों आदि, डेटाबेस बफर कैश, पिन किए गए बफर, फ्लशिंग डेटाबेस बफर कैश, प्रीलोडिंग डेटाबेस इत्यादि के संबंध में, मुझे अपने सभी उत्तर उन्हीं से मिले, हालांकि, दृष्टिकोण थोड़ा अलग है। हालाँकि मेरे प्रश्न परेशान करने वाले थे, उन्होंने बड़े धैर्य के साथ उत्तर दिया और मुझे काफी हद तक स्पष्ट किया जिसके परिणामस्वरूप आप इस ब्लॉग को पढ़ रहे हैं…। :)..
कुछ सीखों (अभी भी सीख रहे हैं) पर, मैंने पोस्टग्रेज़ में मेमोरी से डिस्क के बीच डेटा कैसे प्रवाहित होता है और रॉबर्ट हास (pg_prewarm) द्वारा कुछ महत्वपूर्ण टूल और नए पैच के बीच कैसे प्रवाहित होता है, इसका एक छोटा सा अवलोकन तैयार किया। ।
pg_buffercache
एक योगदान मॉड्यूल, जो बताता है कि PostgreSQL बफर कैश में क्या है। नीचे स्थापना:-
postgres=# CREATE EXTENSION pg_buffercache;
pgfincore
इसमें OS पेज कैश में कौन से डेटा के बारे में जानकारी देने की कार्यक्षमता है। Pgfincore, मॉड्यूल बहुत आसान हो जाता है जब इसे pg_buffercache के साथ जोड़ा जाता है, अब कोई भी PG बफर कैश और OS पेज कैश की जानकारी एक साथ प्राप्त कर सकता है। Cerdic Villemain को धन्यवाद। Pgfincore, backbone is fadvise, fincore जो linux ftools हैं। आप स्रोत स्थापित करके फिनकोर/फ़ैडविज़ का भी उपयोग कर सकते हैं। दो चीजें, आप pgfincore contrib मॉड्यूल का उपयोग कर सकते हैं या ftools दोनों का परिणाम समान है। मैंने दोनों की कोशिश की, वे बस कमाल के हैं।
Installation:
Download the latest version: http://pgfoundry.org/frs/download.php/3186/pgfincore-v1.1.1.tar.gz
As root user:
export PATH=/usr/local/pgsql91/bin:$PATH //Set the path to point pg_config.
tar -xvf pgfincore-v1.1.1.tar.gz
cd pgfincore-1.1.1
make clean
make
make install
Now connect to PG and run below command
postgres=# CREATE EXTENSION pgfincore;
pg_prewarm
संबंध/इंडेक्स को पीजी बफर कैश में प्रीलोड करना। क्या यह PostgreSQL में संभव है? अरे हाँ, रॉबर्ट हास . को धन्यवाद , जिसने हाल ही में समुदाय को पैच सबमिट किया है, उम्मीद है कि यह PG 9.2 या PG 9.3 में उपलब्ध हो सकता है। हालांकि, आप पीजी 9.1 पर अपने परीक्षण के लिए पैच का उपयोग कर सकते हैं।
pg_prewarm में तीन मोड हैं:
- प्रीफेच: डेटा ब्लॉक को अतुल्यकालिक रूप से OS कैश में लाना केवल PG बफ़र्स में नहीं (केवल OS कैश को हिट करता है)
- पढ़ें: सभी ब्लॉक को डमी बफर में पढ़ता है और ओएस कैश में बल देता है। (केवल ओएस कैश हिट करता है)
- बफर: डेटाबेस बफर कैश में सभी ब्लॉक या ब्लॉक की श्रेणी को पढ़ता है।
इंस्टॉलेशन:
मैं अपने पीजी स्रोत इंस्टॉलेशन पर pg_prewarm पैच लगा रहा हूं, आपको अपने सेटअप के अनुसार बदलाव करने की आवश्यकता है।
- पीजी स्रोत का पता न लगाएं:/usr/local/src/postgresql-9.1.3
- पीजी इंस्टालेशन लोकेटिन :/usr/लोकल/pgsql91
- सभी डाउनलोड स्थान:/usr/स्थानीय/src
नोट:pg_prewarm पैच लगाने से पहले PG इंस्टॉल करें।
1. पैच को /usr/local/src/ स्थान पर डाउनलोड करें
http://archives.postgresql.org/pgsql-hackers/2012-03/binRVNreQMnK4.bin
पैच संलग्न ईमेल:
http://archives.postgresql.org/message-id/CA+TgmobRrRxCO+t6gcQrw_dJw+Uf9ZEdwf9beJnu+RB5TEBjEw@mail.gmail.com
2. डाउनलोड करने के बाद पीजी सोर्स लोकेशन पर जाएं और स्टेप्स को फॉलो करें।
# cd /usr/local/src/postgresql-9.1.3
# patch -p1 < ../pg_prewarm.bin (I have renamed after download)
# make -C contrib/pg_prewarm
# make -C contrib/pg_prewarm install
3. उपरोक्त आदेश $PGPATH/contrib/extension के अंतर्गत फ़ाइलें बनाएगा। अब आप योगदान मॉड्यूल जोड़ने के लिए तैयार हैं।
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)
Documentation:
/usr/local/src/postgresql-9.1.3/doc/src/sgml
[root@localhost sgml]# ll pgpre*
-rw-r--r-- 1 root root 2481 Apr 10 10:15 pgprewarm.sgml
dstat
vmstat,iostat,netstat,top,आदि का एक संयोजन, एक "dstat" linux कमांड में एक साथ टूल। जब डेटाबेस असामान्य रूप से व्यवहार करता है, तो ओएस स्तर से कारण जानने के लिए, हम प्रक्रिया, मेमोरी, डिस्क पढ़ने/लिखने, नेटवर्क सूचनाओं को खींचने के लिए कुछ टर्मिनल खोलते हैं, जो विंडोज़ के बीच शफल करने के लिए थोड़ा सा दर्द होता है। तो, dstat में सर्वरल विकल्प हैं, जो सभी कमांड को एक आउटपुट एक विंडो में दिखाने में मदद करता है।
Installation:
Dstat download link: (RHEL 6)
wget http://pkgs.repoforge.org/dstat/dstat-0.7.2-1.el6.rfx.noarch.rpm
or
yum install dstat
Documentation: http://dag.wieers.com/home-made/dstat/
लिनक्स ftools
इसे आधुनिक linux सिस्टम कॉल के साथ काम करने के लिए डिज़ाइन किया गया है, जिसमें mincore, falocate, fadvise, आदि शामिल हैं। Ftools, आपको यह पता लगाने में मदद करेगा कि OS कैश में कौन सी फाइलें हैं। पर्ल/पायथन स्क्रिप्ट का उपयोग करके आप ऑब्जेक्ट फाइलों (pg_class.relfilenode) पर ओएस पेज कैश जानकारी पुनर्प्राप्त कर सकते हैं। pg_fincore इसी पर आधारित है। आप pgfincore या ftools स्क्रिप्ट का उपयोग कर सकते हैं।
Installation:
Download the tar.gz from the link.
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
Note: You need to have python & psycopg2 installed before installing python-ftools.
अब, हम टूल और उपयोगिताओं की जांच के लिए उदाहरण के साथ आगे बढ़ने के लिए पूरी तरह तैयार हैं। मेरे उदाहरण में, मेरे पास एक टेबल है, इसमें एक इंडेक्स और अनुक्रम है जिसमें 100+ एमबी डेटा है।
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)
मैंने पीजी बफर और ओएस पेज कैश से जानकारी खींचने के लिए pgfincore और pg_buffercache को जोड़कर छोटी सी क्वेरी लिखी है। मैं इस क्वेरी का उपयोग अपने उदाहरण के माध्यम से करूँगा, केवल इस क्वेरी आउटपुट को चिपकाने के लिए।
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)
Note: I have bounced the cluster to flush PG buffers & OS Page Cache. So, no data in any Cache/buffer.
pg_prewarm का इस्तेमाल करके रिलेशन/इंडेक्स को प्रीलोड करना:
क्लस्टर को बाउंस करने से पहले, मैंने "कैश" टेबल पर पूरी टेबल अनुक्रमिक स्कैन क्वेरी को सक्रिय किया है, और संबंध/इंडेक्स को गर्म करने से पहले का समय नोट किया है।
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)
pg_prewarm का उपयोग करके गर्म संबंध/अनुक्रमणिका/अनुक्रम दें और क्वेरी योजना की जांच करें।
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)
पाइथॉन-फुटूल स्क्रिप्ट का उपयोग करके समान जानकारी प्राप्त करने के लिए आपको वस्तुओं की relfilenode संख्या जानने की आवश्यकता है, नीचे देखें।
postgres=# select relfilenode,relname from pg_class where relname ilike '%cache%';
relfilenode | relname
-------------+----------------
16787 | icache_seq /// you can exclude sequence.
16790 | cache /// table
16796 | icache /// index
(3 rows)
python-ftools स्क्रिप्ट का उपयोग करना
क्या यह दिलचस्प नहीं है….!!!!.
अब टेबल को बफर में गर्म करने के बाद व्याख्या योजना की तुलना करें।
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)
OS कैश में रिलेशन को फ्लश/प्रीवार्म/इंडेक्स कैसे करें?
pgfadvise का उपयोग करके, आप OS कैश से संबंध को प्रीलोड या फ़्लश कर सकते हैं। अधिक जानकारी के लिए, pgfadvise से संबंधित सभी कार्यों के लिए टर्मिनल में df pgfadvise* टाइप करें। नीचे OS कैश फ्लश करने का उदाहरण दिया गया है।
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 का उपयोग करके पढ़ने/लिखने के अनुपात की जांच कर सकते हैं। अधिक विकल्पों के लिए उपयोग करें dstat –list
dstat -s –top-io –top-bio –top-mem
pg_prewarm रेंज कार्यक्षमता का उपयोग कर ब्लॉक की प्रीलोडिंग रेंज।
मान लें, किसी कारण से, आप क्लस्टर को बाउंस करना चाहते हैं, लेकिन एक बड़ी तालिका जो बफर में है, अच्छा प्रदर्शन कर रही है। बाउंस होने पर, आपकी तालिका बफ़र्स में नहीं रह जाती है, मूल स्थिति में वापस आने के लिए जैसा कि बाउंस होने से पहले था, तो आपको यह जानना होगा कि बफ़र्स में कितने टेबल ब्लॉक थे और pg_prewarm रेंज विकल्प का उपयोग करके उन्हें प्रीलोड करें।
मैंने pg_buffercache को क्वेरी करके एक टेबल बनाया है और बाद में मैंने ब्लॉक रेंज की जानकारी pg_prewarm पर भेज दी है। इसके द्वारा, साझा किए गए बफ़र्स पहले से लोड की गई तालिका के साथ वापस आ जाते हैं। उदाहरण देखें।
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
क्लस्टर को बाउंस करें और टेबल से संबंधित ब्लॉक की रेंज को "block_in_buff" से बफ़र्स में प्रीलोड करें।
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)
देखिए, मेरा शेयर्ड_बफ़र वापस चलन में है।
आनंद लेना…!!! अधिक रोचक सामग्री के साथ वापस आऊंगा। अपनी टिप्पणियाँ पोस्ट करें।