Acesso negado; você precisa (pelo menos um dos) privilégios SUPER para esta operação

87

Então eu tento importar o arquivo sql para rds (1G MEM, 1 CPU). O arquivo sql é como 1.4G

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

Ele ficou preso em:

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

O conteúdo real do 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 não existe no rds, então eu faço:

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

Ainda sem sorte.

kenpeter
fonte

Respostas:

166

Remova a DEFINER=..instrução de seu arquivo sqldump ou substitua os valores do usuário por CURRENT_USER.

O servidor MySQL fornecido pelo RDS não permite uma DEFINERsintaxe para outro usuário (em minha experiência).

Você pode usar um sedscript para removê-los do arquivo:

sed 's/\sDEFINER=`[^`]*`@`[^`]*`//g' -i oldfile.sql
hjpotter92
fonte
3
Você está correto. A razão de não funcionar é que especificar outro usuário como DEFINERquando o usuário conectado não tem o SUPERprivilégio (o que não é permitido no RDS) permitiria o escalonamento arbitrário de privilégios - programas armazenados executados com as credenciais e privilégios de seus DEFINER(em oposição aos do usuário que faz a chamada - o deles INVOKER), por padrão. Também em Server Fault .
Michael - sqlbot
Cara, você é um salva-vidas. Minha empresa de hospedagem me disse que o banco de dados estava corrompido quando exportado e nada que pudesse ser feito para restaurar. Solução perfeita.
Woody,
4
Por algum motivo, tive que usar * em vez de +:sed 's/\sDEFINER=`[^`]*`@`[^`]*`//' -i oldfile.sql
Berend de Boer
Obrigado @BerenddeBoer
Awolad Hossain
1
@WonderLand Você pode tentar o awkque pode ser um pouco mais rápido do quesed
hjpotter92
34

Se o seu arquivo de despejo não tiver DEFINER, certifique-se de que essas linhas abaixo também sejam removidas, se estiverem lá, ou comentadas com --:

No começo:

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

No fim:

-- SET @@SESSION.SQL_LOG_BIN = @MYSQLDUMP_TEMP_LOG_BIN;
Jeremy Jones
fonte
12
Você pode evitar isso adicionando --set-gtid-purged=OFFao seu mysqldumpcomando. Encontrado aqui: stackoverflow.com/a/56251925
Illya Moskvin
13

Outro truque útil é invocar o mysqldump com a opção --set-gtid-purged = OFF, que não grava as seguintes linhas no arquivo de saída:

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

não tenho certeza sobre o DEFINER.

quimm2003
fonte
Obrigado! Isso me ajudou no caso de RDS
Victor
Obrigado. No meu caso, executei o SET @@GLOBAL.GTID_MODE = OFF;MySql Workbench no lado de exportação do banco de dados de origem
Byron Wong
8

Apenas uma atualização extra do MacOS para a resposta do hjpotter92.

Para fazer sedreconhecer o padrão no MacOS, você terá que adicionar uma barra invertida antes do =sinal, assim:

sed -i old 's/\DEFINER\=`[^`]*`@`[^`]*`//g' file.sql
marcel
fonte
funciona a partir de 2020, usando MariaDB 10.4 no macOS Catalina
Wayne
4

Problema : você está tentando importar dados (usando o arquivo mysqldump) para seu banco de dados mysql, mas parece que você não tem permissão para realizar essa operação.

Solução : Supondo que seus dados sejam migrados, propagados e atualizados em seu banco de dados mysql, tire um instantâneo usando mysqldump e exporte-o para o arquivo

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

Da documentação do mysql:

GTID - Um identificador de transação global (GTID) é um identificador único criado e associado a cada transação confirmada no servidor de origem (mestre). Esse identificador é exclusivo não apenas para o servidor no qual foi originado, mas é exclusivo em todos os servidores em uma determinada configuração de replicação. Há um mapeamento 1 para 1 entre todas as transações e todos os GTIDs.

--set-gtid-purged = OFF SET @@ GLOBAL.gtid_purged não é adicionado à saída e SET @@ SESSION.sql_log_bin = 0 não é adicionado à saída. Para um servidor onde GTIDs não estão em uso, use esta opção ou AUTO. Use esta opção apenas para um servidor onde GTIDs estão em uso se você tiver certeza de que o conjunto GTID necessário já está presente em gtid_purged no servidor de destino e não deve ser alterado, ou se você planeja identificar e adicionar manualmente quaisquer GTIDs ausentes.

Em seguida, conecte-se ao seu mysql com o usuário root, dê permissões, libere-as e verifique se seus privilégios de usuário foram atualizados corretamente.

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

agora recarregue os dados e a operação deve ser permitida .

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

Para importar arquivo de banco de dados em .sql.gzformato, remova definidor e importe usando o comando abaixo

zcat path_to_db_to_import.sql.gz | sed -e 's/DEFINER[ ]*=[ ]*[^*]*\*/\*/' | mysql -u user -p new_db_name
  1. Anteriormente, exporte o banco de dados no formato .sql.gz usando o comando abaixo.

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

  2. Importe esse banco de dados exportado e remova o definidor usando o comando abaixo,

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

Kazim Noorani
fonte
2

Ao restaurar o backup, certifique-se de tentar com o mesmo nome de usuário do antigo e do novo.

mafei
fonte
2

Solução Completa

Todas as soluções acima estão bem. E aqui vou combinar todas as soluções para que funcione em todas as situações.

  1. DEFINER fixo

Para Linux e Mac

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

Para
baixar o atom ou notepad ++ para Windows , abra seu arquivo dump sql com atom ou notepad ++, pressione Ctrl + F,
pesquise a palavra DEFINER e remova a linha DEFINER = admin@% (ou pode ser um pouco diferente para você) de todos os lugares e salve o arquivo.
Por exemplo,
antes de remover essa linha: CREATE DEFINER = admin@ %PROCEDUREMyProcedure
Depois de remover essa linha: CREATE PROCEDUREMyProcedure

  1. Remova as 3 linhas Remova todas essas 3 linhas do arquivo de despejo. Você pode usar o comando sed ou abrir o arquivo no editor Atom e pesquisar cada linha e, em seguida, remover a linha.
    Exemplo: Abra Dump2020.sql no Atom, pressione ctrl + F, pesquise SET @@ SESSION.SQL_LOG_BIN = 0 , remova essa linha.
SET @@SESSION.SQL_LOG_BIN= 0;
SET @@GLOBAL.GTID_PURGED=/*!80000 '+'*/ '';
SET @@SESSION.SQL_LOG_BIN = @MYSQLDUMP_TEMP_LOG_BIN;
  1. Há um problema com o arquivo gerado. Você pode enfrentar alguns problemas se o arquivo dump.sql gerado não for adequado. Mas aqui, não vou explicar como gerar um arquivo de despejo. Mas você pode me perguntar ( _ )
novice2ninja
fonte
0

Comentei que todas as linhas começam com SETno *.sqlarquivo e funcionou.

Tengerye
fonte
0

* A resposta só pode ser aplicável a MacOS *

Ao tentar importar um arquivo .sql para um contêiner do docker, encontrei a mensagem de erro:

Acesso negado; você precisa (pelo menos um dos) privilégios SUPER para esta operação

Então, enquanto tentava algumas das outras sugestões, recebi o erro abaixo no meu MacOS (osx)

sed: erro RE: sequência de bytes ilegal

Finalmente, o seguinte comando deste recurso resolveu meu problema de "Acesso negado".

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

Então, eu poderia importar para o banco de dados do docker com:

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

Espero que isto ajude! :)

Mike Dubs
fonte
0

É necessário definir o parâmetro "on" do servidor "log_bin_trust_function_creators" no lado do servidor. Este você pode encontrar facilmente na lâmina do lado esquerdo se for azul maria db.

Karthik Varada
fonte
-1

Declaração

DEFINER = username@ `%

é um problema em seu despejo de backup.

A solução que você pode contornar é remover todas as entradas do arquivo sql dump e importar dados do console do GCP.

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

Tente importar um novo arquivo (NEW-CLEANED-DUMP.sql).

Harsh Manvar
fonte