DETERMINISTIC, NO SQL hoặc READS SQL DATA trong khai báo và ghi nhật ký nhị phân được bật


107

Trong khi nhập cơ sở dữ liệu trong mysql, tôi gặp lỗi sau:

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)

Tôi không biết mình cần thay đổi những thứ nào. Bất kỳ ai có thể giúp tôi làm thế nào để giải quyết điều này?

Câu trả lời:


236

Có hai cách để sửa lỗi này:

  1. Thực thi những điều sau trong bảng điều khiển MySQL:

    SET GLOBAL log_bin_trust_function_creators = 1;

  2. Thêm phần sau vào tệp cấu hình mysql.ini:

    log_bin_trust_function_creators = 1;

Cài đặt này giúp giảm bớt việc kiểm tra các hàm không xác định. Các hàm không xác định là các hàm sửa đổi dữ liệu (nghĩa là có (các) câu lệnh cập nhật, chèn hoặc xóa). Để biết thêm thông tin, hãy xem tại đây .

Xin lưu ý, nếu ghi nhật ký nhị phân KHÔNG được bật, cài đặt này không áp dụng.

Ghi nhật ký nhị phân của các chương trình đã lưu trữ

Nếu ghi nhật ký nhị phân không được bật, log_bin_trust_ Chức năng_creators không được áp dụng.

log_bin_trust_ Chức năng_creators

Biến này áp dụng khi bật ghi nhật ký nhị phân.

Cách tiếp cận tốt nhất là hiểu rõ hơn và sử dụng các khai báo xác định cho các hàm được lưu trữ. Các khai báo này được sử dụng bởi MySQL để tối ưu hóa việc sao chép và việc lựa chọn chúng một cách cẩn thận để có một bản sao lành mạnh là một điều tốt.

XÁC ĐỊNH Một quy trình được coi là “xác định” nếu nó luôn tạo ra cùng một kết quả cho các tham số đầu vào giống nhau và KHÔNG XÁC ĐỊNH nếu không. Điều này chủ yếu được sử dụng với xử lý chuỗi hoặc toán học, nhưng không giới hạn ở đó.

NOT DETERMINISTIC Đối lập với "DETERMINISTIC". " Nếu cả DETERMINISTIC và NOT DETERMINISTIC được đưa ra trong định nghĩa thông thường, thì giá trị mặc định là NOT DETERMINISTIC. Để khai báo rằng một hàm là xác định, bạn phải chỉ định DETERMINISTIC một cách rõ ràng. ". Vì vậy, có vẻ như nếu không có tuyên bố nào được thực hiện, MySQl sẽ coi hàm là "KHÔNG XÁC ĐỊNH". Tuyên bố này từ sách hướng dẫn mâu thuẫn với tuyên bố khác từ một lĩnh vực hướng dẫn khác cho biết rằng: "Khi bạn tạo một hàm được lưu trữ, bạn phải khai báo rằng nó là xác định hoặc nó không sửa đổi dữ liệu. Nếu không, nó có thể không an toàn cho việc khôi phục hoặc sao chép dữ liệu. Theo mặc định, để một câu lệnh CREATE FUNCTION được chấp nhận, ít nhất một trong các DỮ LIỆU SQL DETERMINISTIC, NO SQL hoặc READS phải được chỉ định rõ ràng. Nếu không sẽ xảy ra lỗi "

Cá nhân tôi gặp lỗi trong MySQL 5.5 nếu không có khai báo, vì vậy tôi luôn đặt ít nhất một khai báo "DETERMINISTIC", "NOT DETERMINISTIC", "NO SQL" hoặc "READS SQL DATA" bất kể các khai báo khác mà tôi có thể có.

ĐỌC DỮ LIỆU SQL Điều này nói rõ ràng với MySQL rằng hàm sẽ CHỈ đọc dữ liệu từ cơ sở dữ liệu, do đó, nó không chứa các lệnh sửa đổi dữ liệu, nhưng nó chứa các lệnh SQL đọc dữ liệu (eq SELECT).

MODIFIES SQL DATA Điều này chỉ ra rằng quy trình chứa các câu lệnh có thể ghi dữ liệu (ví dụ: nó chứa các lệnh UPDATE, INSERT, DELETE hoặc ALTER).

KHÔNG SQL Điều này chỉ ra rằng quy trình không chứa câu lệnh SQL.

CHỨA SQL Điều này chỉ ra rằng quy trình chứa các lệnh SQL, nhưng không chứa các câu lệnh đọc hoặc ghi dữ liệu. Đây là mặc định nếu không có đặc điểm nào trong số này được đưa ra rõ ràng. Ví dụ về các câu lệnh như vậy là SELECT NOW (), SELECT 10 + @ b, SET @x = 1 hoặc DO RELEASE_LOCK ('abc'), thực thi nhưng không đọc hoặc ghi dữ liệu.

Lưu ý rằng có các hàm MySQL không an toàn xác định, chẳng hạn như: NOW (), UUID (), v.v., có khả năng tạo ra các kết quả khác nhau trên các máy khác nhau, vì vậy hàm người dùng có chứa các hướng dẫn như vậy phải được khai báo là KHÔNG XÁC ĐỊNH . Ngoài ra, một hàm đọc dữ liệu từ một lược đồ không được giải thích rõ ràng là KHÔNG XÁC ĐỊNH. *

Đánh giá bản chất của một quy trình dựa trên sự “trung thực” của người tạo: MySQL không kiểm tra xem một quy trình được khai báo DETERMINISTIC không có các câu lệnh tạo ra kết quả không xác định. Tuy nhiên, khai báo sai quy trình có thể ảnh hưởng đến kết quả hoặc ảnh hưởng đến hiệu suất. Việc khai báo một quy trình không xác định là DETERMINISTIC có thể dẫn đến kết quả không mong muốn bằng cách khiến trình tối ưu hóa đưa ra các lựa chọn kế hoạch thực thi không chính xác. Việc khai báo một quy trình xác định là NONDETERMINISTIC có thể làm giảm hiệu suất bằng cách khiến các tối ưu hóa có sẵn không được sử dụng.


bạn có thể giải thích cho tôi những gì đã xảy ra trong nền?
ASR

2
Tôi nghi ngờ cơ sở dữ liệu có chức năng sửa đổi dữ liệu (có câu lệnh cập nhật, chèn hoặc xóa trong đó). Để biết thêm thông tin, hãy xem tại đây: dev.mysql.com/doc/refman/5.0/en/stored-programs-logging.html
Donal

1
Bạn nên luôn sao lưu
Donal

nó cần siêu đặc quyền!
Felipe Morales

đã thử điều này nhưng vẫn nhận được vấn đề không xác định, bất kỳ đề xuất nào khác? thanks
Edwin Bermejo

40
  • Khi bạn tạo một hàm được lưu trữ, bạn phải khai báo rằng nó là xác định hoặc nó không sửa đổi dữ liệu. Nếu không, nó có thể không an toàn cho việc khôi phục hoặc sao chép dữ liệu.

  • Theo mặc định, để một câu lệnh CREATE FUNCTION được chấp nhận, ít nhất một trong các DỮ LIỆU SQL DETERMINISTIC, NO SQL hoặc READS phải được chỉ định rõ ràng. Nếu không sẽ xảy ra lỗi:

Để khắc phục sự cố này, hãy thêm các dòng sau câu lệnh After Return và Before Begin:

READS SQL DATA
DETERMINISTIC

Ví dụ :

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

Để biết thêm chi tiết về vấn đề này, vui lòng đọc Tại đây


Điều này hoạt động vì cài đặt READS SQL DATAlà ít hạn chế nhất trong ba. Nếu chức năng của bạn thuộc loại NO SQLhoặc DETERMINISTICloại, bạn có thể cải thiện hiệu suất bằng cách sửa đổi các chức năng của mình. Mặt khác, cài đặt READS SQL DATAnày cũng ít bị lỗi nhất. Vì vậy, nếu bạn sử dụng không chính xác NO SQLhoặc DETERMINISTICbạn có thể nhận được kết quả không chính xác.
Jonathan

@ SunnyS.M, Lời giải thích tuyệt vời giống như ĐỌC DỮ LIỆU SQL. Để khắc phục sự cố này, hãy thêm các dòng sau Câu lệnh After Return và Before Begin:
Md Haidar Ali Khan,

4

theo bình luận của Donald:

Biến này áp dụng khi bật ghi nhật ký nhị phân.

Tất cả những gì tôi phải làm là:

  1. đã tắt log_bin trong my.cnf (#log_bin)
  2. khởi động lại mysql
  3. nhập DB
  4. bật log_bin
  5. khởi động lại mysql

Bước đó giải quyết vấn đề nhập khẩu đó.

(Sau đó, tôi sẽ xem lại mã của lập trình viên để đề xuất cải tiến)


3

Khi hàm của bạn là xác định, bạn có thể an toàn để khai báo nó là hàm xác định. Vị trí của từ khóa "DETERMINISTIC" như sau.

nhập mô tả hình ảnh ở đây


2

Trên Windows 10,

Tôi chỉ giải quyết vấn đề này bằng cách làm như sau.

  1. Goto my.ini và thêm 2 dòng này vào [mysqld]

    skip-log-bin
    log_bin_trust_function_creators = 1
  2. khởi động lại dịch vụ MySQL


sau khi làm điều này, tôi đã nhận lỗi về nô lệ -Got fatal error 1236 from master when reading data from binary log: 'Binary log is not open'
Ramratan Gupta

0

Hãy thử đặt bộ định nghĩa cho chức năng!

Vì vậy, thay vì

CREATE FUNCTION get_pet_owner

bạn sẽ viết một cái gì đó giống với

CREATE DEFINER=procadmin@% FUNCTION get_pet_owner

mà nên làm việc nếu người dùng prodacmin có quyền tạo các hàm / thủ tục.

Trong trường hợp của tôi, hàm hoạt động khi được tạo thông qua MySQL Workbench nhưng không hoạt động khi chạy trực tiếp dưới dạng tập lệnh SQL. Thực hiện các thay đổi ở trên đã khắc phục được sự cố.

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.