Quyền truy cập bị từ chối; bạn cần (ít nhất một trong số) (các) đặc quyền SUPER cho hoạt động này


89

Vì vậy, tôi cố gắng nhập tệp sql vào rds (1G MEM, 1 CPU). Tệp sql giống như 1.4G

mysql -h xxxx.rds.amazonaws.com -u user -ppass --max-allow-packet = 33554432 db <db.sql

Nó bị kẹt ở:

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

Nội dung sql thực tế là:

/*!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 không tồn tại trong rds, vì vậy tôi làm:

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

Vẫn không có may mắn.

Câu trả lời:


168

Xóa DEFINER=..câu lệnh khỏi tệp sqldump của bạn hoặc thay thế các giá trị người dùng bằng CURRENT_USER.

Máy chủ MySQL được cung cấp bởi RDS không cho phép một DEFINERcú pháp cho người dùng khác (theo kinh nghiệm của tôi).

Bạn có thể sử dụng sedtập lệnh để xóa chúng khỏi tệp:

sed 's/\sDEFINER=`[^`]*`@`[^`]*`//g' -i oldfile.sql

3
Bạn hoàn toàn đúng. Lý do nó không hoạt động là việc chỉ định người dùng khác như DEFINERkhi người dùng đã đăng nhập không có SUPERđặc quyền (bản thân nó không được phép trong RDS) sẽ cho phép báo cáo đặc quyền tùy ý - các chương trình được lưu trữ chạy với thông tin đăng nhập và đặc quyền của họ DEFINER(trái ngược với của người dùng đang gọi - của họ INVOKER), theo mặc định. Cũng tại Lỗi máy chủ .
Michael - sqlbot

Man bạn là một người tiết kiệm cuộc sống. Đã có công ty lưu trữ của tôi cho tôi biết cơ sở dữ liệu bị hỏng khi xuất và không thể làm gì để khôi phục. Giải pháp hoàn hảo.
Woody

4
Vì một số lý do, tôi phải sử dụng * thay vì +:sed 's/\sDEFINER=`[^`]*`@`[^`]*`//' -i oldfile.sql
Berend de Boer

Cảm ơn @BerenddeBoer
Awolad Hossain 11/02/18

1
@WonderLand Bạn có thể thử cách awknày có thể nhanh hơn một chútsed
hjpotter92

35

Nếu tệp kết xuất của bạn không có DEFINER, hãy đảm bảo rằng những dòng bên dưới cũng bị xóa nếu chúng ở đó hoặc được nhận xét bằng --:

Khi bắt đầu:

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

Cuối cùng:

-- SET @@SESSION.SQL_LOG_BIN = @MYSQLDUMP_TEMP_LOG_BIN;

12
Bạn có thể ngăn chặn những điều này bằng cách thêm --set-gtid-purged=OFFvào mysqldumplệnh của mình . Tìm thấy ở đây: stackoverflow.com/a/56251925
Illya Moskvin

13

Một thủ thuật hữu ích khác là gọi mysqldump với tùy chọn --set-gtid-purged = OFF không ghi các dòng sau vào tệp đầu ra:

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

không chắc chắn về ĐỊNH NGHĨA.


Cảm ơn! Nó đã giúp tôi trong trường hợp RDS
Victor

Cảm ơn bạn. Trong trường hợp của tôi, tôi đã chạy SET @@GLOBAL.GTID_MODE = OFF;trong MySql Workbench ở phía xuất từ ​​cơ sở dữ liệu nguồn
Byron Wong

8

Chỉ là bản cập nhật bổ sung MacOS cho câu trả lời hjpotter92.

Để sednhận dạng mẫu trong MacOS, bạn sẽ phải thêm dấu gạch chéo ngược trước =dấu, như sau:

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

hoạt động kể từ năm 2020, sử dụng MariaDB 10.4 trên macOS Catalina
Wayne

4

Sự cố: Bạn đang cố gắng nhập dữ liệu (sử dụng tệp mysqldump) vào cơ sở dữ liệu mysql của mình, nhưng có vẻ như bạn không có quyền thực hiện thao tác đó.

Giải pháp : Giả sử dữ liệu của bạn được di chuyển, gieo hạt và cập nhật trong cơ sở dữ liệu mysql của bạn, hãy chụp ảnh nhanh bằng mysqldump và xuất nó thành tệp

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

Từ tài liệu mysql:

GTID - Số nhận dạng giao dịch toàn cầu (GTID) là số nhận dạng duy nhất được tạo và liên kết với mỗi giao dịch được cam kết trên máy chủ gốc (chính). Số nhận dạng này không chỉ duy nhất đối với máy chủ mà nó bắt nguồn, mà là duy nhất trên tất cả các máy chủ trong một thiết lập sao chép nhất định. Có một ánh xạ 1-1 giữa tất cả các giao dịch và tất cả các GTID.

--set-gtid-purged = OFF SET @@ GLOBAL.gtid_purged không được thêm vào đầu ra và SET @@ SESSION.sql_log_bin = 0 không được thêm vào đầu ra. Đối với máy chủ không sử dụng GTID, hãy sử dụng tùy chọn này hoặc TỰ ĐỘNG. Chỉ sử dụng tùy chọn này cho máy chủ nơi GTID đang được sử dụng nếu bạn chắc chắn rằng bộ GTID bắt buộc đã có trong gtid_purged trên máy chủ đích và không được thay đổi hoặc nếu bạn định xác định và thêm bất kỳ GTID bị thiếu nào theo cách thủ công.

Sau đó, kết nối với mysql của bạn bằng user root, cấp quyền, cấp quyền cho chúng và xác minh rằng đặc quyền người dùng của bạn đã được cập nhật chính xác.

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`                     |
+------------------------------------------------------------------+

bây giờ tải lại dữ liệu và hoạt động sẽ được cho phép .

mysql -h [host] -u [user] -p[pass] [db_name] < [mysql_dump_name].sql

3

Để nhập tệp cơ sở dữ liệu theo .sql.gzđịnh dạng, hãy xóa trình xác định và nhập bằng lệnh dưới đây

zcat path_to_db_to_import.sql.gz | sed -e 's/DEFINER[ ]*=[ ]*[^*]*\*/\*/' | mysql -u user -p new_db_name
  1. Trước đó, xuất cơ sở dữ liệu ở định dạng .sql.gz bằng lệnh dưới đây.

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

  2. Nhập cơ sở dữ liệu đã xuất đó và xóa trình xác định bằng lệnh dưới đây,

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


3

Khi bạn khôi phục bản sao lưu, hãy nhớ thử với cùng một tên người dùng cho tên cũ và tên mới.


2

Giải pháp đầy đủ

Tất cả các giải pháp trên đều ổn. Và ở đây tôi sẽ kết hợp tất cả các giải pháp để nó phù hợp với mọi tình huống.

  1. Đã sửa lỗi DEFINER

Đối với Linux và Mac

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

Đối với Windows
tải xuống atom hoặc notepad ++, hãy mở tệp kết xuất sql của bạn bằng atom hoặc notepad ++, nhấn Ctrl + F
để tìm kiếm từ DEFINER và xóa dòng DEFINER = admin@% (hoặc có thể hơi khác đối với bạn) khỏi mọi nơi và lưu tệp.
Ví dụ
trước khi xóa dòng đó: CREATE DEFINER = admin@ %PROCEDUREMyProcedure
Sau khi xóa dòng đó: CREATE PROCEDUREMyProcedure

  1. Xóa 3 dòng Xóa tất cả 3 dòng này khỏi tệp kết xuất. Bạn có thể sử dụng lệnh sed hoặc mở tệp trong trình soạn thảo Atom và tìm kiếm từng dòng rồi xóa dòng.
    Ví dụ: Mở Dump2020.sql trong Atom, Nhấn ctrl + F, tìm kiếm SET @@ SESSION.SQL_LOG_BIN = 0 , xóa dòng đó.
SET @@SESSION.SQL_LOG_BIN= 0;
SET @@GLOBAL.GTID_PURGED=/*!80000 '+'*/ '';
SET @@SESSION.SQL_LOG_BIN = @MYSQLDUMP_TEMP_LOG_BIN;
  1. Có vấn đề với tệp được tạo của bạn Bạn có thể gặp một số vấn đề nếu tệp dump.sql được tạo của bạn không phù hợp. Nhưng ở đây, tôi sẽ không giải thích cách tạo tệp kết xuất. Nhưng bạn có thể hỏi tôi ( _ )

1

Tôi đã nhận xét tất cả các dòng bắt đầu bằng SETtrong *.sqltệp và nó đã hoạt động.


0

* Câu trả lời chỉ có thể áp dụng cho MacOS *

Khi cố gắng nhập tệp .sql vào vùng chứa docker, tôi gặp phải thông báo lỗi:

Quyền truy cập bị từ chối; bạn cần (ít nhất một trong số) (các) đặc quyền SUPER cho hoạt động này

Sau đó, trong khi thử một số đề xuất khác, tôi nhận được lỗi bên dưới trên MacOS (osx) của mình

sed: Lỗi RE: chuỗi byte bất hợp pháp

Cuối cùng, lệnh sau từ tài nguyên này đã giải quyết vấn đề "Quyền truy cập bị từ chối" của tôi.

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

Vì vậy, tôi có thể nhập vào cơ sở dữ liệu docker với:

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

Hi vọng điêu nay co ich! :)


0

Cần đặt "trên" thông số máy chủ "log_bin_trust_ Chức năng_creators" ở phía máy chủ. Cái này bạn có thể dễ dàng tìm thấy ở lưỡi gà bên trái nếu nó là azure maria db.


-1

Tuyên bố

DEFINER = username@ `%

là một vấn đề trong kết xuất dự phòng của bạn.

Giải pháp mà bạn có thể giải quyết là xóa tất cả mục nhập khỏi tệp kết xuất sql và nhập dữ liệu từ bảng điều khiển GCP.

mèo DUMP_FILE_NAME.sql | sed -e 's / DEFINER = <username>@ %// g'> NEW-CLEANED-DUMP.sql

Thử nhập tệp mới (MỚI-CLEANED-DUMP.sql).

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.