PostgreSQL
 sql >> Cơ Sở Dữ Liệu >  >> RDS >> PostgreSQL

Bộ nhớ đệm trong PostgreSQL

Bộ nhớ đệm… !!, hơi khó để nói ngắn gọn với một bài báo. Nhưng tôi sẽ cố gắng chia sẻ kiến ​​thức học được từ Heikki / Robert Haas / Bruce Momjian Nói ngắn gọn. Trong PostgreSQL, có hai lớp, bộ đệm chia sẻ PG và bộ đệm Trang hệ điều hành, bất kỳ quá trình đọc / ghi nào đều phải thông qua bộ đệm hệ điều hành (Không bỏ qua cho đến nay). Postgres ghi dữ liệu trên Bộ đệm trang hệ điều hành và xác nhận với người dùng khi nó đã được ghi vào đĩa, sau đó, bộ nhớ đệm hệ điều hành sẽ ghi vào đĩa vật lý theo tốc độ riêng của nó. Bộ đệm chia sẻ PG không có quyền kiểm soát Bộ đệm trang hệ điều hành và thậm chí nó không biết có gì trong bộ đệm hệ điều hành. Vì vậy, hầu hết các đề xuất được Postgres DBA’s / Professional’s đưa ra để có DISK nhanh hơn / bộ nhớ đệm tốt hơn.

Bộ nhớ đệm / bộ đệm trong PostgreSQL mạnh hơn giống như các cơ sở dữ liệu khác và rất phức tạp. Là người nền tảng Oracle (tư duy cũng… :)), vì vậy, câu hỏi của tôi từ người mà tôi đã học được là làm thế nào / khi nào / cái gì / tại sao, v.v., liên quan đến bộ đệm cơ sở dữ liệu đệm, bộ đệm được ghim, bộ đệm cơ sở dữ liệu Flushing bộ đệm, tải trước cơ sở dữ liệu, v.v., Tôi đã nhận được tất cả các câu trả lời của mình từ họ, tuy nhiên, cách tiếp cận có một chút khác biệt. Mặc dù các câu hỏi của tôi rất khó hiểu, họ đã trả lời một cách rất kiên nhẫn và giải thích cho tôi ở mức độ tốt mà kết quả là bạn đang đọc blog này…. :) ..

Trên một số kiến ​​thức (vẫn đang học), tôi đã rút ra một cái nhìn tổng quan nhỏ về cách thức lưu chuyển dữ liệu giữa Bộ nhớ đến Đĩa trong Postgres cũng như một số công cụ quan trọng và bản vá MỚI của Robert Haas (pg_prewarm) .

pg_buffercache
Một mô-đun đóng góp, cho biết những gì trong bộ đệm đệm PostgreSQL. Cài đặt bên dưới:-

postgres=# CREATE EXTENSION pg_buffercache;

pgfincore
Nó có chức năng cung cấp thông tin về dữ liệu nào trong Bộ đệm trang hệ điều hành. Pgfincore, mô-đun trở nên rất tiện dụng khi nó được kết hợp với pg_buffercache, giờ đây người ta có thể lấy thông tin bộ đệm PG và bộ đệm Trang hệ điều hành cùng nhau. Cảm ơn Cerdic Villemain. Pgfincore, backbone là fadvise, fincore là ftools linux. Bạn cũng có thể sử dụng fincore / fadvise bằng cách cài đặt nguồn. Hai điều, bạn có thể sử dụng mô-đun đóng góp pgfincore hoặc ftools đều cho kết quả như nhau. Tôi đã thử cả hai, chúng chỉ đơn giản là tuyệt vời.

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
Tải trước quan hệ / chỉ mục vào bộ đệm PG đệm. Nó có thể trong PostgreSQL không? ồ vâng, Cảm ơn Robert Haas , người gần đây đã gửi bản vá cho cộng đồng, hy vọng nó có thể có ở phiên bản PG 9.2 hoặc PG 9.3. Tuy nhiên, bạn có thể sử dụng bản vá để thử nghiệm trên PG 9.1.

pg_prewarm có ba CHẾ ĐỘ:

  1. TÌM KIẾM: Tìm nạp khối dữ liệu không đồng bộ chỉ vào bộ đệm hệ điều hành chứ không vào bộ đệm PG (chỉ truy cập bộ đệm hệ điều hành)
  2. ĐỌC: Đọc tất cả các khối vào bộ đệm giả và buộc vào bộ đệm hệ điều hành. (chỉ truy cập bộ nhớ cache của hệ điều hành)
  3. LỖI: đọc tất cả các khối hoặc phạm vi khối vào bộ nhớ đệm của bộ đệm cơ sở dữ liệu.

Cài đặt:
Tôi đang áp dụng bản vá pg_prewarm trên cài đặt nguồn PG của mình, bạn cần phải chỉnh sửa theo thiết lập của mình.

  1. Không có vị trí của nguồn PG:/usr/local/src/postgresql-9.1.3
  2. Ngôn ngữ cài đặt PG:/ usr / local / pgsql91
  3. Tất cả các bản tải xuống Vị trí:/ usr / local / src

Lưu ý:Cài đặt PG trước khi áp dụng bản vá pg_prewarm.

1. Tải bản vá xuống / usr / local / src / location
http://archives.postgresql.org/pgsql-hackers/2012-03/binRVNreQMnK4.bin
Bản vá đính kèm Email:
> http://archives.postgresql.org/message-id/CA+TgmobRrRxCO+t6gcQrw_dJw+Uf9ZEdwf9beJnu+RB5TEBjEw@mail.gmail.com
2. Sau khi tải xuống, hãy chuyển đến vị trí nguồn PG và làm theo các bước.

# 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. Lệnh trên sẽ tạo các tệp dưới $ PGPATH / Contrib / extension. Bây giờ bạn đã sẵn sàng để thêm mô-đun đóng góp.

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
Sự kết hợp của công cụ vmstat, iostat, netstat, top, v.v., với nhau trong một lệnh linux “dstat”. Khi cơ sở dữ liệu hoạt động bất thường, để biết nguyên nhân từ cấp hệ điều hành, chúng tôi mở một số thiết bị đầu cuối để kéo tiến trình, bộ nhớ, đọc / ghi đĩa, thông tin mạng, điều này hơi khó khăn khi xáo trộn giữa các cửa sổ. Vì vậy, dstat có các tùy chọn phục vụ trong đó, giúp hiển thị tất cả các lệnh trong một đầu ra một cửa sổ.

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/

Các công cụ Linux
Nó được thiết kế để làm việc với các lệnh gọi hệ thống linux hiện đại bao gồm, mincore, fallocate, fadvise, v.v. Ftools, sẽ giúp bạn tìm ra tệp nào có trong bộ nhớ cache của hệ điều hành. Sử dụng các tập lệnh perl / python, bạn có thể truy xuất thông tin bộ nhớ cache của trang hệ điều hành trên các tệp đối tượng (pg_class.relfilenode). pg_fincore dựa trên điều này. Bạn có thể sử dụng tập lệnh pgfincore hoặc 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.

Bây giờ, tất cả chúng ta đã sẵn sàng tiến hành ví dụ để kiểm tra với các công cụ &tiện ích. Trong ví dụ của tôi, tôi có một bảng, nó có một chỉ mục &chuỗi với hơn 100 MB dữ liệu trong đó.

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

Truy vấn để biết kích thước được chiếm bởi bảng, trình tự và chỉ mục của nó.

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)

Tôi đã viết một truy vấn nhỏ bằng cách kết hợp pgfincore và pg_buffercache để lấy thông tin từ bộ đệm PG Buffer &OS Page. Tôi sẽ sử dụng truy vấn này thông qua ví dụ của mình, chỉ dán kết quả truy vấn này.

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.

Tải trước quan hệ / chỉ mục bằng pg_prewarm:
Trước khi trả lại cụm, tôi đã kích hoạt truy vấn quét tuần tự toàn bảng trên bảng “Bộ nhớ đệm” và lưu ý thời gian trước khi làm nóng mối quan hệ / chỉ mục.

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)

Cho phép làm ấm mối quan hệ / chỉ mục / trình tự bằng cách sử dụng pg_prewarm và kiểm tra kế hoạch truy vấn.

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 đầu ra:

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)

Để truy xuất thông tin tương tự bằng cách sử dụng tập lệnh python-ftools, bạn cần biết số relfilenode của đối tượng, hãy kiểm tra bên dưới.

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)

sử dụng tập lệnh python-ftools

Nó không thú vị sao…. !!!!.
Bây giờ hãy so sánh kế hoạch giải thích sau khi làm ấm bàn vào bộ đệm.

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)

Làm cách nào để xóa / báo động trước mối quan hệ / chỉ mục trong bộ nhớ cache của hệ điều hành?
Sử dụng pgfadvise, bạn có thể tải trước hoặc xóa mối quan hệ khỏi bộ đệm hệ điều hành. Để biết thêm thông tin, hãy nhập df pgfadvise * trong thiết bị đầu cuối cho tất cả các chức năng liên quan đến pgfadvise. Dưới đây là ví dụ về cách xóa bộ nhớ cache của hệ điều hành.

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)

Trong khi những thứ này diễn ra trong một cửa sổ, bạn có thể kiểm tra tỷ lệ đọc / ghi bằng cách sử dụng dstat. Để có thêm tùy chọn, hãy sử dụng dstat –list
dstat -s –top-io –top-bio –top-mem

Phạm vi tải trước của khối đang sử dụng chức năng phạm vi pg_prewarm.
Giả sử, do một số lý do, bạn muốn trả lại cụm, nhưng một trong những bảng lớn nằm trong bộ đệm đang hoạt động tốt. Khi nảy, bảng của bạn không còn trong bộ đệm nữa, để trở lại trạng thái ban đầu như trước khi nảy thì bạn phải biết có bao nhiêu khối bảng trong bộ đệm và tải trước chúng bằng cách sử dụng tùy chọn phạm vi pg_prewarm.

Tôi đã tạo một bảng bằng cách truy vấn pg_buffercache và sau đó tôi đã gửi thông tin phạm vi khối đến pg_prewarm. Bằng cách này, các bộ đệm được chia sẻ đã trở lại với bảng đã được tải trước đó vào đó. Xem ví dụ.

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

Trả lại cụm và tải trước phạm vi khối liên quan đến bảng vào bộ đệm từ “blocks_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)

Thấy chưa, shared_buffer's của tôi đã hoạt động trở lại.

Vui thích…!!! sẽ trở lại với nhiều thứ thú vị hơn. Đăng nhận xét của bạn.


  1. Database
  2.   
  3. Mysql
  4.   
  5. Oracle
  6.   
  7. Sqlserver
  8.   
  9. PostgreSQL
  10.   
  11. Access
  12.   
  13. SQLite
  14.   
  15. MariaDB
  1. Trừ số năm cho một ngày trong PostgreSQL

  2. Cách to_date () hoạt động trong PostgreSQL

  3. Sử dụng nhiều mục tiêu xung đột trong mệnh đề ON CONFLICT

  4. Không thể kết nối với máy chủ postgres trong một docker từ một ứng dụng dày đặc

  5. PostgreSQL cách xem truy vấn nào đã chạy