DETERMINISTIC ไม่มี SQL หรืออ่านข้อมูล SQL ในการประกาศและเปิดใช้งานการบันทึกไบนารี


109

ขณะนำเข้าฐานข้อมูลใน mysql ฉันพบข้อผิดพลาดต่อไปนี้:

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)

ฉันไม่รู้ว่าจะต้องเปลี่ยนแปลงอะไรบ้าง มีใครช่วยฉันแก้ปัญหานี้ได้ไหม

คำตอบ:


238

มีสองวิธีในการแก้ไขปัญหานี้:

  1. ดำเนินการต่อไปนี้ในคอนโซล MySQL:

    SET GLOBAL log_bin_trust_function_creators = 1;

  2. เพิ่มสิ่งต่อไปนี้ในไฟล์คอนฟิกูเรชัน mysql.ini:

    log_bin_trust_function_creators = 1;

การตั้งค่านี้ช่วยผ่อนคลายการตรวจสอบฟังก์ชันที่ไม่ได้กำหนด ฟังก์ชันที่ไม่ได้กำหนดคือฟังก์ชันที่แก้ไขข้อมูล (เช่นมีคำสั่งอัพเดตแทรกหรือลบ) สำหรับข้อมูลเพิ่มเติมโปรดดูที่นี่

โปรดทราบว่าหากไม่ได้เปิดใช้งานการบันทึกไบนารีการตั้งค่านี้จะใช้ไม่ได้

การบันทึกไบนารีของโปรแกรมที่เก็บไว้

หากไม่ได้เปิดใช้งานการบันทึกไบนารี log_bin_trust_function_creators จะใช้ไม่ได้

log_bin_trust_function_creators

ตัวแปรนี้ใช้เมื่อเปิดใช้งานการบันทึกไบนารี

แนวทางที่ดีที่สุดคือความเข้าใจที่ดีขึ้นและการใช้การประกาศเชิงกำหนดสำหรับฟังก์ชันที่จัดเก็บ การประกาศเหล่านี้ใช้โดย MySQL เพื่อเพิ่มประสิทธิภาพการจำลองแบบและเป็นสิ่งที่ดีที่จะเลือกใช้อย่างระมัดระวังเพื่อให้มีการจำลองแบบที่ดี

DETERMINISTIC รูทีนจะถือว่าเป็น "ดีเทอร์มินิสติก" หากสร้างผลลัพธ์เดียวกันสำหรับพารามิเตอร์อินพุตเดียวกันเสมอและไม่ได้กำหนดไว้เป็นอย่างอื่น ส่วนใหญ่จะใช้กับการประมวลผลสตริงหรือคณิตศาสตร์ แต่ไม่ จำกัด เพียงแค่นั้น

NOT DETERMINISTIC ตรงกันข้ามกับ "DETERMINISTIC" " ถ้าไม่มีทั้ง DETERMINISTIC หรือ NOT DETERMINISTIC ในนิยามรูทีนค่าดีฟอลต์คือ NOT DETERMINISTIC หากต้องการประกาศว่าฟังก์ชันถูกกำหนดคุณต้องระบุ DETERMINISTIC อย่างชัดเจน " ดังนั้นดูเหมือนว่าหากไม่มีการสร้างคำสั่ง MySQl จะถือว่าฟังก์ชันเป็น "NOT DETERMINISTIC" คำสั่งจากคู่มือนี้ขัดแย้งกับคำแถลงอื่น ๆ จากส่วนอื่นของคู่มือซึ่งระบุว่า: "เมื่อคุณสร้างฟังก์ชันที่จัดเก็บคุณต้องประกาศว่าเป็นฟังก์ชันที่กำหนดหรือไม่ได้แก้ไขข้อมูล มิฉะนั้นอาจไม่ปลอดภัยสำหรับการกู้คืนข้อมูลหรือการจำลองแบบ โดยค่าเริ่มต้นสำหรับคำสั่ง CREATE FUNCTION ที่จะยอมรับต้องระบุ DETERMINISTIC, NO SQL หรือ READS SQL อย่างชัดเจนอย่างน้อยหนึ่งรายการ มิฉะนั้นจะเกิดข้อผิดพลาด "

โดยส่วนตัวแล้วฉันพบข้อผิดพลาดใน MySQL 5.5 หากไม่มีการประกาศดังนั้นฉันจึงใส่คำประกาศ "DETERMINISTIC", "NOT DETERMINISTIC", "NO SQL" หรือ "READS SQL DATA" อย่างน้อยหนึ่งรายการเสมอโดยไม่คำนึงถึงการประกาศอื่น ๆ ที่ฉันมี

อ่านข้อมูล SQL สิ่งนี้บอกกับ MySQL อย่างชัดเจนว่าฟังก์ชันนี้จะอ่านข้อมูลจากฐานข้อมูลเท่านั้นดังนั้นจึงไม่มีคำสั่งที่แก้ไขข้อมูล แต่มีคำสั่ง SQL ที่อ่านข้อมูล (eq SELECT)

ปรับเปลี่ยนข้อมูล SQL สิ่งนี้บ่งชี้ว่ารูทีนมีคำสั่งที่อาจเขียนข้อมูล (ตัวอย่างเช่นมีคำสั่ง UPDATE, INSERT, DELETE หรือ ALTER)

ไม่มี SQL สิ่งนี้บ่งชี้ว่ารูทีนไม่มีคำสั่ง SQL

มี SQL สิ่งนี้บ่งชี้ว่ารูทีนมีคำสั่ง SQL แต่ไม่มีคำสั่งที่อ่านหรือเขียนข้อมูล นี่เป็นค่าเริ่มต้นหากไม่มีการระบุลักษณะเหล่านี้อย่างชัดเจน ตัวอย่างของคำสั่งดังกล่าว ได้แก่ SELECT NOW (), SELECT 10 + @ b, SET @x = 1 หรือ DO RELEASE_LOCK ('abc') ซึ่งดำเนินการ แต่ไม่อ่านหรือเขียนข้อมูล

โปรดทราบว่ามีฟังก์ชัน MySQL ที่ไม่สามารถกำหนดได้อย่างปลอดภัยเช่น NOW (), UUID () เป็นต้นซึ่งมีแนวโน้มที่จะให้ผลลัพธ์ที่แตกต่างกันในเครื่องต่าง ๆ ดังนั้นฟังก์ชันผู้ใช้ที่มีคำแนะนำดังกล่าวจะต้องถูกประกาศว่า NOT DETERMINISTIC . นอกจากนี้ฟังก์ชันที่อ่านข้อมูลจากสคีมาที่ไม่ซับซ้อนนั้นชัดเจนว่าเป็น NONDETERMINISTIC *

การประเมินลักษณะของกิจวัตรจะขึ้นอยู่กับ“ ความซื่อสัตย์” ของผู้สร้าง: MySQL ไม่ได้ตรวจสอบว่ากิจวัตรที่ประกาศ DETERMINISTIC นั้นปราศจากข้อความที่ให้ผลลัพธ์ที่ไม่เป็นไปตามเป้าหมาย อย่างไรก็ตามการประกาศกิจวัตรที่ไม่ถูกต้องอาจส่งผลต่อผลลัพธ์หรือส่งผลต่อประสิทธิภาพ การประกาศรูทีนที่ไม่ถูกกำหนดเป็น DETERMINISTIC อาจนำไปสู่ผลลัพธ์ที่ไม่คาดคิดโดยทำให้เครื่องมือเพิ่มประสิทธิภาพตัดสินใจเลือกแผนการดำเนินการที่ไม่ถูกต้อง การประกาศรูทีนดีเทอร์มินิสต์เป็น NONDETERMINISTIC อาจลดประสิทธิภาพลงโดยทำให้ไม่ต้องใช้การเพิ่มประสิทธิภาพที่มีอยู่


คุณช่วยอธิบายฉันได้ไหมว่าเกิดอะไรขึ้นในเบื้องหลัง
ASR

2
ฉันสงสัยว่าฐานข้อมูลมีฟังก์ชันที่ปรับเปลี่ยนข้อมูล (มีคำสั่งอัพเดตแทรกหรือลบอยู่ในนั้น) สำหรับข้อมูลเพิ่มเติมโปรดดูที่นี่: dev.mysql.com/doc/refman/5.0/th/stored-programs-logging.html
Donal

1
คุณควรสำรองข้อมูลเสมอ
Donal

ต้องมีสิทธิพิเศษ!
Felipe Morales

ลองสิ่งนี้แล้วแต่ยังไม่พบปัญหาข้อเสนอแนะอื่นใด ขอบคุณ
Edwin Bermejo

40
  • เมื่อคุณสร้างฟังก์ชันที่จัดเก็บคุณต้องประกาศว่าเป็นฟังก์ชันที่กำหนดหรือไม่ได้แก้ไขข้อมูล มิฉะนั้นอาจไม่ปลอดภัยสำหรับการกู้คืนข้อมูลหรือการจำลองแบบ

  • โดยค่าเริ่มต้นสำหรับคำสั่ง CREATE FUNCTION ที่จะยอมรับต้องระบุ DETERMINISTIC, NO SQL หรือ READS SQL อย่างชัดเจนอย่างน้อยหนึ่งรายการ มิฉะนั้นจะเกิดข้อผิดพลาด:

ในการแก้ไขปัญหานี้ให้เพิ่มบรรทัดต่อไปนี้ After Return และ Before Begin statement:

READS SQL DATA
DETERMINISTIC

ตัวอย่างเช่น :

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

สำหรับรายละเอียดเพิ่มเติมเกี่ยวกับปัญหานี้โปรดอ่านที่นี่


วิธีนี้ได้ผลเนื่องจากการตั้งค่าREADS SQL DATAมีข้อ จำกัด น้อยที่สุดในสามรายการ หากฟังก์ชันของคุณอยู่ในหมวดหมู่NO SQLหรือDETERMINISTICหมวดหมู่คุณสามารถปรับปรุงประสิทธิภาพได้โดยการปรับเปลี่ยนฟังก์ชันของคุณ ในทางกลับกันการตั้งค่าREADS SQL DATAนี้ยังมีโอกาสเกิดข้อผิดพลาดน้อยที่สุด ดังนั้นหากคุณใช้ไม่ถูกต้องNO SQLหรือDETERMINISTICคุณอาจได้ผลลัพธ์ที่ไม่ถูกต้อง
Jonathan

@ SunnyS.M คำอธิบายที่ยอดเยี่ยมเช่นเดียวกับการอ่านข้อมูล SQL DETERMINISTIC ในการแก้ไขปัญหานี้ให้เพิ่มบรรทัดต่อไปนี้ After Return และ Before Begin statement:
Md Haidar Ali Khan

4

ตามความคิดเห็นของโดนัลด์:

ตัวแปรนี้ใช้เมื่อเปิดใช้งานการบันทึกไบนารี

สิ่งที่ฉันต้องทำคือ:

  1. ปิดใช้งาน log_bin ใน my.cnf (#log_bin)
  2. รีสตาร์ท mysql
  3. นำเข้าฐานข้อมูล
  4. เปิดใช้งาน log_bin
  5. รีสตาร์ท mysql

ขั้นตอนนี้จะช่วยแก้ปัญหาการนำเข้า

(จากนั้นฉันจะตรวจสอบโค้ดของโปรแกรมเมอร์เพื่อแนะนำการปรับปรุง)


3

เมื่อฟังก์ชันของคุณถูกกำหนดคุณจะปลอดภัยที่จะประกาศว่าเป็นปัจจัยที่กำหนดได้ ตำแหน่งของคีย์เวิร์ด "DETERMINISTIC" มีดังนี้

ป้อนคำอธิบายภาพที่นี่


2

ใน Windows 10

ฉันเพิ่งแก้ไขปัญหานี้โดยทำดังต่อไปนี้

  1. ไปที่ my.ini และเพิ่ม 2 บรรทัดนี้ภายใต้[mysqld]

    skip-log-bin
    log_bin_trust_function_creators = 1
    
  2. เริ่มบริการ MySQL


หลังจากทำสิ่งนี้ฉันพบข้อผิดพลาดเกี่ยวกับทาส -Got fatal error 1236 from master when reading data from binary log: 'Binary log is not open'
Ramratan Gupta

0

ลองตั้งค่าตัวกำหนดฟังก์ชัน!

ดังนั้นแทนที่จะเป็น

CREATE FUNCTION get_pet_owner

คุณจะเขียนบางอย่างที่คล้ายกับ

CREATE DEFINER=procadmin@% FUNCTION get_pet_owner

ซึ่งควรใช้งานได้หากผู้ใช้prodacminมีสิทธิ์สร้างฟังก์ชัน / โพรซีเดอร์

ในกรณีของฉันฟังก์ชันทำงานเมื่อสร้างผ่าน MySQL Workbench แต่ไม่ทำงานเมื่อเรียกใช้เป็นสคริปต์ SQL โดยตรง การเปลี่ยนแปลงข้างต้นช่วยแก้ปัญหาได้

โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.