Cách giải quyết các vấn đề về đặc quyền khi khôi phục Cơ sở dữ liệu PostgreSQL


104

Tôi đã hủy một bản sao lưu sạch, không có chủ sở hữu cho Cơ sở dữ liệu Postgres bằng lệnh

pg_dump sample_database -O -c -U

Sau đó, khi tôi khôi phục cơ sở dữ liệu với

psql -d sample_database -U app_name

Tuy nhiên, tôi đã gặp một số lỗi khiến tôi không thể khôi phục dữ liệu:

ERROR:  must be owner of extension plpgsql
ERROR:  must be owner of schema public
ERROR:  schema "public" already exists
ERROR:  must be owner of schema public
CREATE EXTENSION
ERROR:  must be owner of extension plpgsql

Tôi đã tìm hiểu sâu vào SQL pg_dumptạo văn bản thuần túy và tôi thấy nó chứa SQL

CREATE SCHEMA public;
COMMENT ON SCHEMA public IS 'standard public schema';
CREATE EXTENSION IF NOT EXISTS plpgsql WITH SCHEMA pg_catalog;
COMMENT ON EXTENSION plpgsql IS 'PL/pgSQL procedural language';

Tôi nghĩ rằng nguyên nhân là do người dùng app_namekhông có đặc quyền để thay đổi publiclược đồ và plpgsql.

Làm thế nào tôi có thể giải quyết vấn đề này?


5
Nếu bạn không cần plpgsql, sau đó DROP EXTENSION plpgsqltrước khi bạn pg_dump. Điều này an toàn hơn việc biến ứng dụng của bạn trở thành siêu người dùng và thuận tiện hơn là bỏ qua các lỗi (nếu bạn sử dụng --single-transactionhoặc -v ON_ERROR_STOP=1). Đây là một vấn đề đã biết, [đã được các nhà phát triển Postgres thảo luận nhiều lần | postgresql.org/message-id/… nhưng không cố định kể từ ngày 9.3.
Mark E. Haase

Câu trả lời:


63

Để giải quyết vấn đề, bạn phải chỉ định các quyền sở hữu thích hợp. Hãy thử cách dưới đây sẽ giải quyết tất cả các vấn đề liên quan đến quyền cho người dùng cụ thể nhưng như đã nêu trong nhận xét, điều này không nên được sử dụng trong sản xuất:

root@server:/var/log/postgresql# sudo -u postgres psql
psql (8.4.4)
Type "help" for help.

postgres=# \du
               List of roles
    Role name    | Attributes  | Member of
-----------------+-------------+-----------
 <user-name>    | Superuser   | {}
                 : Create DB
 postgres       | Superuser   | {}
                 : Create role
                 : Create DB

postgres=# alter role <user-name> superuser;
ALTER ROLE
postgres=#

Vì vậy, kết nối với cơ sở dữ liệu dưới tài khoản Superuser sudo -u postgres psqlvà thực hiện một ALTER ROLE <user-name> Superuser;câu lệnh.

Hãy nhớ rằng đây không phải là giải pháp tốt nhất trên máy chủ lưu trữ nhiều trang web, vì vậy hãy xem xét việc chỉ định các vai trò riêng lẻ thay vào đó: https://www.postgresql.org/docs/current/static/sql-set-role.htmlhttps : //www.postgresql.org/docs/current/static/sql-alterrole.html .


28
có cách nào để làm điều này mà không cần trở thành siêu người dùng không?
Travis Webb

17
"phải chỉ định quyền sở hữu thích hợp" và "thay đổi vai trò <người dùng-name> siêu người dùng" không phải là đồng dư. Quyền sở hữu thích hợp có nghĩa là app_userkhông một người dùng siêu.
Mark E. Haase

@mehaase vui lòng cập nhật từ ngữ của câu trả lời thay vì bỏ phiếu từ chối.
Daniel Sokolowski

5
IMHO đây không phải là giải pháp mà là cách giải quyết nên tránh trong quá trình sản xuất.
Dmytriy Voloshyn

6
Đây là một gợi ý xấu để làm cho một người sử dụng bình thườngsuperuser
Evren Yurtesen

55

Người dùng AWS RDS nếu bạn nhận được điều này là do bạn không phải là siêu người dùng và theo tài liệu aws, bạn không thể là một. Tôi đã tìm thấy tôi phải bỏ qua những lỗi này.


5
Lỗi này ngăn không cho tôi hoàn tất quá trình khôi phục (AWS RDS pg_restore). Bất kỳ mẹo nào để bỏ qua những lỗi này?
avjaarsveld

PS Tôi đã không sử dụng -e hoặc --exit-on-error cho pg_restore
avjaarsveld

6
Tôi thấy rằng, trên RDS, vấn đề là COMMENT ON EXTENSION, không phải CREATE EXTENSION. Xóa các bình luận và bạn sẽ ổn.
pkoch

@pkoch tương tự với Google Cloud Storage. BÌNH LUẬN VỀ MỞ RỘNG là vấn đề và không cần thiết
Jaybeecave

25

Đối với những người sử dụng Google Cloud Platform, bất kỳ lỗi nào cũng sẽ dừng quá trình nhập. Cá nhân tôi gặp phải hai lỗi khác nhau tùy thuộc vào lệnh pg_dump mà tôi đã phát hành:

1- The input is a PostgreSQL custom-format dump. Use the pg_restore command-line client to restore this dump to a database.

Xảy ra khi bạn cố kết xuất DB của mình ở định dạng văn bản không thuần túy. Tức là khi lệnh thiếu tham số -Fp hoặc --format = trơn. Tuy nhiên, nếu bạn thêm nó vào lệnh của mình, bạn có thể gặp phải lỗi sau:

2- SET SET SET SET SET SET CREATE EXTENSION ERROR: must be owner of extension plpgsql

Đây là vấn đề về quyền mà tôi không thể khắc phục bằng cách sử dụng lệnh được cung cấp trong tài liệu GCP , các mẹo từ chuỗi hiện tại này hoặc làm theo lời khuyên từ nhóm Google Postgres tại đây . Bạn nên phát hành lệnh sau:

pg_dump -Fp --no-acl --no-owner -U myusername myDBName > mydump.sql

Điều duy nhất đã làm được mẹo trong trường hợp của tôi là chỉnh sửa thủ công tệp kết xuất và nhận xét tất cả các lệnh liên quan đến plpgsql.

Tôi hy vọng điều này sẽ giúp ích cho những người phụ thuộc vào GCP.

Cập nhật:

Việc kết xuất tệp nhận xét ra các phần mở rộng sẽ dễ dàng hơn, đặc biệt là vì một số kết xuất có thể rất lớn: pg_dump ... | grep -v -E '(CREATE\ EXTENSION|COMMENT\ ON)' > mydump.sql

Có thể thu hẹp lại thành plpgsql: pg_dump ... | grep -v -E '(CREATE\ EXTENSION\ IF\ NOT\ EXISTS\ plpgsql|COMMENT\ ON\ EXTENSION\ plpgsql)' > mydump.sql


1
GCP hiện có pg_dumplệnh chính xác để sử dụng trong tài liệu của họ :pg_dump -U [USERNAME] --format=plain --no-owner --no-acl [DATABASE_NAME] \ | sed -E 's/(DROP|CREATE|COMMENT ON) EXTENSION/-- \1 EXTENSION/g' > [SQL_FILE].sql
Rush

14

Bạn có thể an toàn bỏ qua các thông báo lỗi trong trường hợp này. Không thêm nhận xét vào lược đồ công khai và cài đặt plpgsql (đã được cài đặt sẵn) sẽ không gây ra bất kỳ vấn đề thực sự nào.

Tuy nhiên, nếu bạn muốn cài đặt lại hoàn chỉnh, bạn sẽ cần người dùng có quyền thích hợp. Tất nhiên, đó không phải là người dùng mà ứng dụng của bạn chạy thường xuyên.


12

Câu trả lời ngắn gọn hơn: bỏ qua nó.

Mô-đun này là một phần của Postgres xử lý ngôn ngữ SQL. Lỗi thường sẽ xuất hiện khi sao chép cơ sở dữ liệu từ xa, chẳng hạn như với 'heroku pg: pull'. Nó không ghi đè bộ xử lý SQL của bạn và cảnh báo bạn về điều đó.


9

Hãy thử sử dụng -Lcờ với pg_restore bằng cách chỉ định tệp được lấy từpg_dump -Fc

-L list-file --use-list = list-file

Chỉ khôi phục các phần tử lưu trữ được liệt kê trong tệp danh sách và khôi phục chúng theo thứ tự xuất hiện trong tệp. Lưu ý rằng nếu các công tắc lọc như -n hoặc -t được sử dụng với -L, chúng sẽ hạn chế thêm các mục được khôi phục.

list-file thường được tạo bằng cách chỉnh sửa đầu ra của một hoạt động -l trước đó. Các dòng có thể được di chuyển hoặc loại bỏ, và cũng có thể được nhận xét bằng cách đặt dấu chấm phẩy (;) ở đầu dòng. Xem bên dưới để biết các ví dụ.

https://www.postgresql.org/docs/9.5/app-pgrestore.html

pg_dump -Fc -f pg.dump db_name
pg_restore -l pg.dump | grep -v 'COMMENT - EXTENSION' > pg_restore.list
pg_restore -L pg_restore.list pg.dump

Ở đây bạn có thể thấy Điều ngược lại là đúng bằng cách chỉ xuất ra nhận xét:

pg_dump -Fc -f pg.dump db_name
pg_restore -l pg.dump | grep 'COMMENT - EXTENSION' > pg_restore_inverse.list
pg_restore -L pg_restore_inverse.list pg.dump
--
-- PostgreSQL database dump
--

-- Dumped from database version 9.4.15
-- Dumped by pg_dump version 9.5.14

SET statement_timeout = 0;
SET lock_timeout = 0;
SET client_encoding = 'UTF8';
SET standard_conforming_strings = on;
SELECT pg_catalog.set_config('search_path', '', false);
SET check_function_bodies = false;
SET client_min_messages = warning;
SET row_security = off;

--
-- Name: EXTENSION plpgsql; Type: COMMENT; Schema: -; Owner: 
--

COMMENT ON EXTENSION plpgsql IS 'PL/pgSQL procedural language';


--
-- PostgreSQL database dump complete
--

Tôi nghĩ điều trên là đúng, việc loại trừ nhận xét cho các plugin sẽ không ảnh hưởng đến chức năng của ứng dụng của bạn
Andreas

3

Đối với những người sử dụng AWS , COMMENT ON EXTENSIONchỉ có thể là superuser và như chúng tôi đã biết theo tài liệu, các phiên bản RDS do Amazon quản lý. Do đó, để ngăn bạn vi phạm những thứ như sao chép, người dùng của bạn - ngay cả người dùng gốc mà bạn đã thiết lập khi tạo phiên bản - sẽ không có đầy đủ các đặc quyền của người dùng siêu cấp:

http://docs.aws.amazon.com/AmazonRDS/latest/UserGuide/Appnex.PostgreSQL.CommonDBATasks.html

Khi bạn tạo một phiên bản DB, tài khoản hệ thống người dùng chính mà bạn tạo sẽ được gán cho vai trò rds_superuser. Vai trò rds_superuser là một vai trò Amazon RDS được xác định trước tương tự như vai trò siêu người dùng PostgreSQL (thường được đặt tên là postgres trong các phiên bản cục bộ), nhưng có một số hạn chế. Như với vai trò siêu người dùng PostgreSQL, vai trò rds_superuser có nhiều đặc quyền nhất trên cá thể DB của bạn và bạn không nên gán vai trò này cho người dùng trừ khi họ cần quyền truy cập nhiều nhất vào cá thể DB.

Để khắc phục lỗi này, chỉ cần sử dụng --để nhận xét các dòng SQL chứaCOMMENT ON EXTENSION


2
Hoặc bỏ qua bình luận khi bán phá giá : pg_dump --no-comments.
Dmitrii I.

2

Sử dụng người dùng postgres (quản trị viên) để kết xuất lược đồ, tạo lại nó và cấp quyền riêng tư để sử dụng trước khi bạn thực hiện khôi phục. Trong một lệnh:

sudo -u postgres psql -c "DROP SCHEMA public CASCADE;
create SCHEMA public;
grant usage on schema public to public;
grant create on schema public to public;" myDBName

1

Đối với tôi, tôi đã thiết lập cơ sở dữ liệu với pgAdmin và có vẻ như việc thiết lập chủ sở hữu trong quá trình tạo cơ sở dữ liệu là không đủ. Tôi phải điều hướng xuống giản đồ 'công khai' và đặt cả chủ sở hữu ở đó (ban đầu là 'postgres').


0

Đối với những người đã thu hẹp vấn đề thành các COMMENT ONtuyên bố (theo các câu trả lời khác nhau bên dưới) và những người có quyền truy cập cấp trên người dùng vào cơ sở dữ liệu nguồn mà từ đó tệp kết xuất được tạo, giải pháp đơn giản nhất có thể là ngăn các nhận xét được đưa vào kết xuất ở vị trí đầu tiên, bằng cách xóa chúng khỏi cơ sở dữ liệu nguồn đang được kết xuất ...

COMMENT ON EXTENSION postgis IS NULL;
COMMENT ON EXTENSION plpgsql IS NULL;
COMMENT ON SCHEMA public IS NULL;

Sau đó, bãi thải trong tương lai sẽ không bao gồm các COMMENT ONbáo cáo.


1
Phát triển cục bộ trong Rails (tự động tạo tệp kết xuất mới bất cứ khi nào chạy một quá trình di chuyển giản đồ), giải pháp này cho phép tôi chỉ cần chạy rails db:resetđối với phiên bản AWS RDS postgresql mà không phải xóa các dòng COMMENT ON khỏi tệp kết xuất mỗi khi tôi chạy một lược đồ sự di cư.
Mark Schneider
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.