В доступе отказано; вам нужны (по крайней мере, одна из) привилегии 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';

По-прежнему не повезло.

Кенпетер
источник

Ответы:

167

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

Сервер MySQL, предоставляемый RDS, не позволяет использовать DEFINERсинтаксис для другого пользователя (по моему опыту).

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

sed 's/\sDEFINER=`[^`]*`@`[^`]*`//g' -i oldfile.sql
hjpotter92
источник
3
Вы правы. Причина, по которой это не работает, заключается в том, что указание другого пользователя, DEFINERкогда у зарегистрированного пользователя нет SUPERпривилегии (что само по себе не разрешено в RDS), позволит произвольное повышение привилегий - сохраненные программы запускаются с учетными данными и привилегиями их DEFINER(в отличие от звонящего пользователя - их INVOKER) по умолчанию. Также при сбое сервера .
Майкл - sqlbot
Человек, ты спасатель. Если бы моя хостинговая компания сообщила мне о повреждении базы данных при экспорте, и ничего нельзя было сделать для восстановления. Идеальное решение.
Вуди
4
По какой-то причине мне пришлось использовать * вместо +:sed 's/\sDEFINER=`[^`]*`@`[^`]*`//' -i oldfile.sql
Berend de Boer
Спасибо @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.

quimm2003
источник
Благодарность! Помогло мне в случае РДС
Виктор
Спасибо. В моем случае я работал 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) - это уникальный идентификатор, созданный и связанный с каждой транзакцией, совершенной на исходном сервере (главном). Этот идентификатор уникален не только для сервера, на котором он был создан, но и для всех серверов в данной настройке репликации. Между всеми транзакциями и всеми 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
Avivamg
источник
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
загрузите атом или блокнот ++, откройте файл дампа 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 некорректен, вы можете столкнуться с некоторыми проблемами. Но здесь я не собираюсь объяснять, как создать файл дампа. Но вы можете спросить меня ( _ )
novice2ninja
источник
0

Я прокомментировал все строки, начинающиеся с SETв *.sqlфайле, и это сработало.

Tengerye
источник
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" на стороне сервера. Этот вы легко найдете на лезвии с левой стороны, если это лазурная мария db.

Картик Варада
источник
-1

утверждение

DEFINER = username@ `%

это проблема в резервной копии.

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

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

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

Суровый манвар
источник