DETERMINISTIC, NO SQL veya READS SQL DATA bildiriminde ve ikili günlük kaydı etkinleştirildi


109

Veritabanını mysql'de içe aktarırken aşağıdaki hatayı aldım:

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)

Hangi şeyleri değiştirmem gerektiğini bilmiyorum. Herhangi biri bunu nasıl çözeceğime yardım edebilir mi?

Yanıtlar:


238

Bunu düzeltmenin iki yolu vardır:

  1. MySQL konsolunda aşağıdakileri yürütün:

    SET GLOBAL log_bin_trust_function_creators = 1;

  2. Aşağıdakileri mysql.ini yapılandırma dosyasına ekleyin:

    log_bin_trust_function_creators = 1;

Ayar, deterministik olmayan fonksiyonların kontrolünü rahatlatır. Belirleyici olmayan işlevler, verileri değiştiren işlevlerdir (örn. Güncelleme, ekleme veya silme ifadeleri). Daha fazla bilgi için buraya bakın .

İkili günlük kaydı ETKİN DEĞİLSE, bu ayarın geçerli olmadığını lütfen unutmayın.

Depolanan Programların İkili Günlüğü

İkili günlük kaydı etkinleştirilmezse, log_bin_trust_function_creators uygulanmaz.

log_bin_trust_function_creators

Bu değişken, ikili günlük kaydı etkinleştirildiğinde geçerlidir.

En iyi yaklaşım, depolanan işlevler için deterministik bildirimlerin daha iyi anlaşılması ve kullanılmasıdır. Bu bildirimler MySQL tarafından çoğaltmayı optimize etmek için kullanılır ve sağlıklı bir çoğaltmaya sahip olmak için bunları dikkatlice seçmek iyi bir şeydir.

BELİRLEYİCİ Bir rutin, aynı girdi parametreleri için her zaman aynı sonucu üretiyorsa ve aksi takdirde BELİRLİ DEĞİLSE "deterministik" olarak kabul edilir. Bu çoğunlukla dizi veya matematik işlemede kullanılır, ancak bununla sınırlı değildir.

BELİRLEYİCİ DEĞİL "BELİRLEYİCİ" nin Tersi " Rutin tanımda ne DETERMINISTIC ne de DETERMINISTIC belirtilmemişse, varsayılan BELİRLEYİCİ DEĞİLDİR. Bir fonksiyonun deterministik olduğunu bildirmek için, BELİRLEYİCİ'yi açıkça belirtmelisiniz. " Öyle görünüyor ki, herhangi bir açıklama yapılmazsa, MySQl işlevi "BELİRLEYİCİ DEĞİL" olarak değerlendirecektir. Kılavuzdaki bu ifade, kılavuzun başka bir alanındaki diğer ifadelerle çelişmektedir ve şunu söyler: "Depolanan bir işlev oluşturduğunuzda, bunun deterministik olduğunu veya verileri değiştirmediğini beyan etmeniz gerekir. Aksi takdirde, veri kurtarma veya çoğaltma için güvenli olmayabilir. Varsayılan olarak, bir CREATE FUNCTION ifadesinin kabul edilmesi için, DETERMINISTIC, NO SQL veya READS SQL DATA'dan en az birinin açıkça belirtilmesi gerekir. Aksi takdirde bir hata oluşur "

Herhangi bir bildirim yoksa kişisel olarak MySQL 5.5'te hata aldım, bu yüzden sahip olabileceğim diğer bildirimler ne olursa olsun her zaman en az bir "DETERMINISTIC", "NOT DETERMINISTIC", "NO SQL" veya "READS SQL DATA" bildirimi koyarım.

SQL VERİLERİNİ OKUYOR Bu, MySQL'e fonksiyonun YALNIZCA veritabanlarından veri okuyacağını, dolayısıyla verileri değiştiren komutlar içermediğini, ancak verileri okuyan SQL komutlarını (eq SELECT) içerdiğini açıkça söyler.

MODIFIES SQL DATA Bu, rutinin veri yazabilen ifadeler içerdiğini gösterir (örneğin, UPDATE, INSERT, DELETE veya ALTER komutları içerir).

NO SQL Bu, rutinin hiçbir SQL ifadesi içermediğini gösterir.

CONTAINS SQL Bu, rutinin SQL komutları içerdiğini ancak veri okuyan veya yazan ifadeler içermediğini gösterir. Bu özelliklerden hiçbiri açıkça belirtilmemişse bu varsayılandır. Bu tür ifadelere örnek olarak SELECT NOW (), SELECT 10 + @ b, SET @x = 1 veya DO RELEASE_LOCK ('abc') verilebilir, bunlar çalıştırılır, ancak ne veri okunur ne de yazılır.

Farklı makinelerde farklı sonuçlar üretmesi muhtemel olan NOW (), UUID (), vb. Gibi deterministik güvenli olmayan MySQL fonksiyonları vardır, bu nedenle bu tür talimatları içeren bir kullanıcı fonksiyonunun BELİRLİ DEĞİL olarak bildirilmesi gerekir. . Ayrıca, kopyalanmamış bir şemadan veri okuyan bir işlev açıkça BELİRSİZDİR. *

Bir rutinin doğasının değerlendirilmesi, yaratıcının "dürüstlüğüne" dayanır: MySQL, ilan edilmiş bir DETERMINISTIC rutininin belirleyici olmayan sonuçlar üreten ifadelerden muaf olup olmadığını kontrol etmez. Ancak, bir rutinin yanlış beyan edilmesi sonuçları etkileyebilir veya performansı etkileyebilir. Belirsiz bir rutinin BELİRLEYİCİ olarak bildirilmesi, optimize edicinin yanlış yürütme planı seçimleri yapmasına neden olarak beklenmedik sonuçlara yol açabilir. Belirleyici bir rutini NONDETERMINISTIC olarak ilan etmek, mevcut optimizasyonların kullanılmamasına neden olarak performansı düşürebilir.


bana arka planda ne olduğunu açıklayabilir misin?
ASR

2
Veritabanının verileri değiştiren bir işlevi olduğundan şüpheleniyorum (içinde güncelleme, ekleme veya silme ifadesi vardır). Daha fazla bilgi için buraya bakın: dev.mysql.com/doc/refman/5.0/en/stored-programs-logging.html
Donal

1
Her zaman yedek almalısınız
Donal

süper ayrıcalıklara ihtiyacı var!
Felipe Morales

bunu denediniz ama yine de deterministik olmayan problem var mı? teşekkürler
Edwin Bermejo

40
  • Depolanan bir işlev oluşturduğunuzda, bunun deterministik olduğunu veya verileri değiştirmediğini beyan etmeniz gerekir. Aksi takdirde, veri kurtarma veya çoğaltma için güvenli olmayabilir.

  • Varsayılan olarak, bir CREATE FUNCTION ifadesinin kabul edilmesi için, DETERMINISTIC, NO SQL veya READS SQL DATA'dan en az birinin açıkça belirtilmesi gerekir. Aksi takdirde bir hata oluşur:

Bu sorunu çözmek için After Return ve Before Begin ifadesini aşağıdaki satırları ekleyin:

READS SQL DATA
DETERMINISTIC

Örneğin :

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

Bu sorun hakkında daha fazla ayrıntı için lütfen okuyun Burada


Bu işe yarar çünkü ayar READS SQL DATA, üçü arasında en az kısıtlayıcıdır. İşleviniz NO SQLveya DETERMINISTICkategorisine girerse, işlevlerinizi değiştirerek performansı artırabilirsiniz. Öte yandan, ayar READS SQL DATAaynı zamanda hataya en az eğilimlidir. Yani yanlış kullanırsanız NO SQLveya DETERMINISTICyanlış sonuçlar alabilirsiniz.
Jonathan

@ SunnyS.M, READS SQL DATA DETERMINISTIC gibi harika bir açıklama.Bu sorunu düzeltmek için aşağıdaki satırları Ekledikten Sonra ve Başlamadan Önce ifadesini ekleyin:
Md Haidar Ali Khan

4

Donald'ın yorumunu takiben:

Bu değişken, ikili günlük kaydı etkinleştirildiğinde geçerlidir.

Tek yapmam gereken:

  1. my.cnf'de devre dışı bırakılmış log_bin (#log_bin)
  2. mysql'i yeniden başlat
  3. DB'yi içe aktar
  4. log_bin'i etkinleştir
  5. mysql'i yeniden başlat

Bu ithalat sorununu çözer.

(Sonra bir iyileştirme önermek için programcının kodunu gözden geçireceğim)


3

İşleviniz deterministik olduğunda, onun deterministik olduğunu beyan etmeniz güvenlidir. "DETERMINISTIC" anahtar kelimesinin yeri aşağıdaki gibidir.

görüntü açıklamasını buraya girin


2

Windows 10'da,

Aşağıdakileri yaparak bu sorunu çözdüm.

  1. My.ini'ye gidin ve bu 2 satırı [mysqld] altına ekleyin

    skip-log-bin
    log_bin_trust_function_creators = 1
  2. MySQL hizmetini yeniden başlat


bunu yaptıktan sonra köle konusunda hata aldım -Got fatal error 1236 from master when reading data from binary log: 'Binary log is not open'
Ramratan Gupta

0

İşlev için tanımlayıcıyı ayarlamayı deneyin!

Yani yerine

CREATE FUNCTION get_pet_owner

benzer bir şey yazacaksın

CREATE DEFINER=procadmin@% FUNCTION get_pet_owner

kullanıcı prodacmin ise hangisinin çalışması gerekir işlevler / prosedürler oluşturma hakları .

Benim durumumda, işlev MySQL Workbench aracılığıyla oluşturulduğunda çalıştı, ancak doğrudan bir SQL betiği olarak çalıştırıldığında çalışmadı. Yukarıdaki değişiklikleri yapmak sorunu çözdü.

Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.