Chức năng phía Server

Bài viết liên quan tới chức năng phía server

VACUUM

VACUUM và chức năng autovacuum

Tại sao PostgreSQL cần VACUUM ?

  1. Dung lượng đĩa cứng có thể full
    Khác với các RDBMS khác (như MySQL), khi người dùng chạy lệnh DELETE hay UPDATE, PostgreSQL không xoá dữ liệu cũ đi luôn mà chỉ đánh dấu "đó là dữ liệu đã bị xoá".
    Nên nếu liên tục INSERT/DELETE hoặc UPDATE dữ liệu mà không có cơ chế xoá dữ liệu dư thừa thì dung lượng ổ cứng tăng dẫn đến full.

  2. Lỗi (dữ liệu bị vô hiệu) khi Wraparound Transaction ID
    PostgreSQL sử dụng 32 bit Transaction ID (XID) để quản lý transaction(1). Mỗi một record dữ liệu đều có thông tin về XID. Khi dữ liệu được tham chiếu PostgreSQL sử dụng thông tin XID này so sánh với XID hiện tại để đánh giá dữ liệu này có hữu hiệu không. Dữ liệu đang tham chiếu có XID lớn hơn XID hiện tại là dữ liệu không hữu hiệu. Khi sử dụng hết 32 bit XID (khoảng 4 tỷ transactions), để sử dụng tiếp XID sẽ được reset về ban đầu (0). Nếu không có cơ chế chỉnh lại XID trong data thì mỗi lần reset XID, dữ liệu hiện tại sẽ trống trơn (dữ liệu hiện tại luôn có XID lớn hơn XID đã reset (0)).

Một trong những chức năng của VACUUM là quyết những vấn đề như trên.

(1) transaction(Giao dịch cơ sở dữ liệu): Định nghĩa từ wikipedia: Giao dịch cơ sở dữ liệu (database transaction) là đơn vị tương tác của một hệ quản lý cơ sở dữ liệu hoặc các hệ tương tự, mỗi giao dịch được xử lý một cách nhất quán và tin cậy mà không phụ thuộc vào các giao dịch khác. Một hệ cơ sở dữ liệu lý tưởng sẽ phải bảo đảm toàn bộ các tính chất ACID cho mỗi giao dịch. Trên thực tế, các tính chất này thường được nới lỏng để giúp việc thực thi đạt hiệu quả hơn.

PostgreSQL không thực hiện xóa dữ liệu ngay sau khi DELETE hoặc UPDATE nhằm giải quyết vấn đề cùng một lúc nhiều người sử dụng truy cập một vùng dữ liệu (PostgreSQL gọi cơ chế đó là Multiversion Concurrency Control hay MVCC). Theo thông tin gần đây từ cộng đồng PostgreSQL, từ phiên bản 12(?) PostgreSQL có thể bỏ chức năng VACUUM nhờ sử dụng cơ chế lưu trữ zheap.

VACUUM thực hiện những công việc gì

  • Lấy lại dữ liệu dư thừa để tái sử dụng
  • Cập nhật thông tin thống kê (statistics)
  • Giải quyết vấn đề dữ liệu bị vô hiệu khi Wraparound Transaction ID

Lấy lại dữ liệu dư thừa

Như trên, PostgreSQL chưa xoá dữ liệu cũ khi thực hiện thao tác DELETE/UPDATE. Khi VACUUM, những dữ liệu dư thừa đó sẽ được lấy lại và vị trí dư thừa sẽ được cập nhật lại trong bảng vị trí trống (Free Space Map(FSM)). Ngoài ra những block dữ liệu đã được VACUUM sẽ được đánh dấu là đã VACUUM trên bảng khả thị (Visibility Map(VM)), khi UPDATE/DELETE dữ bảng khả thị sẽ cập nhật lại trạng thái là cần VACUUM.

Free Space Map(FSM): Mỗi bảng dữ liệu (hoặc index) tồn tại tương ứng một FSM. FSM chứa thông tin các vị trí trống trong file dữ liệu. Khi dữ liệu mới được ghi PostgreSQL sẽ nhìn vị trí trống từ FSM trước, việc này giảm thiểu truy cập trực tiếp (sinh I/O disk) vào file dữ liệu. File FSM nằm cùng vị trí với file dữ liệu và có tên = file_dữ_liệu_fsm (như ví dụ dưới).
Visibility Map(VM): Mỗi bảng dữ liệu tồn tại tương ứng một visibility map (VM). Một block dữ liệu tương ứng với 1 bit trên VM. VACUUM xem trước thông tin VM của bảng dữ liệu, và chỉ thực hiện trên những block cần được VACUUM. File VM nằm cùng vị trí với file dữ liệu và có tên = file_dữ_liệu_vm (như ví dụ dưới).


testdb=# create table testtbl(id integer);
CREATE TABLE
testdb=# insert into testtbl select generate_series(1,100);
INSERT 0 100
testdb=# delete from testtbl where id < 90;
DELETE 89
testdb=# checkpoint;
CHECKPOINT
testdb=# \! ls -l $PGDATA/base/16384/24576*
-rw------- 1 bocap staff 8192 Jun 24 18:19 /Users/bocap/Downloads/pg94/data/base/16384/24576
-rw------- 1 bocap staff 24576 Jun 24 18:19 /Users/bocap/Downloads/pg94/data/base/16384/24576_fsm
-rw------- 1 bocap staff 8192 Jun 24 18:19 /Users/bocap/Downloads/pg94/data/base/16384/24576_vm

Cập nhật lại thông tin thống kê

Một số bạn lầm tưởng rằng chỉ có chức năng ANALYZE mới cập nhật lại thông tin thống kê dùng bởi planner, nhưng thực tế VACUUM cũng cập nhật thông tin này. Cụ thể là relpages và reltuples trong system catalog pg_class. Do vậy nên có thể nói VACUUM cũng ảnh hưởng tới việc chọn plan thực thi.


postgres=# select relpages,reltuples from pg_class where relname = 'testtbl';
 relpages | reltuples 
----------+-----------
        0 |         0
(1 row)

postgres=# insert into testtbl select generate_series(1,10),random()::text;
INSERT 0 10
postgres=# select relpages,reltuples from pg_class where relname = 'testtbl';
 relpages | reltuples 
----------+-----------
        0 |         0
(1 row)

postgres=# vacuum testtbl;
VACUUM
postgres=# select relpages,reltuples from pg_class where relname = 'testtbl';
 relpages | reltuples 
----------+-----------
        1 |        10
(1 row)

autovacuum

autovacuum là chức năng tự động thực thi VACUUM hoặc ANALYZE khi cần thiết. Chức năng này hoạt động khi tham số autovacuumtrack_counts thiết lập là on. Cả 2 tham số này đều mặc định là on nên autovacuum sẽ tự động hoạt động khi khởi động PostgreSQL. Khi tham số autovacuum là on. Sau khi khởi động PostgreSQL process "autovacuum launcher process" sẽ đảm nhận việc này.


BocapnoMacBook-Pro:postgres bocap$ ps -ef | grep autovacuum | grep  -v grep
501  3169  3164   0 13Aug17 ??         0:03.13 postgres: autovacuum launcher process


Launcher process cứ mỗi autovacuum_naptime sẽ kiểm tra thông tin thống kê, nếu thấy bảng nào cần thiết VACUUM hoặc ANALYZE, launcher process sẽ khởi động các worker processes để thực hiện việc VACUUM hoặc ANALYZE. Số lượng process autovacuum worker hoạt động trong cùng một thời điểm được giới hạn bởi tham số autovacuum_max_workers (mặc định là 3).


BocapnoMacBook-Pro:postgres bocap$ ps -ef | grep autovacuum | grep  -v grep
  501 26490 26484   0  1:14AM ??         0:00.01 postgres: autovacuum launcher process   
  501 26618 26484   0  1:16AM ??         0:00.03 postgres: autovacuum worker process   postgres

Điều kiện cần thiết cho bảng được VACUUM hoặc ANALYZE bởi autovacuum như bên dưới.

Ví dụ: số lượng dòng là 1000, thì mặc định khi số dòng bị xoá hoặc update lớn hơn 0.2*1000 + 50 = 250 bảng sẽ tự động được VACUUM

Ví dụ: số lượng dòng là 1000, thì mặc định khi số dòng bị xoá, update hoặc insert lớn hơn 0.1*1000 + 50 = 250 bảng sẽ tự động được ANALYZE

Khi chạy một câu truy vấn, thông tin thống kê cần phải chính xác để planner chọn đúng plan tối ưu nhất. autovacuum thực thi việc cập nhật thông tin này, nhưng vì một số lý do nào đó (ví dụ: đối tượng bảng đang bị lock trong transaction khác) , autovacuum không thực thi được tốt. Vì vậy, khi thấy câu truy vấn chạy chậm, nên kiểm tra thông tin thống kê xem ANALYZE, VACUUM đã được thực hiện tốt chưa thông qua view pg_stat_all_tables, và thực hiện  VACUUM ANALYZE  cũng là một giải pháp

Ngoài ra để  process autovacuum không ảnh hưởng tới hệ thống, việc thiết lập autovacuum = off và chạy VACUUM ANALYZE thủ công vào thời điểm thích hợp cũng được sử dụng nhiều

Giám sát hoạt động autovacuum

Để biết đối tượng bảng có được VACUUM, ANALYZE hợp lý không ta có thể xem thông qua view pg_stat_all_tables.

-- ví dụ bên dưới cho thấy bảng testtbl đã được:
-- vacuum thủ công vào lúc: 2017-08-26 23:50:28
-- autovacuum vào lúc: 2017-08-27 01:16:04 
-- autoanalyze vào lúc: 2017-08-27 01:16:04

postgres=# select last_vacuum,last_autovacuum,last_analyze,last_autoanalyze from pg_stat_all_tables where relid = (select oid from pg_class where relname = 'testtbl');
          last_vacuum          |        last_autovacuum        | last_analyze |       last_autoanalyze        
-------------------------------+-------------------------------+--------------+-------------------------------
 2017-08-26 23:50:28.025241+09 | 2017-08-27 01:16:04.664297+09 |              | 2017-08-27 01:16:04.665366+09
(1 row)

Ngoài ra, ta có thể theo dõi tình trạng hoạt động của autovacuum thông qua việc thiết lập tham số log_autovacuum_min_duration = 0 (log tất cả các hoạt động autovacuum).

Ví dụ:


2017-08-27 01:16:04.664 JST [26618] LOG:  automatic vacuum of table "postgres.public.testtbl": index scans: 0
	pages: 1276 removed, 0 remain, 0 skipped due to pins, 0 skipped frozen
	tuples: 100000 removed, 0 remain, 0 are dead but not yet removable, oldest xmin: 579
	buffer usage: 3851 hits, 0 misses, 0 dirtied
	avg read rate: 0.000 MB/s, avg write rate: 0.000 MB/s
	system usage: CPU: user: 0.02 s, system: 0.00 s, elapsed: 0.28 s
2017-08-27 01:16:04.665 JST [26618] LOG:  automatic analyze of table "postgres.public.testtbl" system usage: CPU: user: 0.00 s, system: 0.00 s, elapsed: 0.00 s

 

Lock

Lock

Cũng như các RDBMS khác. PostgreSQL cung cấp chức năng cho phép nhiều người dùng có thể truy cập và xử lý dữ liệu dữ liệu cùng một lúc mà không xảy ra xung đột. Tuỳ thuộc vào mức độ phân ly transaction (transaction isolation level) của PostgreSQL mà dữ liệu được nhìn thấy, xử lý như thế nào trong mỗi transaction. Để thực hiện các xử lý này mỗi khi xử lý một tài nguyên (ví dụ như bảng dữ liệu, dòng dữ liệu), phải có cơ chế lock tài nguyên này lại không cho tiến trình khác có thể can thiệp vào được.
PostgreSQL cung cấp nhiều kiểu lock để xử lý dữ liệu. Ví dụ: khi bạn SELECT nội dung đối tượng SELECT (bảng dữ liệu) sẽ bị yêu cầu ACCESS SHARE lock, khi UPDATE, DELETE dữ liệu đối tượng UPDATE, DELETE (dòng dữ liệu) sẽ bị yêu cầu ROW EXCLUSIVE lock, sau khi lock thành công lock này sẽ tồn tại tới khi transaction trong phiên làm việc đó kết thúc.


Các kiểu lock trên bảng dữ liệu PostgreSQL

Các kiểu lock cho bảng dữ liệu PostgreSQL bạn có thể tham khảo chi tiết từ document của PostgreSQL tại đây.

Câu truy vấn sẽ ở trạng thái chờ khi có một lock xung đột xảy ra trên bảng dữ liệu muốn truy vấn.
Như ví dụ bên dưới, khi bảng testtbl đang bị lock ACCESS SHARE bởi một session khác. Câu truy vấn xung đột với ACCESS SHARE (TRUNCATE) sẽ bị trạng thái chờ (lock wait) cho tới khi lock ACCESS SHARE được giải phóng.


postgres=# select * from pg_locks where relation = (select oid from pg_class where relname = 'testtbl');
-[ RECORD 1 ]------+-------------
locktype           | relation
database           | 12558
relation           | 24576
page               | 
tuple              | 
virtualxid         | 
transactionid      | 
classid            | 
objid              | 
objsubid           | 
virtualtransaction | 3/829
pid                | 5605
mode               | RowShareLock
granted            | t
fastpath           | t

postgres=# truncate testtbl ;

trạng thái chờ (lock wait) nhìn từ process hệ thống.


DangnoMacBook-Pro:work dangminhanh$ ps -ef | grep TRUNCATE |grep -v grep
  501  5696  3164   0  1:19AM ??         0:00.03 postgres: postgres postgres [local] TRUNCATE TABLE waiting

trạng thái lock wait trên database rất hay xảy ra khi logic application chưa đúng. Để troubleshoot trường hợp này ta thường tham khảo 2 view pg_stat_activity và pg_locks. Cách sử dụng xin vui lòng xem ở cuối bài viết này.

Lock wait sẽ xảy ra khi có xung đột như các trường hợp "X" bên dưới (trích dẫn từ Documents của PostgreSQL).

Xung đột lock ở mức độ bảng
Loại Lock yêu cầu Loại lock đang thực thi
ACCESS SHARE ROW SHARE ROW EXCLUSIVE SHARE UPDATE EXCLUSIVE SHARE SHARE ROW EXCLUSIVE EXCLUSIVE ACCESS EXCLUSIVE
ACCESS SHARE               X
ROW SHARE             X X
ROW EXCLUSIVE         X X X X
SHARE UPDATE EXCLUSIVE       X X X X X
SHARE     X X   X X X
SHARE ROW EXCLUSIVE     X X X X X X
EXCLUSIVE   X X X X X X X
ACCESS EXCLUSIVE X X X X X X X X

Các trường hợp lock xảy xảy ra ở mức độ dòng

Locks xảy ra với dòng có các mức độ như FOR UPDATE, FOR NO KEY UPDATE, FOR SHARE, FOR KEY SHARE tương ứng với khi chạy các câu truy vấn SELECT ... FOR UPDATE, FOR NO KEY UPDATE, FOR SHARE, FOR KEY SHARE. Lưu ý là locks xảy ra với dòng không xác nhận qua pg_locks view mà phải xác nhận thông qua pgrowlocks. Các xung đột xảy ra ở mức độ dòng được tóm tắt như bên dưới (trích dẫn từ Documents của PostgreSQL).

Mặc định transaction level cuả PostgreSQL (read committed) cho phép transaction khác ghi dữ liệu khi dữ liệu đó đang được tham chiếu. Điều này có thể làm cho logic của application chạy không đúng, như trường hợp kiểm tra dữ liệu hiện tại sau đó thực hiện câu lệnh cập nhật dữ liệu (dữ liệu lúc cập nhật có thể đã bị thay đổi bởi transaction khác). Trong những trường hợp này ta có thể sử dụng câu lệnh SELECT ... FOR UPDATE để giải quyết, câu lệnh này block dữ liệu đang tham chiếu tại lệnh (SELECT) tới khi transaction hiện tại kết thúc.

Các trường hợp xung đột lock ở mức độ dòng
Requested Lock Mode Current Lock Mode
FOR KEY SHARE FOR SHARE FOR NO KEY UPDATE FOR UPDATE
FOR KEY SHARE       X
FOR SHARE     X X
FOR NO KEY UPDATE   X X X
FOR UPDATE X X X X

Cách xác định tình trạng locks

Thông thường locks xác định thông qua view pg_locks. Trường granted cho biết locks đã thực hiện được chưa. nếu locks trong tình trạng waiting, giá trị của granted sẽ là false(t), trường hợp ngược lại sẽ là true.

như kết quả ví dụ bên dưới. Đối với bảng dữ liệu testtbl, process với PID: 24289 đã lock thành công(granted = t) với mode AccessExclusiveLock. Ở một phiên làm việc (kết nối) khác với PID: 24283 câu truy vấn tới sau cũng muốn lock với mode AccessExclusiveLock và đã bị ở trạng thái chờ(granted = f).


postgres=# select locktype,relation,pid,mode,granted,fastpath from pg_locks where relation = (select oid from pg_class where relname = 'testtbl');
 locktype | relation |  pid  |        mode         | granted | fastpath 
----------+----------+-------+---------------------+---------+----------
 relation |    24576 | 24283 | AccessExclusiveLock | f       | f
 relation |    24576 | 24289 | AccessExclusiveLock | t       | f
(2 rows)

Muốn xác định 2 câu truy vấn nào đang diễn ra, ta xem kết quả của view pg_stat_activity. Như kết quả bên dưới ta xác định được phiên làm việc nào, câu truy vấn nào đang bị ở trạng thái chờ, và phiên làm việc nào đang bị chờ.


postgres=# select datname,pid,wait_event_type,wait_event,state,query from pg_stat_activity where pid = 24283 or pid = 24289;
 datname  |  pid  | wait_event_type | wait_event |        state        |     query      
----------+-------+-----------------+------------+---------------------+----------------
 postgres | 24289 | Client          | ClientRead | idle in transaction | lock testtbl ;
 postgres | 24283 | Lock            | relation   | active              | lock testtbl ;
(2 rows)

Locks wait là một trường hợp điển hình của thiết kế client chưa được tốt, nên khi phát hiện nên xử lý logic phía client hơn là chỉnh tham số lock_timeout. Lưu ý nếu có thiết lập tham số lock_timeout cũng không nên chỉnh trong postgresql.conf, vì nó sẽ ảnh hưởng tới toàn bộ database cluster. Có thể chỉnh tham số này thông qua từng phiên làm việc (câu lệnh SET), hoặc USER, DATABASE (lệnh ALTER ... SET ... ).

Ngoài ra để kiểm tra tình trạng lock wait, ta có thể chỉnh tham số log_lock_waits = on, khi thời gian wait vượt quá giá trị deadlock_timeout PostgreSQL sẽ xuất log messages như bên dưới (đã waited 1001.236 ms nhưng chưa thành công).


LOG:  process 24289 still waiting for AccessExclusiveLock on relation 24576 of database 12558 after 1001.236 ms
DETAIL:  Process holding the lock: 24283. Wait queue: 24289.
STATEMENT:  lock testtbl ;

Khi lock thành công PostgreSQL sẽ xuất log messages như bên dưới (thành công sau 11409.427 ms waited).


LOG:  process 24289 acquired AccessExclusiveLock on relation 24576 of database 12558 after 11409.427 ms
STATEMENT:  lock testtbl ;

 

Cấu trúc processes của PostgreSQL

Cấu trúc processes của PostgreSQL

Khác với một số RDBMS khác sử dụng thread để xử lý, PostgreSQL sử dụng mỗi process cho những chức năng riêng biệt. Sau khi khởi tạo database và khởi động server, PostgreSQL sẽ có những processes như bên dưới.


[postgres@ip-172-31-31-242 ~]$ ps -ef | grep `head -1 $PGDATA/postmaster.pid    
postgres 17397     1  0 Apr11 pts/3    00:06:44 /usr/pgsql-9.6/bin/postgres    
postgres 17398 17397  0 Apr11 ?        00:00:33 postgres: logger process     
postgres 17400 17397  0 Apr11 ?        00:00:18 postgres: checkpointer process    
postgres 17401 17397  0 Apr11 ?        00:01:24 postgres: writer process     
postgres 17402 17397  0 Apr11 ?        00:01:31 postgres: wal writer process    
postgres 17403 17397  0 Apr11 ?        00:06:13 postgres: autovacuum launcher process    
postgres 17404 17397  0 Apr11 ?        00:11:30 postgres: stats collector process    
postgres  7205 17397  0 03:23 ?        00:00:00 postgres: postgres postgres [local] idle    

Cấu trúc tổng quan của các Processes có thể hiểu như bên dưới.

PostgreSQL processes


Postmaster Process


postgres 17397     1  0 Apr11 pts/3    00:06:44 /usr/pgsql-9.6/bin/postgres    

Là process khởi tạo đầu tiên sau khi server khởi động. Process này đảm nhiệm việc khởi động hoặc dừng các process khác nếu cần hoặc có yêu cầu. Sau khi khởi động Postmaster sẽ khởi động các processes thường trực như bên dưới để PostgreSQL server có thể hoạt động.

  • logger process
  • checkpointer process
  • writer process
  • wal writer process
  • autovacuum launcher process (process này không khởi động khi parameter autovacuum = off)
  • stats collector process

 Tiếp đó Postmaster sẽ thực hiện vòng lặp của mình, nếu có yêu cầu kết nối thoả mãn yêu cầu authenticate, hoặc khởi động các tiến trình thường trực khi bị lỗi. Khi có yêu cầu shutdown từ người dùng (pg_ctl stop), Postmaster sẽ gửi các signal tương ứng tới từng server processes.

logger process


postgres 17400 17397  0 Apr11 ?        00:00:18 postgres: logger process    

Process này đảm nhiệm việc ghi log của PostgreSQL.

checkpointer process


postgres 17400 17397  0 Apr11 ?        00:00:18 postgres: checkpointer process    

Process này chủ yếu giữ vai trò thực hiện checkpoint (đồng bộ dữ liệu từ bộ nhớ đệm xuống vùng lưu trữ) khi cần thiết.

writer process


postgres 17401 17397  0 Apr11 ?        00:01:24 postgres: writer process     

Hay còn gọi là background writer process, process này kết hợp với checkpointer process để đảm bảo việc ghi dữ liệu từ bộ đệm xuống vùng lưu trữ. Thông thường khi checkpoint không hoạt động, process này sẽ ghi từng chút một dữ liệu xuống vùng lưu trữ. Để hiểu thêm về background writer process xin vui lòng tham khảo ở manual tại đây.

wal writer process


postgres 17402 17397  0 Apr11 ?        00:01:31 postgres: wal writer process    

Đảm nhiệm việc đồng bộ WAL từ bộ nhớ đệm xuống vùng lưu trữ. Thông thường WAL sẽ được ghi từ bộ đệm xuống vùng lưu trữ khi transaction được commit. Nếu dữ liệu đệm của WAL trên bộ nhớ đệm vượt quá parameter wal_buffers dữ liệu WAL trên vùng nhớ đệm sẽ tự động ghi xuống vùng lưu trữ dữ liệu thông qua process này.

autovacuum launcher process


postgres 17403 17397  0 Apr11 ?        00:06:13 postgres: autovacuum launcher process    

Process này thường trú khi paramter autovacuum = on. Proccess này thực hiện chức năng tự động lấy vùng dữ liệu dư thừa sau khi DELETE hoặc UPDATE dữ liệu. Vui lòng thảo khảo bài viết về VACUUM để biết thêm về VACUUM. Process này khởi động các VACUUM worker processes sau mỗi autovacuum_naptime. Các VACUUM worker processes sẽ thực hiện việc VACUUM dữ liệu trên các database.

stats collector process


postgres 17404 17397  0 Apr11 ?        00:11:30 postgres: stats collector process    

Process này thực hiện vai trò lưu trữ các thông tin thống kê hoạt động của PostgreSQL và cập nhật vào các system catalog (thông tin nội bộ của PostgreSQL hiện diện bởi các bảng hoặc view pg_stat_*).

Server Process


postgres  7205 17397  0 03:23 ?        00:00:00 postgres: postgres postgres [local] idle    

Là các processes được sinh ra khi có yêu cầu từ phía client (aplication). Client gửi yêu cầu (bằng cách chạy các connection API) tới server, phía server sẽ sử dụng thông tin authentication (user, password, database, host) từ client để xem user này có được truy cập vào database không. Nếu được, Postmaster sẽ tạo một server process (bằng API fork()) cho client, từ đó client có thể chạy được các câu truy vấn, ... thông qua server process được tạo.

Một số processes không thường trực

Các processes không thường trực của PostgreSQL
Processes Chức năng
archiver process Thực hiện chức năng backup archive log (WAL). Process này khởi động khi parameter archive_mode = on.
startup process Process này thường trực ở Standby node, thực hiện chức năng phản ảnh dữ liệu WAL nhận được từ Master.
wal receiver process Thường trực ở standby. Sau khi khởi động process này kết nối tới Master node và tạo kết nối replication.
wal sender process postgres Thường trực ở Master khi có Standby (hoặc pg_basebackup) kết nối tới. Số lượng process wal sender bằng với số lượng wal receive + pg_basebackup kết nối tới.
bgworker: logical replication launcher [PostgreSQL 10] Process sử dụng cho chức năng logical replication. 

Giới thiệu về chức năng Replication(đồng bộ dữ liệu) của PostgreSQL

Replication

Bạn cần tạo một standby server để backup dữ liệu, load balance trên nhiều node để giảm tải tăng performance?, ... Chức năng replication sẽ đáp ứng nhu cầu đó của bạn.
Replication là một trong chức năng không thể thiếu của một số RDBMS nói chung và PostgreSQL(Streaming Replication) nói riêng. Ở PostgreSQL bạn có thể liên kiết với một số cluster soft như Pacemaker, hay pgpool-II để triển khai hệ thống High Availablity cho môi trường của bạn. Nguyên lý Streaming Replication của PostgreSQL dựa trên việc chuyển WAL (Transaction log) từ node Master tới Standby, sau đó Standby phản ánh lại nội dung WAL vào dữ liệu.

Chức năng replication của PostgreSQL đầu tiên được thêm vào ở phiên bản 9.0. Sau nhiều cải tiến qua các phiên bản. Hiện tại replication nổi bật với chức năng logical replication trên phiên bản sắp tới PostgreSQL-10. Quá trình phát triển chức năng replication tới phiên bản PostgreSQL 10 được tóm tắt như bên dưới.

Chức năng Replication qua các phiên bản PostgreSQL


Chức năng thiếu đồng bộ - Asynchronous (PostgreSQL 9.0).

Phải nói thêm là cũng ở phiên bản 9.0 này PostgreSQL có thêm chức năng hot_standby. Chức năng này cho phép tham chiếu dữ liệu ở phía Standby. Nếu chức năng này không hoạt động bạn không thể tham chiếu dữ liệu hay đơn giản là kết nối tới Standby server. Chức năng này gọi là thiếu đồng bộ. Vì dữ liệu cập nhật ở phía Master không được cập nhật tức thì ở Standby. Về nguyên lý thì bạn có thể tham khảo hình bên dưới.

Replication không đồng bộ

Chức năng tiền đồng bộ - Synchronous (PostgreSQL 9.1)

Tiến bộ hơn chức năng Asynchronous, ở chế độ Synchronous Standby Server gửi thông điệp thành công tới Master Server sau khi xác nhận đã nhận được thông tin WAL(Transaction log). Sau khi nhận được được thông điệp từ Standby Server, Master kết thúc xử lý cập nhật dữ liệu. Như vậy sau khi cập nhật dữ liệu ở Master Sever, phải chờ một chút thời gian (thường thì khoảng vài micro giây) để Standby phản ánh (recovery) dữ liệu đó từ WAL vừa nhận được. Lưu ý rằng PostgreSQL chỉ support 1 node là Synchronous. Nếu bạn lập nhiều Standby Server node đầu tiên chỉ định trong tham số synchronous_standby_names.

Replication tiền đồng bộ

Chức năng Cascade Replication (PostgreSQL 9.2)

Chức năng này cho phép bạn thiết lập một hoặc nhiều Standby Sever dựa vào một Standby Server chứ không phải Master Server như trước đây. Ở Cascade Replication mặc định chỉ sử dụng Asynchronous.

Chức năng replication slot (PostgreSQL 9.4)

Standby Server dựa vào WAL cung cấp từ Master Server để đồng bộ dữ liệu. Nhưng WAL này cũng có thể bị mất theo cơ chế sử dụng lại WAL của PostgreSQL. Khi WAL chưa được đồng bộ (chuyển tới) ở Standby mà bị mất ở Master Server. Standby này sẽ không thể đồng bộ với Master đó nữa, bạn phải thiết lập lại Standby Server trong trường hợp này.

Chức năng replication slot cho phép tạo một slot tới Master Server, yêu cầu Master Server giữ lại WAL cần thiết cho Standby đó.

Số lượng WAL thông thường phụ thuộc vào tham số max_wal_size (Hay checkpoint_segments ở phiên bản trước 9.5). Bạn cũng có thể chỉnh số lượng WAL giữ lại cho standby server qua tham số wal_keep_segments.

Chức Logical Decoding (PostgreSQL 9.4)

Chức năng Logical Decoding cho phép sử dụng plugin bên ngoài decoding được nội dung WAL thành các câu lệnh SQL. Chức năng này kết hợp với chức năng Replication Slot là nền tảng chính của chức năng Logical Replication trong phiên bản PostgreSQL 10. 

Chức năng Full Synchronous

Mình sử dụng chữ Full vì ở chế độ này, sau khi kết thúc câu lệnh cập nhật dữ liệu ở Master Server, có thể đảm bảo là dữ liệu sẽ chắc chắn đã được cập nhật ở Standby Server.

Full Synchronous

Logical Replication

Chức năng này đang được phát triển ở phiên bản PostgreSQL 10. Master Server public WAL, Standby Server nhận WAL giải mã thành các câu lệnh SQL rồi chạy các câu lệnh đó trên Standby Server. Điều này cho phép PostgreSQL có thể Replication giữa các phiên bản khác nhau, hoặc có thể kỳ vọng là replication với các RDBMS khác.

Các phiên bản PostgreSQL trước phiên bản 10, dữ liệu trên WAL không đủ chi tiết để giải mã thành các câu lệnh SQL. Và phía Server và Client phải nhất quán về phiên bản.

Logical replication



Cấu hình

Thiết lập Paramters

Thiết lập paramters cho từng level Asynchronous, Syncrhonous, Full Synchronous, Logical Replication có thể tóm tắt như bên dưới.

Các parameters liên quan tới Streaming Replication
Parameters Asynchronous Syncrhonous Full Synchronous Logical Replication
wal_level lớn hơn minimal lớn hơn minimal lớn hơn minimal

logical

synchronous_standby_names '' 'tên Standby hoặc *' 'tên Standby hoặc *'  
synchronous_commit    

remote_apply

 
max_wal_senders số lượng Standby số lượng Standby số lượng Standby số lượng Standby
hot_standby on nếu muốn tham chiếu Standby on nếu muốn tham chiếu Standby on nếu muốn tham chiếu Standby on nếu muốn tham chiếu Standby

Ngoài ra nếu bạn muốn archive WAL (lưu lại WAL phục vụ cho mục đích backup), bạn cần archive_mode=on và archive_command='comand để lưu WAL mỗi khi update xong 1 file WAL'

Cấu hình

Rất đơn giản để tạo 1 Standby Server trên PostgreSQL. Bạn dùng câu lệnh pg_basebackup để tạo một basebackup chỉnh sửa tham số nếu cần thiết và khởi động là xong.


Bocap-no-MacBook-Pro:~ bocap$ env | grep PG
PGPORT=9100
PGUSER=postgres
PGPASSWORD=postgres
PGDATABASE=postgres
PGDATA=/usr/local/pgsql/pg1000/data


Bocap-no-MacBook-Pro:~ bocap$ psql
psql (10beta1)
Type "help" for help.

postgres=# show synchronous_standby_names;
 synchronous_standby_names 
---------------------------
 
(1 row)

postgres=# \q

Không quên setting authentication cho kết nối replication. Ở đây mình đặt trust(không yêu cầu password) cho kết nối nội bộ.


Bocap-no-MacBook-Pro:~ bocap$ grep "replication     all" $PGDATA/pg_hba.conf
local   replication     all                                     trust
host    replication     all             127.0.0.1/32            trust
host    replication     all             ::1/128                 trust

Kiểm tra trạng thái replication tại Master Server(chưa có kết nối nào).


Bocap-no-MacBook-Pro:~ bocap$ psql
psql (10beta1)
Type "help" for help.

postgres=# \x
Expanded display is on.
postgres=# select * from pg_stat_replication;
(0 rows)

postgres=# \q

Thực hiện sao chép dữ liệu cho Standby Server. Và khởi động Standby Server. 11111 là port cho Standby


dang-no-MacBoook-Pro:~ bocap$ pg_basebackup -R -D ${PGDATA}.standby
Bocap-no-MacBook-Pro:~ bocap$ echo port=11111 >> ${PGDATA}.standby/postgresql.conf
Bocap-no-MacBook-Pro:~ bocap$ pg_ctl start -D ${PGDATA}.standby
waiting for server to start....2017-07-16 03:01:28.912 JST [79722] LOG:  listening on IPv6 address "::1", port 11111
2017-07-16 03:01:28.912 JST [79722] LOG:  listening on IPv6 address "fe80::1%lo0", port 11111
2017-07-16 03:01:28.912 JST [79722] LOG:  listening on IPv4 address "127.0.0.1", port 11111
2017-07-16 03:01:28.921 JST [79722] LOG:  listening on Unix socket "/tmp/.s.PGSQL.11111"
2017-07-16 03:01:28.941 JST [79723] LOG:  database system was interrupted; last known up at 2017-07-16 03:00:38 JST
2017-07-16 03:01:29.126 JST [79723] LOG:  entering standby mode
2017-07-16 03:01:29.134 JST [79723] LOG:  redo starts at 0/2000028
2017-07-16 03:01:29.135 JST [79723] LOG:  consistent recovery state reached at 0/20000F8
2017-07-16 03:01:29.135 JST [79722] LOG:  database system is ready to accept read only connections
2017-07-16 03:01:29.160 JST [79727] LOG:  started streaming WAL from primary at 0/3000000 on timeline 1
 done
server started

Kiểm tra tình trạng Replication hiện tại (async: chưa đồng bộ)


Bocap-no-MacBook-Pro:~ bocap$ psql
psql (10beta1)
Type "help" for help.

postgres=# \x
Expanded display is on.
postgres=# select * from pg_stat_replication ;
-[ RECORD 1 ]----+------------------------------
pid              | 79728
usesysid         | 16385
usename          | postgres
application_name | walreceiver
client_addr      | 
client_hostname  | 
client_port      | -1
backend_start    | 2017-07-16 03:01:29.158203+09
backend_xmin     | 
state            | streaming
sent_lsn         | 0/3000060
write_lsn        | 0/3000060
flush_lsn        | 0/3000060
replay_lsn       | 0/3000060
write_lag        | 
flush_lag        | 
replay_lag       | 
sync_priority    | 0
sync_state       | async

postgres=# create table test_synchronous(id integer);
CREATE TABLE
postgres=# insert into test_synchronous values (1);
INSERT 0 1
postgres=# select * from test_synchronous ;
 id 
----
  1
(1 row)

postgres=# \q
Bocap-no-MacBook-Pro:~ bocap$ psql -p 11111
psql (10beta1)
Type "help" for help.

postgres=# select * from test_synchronous ;
 id 
----
  1
(1 row)

postgres=# \q

Chuyển qua chế độ tiền đồng bộ và kiểm tra tình trạng Replication


Bocap-no-MacBook-Pro:~ bocap$ echo synchronous_standby_names='walreceiver' >> $PGDATA/postgresql.conf
Bocap-no-MacBook-Pro:~ bocap$ pg_ctl reload
server signaled
2017-07-16 03:04:48.747 JST [69073] LOG:  received SIGHUP, reloading configuration files
Bocap-no-MacBook-Pro:~ bocap$ 2017-07-16 03:04:48.755 JST [69073] LOG:  parameter "synchronous_standby_names" changed to "walreceiver"

Bocap-no-MacBook-Pro:~ bocap$ 2017-07-16 03:04:50.068 JST [79728] LOG:  standby "walreceiver" is now a synchronous standby with priority 1


Bocap-no-MacBook-Pro:~ bocap$ psql
psql (10beta1)
Type "help" for help.

postgres=# \x
Expanded display is on.
postgres=# show synchronous_standby_names;
-[ RECORD 1 ]-------------+------------
synchronous_standby_names | walreceiver

postgres=# select * from pg_stat_replication ;
-[ RECORD 1 ]----+------------------------------
pid              | 79728
usesysid         | 16385
usename          | postgres
application_name | walreceiver
client_addr      | 
client_hostname  | 
client_port      | -1
backend_start    | 2017-07-16 03:01:29.158203+09
backend_xmin     | 
state            | streaming
sent_lsn         | 0/3019058
write_lsn        | 0/3019058
flush_lsn        | 0/3019058
replay_lsn       | 0/3019058
write_lag        | 
flush_lag        | 
replay_lag       | 
sync_priority    | 1
sync_state       | sync

postgres=# \q

Chuyển qua chế độ Full Replication


Bocap-no-MacBook-Pro:~ bocap$ psql
psql (10beta1)
Type "help" for help.

postgres=# show synchronous_commit;
 synchronous_commit 
--------------------
 on
(1 row)

postgres=# \q


Bocap-no-MacBook-Pro:~ bocap$ echo synchronous_commit='remote_apply' >> $PGDATA/postgresql.conf
Bocap-no-MacBook-Pro:~ bocap$ pg_ctl reload
server signaled
2017-07-16 03:23:54.258 JST [69073] LOG:  received SIGHUP, reloading configuration files
Bocap-no-MacBook-Pro:~ bocap$ 2017-07-16 03:23:54.261 JST [69073] LOG:  parameter "synchronous_commit" changed to "remote_apply"


Bocap-no-MacBook-Pro:~ bocap$ psql
psql (10beta1)
Type "help" for help.

postgres=# \x
Expanded display is on.
postgres=# select * from pg_stat_replication ;
-[ RECORD 1 ]----+------------------------------
pid              | 79728
usesysid         | 16385
usename          | postgres
application_name | walreceiver
client_addr      | 
client_hostname  | 
client_port      | -1
backend_start    | 2017-07-16 03:01:29.158203+09
backend_xmin     | 
state            | streaming
sent_lsn         | 0/3019138
write_lsn        | 0/3019138
flush_lsn        | 0/3019138
replay_lsn       | 0/3019138
write_lag        | 
flush_lag        | 
replay_lag       | 
sync_priority    | 1
sync_state       | sync

postgres=# show synchronous_commit;
-[ RECORD 1 ]------+-------------
synchronous_commit | remote_apply

postgres=# \q
Bocap-no-MacBook-Pro:~ bocap$ 


Logical Replication

Về cơ bản để sử dụng chức năng Logical Replication. Chúng ta tạo Publication bằng lệnh CREATE PUBLICATION phía Master Server. Phía Server còn lại (phía nhận WAL không phải là Standby như trên mà là một DB Server có thể ghi dữ liệu bình thường) tạo Subscription bằng lệnh CREATE SUBSCRIPTION như ví dụ bên dưới. Chi tiết về chức năng này sẽ được viết ở bài viết khác, khi PostgreSQL 10 đã được hoàn thành.


Bocap-no-MacBook-Pro:~ bocap$ echo wal_level='logical' >> $PGDATA/postgresql.conf
Bocap-no-MacBook-Pro:~ bocap$ pg_ctl restart
waiting for server to shut down...2017-07-16 03:51:02.705 JST [80462] LOG:  received fast shutdown request
.2017-07-16 03:51:02.705 JST [80462] LOG:  aborting any active transactions
2017-07-16 03:51:02.708 JST [80464] LOG:  shutting down
2017-07-16 03:51:02.750 JST [80462] LOG:  database system is shut down
 done
server stopped
waiting for server to start....2017-07-16 03:51:03.739 JST [80476] LOG:  listening on IPv6 address "::1", port 9100
2017-07-16 03:51:03.739 JST [80476] LOG:  listening on IPv6 address "fe80::1%lo0", port 9100
2017-07-16 03:51:03.739 JST [80476] LOG:  listening on IPv4 address "127.0.0.1", port 9100
2017-07-16 03:51:03.754 JST [80476] LOG:  listening on Unix socket "/tmp/.s.PGSQL.9100"
2017-07-16 03:51:03.787 JST [80477] LOG:  database system was shut down at 2017-07-16 03:51:02 JST
2017-07-16 03:51:03.791 JST [80476] LOG:  database system is ready to accept connections
 done
server started
Bocap-no-MacBook-Pro:~ bocap$
Bocap-no-MacBook-Pro:~ bocap$ psql -c "CREATE TABLE test_logical_rep(id integer)"
CREATE TABLE
Bocap-no-MacBook-Pro:~ bocap$ psql -c "CREATE PUBLICATION pub_test FOR TABLE test_logical_rep"
CREATE PUBLICATION
Bocap-no-MacBook-Pro:~ bocap$ psql -p 5432 -c "CREATE TABLE test_logical_rep(id integer)" 
CREATE TABLE
Bocap-no-MacBook-Pro:~ bocap$ psql -p 5432 -c "CREATE SUBSCRIPTION sub_test CONNECTION 'dbname=postgres port=9100 user=postgres' PUBLICATION pub_test"
NOTICE:  synchronized table states
2017-07-16 03:58:54.172 JST [80532] LOG:  logical decoding found consistent point at 0/3033BB0
2017-07-16 03:58:54.172 JST [80532] DETAIL:  There are no running transactions.
NOTICE:  created replication slot "sub_test" on publisher
CREATE SUBSCRIPTION
Bocap-no-MacBook-Pro:~ bocap$ 2017-07-16 03:58:54.190 JST [80533] LOG:  logical replication apply worker for subscription "sub_test" has started
2017-07-16 03:58:54.196 JST [80534] LOG:  starting logical decoding for slot "sub_test"
2017-07-16 03:58:54.196 JST [80534] DETAIL:  streaming transactions committing after 0/3033BE8, reading WAL from 0/3033BB0
2017-07-16 03:58:54.196 JST [80534] LOG:  logical decoding found consistent point at 0/3033BB0
2017-07-16 03:58:54.196 JST [80534] DETAIL:  There are no running transactions.
2017-07-16 03:58:54.198 JST [80535] LOG:  logical replication table synchronization worker for subscription "sub_test", table "test_logical_rep" has started
2017-07-16 03:58:54.207 JST [80536] LOG:  logical decoding found consistent point at 0/3033BE8
2017-07-16 03:58:54.207 JST [80536] DETAIL:  There are no running transactions.
2017-07-16 03:58:55.197 JST [80535] LOG:  logical replication table synchronization worker for subscription "sub_test", table "test_logical_rep" has finished

Bocap-no-MacBook-Pro:~ bocap$ psql -c "INSERT INTO test_logical_rep VALUES(11111);"
INSERT 0 1
Bocap-no-MacBook-Pro:~ bocap$ psql -p 5432 -c "select * from test_logical_rep"
  id   
-------
 11111
(1 row)

Bocap-no-MacBook-Pro:~ bocap$ 

Xin vui lòng đặt câu hỏi hoặc thảo luận bằng comments box bên dưới.

CHECKPOINT

Cơ chế lưu dữ liệu trên PostgreSQL

PostgreSQL cũng như một số RDBMS khác. Khi bạn chạy một câu lệnh cập nhật dữ liệu (UPDATE/INSERT/DELETE), dữ liệu vật lý trên đĩa cứng chưa thay đổi mà chỉ thay đổi trên bộ đệm (bộ nhớ dùng chung: PostgreSQL = shared_buffers). Khi bạn tham chiếu dữ liệu (SELECT), trước hết PostgreSQL xem dữ liệu tồn tại trên bộ đệm không, nếu tồn tại dữ liệu sẽ trả về người dùng. Nếu dữ liệu không tồn tại trên bộ đệm, PostgreSQL sẽ truy cập xuống vùng vật lý (ổ đĩa cứng) để lấy dữ liệu, sau đó trước khi trả về cho người dùng dữ liệu đó sẽ được đưa lên bộ đệm.
Cơ chế nêu trên làm tăng tốc độ xử lý nhờ vào việc giảm thiểu I/O trên đĩa cứng.

Độ lớn bộ đệm?

Độ lớn vùng nhớ đệm của PostgreSQL được chỉ định qua parameter shared_buffers (giá trị mặc định của parameter này tuỳ thuộc vào phiên bản PostgreSQL và bộ nhớ hệ thống).

Xem qua ở trên bạn chắc sẽ băn khoăn nếu dữ liệu vừa cập nhật trên bộ đệm, nếu máy tính bị tắt nguồn hoặc OS panic, thì dữ liệu này sẽ bị mất? Bạn yên tâm vì PostgreSQL cũng như các RDBMS khác PostgreSQL có cơ chế roll forward (phục hồi dữ liệu từ transaction log: WAL). Bạn có thể xem qua hình vẽ bên dưới để hiểu thêm.

CHECKPOINT

Khi buffer bị đầy PostgreSQL sẽ ghi những dirty buffers xuống đĩa để chỗ trống cho dữ liệu mới, quá trình này diễn ra liên tục làm tăng cách thao tác thừa sẽ ảnh hưởng tới người dùng. Vì vậy PostgreSQL cần có chức năng CHECKPOINT. CHECKPOINT là cơ chế đồng bộ dữ liệu cập nhật (đã commit) từ bộ nhớ đệm xuống dưới đĩa cứng.

Bạn có thể hình dung đơn giản chức năng CHECKPOINT thực hiện thông qua cơ chế ghi dữ liệu của PostgreSQL như bên dưới.

Cơ chế ghi dữ liệu của PostgreSQL

PostgreSQL thực hiện tự động xử lý checkpoint thông qua process checkpointer (phiên bản trước 9.2 thông qua background process). 


[postgres@ip-172-31-31-242 ~]$ pg_ctl status
pg_ctl: server is running (PID: 17397)
/usr/pgsql-9.6/bin/postgres
[postgres@ip-172-31-31-242 ~]$ ps -ef | grep 17397
postgres 14946 14348  0 13:11 pts/2    00:00:00 grep --color=auto 17397
postgres 17397     1  0 Apr11 pts/3    00:04:48 /usr/pgsql-9.6/bin/postgres
postgres 17398 17397  0 Apr11 ?        00:00:08 postgres: logger process   
postgres 17400 17397  0 Apr11 ?        00:00:10 **postgres: checkpointer process**  
postgres 17401 17397  0 Apr11 ?        00:01:08 postgres: writer process   
postgres 17402 17397  0 Apr11 ?        00:01:12 postgres: wal writer process  
postgres 17403 17397  0 Apr11 ?        00:04:31 postgres: autovacuum launcher process  
postgres 17404 17397  0 Apr11 ?        00:08:14 postgres: stats collector process  
[postgres@ip-172-31-31-242 ~]$   

CHECKPOINT diễn ra khi nào

Thông thường trong vận hành CHECKPOINT xảy ra khi có các điều kiện sau.

  • Khi thời gian từ lần CHECKPOINT trước vượt quá tham số checkpoint_timeout Mặc định parameter này là 5 phút. Như vậy chắc chắn trong vòng 5 phút sẽ có 1 CHECKPOINT xảy ra. Lưu ý: CHECKPOINT xử lý theo cơ chế này, để giảm thiểu disk I/O PostgreSQL làm thao tác này chậm hơn các cơ chế CHECKPOINT khác (sự trì hoãn này phụ thuộc vào giá trị của parameter checkpoint_completion_target).

    Khi CHECKPOINT theo cơ chế này xảy ra, PostgreSQL log sẽ có messages như bên dưới(lưu ý set log_checkpoints = on để xuất log khi có CHECKPOINT xảy ra)

    
    [2017-07-08 12:57:05.993 EDT ] LOG: checkpoint starting: time
    [2017-07-08 12:57:12.020 EDT ] LOG: checkpoint complete: wrote 64 buffers (0.4%); 0 transaction log file(s) added, 0 removed, 0 recycled; write=6.017 s, sync=0.002 s, total=6.026 s; sync files=17, longest=0.001 s, average=0.000 s; distance=730 kB, estimate=970 kB
    
    
  • Khi lượng dữ liệu transaction log (WAL) lớn hơn max_wal_size (phiên bản trước 9.5 là tham số checkpoint_segments) Khi dung lượng của WAL (transaction log, được lưu trữ trong <thư mục database>/pg_xlog (PostgreSQL 10 -> pg_wal)) vượt quá max_wal_size, CHECKPOINT sẽ tự động diễn ra.

    lưu ý: tương quan giữa max_wal_size và checkpoint_segments bạn có thể hiểu là (max_wal_size = checkpoint_segments*3 + 1)

    CHECKPOINT theo cơ chế này xảy ra sẽ có messages như bên dưới trong PostgreSQL's log.

    
    [2017-07-08 13:02:42.620 EDT ] LOG:  checkpoint starting: xlog
    [2017-07-08 13:02:43.921 EDT ] LOG:  checkpoint complete: wrote 2312 buffers (14.1%); 0 transaction log file(s) added, 1 removed, 1 recycled; write=1.011 s, sync=0.139 s, total=1.311 s; sync files=2, longest=0.139 s, average=0.069 s; distance=32759 kB, estimate=34561 kB
    
    
  • Ngoài ra CHECKPOINT còn xảy ra trong các trường hợp sau

  1. Chạy câu lệnh CHECKPOINT từ người dùng (quyền super user)
  2. Khi Shutdown server PostgreSQL
  3. Khi khởi động PostgreSQL trong chế độ recovery (roll forward)
  4. Khi tạo dữ liệu backup từ câu lệnh pg_basebackup

Tinh chỉnh CHECKPOINT sao cho hợp lý để hệ thống chạy tốt cũng là một việc quan trọng. Nếu tăng thời gian tự động CHECKPOINT, thì dữ liệu WAL sẽ nhiều, crash recovery, và CHECKPOINT sẽ mất nhiều thời gian ảnh hưởng tới người dùng. Nếu giảm thời gian này đi thì số lượng CHECKPOINT sẽ tăng lên, làm disk I/O tăng ảnh hưởng tới người dùng. Lưu ý là sau mỗi lần CHECKPOINT, lần cập nhật dữ liệu đầu tiên sẽ lưu cả block dữ liệu (full-page writes) lên WAL điều này làm ảnh hưởng tới disk I/O đáng kể. Vì vậy bạn nên thao khảo sát work-load của người dùng để quyết định tinh chỉnh như thế nào cho PostgreSQL chạy hiệu quả nhé.

Xin vui lòng đặt câu hỏi hoặc thảo luận bằng comments box bên dưới.

Trang

Đăng kí nhận RSS - Chức năng phía Server