Last modified: 2010-05-15 15:38:31 UTC
I recently upgraded from MediaWiki 1.4.9 to MediaWiki 1.5.6. After upgrading, everything seemed okay, but I've had some users reporting problems with the images. On my test server, I had some major problems with the image MIME types not being set correctly. I know that's part of what the rebuildImages.php script does, so I try to run it. Every time I run it, though, it hangs. For the last hour or two, I've been poking through the rebuildImages.php file trying to figure out why it's crashing on my host. It's crashing on this line: $ret = mysql_query( $sql, $this->mConn ); in the file includes/Database.php, at line 349. I snagged the value of $sql just before the command runs, and if I plug it into my mysql client and run it manually, it runs fine. (That is, there's nothing wrong with the SQL syntax that is being run, and it looks like a normal command.) A sample SQL statement being executed is as follows: /* ImageBuilder::buildTable */ UPDATE `wiki_image` SET img_width = '32',img_height = '32',img_bits = '8',img_media_type = 'BITMAP',img_major_mime = 'image',img_minor_mime = 'png' WHERE img_name = 'RadiationBurst_CosmicBurst.png' I don't know why the _function_ is failing, but it might be worth noting that the _query_ is actually working. I can't imagine a problem with the mysql_query function, because isn't that pretty much the same function that is used elsewhere to, well, generate every page in the wiki? (Which, incidentally, is working fine...) Here's a blow-by-blow of what's happening. When I run php rebuildImages.php, it loads the first image and runs that query and hangs on it, but after the query has updated the table. I stop it (Ctrl-C), and run php rebuildImages.php again, and it skips the first image and hangs on the second, again, after the query has updated the table. As long as I keep typing php rebuildImages.php, it will keep updaing one row and hanging. If I put something to output text to the console just before and just after that line, what is programmed to output before gets written, but not what is programmed to be output after. Any ideas? I put some notes about this problem, as well as some other things that might be relevant, at http://meta.wikimedia.org/wiki/Help_talk:Upgrading_MediaWiki#My_upgrade_experience... (yes, you need the dots in the URL). The site where MediaWiki is installed is at http://paragonwiki.com
This isn't such a major issue for me any more, as I've gone in and manually used a script with ImageMagick to update all of the new records in the new schema. Still, it strikes me as something that should probably be tested.
I had the same experience with 1.6.7 Yeah, this is happening because in buildTable, there's the "SELECT * FROM $image" that locks the table, and then there's the update process that tries to update a locked table after, so the result is just deadlock. I'm not sure why the initial SELECT locks the table, but tt seems like in this case, a possible alternative function for buildTable would just to store the rows in an array, which could be problematic for dbs that have millions of images, but hey, it doesn't lock, does it? function buildTable( $table, $key, $callback ) { $fname = 'ImageBuilder::buildTable'; $count = $this->dbw->selectField( $table, 'count(*)', '', $fname ); $this->init( $count, $table ); $this->log( "Processing $table..." ); $tableName = $this->dbr->tableName( $table ); $sql = "SELECT * FROM $tableName"; $result = $this->dbr->query( $sql, $fname ); $rows = array(); while( $row = $this->dbr->fetchObject( $result ) ) { $rows[] = $row; } $this->dbr->freeResult( $result ); foreach ($rows as $row) { $update = call_user_func( $callback, $row ); if( is_array( $update ) ) { if( !$this->dryrun ) { $this->dbw->update( $table, $update, array( $key => $row->$key ), $fname ); } $this->progress( 1 ); } else { $this->progress( 0 ); } } $this->log( "Finished $table... $this->updated of $this->processed rows updated" ); }
You'll need to switch your tables to InnoDB. MyISAM is really limited...