Cách sửa lỗi 'The MySQL server is running with the --secure-file-priv option' trong MySQL

intermediate🗄️ MySQL2026-05-28| MySQL 5.7+, MySQL 8.0+, Ubuntu/Debian, CentOS, Windows Server

Error Message

ERROR 1290 (HY000): The MySQL server is running with the --secure-file-priv option so it cannot execute this statement
#mysql#nhập dữ liệu#xuất dữ liệu#secure-file-priv#load-data

Bối cảnhTôi đang thực hiện một tác vụ di chuyển dữ liệu, trong đó tôi cần xuất một bảng lớn sang tệp CSV cho một công cụ báo cáo. Tôi đã chạy lệnh tiêu chuẩn SELECT ... INTO OUTFILE, mong đợi kết quả nhanh chóng. Thay vào đó, MySQL đã chặn tôi ngay lập tức với một lỗi bảo mật. Điều này cũng thường xuyên xảy ra khi cố gắng tải dữ liệu hàng loạt bằng lệnh LOAD DATA INFILE.

mysql> SELECT * FROM orders INTO OUTFILE '/tmp/orders_dump.csv';
ERROR 1290 (HY000): The MySQL server is running with the --secure-file-priv option so it cannot execute this statement

Lỗi này là một tính năng bảo mật, không phải là lỗi chương trình. MySQL sử dụng biến secure-file-priv để giới hạn nơi máy chủ có thể đọc hoặc ghi tệp. Điều này ngăn chặn kẻ tấn công khi có được quyền truy cập SQL injection có thể đọc các tệp hệ thống nhạy cảm (như /etc/passwd) hoặc ghi các mã độc vào thư mục gốc của trang web (web root).

Quá trình gỡ lỗi (Debug)Điều đầu tiên cần làm là tìm hiểu chính xác cách máy chủ đang bị hạn chế. Bạn có thể kiểm tra giá trị hiện tại của biến secure_file_priv trực tiếp từ MySQL shell:

mysql> SHOW VARIABLES LIKE "secure_file_priv";
+------------------+-----------------------+
| Variable_name    | Value                 |
+------------------+-----------------------+
| secure_file_priv | /var/lib/mysql-files/ |
+------------------+-----------------------+
1 row in set (0.01 sec)

Giải thích kết quả- Một đường dẫn cụ thể (ví dụ: /var/lib/mysql-files/): Máy chủ sẽ chỉ cho phép các hoạt động nhập/xuất trong thư mục cụ thể này.- NULL: Máy chủ đã vô hiệu hóa tất cả các hoạt động nhập và xuất. Điều này thường là mặc định trong các bản cài đặt MySQL mới hơn.- Giá trị trống (""): Không có hạn chế nào. Điều này không an toàn nhưng cho phép bạn đọc/ghi ở bất cứ đâu mà người dùng mysql có quyền ở cấp độ hệ điều hành (OS).## Giải pháp### Cách 1: Sử dụng thư mục được phép (Khuyên dùng)Nếu biến được đặt thành một đường dẫn cụ thể, cách khắc phục dễ dàng và an toàn nhất là chỉ cần di chuyển tệp của bạn vào đó. Thay vì cố gắng ghi vào /tmp/, hãy sử dụng thư mục an toàn đã được chỉ định.

-- Câu lệnh này sẽ hoạt động nếu secure_file_priv là /var/lib/mysql-files/
SELECT * FROM orders 
INTO OUTFILE '/var/lib/mysql-files/orders_dump.csv'
FIELDS TERMINATED BY ',' 
ENCLOSED BY '"' 
LINES TERMINATED BY '\n';

Sau khi xuất dữ liệu, bạn có thể di chuyển tệp từ thư mục đó đến đích mong muốn bằng dòng lệnh.

Cách 2: Thay đổi cấu hình (Khắc phục vĩnh viễn)Nếu bạn cần xuất tệp sang một vị trí khác hoặc nếu giá trị hiện tại là NULL, bạn phải sửa đổi tệp cấu hình MySQL.

Trên Linux (Ubuntu/Debian/CentOS)1. Mở tệp cấu hình MySQL của bạn (thường là my.cnf hoặc mysqld.cnf):

sudo nano /etc/mysql/mysql.conf.d/mysqld.cnf
# hoặc
sudo nano /etc/my.cnf
  1. Tìm mục [mysqld] và tìm dòng secure-file-priv. Nếu nó không tồn tại, hãy thêm nó vào. Để vô hiệu hóa hoàn toàn hạn chế, hãy đặt nó thành một chuỗi trống:
[mysqld]
secure-file-priv = ""
  1. Lưu tệp và khởi động lại dịch vụ MySQL:
sudo systemctl restart mysql

Trên Windows1. Xác định vị trí tệp my.ini của bạn (thường ở C:\ProgramData\MySQL\MySQL Server X.X\). Lưu ý rằng ProgramData là một thư mục ẩn.

  1. Tìm dòng secure-file-priv và thay đổi nó:
secure-file-priv=""
  1. Khởi động lại dịch vụ MySQL bằng services.msc.

Cách 3: Xử lý với AppArmor (Dành riêng cho Ubuntu)Ngay cả khi bạn đã đặt secure-file-priv = "", mô-đun bảo mật AppArmor của Ubuntu vẫn có thể chặn hoạt động ghi vào một số thư mục nhất định. Nếu bạn thấy lỗi "Permission denied" mặc dù đã thay đổi cấu hình, bạn cần chỉnh sửa profile AppArmor.

sudo nano /etc/apparmor.d/usr.sbin.mysqld

Thêm các đường dẫn bạn muốn cho phép (ví dụ: /data/):

/data/ r,
/data/** rw,

Sau đó tải lại AppArmor:

sudo systemctl reload apparmor

Các bước xác minhĐể xác nhận việc sửa lỗi đã hoạt động, hãy đăng nhập lại vào MySQL và kiểm tra lại biến:

mysql> SHOW VARIABLES LIKE "secure_file_priv";
+------------------+-------+
| Variable_name    | Value |
+------------------+-------+
| secure_file_priv |       |
+------------------+-------+

Nếu giá trị trống, hãy thử một lệnh xuất kiểm tra nhỏ:

mysql> SELECT 1 INTO OUTFILE '/tmp/test_write.txt';
Query OK, 1 row affected (0.00 sec)

Nếu tệp được tạo thành công trong /tmp/, vấn đề đã được giải quyết.

Bài học kinh nghiệm- Giá trị mặc định rất quan trọng: Các phiên bản MySQL hiện đại ưu tiên bảo mật ngay khi cài đặt. Biết rằng NULL có nghĩa là "vô hiệu hóa" sẽ giúp tiết kiệm nhiều thời gian tìm hiểu.- Bảo mật so với Sự thuận tiện: Mặc dù việc đặt biến thành "" là dễ dàng, nhưng cách tốt nhất là duy trì một thư mục riêng biệt cho việc nhập/xuất cơ sở dữ liệu và chỉ cấp quyền sở hữu thư mục đó cho người dùng mysql.- Bảo mật đa lớp: Trên Linux, quyền của MySQL chỉ là một lớp. AppArmor hoặc SELinux có thể chặn các hoạt động tệp ngay cả khi cấu hình cơ sở dữ liệu cho phép. Luôn kiểm tra nhật ký hệ thống (/var/log/syslog hoặc journalctl) nếu bạn nhận được lỗi "Permission denied" sau khi thay đổi cài đặt MySQL.

Related Error Notes