Sửa lỗi Duplicate entry ‘0’ for key ‘PRIMARY’ for query INSERT INTO `wp_usermeta`

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.

Từ khóa
Nếu bạn thấy bài viết có ích hãy sao chép link và chia sẻ bài viết
user

Yêu thích Võ thuật và Công nghệ thông tin, thích viết và chia sẽ về 2 lĩnh vực này thế thôi :D

Bài viết liên quan