Commit 5569b3eb authored by Marko Mäkelä's avatar Marko Mäkelä

MDEV-16041 Do not write for null update (properly fix MySQL Bug#29157)

InnoDB takes a lot of time to perform null updates. The reason is that
even though an empty update vector was created, InnoDB will go on to
write undo log records and update the system columns
DB_TRX_ID and DB_ROLL_PTR in the clustered index, and of course write
redo log for all this.

This could have been fixed properly in
commit 54a492ec more than 10 years ago.
parent c5ea43fc
......@@ -1335,11 +1335,17 @@ UPDATE t6 SET b = "updated by client 2";
SELECT * FROM t6;
a b aa bb
1 inserted by client 1 1 inserted by client 1
2 updated by client 2 2 inserted by client 1
2 inserted by client 1 2 inserted by client 1
3 inserted by client 1 3 inserted by client 1
4 updated by client 2 4 inserted by client 1
5 updated by client 2 NULL NULL
10 updated by client 2 1 inserted by client 1
SELECT * FROM t6 LOCK IN SHARE MODE;
a b aa bb
2 updated by client 2 2 inserted by client 1
4 updated by client 2 4 inserted by client 1
5 updated by client 2 NULL NULL
10 updated by client 2 1 inserted by client 1
SELECT COUNT(*) FROM t6;
COUNT(*)
6
......
......@@ -1701,7 +1701,7 @@ variable_value - @innodb_rows_inserted_orig
964
SELECT variable_value - @innodb_rows_updated_orig FROM information_schema.global_status WHERE LOWER(variable_name) = 'innodb_rows_updated';
variable_value - @innodb_rows_updated_orig
866
865
SELECT variable_value - @innodb_row_lock_waits_orig FROM information_schema.global_status WHERE LOWER(variable_name) = 'innodb_row_lock_waits';
variable_value - @innodb_row_lock_waits_orig
0
......
......@@ -301,6 +301,7 @@ SELECT COUNT(*) FROM t5;
UPDATE t6 SET b = "updated by client 2";
SELECT * FROM t6;
SELECT * FROM t6 LOCK IN SHARE MODE;
SELECT COUNT(*) FROM t6;
DELETE FROM t7;
......
......@@ -9032,6 +9032,14 @@ ha_innobase::update_row(
goto func_exit;
}
if (!uvect->n_fields) {
/* This is the same as success, but instructs
MySQL that the row is not really updated and it
should not increase the count of updated rows.
This is fix for http://bugs.mysql.com/29157 */
DBUG_RETURN(HA_ERR_RECORD_IS_THE_SAME);
}
/* This is not a delete */
m_prebuilt->upd_node->is_delete = FALSE;
......@@ -9068,20 +9076,12 @@ ha_innobase::update_row(
innobase_srv_conc_exit_innodb(m_prebuilt);
func_exit:
err = convert_error_code_to_mysql(
error, m_prebuilt->table->flags, m_user_thd);
/* If success and no columns were updated. */
if (err == 0 && uvect->n_fields == 0) {
/* This is the same as success, but instructs
MySQL that the row is not really updated and it
should not increase the count of updated rows.
This is fix for http://bugs.mysql.com/29157 */
err = HA_ERR_RECORD_IS_THE_SAME;
} else if (err == HA_FTS_INVALID_DOCID) {
if (error == DB_FTS_INVALID_DOCID) {
err = HA_FTS_INVALID_DOCID;
my_error(HA_FTS_INVALID_DOCID, MYF(0));
} else {
err = convert_error_code_to_mysql(
error, m_prebuilt->table->flags, m_user_thd);
}
/* Tell InnoDB server that there might be work for
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment