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.

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

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;

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.


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

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

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


2

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


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 ( _ )

0

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


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! :)


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.


-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).

Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.