ปฏิเสธการเข้าใช้; คุณต้องการ (อย่างน้อยหนึ่งใน) สิทธิ์ SUPER สำหรับการดำเนินการนี้


99

ฉันจึงลองนำเข้าไฟล์ sql เป็น rds (1G MEM, 1 CPU) ไฟล์ sql เหมือน 1.4G

mysql -h xxxx.rds.amazonaws.com -u ผู้ใช้ -ppass --max-allow-packet = 33554432 db <db.sql

มันติดอยู่ที่:

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

เนื้อหา sql จริงคือ:

/*!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 ไม่มีอยู่ใน rds ดังนั้นฉันจึงทำ:

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

ยังไม่มีโชค

คำตอบ:


180

ลบDEFINER=..คำสั่งออกจากไฟล์ sqldump ของคุณหรือแทนที่ค่าผู้ใช้ด้วยCURRENT_USER.

เซิร์ฟเวอร์ MySQL ที่จัดทำโดย RDS ไม่อนุญาตให้ใช้DEFINERไวยากรณ์สำหรับผู้ใช้รายอื่น (จากประสบการณ์ของฉัน)

คุณสามารถใช้sedสคริปต์เพื่อลบออกจากไฟล์:

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

3
คุณถูกต้อง เหตุผลที่ใช้ไม่ได้คือการระบุผู้ใช้รายอื่นDEFINERเมื่อผู้ใช้ที่เข้าสู่ระบบไม่มีSUPERสิทธิ์ (ซึ่งตัวเองไม่ได้รับอนุญาตใน RDS) จะอนุญาตให้เพิ่มสิทธิ์ตามอำเภอใจ - โปรแกรมที่จัดเก็บไว้จะทำงานด้วยข้อมูลประจำตัวและสิทธิ์ของผู้ใช้DEFINER(ตรงข้ามกับผู้ใช้ที่โทร - ของพวกเขาINVOKER) ตามค่าเริ่มต้น นอกจากนี้ในความผิดพลาดของเซิร์ฟเวอร์
Michael - sqlbot

ผู้ชายคุณเป็นผู้ช่วยชีวิต หาก บริษัท โฮสติ้งของฉันแจ้งว่าฐานข้อมูลเสียหายเมื่อส่งออกและไม่มีสิ่งใดที่สามารถกู้คืนได้ โซลูชั่นที่สมบูรณ์แบบ
Woody

5
ด้วยเหตุผลบางอย่างฉันต้องใช้ * แทน +:sed 's/\sDEFINER=`[^`]*`@`[^`]*`//' -i oldfile.sql
Berend de Boer

ขอบคุณ @BerenddeBoer
Awolad Hossain

1
@WonderLand คุณสามารถลองawkซึ่งอาจเร็วกว่าเล็กน้อยsed
hjpotter92

50

หากไฟล์ดัมพ์ของคุณไม่มีDEFINERให้ตรวจสอบว่าบรรทัดด้านล่างนี้ถูกลบออกไปด้วยหากมีหรือแสดงความคิดเห็นด้วย--:

จุดเริ่มต้น:

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

ในตอนท้าย:

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

13
คุณสามารถป้องกันสิ่งเหล่านี้ได้โดยเพิ่มคำสั่ง--set-gtid-purged=OFFของคุณ mysqldumpพบที่นี่: stackoverflow.com/a/56251925
Illya Moskvin

17

เคล็ดลับที่มีประโยชน์อีกประการหนึ่งคือการเรียกใช้ mysqldump ด้วยตัวเลือก --set-gtid-purged = OFF ซึ่งไม่ได้เขียนบรรทัดต่อไปนี้ลงในไฟล์เอาต์พุต:

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

ไม่แน่ใจเกี่ยวกับ DEFINER one


1
ขอบคุณ! มันช่วยฉันได้ในกรณีของ RDS
Victor

ขอขอบคุณ. ในกรณีของฉันฉันทำงานSET @@GLOBAL.GTID_MODE = OFF;ใน MySql Workbench ในด้านการส่งออกจากฐานข้อมูลต้นทาง
Byron Wong

8

เพียงแค่อัปเดตเพิ่มเติมสำหรับ MacOS สำหรับคำตอบ hjpotter92

หากต้องการsedจดจำรูปแบบใน MacOS คุณจะต้องเพิ่มแบ็กสแลชหน้า=เครื่องหมายดังนี้:

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

ใช้งานได้ในปี 2020 โดยใช้ MariaDB 10.4 บน macOS Catalina
Wayne

4

ปัญหา : คุณกำลังพยายามนำเข้าข้อมูล (โดยใช้ไฟล์ mysqldump) ไปยังฐานข้อมูล mysql ของคุณ แต่ดูเหมือนว่าคุณไม่ได้รับอนุญาตให้ดำเนินการดังกล่าว

วิธีแก้ไข : สมมติว่าข้อมูลของคุณถูกโอนย้ายเมล็ดพันธุ์และอัปเดตในฐานข้อมูล mysql ของคุณถ่ายภาพโดยใช้ mysqldump และส่งออกไปยังไฟล์

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

จากเอกสาร mysql:

GTID - ตัวระบุธุรกรรมทั่วโลก (GTID) คือตัวระบุเฉพาะที่สร้างขึ้นและเชื่อมโยงกับแต่ละธุรกรรมที่กระทำบนเซิร์ฟเวอร์ต้นทาง (หลัก) ตัวระบุนี้ไม่เฉพาะกับเซิร์ฟเวอร์ที่กำเนิดเท่านั้น แต่ยังไม่ซ้ำกันในเซิร์ฟเวอร์ทั้งหมดในการตั้งค่าการจำลองแบบที่กำหนด มีการแมปแบบ 1 ต่อ 1 ระหว่างธุรกรรมทั้งหมดและ GTID ทั้งหมด

--set-gtid-purged = OFF SET @@ GLOBAL.gtid_purged จะไม่ถูกเพิ่มลงในเอาต์พุตและ SET @@ SESSION.sql_log_bin = 0 จะไม่ถูกเพิ่มลงในเอาต์พุต สำหรับเซิร์ฟเวอร์ที่ไม่ได้ใช้ GTID ให้ใช้ตัวเลือกนี้หรืออัตโนมัติ ใช้ตัวเลือกนี้สำหรับเซิร์ฟเวอร์ที่ใช้ GTID เท่านั้นหากคุณแน่ใจว่าชุด GTID ที่ต้องการมีอยู่แล้วใน gtid_purged บนเซิร์ฟเวอร์เป้าหมายและไม่ควรเปลี่ยนแปลงหรือหากคุณวางแผนที่จะระบุและเพิ่ม GTID ที่ขาดหายไปด้วยตนเอง

หลังจากนั้นเชื่อมต่อกับ mysql ของคุณด้วยรูทผู้ใช้ให้สิทธิ์ล้างและตรวจสอบว่าสิทธิ์ผู้ใช้ของคุณได้รับการอัปเดตอย่างถูกต้อง

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

ตอนนี้โหลดข้อมูลและการดำเนินการควรจะได้รับอนุญาต

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

3

สำหรับการนำเข้าไฟล์ฐานข้อมูลใน.sql.gzรูปแบบให้ลบตัวกำหนดและนำเข้าโดยใช้คำสั่งด้านล่าง

zcat path_to_db_to_import.sql.gz | sed -e 's/DEFINER[ ]*=[ ]*[^*]*\*/\*/' | mysql -u user -p new_db_name
  1. ก่อนหน้านี้ส่งออกฐานข้อมูลในรูปแบบ. sql.gz โดยใช้คำสั่งด้านล่าง

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

  2. นำเข้าฐานข้อมูลที่ส่งออกและลบตัวกำหนดโดยใช้คำสั่งด้านล่าง

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


2

เมื่อคุณกู้คืนข้อมูลสำรองโปรดลองใช้ชื่อผู้ใช้เดิมและชื่อใหม่


2

โซลูชั่นเต็มรูปแบบ

วิธีแก้ปัญหาทั้งหมดข้างต้นใช้ได้ดี และที่นี่ฉันจะรวมวิธีแก้ปัญหาทั้งหมดเข้าด้วยกันเพื่อให้สามารถใช้ได้กับทุกสถานการณ์

  1. คงที่ DEFINER

สำหรับ Linux และ Mac

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

สำหรับ Windows
download atom หรือ notepad ++ ให้เปิดไฟล์ dump sql ด้วย atom หรือ notepad ++ กด Ctrl + F
ค้นหาคำว่าDEFINERและลบบรรทัดDEFINER = admin@% (หรืออาจแตกต่างกันเล็กน้อยสำหรับคุณ) จากทุกที่และบันทึกไฟล์
ตัวอย่าง
ก่อนลบบรรทัดนั้น: CREATE DEFINER = admin@ %PROCEDUREMyProcedure
หลังจากลบบรรทัดนั้น: CREATE PROCEDUREMyProcedure

  1. ลบ 3 บรรทัด ลบทั้ง 3 บรรทัดนี้ออกจากไฟล์ดัมพ์ คุณสามารถใช้คำสั่งsedหรือเปิดไฟล์ในโปรแกรมแก้ไข Atom และค้นหาแต่ละบรรทัดจากนั้นลบบรรทัด
    ตัวอย่าง: เปิด Dump2020.sql ใน Atom กด ctrl + F ค้นหาSET @@ SESSION.SQL_LOG_BIN = 0ลบบรรทัดนั้น
SET @@SESSION.SQL_LOG_BIN= 0;
SET @@GLOBAL.GTID_PURGED=/*!80000 '+'*/ '';
SET @@SESSION.SQL_LOG_BIN = @MYSQLDUMP_TEMP_LOG_BIN;
  1. มีปัญหากับไฟล์ที่ คุณสร้างขึ้นคุณอาจประสบปัญหาหากไฟล์ dump.sql ที่สร้างขึ้นไม่ถูกต้อง แต่ที่นี่ฉันจะไม่อธิบายวิธีสร้างไฟล์ดัมพ์ แต่คุณสามารถถามฉัน ( _ )

1

ผมแสดงความคิดเห็นทุกสายเริ่มต้นด้วยSETใน*.sqlไฟล์และการทำงาน


0

* คำตอบสามารถใช้ได้กับ MacOS เท่านั้น *

เมื่อพยายามนำเข้าไฟล์. sql ไปยัง Docker container ฉันพบข้อความแสดงข้อผิดพลาด:

ปฏิเสธการเข้าใช้; คุณต้องการ (อย่างน้อยหนึ่งใน) สิทธิ์ SUPER สำหรับการดำเนินการนี้

จากนั้นในขณะที่ลองทำตามคำแนะนำอื่น ๆ ฉันได้รับข้อผิดพลาดด้านล่างบน MacOS (osx)

sed: ข้อผิดพลาด RE: ลำดับไบต์ที่ไม่ถูกต้อง

ในที่สุดคำสั่งต่อไปนี้จากทรัพยากรนี้แก้ไขปัญหา "การเข้าถึงถูกปฏิเสธ" ของฉัน

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

ดังนั้นฉันสามารถนำเข้าสู่ฐานข้อมูลนักเทียบท่าด้วย:

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

หวังว่านี่จะช่วยได้! :)


0

จำเป็นต้องตั้งค่า "บน" พารามิเตอร์เซิร์ฟเวอร์ "log_bin_trust_function_creators" ที่ฝั่งเซิร์ฟเวอร์ อันนี้หาได้ง่ายๆที่ใบมีดด้านซ้ายถ้าเป็น azure maria db


-1

คำให้การ

ผู้กำหนด = username@ `%

เป็นปัญหาในการถ่ายโอนข้อมูลสำรองของคุณ

วิธีแก้ปัญหาที่คุณสามารถแก้ไขได้คือการลบรายการทั้งหมดจากไฟล์ดัมพ์ sql และนำเข้าข้อมูลจากคอนโซล GCP

แมว DUMP_FILE_NAME.sql | sed -e 's / DEFINER = <username>@ %// g'> ใหม่ -CLEANED-DUMP.sql

ลองนำเข้าไฟล์ใหม่ (NEW-CLEANED-DUMP.sql)

โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.