Hi,

I just ran into a major desaster with the 'Flag' module after installing the 'flag_weight' module for the first time (which is recommended on the 'Flag' project page, so I considered it to be safe). First I downloaded and installed the 'flag_weight' module, enabled it, and ran update.php, as ususal, even if this module does not come with any schema extensions. Also cleared the cache via Drush (drush cc all).

I didn't bother with the new module but went straight to ./admin/build/flags to add a new flag (a flag to mark favourite movies). I went through the configuration screens, but no new flag was created. I can not tell if flag 6.x-2.0-beta6 would have been capable to create new flags on this site because I never tried this; the flags I'm using were created with flag 6.x-1.3 or earlier.

I retried two times more, then the 'abuse_node' flag suddenly lost the enabled content types (it somehow reset from several enabled roles to one (authenticated user), and lost all content types except for 'story').

Next I edited the 'abuse_node' flag, added the lost user roles, and content types. After saving this flag, a red alert popped up, saying "This view is looking for a flag by the name "network", but there is no such flag. Perhaps it was deleted. Please update the relationship "Flags: network ..." in this view to use an existing flag." The flag the error message was referencing to is used in a View that is used on every page on my site, including the admin pages; the reported error probably did not relate directly to the editing operation on the 'abuse_node' flag, but saving this this flag oviously deleted another flag. And indeed, the custom "network" flag was gone from ./admin/build/flags. Next I checked the database:

mysql> select name from flags;
+--------------+
| name         |
+--------------+
| abuse_node   |
| lesezeichen  |
| merkliste    |
| produktdaten |
+--------------+
4 rows in set (0.00 sec)

The custom 'network' flag has been erased from the database, without my doing. When looking at the database table, panic started to creep up my spine as important site logic is based on the vanished flag (it instructs essential views what to show). Since this flag is gone, the view broke, and the wrong content is displayed to wrong users. At least for my use case this is a catastrophy.

And it's getting worse. I have an export of the vanished flag (as I said, it's important for my site, so I have a backup); when trying to import this exported view, I'm getting a WSOD (blank screen, without error message in watchdog log).

To summarize: At this point, I can not create a new flag; an existing flag has been deleted, and this breaks an important part of my site's logic; I can not import a backup of the flag; and I can not create a "new" flag with the "old" name to fix the view. I can not even edit the View as Views does not allow me to delete the relationship on the vanished flag. A total nightmare.

Versions used: I'm running flag 6.x-2.0-beta6 (instead of 6.x-1.3 because of #1302480: Unflag does not work which broke the stable release on all production sites); flag_abuse 6.x-2.0-rc1 (enabled); flag_friend 6.x-1.0 (installed, but not enabled); flag_terms 6.x-1.0-beta2 (installed, but not enabled); flag_weights 6.x-1.1 (recently installed and enabled); also I'm running Views 6.x-2.x-dev because of #1331032: Empty rewritten fields are not hidden anymore plus additional patch; however, probably I'm not running into #1335604: Flag 1.3 doesn't work with views 6.2.14 because I already use the dev release. Other environment: Pressflow 6.22.x, Memcache, APC, Boost, css_gzip, and javascript_aggregator.

My mental state currently does not allow any constructive attempts to reproduce the desaster. I think I'll now get wasted and add other findings with a hopefully clearer head tomorrow.

Thanks for any ideas or suggestions about what could trigger things like deleting configured flags, or not allowing me to add new flags (I'm using flags on this site for over two years without any incident except for the already mentioned #1302480).

Comments

asb’s picture

Quick update: I just tried to add a new flag on another site with flag 6.x-2.0-beta6. That results in a green message, saying: "Flag testflag was saved" (localized interface; original message text is probably: Flag @name has been saved), but "testflag" is neither listed at ./admin/build/flags, nor saved to the database. So the issue already starts with a vanilla flag 6.x-2.0-beta6.

asb’s picture

Version: 6.x-2.0-beta6 » 6.x-2.x-dev

Upgraded to 6.x-2.x-dev on the affected site. The (sub-) issue "Can not create new flags" exists here as well. When trying to import an an exported flag from 6.x-2.0-beta6, I'm not getting a WSOD with this version; the behaviour is identical to the manual creation: Positive confirmation message, but no flag is saved to the database. If the export is somehow modified, I'm not getting a refusal message (like in Views) but the WSOD.

Also verified the sub-issue on several other sites that were upgraded from 6.x-1.3 or earlier to 6.x-2.0-beta6. All those sites are affected and do not allow to configure new flags; behaviour as described in #1.

The "Can not create new flags" issue does not appear on sites where the 'flag' module has not been upgraded or where still flag-6.x-1.3 is used. Very nasty in combination with #1302480: Unflag does not work, though :-(

quicksketch’s picture

I can't really say why a flag would suddenly disappear. Considering the variety of flag related modules and patches on your site, it's going to be very difficult to reproduce such a problem. However as far as the upgrade path from 1.3 to 2.x being broken, it's possible that this is the case but last I tested it (just before making the beta6 release), it was working fine. I recall that other users had reported that their flag table somehow lost its auto-increment property on the FID column. The problem you're describing sounds the same. Actually that problem might also explain a flag going missing entirely, if you have two flags in the database with an FID of 0, one of them might not show up.

However we've tried to fix this several times in the past, but somehow the update fails (silently) even though it works for most users. Perhaps it's an oddity with some versions of MySQL, I'm not sure. For reference:

#420250: Flag D5->D6 Update Doesn't Add Auto-increment to flags.fid Column
#715382: FID auto-increment missing from flags table on upgrade
#629396: Data upgraded from D5, no flags.fid field not set to auto_increment

asb’s picture

Thanks for the reply.

Indeed... On the affected site:

mysql> describe flag_types;
+-------+----------------------+------+-----+---------+-------+
| Field | Type                 | Null | Key | Default | Extra |
+-------+----------------------+------+-----+---------+-------+
| fid   | smallint(5) unsigned | NO   | MUL | 0       |       |
| type  | varchar(32)          | NO   |     |         |       |
+-------+----------------------+------+-----+---------+-------+
2 rows in set (0.00 sec)

mysql> describe flags;
+--------------+----------------------+------+-----+---------+-------+
| Field        | Type                 | Null | Key | Default | Extra |
+--------------+----------------------+------+-----+---------+-------+
| fid          | smallint(5) unsigned | NO   | PRI | 0       |       |
| content_type | varchar(32)          | YES  |     |         |       |
| name         | varchar(32)          | YES  | UNI |         |       |
| title        | varchar(255)         | YES  |     |         |       |
| global       | tinyint(4)           | YES  |     | 0       |       |
| options      | text                 | YES  |     | NULL    |       |
+--------------+----------------------+------+-----+---------+-------+
6 rows in set (0.00 sec)

On a unaffected site:

mysql> describe flag_types;
+-------+----------------------+------+-----+---------+-------+
| Field | Type                 | Null | Key | Default | Extra |
+-------+----------------------+------+-----+---------+-------+
| fid   | smallint(5) unsigned | NO   | MUL | 0       |       |
| type  | varchar(32)          | NO   |     |         |       |
+-------+----------------------+------+-----+---------+-------+
2 rows in set (0.00 sec)

mysql> describe flags;
+--------------+----------------------+------+-----+---------+----------------+
| Field        | Type                 | Null | Key | Default | Extra          |
+--------------+----------------------+------+-----+---------+----------------+
| fid          | smallint(5) unsigned | NO   | PRI | NULL    | auto_increment |
| content_type | varchar(32)          | NO   |     |         |                |
| name         | varchar(32)          | YES  | UNI |         |                |
| title        | varchar(255)         | YES  |     |         |                |
| roles        | varchar(255)         | YES  |     |         |                |
| global       | tinyint(4)           | YES  |     | 0       |                |
| options      | text                 | YES  |     | NULL    |                |
+--------------+----------------------+------+-----+---------+----------------+
7 rows in set (0.00 sec)

So what's the suggested action - uninstall 'flag' and related modules, drop the 'flag'-related tables (flag_content, flag_counts, flag_types, flags), and start from scratch on all sites with broken "auto_increment" ?

Or maybe something like alter table flags add fid Int NOT NULL AUTO_INCREMENT key; or ALTER TABLE flags AUTO_INCREMENT = 1 might work (just suggestions from Googling around the MySQL manual)?

Rerunning flag_update_6002() (referenced in #420250: Flag D5->D6 Update Doesn't Add Auto-increment to flags.fid Column) gives me on the affected site:

flag module
Update #6002
Failed: ALTER TABLE {flag_content} DROP PRIMARY KEY
Failed: ALTER TABLE {flag_content} ADD `fcid` INT unsigned auto_increment DEFAULT NULL, ADD PRIMARY KEY (fcid)
ALTER TABLE {flag_content} CHANGE `fcid` `fcid` INT unsigned NOT NULL auto_increment
ALTER TABLE {flag_content} ADD UNIQUE KEY fid_content_type_content_id_uid (fid, content_type, content_id, uid)
Update #6003
No queries
Update #6004
No queries
Update #6200
No queries
Update #6201
ALTER TABLE {flag_content} DROP KEY fid_content_type_content_id_uid
ALTER TABLE {flag_content} ADD UNIQUE KEY fid_content_id_uid (fid, content_id, uid)
ALTER TABLE {flag_counts} ADD INDEX count (count)
Update #6202
ALTER TABLE {flag_content} DROP KEY fid_content_id_uid
Failed: ALTER TABLE {flag_content} DROP INDEX content_type_uid
Failed: ALTER TABLE {flag_content} ADD `sid` INT unsigned NOT NULL DEFAULT 0
Failed: ALTER TABLE {flag_content} ADD UNIQUE KEY fid_content_id_uid_sid (fid, content_id, uid, sid)
Failed: ALTER TABLE {flag_content} ADD INDEX content_type_uid_sid (content_type, uid, sid)
Update #6203
DELETE FROM {flag_counts} WHERE count = 0
Update #6204
ALTER TABLE {flag_counts} DROP PRIMARY KEY
ALTER TABLE {flag_counts} ADD PRIMARY KEY (fid, content_id)
Update #6205
No queries
Update #6206
ALTER TABLE {flag_content} ADD INDEX content_type_content_id_uid_sid (content_type, content_id, uid, sid)
Update #6207
Failed: ALTER TABLE {flag_counts} ADD `last_updated` INT unsigned NOT NULL DEFAULT 0, ADD INDEX last_updated (last_updated)
Update #6208
ALTER TABLE {flag_counts} DROP INDEX count
Failed: ALTER TABLE {flag_counts} DROP INDEX last_updated
Failed: ALTER TABLE {flag_counts} ADD INDEX fid_count (fid, count)
Failed: ALTER TABLE {flag_counts} ADD INDEX fid_last_updated (fid, last_updated)

Whoops?

quicksketch’s picture

Well I think you may have it right there. If update 6002 failed for you the first time but you (or whoever ran the update) didn't take notice, then that's the cause of all your troubles. But it's hard to say at this point. You can ever re-run updates a second time and expect them to work, because your database has already been modified. A this point I think you've pretty well hosed your database, but it's still possible to fix it manually be going through and manually making all the indexes/keys/columns.

In any case, I'm still at a loss for why this problem occurs. I can install Flag 1.3 and upgrade it to 2.x without any troubles at all. We've even added the update to add the auto-increment column twice (just in case the first onen didn't work), but even that doesn't solve the problem if something is preventing the index from being created.

asb’s picture

I don't know enough about the database structures of the 'flag' module to offer real help with this, but at least on almost all my sites where I have updated to 6.x-2.0-beta6 from flag 6.x-1.3 or earlier the error is consistent. I compared the 'flag' table on a rough dozend of sites, and the structure almost always looks like this:

mysql> describe flags;
+--------------+----------------------+------+-----+---------+-------+
| Field        | Type                 | Null | Key | Default | Extra |
+--------------+----------------------+------+-----+---------+-------+
| fid          | smallint(5) unsigned | NO   | PRI | 0       |       |
| content_type | varchar(32)          | YES  |     |         |       |
| name         | varchar(32)          | YES  | UNI |         |       |
| title        | varchar(255)         | YES  |     |         |       |
| roles        | varchar(255)         | YES  |     |         |       |
| global       | tinyint(4)           | YES  |     | 0       |       |
| options      | text                 | YES  |     | NULL    |       |
+--------------+----------------------+------+-----+---------+-------+
7 rows in set (0.00 sec)

On these sites I'm not using anything but a vanilla 'flag' module (no flag-related modules), so at least this sub-issue definitely can not be caused by an interference between flag "core" and flag "contrib".

Regarding the MySQL version: I'm running Ver 14.14 Distrib 5.1.49 from Debian GNU/Linux 6.0 "Squeeze", so that's not much out of the ordinary, also.

Since 'flag' does not depend on other modules (like 'ctools'), what could interfere with database updates except Drupal core?

Regarding rerunning flag_update_6002(), I understand that running those updates a second time might not [can not|will not] work; however that's a bit surprising since that's the way major CCK updates (e.g. from D5 to D6) were accomplished: Keep rerunning update.php, until all errors are gone. Considering that and regarding the update errors quoted in #4, I don't see an attempt to alter the field "fid" in the "flag" table (if I'm even looking at the right database table, and if I tried to rerun the right database update).

but it's still possible to fix it (the database) manually be going through and manually making all the indexes/keys/columns.

Well, I'm afraid this is clearly out of my league, but at least I can offer a pretty consistent testbed, in case you try to add the auto-increment column a third time, or something like this ;)

Regarding the one site with 6.x-2.0-beta6 that actually has this auto_increment property, the only major configuration difference compared to my other sites is that this site hadn't the 'boost' module enabled. But is it even theoretically possible that some module tampers with the ability of Drupal core to update the database schema??

quicksketch’s picture

Title: Can not create new flags; existing flag is being removed from database » Update from 1.3 to 2.x does not preserve auto_increment on FID column

Hm, I'll need to give this more research. I doubt boost would be the source of the problem.

asb’s picture

Sorry for burdening you with more work :-(

Again, I'm willing to provide any help I can give, including access to database dumps in various stages, if that helps.

asb’s picture

OK, before dropping 'Flag' completely, I tried this:

mysql> ALTER TABLE flags CHANGE COLUMN fid fid int(10) unsigned NOT NULL auto_increment;
Query OK, 4 rows affected (0.18 sec)
Records: 4  Duplicates: 0  Warnings: 0

That gives me this schema:

mysql> describe flags;
+--------------+------------------+------+-----+---------+----------------+
| Field        | Type             | Null | Key | Default | Extra          |
+--------------+------------------+------+-----+---------+----------------+
| fid          | int(10) unsigned | NO   | PRI | NULL    | auto_increment |
| content_type | varchar(32)      | YES  |     |         |                |
| name         | varchar(32)      | YES  | UNI |         |                |
| title        | varchar(255)     | YES  |     |         |                |
| global       | tinyint(4)       | YES  |     | 0       |                |
| options      | text             | YES  |     | NULL    |                |
+--------------+------------------+------+-----+---------+----------------+
6 rows in set (0.00 sec)

However, I'm still at a loss what "manually making all the indexes/keys/columns" actually would require. It would really help to get some instructions which tables and/or fields need to be modified as well.

Please note that the field "content_type" has Null=YES, by my unaffected site has Null=No. I don't know what the correct definition would be.

However, the SQL one-liner gives me the following changes:

  • I can create new flags again;
  • I can import the backed-up flag that got "lost" (however, it's just listed but seems not to work)
  • I can edit existing flags and save changes

Is it really that easy?

PS: Since the issue queue has numerous issues related to schema changes, maybe it would help to verify the current schema at some point. This could notify the user about problems, for example, at the status report page (./admin/reports/status).

asb’s picture

Also, for the sake of the experiment I set up an older version of the affected site and directly updated from 6.x-1.3 to 6.x-2.x-dev. But I executed the SQL statement from above (ALTER TABLE flags CHANGE COLUMN fid fid int(10) unsigned NOT NULL auto_increment;) before running update.php/drush updatedb (!) When running drush updatedb, this gave me:

The following updates are pending:

 flag module
 6200 - Convert role access to have separate "flag" and "unflag" permissions.
 6201 - Refine the indexes.   The content type inclusion actually slowed down on unique key. And a count  index would be helpful for sorting by counts.
 6202 - Add the sid column and unique index on the flag_content table.
 6203 - Remove count = 0 rows from the count tables.
 6204 - Remove "content type" from the flag_counts primary key.
 6205 - Provide a better index on the flag_content table to include 'uid' and 'sid'.
 6206 - Correction to flag_update_6205(). Convert unique key to an index.
 6207 - Adds column last_updated to flag_counts table.
 6208 - Convert flag_count indexes to include FID for more efficient indexing.

 flag_actions module
 6200 - Add a "repeat_threshold" value to all existing Flag actions.

Do you wish to run all pending updates? (y/n): y
Executing flag_update_6200
ALTER TABLE {flags} DROP roles
Executing flag_update_6201
ALTER TABLE {flag_content} DROP KEY fid_content_type_content_id_uid
ALTER TABLE {flag_content} ADD UNIQUE KEY fid_content_id_uid (fid, content_id, uid)
ALTER TABLE {flag_counts} ADD INDEX count (count)
Executing flag_update_6202
ALTER TABLE {flag_content} DROP KEY fid_content_id_uid
ALTER TABLE {flag_content} DROP INDEX content_type_uid
ALTER TABLE {flag_content} ADD `sid` INT unsigned NOT NULL DEFAULT 0
ALTER TABLE {flag_content} ADD UNIQUE KEY fid_content_id_uid_sid (fid, content_id, uid, sid)
ALTER TABLE {flag_content} ADD INDEX content_type_uid_sid (content_type, uid, sid)
Executing flag_update_6203
DELETE FROM {flag_counts} WHERE count = 0
Executing flag_update_6204
ALTER TABLE {flag_counts} DROP PRIMARY KEY
ALTER TABLE {flag_counts} ADD PRIMARY KEY (fid, content_id)
Executing flag_update_6205
Executing flag_update_6206
ALTER TABLE {flag_content} ADD INDEX content_type_content_id_uid_sid (content_type, content_id, uid, sid)
Executing flag_update_6207
ALTER TABLE {flag_counts} ADD `last_updated` INT unsigned NOT NULL DEFAULT 0, ADD INDEX last_updated (last_updated)
Executing flag_update_6208
ALTER TABLE {flag_counts} DROP INDEX count
ALTER TABLE {flag_counts} DROP INDEX last_updated
ALTER TABLE {flag_counts} ADD INDEX fid_count (fid, count)
ALTER TABLE {flag_counts} ADD INDEX fid_last_updated (fid, last_updated)
Executing flag_actions_update_6200
ALTER TABLE {flag_actions} ADD `repeat_threshold` SMALLINT NOT NULL DEFAULT 0
ALTER TABLE {flag_actions} CHANGE `threshold` `threshold` SMALLINT NOT NULL DEFAULT 0

'all' cache was cleared
Finished performing updates.

All updates were run successfully, and no errors were indicated. Final table schema:

mysql> describe flags;
+--------------+------------------+------+-----+---------+----------------+
| Field        | Type             | Null | Key | Default | Extra          |
+--------------+------------------+------+-----+---------+----------------+
| fid          | int(10) unsigned | NO   | PRI | NULL    | auto_increment |
| content_type | varchar(32)      | YES  |     |         |                |
| name         | varchar(32)      | YES  | UNI |         |                |
| title        | varchar(255)     | YES  |     |         |                |
| global       | tinyint(4)       | YES  |     | 0       |                |
| options      | text             | YES  |     | NULL    |                |
+--------------+------------------+------+-----+---------+----------------+
6 rows in set (0.00 sec)

Maybe that little line of SQL is the manual fix?

quicksketch’s picture

maybe it would help to verify the current schema at some point.

There's a module that serves a dedicated purpose for this: http://drupal.org/project/schema

socketwench’s picture

Status: Active » Closed (cannot reproduce)

Closing, since the issue could not be reproduced. Sorry!!!