Sửa lỗi Duplicate entry ‘0’ for key ‘PRIMARY’ for query INSERT INTO `wp_usermeta`
Sơ đồ trang
Dạo này mình gặp khá nhiều trường hợp khách hàng mới gửi yêu cầu sửa lỗi website không thể cập nhật dữ liêu, cụ thể nhập data, content vào nhưng khi nhấn lưu hoặc đăng đều không lưu được giá trị, khi mình tiếp nhận website và bật debug lên thì gặp phải thông báo lỗi WordPress database error Duplicate entry '0' for key 'PRIMARY' for query INSERT INTO wp_usermeta (user_id, meta_key, meta_value) VALUES (1, 'primary_blog', '1') made by require_once('wp-admin/network/admin.php'), require_once('wp-admin/admin.php'), do_action('admin_init'), WP_Hook->do_action, WP_Hook->apply_filters, _wp_admin_bar_init, WP_Admin_Bar->initialize, get_active_blog_for_user, update_user_meta, update_metadata, add_metadata
Sửa lỗi Duplicate entry ‘0’ for key ‘PRIMARY’
Nếu bạn cũng phải lỗi sau thì có thể sử lỗi này bằng cách rất đơn giản như sau.
1. Login vào phpMyAdmin
2. Vào bảng dữ liệu được thông báo lỗi cụ thể thông báo lỗi như ở trên bạn hãy vào table wp_usermeta
(Tùy vào lỗi ở bảng nào thì bạn hãy click vào bảng đấy nhé)
3. Nhấn vào Structure > Change
4. Chọn vào AI như hình dưới
5. Tiếp theo bạn nhấn Save lại là fix được thôi.
Lỗi trên đơn giản là ID bị trùng lặp khi không được tự đăng tăng lên AI = Auto increment nên bạn chỉ cần chọn vào AI là ID sẽ tự động tăng lên khi bạn thêm dữ liệu mới vào cơ sở dữ liệu.
Ngoải lỗi này thì có thể bạn sẽ gặp phải lỗi Missing Unique Column and Primary Key thì có thể fix như sau:
Sử dụng wp cli để check xem key nào bị thiếu
wp db query "DESCRIBE $(wp db prefix --allow-root)options" --allow-root
Kết quả đầu ra cho thấy rằng không có khóa chính (the option_id) và không có ràng buộc nào được áp đặt cho cột option_name
+--------------+---------------------+------+-----+---------+-------+ | Field | Type | Null | Key | Default | Extra | +--------------+---------------------+------+-----+---------+-------+ | option_id | bigint(20) unsigned | NO | | NULL | | | option_name | varchar(191) | YES | | NULL | | | option_value | longtext | NO | | NULL | | | autoload | varchar(20) | NO | | yes | | +--------------+---------------------+------+-----+---------+-------+
Một bảng wp_options
đúng sẽ như thế này với PRIMARY key (PRI) và UNIQUE constraint (UNI)
+--------------+---------------------+------+-----+---------+----------------+ | Field | Type | Null | Key | Default | Extra | +--------------+---------------------+------+-----+---------+----------------+ | option_id | bigint(20) unsigned | NO | PRI | NULL | auto_increment | | option_name | varchar(191) | YES | UNI | | | | option_value | longtext | NO | | NULL | | | autoload | varchar(20) | NO | | yes | | +--------------+---------------------+------+-----+---------+----------------+
Fix wp_options Missing Primary Key
Để đặt cột option_id
làm khóa chính, bạn có thể chạy truy vấn này
wp db query "ALTER TABLE $(wp db prefix --allow-root)options MODIFY option_id INT AUTO_INCREMENT PRIMARY KEY;" --allow-root
Giờ bạn có thể check lại
wp db query "DESCRIBE $(wp db prefix --allow-root)options" --allow-root
+--------------+--------------+------+-----+---------+----------------+ | Field | Type | Null | Key | Default | Extra | +--------------+--------------+------+-----+---------+----------------+ | option_id | int(11) | NO | PRI | NULL | auto_increment | | option_name | varchar(191) | YES | | NULL | | | option_value | longtext | NO | | NULL | | | autoload | varchar(20) | NO | | yes | | +--------------+--------------+------+-----+---------+----------------+
Fix wp_options Missing Unique Column
Truy vấn này sẽ cố gắng thêm ràng buộc UNIQUE
trên cột option_name
wp db query "ALTER TABLE $(wp db prefix --allow-root)options ADD UNIQUE (option_name);" --allow-root
Nếu bạn gặp lỗi ERROR 1062 (23000)
ở dòng 1: Mục nhập trùng lặp ‘jetpack_available_modules
‘ cho khóa ‘option_name’ sau đó có một số giá trị option_name trùng lặp, bạn có thể xem chúng bằng truy vấn này
wp db query "SELECT option_name, COUNT(*) optioncount FROM $(wp db prefix --allow-root)options GROUP BY option_name HAVING optioncount > 1 ORDER BY optioncount DESC;" --allow-root
Theo thứ tự tăng dần ở đây là tất cả các bản sao, chúng tôi sẽ tự động xóa chúng
Việc tự động loại bỏ các giá trị trùng lặp trong bảng option_name
có thể được thực hiện theo hai cách: sử dụng giá trị option_id
cũ nhất (số nhỏ nhất) hoặc giá trị option_id
mới nhất (số lớn nhất).
Giữ tùy chọn option_name trùng lặp cũ nhất
Truy vấn SQL này hiển thị cho bạn tất cả ngoại trừ các hàng cũ nhất (MIN) option_id đối với mọi giá trị option_name trùng lặp
SELECT * FROM wp options WHERE option_id NOT IN (SELECT * FROM (SELECT MIN(n.option_id) FROM wp_options n GROUP BY n.option_name) x)
Truy vấn SQL này giữ lại option_id (MIN) cũ nhất cho mọi giá trị option_name trùng lặp và xóa tất cả các hàng trùng lặp mới hơn
DELETE FROM wp options WHERE option_id NOT IN (SELECT * FROM (SELECT MIN(n.option_id) FROM wp_options n GROUP BY n.option_name) x)
Đây là một lớp lót để sử dụng với lệnh truy vấn wp db của WP-CLI để giữ lại option_name trùng lặp cũ nhất
wp db query "DELETE FROM $(wp db prefix --allow-root)options WHERE option_id NOT IN (SELECT * FROM (SELECT MIN(n.option_id) FROM $(wp db prefix --allow-root)options n GROUP BY n.option_name) x)" --allow-root
Giữ option_name trùng lặp mới nhất
Truy vấn SQL này hiển thị tất cả ngoại trừ các hàng (MAX) mới nhất option_id cho mọi giá trị option_name trùng lặp
SELECT * FROM wp_options WHERE option_id NOT IN (SELECT * FROM (SELECT MAX(n.option_id) FROM wp_options n GROUP BY n.option_name) x)
Truy vấn SQL này giữ lại option_id (MAX) mới nhất cho mọi giá trị option_name trùng lặp và xóa tất cả các hàng trùng lặp cũ hơn
DELETE FROM wp_options WHERE option_id NOT IN (SELECT * FROM (SELECT MAX(n.option_id) FROM wp_options n GROUP BY n.option_name) x)
Đây là một lớp lót để sử dụng với lệnh truy vấn WP-CLI wp db để giữ option_name
trùng lặp mới nhất
wp db query "DELETE FROM $(wp db prefix --allow-root)options WHERE option_id NOT IN (SELECT * FROM (SELECT MAX(n.option_id) FROM $(wp db prefix --allow-root)options n GROUP BY n.option_name) x)" --allow-root
Xác minh các khóa và ràng buộc của wp_options
Bây giờ chúng ta hãy thực hiện lại ràng buộc UNIQUE trên cột option_name
wp db query "ALTER TABLE $(wp db prefix --allow-root)options ADD UNIQUE (option_name);" --allow-root
Nếu bạn không gặp lỗi nào thì hãy kiểm tra lại bảng
wp db query "DESCRIBE $(wp db prefix --allow-root)options;" --allow-root
Bây giờ bảng cơ sở dữ liệu wp_options
của WordPress có PRIMARY KEY được yêu cầu trên bảng option_id và ràng buộc UNIQUE constraint trên bảng option_name
+--------------+---------------------+------+-----+---------+----------------+ | Field | Type | Null | Key | Default | Extra | +--------------+---------------------+------+-----+---------+----------------+ | option_id | bigint(20) unsigned | NO | PRI | NULL | auto_increment | | option_name | varchar(191) | NO | UNI | | | | option_value | longtext | NO | | NULL | | | autoload | varchar(20) | NO | | yes | | +--------------+---------------------+------+-----+---------+----------------+
Hy vọng bài viết ngắn sẽ giúp ích được cho nhiều người.
Trân trọng.