It seems (have to confirm still) that Facebook solved this in day zero code import [1] by adding the following to ha_commit_trans(). For some reason we didn't fix it then.
else if (is_real_trans && !trans->no_2pc && (rw_ha_count == 1))
{
/* When innodb_fake_changes is enabled for a transaction and that transaction
changes no InnoDB rows then the InnoDB handlerton is marked as read-only and
does not participate in 2 phase commit above. So InnoDB won't be able to
raise an error during commit and the transaction would be written to the
binlog. This code prevents that. */
facebook-5.1$ bzr log -r 3763
------------------------------------------------------------
revno: 3763
committer: Mark Callaghan <email address hidden>
branch nick: 51fb
timestamp: Tue 2012-01-03 10:03:20 -0800
message:
Port innodb_fake_changes.patch from Percona
This adds a session parameter, innodb_fake_changes, that prevents
rows from being locked and modified when set. It can be used to prefetch
transactions. When set COMMIT and auto-commit statements will return an
error. Non auto-commit statements are not foced to fail with this set.
Binlog events are not written for a session when this is set for changes
to InnoDB tables. All bets are off if a session mixes changes to MyISAM
and InnoDB.
It seems (have to confirm still) that Facebook solved this in day zero code import [1] by adding the following to ha_commit_trans(). For some reason we didn't fix it then.
else if (is_real_trans && !trans->no_2pc && (rw_ha_count == 1))
{
/* When innodb_fake_changes is enabled for a transaction and that transaction
changes no InnoDB rows then the InnoDB handlerton is marked as read-only and
does not participate in 2 phase commit above. So InnoDB won't be able to
raise an error during commit and the transaction would be written to the
binlog. This code prevents that. */
Ha_trx_info *ha; fake_change( ht, thd))
thd_ reset_diagnosti cs(thd) ; /* avoid debug assertion */
ha_rollback_ trans(thd, all);
my_error( ER_ERROR_ DURING_ COMMIT, MYF(0), HA_ERR_ WRONG_COMMAND) ;
for (ha= ha_info_orig; ha; ha= ha->next())
{
handlerton *ht= ha->ht();
if (ht->is_fake_change && ht->is_
{
error= 1;
goto end;
}
}
}
[1]
facebook-5.1$ bzr log -r 3763 ------- ------- ------- ------- ------- ------- ------- ---- fake_changes. patch from Percona
-------
revno: 3763
committer: Mark Callaghan <email address hidden>
branch nick: 51fb
timestamp: Tue 2012-01-03 10:03:20 -0800
message:
Port innodb_
This adds a session parameter, innodb_ fake_changes, that prevents
rows from being locked and modified when set. It can be used to prefetch
transactions. When set COMMIT and auto-commit statements will return an
error. Non auto-commit statements are not foced to fail with this set.
Binlog events are not written for a session when this is set for changes
to InnoDB tables. All bets are off if a session mixes changes to MyISAM
and InnoDB.
The patch is at bazaar. launchpad. net/~percona- dev/percona- server/ 5.1/view/ head:/patches/ innodb_ fake_changes. patch
http://