Hỏi về lỗi phân quyền khi chạy lệnh của PostgreSQL và cách khắc phục

Update: mình đã gửi solution, nhưng nguyên dân gốc rễ mọi người đọc thêm của 2 bác dưới nhé, cực chi tiết và dễ hiểu.

Chào cả nhà,
Mình đang làm phần backup database bằng pg_dump cho website của mình. Code test chạy thì cũng ổn rồi mà giờ lên docker image thì mình đang gặp vấn đề chưa biết cách xử lý. Cụ thể, mình chọn Debian 10 làm base image, add user flask để chạy ứng dụng.
Lúc này trong image đó mình test khi mình chạy các lệnh postgresql với user root, nó chạy ổn. Nhưng khi qua user flask (user này start app), nó báo lỗi như này:

[email protected]:/portal$ pg_dump postgresql://postgres:@localhost:5432/postgres -Fc -f ./backup_file_test -v
Error: Invalid data directory for cluster 12 main

Thử lại với user root, nó chạy oke

[email protected]:/portal# pg_dump postgresql://postgres:@localhost:5432/postgres -Fc -f ./backup_file_test -v
pg_dump: last built-in OID is 16383
pg_dump: reading extensions
pg_dump: identifying extension members
pg_dump: reading schemas
pg_dump: reading user-defined tables
pg_dump: reading user-defined functions
pg_dump: reading user-defined types
pg_dump: reading procedural languages
pg_dump: reading user-defined aggregate functions
pg_dump: reading user-defined operators
pg_dump: reading user-defined access methods
pg_dump: reading user-defined operator classes
pg_dump: reading user-defined operator families
pg_dump: reading user-defined text search parsers
pg_dump: reading user-defined text search templates
pg_dump: reading user-defined text search dictionaries
pg_dump: reading user-defined text search configurations
pg_dump: reading user-defined foreign-data wrappers
pg_dump: reading user-defined foreign servers
pg_dump: reading default privileges
pg_dump: reading user-defined collations
pg_dump: reading user-defined conversions
pg_dump: reading type casts
pg_dump: reading transforms
pg_dump: reading table inheritance information
pg_dump: reading event triggers
pg_dump: finding extension tables
pg_dump: finding inheritance relationships
pg_dump: reading column info for interesting tables
pg_dump: finding the columns and types of table "abc"

----
Quá trình dump okie
----

Cầm cái lỗi Error: Invalid data directory for cluster 12 main đi kiếm trên google, đa số thì bảo là do mình cấu hình cái database sai, nhưng mình thấy user root chạy được nên nghĩ không phải.
Có vẻ như là thiếu quyền hoặc gì đó. Đây là lần đầu mình gặp vấn đề này nên cũng lơ mơ chưa tìm được cách khắc phục nên lên đây hỏi mọi người tìm cách khắc phục. Thiếu thông tin gì mọi người cứ nói nhé mình sẽ cung cấp thêm.
Chân thành cảm ơn cả nhà

Mình loanh quanh tìm hiểu thì hiện tại có cách mình có thể cho code chạy được, nhưng không hiểu bản chất vấn đề của mình là ở đâu, mình chia sẻ lại để ai gặp trường hợp như này có thể fix như mình.

Đơn giản là thay vì kết nối Unix socket thì chuyển qua TCPIP như sau:

// Thêm -h localhost vào trong câu lệnh

pg_dump -h localhost postgresql://postgres:@localhost:5432/postgres -Fc -f ./backup_file -v

// Set biến global để không phải thêm param -h localhost vào câu lệnh
export PGHOST=localhost 

Có vẻ như ở tài khoản flask, nó không kết nối được socket thì phải, mình dùng netstat check thì thấy đang running

[email protected]:/portal$ netstat -nlp | grep 5432
(Not all processes could be identified, non-owned process info
 will not be shown, you would have to be root to see it all.)
tcp        0      0 0.0.0.0:5432            0.0.0.0:*               LISTEN      -                   
tcp6       0      0 :::5432                 :::*                    LISTEN      -                   
unix  2      [ ACC ]     STREAM     LISTENING     453422131 -                    /var/run/postgresql/.s.PGSQL.5432

ở câu lệnh trên, mình thấy đường dẫn file là /var/run/postgresql/.s.PGSQL.5432 nên mình thử lệnh

[email protected]:/portal$ psql -U postgres -h /var/run/postgresql/
psql (12.10 (Debian 12.10-1.pgdg110+1))
Type "help" for help.

postgres=# 

Ừa, nó chạy rồi á, nhưng chẳng hiểu mute gì cả, mò mò mò thôi à. Lúc này như cái trên, mình lưu thành biến để không phải truyền lại mỗi lần chạy lệnh

// Set biến global để không phải thêm param -h localhost vào câu lệnh
export PGHOST=" /var/run/postgresql/" 

Mình không giỏi cái này, tìm hiểu hoài cũng chưa ra. Ai biết xin hãy chia sẻ lại nhé.
Cảm ơn cả nhà.

P/s: xin các mod đừng close topic. Em muốn biết được vấn đề gốc để hiểu hơn, biết cách sửa này đúng sai hay đại loại vậy. Cảm ơn các mod.

Khi bạn còn vấn đề thắc mắc thì không có lý gì mà mod lại đóng topic của bạn cả. (btw Trust Level 4 member đều có thể close topic, không chỉ có mod)

Mình thử search host /var/run/postgresql thì thấy có lý do này:

The convention for PostgreSQL packaged for Debian or Debian derivatives such as Ubuntu is to use /var/run/postgresql as the directory for Unix domain sockets. On the other hand the convention for self-compiled postgres client libs is to use /tmp, unless self-configured otherwise.

Thế là bạn đã kết nối thành công với Unix socket rồi đó :stuck_out_tongue:

1 Like

Hay thiệt, cảm ơn bác. Cho mình hỏi ngáo thêm là kết nối TCP/IP với UNix socket này thằng nào sẽ đem lại hiệu quả tốt hơn nhỉ? Mình đoán là socket nhưng vẫn muốn hiểu hơn nguyên nhân thực sự.
Chân thành cảm ơn bác

Socket phải hiệu quả hơn TCP/IP nhưng nó có nhược điểm là phải chạy chung trên cùng server nên chỉ có thể áp dụng vertical scaling mà không thể horizontal scaling. Nói cách khác, viết phần mềm thì server phần mềm và server cơ sở dữ liệu mà nằm cùng nhau thì dùng socket sẽ hiệu quả hơn dùng TCP, và vẫn dùng TCP nếu thích ít hiệu quả hơn một chút. Còn khi phần mềm (code) và cơ sở dữ liệu không cùng server, ta chỉ có thể dùng TCP.

Lý do Unix socket nhanh hơn TCP socket bởi vì: Unix socket được nhân *nix hỗ trợ, còn TCP thì sử dụng thông qua giao diện của Network, mà Network thì ta biết rồi, có mô hình ảo là 7 lớp. Suy luận kiểu trẻ em: chạy kiểu gì 7 tầng nhanh hơn hai bên chung vách mà vách lại vô hình? là đã thấy đáp án.

2 Likes

Ra vậy, chân thành cảm ơn bác rất nhiều.

83% thành viên diễn đàn không hỏi bài tập, còn bạn thì sao?