DETERMINISTIC, NO SQL ou READS SQL DATA em sua declaração e o registro binário está habilitado

107

Ao importar o banco de dados no mysql, recebi o seguinte erro:

1418 (HY000) at line 10185: This function has none of DETERMINISTIC, NO SQL, or READS SQL DATA in its declaration and binary logging is enabled (you *might* want to use the less safe log_bin_trust_function_creators variable)

Não sei o que preciso mudar. Alguém pode me ajudar a resolver isso?

ASR
fonte

Respostas:

236

Existem duas maneiras de corrigir isso:

  1. Execute o seguinte no console MySQL:

    SET GLOBAL log_bin_trust_function_creators = 1;

  2. Adicione o seguinte ao arquivo de configuração mysql.ini:

    log_bin_trust_function_creators = 1;

A configuração relaxa a verificação de funções não determinísticas. Funções não determinísticas são funções que modificam dados (isto é, atualizar, inserir ou deletar instrução (ões)). Para mais informações, veja aqui .

Observe que, se o log binário NÃO estiver habilitado, esta configuração não se aplica.

Registro Binário de Programas Armazenados

Se o log binário não estiver habilitado, log_bin_trust_function_creators não se aplica.

log_bin_trust_function_creators

Esta variável se aplica quando o log binário está habilitado.

A melhor abordagem é um melhor entendimento e uso de declarações determinísticas para funções armazenadas. Essas declarações são usadas pelo MySQL para otimizar a replicação e é bom escolhê-las com cuidado para ter uma replicação saudável.

DETERMINISTICO Uma rotina é considerada “determinística” se sempre produzir o mesmo resultado para os mesmos parâmetros de entrada e NÃO DETERMINÍSTICA caso contrário. Isso é usado principalmente com processamento de string ou matemático, mas não se limita a isso.

NÃO DETERMINISTICO Oposto de "DETERMINISTAS". " Se nem DETERMINISTIC nem NOT DETERMINISTIC forem fornecidos na definição da rotina, o padrão é NOT DETERMINISTIC. Para declarar que uma função é determinística, você deve especificar DETERMINISTIC explicitamente. ". Portanto, parece que, se nenhuma declaração for feita, o MySQL tratará a função como "NÃO DETERMINISTICA". Esta declaração do manual está em contradição com outra declaração de outra área do manual que diz que: "Ao criar uma função armazenada, você deve declarar que ela é determinística ou que não modifica os dados. Caso contrário, pode não ser seguro para recuperação ou replicação de dados. Por padrão, para que uma instrução CREATE FUNCTION seja aceita, pelo menos um DETERMINISTIC, NO SQL ou READS SQL DATA deve ser especificado explicitamente. Caso contrário, ocorre um erro "

Eu pessoalmente recebi um erro no MySQL 5.5 se não houver nenhuma declaração, então eu sempre coloco pelo menos uma declaração de "DETERMINISTIC", "NOT DETERMINISTIC", "NO SQL" ou "READS SQL DATA" independente de outras declarações que eu possa ter.

READS SQL DATA Isto diz explicitamente ao MySQL que a função irá SOMENTE ler dados de bancos de dados, portanto, não contém instruções que modificam os dados, mas contém instruções SQL que lêem os dados (eq SELECT).

MODIFIES SQL DATA Indica que a rotina contém instruções que podem escrever dados (por exemplo, contém instruções UPDATE, INSERT, DELETE ou ALTER).

NO SQL Isso indica que a rotina não contém instruções SQL.

CONTAINS SQL Isso indica que a rotina contém instruções SQL, mas não contém instruções que leem ou gravem dados. Este é o padrão se nenhuma dessas características for fornecida explicitamente. Exemplos de tais instruções são SELECT NOW (), SELECT 10 + @ b, SET @x = 1 ou DO RELEASE_LOCK ('abc'), que executam, mas não lêem nem gravam dados.

Observe que há funções do MySQL que não são deterministicamente seguras, como: NOW (), UUID (), etc, que provavelmente produzirão resultados diferentes em máquinas diferentes, portanto, uma função de usuário que contém tais instruções deve ser declarada como NOT DETERMINISTIC . Além disso, uma função que lê dados de um esquema não replicado é claramente NONDETERMINISTIC. *

A avaliação da natureza de uma rotina é baseada na “honestidade” do criador: o MySQL não verifica se uma rotina declarada DETERMINISTICA está livre de declarações que produzem resultados não determinísticos. No entanto, declarar incorretamente uma rotina pode afetar os resultados ou afetar o desempenho. Declarar uma rotina não determinística como DETERMINISTIC pode levar a resultados inesperados, fazendo com que o otimizador faça escolhas incorretas de plano de execução. Declarar uma rotina determinística como NONDETERMINISTIC pode diminuir o desempenho, fazendo com que as otimizações disponíveis não sejam usadas.

Donal
fonte
você pode me explicar o que aconteceu no fundo?
ASR
2
Suspeito que o banco de dados tenha uma função que modifica os dados (contém uma instrução de atualização, inserção ou exclusão). Para mais informações, consulte aqui: dev.mysql.com/doc/refman/5.0/en/stored-programs-logging.html
Donal
1
Você deve sempre fazer backups
Donal
ele precisa de superprivilégios!
Felipe Morales
tentei fazer isso, mas ainda tenho o problema não determinístico, alguma outra sugestão? obrigado
Edwin Bermejo
40
  • Ao criar uma função armazenada, você deve declarar que ela é determinística ou que não modifica os dados. Caso contrário, pode não ser seguro para recuperação ou replicação de dados.

  • Por padrão, para que uma instrução CREATE FUNCTION seja aceita, pelo menos um DETERMINISTIC, NO SQL ou READS SQL DATA deve ser especificado explicitamente. Caso contrário, ocorre um erro:

Para corrigir esse problema, adicione as seguintes linhas após a declaração de retorno e antes de começar:

READS SQL DATA
DETERMINISTIC

Por exemplo :

CREATE FUNCTION f2()
RETURNS CHAR(36) CHARACTER SET utf8
/*ADD HERE */
READS SQL DATA
DETERMINISTIC
BEGIN

Para obter mais detalhes sobre este problema, leia aqui

Sunny SM
fonte
Isso funciona porque a configuração READS SQL DATAé a menos restritiva dos três. Se sua função se enquadrar na categoria NO SQLou DETERMINISTIC, você pode melhorar o desempenho modificando suas funções. Por outro lado, a configuração READS SQL DATAtambém é a menos sujeita a erros. Portanto, se você usar incorretamente NO SQLou DETERMINISTICpoderá obter resultados incorretos.
Jonathan
@ SunnyS.M, Explicação incrível como READS SQL DATA DETERMINISTIC.Para corrigir este problema, adicione as seguintes linhas declaração After Return e Before Begin:
Md Haidar Ali Khan
4

seguindo o comentário de Donald:

Esta variável se aplica quando o log binário está habilitado.

Tudo que eu tive que fazer foi:

  1. log_bin desativado em my.cnf (#log_bin)
  2. reinicie o mysql
  3. import DB
  4. habilitar log_bin
  5. reinicie o mysql

Esse passo para fora desse problema de importação.

(Em seguida, revisarei o código do programador para sugerir uma melhoria)

Mayra Navarro
fonte
3

Quando sua função é determinística, você pode declará-la com segurança como determinística. A localização da palavra-chave "DETERMINISTIC" é a seguinte.

insira a descrição da imagem aqui

Park JongBum
fonte
2

No Windows 10,

Acabei de resolver esse problema fazendo o seguinte.

  1. Vá para my.ini e adicione essas 2 linhas em [mysqld]

    skip-log-bin
    log_bin_trust_function_creators = 1
  2. reinicie o serviço MySQL

Preetham
fonte
depois de fazer isso, recebi um erro no escravo -Got fatal error 1236 from master when reading data from binary log: 'Binary log is not open'
Ramratan Gupta
0

Experimente definir o definidor para a função!

Então, em vez de

CREATE FUNCTION get_pet_owner

você vai escrever algo semelhante a

CREATE DEFINER=procadmin@% FUNCTION get_pet_owner

que deve funcionar se o usuário prodacmin tiver direitos para criar funções / procedimentos.

No meu caso, a função funcionou quando gerada através do MySQL Workbench, mas não funcionou quando executada diretamente como um script SQL. Fazer as alterações acima corrigiu o problema.

DevKingKev
fonte