Akses ditolak; Anda memerlukan (setidaknya satu dari) hak istimewa SUPER untuk operasi ini

99

Jadi saya mencoba mengimpor file sql ke rds (1G MEM, 1 CPU). File sql seperti 1.4G

mysql -h xxxx.rds.amazonaws.com -u pengguna -ppass --max-diperbolehkan-paket = 33554432 db <db.sql

Itu macet di:

ERROR 1227 (42000) at line 374: Access denied; you need (at least one of) the SUPER privilege(s) for this operation

Konten sql sebenarnya adalah:

/*!50003 CREATE*/ /*!50017 DEFINER=`another_user`@`1.2.3.4`*/ /*!50003 TRIGGER `change_log_BINS` BEFORE INSERT ON `change_log` FOR EACH ROW
IF (NEW.created_at IS NULL OR NEW.created_at = '00-00-00 00:00:00' OR NEW.created_at = '') THEN
        SET NEW.created_at = NOW();
END IF */;;

another_user tidak ada di rds, jadi saya lakukan:

GRANT ALL PRIVILEGES ON db.* TO another_user@'localhost';

Masih belum berhasil.

kenpeter
sumber

Jawaban:

180

Hapus DEFINER=..pernyataan dari file sqldump Anda, atau ganti nilai pengguna dengan CURRENT_USER.

Server MySQL yang disediakan oleh RDS tidak mengizinkan DEFINERsintaks untuk pengguna lain (menurut pengalaman saya).

Anda dapat menggunakan sedskrip untuk menghapusnya dari file:

sed 's/\sDEFINER=`[^`]*`@`[^`]*`//g' -i oldfile.sql
hjpotter92
sumber
3
Kamu benar. Alasan tidak berhasil adalah bahwa menentukan pengguna lain seperti DEFINERketika pengguna yang masuk tidak memiliki SUPERhak istimewa (yang tidak diizinkan di RDS) akan memungkinkan eskalasi hak istimewa sewenang-wenang - program yang disimpan dijalankan dengan kredensial dan hak istimewa mereka. DEFINER(sebagai lawan dari pengguna yang memanggil - mereka INVOKER), secara default. Juga di Kesalahan Server .
Michael - sqlbot
Man, Anda adalah penyelamat hidup. Apakah perusahaan hosting saya memberi tahu saya database yang rusak saat diekspor dan tidak ada yang bisa dilakukan untuk memulihkan. Solusi sempurna.
Woody
5
Untuk beberapa alasan saya harus menggunakan * daripada +:sed 's/\sDEFINER=`[^`]*`@`[^`]*`//' -i oldfile.sql
Berend de Boer
Terima kasih @BerenddeBer
Awolad Hossain
1
@WonderLand Anda dapat mencoba awkyang mungkin sedikit lebih cepat darised
hjpotter92
50

Jika file dump Anda tidak memiliki DEFINER, pastikan baris di bawah ini juga dihapus jika ada, atau diberi komentar dengan --:

Di awal:

-- SET @@SESSION.SQL_LOG_BIN= 0;
-- SET @@GLOBAL.GTID_PURGED=/*!80000 '+'*/ '';

Pada akhirnya:

-- SET @@SESSION.SQL_LOG_BIN = @MYSQLDUMP_TEMP_LOG_BIN;
Jeremy Jones
sumber
13
Anda dapat mencegahnya dengan menambahkan --set-gtid-purged=OFFke mysqldumpperintah Anda . Ditemukan di sini: stackoverflow.com/a/56251925
Illya Moskvin
17

Trik berguna lainnya adalah memanggil mysqldump dengan opsi --set-gtid-purged = OFF yang tidak menulis baris berikut ke file output:

SET @@SESSION.SQL_LOG_BIN= 0;
SET @@GLOBAL.GTID_PURGED=/*!80000 '+'*/ '';
SET @@SESSION.SQL_LOG_BIN = @MYSQLDUMP_TEMP_LOG_BIN;

tidak yakin tentang yang DEFINER.

quimm2003
sumber
1
Terima kasih! Ini membantu saya dalam kasus RDS
Victor
Terima kasih. Dalam kasus saya, saya menjalankan SET @@GLOBAL.GTID_MODE = OFF;MySql Workbench di sisi pengekspor dari database sumber
Byron Wong
8

Hanya pembaruan ekstra MacOS untuk jawaban hjpotter92.

Untuk sedmengenali pola di MacOS, Anda harus menambahkan garis miring terbalik sebelum =tanda, seperti ini:

sed -i old 's/\DEFINER\=`[^`]*`@`[^`]*`//g' file.sql
marcel
sumber
berfungsi mulai 2020, menggunakan MariaDB 10.4 di macOS Catalina
Wayne
4

Masalah : Anda mencoba mengimpor data (menggunakan file mysqldump) ke database mysql Anda, tetapi tampaknya Anda tidak memiliki izin untuk melakukan operasi itu.

Solusi : Dengan asumsi data Anda dimigrasi, diunggulkan, dan diperbarui dalam database mysql Anda, ambil snapshot menggunakan mysqldump dan ekspor ke file

mysqldump -u [username] -p [databaseName] --set-gtid-purged=OFF > [filename].sql

Dari dokumentasi mysql:

GTID - Pengenal transaksi global (GTID) adalah pengenal unik yang dibuat dan dikaitkan dengan setiap transaksi yang dilakukan di server asal (master). Pengenal ini unik tidak hanya untuk server asalnya, tetapi juga unik di semua server dalam penyiapan replikasi tertentu. Ada pemetaan 1-ke-1 antara semua transaksi dan semua GTID.

--set-gtid-purged = OFF SET @@ GLOBAL.gtid_purged tidak ditambahkan ke keluaran, dan SET @@ SESSION.sql_log_bin = 0 tidak ditambahkan ke keluaran. Untuk server di mana GTID tidak digunakan, gunakan opsi ini atau AUTO. Gunakan opsi ini hanya untuk server tempat GTID digunakan jika Anda yakin bahwa kumpulan GTID yang diperlukan sudah ada di gtid_purged pada server target dan tidak boleh diubah, atau jika Anda berencana untuk mengidentifikasi dan menambahkan GTID yang hilang secara manual.

Setelah itu hubungkan ke mysql Anda dengan root pengguna, berikan izin, bersihkan, dan verifikasi bahwa hak pengguna Anda telah diperbarui dengan benar.

mysql -u root -p
UPDATE mysql.user SET Super_Priv='Y' WHERE user='johnDoe' AND host='%';
FLUSH PRIVILEGES;
mysql> SHOW GRANTS FOR 'johnDoe';
+------------------------------------------------------------------+
| Grants for johnDoe                                               |
+------------------------------------------------------------------+
| GRANT USAGE ON *.* TO `johnDoe`                                  |
| GRANT ALL PRIVILEGES ON `db1`.* TO `johnDoe`                     |
+------------------------------------------------------------------+

sekarang muat ulang data dan operasi harus diizinkan .

mysql -h [host] -u [user] -p[pass] [db_name] < [mysql_dump_name].sql
avivamg.dll
sumber
3

Untuk mengimpor file database dalam .sql.gzformat, hapus definer dan impor menggunakan perintah di bawah ini

zcat path_to_db_to_import.sql.gz | sed -e 's/DEFINER[ ]*=[ ]*[^*]*\*/\*/' | mysql -u user -p new_db_name
  1. Sebelumnya, ekspor database dalam format .sql.gz menggunakan perintah di bawah ini.

    mysqldump -u user -p old_db | gzip -9 > path_to_db_exported.sql.gz;

  2. Impor database yang diekspor dan hapus definer menggunakan perintah di bawah ini,

    zcat path_to_db_exported.sql.gz | sed -e 's/DEFINER[ ]*=[ ]*[^*]*\*/\*/' | mysql -u user -p new_db

Kazim Noorani
sumber
2

Saat Anda memulihkan cadangan, Pastikan untuk mencoba dengan nama pengguna yang sama untuk yang lama dan yang baru.

mafei
sumber
2

Solusi Lengkap

Semua solusi di atas baik-baik saja. Dan di sini saya akan menggabungkan semua solusi sehingga dapat bekerja untuk semua situasi.

  1. Memperbaiki DEFINER

Untuk Linux dan Mac

sed -i old 's/\DEFINER\=`[^`]*`@`[^`]*`//g' file.sql

Untuk Windows
unduh atom atau notepad ++, buka file dump sql Anda dengan atom atau notepad ++, tekan Ctrl + F
cari kata DEFINER , dan hapus baris DEFINER = admin@% (atau mungkin sedikit berbeda untuk Anda) dari mana saja dan simpan file.
Sebagai contoh
sebelum menghapus baris itu: CREATE DEFINER = admin@ %PROCEDUREMyProcedure
Setelah menghapus baris itu: CREATE PROCEDUREMyProcedure

  1. Hapus 3 baris Hapus semua 3 baris ini dari file dump. Anda dapat menggunakan perintah sed atau membuka file di editor Atom dan mencari setiap baris lalu menghapus baris tersebut.
    Contoh: Buka Dump2020.sql di Atom, Tekan ctrl + F, cari SET @@ SESSION.SQL_LOG_BIN = 0 , hapus baris itu.
SET @@SESSION.SQL_LOG_BIN= 0;
SET @@GLOBAL.GTID_PURGED=/*!80000 '+'*/ '';
SET @@SESSION.SQL_LOG_BIN = @MYSQLDUMP_TEMP_LOG_BIN;
  1. Ada masalah dengan file yang Anda buat. Anda mungkin menghadapi beberapa masalah jika file dump.sql yang Anda buat tidak sesuai. Tapi di sini, saya tidak akan menjelaskan cara membuat file dump. Tapi Anda bisa bertanya kepada saya ( _ )
novice2ninja
sumber
1

Saya berkomentar semua baris mulai dengan SETdi *.sqlberkas dan bekerja.

Tengerye
sumber
0

* Jawaban mungkin hanya berlaku untuk MacOS *

Saat mencoba mengimpor file .sql ke dalam kontainer buruh pelabuhan, saya menemukan pesan kesalahan:

Akses ditolak; Anda memerlukan (setidaknya satu dari) hak istimewa SUPER untuk operasi ini

Kemudian ketika mencoba beberapa saran lain, saya menerima kesalahan di bawah ini di MacOS (osx) saya

sed: RE error: urutan byte ilegal

Akhirnya, perintah berikut dari sumber ini menyelesaikan masalah "Access Denied" saya.

LC_ALL=C sed -i old 's/\DEFINER\=`[^`]*`@`[^`]*`//g' fileName.sql

Jadi saya bisa mengimpor ke database buruh pelabuhan dengan:

docker exec -i dockerContainerName mysql -uuser -ppassword table < importFile.sql

Semoga ini membantu! :)

Mike Dubs
sumber
0

Perlu menyetel "pada" parameter server "log_bin_trust_function_creators" di sisi server. Yang ini dapat dengan mudah Anda temukan di bilah sisi kiri jika itu adalah azure maria db.

karthik varada
sumber
-1

Pernyataan

PENILAI = username@ `%

adalah masalah di dump cadangan Anda.

Solusi yang dapat Anda atasi adalah dengan menghapus semua entri dari file sql dump dan mengimpor data dari konsol GCP.

kucing DUMP_FILE_NAME.sql | sed -e 's / DEFINER = <username>@ %// g'> BARU-DIBERSIHKAN-DUMP.sql

Coba impor file baru (NEW-CLEANED-DUMP.sql).

Harsh Manvar
sumber