Brak dostępu; potrzebujesz (przynajmniej jednego) uprawnień SUPER do tej operacji

87

Więc próbuję zaimportować plik sql do rds (1G MEM, 1 procesor). Plik sql ma rozmiar 1,4G

mysql -h xxxx.rds.amazonaws.com -u użytkownik -ppass --max-allowed-packet = 33554432 db <db.sql

Utknęło w:

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

Rzeczywista zawartość sql to:

/*!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 nie istnieje w rds, więc robię:

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

Wciąż nie ma szczęścia.

kenpeter
źródło

Odpowiedzi:

166

Usuń DEFINER=..instrukcję z pliku sqldump lub zamień wartości użytkownika na CURRENT_USER.

Serwer MySQL dostarczony przez RDS nie pozwala na DEFINERskładnię dla innego użytkownika (z mojego doświadczenia).

Możesz użyć sedskryptu, aby usunąć je z pliku:

sed 's/\sDEFINER=`[^`]*`@`[^`]*`//g' -i oldfile.sql
hjpotter92
źródło
3
Masz rację. Powodem, dla którego to nie działa, jest to, że określenie innego użytkownika, DEFINERgdy zalogowany użytkownik nie ma SUPERuprawnienia (co samo w sobie jest niedozwolone w RDS), umożliwiłoby dowolną eskalację uprawnień - zapisane programy działają z poświadczeniami i uprawnieniami ich DEFINER(w przeciwieństwie do użytkownika dzwoniącego - ich INVOKER), domyślnie. Również w przypadku awarii serwera .
Michael - sqlbot
Człowieku, ratujesz życie. Czy moja firma hostingowa poinformowała mnie o uszkodzeniu bazy danych podczas eksportu i nie można było nic zrobić, aby ją przywrócić. Idealne rozwiązanie.
Woody
4
Z jakiegoś powodu musiałem użyć * zamiast +:sed 's/\sDEFINER=`[^`]*`@`[^`]*`//' -i oldfile.sql
Berend de Boer
Dzięki @BerenddeBoer
Awolad Hossain
1
@WonderLand Możesz spróbować, awkco może być trochę szybsze niżsed
hjpotter92
34

Jeśli twój plik zrzutu nie ma DEFINER, upewnij się, że te wiersze poniżej zostały również usunięte, jeśli się tam znajdują, lub zakomentowane za pomocą --:

Na początku:

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

Na końcu:

-- SET @@SESSION.SQL_LOG_BIN = @MYSQLDUMP_TEMP_LOG_BIN;
Jeremy Jones
źródło
12
Możesz temu zapobiec, dodając --set-gtid-purged=OFFdo mysqldumppolecenia. Znaleziono tutaj: stackoverflow.com/a/56251925
Illya Moskvin
13

Inną przydatną sztuczką jest wywołanie mysqldump z opcją --set-gtid-purged = OFF, która nie zapisuje następujących wierszy w pliku wyjściowym:

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

nie jestem pewien co do DEFINERA.

quimm2003
źródło
Dzięki! Pomogło mi to w przypadku RDS
Victor
Dziękuję Ci. W moim przypadku uruchomiłem SET @@GLOBAL.GTID_MODE = OFF;w MySql Workbench po stronie eksportującej ze źródłowej bazy danych
Byron Wong
8

Tylko dodatkowa aktualizacja MacOS dla odpowiedzi hjpotter92.

Aby sedrozpoznać wzór w systemie MacOS, musisz dodać ukośnik odwrotny przed =znakiem, na przykład:

sed -i old 's/\DEFINER\=`[^`]*`@`[^`]*`//g' file.sql
marcel
źródło
działa od 2020 roku, używając MariaDB 10.4 na macOS Catalina
Wayne
4

Problem : Próbujesz zaimportować dane (używając pliku mysqldump) do bazy danych mysql, ale wygląda na to, że nie masz uprawnień do wykonania tej operacji.

Rozwiązanie : Zakładając, że dane są migrowane, wysyłane i aktualizowane w bazie danych mysql, zrób migawkę za pomocą mysqldump i wyeksportuj ją do pliku

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

Z dokumentacji mysql:

GTID - globalny identyfikator transakcji (GTID) to unikalny identyfikator utworzony i powiązany z każdą transakcją popełnioną na serwerze pochodzenia (głównym). Ten identyfikator jest unikalny nie tylko dla serwera, z którego pochodzi, ale jest unikalny dla wszystkich serwerów w danej konfiguracji replikacji. Istnieje mapowanie 1 do 1 między wszystkimi transakcjami i wszystkimi identyfikatorami GTID.

--set-gtid- purged = OFF SET @@ GLOBAL.gtid_purged nie jest dodawane do wyjścia, a SET @@ SESSION.sql_log_bin = 0 nie jest dodawane do wyjścia. W przypadku serwera, na którym nie są używane identyfikatory GTID, użyj tej opcji lub AUTO. Użyj tej opcji tylko dla serwera, na którym używane są identyfikatory GTID, jeśli masz pewność, że wymagany zestaw GTID jest już obecny w gtid_purged na serwerze docelowym i nie powinien być zmieniany lub jeśli planujesz ręcznie zidentyfikować i dodać brakujące GTID.

Następnie połącz się z mysql za pomocą użytkownika root, nadaj uprawnienia, opróżnij je i sprawdź, czy uprawnienia użytkownika zostały poprawnie zaktualizowane.

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

teraz przeładuj dane i operacja powinna być dozwolona .

mysql -h [host] -u [user] -p[pass] [db_name] < [mysql_dump_name].sql
avivamg
źródło
3

Aby zaimportować plik bazy danych w .sql.gzformacie, usuń definicję i zaimportuj za pomocą poniższego polecenia

zcat path_to_db_to_import.sql.gz | sed -e 's/DEFINER[ ]*=[ ]*[^*]*\*/\*/' | mysql -u user -p new_db_name
  1. Wcześniej wyeksportuj bazę danych w formacie .sql.gz za pomocą poniższego polecenia.

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

  2. Zaimportuj wyeksportowaną bazę danych i usuń definicję za pomocą poniższego polecenia,

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

Kazim Noorani
źródło
2

Podczas przywracania kopii zapasowej upewnij się, że używasz tej samej nazwy użytkownika dla starego i nowego.

mafei
źródło
2

Pełne rozwiązanie

Wszystkie powyższe rozwiązania są w porządku. I tutaj połączę wszystkie rozwiązania, aby działały we wszystkich sytuacjach.

  1. Naprawiono DEFINER

Dla systemu Linux i Mac

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

W przypadku
pobierania atomu lub notatnika ++ dla systemu Windows otwórz plik dump sql za pomocą atomu lub notepad ++, naciśnij Ctrl + F
wyszukaj słowo DEFINER i usuń wiersz DEFINER = admin@% (lub może być trochę inny dla ciebie) z dowolnego miejsca i zapisz plik.
Jak na przykład
przed usunięciem tej linii: CREATE DEFINER = admin@ %PROCEDUREMyProcedure
Po usunięciu tej linii: CREATE PROCEDUREMyProcedure

  1. Usuń 3 linie Usuń wszystkie 3 linie z pliku zrzutu. Możesz użyć polecenia sed lub otworzyć plik w edytorze Atom i wyszukać każdą linię, a następnie usunąć linię.
    Przykład: Otwórz Dump2020.sql w Atom, naciśnij ctrl + F, wyszukaj SET @@ SESSION.SQL_LOG_BIN = 0 , usuń tę linię.
SET @@SESSION.SQL_LOG_BIN= 0;
SET @@GLOBAL.GTID_PURGED=/*!80000 '+'*/ '';
SET @@SESSION.SQL_LOG_BIN = @MYSQLDUMP_TEMP_LOG_BIN;
  1. Wystąpił problem z wygenerowanym plikiem Możesz napotkać problem, jeśli wygenerowany plik dump.sql nie jest prawidłowy. Ale tutaj nie będę wyjaśniał, jak wygenerować plik zrzutu. Ale możesz mnie zapytać ( _ )
novice2ninja
źródło
0

Skomentowałem wszystkie linie zaczynające się od SETw *.sqlpliku i zadziałało.

Tengerye
źródło
0

* Odpowiedź może dotyczyć tylko systemu MacOS *

Podczas próby zaimportowania pliku .sql do kontenera Dockera, napotkałem komunikat o błędzie:

Brak dostępu; potrzebujesz (przynajmniej jednego) uprawnień SUPER do tej operacji

Następnie podczas wypróbowywania innych sugestii otrzymałem poniższy błąd na moim MacOS (osx)

sed: błąd RE: niedozwolona sekwencja bajtów

Wreszcie następujące polecenie z tego zasobu rozwiązało mój problem „Odmowa dostępu”.

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

Mogłem więc zaimportować do bazy Dockera za pomocą:

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

Mam nadzieję że to pomoże! :)

Mike Dubs
źródło
0

Należy ustawić parametr serwera „on” „log_bin_trust_function_creators” po stronie serwera. Ten można łatwo znaleźć na lewym ostrzu, jeśli jest lazurowy maria db.

karthik varada
źródło
-1

Komunikat

DEFINER = username@ `%

jest problemem w zrzucie kopii zapasowej.

Rozwiązaniem, które możesz obejść, jest usunięcie całego wpisu z pliku zrzutu sql i zaimportowanie danych z konsoli GCP.

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

Spróbuj zaimportować nowy plik (NEW-CLEANED-DUMP.sql).

Harsh Manvar
źródło