summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMarko Mäkelä <marko.makela@mariadb.com>2018-04-26 20:56:14 +0300
committerMarko Mäkelä <marko.makela@mariadb.com>2018-04-26 20:56:14 +0300
commit5569b3eb091d54664c75f13564510daa74c56288 (patch)
tree7771200b345d9cac623b59ac7888bf394523bb8e
parentc5ea43fc9956135077ad839c4e03f72d8fc51220 (diff)
downloadmariadb-git-5569b3eb091d54664c75f13564510daa74c56288.tar.gz
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 54a492ecac792a13f374978ba0584d3e7eb9ab77 more than 10 years ago.
-rw-r--r--mysql-test/suite/innodb/r/innodb-isolation.result8
-rw-r--r--mysql-test/suite/innodb/r/innodb.result2
-rw-r--r--mysql-test/suite/innodb/t/innodb-isolation.test1
-rw-r--r--storage/innobase/handler/ha_innodb.cc26
4 files changed, 22 insertions, 15 deletions
diff --git a/mysql-test/suite/innodb/r/innodb-isolation.result b/mysql-test/suite/innodb/r/innodb-isolation.result
index 2248d25b39a..ce9c530ff44 100644
--- a/mysql-test/suite/innodb/r/innodb-isolation.result
+++ b/mysql-test/suite/innodb/r/innodb-isolation.result
@@ -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
diff --git a/mysql-test/suite/innodb/r/innodb.result b/mysql-test/suite/innodb/r/innodb.result
index ed8720a0df9..0d92968b095 100644
--- a/mysql-test/suite/innodb/r/innodb.result
+++ b/mysql-test/suite/innodb/r/innodb.result
@@ -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
diff --git a/mysql-test/suite/innodb/t/innodb-isolation.test b/mysql-test/suite/innodb/t/innodb-isolation.test
index 56cd668b305..d00fefb9fc6 100644
--- a/mysql-test/suite/innodb/t/innodb-isolation.test
+++ b/mysql-test/suite/innodb/t/innodb-isolation.test
@@ -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;
diff --git a/storage/innobase/handler/ha_innodb.cc b/storage/innobase/handler/ha_innodb.cc
index b4b61019e31..fd8e2de4819 100644
--- a/storage/innobase/handler/ha_innodb.cc
+++ b/storage/innobase/handler/ha_innodb.cc
@@ -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