Make WordPress Core

Opened 15 years ago

Closed 15 years ago

Last modified 15 years ago

#11081 closed defect (bug) (invalid)

wp_insert_post() creates duplicates posts with two simultaneous mysql connections

Reported by: maribge's profile maribge Owned by: ryan's profile ryan
Milestone: Priority: normal
Severity: normal Version:
Component: Query Keywords: reporter-feedback
Focuses: Cc:

Description

Hi,

I'm running the lates 2.8.5 wordpress release, but "tested" this bug with an older version too. Tested it on 2 Windows machines and one Unix with different mysql versions.

Precondition: create a sample plugin

<?php

/*
Plugin Name: Test plugin
Plugin URI: http://test
Description: test plugin.
Version: 1.0
Author: test
Author URI: http://test
*/

function test_insertPosts()
{
$postpost_title? = 'test title';
$postpost_content? = 'test content';
$postpost_status? = 'publish';
$postpost_author? = 1;
$postpost_category? = array(0);
$postguid? = 'somethingsss';

$post = add_magic_quotes($post);
$postID = wp_insert_post($post);

if(is_wp_error($postID)) return false;

return $postID;
}

add_action('init', 'test_insertPosts');

?>

On each refresh of the blog's home page this plugin should generate one post, however occasionally it generates two or even three posts at a time by establishing two or more simultaneous connections with a mysql database. Generally multiple(duplicate) posts are generated at the first, second or third homepage refreshes.

Watch this video as an illustration: http://www.youtube.com/watch?v=WdeDp4PjZnk . Don't pay attention to other issues addressed in the video though, just the duplicate post issue.

I looked through the mysql log file to locate the problem. I found that occasionally wordpress creates two simultaneous mysql conncetions and makes INSERT INTO 'wp_posts' query twice, instead of one and than closes both connections. The log file is attached, but I'm posting a snippet of it here:

mysqld, Version: 5.1.34-community-log (MySQL Community Server (GPL)). started with:
TCP Port: 3306, Named Pipe: (null)
Time                 Id Command    Argument
091105 16:18:00    1 Connect	admin@localhost on 
		    1 Query	SET NAMES utf8
		    1 Init DB	wordpress
		    1 Query	SELECT option_name, option_value FROM wp_options WHERE autoload = 'yes'
		    1 Query	UPDATE `wp_options` SET `option_value` = '1257427080' WHERE `option_name` = '_transient_doing_cron'
		    2 Connect	admin@localhost on 
		    2 Query	SET NAMES utf8
		    2 Init DB	wordpress
		    2 Query	SELECT option_name, option_value FROM wp_options WHERE autoload = 'yes'
		    2 Query	SELECT option_value FROM wp_options WHERE option_name = 'sidebars_widgets' LIMIT 1
		    2 Query	SELECT post_name FROM wp_posts WHERE post_name = 'test-title' AND post_type = 'post' AND ID != 0 LIMIT 1
		    2 Query	INSERT INTO `wp_posts` (`post_author`,`post_date`,`post_date_gmt`,`post_content`,`post_content_filtered`,`post_title`,`post_excerpt`,`post_status`,`post_type`,`comment_status`,`ping_status`,`post_password`,`post_name`,`to_ping`,`pinged`,`post_modified`,`post_modified_gmt`,`post_parent`,`menu_order`,`guid`) VALUES ('1','2009-11-05 16:18:00','2009-11-05 13:18:00','test content','','test title','','publish','post','open','open','','test-title','','','2009-11-05 16:18:00','2009-11-05 13:18:00','0','0','somethingsss')
		    2 Query	SELECT tr.term_taxonomy_id FROM wp_term_relationships AS tr INNER JOIN wp_term_taxonomy AS tt ON tr.term_taxonomy_id = tt.term_taxonomy_id WHERE tr.object_id IN (3) AND tt.taxonomy IN ('category')
		    2 Query	SELECT * FROM wp_posts WHERE ID = 3 LIMIT 1
		    2 Query	SELECT ID FROM wp_posts WHERE post_parent = 3
		    2 Query	SELECT * FROM wp_posts WHERE ID = 3 LIMIT 1
		    2 Query	INSERT INTO `wp_postmeta` (`post_id`,`meta_value`,`meta_key`) VALUES ('3','1','_pingme')
		    2 Query	INSERT INTO `wp_postmeta` (`post_id`,`meta_value`,`meta_key`) VALUES ('3','1','_encloseme')
		    2 Query	SELECT ID FROM wp_posts WHERE post_parent = 3
		    2 Query	UPDATE `wp_options` SET `option_value` = 'a:2:{i:1257467774;a:3:{s:16:\"wp_version_check\";a:1:{s:32:\"40cd750bba9870f18aada2478b24840a\";a:3:{s:8:\"schedule\";s:10:\"twicedaily\";s:4:\"args\";a:0:{}s:8:\"interval\";i:43200;}}s:17:\"wp_update_plugins\";a:1:{s:32:\"40cd750bba9870f18aada2478b24840a\";a:3:{s:8:\"schedule\";s:10:\"twicedaily\";s:4:\"args\";a:0:{}s:8:\"interval\";i:43200;}}s:16:\"wp_update_themes\";a:1:{s:32:\"40cd750bba9870f18aada2478b24840a\";a:3:{s:8:\"schedule\";s:10:\"twicedaily\";s:4:\"args\";a:0:{}s:8:\"interval\";i:43200;}}}s:7:\"version\";i:2;}' WHERE `option_name` = 'cron'
		    2 Query	SELECT * FROM wp_posts, wp_postmeta WHERE wp_posts.ID = wp_postmeta.post_id AND wp_postmeta.meta_key = '_pingme' LIMIT 1
		    2 Query	DELETE FROM wp_postmeta WHERE post_id = 3 AND meta_key = '_pingme'
		    2 Query	SELECT pinged FROM wp_posts WHERE ID = 3
		    2 Query	SELECT * FROM wp_posts, wp_postmeta WHERE wp_posts.ID = wp_postmeta.post_id AND wp_postmeta.meta_key = '_pingme' LIMIT 1
		    2 Query	SELECT * FROM wp_posts, wp_postmeta WHERE wp_posts.ID = wp_postmeta.post_id AND wp_postmeta.meta_key = '_encloseme' LIMIT 1
		    2 Query	DELETE FROM wp_postmeta WHERE post_id = 3 AND meta_key = '_encloseme'
		    2 Query	SELECT post_id, meta_key, meta_value FROM wp_postmeta WHERE post_id IN (3)
		    2 Query	SELECT * FROM wp_posts, wp_postmeta WHERE wp_posts.ID = wp_postmeta.post_id AND wp_postmeta.meta_key = '_encloseme' LIMIT 1
		    2 Query	SELECT ID FROM wp_posts WHERE to_ping <> '' AND post_status = 'publish'
091105 16:18:01    2 Quit	
		    1 Query	SELECT * FROM wp_users WHERE user_login = 'admin'
		    1 Query	SELECT meta_key, meta_value FROM wp_usermeta WHERE user_id = 1
		    1 Query	SELECT option_value FROM wp_options WHERE option_name = 'sidebars_widgets' LIMIT 1
		    1 Query	SELECT post_name FROM wp_posts WHERE post_name = 'test-title' AND post_type = 'post' AND ID != 0 LIMIT 1
		    1 Query	SELECT post_name FROM wp_posts WHERE post_name = 'test-title-2' AND post_type = 'post' AND ID != 0 LIMIT 1
		    1 Query	INSERT INTO `wp_posts` (`post_author`,`post_date`,`post_date_gmt`,`post_content`,`post_content_filtered`,`post_title`,`post_excerpt`,`post_status`,`post_type`,`comment_status`,`ping_status`,`post_password`,`post_name`,`to_ping`,`pinged`,`post_modified`,`post_modified_gmt`,`post_parent`,`menu_order`,`guid`) VALUES ('1','2009-11-05 16:18:01','2009-11-05 13:18:01','test content','','test title','','publish','post','open','open','','test-title-2','','','2009-11-05 16:18:01','2009-11-05 13:18:01','0','0','somethingsss')
		    1 Query	SELECT tr.term_taxonomy_id FROM wp_term_relationships AS tr INNER JOIN wp_term_taxonomy AS tt ON tr.term_taxonomy_id = tt.term_taxonomy_id WHERE tr.object_id IN (4) AND tt.taxonomy IN ('category')
		    1 Query	SELECT * FROM wp_posts WHERE ID = 4 LIMIT 1
		    1 Query	SELECT ID FROM wp_posts WHERE post_parent = 4
		    1 Query	SELECT * FROM wp_posts WHERE ID = 4 LIMIT 1
		    1 Query	INSERT INTO `wp_postmeta` (`post_id`,`meta_value`,`meta_key`) VALUES ('4','1','_pingme')
		    1 Query	INSERT INTO `wp_postmeta` (`post_id`,`meta_value`,`meta_key`) VALUES ('4','1','_encloseme')
		    1 Query	SELECT ID FROM wp_posts WHERE post_parent = 4
		    1 Query	SELECT SQL_CALC_FOUND_ROWS  wp_posts.* FROM wp_posts  WHERE 1=1  AND wp_posts.post_type = 'post' AND (wp_posts.post_status = 'publish' OR wp_posts.post_status = 'private')  ORDER BY wp_posts.post_date DESC LIMIT 0, 10
		    1 Query	SELECT FOUND_ROWS()
		    1 Query	SELECT t.*, tt.*, tr.object_id FROM wp_terms AS t INNER JOIN wp_term_taxonomy AS tt ON tt.term_id = t.term_id INNER JOIN wp_term_relationships AS tr ON tr.term_taxonomy_id = tt.term_taxonomy_id WHERE tt.taxonomy IN ('category', 'post_tag') AND tr.object_id IN (4, 3) ORDER BY t.name ASC
		    1 Query	SELECT post_id, meta_key, meta_value FROM wp_postmeta WHERE post_id IN (4,3)
		    1 Query	SELECT option_value FROM wp_options WHERE option_name = 'kubrick_header_image' LIMIT 1
		    1 Query	SELECT option_value FROM wp_options WHERE option_name = 'kubrick_header_color' LIMIT 1
		    1 Query	SELECT option_value FROM wp_options WHERE option_name = 'kubrick_header_display' LIMIT 1
		    1 Query	SELECT * FROM wp_posts  WHERE (post_type = 'page' AND post_status = 'publish')     ORDER BY menu_order, post_title ASC
		    1 Query	SELECT option_value FROM wp_options WHERE option_name = 'page_for_posts' LIMIT 1
		    1 Query	SELECT YEAR(post_date) AS `year`, MONTH(post_date) AS `month`, count(ID) as posts FROM wp_posts  WHERE post_type = 'post' AND post_status = 'publish' GROUP BY YEAR(post_date), MONTH(post_date) ORDER BY post_date DESC
		    1 Query	SELECT t.*, tt.* FROM wp_terms AS t INNER JOIN wp_term_taxonomy AS tt ON t.term_id = tt.term_id WHERE tt.taxonomy IN ('category')  ORDER BY t.name ASC
		    1 Query	SELECT t.*, tt.* FROM wp_terms AS t INNER JOIN wp_term_taxonomy AS tt ON t.term_id = tt.term_id WHERE tt.taxonomy IN ('link_category')  AND tt.count > 0 ORDER BY t.name ASC
		    1 Query	SELECT *  , IF (DATE_ADD(link_updated, INTERVAL 120 MINUTE) >= NOW(), 1,0) as recently_updated   FROM wp_links  INNER JOIN wp_term_relationships AS tr ON (wp_links.link_id = tr.object_id) INNER JOIN wp_term_taxonomy as tt ON tt.term_taxonomy_id = tr.term_taxonomy_id WHERE 1=1 AND link_visible = 'Y'  AND ( tt.term_id = 2 ) AND taxonomy = 'link_category'    ORDER BY link_name ASC
		    1 Quit	

As you can clearly see, after the first connection had been extablished and two queries made:

091105 16:18:00    1 Connect	admin@localhost on 
		    1 Query	SET NAMES utf8
		    1 Init DB	wordpress
		    1 Query	SELECT option_name, option_value FROM wp_options WHERE autoload = 'yes'
		    1 Query	UPDATE `wp_options` SET `option_value` = '1257427080' WHERE `option_name` = '_transient_doing_cron'		    

wordpress initiates another mysql connection:

2 Connect	admin@localhost on 
		    2 Query	SET NAMES utf8
		    2 Init DB	wordpress

During the second connection query "INSERT INTO wp_posts" is performed. Then the second connection session ends:

091105 16:18:01    2 Quit

and queries of the first connection resume, and another "INSERT INTO wp_posts" query is made (which is a duplicate post). Then the first connection shuts down:

1 Quit

I've been trying to figure out what causes it (presumably two instances of the wpbd class are made), but failed to locate the problem in the wordpress code.

Thanks,
Merab.

Attachments (1)

mysql.log (12.1 KB) - added by maribge 15 years ago.

Download all attachments as: .zip

Change History (4)

@maribge
15 years ago

#1 @scribu
15 years ago

  • Keywords reporter-feedback added; wp_insert_post duplicate entries mysql removed

Add this condition and see if it helps:

if ( true === DOING_CRON || true === DOING_AJAX )
    return;

#2 @ryan
15 years ago

  • Resolution set to invalid
  • Status changed from new to closed

Yes, check cron requests. wp_insert_post() schedules ping processing. Later page loads will spawn a request to process the ping, which will trigger your insert since it is attached to "init". Closing as invalid pending further info.

#3 @ryan
15 years ago

  • Milestone 2.9 deleted
Note: See TracTickets for help on using tickets.