MySQL lưu trữ thông tin người dùng và quyền truy cập trong cơ sở dữ liệu hệ thống mysql. Các bảng chính liên quan bao gồm: user, db, tables_priv, columns_priv, và procs_priv. Trong đó, bảng user là quan trọng nhất vì chứa quyền cấp toàn cục (global privileges), áp dụng cho tất cả cơ sở dữ liệu trên máy chủ (*.*).
Các cấp độ quyền:
- Bảng
user: Quyền toàn cục –*.* - Bảng
db: Quyền theo cơ sở dữ liệu –[dbname].* - Bảng
tables_priv: Quyền theo bảng –[dbname].[table] - Bảng
columns_priv: Quyền theo cột - Bảng
procs_priv: Quyền cho stored procedures/routines
Mỗi tài khoản được xác định duy nhất bởi cặp (user, host). Ví dụ:
mysql> SELECT user, host FROM mysql.user;
+------------------+-----------+
| user | host |
+------------------+-----------+
| mysql.session | localhost |
| mysql.sys | localhost |
| root | localhost |
| test | localhost |
+------------------+-----------+
Để xem quyền của một người dùng cụ thể, sử dụng lệnh:
SHOW GRANTS FOR 'root'@'localhost';
-- Kết quả:
GRANT ALL PRIVILEGES ON *.* TO 'root'@'localhost' WITH GRANT OPTION
SHOW GRANTS FOR 'test'@'localhost';
-- Kết quả:
GRANT USAGE ON *.* TO 'test'@'localhost'
GRANT SELECT ON `test_db`.* TO 'test'@'localhost'
Tạo người dùng mới
MySQL có plugin kiểm tra độ phức tạp mật khẩu. Các tham số liên quan:
validate_password_policy: Mức độ chính sách (LOW, MEDIUM, STRONG)validate_password_length: Độ dài tối thiểuvalidate_password_number_count: Số chữ số tối thiểuvalidate_password_special_char_count: Số ký tự đặc biệt tối thiểuvalidate_password_mixed_case_count: Số chữ hoa/thường tối thiểu
Để tắt kiểm tra mật khẩu (chỉ nên dùng trong môi trường phát triển):
SET GLOBAL validate_password_policy = 0;
FLUSH PRIVILEGES;
Lệnh tạo người dùng:
CREATE USER 't1'@'localhost' IDENTIFIED BY '12345678';
FLUSH PRIVILEGES;
Sau khi tạo, người dùng chỉ có quyền USAGE (không có quyền thực thi gì ngoài kết nối).
Cấp quyền và quản lý mật khẩu
Lệnh GRANT có thể đồng thời tạo người dùng, cấp quyền và đặt mật khẩu:
-- Cấp quyền cho người dùng đã tồn tại (giữ nguyên mật khẩu)
GRANT ALL PRIVILEGES ON test.* TO 't1'@'localhost';
-- Cấp quyền và đổi mật khẩu
GRANT SELECT ON mysql.* TO 't1'@'localhost' IDENTIFIED BY 'abcdefgh';
-- Tạo người dùng mới + cấp quyền
GRANT ALL ON test_db.* TO 't2'@'localhost' IDENTIFIED BY '12345678';
Sau mỗi thao tác, luôn chạy FLUSH PRIVILEGES; để áp dụng thay đổi.
Đổi mật khẩu sau khi đăng nhập
Sử dụng một trong hai lệnh sau:
ALTER USER 't1'@'localhost' IDENTIFIED BY 'mymypass';
-- hoặc
SET PASSWORD FOR 't1'@'localhost' = PASSWORD('mymypass');
FLUSH PRIVILEGES;
Thu hồi quyền
Lệnh REVOKE có cú pháp tương tự GRANT:
REVOKE SELECT ON mysql.* FROM 't1'@'localhost';
FLUSH PRIVILEGES;
Xóa người dùng
Nên dùng lệnh DROP USER thay vì xóa trực tiếp từ bảng mysql.user để tránh dữ liệu rác:
-- KHÔNG KHUYẾN KHÍCH
DELETE FROM mysql.user WHERE user='t1' AND host='localhost';
-- KHUYẾN KHÍCH
DROP USER 't2'@'localhost';
FLUSH PRIVILEGES;
Lệnh DROP USER tự động dọn sạch quyền trong các bảng như db, tables_priv, v.v.
Khôi phục mật khẩu root khi quên
Bước 1: Sửa file cấu hình /etc/my.cnf (hoặc my.ini trên Windows), thêm vào phần [mysqld]:
skip-grant-tables
Bước 2: Khởi động lại dịch vụ MySQL.
Bước 3: Đăng nhập mà không cần mật khẩu và cập nhật:
mysql
UPDATE mysql.user SET authentication_string = PASSWORD('newpass') WHERE user = 'root';
FLUSH PRIVILEGES;
Bước 4: Xóa dòng skip-grant-tables và khởi động lại MySQL.