Cara mengatasi masalah hak istimewa saat memulihkan Database PostgreSQL

105

Saya telah membuang cadangan pemilik yang bersih dan tidak ada untuk Postgres Database dengan perintah

pg_dump sample_database -O -c -U

Nanti saat saya restore database dengan

psql -d sample_database -U app_name

Namun, saya mengalami beberapa kesalahan yang membuat saya tidak dapat memulihkan data:

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

Saya menggali ke dalam pg_dumpmenghasilkan SQL teks biasa dan saya menemukan itu berisi 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';

Saya pikir penyebabnya adalah pengguna app_nametidak memiliki hak istimewa untuk mengubah publicskema dan plpgsql.

Bagaimana saya bisa mengatasi masalah ini?

steveyang.dll
sumber
5
Jika Anda tidak membutuhkannya plpgsql, maka DROP EXTENSION plpgsqlsebelum Anda pg_dump. Ini lebih aman daripada menjadikan aplikasi Anda pengguna super, dan lebih nyaman daripada mengabaikan kesalahan (yang gagal jika Anda menggunakan --single-transactionatau -v ON_ERROR_STOP=1). Ini adalah masalah yang diketahui, [dibahas panjang lebar oleh para pengembang Postgres | postgresql.org/message-id/… tetapi tidak diperbaiki pada 9.3.
Mark E. Haase

Jawaban:

63

Untuk mengatasi masalah ini, Anda harus menetapkan izin kepemilikan yang sesuai. Coba di bawah ini yang seharusnya menyelesaikan semua masalah terkait izin untuk pengguna tertentu tetapi seperti yang dinyatakan dalam komentar ini tidak boleh digunakan dalam produksi:

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=#

Jadi hubungkan ke database di bawah akun Superuser sudo -u postgres psqldan jalankan ALTER ROLE <user-name> Superuser;pernyataan.

Perlu diingat bahwa ini bukan solusi terbaik di server hosting multi-situs, jadi lihatlah menetapkan peran individu sebagai gantinya: https://www.postgresql.org/docs/current/static/sql-set-role.html dan https : //www.postgresql.org/docs/current/static/sql-alterrole.html .

Daniel Sokolowski
sumber
28
apakah ada cara untuk melakukan ini tanpa menjadi pengguna super?
Travis Webb
17
"harus menetapkan izin kepemilikan yang tepat" dan "mengubah peran <namapengguna> superuser" tidak kongruen. Kepemilikan yang tepat akan berarti bahwa app_useradalah tidak super user.
Mark E. Haase
@mehaase harap perbarui kata-kata jawaban dan bukan voting turun.
Daniel Sokolowski
5
IMHO ini bukanlah solusi tetapi solusi yang harus dihindari dalam produksi.
Dmytriy Voloshyn
6
Ini adalah saran yang buruk untuk membuat pengguna biasasuperuser
Evren Yurtesen
55

Pengguna AWS RDS jika Anda mendapatkan ini, itu karena Anda bukan pengguna super dan menurut dokumentasi aws Anda tidak bisa menjadi salah satunya. Saya menemukan bahwa saya harus mengabaikan kesalahan ini.

Jim Zucker
sumber
5
Kesalahan ini mencegah pemulihan selesai untuk saya (AWS RDS pg_restore). Adakah tips untuk mengabaikan kesalahan ini?
avjaarsveld
PS Saya tidak menggunakan -e atau --exit-on-error untuk pg_restore
avjaarsveld
7
Saya telah menemukan bahwa, di RDS, masalahnya COMMENT ON EXTENSIONbukan CREATE EXTENSION. Hapus komentar dan Anda akan baik-baik saja.
pkoch
@pkoch sama dengan Google Cloud Storage. KOMENTAR TENTANG EKSTENSI adalah masalah dan tidak diperlukan
Jaybeecave
25

Bagi orang yang menggunakan Google Cloud Platform, kesalahan apa pun akan menghentikan proses impor. Secara pribadi saya mengalami dua kesalahan berbeda tergantung pada perintah pg_dump yang saya keluarkan:

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

Terjadi ketika Anda mencoba membuang DB Anda dalam format teks non-biasa. Yaitu ketika perintah tidak memiliki parameter -Fp atau --format = plain. Namun, jika Anda menambahkannya ke perintah Anda, Anda mungkin mengalami kesalahan berikut:

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

Ini adalah masalah izin yang tidak dapat saya perbaiki menggunakan perintah yang disediakan di dokumen GCP , tips dari utas saat ini, atau mengikuti saran dari tim Google Postgres di sini . Yang merekomendasikan untuk mengeluarkan perintah berikut:

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

Satu-satunya hal yang melakukan trik dalam kasus saya adalah mengedit file dump secara manual dan mengomentari semua perintah yang berkaitan dengan plpgsql.

Saya harap ini membantu jiwa-jiwa yang bergantung pada GCP.

Pembaruan:

Lebih mudah untuk membuang file yang mengomentari ekstensi, terutama karena beberapa dump bisa sangat besar: pg_dump ... | grep -v -E '(CREATE\ EXTENSION|COMMENT\ ON)' > mydump.sql

Yang dapat dipersempit menjadi plpgsql: pg_dump ... | grep -v -E '(CREATE\ EXTENSION\ IF\ NOT\ EXISTS\ plpgsql|COMMENT\ ON\ EXTENSION\ plpgsql)' > mydump.sql

Stanislasdrg Kembalikan Monica
sumber
1
GCP sekarang memiliki pg_dumpperintah yang tepat untuk digunakan di dokumen mereka :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

Anda mungkin dapat dengan aman mengabaikan pesan kesalahan dalam kasus ini. Gagal menambahkan komentar ke skema publik dan menginstal plpgsql (yang seharusnya sudah diinstal) tidak akan menyebabkan masalah nyata.

Namun, jika Anda ingin melakukan penginstalan ulang lengkap, Anda memerlukan pengguna dengan izin yang sesuai. Tentu saja itu seharusnya bukan pengguna yang menjalankan aplikasi Anda secara rutin.

Richard Huxton
sumber
12

Jawaban yang lebih singkat: abaikan saja.

Modul ini adalah bagian dari Postgres yang memproses bahasa SQL. Kesalahan akan sering muncul sebagai bagian dari menyalin database jarak jauh, seperti dengan 'heroku pg: pull'. Itu tidak menimpa prosesor SQL Anda dan memperingatkan Anda tentang itu.

Charles Merriam
sumber
10

Coba gunakan -Lbendera dengan pg_restore dengan menentukan file yang diambil daripg_dump -Fc

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

Pulihkan hanya elemen arsip yang terdaftar dalam file daftar, dan pulihkan dalam urutan kemunculannya di file. Perhatikan bahwa jika sakelar pemfilteran seperti -n atau -t digunakan dengan -L, mereka selanjutnya akan membatasi item yang dipulihkan.

list-file biasanya dibuat dengan mengedit output dari operasi -l sebelumnya. Garis dapat dipindahkan atau dihapus, dan juga dapat dikomentari dengan menempatkan titik koma (;) di awal baris. Lihat contoh di bawah.

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

Di sini Anda dapat melihat Inverse benar dengan hanya mengeluarkan komentar:

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
--
Ligemer
sumber
Saya rasa hal di atas benar, mengecualikan komentar untuk plugin tidak akan memengaruhi fungsionalitas aplikasi Anda
Andreas
3

Untuk orang yang menggunakan AWS , COMMENT ON EXTENSIONini hanya mungkin sebagai pengguna super , dan seperti yang kita ketahui oleh dokumen, instans RDS dikelola oleh Amazon. Dengan demikian, untuk mencegah Anda merusak hal-hal seperti replikasi, pengguna Anda - bahkan pengguna root yang Anda siapkan saat membuat instance - tidak akan memiliki hak superuser penuh:

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

Saat Anda membuat instans DB, akun sistem pengguna master yang Anda buat ditetapkan ke peran rds_superuser. Peran rds_superuser adalah peran Amazon RDS yang ditentukan sebelumnya yang mirip dengan peran superuser PostgreSQL (biasanya dinamai postgres dalam instans lokal), tetapi dengan beberapa batasan. Seperti halnya peran superuser PostgreSQL, peran rds_superuser memiliki hak istimewa paling banyak pada instans DB Anda dan Anda tidak boleh menetapkan peran ini kepada pengguna kecuali mereka paling membutuhkan akses ke instans DB.

Untuk memperbaiki kesalahan ini, cukup gunakan --untuk mengomentari baris SQL yang berisiCOMMENT ON EXTENSION

Petar Nikov
sumber
2
Atau komentar omit saat pembuangan: pg_dump --no-comments.
Dmitrii I.
2

Gunakan pengguna postgres (admin) untuk membuang skema, membuatnya kembali dan memberikan hak istimewa untuk digunakan sebelum Anda melakukan pemulihan. Dalam satu perintah:

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
Pascal_dher
sumber
1

Bagi saya, saya sedang menyiapkan database dengan pgAdmin dan tampaknya pengaturan pemilik selama pembuatan database tidak cukup. Saya harus menavigasi ke skema 'publik' dan mengatur pemilik di sana juga (awalnya 'postgres').

Peter L.
sumber
0

Untuk orang-orang yang telah mempersempit masalah ke COMMENT ONpernyataan (sesuai dengan berbagai jawaban di bawah) dan yang memiliki akses superuser ke database sumber dari mana file dump dibuat, solusi paling sederhana mungkin untuk mencegah komentar dimasukkan ke dump file di tempat pertama, dengan menghapusnya dari database sumber yang dibuang ...

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

Pembuangan masa depan tidak akan menyertakan COMMENT ONpernyataan.

Mark Schneider
sumber
1
Mengembangkan secara lokal di Rails (yang membuat file dump baru secara otomatis setiap kali migrasi skema dijalankan), solusi ini memungkinkan saya untuk menjalankannya rails db:resetpada instans postgresql AWS RDS tanpa harus menghapus baris KOMENTAR ON dari file dump setiap kali saya menjalankan skema migrasi.
Mark Schneider