У доступі відмовлено; вам потрібна (принаймні одна з) привілеїв SUPER для цієї операції


89

Тому я намагаюся імпортувати файл sql у rds (1G MEM, 1 CPU). Файл sql схожий на 1.4G

mysql -h xxxx.rds.amazonaws.com -u user -ppass --max-allowed-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';

Досі не везе.

Відповіді:


168

Або видаліть DEFINER=..оператор із вашого файлу sqldump, або замініть значення користувача на CURRENT_USER.

Сервер MySQL, наданий RDS, не дозволяє DEFINERсинтаксис для іншого користувача (на мій досвід).

Ви можете використовувати sedскрипт, щоб видалити їх із файлу:

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

3
Ви маєте рацію. Причина, по якій це не працює, полягає в тому, що вказівка ​​іншого користувача, оскільки DEFINERколи зареєстрований користувач не має SUPERпривілеїв (що сам по собі не дозволений у RDS), дозволить довільне посилення привілеїв - збережені програми запускаються з обліковими даними та привілеями своїх DEFINER(на відміну від виклику користувача - їх INVOKER), за замовчуванням. Також на сервері Fault .
Майкл - sqlbot

Чоловіче, ти врятував життя. Якби моя хостинг-компанія повідомила мені пошкоджену базу даних під час експорту, і нічого не можна було зробити для відновлення. Ідеальне рішення.
Вуді

4
Чомусь мені довелося використовувати * замість +:sed 's/\sDEFINER=`[^`]*`@`[^`]*`//' -i oldfile.sql
Беренд де Бур

Дякую @BerenddeBoer
Awolad Hossain

1
@WonderLand Ви можете спробувати, awkщо може бути трохи швидше, ніжsed
hjpotter92

35

Якщо у вашому файлі дампа немає DEFINER, переконайтесь, що ці рядки нижче також видалено, якщо вони є там, або прокоментовано за допомогою --:

На початку:

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

В кінці:

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

12
Ви можете запобігти цим, додавши --set-gtid-purged=OFFдо своєї mysqldumpкоманди. Знайдено тут: stackoverflow.com/a/56251925
Ілля Москвін

13

Ще одним корисним трюком є ​​виклик 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.


Дякую! Це допомогло мені у випадку RDS
Віктор

Дякую. У моєму випадку я працював SET @@GLOBAL.GTID_MODE = OFF;у MySql Workbench на стороні експорту з вихідної бази даних
Байрон Вонг,

8

Просто додаткове оновлення MacOS для відповіді hjpotter92.

Щоб sedрозпізнати шаблон у MacOS, вам доведеться додати зворотну скісну риску перед =знаком, наприклад:

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

працює з 2020 року, використовуючи MariaDB 10.4 на macOS Catalina
Уейн

4

Проблема : Ви намагаєтесь імпортувати дані (використовуючи файл mysqldump) у свою базу даних mysql, але, схоже, у вас немає дозволу на виконання цієї операції.

Рішення : Припускаючи, що дані перенесені, засіяні та оновлені у вашій базі даних mysql, зробіть знімок за допомогою mysqldump та експортуйте його у файл

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

З документації mysql:

GTID - глобальний ідентифікатор транзакції (GTID) - це унікальний ідентифікатор, який створюється та асоціюється з кожною транзакцією, здійсненою на сервері походження (master). Цей ідентифікатор унікальний не лише для сервера, на якому він виник, але унікальний для всіх серверів у заданій установці реплікації. Існує співвідношення 1: 1 між усіма транзакціями та усіма GTID.

--set-gtid-purged = OFF SET @@ GLOBAL.gtid_purged не додається до виводу, а SET @@ SESSION.sql_log_bin = 0 не додається до виводу. Для сервера, де GTID не використовуються, використовуйте цю опцію або AUTO. Використовуйте цю опцію лише для сервера, де використовуються GTID, якщо ви впевнені, що необхідний набір GTID вже присутній у gtid_purged на цільовому сервері і не повинен бути змінений, або якщо ви плануєте ідентифікувати та додати відсутні відсутні GTID вручну.

Потім підключіться до вашого mysql за допомогою root користувача, надайте дозволи, очистіть їх і переконайтеся, що ваші привілеї користувача оновлені правильно.

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


3

Відновляючи резервну копію, обов’язково спробуйте використати одне і те ж ім’я користувача для старого та нового.


2

Повне рішення

Всі перераховані вище рішення прекрасні. І тут я буду поєднувати всі рішення, щоб воно могло працювати в усіх ситуаціях.

  1. Виправлено ВИЗНАЧИТЕЛЬ

Для Linux та Mac

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

Для
завантаження Windows atom або notepad ++ відкрийте ваш файл дампа 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 у контейнер докера, я зіткнувся з повідомленням про помилку:

У доступі відмовлено; вам потрібна (принаймні одна з) привілеїв 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

Потрібно встановити параметр "on" сервера "log_bin_trust_function_creators" на стороні сервера. Цю можна легко знайти на лівому боковому лезі, якщо це блакитна Марія ДБ.


-1

Заява

ВИЗНАЧАЛЬНИК = username@ `%

- проблема у вашому дампі резервної копії.

Рішення, яке можна обійти, - це видалити всі записи із файлу дампа sql та імпортувати дані з консолі GCP.

кішка DUMP_FILE_NAME.sql | sed -e 's / DEFINER = <username>@ %// g'> NEW-CLEANED-DUMP.sql

Спробуйте імпортувати новий файл (NEW-CLEANED-DUMP.sql).

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.