diff options
106 files changed, 936 insertions, 1924 deletions
diff --git a/mysql-test/extra/binlog_tests/drop_temp_table.test b/mysql-test/extra/binlog_tests/drop_temp_table.test index c852ee4c8a0..4241974d813 100644 --- a/mysql-test/extra/binlog_tests/drop_temp_table.test +++ b/mysql-test/extra/binlog_tests/drop_temp_table.test @@ -14,12 +14,8 @@ CREATE TEMPORARY TABLE `table:name` (a INT); CREATE TEMPORARY TABLE shortn2 (a INT); ############################################################################## -# BUG#46572 DROP TEMPORARY table IF EXISTS does not have a consistent behavior -# in ROW mode -# -# In RBR, 'DROP TEMPORARY TABLE ...' statement should never be binlogged no -# matter if the tables exist or not. In contrast, both in SBR and MBR, the -# statement should be always binlogged no matter if the tables exist or not. +# MDEV-20091: DROP TEMPORARY TABLE IF EXISTS statements will be written +# to binlog only if the corresponding temporary table exists. ############################################################################## CREATE TEMPORARY TABLE tmp(c1 int); CREATE TEMPORARY TABLE tmp1(c1 int); @@ -30,12 +26,12 @@ CREATE TABLE t(c1 int); DROP TEMPORARY TABLE IF EXISTS tmp; --disable_warnings -# Before fixing BUG#46572, 'DROP TEMPORARY TABLE IF EXISTS...' statement was -# binlogged when the table did not exist in RBR. +# Post MDEV-20091: Following DROP TEMPORARY TABLE statement should not be +# logged as the table is already dropped above. DROP TEMPORARY TABLE IF EXISTS tmp; -# In RBR, 'DROP TEMPORARY TABLE ...' statement is never binlogged no matter if -# the tables exist or not. +# Post MDEV-20091: Only DROP TEMPORARY TABLE statement should be written only +# for 'tmp1' table. DROP TEMPORARY TABLE IF EXISTS tmp, tmp1; DROP TEMPORARY TABLE tmp3; @@ -79,6 +75,12 @@ DROP DATABASE `drop-temp+table-test`; # if there are open temporary tables. As such the implicit drop # for temporary tables on session closing must be logged. # +# MDEV-20091: DROP TEMPORARY TABLE IF EXISTS statements will be written to +# binlog only if the corresponding temporary table exists. In row based +# replication temporary tables are not replicated hence their corresponding +# DROP TEMPORARY TABLE statement will be not be written to binary log upon +# session closure. +# RESET MASTER; @@ -92,8 +94,10 @@ SELECT @@session.binlog_format; --disconnect con1 -- connection default +if (!`SELECT @@BINLOG_FORMAT = 'ROW'`) { --let $wait_binlog_event= DROP --source include/wait_for_binlog_event.inc +} -- source include/show_binlog_events.inc RESET MASTER; diff --git a/mysql-test/extra/rpl_tests/rpl_drop_create_temp_table.test b/mysql-test/extra/rpl_tests/rpl_drop_create_temp_table.test index ffd7fe1a5c4..f8b521e3abf 100644 --- a/mysql-test/extra/rpl_tests/rpl_drop_create_temp_table.test +++ b/mysql-test/extra/rpl_tests/rpl_drop_create_temp_table.test @@ -32,6 +32,10 @@ # is any # Drop-Temp-TT-Temp - Drops two temporary T-tables if there is any # Drop-Temp-NN-Temp - Drops two temporary N-tables if there is any +# +# Note: MDEV-20091: DROP TEMPORARY TABLE IF EXISTS statements will be written +# to binlog only if the corresponding temporary table exists. +# # Drop-Temp-Xe-Temp - Tries to drop a temporary table that does not exist # Drop-Temp-NXe-Temp - Drops a temporary N-table if there is any and # a temporary table that does not exist diff --git a/mysql-test/include/binlog_parallel_replication_marks.test b/mysql-test/include/binlog_parallel_replication_marks.test index b915d26ce99..82fa997822d 100644 --- a/mysql-test/include/binlog_parallel_replication_marks.test +++ b/mysql-test/include/binlog_parallel_replication_marks.test @@ -49,9 +49,16 @@ connection default; # We need to wait for the implicit DROP TEMPORARY TABLE to be logged after # tmp_con disconnect, otherwise we get sporadic test failures. +# MDEV-20091: DROP TEMPORARY TABLE IF EXISTS statements will be written to +# binlog only if the corresponding temporary table exists. In row based +# replication temporary tables are not replicated hence their corresponding +# DROP TEMPORARY TABLE statement will be not be written to binary log upon +# session closure. + +if (!`SELECT @@BINLOG_FORMAT = 'ROW'`) { --let $wait_condition= SELECT variable_value > $before_drop_pos FROM information_schema.global_status WHERE variable_name = 'binlog_snapshot_position' --source include/wait_condition.inc - +} --let $binlog_pos2=query_get_value(SHOW MASTER STATUS, Position, 1) --let $binlog_file= query_get_value(SHOW MASTER STATUS, File, 1) diff --git a/mysql-test/suite/binlog/r/binlog_parallel_replication_marks_row.result b/mysql-test/suite/binlog/r/binlog_parallel_replication_marks_row.result index d63538e5318..c4a1ba9b83b 100644 --- a/mysql-test/suite/binlog/r/binlog_parallel_replication_marks_row.result +++ b/mysql-test/suite/binlog/r/binlog_parallel_replication_marks_row.result @@ -105,6 +105,4 @@ BEGIN # server id 1 end_log_pos # CRC32 0x######## Table_map: `test`.`t1` mapped to number # # server id 1 end_log_pos # CRC32 0x######## Write_rows: table id # flags: STMT_END_F COMMIT/*!*/; -# server id 1 end_log_pos # CRC32 0x######## GTID #-#-# ddl -DROP /*!40005 TEMPORARY */ TABLE IF EXISTS `t5` DROP TABLE t1; diff --git a/mysql-test/suite/binlog/r/binlog_row_drop_tmp_tbl.result b/mysql-test/suite/binlog/r/binlog_row_drop_tmp_tbl.result index 4b35170b2db..831a1c8a9a3 100644 --- a/mysql-test/suite/binlog/r/binlog_row_drop_tmp_tbl.result +++ b/mysql-test/suite/binlog/r/binlog_row_drop_tmp_tbl.result @@ -35,15 +35,9 @@ master-bin.000001 # Query # # CREATE DATABASE `drop-temp+table-test` master-bin.000001 # Gtid # # GTID #-#-# master-bin.000001 # Query # # use `drop-temp+table-test`; CREATE TABLE t(c1 int) master-bin.000001 # Gtid # # GTID #-#-# -master-bin.000001 # Query # # DROP TEMPORARY TABLE IF EXISTS `drop-temp+table-test`.`tmp` /* generated by server */ -master-bin.000001 # Gtid # # GTID #-#-# -master-bin.000001 # Query # # DROP TEMPORARY TABLE IF EXISTS `drop-temp+table-test`.`tmp` /* generated by server */ -master-bin.000001 # Gtid # # GTID #-#-# master-bin.000001 # Query # # use `drop-temp+table-test`; DROP TABLE IF EXISTS `t` /* generated by server */ master-bin.000001 # Gtid # # GTID #-#-# master-bin.000001 # Query # # use `drop-temp+table-test`; DROP TABLE IF EXISTS `tmp2`,`t` /* generated by server */ -master-bin.000001 # Gtid # # GTID #-#-# -master-bin.000001 # Query # # use `drop-temp+table-test`; DROP /*!40005 TEMPORARY */ TABLE IF EXISTS `shortn2`,`table:name`,`shortn1` DROP DATABASE `drop-temp+table-test`; RESET MASTER; CREATE TABLE t1 ( i text ); @@ -65,7 +59,5 @@ master-bin.000001 # Annotate_rows # # INSERT INTO t1 VALUES ('1') master-bin.000001 # Table_map # # table_id: # (test.t1) master-bin.000001 # Write_rows_v1 # # table_id: # flags: STMT_END_F master-bin.000001 # Query # # COMMIT -master-bin.000001 # Gtid # # GTID #-#-# -master-bin.000001 # Query # # use `test`; DROP /*!40005 TEMPORARY */ TABLE IF EXISTS `ttmp1` RESET MASTER; DROP TABLE t1; diff --git a/mysql-test/suite/binlog/r/binlog_row_mix_innodb_myisam.result b/mysql-test/suite/binlog/r/binlog_row_mix_innodb_myisam.result index 0bff58fda2a..88d1f7dd42e 100644 --- a/mysql-test/suite/binlog/r/binlog_row_mix_innodb_myisam.result +++ b/mysql-test/suite/binlog/r/binlog_row_mix_innodb_myisam.result @@ -348,8 +348,6 @@ master-bin.000001 # Write_rows_v1 # # table_id: # flags: STMT_END_F master-bin.000001 # Query # # COMMIT master-bin.000001 # Gtid # # GTID #-#-# master-bin.000001 # Query # # use `test`; create table t2 (n int) engine=innodb -master-bin.000001 # Gtid # # GTID #-#-# -master-bin.000001 # Query # # use `test`; DROP /*!40005 TEMPORARY */ TABLE IF EXISTS `t1`,`ti` do release_lock("lock1"); drop table t0,t2; set autocommit=0; diff --git a/mysql-test/suite/binlog/r/binlog_stm_drop_tmp_tbl.result b/mysql-test/suite/binlog/r/binlog_stm_drop_tmp_tbl.result index 8340420f5ad..4bca7cbe298 100644 --- a/mysql-test/suite/binlog/r/binlog_stm_drop_tmp_tbl.result +++ b/mysql-test/suite/binlog/r/binlog_stm_drop_tmp_tbl.result @@ -51,12 +51,8 @@ master-bin.000001 # Query # # use `drop-temp+table-test`; CREATE TABLE t(c1 int) master-bin.000001 # Gtid # # GTID #-#-# master-bin.000001 # Query # # DROP TEMPORARY TABLE IF EXISTS `drop-temp+table-test`.`tmp` /* generated by server */ master-bin.000001 # Gtid # # GTID #-#-# -master-bin.000001 # Query # # DROP TEMPORARY TABLE IF EXISTS `drop-temp+table-test`.`tmp` /* generated by server */ -master-bin.000001 # Gtid # # GTID #-#-# master-bin.000001 # Query # # DROP TEMPORARY TABLE IF EXISTS `drop-temp+table-test`.`tmp1` /* generated by server */ master-bin.000001 # Gtid # # GTID #-#-# -master-bin.000001 # Query # # DROP TEMPORARY TABLE IF EXISTS `drop-temp+table-test`.`tmp` /* generated by server */ -master-bin.000001 # Gtid # # GTID #-#-# master-bin.000001 # Query # # use `drop-temp+table-test`; DROP TEMPORARY TABLE `tmp3` /* generated by server */ master-bin.000001 # Gtid # # GTID #-#-# master-bin.000001 # Query # # DROP TEMPORARY TABLE IF EXISTS `drop-temp+table-test`.`tmp2` /* generated by server */ diff --git a/mysql-test/suite/rpl/r/create_or_replace_mix.result b/mysql-test/suite/rpl/r/create_or_replace_mix.result index 6ad37ab5e46..661278aa7ef 100644 --- a/mysql-test/suite/rpl/r/create_or_replace_mix.result +++ b/mysql-test/suite/rpl/r/create_or_replace_mix.result @@ -265,6 +265,16 @@ set binlog_format="STATEMENT"; ERROR HY000: Cannot switch out of the row-based binary log format when the session has open temporary tables drop temporary table t8; set @@binlog_format=@org_binlog_format; +set @@session.binlog_format=default; +drop temporary table if exists t9; +Warnings: +Note 1051 Unknown table 'test.t9' +connect con1,localhost,root,,; +set session binlog_format=default; +create temporary table t9 (i int); +*** Must be no DROP logged for t9 when there was no CREATE, at disconnect too *** +disconnect con1; +connection server_1; include/show_binlog_events.inc Log_name Pos Event_type Server_id End_log_pos Info master-bin.000001 # Gtid # # GTID #-#-# @@ -275,5 +285,9 @@ master-bin.000001 # Gtid # # GTID #-#-# master-bin.000001 # Query # # use `test`; create temporary table t7 (a int) master-bin.000001 # Gtid # # GTID #-#-# master-bin.000001 # Query # # DROP TEMPORARY TABLE IF EXISTS `test`.`t7` /* generated by server */ +master-bin.000001 # Gtid # # GTID #-#-# +master-bin.000001 # Query # # use `test`; create temporary table t9 (i int) +master-bin.000001 # Gtid # # GTID #-#-# +master-bin.000001 # Query # # use `test`; DROP /*!40005 TEMPORARY */ TABLE IF EXISTS `t9` drop table t2; include/rpl_end.inc diff --git a/mysql-test/suite/rpl/r/create_or_replace_row.result b/mysql-test/suite/rpl/r/create_or_replace_row.result index ad7a537a2c9..c45daefd671 100644 --- a/mysql-test/suite/rpl/r/create_or_replace_row.result +++ b/mysql-test/suite/rpl/r/create_or_replace_row.result @@ -293,6 +293,16 @@ set binlog_format="STATEMENT"; ERROR HY000: Cannot switch out of the row-based binary log format when the session has open temporary tables drop temporary table t8; set @@binlog_format=@org_binlog_format; +set @@session.binlog_format=default; +drop temporary table if exists t9; +Warnings: +Note 1051 Unknown table 'test.t9' +connect con1,localhost,root,,; +set session binlog_format=default; +create temporary table t9 (i int); +*** Must be no DROP logged for t9 when there was no CREATE, at disconnect too *** +disconnect con1; +connection server_1; include/show_binlog_events.inc Log_name Pos Event_type Server_id End_log_pos Info master-bin.000001 # Gtid # # GTID #-#-# diff --git a/mysql-test/suite/rpl/r/create_or_replace_statement.result b/mysql-test/suite/rpl/r/create_or_replace_statement.result index 69206cc861f..f95b451e5ec 100644 --- a/mysql-test/suite/rpl/r/create_or_replace_statement.result +++ b/mysql-test/suite/rpl/r/create_or_replace_statement.result @@ -252,6 +252,16 @@ set binlog_format="STATEMENT"; ERROR HY000: Cannot switch out of the row-based binary log format when the session has open temporary tables drop temporary table t8; set @@binlog_format=@org_binlog_format; +set @@session.binlog_format=default; +drop temporary table if exists t9; +Warnings: +Note 1051 Unknown table 'test.t9' +connect con1,localhost,root,,; +set session binlog_format=default; +create temporary table t9 (i int); +*** Must be no DROP logged for t9 when there was no CREATE, at disconnect too *** +disconnect con1; +connection server_1; include/show_binlog_events.inc Log_name Pos Event_type Server_id End_log_pos Info master-bin.000001 # Gtid # # GTID #-#-# @@ -262,5 +272,9 @@ master-bin.000001 # Gtid # # GTID #-#-# master-bin.000001 # Query # # use `test`; create temporary table t7 (a int) master-bin.000001 # Gtid # # GTID #-#-# master-bin.000001 # Query # # DROP TEMPORARY TABLE IF EXISTS `test`.`t7` /* generated by server */ +master-bin.000001 # Gtid # # GTID #-#-# +master-bin.000001 # Query # # use `test`; create temporary table t9 (i int) +master-bin.000001 # Gtid # # GTID #-#-# +master-bin.000001 # Query # # use `test`; DROP /*!40005 TEMPORARY */ TABLE IF EXISTS `t9` drop table t2; include/rpl_end.inc diff --git a/mysql-test/suite/rpl/r/rpl_mixed_drop_create_temp_table.result b/mysql-test/suite/rpl/r/rpl_mixed_drop_create_temp_table.result index 76f812b7512..d2f590ad136 100644 --- a/mysql-test/suite/rpl/r/rpl_mixed_drop_create_temp_table.result +++ b/mysql-test/suite/rpl/r/rpl_mixed_drop_create_temp_table.result @@ -91,9 +91,6 @@ Warnings: Note 1051 Unknown table 'test.tt_xx_1' -b-b-b-b-b-b-b-b-b-b-b- >> Drop-Temp-If-Xe-Temp << -b-b-b-b-b-b-b-b-b-b-b- include/show_binlog_events.inc -Log_name Pos Event_type Server_id End_log_pos Info -master-bin.000001 # Gtid # # GTID #-#-# -master-bin.000001 # Query # # DROP TEMPORARY TABLE IF EXISTS `test`.`tt_xx_1` /* generated by server */ -e-e-e-e-e-e-e-e-e-e-e- >> Drop-Temp-If-Xe-Temp << -e-e-e-e-e-e-e-e-e-e-e- SET @commands= 'Drop-Temp-TXe-Temp'; @@ -114,7 +111,7 @@ Note 1051 Unknown table 'test.tt_1' include/show_binlog_events.inc Log_name Pos Event_type Server_id End_log_pos Info master-bin.000001 # Gtid # # GTID #-#-# -master-bin.000001 # Query # # DROP TEMPORARY TABLE IF EXISTS `test`.`tt_tmp_2`,`test`.`tt_1` /* generated by server */ +master-bin.000001 # Query # # DROP TEMPORARY TABLE IF EXISTS `test`.`tt_tmp_2` /* generated by server */ -e-e-e-e-e-e-e-e-e-e-e- >> Drop-Temp-If-TXe-Temp << -e-e-e-e-e-e-e-e-e-e-e- SET @commands= 'Drop-Temp-NXe-Temp'; @@ -136,8 +133,6 @@ include/show_binlog_events.inc Log_name Pos Event_type Server_id End_log_pos Info master-bin.000001 # Gtid # # GTID #-#-# master-bin.000001 # Query # # DROP TEMPORARY TABLE IF EXISTS `test`.`nt_tmp_2` /* generated by server */ -master-bin.000001 # Gtid # # GTID #-#-# -master-bin.000001 # Query # # DROP TEMPORARY TABLE IF EXISTS `test`.`tt_1` /* generated by server */ -e-e-e-e-e-e-e-e-e-e-e- >> Drop-Temp-If-NXe-Temp << -e-e-e-e-e-e-e-e-e-e-e- SET @commands= 'Drop-Temp-TN-Temp'; @@ -293,7 +288,6 @@ include/show_binlog_events.inc Log_name Pos Event_type Server_id End_log_pos Info master-bin.000001 # Gtid # # BEGIN GTID #-#-# master-bin.000001 # Query # # use `test`; INSERT INTO tt_xx_1() VALUES (1) -master-bin.000001 # Query # # DROP TEMPORARY TABLE IF EXISTS `test`.`tt_xx_1` /* generated by server */ master-bin.000001 # Xid # # COMMIT /* XID */ -e-e-e-e-e-e-e-e-e-e-e- >> B T Drop-Temp-If-Xe-Temp C << -e-e-e-e-e-e-e-e-e-e-e- @@ -316,8 +310,6 @@ master-bin.000001 # Query # # use `test`; INSERT INTO nt_xx_1() VALUES (1) master-bin.000001 # Query # # COMMIT master-bin.000001 # Gtid # # BEGIN GTID #-#-# master-bin.000001 # Query # # use `test`; INSERT INTO tt_xx_1() VALUES (1) -master-bin.000001 # Query # # DROP TEMPORARY TABLE IF EXISTS `test`.`tt_xx_1` /* generated by server */ -master-bin.000001 # Query # # DROP TEMPORARY TABLE IF EXISTS `test`.`tt_xx_1` /* generated by server */ master-bin.000001 # Xid # # COMMIT /* XID */ -e-e-e-e-e-e-e-e-e-e-e- >> B T Drop-Temp-If-Xe-Temp N Drop-Temp-If-Xe-Temp C << -e-e-e-e-e-e-e-e-e-e-e- @@ -370,7 +362,7 @@ include/show_binlog_events.inc Log_name Pos Event_type Server_id End_log_pos Info master-bin.000001 # Gtid # # BEGIN GTID #-#-# master-bin.000001 # Query # # use `test`; INSERT INTO tt_xx_1() VALUES (1) -master-bin.000001 # Query # # DROP TEMPORARY TABLE IF EXISTS `test`.`tt_tmp_2`,`test`.`tt_1` /* generated by server */ +master-bin.000001 # Query # # DROP TEMPORARY TABLE IF EXISTS `test`.`tt_tmp_2` /* generated by server */ master-bin.000001 # Xid # # COMMIT /* XID */ -e-e-e-e-e-e-e-e-e-e-e- >> B T Drop-Temp-If-TXe-Temp C << -e-e-e-e-e-e-e-e-e-e-e- @@ -393,8 +385,8 @@ master-bin.000001 # Query # # use `test`; INSERT INTO nt_xx_1() VALUES (1) master-bin.000001 # Query # # COMMIT master-bin.000001 # Gtid # # BEGIN GTID #-#-# master-bin.000001 # Query # # use `test`; INSERT INTO tt_xx_1() VALUES (1) -master-bin.000001 # Query # # DROP TEMPORARY TABLE IF EXISTS `test`.`tt_tmp_2`,`test`.`tt_1` /* generated by server */ -master-bin.000001 # Query # # DROP TEMPORARY TABLE IF EXISTS `test`.`tt_tmp_1`,`test`.`tt_1` /* generated by server */ +master-bin.000001 # Query # # DROP TEMPORARY TABLE IF EXISTS `test`.`tt_tmp_2` /* generated by server */ +master-bin.000001 # Query # # DROP TEMPORARY TABLE IF EXISTS `test`.`tt_tmp_1` /* generated by server */ master-bin.000001 # Xid # # COMMIT /* XID */ -e-e-e-e-e-e-e-e-e-e-e- >> B T Drop-Temp-If-TXe-Temp N Drop-Temp-If-TXe-Temp C << -e-e-e-e-e-e-e-e-e-e-e- @@ -456,7 +448,6 @@ master-bin.000001 # Query # # DROP TEMPORARY TABLE IF EXISTS `test`.`nt_tmp_2` / master-bin.000001 # Query # # COMMIT master-bin.000001 # Gtid # # BEGIN GTID #-#-# master-bin.000001 # Query # # use `test`; INSERT INTO tt_xx_1() VALUES (1) -master-bin.000001 # Query # # DROP TEMPORARY TABLE IF EXISTS `test`.`tt_1` /* generated by server */ master-bin.000001 # Xid # # COMMIT /* XID */ -e-e-e-e-e-e-e-e-e-e-e- >> B T Drop-Temp-If-NXe-Temp C << -e-e-e-e-e-e-e-e-e-e-e- @@ -485,8 +476,6 @@ master-bin.000001 # Query # # DROP TEMPORARY TABLE IF EXISTS `test`.`nt_tmp_1` / master-bin.000001 # Query # # COMMIT master-bin.000001 # Gtid # # BEGIN GTID #-#-# master-bin.000001 # Query # # use `test`; INSERT INTO tt_xx_1() VALUES (1) -master-bin.000001 # Query # # DROP TEMPORARY TABLE IF EXISTS `test`.`tt_1` /* generated by server */ -master-bin.000001 # Query # # DROP TEMPORARY TABLE IF EXISTS `test`.`tt_1` /* generated by server */ master-bin.000001 # Xid # # COMMIT /* XID */ -e-e-e-e-e-e-e-e-e-e-e- >> B T Drop-Temp-If-NXe-Temp N Drop-Temp-If-NXe-Temp C << -e-e-e-e-e-e-e-e-e-e-e- @@ -803,7 +792,6 @@ include/show_binlog_events.inc Log_name Pos Event_type Server_id End_log_pos Info master-bin.000001 # Gtid # # BEGIN GTID #-#-# master-bin.000001 # Query # # use `test`; INSERT INTO tt_xx_1() VALUES (1) -master-bin.000001 # Query # # DROP TEMPORARY TABLE IF EXISTS `test`.`tt_xx_1` /* generated by server */ master-bin.000001 # Query # # ROLLBACK -e-e-e-e-e-e-e-e-e-e-e- >> B T Drop-Temp-If-Xe-Temp R << -e-e-e-e-e-e-e-e-e-e-e- @@ -828,8 +816,6 @@ master-bin.000001 # Query # # use `test`; INSERT INTO nt_xx_1() VALUES (1) master-bin.000001 # Query # # COMMIT master-bin.000001 # Gtid # # BEGIN GTID #-#-# master-bin.000001 # Query # # use `test`; INSERT INTO tt_xx_1() VALUES (1) -master-bin.000001 # Query # # DROP TEMPORARY TABLE IF EXISTS `test`.`tt_xx_1` /* generated by server */ -master-bin.000001 # Query # # DROP TEMPORARY TABLE IF EXISTS `test`.`tt_xx_1` /* generated by server */ master-bin.000001 # Query # # ROLLBACK -e-e-e-e-e-e-e-e-e-e-e- >> B T Drop-Temp-If-Xe-Temp N Drop-Temp-If-Xe-Temp R << -e-e-e-e-e-e-e-e-e-e-e- @@ -884,7 +870,7 @@ include/show_binlog_events.inc Log_name Pos Event_type Server_id End_log_pos Info master-bin.000001 # Gtid # # BEGIN GTID #-#-# master-bin.000001 # Query # # use `test`; INSERT INTO tt_xx_1() VALUES (1) -master-bin.000001 # Query # # DROP TEMPORARY TABLE IF EXISTS `test`.`tt_tmp_2`,`test`.`tt_1` /* generated by server */ +master-bin.000001 # Query # # DROP TEMPORARY TABLE IF EXISTS `test`.`tt_tmp_2` /* generated by server */ master-bin.000001 # Query # # ROLLBACK -e-e-e-e-e-e-e-e-e-e-e- >> B T Drop-Temp-If-TXe-Temp R << -e-e-e-e-e-e-e-e-e-e-e- @@ -909,8 +895,8 @@ master-bin.000001 # Query # # use `test`; INSERT INTO nt_xx_1() VALUES (1) master-bin.000001 # Query # # COMMIT master-bin.000001 # Gtid # # BEGIN GTID #-#-# master-bin.000001 # Query # # use `test`; INSERT INTO tt_xx_1() VALUES (1) -master-bin.000001 # Query # # DROP TEMPORARY TABLE IF EXISTS `test`.`tt_tmp_2`,`test`.`tt_1` /* generated by server */ -master-bin.000001 # Query # # DROP TEMPORARY TABLE IF EXISTS `test`.`tt_tmp_1`,`test`.`tt_1` /* generated by server */ +master-bin.000001 # Query # # DROP TEMPORARY TABLE IF EXISTS `test`.`tt_tmp_2` /* generated by server */ +master-bin.000001 # Query # # DROP TEMPORARY TABLE IF EXISTS `test`.`tt_tmp_1` /* generated by server */ master-bin.000001 # Query # # ROLLBACK -e-e-e-e-e-e-e-e-e-e-e- >> B T Drop-Temp-If-TXe-Temp N Drop-Temp-If-TXe-Temp R << -e-e-e-e-e-e-e-e-e-e-e- @@ -974,7 +960,6 @@ master-bin.000001 # Query # # DROP TEMPORARY TABLE IF EXISTS `test`.`nt_tmp_2` / master-bin.000001 # Query # # COMMIT master-bin.000001 # Gtid # # BEGIN GTID #-#-# master-bin.000001 # Query # # use `test`; INSERT INTO tt_xx_1() VALUES (1) -master-bin.000001 # Query # # DROP TEMPORARY TABLE IF EXISTS `test`.`tt_1` /* generated by server */ master-bin.000001 # Query # # ROLLBACK -e-e-e-e-e-e-e-e-e-e-e- >> B T Drop-Temp-If-NXe-Temp R << -e-e-e-e-e-e-e-e-e-e-e- @@ -1005,8 +990,6 @@ master-bin.000001 # Query # # DROP TEMPORARY TABLE IF EXISTS `test`.`nt_tmp_1` / master-bin.000001 # Query # # COMMIT master-bin.000001 # Gtid # # BEGIN GTID #-#-# master-bin.000001 # Query # # use `test`; INSERT INTO tt_xx_1() VALUES (1) -master-bin.000001 # Query # # DROP TEMPORARY TABLE IF EXISTS `test`.`tt_1` /* generated by server */ -master-bin.000001 # Query # # DROP TEMPORARY TABLE IF EXISTS `test`.`tt_1` /* generated by server */ master-bin.000001 # Query # # ROLLBACK -e-e-e-e-e-e-e-e-e-e-e- >> B T Drop-Temp-If-NXe-Temp N Drop-Temp-If-NXe-Temp R << -e-e-e-e-e-e-e-e-e-e-e- diff --git a/mysql-test/suite/rpl/r/rpl_row_drop_create_temp_table.result b/mysql-test/suite/rpl/r/rpl_row_drop_create_temp_table.result index cc85e454cd2..f6e04b950d8 100644 --- a/mysql-test/suite/rpl/r/rpl_row_drop_create_temp_table.result +++ b/mysql-test/suite/rpl/r/rpl_row_drop_create_temp_table.result @@ -85,9 +85,6 @@ Warnings: Note 1051 Unknown table 'test.tt_xx_1' -b-b-b-b-b-b-b-b-b-b-b- >> Drop-Temp-If-Xe-Temp << -b-b-b-b-b-b-b-b-b-b-b- include/show_binlog_events.inc -Log_name Pos Event_type Server_id End_log_pos Info -master-bin.000001 # Gtid # # GTID #-#-# -master-bin.000001 # Query # # DROP TEMPORARY TABLE IF EXISTS `test`.`tt_xx_1` /* generated by server */ -e-e-e-e-e-e-e-e-e-e-e- >> Drop-Temp-If-Xe-Temp << -e-e-e-e-e-e-e-e-e-e-e- SET @commands= 'Drop-Temp-TXe-Temp'; @@ -103,9 +100,6 @@ Warnings: Note 1051 Unknown table 'test.tt_1' -b-b-b-b-b-b-b-b-b-b-b- >> Drop-Temp-If-TXe-Temp << -b-b-b-b-b-b-b-b-b-b-b- include/show_binlog_events.inc -Log_name Pos Event_type Server_id End_log_pos Info -master-bin.000001 # Gtid # # GTID #-#-# -master-bin.000001 # Query # # DROP TEMPORARY TABLE IF EXISTS `test`.`tt_1` /* generated by server */ -e-e-e-e-e-e-e-e-e-e-e- >> Drop-Temp-If-TXe-Temp << -e-e-e-e-e-e-e-e-e-e-e- SET @commands= 'Drop-Temp-NXe-Temp'; @@ -121,9 +115,6 @@ Warnings: Note 1051 Unknown table 'test.tt_1' -b-b-b-b-b-b-b-b-b-b-b- >> Drop-Temp-If-NXe-Temp << -b-b-b-b-b-b-b-b-b-b-b- include/show_binlog_events.inc -Log_name Pos Event_type Server_id End_log_pos Info -master-bin.000001 # Gtid # # GTID #-#-# -master-bin.000001 # Query # # DROP TEMPORARY TABLE IF EXISTS `test`.`tt_1` /* generated by server */ -e-e-e-e-e-e-e-e-e-e-e- >> Drop-Temp-If-NXe-Temp << -e-e-e-e-e-e-e-e-e-e-e- SET @commands= 'Drop-Temp-TN-Temp'; @@ -276,7 +267,6 @@ master-bin.000001 # Gtid # # BEGIN GTID #-#-# master-bin.000001 # Annotate_rows # # INSERT INTO tt_xx_1() VALUES (1) master-bin.000001 # Table_map # # table_id: # (test.tt_xx_1) master-bin.000001 # Write_rows_v1 # # table_id: # flags: STMT_END_F -master-bin.000001 # Query # # DROP TEMPORARY TABLE IF EXISTS `test`.`tt_xx_1` /* generated by server */ master-bin.000001 # Xid # # COMMIT /* XID */ -e-e-e-e-e-e-e-e-e-e-e- >> B T Drop-Temp-If-Xe-Temp C << -e-e-e-e-e-e-e-e-e-e-e- @@ -303,8 +293,6 @@ master-bin.000001 # Gtid # # BEGIN GTID #-#-# master-bin.000001 # Annotate_rows # # INSERT INTO tt_xx_1() VALUES (1) master-bin.000001 # Table_map # # table_id: # (test.tt_xx_1) master-bin.000001 # Write_rows_v1 # # table_id: # flags: STMT_END_F -master-bin.000001 # Query # # DROP TEMPORARY TABLE IF EXISTS `test`.`tt_xx_1` /* generated by server */ -master-bin.000001 # Query # # DROP TEMPORARY TABLE IF EXISTS `test`.`tt_xx_1` /* generated by server */ master-bin.000001 # Xid # # COMMIT /* XID */ -e-e-e-e-e-e-e-e-e-e-e- >> B T Drop-Temp-If-Xe-Temp N Drop-Temp-If-Xe-Temp C << -e-e-e-e-e-e-e-e-e-e-e- @@ -362,7 +350,6 @@ master-bin.000001 # Gtid # # BEGIN GTID #-#-# master-bin.000001 # Annotate_rows # # INSERT INTO tt_xx_1() VALUES (1) master-bin.000001 # Table_map # # table_id: # (test.tt_xx_1) master-bin.000001 # Write_rows_v1 # # table_id: # flags: STMT_END_F -master-bin.000001 # Query # # DROP TEMPORARY TABLE IF EXISTS `test`.`tt_1` /* generated by server */ master-bin.000001 # Xid # # COMMIT /* XID */ -e-e-e-e-e-e-e-e-e-e-e- >> B T Drop-Temp-If-TXe-Temp C << -e-e-e-e-e-e-e-e-e-e-e- @@ -389,8 +376,6 @@ master-bin.000001 # Gtid # # BEGIN GTID #-#-# master-bin.000001 # Annotate_rows # # INSERT INTO tt_xx_1() VALUES (1) master-bin.000001 # Table_map # # table_id: # (test.tt_xx_1) master-bin.000001 # Write_rows_v1 # # table_id: # flags: STMT_END_F -master-bin.000001 # Query # # DROP TEMPORARY TABLE IF EXISTS `test`.`tt_1` /* generated by server */ -master-bin.000001 # Query # # DROP TEMPORARY TABLE IF EXISTS `test`.`tt_1` /* generated by server */ master-bin.000001 # Xid # # COMMIT /* XID */ -e-e-e-e-e-e-e-e-e-e-e- >> B T Drop-Temp-If-TXe-Temp N Drop-Temp-If-TXe-Temp C << -e-e-e-e-e-e-e-e-e-e-e- @@ -448,7 +433,6 @@ master-bin.000001 # Gtid # # BEGIN GTID #-#-# master-bin.000001 # Annotate_rows # # INSERT INTO tt_xx_1() VALUES (1) master-bin.000001 # Table_map # # table_id: # (test.tt_xx_1) master-bin.000001 # Write_rows_v1 # # table_id: # flags: STMT_END_F -master-bin.000001 # Query # # DROP TEMPORARY TABLE IF EXISTS `test`.`tt_1` /* generated by server */ master-bin.000001 # Xid # # COMMIT /* XID */ -e-e-e-e-e-e-e-e-e-e-e- >> B T Drop-Temp-If-NXe-Temp C << -e-e-e-e-e-e-e-e-e-e-e- @@ -475,8 +459,6 @@ master-bin.000001 # Gtid # # BEGIN GTID #-#-# master-bin.000001 # Annotate_rows # # INSERT INTO tt_xx_1() VALUES (1) master-bin.000001 # Table_map # # table_id: # (test.tt_xx_1) master-bin.000001 # Write_rows_v1 # # table_id: # flags: STMT_END_F -master-bin.000001 # Query # # DROP TEMPORARY TABLE IF EXISTS `test`.`tt_1` /* generated by server */ -master-bin.000001 # Query # # DROP TEMPORARY TABLE IF EXISTS `test`.`tt_1` /* generated by server */ master-bin.000001 # Xid # # COMMIT /* XID */ -e-e-e-e-e-e-e-e-e-e-e- >> B T Drop-Temp-If-NXe-Temp N Drop-Temp-If-NXe-Temp C << -e-e-e-e-e-e-e-e-e-e-e- @@ -809,7 +791,6 @@ master-bin.000001 # Gtid # # BEGIN GTID #-#-# master-bin.000001 # Annotate_rows # # INSERT INTO tt_xx_1() VALUES (1) master-bin.000001 # Table_map # # table_id: # (test.tt_xx_1) master-bin.000001 # Write_rows_v1 # # table_id: # flags: STMT_END_F -master-bin.000001 # Query # # DROP TEMPORARY TABLE IF EXISTS `test`.`tt_xx_1` /* generated by server */ master-bin.000001 # Query # # ROLLBACK -e-e-e-e-e-e-e-e-e-e-e- >> B T Drop-Temp-If-Xe-Temp R << -e-e-e-e-e-e-e-e-e-e-e- @@ -838,8 +819,6 @@ master-bin.000001 # Gtid # # BEGIN GTID #-#-# master-bin.000001 # Annotate_rows # # INSERT INTO tt_xx_1() VALUES (1) master-bin.000001 # Table_map # # table_id: # (test.tt_xx_1) master-bin.000001 # Write_rows_v1 # # table_id: # flags: STMT_END_F -master-bin.000001 # Query # # DROP TEMPORARY TABLE IF EXISTS `test`.`tt_xx_1` /* generated by server */ -master-bin.000001 # Query # # DROP TEMPORARY TABLE IF EXISTS `test`.`tt_xx_1` /* generated by server */ master-bin.000001 # Query # # ROLLBACK -e-e-e-e-e-e-e-e-e-e-e- >> B T Drop-Temp-If-Xe-Temp N Drop-Temp-If-Xe-Temp R << -e-e-e-e-e-e-e-e-e-e-e- @@ -899,7 +878,6 @@ master-bin.000001 # Gtid # # BEGIN GTID #-#-# master-bin.000001 # Annotate_rows # # INSERT INTO tt_xx_1() VALUES (1) master-bin.000001 # Table_map # # table_id: # (test.tt_xx_1) master-bin.000001 # Write_rows_v1 # # table_id: # flags: STMT_END_F -master-bin.000001 # Query # # DROP TEMPORARY TABLE IF EXISTS `test`.`tt_1` /* generated by server */ master-bin.000001 # Query # # ROLLBACK -e-e-e-e-e-e-e-e-e-e-e- >> B T Drop-Temp-If-TXe-Temp R << -e-e-e-e-e-e-e-e-e-e-e- @@ -928,8 +906,6 @@ master-bin.000001 # Gtid # # BEGIN GTID #-#-# master-bin.000001 # Annotate_rows # # INSERT INTO tt_xx_1() VALUES (1) master-bin.000001 # Table_map # # table_id: # (test.tt_xx_1) master-bin.000001 # Write_rows_v1 # # table_id: # flags: STMT_END_F -master-bin.000001 # Query # # DROP TEMPORARY TABLE IF EXISTS `test`.`tt_1` /* generated by server */ -master-bin.000001 # Query # # DROP TEMPORARY TABLE IF EXISTS `test`.`tt_1` /* generated by server */ master-bin.000001 # Query # # ROLLBACK -e-e-e-e-e-e-e-e-e-e-e- >> B T Drop-Temp-If-TXe-Temp N Drop-Temp-If-TXe-Temp R << -e-e-e-e-e-e-e-e-e-e-e- @@ -989,7 +965,6 @@ master-bin.000001 # Gtid # # BEGIN GTID #-#-# master-bin.000001 # Annotate_rows # # INSERT INTO tt_xx_1() VALUES (1) master-bin.000001 # Table_map # # table_id: # (test.tt_xx_1) master-bin.000001 # Write_rows_v1 # # table_id: # flags: STMT_END_F -master-bin.000001 # Query # # DROP TEMPORARY TABLE IF EXISTS `test`.`tt_1` /* generated by server */ master-bin.000001 # Query # # ROLLBACK -e-e-e-e-e-e-e-e-e-e-e- >> B T Drop-Temp-If-NXe-Temp R << -e-e-e-e-e-e-e-e-e-e-e- @@ -1018,8 +993,6 @@ master-bin.000001 # Gtid # # BEGIN GTID #-#-# master-bin.000001 # Annotate_rows # # INSERT INTO tt_xx_1() VALUES (1) master-bin.000001 # Table_map # # table_id: # (test.tt_xx_1) master-bin.000001 # Write_rows_v1 # # table_id: # flags: STMT_END_F -master-bin.000001 # Query # # DROP TEMPORARY TABLE IF EXISTS `test`.`tt_1` /* generated by server */ -master-bin.000001 # Query # # DROP TEMPORARY TABLE IF EXISTS `test`.`tt_1` /* generated by server */ master-bin.000001 # Query # # ROLLBACK -e-e-e-e-e-e-e-e-e-e-e- >> B T Drop-Temp-If-NXe-Temp N Drop-Temp-If-NXe-Temp R << -e-e-e-e-e-e-e-e-e-e-e- diff --git a/mysql-test/suite/rpl/r/rpl_row_drop_temp_table.result b/mysql-test/suite/rpl/r/rpl_row_drop_temp_table.result new file mode 100644 index 00000000000..eea0dbd40e7 --- /dev/null +++ b/mysql-test/suite/rpl/r/rpl_row_drop_temp_table.result @@ -0,0 +1,38 @@ +include/master-slave.inc +[connection master] +connection slave; +SET GLOBAL read_only=1; +connection master; +CREATE PROCEDURE testproc() +BEGIN +DROP TEMPORARY TABLE IF EXISTS t1_tmp; +DROP TEMPORARY TABLE IF EXISTS t2_tmp; +CREATE TEMPORARY TABLE IF NOT EXISTS t1_tmp ( t1 varchar(400) DEFAULT NULL) ENGINE=InnoDB DEFAULT CHARSET=utf8; +CREATE TEMPORARY TABLE IF NOT EXISTS t2_tmp ( t2 varchar(16) NOT NULL ) ENGINE=InnoDB DEFAULT CHARSET=utf8; +END| +SET GLOBAL read_only=1; +CALL testproc(); +******** None of the above DROP TEMPORARY TABLE statement should be found in binary log ******** +include/show_binlog_events.inc +Log_name Pos Event_type Server_id End_log_pos Info +master-bin.000001 # Gtid # # GTID #-#-# +master-bin.000001 # Query # # use `test`; CREATE DEFINER=`root`@`localhost` PROCEDURE `testproc`() +BEGIN +DROP TEMPORARY TABLE IF EXISTS t1_tmp; +DROP TEMPORARY TABLE IF EXISTS t2_tmp; +CREATE TEMPORARY TABLE IF NOT EXISTS t1_tmp ( t1 varchar(400) DEFAULT NULL) ENGINE=InnoDB DEFAULT CHARSET=utf8; +CREATE TEMPORARY TABLE IF NOT EXISTS t2_tmp ( t2 varchar(16) NOT NULL ) ENGINE=InnoDB DEFAULT CHARSET=utf8; +END +connection slave; +SELECT @@read_only; +@@read_only +1 +======== CLEAN UP ========= +connection master; +DROP TEMPORARY TABLE t1_tmp; +DROP TEMPORARY TABLE t2_tmp; +DROP PROCEDURE testproc; +SET GLOBAL read_only=0; +connection slave; +SET GLOBAL read_only=0; +include/rpl_end.inc diff --git a/mysql-test/suite/rpl/r/rpl_stm_drop_create_temp_table.result b/mysql-test/suite/rpl/r/rpl_stm_drop_create_temp_table.result index d4bced3e521..d4250159866 100644 --- a/mysql-test/suite/rpl/r/rpl_stm_drop_create_temp_table.result +++ b/mysql-test/suite/rpl/r/rpl_stm_drop_create_temp_table.result @@ -91,9 +91,6 @@ Warnings: Note 1051 Unknown table 'test.tt_xx_1' -b-b-b-b-b-b-b-b-b-b-b- >> Drop-Temp-If-Xe-Temp << -b-b-b-b-b-b-b-b-b-b-b- include/show_binlog_events.inc -Log_name Pos Event_type Server_id End_log_pos Info -master-bin.000001 # Gtid # # GTID #-#-# -master-bin.000001 # Query # # DROP TEMPORARY TABLE IF EXISTS `test`.`tt_xx_1` /* generated by server */ -e-e-e-e-e-e-e-e-e-e-e- >> Drop-Temp-If-Xe-Temp << -e-e-e-e-e-e-e-e-e-e-e- SET @commands= 'Drop-Temp-TXe-Temp'; @@ -114,7 +111,7 @@ Note 1051 Unknown table 'test.tt_1' include/show_binlog_events.inc Log_name Pos Event_type Server_id End_log_pos Info master-bin.000001 # Gtid # # GTID #-#-# -master-bin.000001 # Query # # DROP TEMPORARY TABLE IF EXISTS `test`.`tt_tmp_2`,`test`.`tt_1` /* generated by server */ +master-bin.000001 # Query # # DROP TEMPORARY TABLE IF EXISTS `test`.`tt_tmp_2` /* generated by server */ -e-e-e-e-e-e-e-e-e-e-e- >> Drop-Temp-If-TXe-Temp << -e-e-e-e-e-e-e-e-e-e-e- SET @commands= 'Drop-Temp-NXe-Temp'; @@ -136,8 +133,6 @@ include/show_binlog_events.inc Log_name Pos Event_type Server_id End_log_pos Info master-bin.000001 # Gtid # # GTID #-#-# master-bin.000001 # Query # # DROP TEMPORARY TABLE IF EXISTS `test`.`nt_tmp_2` /* generated by server */ -master-bin.000001 # Gtid # # GTID #-#-# -master-bin.000001 # Query # # DROP TEMPORARY TABLE IF EXISTS `test`.`tt_1` /* generated by server */ -e-e-e-e-e-e-e-e-e-e-e- >> Drop-Temp-If-NXe-Temp << -e-e-e-e-e-e-e-e-e-e-e- SET @commands= 'Drop-Temp-TN-Temp'; @@ -293,7 +288,6 @@ include/show_binlog_events.inc Log_name Pos Event_type Server_id End_log_pos Info master-bin.000001 # Gtid # # BEGIN GTID #-#-# master-bin.000001 # Query # # use `test`; INSERT INTO tt_xx_1() VALUES (1) -master-bin.000001 # Query # # DROP TEMPORARY TABLE IF EXISTS `test`.`tt_xx_1` /* generated by server */ master-bin.000001 # Xid # # COMMIT /* XID */ -e-e-e-e-e-e-e-e-e-e-e- >> B T Drop-Temp-If-Xe-Temp C << -e-e-e-e-e-e-e-e-e-e-e- @@ -316,8 +310,6 @@ master-bin.000001 # Query # # use `test`; INSERT INTO nt_xx_1() VALUES (1) master-bin.000001 # Query # # COMMIT master-bin.000001 # Gtid # # BEGIN GTID #-#-# master-bin.000001 # Query # # use `test`; INSERT INTO tt_xx_1() VALUES (1) -master-bin.000001 # Query # # DROP TEMPORARY TABLE IF EXISTS `test`.`tt_xx_1` /* generated by server */ -master-bin.000001 # Query # # DROP TEMPORARY TABLE IF EXISTS `test`.`tt_xx_1` /* generated by server */ master-bin.000001 # Xid # # COMMIT /* XID */ -e-e-e-e-e-e-e-e-e-e-e- >> B T Drop-Temp-If-Xe-Temp N Drop-Temp-If-Xe-Temp C << -e-e-e-e-e-e-e-e-e-e-e- @@ -370,7 +362,7 @@ include/show_binlog_events.inc Log_name Pos Event_type Server_id End_log_pos Info master-bin.000001 # Gtid # # BEGIN GTID #-#-# master-bin.000001 # Query # # use `test`; INSERT INTO tt_xx_1() VALUES (1) -master-bin.000001 # Query # # DROP TEMPORARY TABLE IF EXISTS `test`.`tt_tmp_2`,`test`.`tt_1` /* generated by server */ +master-bin.000001 # Query # # DROP TEMPORARY TABLE IF EXISTS `test`.`tt_tmp_2` /* generated by server */ master-bin.000001 # Xid # # COMMIT /* XID */ -e-e-e-e-e-e-e-e-e-e-e- >> B T Drop-Temp-If-TXe-Temp C << -e-e-e-e-e-e-e-e-e-e-e- @@ -393,8 +385,8 @@ master-bin.000001 # Query # # use `test`; INSERT INTO nt_xx_1() VALUES (1) master-bin.000001 # Query # # COMMIT master-bin.000001 # Gtid # # BEGIN GTID #-#-# master-bin.000001 # Query # # use `test`; INSERT INTO tt_xx_1() VALUES (1) -master-bin.000001 # Query # # DROP TEMPORARY TABLE IF EXISTS `test`.`tt_tmp_2`,`test`.`tt_1` /* generated by server */ -master-bin.000001 # Query # # DROP TEMPORARY TABLE IF EXISTS `test`.`tt_tmp_1`,`test`.`tt_1` /* generated by server */ +master-bin.000001 # Query # # DROP TEMPORARY TABLE IF EXISTS `test`.`tt_tmp_2` /* generated by server */ +master-bin.000001 # Query # # DROP TEMPORARY TABLE IF EXISTS `test`.`tt_tmp_1` /* generated by server */ master-bin.000001 # Xid # # COMMIT /* XID */ -e-e-e-e-e-e-e-e-e-e-e- >> B T Drop-Temp-If-TXe-Temp N Drop-Temp-If-TXe-Temp C << -e-e-e-e-e-e-e-e-e-e-e- @@ -456,7 +448,6 @@ master-bin.000001 # Query # # DROP TEMPORARY TABLE IF EXISTS `test`.`nt_tmp_2` / master-bin.000001 # Query # # COMMIT master-bin.000001 # Gtid # # BEGIN GTID #-#-# master-bin.000001 # Query # # use `test`; INSERT INTO tt_xx_1() VALUES (1) -master-bin.000001 # Query # # DROP TEMPORARY TABLE IF EXISTS `test`.`tt_1` /* generated by server */ master-bin.000001 # Xid # # COMMIT /* XID */ -e-e-e-e-e-e-e-e-e-e-e- >> B T Drop-Temp-If-NXe-Temp C << -e-e-e-e-e-e-e-e-e-e-e- @@ -485,8 +476,6 @@ master-bin.000001 # Query # # DROP TEMPORARY TABLE IF EXISTS `test`.`nt_tmp_1` / master-bin.000001 # Query # # COMMIT master-bin.000001 # Gtid # # BEGIN GTID #-#-# master-bin.000001 # Query # # use `test`; INSERT INTO tt_xx_1() VALUES (1) -master-bin.000001 # Query # # DROP TEMPORARY TABLE IF EXISTS `test`.`tt_1` /* generated by server */ -master-bin.000001 # Query # # DROP TEMPORARY TABLE IF EXISTS `test`.`tt_1` /* generated by server */ master-bin.000001 # Xid # # COMMIT /* XID */ -e-e-e-e-e-e-e-e-e-e-e- >> B T Drop-Temp-If-NXe-Temp N Drop-Temp-If-NXe-Temp C << -e-e-e-e-e-e-e-e-e-e-e- @@ -803,7 +792,6 @@ include/show_binlog_events.inc Log_name Pos Event_type Server_id End_log_pos Info master-bin.000001 # Gtid # # BEGIN GTID #-#-# master-bin.000001 # Query # # use `test`; INSERT INTO tt_xx_1() VALUES (1) -master-bin.000001 # Query # # DROP TEMPORARY TABLE IF EXISTS `test`.`tt_xx_1` /* generated by server */ master-bin.000001 # Query # # ROLLBACK -e-e-e-e-e-e-e-e-e-e-e- >> B T Drop-Temp-If-Xe-Temp R << -e-e-e-e-e-e-e-e-e-e-e- @@ -828,8 +816,6 @@ master-bin.000001 # Query # # use `test`; INSERT INTO nt_xx_1() VALUES (1) master-bin.000001 # Query # # COMMIT master-bin.000001 # Gtid # # BEGIN GTID #-#-# master-bin.000001 # Query # # use `test`; INSERT INTO tt_xx_1() VALUES (1) -master-bin.000001 # Query # # DROP TEMPORARY TABLE IF EXISTS `test`.`tt_xx_1` /* generated by server */ -master-bin.000001 # Query # # DROP TEMPORARY TABLE IF EXISTS `test`.`tt_xx_1` /* generated by server */ master-bin.000001 # Query # # ROLLBACK -e-e-e-e-e-e-e-e-e-e-e- >> B T Drop-Temp-If-Xe-Temp N Drop-Temp-If-Xe-Temp R << -e-e-e-e-e-e-e-e-e-e-e- @@ -884,7 +870,7 @@ include/show_binlog_events.inc Log_name Pos Event_type Server_id End_log_pos Info master-bin.000001 # Gtid # # BEGIN GTID #-#-# master-bin.000001 # Query # # use `test`; INSERT INTO tt_xx_1() VALUES (1) -master-bin.000001 # Query # # DROP TEMPORARY TABLE IF EXISTS `test`.`tt_tmp_2`,`test`.`tt_1` /* generated by server */ +master-bin.000001 # Query # # DROP TEMPORARY TABLE IF EXISTS `test`.`tt_tmp_2` /* generated by server */ master-bin.000001 # Query # # ROLLBACK -e-e-e-e-e-e-e-e-e-e-e- >> B T Drop-Temp-If-TXe-Temp R << -e-e-e-e-e-e-e-e-e-e-e- @@ -909,8 +895,8 @@ master-bin.000001 # Query # # use `test`; INSERT INTO nt_xx_1() VALUES (1) master-bin.000001 # Query # # COMMIT master-bin.000001 # Gtid # # BEGIN GTID #-#-# master-bin.000001 # Query # # use `test`; INSERT INTO tt_xx_1() VALUES (1) -master-bin.000001 # Query # # DROP TEMPORARY TABLE IF EXISTS `test`.`tt_tmp_2`,`test`.`tt_1` /* generated by server */ -master-bin.000001 # Query # # DROP TEMPORARY TABLE IF EXISTS `test`.`tt_tmp_1`,`test`.`tt_1` /* generated by server */ +master-bin.000001 # Query # # DROP TEMPORARY TABLE IF EXISTS `test`.`tt_tmp_2` /* generated by server */ +master-bin.000001 # Query # # DROP TEMPORARY TABLE IF EXISTS `test`.`tt_tmp_1` /* generated by server */ master-bin.000001 # Query # # ROLLBACK -e-e-e-e-e-e-e-e-e-e-e- >> B T Drop-Temp-If-TXe-Temp N Drop-Temp-If-TXe-Temp R << -e-e-e-e-e-e-e-e-e-e-e- @@ -974,7 +960,6 @@ master-bin.000001 # Query # # DROP TEMPORARY TABLE IF EXISTS `test`.`nt_tmp_2` / master-bin.000001 # Query # # COMMIT master-bin.000001 # Gtid # # BEGIN GTID #-#-# master-bin.000001 # Query # # use `test`; INSERT INTO tt_xx_1() VALUES (1) -master-bin.000001 # Query # # DROP TEMPORARY TABLE IF EXISTS `test`.`tt_1` /* generated by server */ master-bin.000001 # Query # # ROLLBACK -e-e-e-e-e-e-e-e-e-e-e- >> B T Drop-Temp-If-NXe-Temp R << -e-e-e-e-e-e-e-e-e-e-e- @@ -1005,8 +990,6 @@ master-bin.000001 # Query # # DROP TEMPORARY TABLE IF EXISTS `test`.`nt_tmp_1` / master-bin.000001 # Query # # COMMIT master-bin.000001 # Gtid # # BEGIN GTID #-#-# master-bin.000001 # Query # # use `test`; INSERT INTO tt_xx_1() VALUES (1) -master-bin.000001 # Query # # DROP TEMPORARY TABLE IF EXISTS `test`.`tt_1` /* generated by server */ -master-bin.000001 # Query # # DROP TEMPORARY TABLE IF EXISTS `test`.`tt_1` /* generated by server */ master-bin.000001 # Query # # ROLLBACK -e-e-e-e-e-e-e-e-e-e-e- >> B T Drop-Temp-If-NXe-Temp N Drop-Temp-If-NXe-Temp R << -e-e-e-e-e-e-e-e-e-e-e- diff --git a/mysql-test/suite/rpl/t/create_or_replace.inc b/mysql-test/suite/rpl/t/create_or_replace.inc index 7d0dc487061..35a6ead60ca 100644 --- a/mysql-test/suite/rpl/t/create_or_replace.inc +++ b/mysql-test/suite/rpl/t/create_or_replace.inc @@ -205,6 +205,19 @@ set binlog_format="STATEMENT"; drop temporary table t8; set @@binlog_format=@org_binlog_format; +# MDEV-20091: +# 1. No DROP should be logged for non-existing tmp table, nor +# 2. at the connection close when its creation has not been logged. +set @@session.binlog_format=default; +drop temporary table if exists t9; + +--connect(con1,localhost,root,,) +set session binlog_format=default; +create temporary table t9 (i int); +--echo *** Must be no DROP logged for t9 when there was no CREATE, at disconnect too *** +--disconnect con1 + +--connection server_1 --source include/show_binlog_events.inc # Clean up diff --git a/mysql-test/suite/rpl/t/rpl_row_drop_temp_table.test b/mysql-test/suite/rpl/t/rpl_row_drop_temp_table.test new file mode 100644 index 00000000000..ba3770d3013 --- /dev/null +++ b/mysql-test/suite/rpl/t/rpl_row_drop_temp_table.test @@ -0,0 +1,54 @@ +# ==== Purpose ==== +# +# Test verifies that plain DROP TEMPORARY TABLE IF EXISTS statements are not +# replicated during row based replication. +# +# ==== Implementation ==== +# +# Steps: +# 0 - Have a read_only master and slave. Binlog format should be "ROW". +# 1 - Create a procedure which executes DROP TEMPORARY TABLE IF EXISTS +# statements prior to CREATE TEMPORARY TABLE. +# 2 - Execute the procedure. +# 3 - Verify that the DROP TEMPORARY TABLE IF EXISTS statements within the +# procedure are not written to the binary log. +# +# ==== References ==== +# +# MDEV-20091: DROP TEMPORARY table is logged despite no CREATE was logged +# + +--source include/have_binlog_format_row.inc +--source include/have_innodb.inc +--source include/master-slave.inc + +connection slave; +SET GLOBAL read_only=1; + +connection master; +DELIMITER |; +CREATE PROCEDURE testproc() +BEGIN + DROP TEMPORARY TABLE IF EXISTS t1_tmp; + DROP TEMPORARY TABLE IF EXISTS t2_tmp; + CREATE TEMPORARY TABLE IF NOT EXISTS t1_tmp ( t1 varchar(400) DEFAULT NULL) ENGINE=InnoDB DEFAULT CHARSET=utf8; + CREATE TEMPORARY TABLE IF NOT EXISTS t2_tmp ( t2 varchar(16) NOT NULL ) ENGINE=InnoDB DEFAULT CHARSET=utf8; +END| +DELIMITER ;| +SET GLOBAL read_only=1; +CALL testproc(); +--echo ******** None of the above DROP TEMPORARY TABLE statement should be found in binary log ******** +--source include/show_binlog_events.inc +--sync_slave_with_master +SELECT @@read_only; + +--echo ======== CLEAN UP ========= +connection master; +DROP TEMPORARY TABLE t1_tmp; +DROP TEMPORARY TABLE t2_tmp; +DROP PROCEDURE testproc; +SET GLOBAL read_only=0; +--sync_slave_with_master +SET GLOBAL read_only=0; + +--source include/rpl_end.inc diff --git a/sql/sql_table.cc b/sql/sql_table.cc index 043cfaaaaaa..bbc8cc4be01 100644 --- a/sql/sql_table.cc +++ b/sql/sql_table.cc @@ -2268,7 +2268,7 @@ int mysql_rm_table_no_locks(THD *thd, TABLE_LIST *tables, bool if_exists, for (table= tables; table; table= table->next_local) { bool is_trans= 0; - bool table_creation_was_logged= 1; + bool table_creation_was_logged= 0; char *db=table->db; size_t db_length= table->db_length; handlerton *table_type= 0; diff --git a/sql/temporary_tables.cc b/sql/temporary_tables.cc index ae7cb274843..b97e0334f0d 100644 --- a/sql/temporary_tables.cc +++ b/sql/temporary_tables.cc @@ -1334,6 +1334,7 @@ bool THD::log_events_and_free_tmp_shares() my_thread_id save_pseudo_thread_id= variables.pseudo_thread_id; char db_buf[FN_REFLEN]; String db(db_buf, sizeof(db_buf), system_charset_info); + bool at_least_one_create_logged; /* Set pseudo_thread_id to be that of the processed table. @@ -1351,7 +1352,7 @@ bool THD::log_events_and_free_tmp_shares() within the sublist of common pseudo_thread_id to create single DROP query. */ - for (; + for (at_least_one_create_logged= false; share && IS_USER_TABLE(share) && tmpkeyval(share) == variables.pseudo_thread_id && share->db.length == db.length() && @@ -1359,51 +1360,57 @@ bool THD::log_events_and_free_tmp_shares() /* Get the next TABLE_SHARE in the list. */ share= temporary_tables->pop_front()) { - /* - We are going to add ` around the table names and possible more - due to special characters. - */ - append_identifier(this, &s_query, share->table_name.str, - share->table_name.length); - s_query.append(','); + if (share->table_creation_was_logged) + { + at_least_one_create_logged= true; + /* + We are going to add ` around the table names and possible more + due to special characters. + */ + append_identifier(this, &s_query, share->table_name.str, + share->table_name.length); + s_query.append(','); + } rm_temporary_table(share->db_type(), share->path.str); free_table_share(share); my_free(share); } - - clear_error(); - CHARSET_INFO *cs_save= variables.character_set_client; - variables.character_set_client= system_charset_info; - thread_specific_used= true; - - Query_log_event qinfo(this, s_query.ptr(), - s_query.length() - 1 /* to remove trailing ',' */, - false, true, false, 0); - qinfo.db= db.ptr(); - qinfo.db_len= db.length(); - variables.character_set_client= cs_save; - - get_stmt_da()->set_overwrite_status(true); - transaction.stmt.mark_dropped_temp_table(); - if ((error= (mysql_bin_log.write(&qinfo) || error))) + if (at_least_one_create_logged) { - /* - If we're here following THD::cleanup, thence the connection - has been closed already. So lets print a message to the - error log instead of pushing yet another error into the - stmt_da. - - Also, we keep the error flag so that we propagate the error - up in the stack. This way, if we're the SQL thread we notice - that THD::close_tables failed. (Actually, the SQL - thread only calls THD::close_tables while applying - old Start_log_event_v3 events.) - */ - sql_print_error("Failed to write the DROP statement for " - "temporary tables to binary log"); - } + clear_error(); + CHARSET_INFO *cs_save= variables.character_set_client; + variables.character_set_client= system_charset_info; + thread_specific_used= true; + + Query_log_event qinfo(this, s_query.ptr(), + s_query.length() - 1 /* to remove trailing ',' */, + false, true, false, 0); + qinfo.db= db.ptr(); + qinfo.db_len= db.length(); + variables.character_set_client= cs_save; + + get_stmt_da()->set_overwrite_status(true); + transaction.stmt.mark_dropped_temp_table(); + if ((error= (mysql_bin_log.write(&qinfo) || error))) + { + /* + If we're here following THD::cleanup, thence the connection + has been closed already. So lets print a message to the + error log instead of pushing yet another error into the + stmt_da. + + Also, we keep the error flag so that we propagate the error + up in the stack. This way, if we're the SQL thread we notice + that THD::close_tables failed. (Actually, the SQL + thread only calls THD::close_tables while applying + old Start_log_event_v3 events.) + */ + sql_print_error("Failed to write the DROP statement for " + "temporary tables to binary log"); + } - get_stmt_da()->set_overwrite_status(false); + get_stmt_da()->set_overwrite_status(false); + } variables.pseudo_thread_id= save_pseudo_thread_id; thread_specific_used= save_thread_specific_used; } diff --git a/storage/innobase/CMakeLists.txt b/storage/innobase/CMakeLists.txt index 7f08c818454..1b5345cbddc 100644 --- a/storage/innobase/CMakeLists.txt +++ b/storage/innobase/CMakeLists.txt @@ -146,8 +146,7 @@ SET(INNOBASE_SOURCES ut/ut0rnd.cc ut/ut0ut.cc ut/ut0vec.cc - ut/ut0wqueue.cc - ut/ut0timer.cc) + ut/ut0wqueue.cc) MYSQL_ADD_PLUGIN(innobase ${INNOBASE_SOURCES} STORAGE_ENGINE MODULE_OUTPUT_NAME ha_innodb diff --git a/storage/innobase/btr/btr0defragment.cc b/storage/innobase/btr/btr0defragment.cc index 857181371ff..6995c6f0998 100644 --- a/storage/innobase/btr/btr0defragment.cc +++ b/storage/innobase/btr/btr0defragment.cc @@ -1,6 +1,6 @@ /***************************************************************************** -Copyright (C) 2013, 2014 Facebook, Inc. All Rights Reserved. +Copyright (C) 2012, 2014 Facebook, Inc. All Rights Reserved. Copyright (C) 2014, 2019, MariaDB Corporation. This program is free software; you can redistribute it and/or modify it under @@ -36,7 +36,6 @@ Modified 30/07/2014 Jan Lindström jan.lindstrom@mariadb.com #include "ibuf0ibuf.h" #include "lock0lock.h" #include "srv0start.h" -#include "ut0timer.h" #include <list> @@ -100,8 +99,7 @@ Initialize defragmentation. */ void btr_defragment_init() { - srv_defragment_interval = ut_microseconds_to_timer( - (ulonglong) (1000000.0 / srv_defragment_frequency)); + srv_defragment_interval = 1000000000ULL / srv_defragment_frequency; mutex_create(LATCH_ID_BTR_DEFRAGMENT_MUTEX, &btr_defragment_mutex); } @@ -735,7 +733,7 @@ DECLARE_THREAD(btr_defragment_thread)(void*) } pcur = item->pcur; - ulonglong now = ut_timer_now(); + ulonglong now = my_interval_timer(); ulonglong elapsed = now - item->last_processed; if (elapsed < srv_defragment_interval) { @@ -745,11 +743,12 @@ DECLARE_THREAD(btr_defragment_thread)(void*) defragmentation of all indices queue up on a single thread, it's likely other indices that follow this one don't need to sleep again. */ - os_thread_sleep(((ulint)ut_timer_to_microseconds( - srv_defragment_interval - elapsed))); + os_thread_sleep(static_cast<ulint> + ((srv_defragment_interval - elapsed) + / 1000)); } - now = ut_timer_now(); + now = my_interval_timer(); mtr_start(&mtr); cursor = btr_pcur_get_btr_cur(pcur); index = btr_cur_get_index(cursor); diff --git a/storage/innobase/buf/buf0buf.cc b/storage/innobase/buf/buf0buf.cc index 806c5a6a1d4..e3c6605652f 100644 --- a/storage/innobase/buf/buf0buf.cc +++ b/storage/innobase/buf/buf0buf.cc @@ -1942,7 +1942,7 @@ buf_pool_init_instance( buf_pool->zip_hash = hash_create(2 * buf_pool->curr_size); - buf_pool->last_printout_time = ut_time(); + buf_pool->last_printout_time = time(NULL); } /* 2. Initialize flushing fields -------------------------------- */ @@ -2780,7 +2780,7 @@ buf_pool_resize() buf_resize_status("Withdrawing blocks to be shrunken."); - ib_time_t withdraw_started = ut_time(); + time_t withdraw_started = time(NULL); ulint message_interval = 60; ulint retry_interval = 1; @@ -2806,8 +2806,10 @@ withdraw_retry: /* abort buffer pool load */ buf_load_abort(); + const time_t current_time = time(NULL); + if (should_retry_withdraw - && ut_difftime(ut_time(), withdraw_started) >= message_interval) { + && difftime(current_time, withdraw_started) >= message_interval) { if (message_interval > 900) { message_interval = 1800; @@ -2823,8 +2825,7 @@ withdraw_retry: trx = UT_LIST_GET_NEXT(mysql_trx_list, trx)) { if (trx->state != TRX_STATE_NOT_STARTED && trx->mysql_thd != NULL - && ut_difftime(withdraw_started, - trx->start_time) > 0) { + && withdraw_started > trx->start_time) { if (!found) { ib::warn() << "The following trx might hold" @@ -2837,13 +2838,13 @@ withdraw_retry: } lock_trx_print_wait_and_mvcc_state( - stderr, trx); + stderr, trx, current_time); } } trx_sys_mutex_exit(); lock_mutex_exit(); - withdraw_started = ut_time(); + withdraw_started = current_time; } if (should_retry_withdraw) { @@ -6306,7 +6307,7 @@ void buf_refresh_io_stats( buf_pool_t* buf_pool) { - buf_pool->last_printout_time = ut_time(); + buf_pool->last_printout_time = time(NULL); buf_pool->old_stat = buf_pool->stat; } diff --git a/storage/innobase/buf/buf0flu.cc b/storage/innobase/buf/buf0flu.cc index 841a5eb46ae..74df5ee2de8 100644 --- a/storage/innobase/buf/buf0flu.cc +++ b/storage/innobase/buf/buf0flu.cc @@ -2459,7 +2459,7 @@ page_cleaner_flush_pages_recommendation( if (prev_lsn == 0) { /* First time around. */ prev_lsn = cur_lsn; - prev_time = ut_time(); + prev_time = time(NULL); return(0); } @@ -2469,7 +2469,7 @@ page_cleaner_flush_pages_recommendation( sum_pages += last_pages_in; - time_t curr_time = ut_time(); + time_t curr_time = time(NULL); double time_elapsed = difftime(curr_time, prev_time); /* We update our variables every srv_flushing_avg_loops diff --git a/storage/innobase/dict/dict0defrag_bg.cc b/storage/innobase/dict/dict0defrag_bg.cc index f1ea8ae30d2..73f55cc8667 100644 --- a/storage/innobase/dict/dict0defrag_bg.cc +++ b/storage/innobase/dict/dict0defrag_bg.cc @@ -238,7 +238,6 @@ dict_stats_save_defrag_summary( dict_index_t* index) /*!< in: index */ { dberr_t ret=DB_SUCCESS; - lint now = (lint) ut_time(); if (dict_index_is_ibuf(index)) { return DB_SUCCESS; @@ -247,7 +246,7 @@ dict_stats_save_defrag_summary( rw_lock_x_lock(&dict_operation_lock); mutex_enter(&dict_sys->mutex); - ret = dict_stats_save_index_stat(index, now, "n_pages_freed", + ret = dict_stats_save_index_stat(index, time(NULL), "n_pages_freed", index->stat_defrag_n_pages_freed, NULL, "Number of pages freed during" @@ -278,7 +277,7 @@ dict_stats_save_defrag_stats( return dict_stats_report_error(index->table, true); } - lint now = (lint) ut_time(); + const time_t now = time(NULL); mtr_t mtr; ulint n_leaf_pages; ulint n_leaf_reserved; diff --git a/storage/innobase/dict/dict0mem.cc b/storage/innobase/dict/dict0mem.cc index d09ffe6f9b5..fe01948b70d 100644 --- a/storage/innobase/dict/dict0mem.cc +++ b/storage/innobase/dict/dict0mem.cc @@ -1089,7 +1089,7 @@ void dict_mem_init(void) { /* Initialize a randomly distributed temporary file number */ - ib_uint32_t now = static_cast<ib_uint32_t>(ut_time()); + ib_uint32_t now = static_cast<ib_uint32_t>(time(NULL)); const byte* buf = reinterpret_cast<const byte*>(&now); diff --git a/storage/innobase/dict/dict0stats.cc b/storage/innobase/dict/dict0stats.cc index 1df016d9301..4db4687e600 100644 --- a/storage/innobase/dict/dict0stats.cc +++ b/storage/innobase/dict/dict0stats.cc @@ -962,7 +962,7 @@ dict_stats_update_transient( table->stat_sum_of_other_index_sizes = sum_of_index_sizes - index->stat_index_size; - table->stats_last_recalc = ut_time(); + table->stats_last_recalc = time(NULL); table->stat_modified_counter = 0; @@ -2269,7 +2269,7 @@ dict_stats_update_persistent( += index->stat_index_size; } - table->stats_last_recalc = ut_time(); + table->stats_last_recalc = time(NULL); table->stat_modified_counter = 0; @@ -2298,7 +2298,7 @@ rolled back only in the case of error, but not freed. dberr_t dict_stats_save_index_stat( dict_index_t* index, - ib_time_t last_update, + time_t last_update, const char* stat_name, ib_uint64_t stat_value, ib_uint64_t* sample_size, @@ -2427,7 +2427,6 @@ dict_stats_save( const index_id_t* only_for_index) { pars_info_t* pinfo; - ib_time_t now; dberr_t ret; dict_table_t* table; char db_utf8[MAX_DB_UTF8_LEN]; @@ -2446,7 +2445,7 @@ dict_stats_save( dict_fs2utf8(table->name.m_name, db_utf8, sizeof(db_utf8), table_utf8, sizeof(table_utf8)); - now = ut_time(); + const time_t now = time(NULL); rw_lock_x_lock(&dict_operation_lock); mutex_enter(&dict_sys->mutex); diff --git a/storage/innobase/dict/dict0stats_bg.cc b/storage/innobase/dict/dict0stats_bg.cc index 84bc9af8464..ec3f0a8eae6 100644 --- a/storage/innobase/dict/dict0stats_bg.cc +++ b/storage/innobase/dict/dict0stats_bg.cc @@ -385,14 +385,14 @@ dict_stats_process_entry_from_recalc_pool() mutex_exit(&dict_sys->mutex); - /* ut_time() could be expensive, the current function + /* time() could be expensive, the current function is called once every time a table has been changed more than 10% and on a system with lots of small tables, this could become hot. If we find out that this is a problem, then the check below could eventually be replaced with something else, though a time interval is the natural approach. */ - if (ut_difftime(ut_time(), table->stats_last_recalc) + if (difftime(time(NULL), table->stats_last_recalc) < MIN_RECALC_INTERVAL) { /* Stats were (re)calculated not long ago. To avoid diff --git a/storage/innobase/eval/eval0eval.cc b/storage/innobase/eval/eval0eval.cc index 2ba55ffca3d..e02fc7f561b 100644 --- a/storage/innobase/eval/eval0eval.cc +++ b/storage/innobase/eval/eval0eval.cc @@ -1,6 +1,7 @@ /***************************************************************************** Copyright (c) 1997, 2016, Oracle and/or its affiliates. All Rights Reserved. +Copyright (c) 2019, MariaDB Corporation. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software @@ -814,7 +815,7 @@ eval_predefined( dfield_get_data(que_node_get_val(arg1))); } else if (func == PARS_SYSDATE_TOKEN) { - int_val = (lint) ut_time(); + int_val = (lint) time(NULL); } else { eval_predefined_2(func_node); diff --git a/storage/innobase/fts/fts0fts.cc b/storage/innobase/fts/fts0fts.cc index 0a25711d9ae..fb808abf413 100644 --- a/storage/innobase/fts/fts0fts.cc +++ b/storage/innobase/fts/fts0fts.cc @@ -74,8 +74,8 @@ ulong fts_min_token_size; // FIXME: testing -static ib_time_t elapsed_time = 0; -static ulint n_nodes = 0; +static time_t elapsed_time; +static ulint n_nodes; #ifdef FTS_CACHE_SIZE_DEBUG /** The cache size permissible lower limit (1K) */ @@ -3872,7 +3872,7 @@ fts_write_node( pars_info_t* info; dberr_t error; ib_uint32_t doc_count; - ib_time_t start_time; + time_t start_time; doc_id_t last_doc_id; doc_id_t first_doc_id; char table_name[MAX_FULL_NAME_LEN]; @@ -3921,9 +3921,9 @@ fts_write_node( " :last_doc_id, :doc_count, :ilist);"); } - start_time = ut_time(); + start_time = time(NULL); error = fts_eval_sql(trx, *graph); - elapsed_time += ut_time() - start_time; + elapsed_time += time(NULL) - start_time; ++n_nodes; return(error); @@ -4100,7 +4100,7 @@ fts_sync_begin( n_nodes = 0; elapsed_time = 0; - sync->start_time = ut_time(); + sync->start_time = time(NULL); sync->trx = trx_allocate_for_background(); trx_start_internal(sync->trx); @@ -4239,7 +4239,7 @@ fts_sync_commit( if (fts_enable_diag_print && elapsed_time) { ib::info() << "SYNC for table " << sync->table->name << ": SYNC time: " - << (ut_time() - sync->start_time) + << (time(NULL) - sync->start_time) << " secs: elapsed " << (double) n_nodes / elapsed_time << " ins/sec"; diff --git a/storage/innobase/fts/fts0opt.cc b/storage/innobase/fts/fts0opt.cc index 3a82ba15e4c..f297b7e2594 100644 --- a/storage/innobase/fts/fts0opt.cc +++ b/storage/innobase/fts/fts0opt.cc @@ -58,7 +58,7 @@ static os_event_t fts_opt_shutdown_event = NULL; static const ulint FTS_WORD_NODES_INIT_SIZE = 64; /** Last time we did check whether system need a sync */ -static ib_time_t last_check_sync_time; +static time_t last_check_sync_time; /** FTS optimize thread message types. */ enum fts_msg_type_t { @@ -180,12 +180,11 @@ struct fts_slot_t { ulint deleted; /*!< Number of doc ids deleted since the last time this table was optimized */ - ib_time_t last_run; /*!< Time last run completed */ + /** time(NULL) of completing fts_optimize_table_bk() */ + time_t last_run; - ib_time_t completed; /*!< Optimize finish time */ - - ib_time_t interval_time; /*!< Minimum time to wait before - optimizing the table again. */ + /** time(NULL) of latest successful fts_optimize_table() */ + time_t completed; }; /** A table remove message for the FTS optimize thread. */ @@ -217,8 +216,8 @@ char fts_enable_diag_print; /** ZLib compressed block size.*/ static ulint FTS_ZIP_BLOCK_SIZE = 1024; -/** The amount of time optimizing in a single pass, in milliseconds. */ -static ib_time_t fts_optimize_time_limit = 0; +/** The amount of time optimizing in a single pass, in seconds. */ +static ulint fts_optimize_time_limit; /** It's defined in fts0fts.cc */ extern const char* fts_common_tables[]; @@ -1530,7 +1529,7 @@ fts_optimize_compact( /*=================*/ fts_optimize_t* optim, /*!< in: optimize state data */ dict_index_t* index, /*!< in: current FTS being optimized */ - ib_time_t start_time) /*!< in: optimize start time */ + time_t start_time) /*!< in: optimize start time */ { ulint i; dberr_t error = DB_SUCCESS; @@ -1563,8 +1562,11 @@ fts_optimize_compact( /* Free the word that was optimized. */ fts_word_free(word); + ulint interval = ulint(time(NULL) - start_time); + if (fts_optimize_time_limit > 0 - && (ut_time() - start_time) > fts_optimize_time_limit) { + && (lint(interval) < 0 + || interval > fts_optimize_time_limit)) { optim->done = TRUE; } @@ -1624,7 +1626,7 @@ fts_optimize_get_index_start_time( /*==============================*/ trx_t* trx, /*!< in: transaction */ dict_index_t* index, /*!< in: FTS index */ - ib_time_t* start_time) /*!< out: time in secs */ + time_t* start_time) /*!< out: time in secs */ { return(fts_config_get_index_ulint( trx, index, FTS_OPTIMIZE_START_TIME, @@ -1640,7 +1642,7 @@ fts_optimize_set_index_start_time( /*==============================*/ trx_t* trx, /*!< in: transaction */ dict_index_t* index, /*!< in: FTS index */ - ib_time_t start_time) /*!< in: start time */ + time_t start_time) /*!< in: start time */ { return(fts_config_set_index_ulint( trx, index, FTS_OPTIMIZE_START_TIME, @@ -1656,7 +1658,7 @@ fts_optimize_get_index_end_time( /*============================*/ trx_t* trx, /*!< in: transaction */ dict_index_t* index, /*!< in: FTS index */ - ib_time_t* end_time) /*!< out: time in secs */ + time_t* end_time) /*!< out: time in secs */ { return(fts_config_get_index_ulint( trx, index, FTS_OPTIMIZE_END_TIME, (ulint*) end_time)); @@ -1671,7 +1673,7 @@ fts_optimize_set_index_end_time( /*============================*/ trx_t* trx, /*!< in: transaction */ dict_index_t* index, /*!< in: FTS index */ - ib_time_t end_time) /*!< in: end time */ + time_t end_time) /*!< in: end time */ { return(fts_config_set_index_ulint( trx, index, FTS_OPTIMIZE_END_TIME, (ulint) end_time)); @@ -1734,22 +1736,23 @@ fts_optimize_free( Get the max time optimize should run in millisecs. @return max optimize time limit in millisecs. */ static -ib_time_t +ulint fts_optimize_get_time_limit( /*========================*/ trx_t* trx, /*!< in: transaction */ fts_table_t* fts_table) /*!< in: aux table */ { - ib_time_t time_limit = 0; + ulint time_limit = 0; fts_config_get_ulint( trx, fts_table, - FTS_OPTIMIZE_LIMIT_IN_SECS, (ulint*) &time_limit); + FTS_OPTIMIZE_LIMIT_IN_SECS, &time_limit); + /* FIXME: This is returning milliseconds, while the variable + is being stored and interpreted as seconds! */ return(time_limit * 1000); } - /**********************************************************************//** Run OPTIMIZE on the given table. Note: this can take a very long time (hours). */ @@ -1762,7 +1765,6 @@ fts_optimize_words( fts_string_t* word) /*!< in: the starting word to optimize */ { fts_fetch_t fetch; - ib_time_t start_time; que_t* graph = NULL; CHARSET_INFO* charset = optim->fts_index_table.charset; @@ -1772,7 +1774,7 @@ fts_optimize_words( fts_optimize_time_limit = fts_optimize_get_time_limit( optim->trx, &optim->fts_common_table); - start_time = ut_time(); + const time_t start_time = time(NULL); /* Setup the callback to use for fetching the word ilist etc. */ fetch.read_arg = optim->words; @@ -1858,7 +1860,7 @@ fts_optimize_index_completed( dberr_t error; byte buf[sizeof(ulint)]; #ifdef FTS_OPTIMIZE_DEBUG - ib_time_t end_time = ut_time(); + time_t end_time = time(NULL); error = fts_optimize_set_index_end_time(optim->trx, index, end_time); #endif @@ -2249,8 +2251,8 @@ fts_optimize_indexes( dict_index_t* index; #ifdef FTS_OPTIMIZE_DEBUG - ib_time_t end_time; - ib_time_t start_time; + time_t end_time; + time_t start_time; /* Get the start and end optimize times for this index. */ error = fts_optimize_get_index_start_time( @@ -2270,14 +2272,14 @@ fts_optimize_indexes( /* Start time will be 0 only for the first time or after completing the optimization of all FTS indexes. */ if (start_time == 0) { - start_time = ut_time(); + start_time = time(NULL); error = fts_optimize_set_index_start_time( optim->trx, index, start_time); } /* Check if this index needs to be optimized or not. */ - if (ut_difftime(end_time, start_time) < 0) { + if (difftime(end_time, start_time) < 0) { error = fts_optimize_index(optim, index); if (error != DB_SUCCESS) { @@ -2349,7 +2351,7 @@ fts_optimize_reset_start_time( for (uint i = 0; i < ib_vector_size(fts->indexes); ++i) { dict_index_t* index; - ib_time_t start_time = 0; + time_t start_time = 0; /* Reset the start time to 0 for this index. */ error = fts_optimize_set_index_start_time( @@ -2378,11 +2380,13 @@ fts_optimize_table_bk( /*==================*/ fts_slot_t* slot) /*!< in: table to optimiza */ { - dberr_t error; + const time_t now = time(NULL); + const ulint interval = ulint(now - slot->last_run); /* Avoid optimizing tables that were optimized recently. */ if (slot->last_run > 0 - && (ut_time() - slot->last_run) < slot->interval_time) { + && lint(interval) >= 0 + && interval < FTS_OPTIMIZE_INTERVAL_IN_SECS) { return(DB_SUCCESS); } @@ -2390,12 +2394,19 @@ fts_optimize_table_bk( dict_table_t* table = dict_table_open_on_id( slot->table_id, FALSE, DICT_TABLE_OP_NORMAL); - if (table && fil_table_accessible(table) + if (!table) { + slot->last_run = now; + return DB_SUCCESS; + } + + dberr_t error; + + if (fil_table_accessible(table) && table->fts && table->fts->cache && table->fts->cache->deleted >= FTS_OPTIMIZE_THRESHOLD) { error = fts_optimize_table(table); - slot->last_run = ut_time(); + slot->last_run = time(NULL); if (error == DB_SUCCESS) { slot->running = false; @@ -2403,7 +2414,7 @@ fts_optimize_table_bk( } } else { /* Note time this run completed. */ - slot->last_run = ut_time(); + slot->last_run = now; error = DB_SUCCESS; } @@ -2653,7 +2664,6 @@ static bool fts_optimize_new_table(dict_table_t* table) slot->table_id = table->id; slot->running = false; - slot->interval_time = FTS_OPTIMIZE_INTERVAL_IN_SECS; return(TRUE); } @@ -2689,37 +2699,23 @@ Calculate how many tables in fts_slots need to be optimized. @return no. of tables to optimize */ static ulint fts_optimize_how_many() { - ulint i; - ib_time_t delta; - ulint n_tables = 0; - ib_time_t current_time; - - current_time = ut_time(); + ulint n_tables = 0; + const time_t current_time = time(NULL); - for (i = 0; i < ib_vector_size(fts_slots); ++i) { + for (ulint i = 0; i < ib_vector_size(fts_slots); ++i) { const fts_slot_t* slot = static_cast<const fts_slot_t*>( ib_vector_get_const(fts_slots, i)); if (slot->table_id == 0) { continue; } - if (!slot->running) { - ut_a(slot->completed <= current_time); - - delta = current_time - slot->completed; + const time_t end = slot->running + ? slot->last_run : slot->completed; + ulint interval = ulint(current_time - end); - /* Skip slots that have been optimized recently. */ - if (delta >= slot->interval_time) { - ++n_tables; - } - } else { - ut_a(slot->last_run <= current_time); - - delta = current_time - slot->last_run; - - if (delta > slot->interval_time) { - ++n_tables; - } + if (lint(interval) < 0 + || interval >= FTS_OPTIMIZE_INTERVAL_IN_SECS) { + ++n_tables; } } @@ -2731,14 +2727,15 @@ Check if the total memory used by all FTS table exceeds the maximum limit. @return true if a sync is needed, false otherwise */ static bool fts_is_sync_needed() { - ulint total_memory = 0; - double time_diff = difftime(ut_time(), last_check_sync_time); + ulint total_memory = 0; + const time_t now = time(NULL); + double time_diff = difftime(now, last_check_sync_time); - if (fts_need_sync || time_diff < 5) { + if (fts_need_sync || (time_diff >= 0 && time_diff < 5)) { return(false); } - last_check_sync_time = ut_time(); + last_check_sync_time = now; for (ulint i = 0; i < ib_vector_size(fts_slots); ++i) { const fts_slot_t* slot = static_cast<const fts_slot_t*>( @@ -2969,7 +2966,7 @@ fts_optimize_init(void) table_vector.clear(); fts_opt_shutdown_event = os_event_create(0); - last_check_sync_time = ut_time(); + last_check_sync_time = time(NULL); os_thread_create(fts_optimize_thread, fts_optimize_wq, NULL); } diff --git a/storage/innobase/handler/ha_innodb.cc b/storage/innobase/handler/ha_innodb.cc index dc490b83ed5..40c7e3b8ec7 100644 --- a/storage/innobase/handler/ha_innodb.cc +++ b/storage/innobase/handler/ha_innodb.cc @@ -100,7 +100,6 @@ this program; if not, write to the Free Software Foundation, Inc., #include "row0trunc.h" #include "row0upd.h" #include "fil0crypt.h" -#include "ut0timer.h" #include "srv0mon.h" #include "srv0srv.h" #include "srv0start.h" @@ -1725,21 +1724,6 @@ thd_trx_is_auto_commit( && thd_is_select(thd)); } -extern "C" time_t thd_start_time(const THD* thd); - -/******************************************************************//** -Get the thread start time. -@return the thread start time in seconds since the epoch. */ -ulint -thd_start_time_in_secs( -/*===================*/ - THD* thd) /*!< in: thread handle, or NULL */ -{ - // FIXME: This function should be added to the server code. - //return(thd_start_time(thd)); - return(ulint(ut_time())); -} - /** Enter InnoDB engine after checking the max number of user threads allowed, else the thread is put into sleep. @param[in,out] prebuilt row prebuilt handler */ @@ -18891,8 +18875,7 @@ innodb_defragment_frequency_update( from check function */ { srv_defragment_frequency = (*static_cast<const uint*>(save)); - srv_defragment_interval = ut_microseconds_to_timer( - (ulonglong) (1000000.0 / srv_defragment_frequency)); + srv_defragment_interval = 1000000000ULL / srv_defragment_frequency; } static inline char *my_strtok_r(char *str, const char *delim, char **saveptr) diff --git a/storage/innobase/include/dict0mem.h b/storage/innobase/include/dict0mem.h index 980edc84a14..a6047d6f8c3 100644 --- a/storage/innobase/include/dict0mem.h +++ b/storage/innobase/include/dict0mem.h @@ -1618,7 +1618,7 @@ struct dict_table_t { unsigned stat_initialized:1; /** Timestamp of last recalc of the stats. */ - ib_time_t stats_last_recalc; + time_t stats_last_recalc; /** The two bits below are set in the 'stat_persistent' member. They have the following meaning: diff --git a/storage/innobase/include/dict0stats.h b/storage/innobase/include/dict0stats.h index 1a5047605ca..98956412ae2 100644 --- a/storage/innobase/include/dict0stats.h +++ b/storage/innobase/include/dict0stats.h @@ -203,7 +203,7 @@ rolled back only in the case of error, but not freed. dberr_t dict_stats_save_index_stat( dict_index_t* index, - ib_time_t last_update, + time_t last_update, const char* stat_name, ib_uint64_t stat_value, ib_uint64_t* sample_size, diff --git a/storage/innobase/include/fts0types.h b/storage/innobase/include/fts0types.h index 26f18cc3d1d..a08a60b9e95 100644 --- a/storage/innobase/include/fts0types.h +++ b/storage/innobase/include/fts0types.h @@ -1,7 +1,7 @@ /***************************************************************************** Copyright (c) 2007, 2016, Oracle and/or its affiliates. All Rights Reserved. -Copyright (c) 2017, MariaDB Corporation. +Copyright (c) 2017, 2019, MariaDB Corporation. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software @@ -123,7 +123,8 @@ struct fts_sync_t { doc_id_t max_doc_id; /*!< The doc id at which the cache was noted as being full, we use this to set the upper_limit field */ - ib_time_t start_time; /*!< SYNC start time */ + time_t start_time; /*!< SYNC start time; only used if + fts_enable_diag_print */ bool in_progress; /*!< flag whether sync is in progress.*/ bool unlock_cache; /*!< flag whether unlock cache when write fts node */ diff --git a/storage/innobase/include/ha_prototypes.h b/storage/innobase/include/ha_prototypes.h index 20e2015b5d5..7fd0de92562 100644 --- a/storage/innobase/include/ha_prototypes.h +++ b/storage/innobase/include/ha_prototypes.h @@ -372,14 +372,6 @@ thd_trx_is_auto_commit( /*===================*/ THD* thd); /*!< in: thread handle, or NULL */ -/******************************************************************//** -Get the thread start time. -@return the thread start time in seconds since the epoch. */ -ulint -thd_start_time_in_secs( -/*===================*/ - THD* thd); /*!< in: thread handle, or NULL */ - /*****************************************************************//** A wrapper function of innobase_convert_name(), convert a table name to the MySQL system_charset_info (UTF-8) and quote it if needed. diff --git a/storage/innobase/include/lock0lock.h b/storage/innobase/include/lock0lock.h index 934f68df082..18bc3abfaf1 100644 --- a/storage/innobase/include/lock0lock.h +++ b/storage/innobase/include/lock0lock.h @@ -1,7 +1,7 @@ /***************************************************************************** Copyright (c) 1996, 2016, Oracle and/or its affiliates. All Rights Reserved. -Copyright (c) 2017, 2018, MariaDB Corporation. +Copyright (c) 2017, 2019, MariaDB Corporation. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software @@ -595,11 +595,10 @@ lock_print_info_summary( /** Prints transaction lock wait and MVCC state. @param[in,out] file file where to print -@param[in] trx transaction */ +@param[in] trx transaction +@param[in] now current time */ void -lock_trx_print_wait_and_mvcc_state( - FILE* file, - const trx_t* trx); +lock_trx_print_wait_and_mvcc_state(FILE* file, const trx_t* trx, time_t now); /*********************************************************************//** Prints info of locks for each transaction. This function assumes that the diff --git a/storage/innobase/include/lock0types.h b/storage/innobase/include/lock0types.h index f8cc52bc81d..1ae319e6b79 100644 --- a/storage/innobase/include/lock0types.h +++ b/storage/innobase/include/lock0types.h @@ -1,7 +1,7 @@ /***************************************************************************** Copyright (c) 1996, 2015, Oracle and/or its affiliates. All Rights Reserved. -Copyright (c) 2018, MariaDB Corporation. +Copyright (c) 2018, 2019, MariaDB Corporation. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software @@ -191,10 +191,14 @@ struct ib_lock_t lock. The link node in a singly linked list, used during hashing. */ - /* Statistics for how long lock has been held and time - how long this lock had to be waited before it was granted */ - time_t requested_time; /*!< Lock request time */ - ulint wait_time; /*!< Time waited this lock or 0 */ + /** time(NULL) of the lock request creation. + Used for computing wait_time and diagnostics only. + Note: bogus durations may be reported + when the system time is adjusted! */ + time_t requested_time; + /** Cumulated wait time in seconds. + Note: may be bogus when the system time is adjusted! */ + ulint wait_time; union { lock_table_t tab_lock;/*!< table lock */ diff --git a/storage/innobase/include/log0recv.h b/storage/innobase/include/log0recv.h index 03f6a6ff878..74aa4fcb517 100644 --- a/storage/innobase/include/log0recv.h +++ b/storage/innobase/include/log0recv.h @@ -263,7 +263,7 @@ struct recv_sys_t{ /*!< the LSN of a MLOG_CHECKPOINT record, or 0 if none was parsed */ /** the time when progress was last reported */ - ib_time_t progress_time; + time_t progress_time; mem_heap_t* heap; /*!< memory heap of log records and file addresses*/ hash_table_t* addr_hash;/*!< hash table of file addresses of pages */ @@ -288,7 +288,7 @@ struct recv_sys_t{ @param[in] time the current time @return whether progress should be reported (the last report was at least 15 seconds ago) */ - bool report(ib_time_t time) + bool report(time_t time) { if (time - progress_time < 15) { return false; diff --git a/storage/innobase/include/srv0mon.h b/storage/innobase/include/srv0mon.h index 2a51780fcd8..343cb0e741a 100644 --- a/storage/innobase/include/srv0mon.h +++ b/storage/innobase/include/srv0mon.h @@ -63,9 +63,9 @@ create the internal counter ID in "monitor_id_t". */ /** Structure containing the actual values of a monitor counter. */ struct monitor_value_t { - ib_time_t mon_start_time; /*!< Start time of monitoring */ - ib_time_t mon_stop_time; /*!< Stop time of monitoring */ - ib_time_t mon_reset_time; /*!< Time counter resetted */ + time_t mon_start_time; /*!< Start time of monitoring */ + time_t mon_stop_time; /*!< Stop time of monitoring */ + time_t mon_reset_time; /*!< Time of resetting the counter */ mon_type_t mon_value; /*!< Current counter Value */ mon_type_t mon_max_value; /*!< Current Max value */ mon_type_t mon_min_value; /*!< Current Min value */ diff --git a/storage/innobase/include/srv0srv.h b/storage/innobase/include/srv0srv.h index 9242d9af523..591eec4b42c 100644 --- a/storage/innobase/include/srv0srv.h +++ b/storage/innobase/include/srv0srv.h @@ -1110,10 +1110,14 @@ struct srv_slot_t{ ibool suspended; /*!< TRUE if the thread is waiting for the event of this slot */ - ib_time_t suspend_time; /*!< time when the thread was - suspended. Initialized by - lock_wait_table_reserve_slot() - for lock wait */ + /** time(NULL) when the thread was suspended. + FIXME: Use my_interval_timer() or similar, to avoid bogus + timeouts in lock_wait_check_and_cancel() or lock_wait_suspend_thread() + when the system time is adjusted to the past! + + FIXME: This is duplicating trx_lock_t::wait_started, + which is being used for diagnostic purposes only. */ + time_t suspend_time; ulong wait_timeout; /*!< wait time that if exceeded the thread will be timed out. Initialized by diff --git a/storage/innobase/include/trx0i_s.h b/storage/innobase/include/trx0i_s.h index 6cf3b84705e..7e766072272 100644 --- a/storage/innobase/include/trx0i_s.h +++ b/storage/innobase/include/trx0i_s.h @@ -1,7 +1,7 @@ /***************************************************************************** Copyright (c) 2007, 2015, Oracle and/or its affiliates. All Rights Reserved. -Copyright (c) 2017, MariaDB Corporation. +Copyright (c) 2017, 2019, MariaDB Corporation. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software @@ -127,12 +127,12 @@ struct i_s_trx_row_t { trx_id_t trx_id; /*!< transaction identifier */ const char* trx_state; /*!< transaction state from trx_get_que_state_str() */ - ib_time_t trx_started; /*!< trx_t::start_time */ + time_t trx_started; /*!< trx_t::start_time */ const i_s_locks_row_t* requested_lock_row; /*!< pointer to a row in innodb_locks if trx is waiting, or NULL */ - ib_time_t trx_wait_started; /*!< trx_t::wait_started */ + time_t trx_wait_started; /*!< trx_t->lock.wait_started */ uintmax_t trx_weight; /*!< TRX_WEIGHT() */ ulint trx_mysql_thread_id; /*!< thd_get_thread_id() */ const char* trx_query; /*!< MySQL statement being diff --git a/storage/innobase/include/trx0trx.h b/storage/innobase/include/trx0trx.h index b2ab4979e26..4ab29e08e0f 100644 --- a/storage/innobase/include/trx0trx.h +++ b/storage/innobase/include/trx0trx.h @@ -963,10 +963,11 @@ struct trx_t { on dict_operation_lock. Protected by dict_operation_lock. */ - time_t start_time; /*!< time the state last time became - TRX_STATE_ACTIVE */ - ib_uint64_t start_time_micro; /*!< start time of transaction in - microseconds */ + /** wall-clock time of the latest transition to TRX_STATE_ACTIVE; + used for diagnostic purposes only */ + time_t start_time; + /** microsecond_interval_timer() of transaction start */ + ulonglong start_time_micro; lsn_t commit_lsn; /*!< lsn at the time of the commit */ table_id_t table_id; /*!< Table to drop iff dict_operation == TRX_DICT_OP_TABLE, or 0. */ diff --git a/storage/innobase/include/ut0timer.h b/storage/innobase/include/ut0timer.h deleted file mode 100644 index 376af3cf0ef..00000000000 --- a/storage/innobase/include/ut0timer.h +++ /dev/null @@ -1,67 +0,0 @@ -/***************************************************************************** - -Copyright (c) 2013, 2014, Facebook, Inc. All Rights Reserved. -Copyright (c) 2014, 2018, MariaDB Corporation. - -This program is free software; you can redistribute it and/or modify it under -the terms of the GNU General Public License as published by the Free Software -Foundation; version 2 of the License. - -This program is distributed in the hope that it will be useful, but WITHOUT -ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS -FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. - -You should have received a copy of the GNU General Public License along with -this program; if not, write to the Free Software Foundation, Inc., -51 Franklin Street, Fifth Floor, Boston, MA 02110-1335 USA - -*****************************************************************************/ - -/********************************************************************//** -@file include/ut0timer.h -Timer routines - -Created 30/07/2014 Jan Lindström jan.lindstrom@skysql.com -modified from https://github.com/facebook/mysql-5.6/commit/c75a413edeb96eb99bf11d7269bdfea06f96d6b6 -*************************************************************************/ -#ifndef ut0timer_h -#define ut0timer_h - -#include "univ.i" - -/* Current timer stats */ -extern struct my_timer_unit_info ut_timer; - -/**************************************************************//** -Function pointer to point selected timer function. -@return timer current value */ -extern ulonglong (*ut_timer_now)(void); - -/**************************************************************//** -Sets up the data required for use of my_timer_* functions. -Selects the best timer by high frequency, and tight resolution. -Points my_timer_now() to the selected timer function. -Initializes my_timer struct to contain the info for selected timer.*/ -UNIV_INTERN -void ut_init_timer(void); - -/**************************************************************//** -Convert native timer units in a ulonglong into microseconds in a double -@return time in microseconds */ -UNIV_INLINE -double -ut_timer_to_microseconds( -/*=====================*/ - ulonglong when); /*!< in: time where to calculate */ -/**************************************************************//** -Convert microseconds in a double to native timer units in a ulonglong -@return time in microseconds */ -UNIV_INLINE -ulonglong -ut_microseconds_to_timer( -/*=====================*/ - ulonglong when); /*!< in: time where to calculate */ - -#include "ut0timer.ic" - -#endif diff --git a/storage/innobase/include/ut0timer.ic b/storage/innobase/include/ut0timer.ic deleted file mode 100644 index 26cf0bd2fbe..00000000000 --- a/storage/innobase/include/ut0timer.ic +++ /dev/null @@ -1,56 +0,0 @@ -/***************************************************************************** - -Copyright (c) 2013, 2014, Facebook, Inc. All Rights Reserved. -Copyright (c) 2014, 2018, MariaDB Corporation. - -This program is free software; you can redistribute it and/or modify it under -the terms of the GNU General Public License as published by the Free Software -Foundation; version 2 of the License. - -This program is distributed in the hope that it will be useful, but WITHOUT -ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS -FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. - -You should have received a copy of the GNU General Public License along with -this program; if not, write to the Free Software Foundation, Inc., -51 Franklin Street, Fifth Floor, Boston, MA 02110-1335 USA - -*****************************************************************************/ - -/********************************************************************//** -@file include/ut0timer.ic -Timer routines - -Created 30/07/2014 Jan Lindström jan.lindstrom@skysql.com -modified from https://github.com/facebook/mysql-5.6/commit/c75a413edeb96eb99bf11d7269bdfea06f96d6b6 -*************************************************************************/ - -/**************************************************************//** -Convert native timer units in a ulonglong into microseconds in a double -@return time in microseconds */ -UNIV_INLINE -double -ut_timer_to_microseconds( -/*=====================*/ - ulonglong when) /*!< in: time where to calculate */ -{ - double ret = (double)(when); - ret *= 1000000.0; - ret /= (double)(ut_timer.frequency); - return ret; -} - -/**************************************************************//** -Convert microseconds in a double to native timer units in a ulonglong -@return time in microseconds */ -UNIV_INLINE -ulonglong -ut_microseconds_to_timer( -/*=====================*/ - ulonglong when) /*!< in: time where to calculate */ -{ - double ret = (double)when; - ret *= (double)(ut_timer.frequency); - ret /= 1000000.0; - return (ulonglong)ret; -} diff --git a/storage/innobase/include/ut0ut.h b/storage/innobase/include/ut0ut.h index 3d1c657bf91..000d8b6b379 100644 --- a/storage/innobase/include/ut0ut.h +++ b/storage/innobase/include/ut0ut.h @@ -50,9 +50,6 @@ Created 1/20/1994 Heikki Tuuri /** Index name prefix in fast index creation, as a string constant */ #define TEMP_INDEX_PREFIX_STR "\377" -/** Time stamp */ -typedef time_t ib_time_t; - #ifdef HAVE_PAUSE_INSTRUCTION /* According to the gcc info page, asm volatile means that the instruction has important side-effects and must not be removed. @@ -201,26 +198,6 @@ store the given number of bits. #define UT_BITS_IN_BYTES(b) (((b) + 7) / 8) /**********************************************************//** -Returns system time. We do not specify the format of the time returned: -the only way to manipulate it is to use the function ut_difftime. -@return system time */ -ib_time_t -ut_time(void); -/*=========*/ - -/**********************************************************//** -Returns system time. -Upon successful completion, the value 0 is returned; otherwise the -value -1 is returned and the global variable errno is set to indicate the -error. -@return 0 on success, -1 otherwise */ -int -ut_usectime( -/*========*/ - ulint* sec, /*!< out: seconds since the Epoch */ - ulint* ms); /*!< out: microseconds since the Epoch+*sec */ - -/**********************************************************//** Returns the number of milliseconds since some epoch. The value may wrap around. It should only be used for heuristic purposes. @@ -228,25 +205,6 @@ purposes. ulint ut_time_ms(void); /*============*/ - -/**********************************************************//** -Returns the number of milliseconds since some epoch. The -value may wrap around. It should only be used for heuristic -purposes. -@return ms since epoch */ -ulint -ut_time_ms(void); -/*============*/ - -/**********************************************************//** -Returns the difference of two times in seconds. -@return time2 - time1 expressed in seconds */ -double -ut_difftime( -/*========*/ - ib_time_t time2, /*!< in: time */ - ib_time_t time1); /*!< in: time */ - #endif /* !UNIV_INNOCHECKSUM */ /** Determines if a number is zero or a power of two. diff --git a/storage/innobase/include/ut0wqueue.h b/storage/innobase/include/ut0wqueue.h index 008ea2a70dd..6a096a36894 100644 --- a/storage/innobase/include/ut0wqueue.h +++ b/storage/innobase/include/ut0wqueue.h @@ -84,7 +84,7 @@ ib_wqueue_timedwait( /*================*/ /* out: work item or NULL on timeout*/ ib_wqueue_t* wq, /* in: work queue */ - ib_time_t wait_in_usecs); /* in: wait time in micro seconds */ + ulint wait_in_usecs); /* in: wait time in micro seconds */ /******************************************************************** Return first item on work queue or NULL if queue is empty diff --git a/storage/innobase/lock/lock0lock.cc b/storage/innobase/lock/lock0lock.cc index 2344ccff00f..21171bad2bb 100644 --- a/storage/innobase/lock/lock0lock.cc +++ b/storage/innobase/lock/lock0lock.cc @@ -74,44 +74,39 @@ extern "C" int thd_need_ordering_with(const MYSQL_THD thd, const MYSQL_THD other extern "C" int thd_deadlock_victim_preference(const MYSQL_THD thd1, const MYSQL_THD thd2); -/** Print info of a table lock. +/** Pretty-print a table lock. @param[in,out] file output stream @param[in] lock table lock */ -static -void -lock_table_print(FILE* file, const lock_t* lock); +static void lock_table_print(FILE* file, const lock_t* lock); -/** Print info of a record lock. +/** Pretty-print a record lock. @param[in,out] file output stream -@param[in] lock record lock */ -static -void -lock_rec_print(FILE* file, const lock_t* lock); +@param[in] lock record lock +@param[in,out] mtr mini-transaction for accessing the record */ +static void lock_rec_print(FILE* file, const lock_t* lock, mtr_t& mtr); /** Deadlock checker. */ class DeadlockChecker { public: - /** Checks if a joining lock request results in a deadlock. If - a deadlock is found this function will resolve the deadlock - by choosing a victim transaction and rolling it back. It - will attempt to resolve all deadlocks. The returned transaction - id will be the joining transaction id or 0 if some other - transaction was chosen as a victim and rolled back or no - deadlock found. - - @param lock lock the transaction is requesting - @param trx transaction requesting the lock - - @return id of transaction chosen as victim or 0 */ - static const trx_t* check_and_resolve( - const lock_t* lock, - trx_t* trx); + /** Check if a joining lock request results in a deadlock. + If a deadlock is found, we will resolve the deadlock by + choosing a victim transaction and rolling it back. + We will attempt to resolve all deadlocks. + + @param[in] lock the lock request + @param[in,out] trx transaction requesting the lock + + @return trx if it was chosen as victim + @retval NULL if another victim was chosen, + or there is no deadlock (any more) */ + static const trx_t* check_and_resolve(const lock_t* lock, trx_t* trx); private: /** Do a shallow copy. Default destructor OK. @param trx the start transaction (start node) @param wait_lock lock that a transaction wants - @param mark_start visited node counter */ + @param mark_start visited node counter + @param report_waiters whether to call thd_rpl_deadlock_check() */ DeadlockChecker( const trx_t* trx, const lock_t* wait_lock, @@ -759,11 +754,12 @@ lock_rec_has_to_wait( thread, we need to look at trx ordering and lock types */ if (wsrep_thd_is_BF(trx->mysql_thd, FALSE) && wsrep_thd_is_BF(lock2->trx->mysql_thd, TRUE)) { + mtr_t mtr; if (wsrep_debug) { ib::info() << "BF-BF lock conflict, locking: " << for_locking; - lock_rec_print(stderr, lock2); + lock_rec_print(stderr, lock2, mtr); ib::info() << " SQL1: " << wsrep_thd_query(trx->mysql_thd); ib::info() << " SQL2: " @@ -786,7 +782,7 @@ lock_rec_has_to_wait( << wsrep_thd_conflict_state(trx->mysql_thd, FALSE) << " locked " << wsrep_thd_conflict_state(lock2->trx->mysql_thd, FALSE); - lock_rec_print(stderr, lock2); + lock_rec_print(stderr, lock2, mtr); ib::info() << " SQL1: " << wsrep_thd_query(trx->mysql_thd); ib::info() << " SQL2: " @@ -1110,6 +1106,7 @@ wsrep_kill_victim( my_bool bf_this = wsrep_thd_is_BF(trx->mysql_thd, FALSE); my_bool bf_other = wsrep_thd_is_BF(lock->trx->mysql_thd, TRUE); + mtr_t mtr; if ((bf_this && !bf_other) || (bf_this && bf_other && wsrep_trx_order_before( @@ -1141,7 +1138,7 @@ wsrep_kill_victim( ib::info() << "*** WAITING FOR THIS LOCK TO BE GRANTED:"; if (lock_get_type(lock) == LOCK_REC) { - lock_rec_print(stderr, lock); + lock_rec_print(stderr, lock, mtr); } else { lock_table_print(stderr, lock); } @@ -1357,6 +1354,7 @@ wsrep_print_wait_locks( lock_t* c_lock) /* conflicting lock to print */ { if (wsrep_debug && c_lock->trx->lock.wait_lock != c_lock) { + mtr_t mtr; ib::info() << "WSREP: c_lock != wait lock"; ib::info() << " SQL: " << wsrep_thd_query(c_lock->trx->mysql_thd); @@ -1364,13 +1362,14 @@ wsrep_print_wait_locks( if (lock_get_type_low(c_lock) & LOCK_TABLE) { lock_table_print(stderr, c_lock); } else { - lock_rec_print(stderr, c_lock); + lock_rec_print(stderr, c_lock, mtr); } if (lock_get_type_low(c_lock->trx->lock.wait_lock) & LOCK_TABLE) { lock_table_print(stderr, c_lock->trx->lock.wait_lock); } else { - lock_rec_print(stderr, c_lock->trx->lock.wait_lock); + lock_rec_print(stderr, c_lock->trx->lock.wait_lock, + mtr); } } } @@ -1583,11 +1582,7 @@ If only one of them is a wait lock, it has lower priority. If either is a high priority transaction, the lock has higher priority. Otherwise, the one with an older transaction has higher priority. @returns true if lock1 has higher priority, false otherwise. */ -static -bool -has_higher_priority( - lock_t *lock1, - lock_t *lock2) +static bool has_higher_priority(lock_t *lock1, lock_t *lock2) { if (lock1 == NULL) { return false; @@ -1789,10 +1784,7 @@ lock_rec_enqueue_waiting( lock_prdt_set_prdt(lock, prdt); } - if ( -#ifdef UNIV_DEBUG - const trx_t* victim = -#endif + if (ut_d(const trx_t* victim =) DeadlockChecker::check_and_resolve(lock, trx)) { ut_ad(victim == trx); lock_reset_lock_and_trx_wait(lock); @@ -1816,7 +1808,7 @@ lock_rec_enqueue_waiting( trx->lock.que_state = TRX_QUE_LOCK_WAIT; trx->lock.was_chosen_as_deadlock_victim = false; - trx->lock.wait_started = ut_time(); + trx->lock.wait_started = time(NULL); ut_a(que_thr_stop(thr)); @@ -2226,12 +2218,13 @@ lock_rec_has_to_wait_in_queue( if (wsrep_thd_is_BF(wait_lock->trx->mysql_thd, FALSE) && wsrep_thd_is_BF(lock->trx->mysql_thd, TRUE)) { if (wsrep_debug) { + mtr_t mtr; ib::info() << "WSREP: waiting BF trx: " << ib::hex(wait_lock->trx->id) << " query: " << wsrep_thd_query(wait_lock->trx->mysql_thd); - lock_rec_print(stderr, wait_lock); + lock_rec_print(stderr, wait_lock, mtr); ib::info() << "WSREP: do not wait another BF trx: " << ib::hex(lock->trx->id) << " query: " << wsrep_thd_query(lock->trx->mysql_thd); - lock_rec_print(stderr, lock); + lock_rec_print(stderr, lock, mtr); } /* don't wait for another BF lock */ continue; @@ -3907,7 +3900,7 @@ lock_table_enqueue_waiting( ); const trx_t* victim_trx = - DeadlockChecker::check_and_resolve(lock, trx); + DeadlockChecker::check_and_resolve(lock, trx); if (victim_trx != 0) { ut_ad(victim_trx == trx); @@ -3928,7 +3921,7 @@ lock_table_enqueue_waiting( trx->lock.que_state = TRX_QUE_LOCK_WAIT; - trx->lock.wait_started = ut_time(); + trx->lock.wait_started = time(NULL); trx->lock.was_chosen_as_deadlock_victim = false; ut_a(que_thr_stop(thr)); @@ -4714,12 +4707,10 @@ lock_remove_all_on_table( /*===================== VALIDATION AND DEBUGGING ====================*/ -/** Print info of a table lock. +/** Pretty-print a table lock. @param[in,out] file output stream @param[in] lock table lock */ -static -void -lock_table_print(FILE* file, const lock_t* lock) +static void lock_table_print(FILE* file, const lock_t* lock) { ut_ad(lock_mutex_own()); ut_a(lock_get_type_low(lock) == LOCK_TABLE); @@ -4753,20 +4744,14 @@ lock_table_print(FILE* file, const lock_t* lock) putc('\n', file); } -/** Print info of a record lock. +/** Pretty-print a record lock. @param[in,out] file output stream -@param[in] lock record lock */ -static -void -lock_rec_print(FILE* file, const lock_t* lock) +@param[in] lock record lock +@param[in,out] mtr mini-transaction for accessing the record */ +static void lock_rec_print(FILE* file, const lock_t* lock, mtr_t& mtr) { ulint space; ulint page_no; - mtr_t mtr; - mem_heap_t* heap = NULL; - ulint offsets_[REC_OFFS_NORMAL_SIZE]; - ulint* offsets = offsets_; - rec_offs_init(offsets_); ut_ad(lock_mutex_own()); ut_a(lock_get_type_low(lock) == LOCK_REC); @@ -4806,13 +4791,16 @@ lock_rec_print(FILE* file, const lock_t* lock) fputs(" waiting", file); } - mtr_start(&mtr); - putc('\n', file); - const buf_block_t* block; + mem_heap_t* heap = NULL; + ulint offsets_[REC_OFFS_NORMAL_SIZE]; + ulint* offsets = offsets_; + rec_offs_init(offsets_); - block = buf_page_try_get(page_id_t(space, page_no), &mtr); + mtr.start(); + const buf_block_t* block = buf_page_try_get(page_id_t(space, page_no), + &mtr); for (ulint i = 0; i < lock_rec_get_n_bits(lock); ++i) { @@ -4840,9 +4828,9 @@ lock_rec_print(FILE* file, const lock_t* lock) putc('\n', file); } - mtr_commit(&mtr); + mtr.commit(); - if (heap) { + if (UNIV_LIKELY_NULL(heap)) { mem_heap_free(heap); } } @@ -4975,11 +4963,10 @@ lock_print_info_summary( /** Prints transaction lock wait and MVCC state. @param[in,out] file file where to print -@param[in] trx transaction */ +@param[in] trx transaction +@param[in] now current time */ void -lock_trx_print_wait_and_mvcc_state( - FILE* file, - const trx_t* trx) +lock_trx_print_wait_and_mvcc_state(FILE* file, const trx_t* trx, time_t now) { fprintf(file, "---"); @@ -4996,10 +4983,11 @@ lock_trx_print_wait_and_mvcc_state( fprintf(file, "------- TRX HAS BEEN WAITING %lu SEC" " FOR THIS LOCK TO BE GRANTED:\n", - (ulong) difftime(ut_time(), trx->lock.wait_started)); + (ulong) difftime(now, trx->lock.wait_started)); if (lock_get_type_low(trx->lock.wait_lock) == LOCK_REC) { - lock_rec_print(file, trx->lock.wait_lock); + mtr_t mtr; + lock_rec_print(file, trx->lock.wait_lock, mtr); } else { lock_table_print(file, trx->lock.wait_lock); } @@ -5017,6 +5005,7 @@ lock_trx_print_locks( FILE* file, /*!< in/out: File to write */ const trx_t* trx) /*!< in: current transaction */ { + mtr_t mtr; uint32_t i= 0; /* Iterate over the transaction's locks. */ for (lock_t *lock = UT_LIST_GET_FIRST(trx->lock.trx_locks); @@ -5024,7 +5013,7 @@ lock_trx_print_locks( lock = UT_LIST_GET_NEXT(trx_locks, lock)) { if (lock_get_type_low(lock) == LOCK_REC) { - lock_rec_print(file, lock); + lock_rec_print(file, lock, mtr); } else { ut_ad(lock_get_type_low(lock) & LOCK_TABLE); @@ -5045,25 +5034,26 @@ lock_trx_print_locks( /** Functor to display all transactions (except recovered ones) */ struct lock_print_info { - lock_print_info(FILE* file) : file(file) {} + lock_print_info(FILE* file, time_t now) : file(file), now(now) {} void operator()(const trx_t* trx) const { ut_ad(mutex_own(&trx_sys->mutex)); ut_ad(trx->in_mysql_trx_list); - lock_trx_print_wait_and_mvcc_state(file, trx); + lock_trx_print_wait_and_mvcc_state(file, trx, now); if (trx->will_lock && srv_print_innodb_lock_monitor) lock_trx_print_locks(file, trx); } FILE* const file; + const time_t now; }; /** Functor to display recovered read-write transactions */ struct lock_print_info_rw_recovered { - lock_print_info_rw_recovered(FILE* file) : file(file) {} + lock_print_info_rw_recovered(FILE* file, time_t now) : file(file),now(now) {} void operator()(const trx_t* trx) const { @@ -5073,13 +5063,14 @@ struct lock_print_info_rw_recovered return; ut_ad(!trx->in_mysql_trx_list); - lock_trx_print_wait_and_mvcc_state(file, trx); + lock_trx_print_wait_and_mvcc_state(file, trx, now); if (trx->will_lock && srv_print_innodb_lock_monitor) lock_trx_print_locks(file, trx); } FILE* const file; + const time_t now; }; /*********************************************************************//** @@ -5094,10 +5085,12 @@ lock_print_info_all_transactions( ut_ad(lock_mutex_own()); fprintf(file, "LIST OF TRANSACTIONS FOR EACH SESSION:\n"); + const time_t now = time(NULL); mutex_enter(&trx_sys->mutex); - ut_list_map(trx_sys->mysql_trx_list, lock_print_info(file)); - ut_list_map(trx_sys->rw_trx_list, lock_print_info_rw_recovered(file)); + ut_list_map(trx_sys->mysql_trx_list, lock_print_info(file, now)); + ut_list_map(trx_sys->rw_trx_list, + lock_print_info_rw_recovered(file, now)); mutex_exit(&trx_sys->mutex); lock_mutex_exit(); ut_ad(lock_validate()); @@ -6995,10 +6988,11 @@ DeadlockChecker::print(const lock_t* lock) ut_ad(lock_mutex_own()); if (lock_get_type_low(lock) == LOCK_REC) { - lock_rec_print(lock_latest_err_file, lock); + mtr_t mtr; + lock_rec_print(lock_latest_err_file, lock, mtr); if (srv_print_all_deadlocks) { - lock_rec_print(stderr, lock); + lock_rec_print(stderr, lock, mtr); } } else { lock_table_print(lock_latest_err_file, lock); @@ -7293,7 +7287,7 @@ DeadlockChecker::search() @param trx transaction rolled back @param lock lock trx wants */ void -DeadlockChecker::rollback_print(const trx_t* trx, const lock_t* lock) +DeadlockChecker::rollback_print(const trx_t* trx, const lock_t* lock) { ut_ad(lock_mutex_own()); @@ -7333,16 +7327,17 @@ DeadlockChecker::trx_rollback() trx_mutex_exit(trx); } -/** Checks if a joining lock request results in a deadlock. If a deadlock is -found this function will resolve the deadlock by choosing a victim transaction -and rolling it back. It will attempt to resolve all deadlocks. The returned -transaction id will be the joining transaction instance or NULL if some other -transaction was chosen as a victim and rolled back or no deadlock found. +/** Check if a joining lock request results in a deadlock. +If a deadlock is found, we will resolve the deadlock by +choosing a victim transaction and rolling it back. +We will attempt to resolve all deadlocks. -@param[in] lock lock the transaction is requesting -@param[in,out] trx transaction requesting the lock +@param[in] lock the lock request +@param[in,out] trx transaction requesting the lock -@return transaction instanace chosen as victim or 0 */ +@return trx if it was chosen as victim +@retval NULL if another victim was chosen, +or there is no deadlock (any more) */ const trx_t* DeadlockChecker::check_and_resolve(const lock_t* lock, trx_t* trx) { diff --git a/storage/innobase/lock/lock0wait.cc b/storage/innobase/lock/lock0wait.cc index 0712c57fb53..947e56ebeee 100644 --- a/storage/innobase/lock/lock0wait.cc +++ b/storage/innobase/lock/lock0wait.cc @@ -1,7 +1,7 @@ /***************************************************************************** Copyright (c) 1996, 2016, Oracle and/or its affiliates. All Rights Reserved. -Copyright (c) 2014, 2018, MariaDB Corporation. +Copyright (c) 2014, 2019, MariaDB Corporation. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software @@ -58,7 +58,7 @@ lock_wait_table_print(void) (ulong) slot->in_use, (ulong) slot->suspended, slot->wait_timeout, - (ulong) difftime(ut_time(), slot->suspend_time)); + (ulong) difftime(time(NULL), slot->suspend_time)); } } @@ -155,7 +155,7 @@ lock_wait_table_reserve_slot( os_event_reset(slot->event); slot->suspended = TRUE; - slot->suspend_time = ut_time(); + slot->suspend_time = time(NULL); slot->wait_timeout = wait_timeout; if (slot == lock_sys->last_slot) { @@ -231,13 +231,8 @@ lock_wait_suspend_thread( user OS thread */ { srv_slot_t* slot; - double wait_time; trx_t* trx; ibool was_declared_inside_innodb; - int64_t start_time = 0; - int64_t finish_time; - ulint sec; - ulint ms; ulong lock_wait_timeout; trx = thr_get_trx(thr); @@ -283,15 +278,12 @@ lock_wait_suspend_thread( lock_wait_mutex_exit(); trx_mutex_exit(trx); + ulonglong start_time = 0; + if (thr->lock_state == QUE_THR_LOCK_ROW) { srv_stats.n_lock_wait_count.inc(); srv_stats.n_lock_wait_current_count.inc(); - - if (ut_usectime(&sec, &ms) == -1) { - start_time = -1; - } else { - start_time = static_cast<int64_t>(sec) * 1000000 + ms; - } + start_time = my_interval_timer(); } ulint lock_type = ULINT_UNDEFINED; @@ -371,34 +363,28 @@ lock_wait_suspend_thread( row_mysql_freeze_data_dictionary(trx); } - wait_time = ut_difftime(ut_time(), slot->suspend_time); + double wait_time = difftime(time(NULL), slot->suspend_time); /* Release the slot for others to use */ lock_wait_table_release_slot(slot); if (thr->lock_state == QUE_THR_LOCK_ROW) { - ulint diff_time; - - if (ut_usectime(&sec, &ms) == -1) { - finish_time = -1; - } else { - finish_time = static_cast<int64_t>(sec) * 1000000 + ms; - } - - diff_time = (finish_time > start_time) ? - (ulint) (finish_time - start_time) : 0; - srv_stats.n_lock_wait_current_count.dec(); - srv_stats.n_lock_wait_time.add(diff_time); - /* Only update the variable if we successfully - retrieved the start and finish times. See Bug#36819. */ - if (diff_time > lock_sys->n_lock_max_wait_time - && start_time != -1 - && finish_time != -1) { + const ulonglong finish_time = my_interval_timer(); + ulint diff_time; - lock_sys->n_lock_max_wait_time = diff_time; + if (finish_time < start_time) { + diff_time = 0; + } else { + diff_time = ulint((finish_time - start_time) / 1000); + srv_stats.n_lock_wait_time.add(diff_time); + /* Only update the variable if we successfully + retrieved the start and finish times. See Bug#36819. */ + if (diff_time > lock_sys->n_lock_max_wait_time) { + lock_sys->n_lock_max_wait_time = diff_time; + } } /* Record the lock wait time for this thread */ @@ -472,19 +458,12 @@ lock_wait_check_and_cancel( const srv_slot_t* slot) /*!< in: slot reserved by a user thread when the wait started */ { - trx_t* trx; - double wait_time; - ib_time_t suspend_time = slot->suspend_time; - ut_ad(lock_wait_mutex_own()); - ut_ad(slot->in_use); - ut_ad(slot->suspended); - wait_time = ut_difftime(ut_time(), suspend_time); - - trx = thr_get_trx(slot->thr); + double wait_time = difftime(time(NULL), slot->suspend_time); + trx_t* trx = thr_get_trx(slot->thr); if (trx_is_interrupted(trx) || (slot->wait_timeout < 100000000 @@ -519,7 +498,6 @@ lock_wait_check_and_cancel( trx_mutex_exit(trx); } - } /*********************************************************************//** diff --git a/storage/innobase/log/log0recv.cc b/storage/innobase/log/log0recv.cc index a8b3ed4f837..2df1a8950d8 100644 --- a/storage/innobase/log/log0recv.cc +++ b/storage/innobase/log/log0recv.cc @@ -853,7 +853,7 @@ recv_sys_init() ut_malloc_nokey(RECV_PARSING_BUF_SIZE)); recv_sys->addr_hash = hash_create(size / 512); - recv_sys->progress_time = ut_time(); + recv_sys->progress_time = time(NULL); recv_max_page_lsn = 0; /* Call the constructor for recv_sys_t::dblwr member */ @@ -1007,7 +1007,7 @@ fail: } } - if (recv_sys->report(ut_time())) { + if (recv_sys->report(time(NULL))) { ib::info() << "Read redo log up to LSN=" << *start_lsn; service_manager_extend_timeout(INNODB_EXTEND_TIMEOUT_INTERVAL, "Read redo log up to LSN=" LSN_PF, @@ -2191,7 +2191,7 @@ skip_log: mtr.discard_modifications(); mtr.commit(); - ib_time_t time = ut_time(); + time_t now = time(NULL); mutex_enter(&recv_sys->mutex); @@ -2204,7 +2204,7 @@ skip_log: ut_a(recv_sys->n_addrs > 0); if (ulint n = --recv_sys->n_addrs) { - if (recv_sys->report(time)) { + if (recv_sys->report(now)) { ib::info() << "To recover: " << n << " pages from log"; service_manager_extend_timeout( INNODB_EXTEND_TIMEOUT_INTERVAL, "To recover: " ULINTPF " pages from log", n); diff --git a/storage/innobase/os/os0event.cc b/storage/innobase/os/os0event.cc index a93b11649d5..e0c38690b25 100644 --- a/storage/innobase/os/os0event.cc +++ b/storage/innobase/os/os0event.cc @@ -1,6 +1,7 @@ /***************************************************************************** Copyright (c) 2013, 2015, Oracle and/or its affiliates. All Rights Reserved. +Copyright (c) 2019, MariaDB Corporation. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software @@ -29,12 +30,6 @@ Created 2012-09-23 Sunny Bains #ifdef _WIN32 #include <windows.h> #include <synchapi.h> -#endif /* _WIN32 */ - -/** The number of microsecnds in a second. */ -static const ulint MICROSECS_IN_A_SECOND = 1000000; - -#ifdef _WIN32 /** Native condition variable. */ typedef CONDITION_VARIABLE os_cond_t; #else @@ -361,26 +356,9 @@ os_event::wait_time_low( struct timespec abstime; if (time_in_usec != OS_SYNC_INFINITE_TIME) { - struct timeval tv; - int ret; - ulint sec; - ulint usec; - - ret = ut_usectime(&sec, &usec); - ut_a(ret == 0); - - tv.tv_sec = sec; - tv.tv_usec = usec; - - tv.tv_usec += time_in_usec; - - if ((ulint) tv.tv_usec >= MICROSECS_IN_A_SECOND) { - tv.tv_sec += tv.tv_usec / MICROSECS_IN_A_SECOND; - tv.tv_usec %= MICROSECS_IN_A_SECOND; - } - - abstime.tv_sec = tv.tv_sec; - abstime.tv_nsec = tv.tv_usec * 1000; + ulonglong usec = ulonglong(time_in_usec) + my_hrtime().val; + abstime.tv_sec = usec / 1000000; + abstime.tv_nsec = (usec % 1000000) * 1000; } else { abstime.tv_nsec = 999999999; abstime.tv_sec = (time_t) ULINT_MAX; diff --git a/storage/innobase/os/os0file.cc b/storage/innobase/os/os0file.cc index 2a89a6fc982..6d40d45412f 100644 --- a/storage/innobase/os/os0file.cc +++ b/storage/innobase/os/os0file.cc @@ -6062,7 +6062,7 @@ AIO::start( os_aio_validate(); - os_last_printout = ut_time(); + os_last_printout = time(NULL); if (srv_use_native_aio) { return(true); @@ -6318,7 +6318,7 @@ AIO::reserve_slot( } slot->is_reserved = true; - slot->reservation_time = ut_time(); + slot->reservation_time = time(NULL); slot->m1 = m1; slot->m2 = m2; slot->file = file; @@ -7128,7 +7128,7 @@ private: { ulint age; - age = (ulint) difftime(ut_time(), slot->reservation_time); + age = (ulint) difftime(time(NULL), slot->reservation_time); if ((age >= 2 && age > m_oldest) || (age >= 2 @@ -7530,7 +7530,7 @@ os_aio_print(FILE* file) AIO::print_all(file); putc('\n', file); - current_time = ut_time(); + current_time = time(NULL); time_elapsed = 0.001 + difftime(current_time, os_last_printout); fprintf(file, @@ -7596,7 +7596,7 @@ os_aio_refresh_stats() os_bytes_read_since_printout = 0; - os_last_printout = ut_time(); + os_last_printout = time(NULL); } /** Checks that all slots in the system have been freed, that is, there are diff --git a/storage/innobase/srv/srv0srv.cc b/storage/innobase/srv/srv0srv.cc index 6e0b994ad76..a93a7cd71f8 100644 --- a/storage/innobase/srv/srv0srv.cc +++ b/storage/innobase/srv/srv0srv.cc @@ -1728,8 +1728,9 @@ DECLARE_THREAD(srv_monitor_thread)(void*) pfs_register_thread(srv_monitor_thread_key); #endif /* UNIV_PFS_THREAD */ - srv_last_monitor_time = ut_time(); - last_monitor_time = ut_time(); + current_time = time(NULL); + srv_last_monitor_time = current_time; + last_monitor_time = current_time; mutex_skipped = 0; last_srv_print_monitor = srv_print_innodb_monitor; loop: @@ -1740,12 +1741,12 @@ loop: os_event_wait_time_low(srv_monitor_event, 5000000, sig_count); - current_time = ut_time(); + current_time = time(NULL); time_elapsed = difftime(current_time, last_monitor_time); if (time_elapsed > 15) { - last_monitor_time = ut_time(); + last_monitor_time = current_time; if (srv_print_innodb_monitor) { /* Reset mutex_skipped counter everytime @@ -2096,20 +2097,16 @@ static void srv_shutdown_print_master_pending( /*==============================*/ - ib_time_t* last_print_time, /*!< last time the function + time_t* last_print_time, /*!< last time the function print the message */ ulint n_tables_to_drop, /*!< number of tables to be dropped */ ulint n_bytes_merged) /*!< number of change buffer just merged */ { - ib_time_t current_time; - double time_elapsed; - - current_time = ut_time(); - time_elapsed = ut_difftime(current_time, *last_print_time); + time_t current_time = time(NULL); - if (time_elapsed > 60) { + if (difftime(current_time, *last_print_time) > 60) { *last_print_time = current_time; if (n_tables_to_drop) { @@ -2193,7 +2190,7 @@ void srv_master_do_active_tasks(void) /*============================*/ { - ib_time_t cur_time = ut_time(); + time_t cur_time = time(NULL); ulonglong counter_time = microsecond_interval_timer(); /* First do the tasks that we are suppose to do at each @@ -2369,7 +2366,7 @@ srv_shutdown(bool ibuf_merge) { ulint n_bytes_merged = 0; ulint n_tables_to_drop; - ib_time_t now = ut_time(); + time_t now = time(NULL); do { ut_ad(!srv_read_only_mode); @@ -2514,10 +2511,10 @@ srv_purge_should_exit(ulint n_purged) /* Slow shutdown was requested. */ if (n_purged) { #if defined HAVE_SYSTEMD && !defined EMBEDDED_LIBRARY - static ib_time_t progress_time; - ib_time_t time = ut_time(); - if (time - progress_time >= 15) { - progress_time = time; + static time_t progress_time; + time_t now = time(NULL); + if (now - progress_time >= 15) { + progress_time = now; service_manager_extend_timeout( INNODB_EXTEND_TIMEOUT_INTERVAL, "InnoDB: to purge " ULINTPF " transactions", diff --git a/storage/innobase/srv/srv0start.cc b/storage/innobase/srv/srv0start.cc index 86a56b42add..f3e91dee159 100644 --- a/storage/innobase/srv/srv0start.cc +++ b/storage/innobase/srv/srv0start.cc @@ -47,7 +47,6 @@ Created 2/16/1996 Heikki Tuuri #include "row0ftsort.h" #include "ut0mem.h" -#include "ut0timer.h" #include "mem0mem.h" #include "data0data.h" #include "data0type.h" diff --git a/storage/innobase/sync/sync0arr.cc b/storage/innobase/sync/sync0arr.cc index 50770f926d3..0c942ada430 100644 --- a/storage/innobase/sync/sync0arr.cc +++ b/storage/innobase/sync/sync0arr.cc @@ -2,7 +2,7 @@ Copyright (c) 1995, 2016, Oracle and/or its affiliates. All Rights Reserved. Copyright (c) 2008, Google Inc. -Copyright (c) 2013, 2017, MariaDB Corporation. +Copyright (c) 2013, 2019, MariaDB Corporation. Portions of this file contain modifications contributed and copyrighted by Google, Inc. Those modifications are gratefully acknowledged and are described @@ -119,8 +119,10 @@ struct sync_cell_t { has not been signalled in the period between the reset and wait call. */ - time_t reservation_time;/*!< time when the thread reserved - the wait cell */ + /** time(NULL) when the wait cell was reserved. + FIXME: sync_array_print_long_waits_low() may display bogus + warnings when the system time is adjusted to the past! */ + time_t reservation_time; }; /* NOTE: It is allowed for a thread to wait for an event allocated for @@ -375,7 +377,7 @@ sync_array_reserve_cell( cell->thread_id = os_thread_get_curr_id(); - cell->reservation_time = ut_time(); + cell->reservation_time = time(NULL); /* Make sure the event is reset and also store the value of signal_count at which the event was reset. */ diff --git a/storage/innobase/trx/trx0i_s.cc b/storage/innobase/trx/trx0i_s.cc index bdd62528a22..6dba53dee6b 100644 --- a/storage/innobase/trx/trx0i_s.cc +++ b/storage/innobase/trx/trx0i_s.cc @@ -456,7 +456,7 @@ fill_trx_row( ut_ad(lock_mutex_own()); row->trx_id = trx_get_id_for_print(trx); - row->trx_started = (ib_time_t) trx->start_time; + row->trx_started = trx->start_time; row->trx_state = trx_get_que_state_str(trx); row->requested_lock_row = requested_lock_row; ut_ad(requested_lock_row == NULL @@ -465,7 +465,7 @@ fill_trx_row( if (trx->lock.wait_lock != NULL) { ut_a(requested_lock_row != NULL); - row->trx_wait_started = (ib_time_t) trx->lock.wait_started; + row->trx_wait_started = trx->lock.wait_started; } else { ut_a(requested_lock_row == NULL); row->trx_wait_started = 0; diff --git a/storage/innobase/trx/trx0purge.cc b/storage/innobase/trx/trx0purge.cc index 2b57b5ef15f..78bf2fc29b8 100644 --- a/storage/innobase/trx/trx0purge.cc +++ b/storage/innobase/trx/trx0purge.cc @@ -171,7 +171,8 @@ purge_graph_build() trx_t* trx = trx_allocate_for_background(); ut_ad(!trx->id); - trx->start_time = ut_time(); + trx->start_time = time(NULL); + trx->start_time_micro = microsecond_interval_timer(); trx->state = TRX_STATE_ACTIVE; trx->op_info = "purge trx"; diff --git a/storage/innobase/trx/trx0roll.cc b/storage/innobase/trx/trx0roll.cc index 99659c7f71d..f1a19d91d0b 100644 --- a/storage/innobase/trx/trx0roll.cc +++ b/storage/innobase/trx/trx0roll.cc @@ -771,11 +771,11 @@ trx_roll_must_shutdown() return true; } - ib_time_t time = ut_time(); + time_t now = time(NULL); mutex_enter(&trx_sys->mutex); mutex_enter(&recv_sys->mutex); - if (recv_sys->report(time)) { + if (recv_sys->report(now)) { ulint n_trx = 0; ulonglong n_rows = 0; for (const trx_t* t = UT_LIST_GET_FIRST(trx_sys->rw_trx_list); diff --git a/storage/innobase/trx/trx0trx.cc b/storage/innobase/trx/trx0trx.cc index b8df50b6370..196ae5db36e 100644 --- a/storage/innobase/trx/trx0trx.cc +++ b/storage/innobase/trx/trx0trx.cc @@ -781,7 +781,8 @@ trx_resurrect_insert( /* trx_start_low() is not called with resurrect, so need to initialize start time here.*/ if (trx->state != TRX_STATE_COMMITTED_IN_MEMORY) { - trx->start_time = ut_time(); + trx->start_time = time(NULL); + trx->start_time_micro = microsecond_interval_timer(); } if (undo->dict_operation) { @@ -867,7 +868,8 @@ trx_resurrect_update( start time here.*/ if (trx->state == TRX_STATE_ACTIVE || trx->state == TRX_STATE_PREPARED) { - trx->start_time = ut_time(); + trx->start_time = time(NULL); + trx->start_time_micro = microsecond_interval_timer(); } if (undo->dict_operation) { @@ -1251,14 +1253,10 @@ trx_start_low( } } - if (trx->mysql_thd != NULL) { - trx->start_time = thd_start_time_in_secs(trx->mysql_thd); - trx->start_time_micro = thd_query_start_micro(trx->mysql_thd); - - } else { - trx->start_time = ut_time(); - trx->start_time_micro = 0; - } + trx->start_time = time(NULL); + trx->start_time_micro = trx->mysql_thd + ? thd_query_start_micro(trx->mysql_thd) + : microsecond_interval_timer(); ut_a(trx->error_state == DB_SUCCESS); @@ -1539,7 +1537,7 @@ trx_update_mod_tables_timestamp( /* consider using trx->start_time if calling time() is too expensive here */ - time_t now = ut_time(); + const time_t now = time(NULL); trx_mod_tables_t::const_iterator end = trx->mod_tables.end(); diff --git a/storage/innobase/ut/ut0timer.cc b/storage/innobase/ut/ut0timer.cc deleted file mode 100644 index 9aefcafebc6..00000000000 --- a/storage/innobase/ut/ut0timer.cc +++ /dev/null @@ -1,90 +0,0 @@ -/***************************************************************************** - -Copyright (c) 2013, 2014, Facebook, Inc. All Rights Reserved. -Copyright (c) 2014, SkySQL Ab. All Rights Reserved. - -This program is free software; you can redistribute it and/or modify it under -the terms of the GNU General Public License as published by the Free Software -Foundation; version 2 of the License. - -This program is distributed in the hope that it will be useful, but WITHOUT -ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS -FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. - -You should have received a copy of the GNU General Public License along with -this program; if not, write to the Free Software Foundation, Inc., -51 Franklin Street, Fifth Floor, Boston, MA 02110-1335 USA - -*****************************************************************************/ - -/********************************************************************//** -@file ut/ut0timer.cc -Timer rountines - -Created 30/07/2014 Jan Lindström jan.lindstrom@skysql.com -modified from https://github.com/facebook/mysql-5.6/commit/c75a413edeb96eb99bf11d7269bdfea06f96d6b6 -*************************************************************************/ - -#include "data0type.h" -#include <my_rdtsc.h> -#include <ut0timer.h> - -/**************************************************************//** -Initial timer definition -@return 0 */ -static -ulonglong -ut_timer_none(void) -/*===============*/ -{ - return 0; -} - -/**************************************************************//** -Function pointer to point selected timer function. -@return timer current value */ -ulonglong (*ut_timer_now)(void) = &ut_timer_none; - -struct my_timer_unit_info ut_timer; -extern MYSQL_PLUGIN_IMPORT MY_TIMER_INFO sys_timer_info; - -/**************************************************************//** -Sets up the data required for use of my_timer_* functions. -Selects the best timer by high frequency, and tight resolution. -Points my_timer_now() to the selected timer function. -Initializes my_timer struct to contain the info for selected timer.*/ -UNIV_INTERN -void -ut_init_timer(void) -/*===============*/ -{ - if (sys_timer_info.cycles.frequency > 1000000 && - sys_timer_info.cycles.resolution == 1) { - ut_timer = sys_timer_info.cycles; - ut_timer_now = &my_timer_cycles; - } else if (sys_timer_info.nanoseconds.frequency > 1000000 && - sys_timer_info.nanoseconds.resolution == 1) { - ut_timer = sys_timer_info.nanoseconds; - ut_timer_now = &my_timer_nanoseconds; - } else if (sys_timer_info.microseconds.frequency >= 1000000 && - sys_timer_info.microseconds.resolution == 1) { - ut_timer = sys_timer_info.microseconds; - ut_timer_now = &my_timer_microseconds; - - } else if (sys_timer_info.milliseconds.frequency >= 1000 && - sys_timer_info.milliseconds.resolution == 1) { - ut_timer = sys_timer_info.milliseconds; - ut_timer_now = &my_timer_milliseconds; - } else if (sys_timer_info.ticks.frequency >= 1000 && - /* Will probably be false */ - sys_timer_info.ticks.resolution == 1) { - ut_timer = sys_timer_info.ticks; - ut_timer_now = &my_timer_ticks; - } else { - /* None are acceptable, so leave it as "None", and fill in struct */ - ut_timer.frequency = 1; /* Avoid div-by-zero */ - ut_timer.overhead = 0; /* Since it doesn't do anything */ - ut_timer.resolution = 10; /* Another sign it's bad */ - ut_timer.routine = 0; /* None */ - } -} diff --git a/storage/innobase/ut/ut0ut.cc b/storage/innobase/ut/ut0ut.cc index aa73ee010fc..252f3a50ae1 100644 --- a/storage/innobase/ut/ut0ut.cc +++ b/storage/innobase/ut/ut0ut.cc @@ -38,112 +38,6 @@ Created 5/11/1994 Heikki Tuuri #include <string> #include "log.h" -#ifdef _WIN32 -typedef VOID(WINAPI *time_fn)(LPFILETIME); -static time_fn ut_get_system_time_as_file_time = GetSystemTimeAsFileTime; - -/*****************************************************************//** -NOTE: The Windows epoch starts from 1601/01/01 whereas the Unix -epoch starts from 1970/1/1. For selection of constant see: -http://support.microsoft.com/kb/167296/ */ -#define WIN_TO_UNIX_DELTA_USEC 11644473600000000LL - - -/*****************************************************************//** -This is the Windows version of gettimeofday(2). -@return 0 if all OK else -1 */ -static -int -ut_gettimeofday( -/*============*/ - struct timeval* tv, /*!< out: Values are relative to Unix epoch */ - void* tz) /*!< in: not used */ -{ - FILETIME ft; - int64_t tm; - - if (!tv) { - errno = EINVAL; - return(-1); - } - - ut_get_system_time_as_file_time(&ft); - - tm = (int64_t) ft.dwHighDateTime << 32; - tm |= ft.dwLowDateTime; - - ut_a(tm >= 0); /* If tm wraps over to negative, the quotient / 10 - does not work */ - - tm /= 10; /* Convert from 100 nsec periods to usec */ - - /* If we don't convert to the Unix epoch the value for - struct timeval::tv_sec will overflow.*/ - tm -= WIN_TO_UNIX_DELTA_USEC; - - tv->tv_sec = (long) (tm / 1000000L); - tv->tv_usec = (long) (tm % 1000000L); - - return(0); -} -#else -/** An alias for gettimeofday(2). On Microsoft Windows, we have to -reimplement this function. */ -#define ut_gettimeofday gettimeofday -#endif - -/**********************************************************//** -Returns system time. We do not specify the format of the time returned: -the only way to manipulate it is to use the function ut_difftime. -@return system time */ -ib_time_t -ut_time(void) -/*=========*/ -{ - return(time(NULL)); -} - - -/**********************************************************//** -Returns system time. -Upon successful completion, the value 0 is returned; otherwise the -value -1 is returned and the global variable errno is set to indicate the -error. -@return 0 on success, -1 otherwise */ -int -ut_usectime( -/*========*/ - ulint* sec, /*!< out: seconds since the Epoch */ - ulint* ms) /*!< out: microseconds since the Epoch+*sec */ -{ - struct timeval tv; - int ret; - int errno_gettimeofday; - int i; - - for (i = 0; i < 10; i++) { - - ret = ut_gettimeofday(&tv, NULL); - - if (ret == -1) { - errno_gettimeofday = errno; - ib::error() << "gettimeofday(): " - << strerror(errno_gettimeofday); - os_thread_sleep(100000); /* 0.1 sec */ - errno = errno_gettimeofday; - } else { - break; - } - } - - if (ret != -1) { - *sec = (ulint) tv.tv_sec; - *ms = (ulint) tv.tv_usec; - } - - return(ret); -} - /**********************************************************//** Returns the number of milliseconds since some epoch. The value may wrap around. It should only be used for heuristic @@ -155,19 +49,6 @@ ut_time_ms(void) { return static_cast<ulint>(my_interval_timer() / 1000000); } - -/**********************************************************//** -Returns the difference of two times in seconds. -@return time2 - time1 expressed in seconds */ -double -ut_difftime( -/*========*/ - ib_time_t time2, /*!< in: time */ - ib_time_t time1) /*!< in: time */ -{ - return(difftime(time2, time1)); -} - #endif /* !UNIV_INNOCHECKSUM */ /**********************************************************//** diff --git a/storage/innobase/ut/ut0wqueue.cc b/storage/innobase/ut/ut0wqueue.cc index 4697aa2fc46..026431695ed 100644 --- a/storage/innobase/ut/ut0wqueue.cc +++ b/storage/innobase/ut/ut0wqueue.cc @@ -135,7 +135,7 @@ ib_wqueue_timedwait( /*================*/ /* out: work item or NULL on timeout*/ ib_wqueue_t* wq, /* in: work queue */ - ib_time_t wait_in_usecs) /* in: wait time in micro seconds */ + ulint wait_in_usecs) /* in: wait time in micro seconds */ { ib_list_node_t* node = NULL; diff --git a/storage/xtradb/CMakeLists.txt b/storage/xtradb/CMakeLists.txt index 423b6dafd8e..07ee23fae5c 100644 --- a/storage/xtradb/CMakeLists.txt +++ b/storage/xtradb/CMakeLists.txt @@ -501,8 +501,7 @@ SET(INNOBASE_SOURCES ut/ut0rnd.cc ut/ut0ut.cc ut/ut0vec.cc - ut/ut0wqueue.cc - ut/ut0timer.cc) + ut/ut0wqueue.cc) IF(CMAKE_SYSTEM_PROCESSOR MATCHES "ppc64le") enable_language(ASM) diff --git a/storage/xtradb/btr/btr0defragment.cc b/storage/xtradb/btr/btr0defragment.cc index bb73f878cca..070f6a9cc0a 100644 --- a/storage/xtradb/btr/btr0defragment.cc +++ b/storage/xtradb/btr/btr0defragment.cc @@ -1,7 +1,7 @@ /***************************************************************************** Copyright (C) 2012, 2014 Facebook, Inc. All Rights Reserved. -Copyright (C) 2014, 2015, MariaDB Corporation. All Rights Reserved. +Copyright (C) 2014, 2019, MariaDB Corporation. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software @@ -35,8 +35,6 @@ Modified 30/07/2014 Jan Lindström jan.lindstrom@mariadb.com #include "ibuf0ibuf.h" #include "lock0lock.h" #include "srv0start.h" -#include "srv0srv.h" -#include "ut0timer.h" #include <list> @@ -100,8 +98,7 @@ Initialize defragmentation. */ void btr_defragment_init() { - srv_defragment_interval = ut_microseconds_to_timer( - (ulonglong) (1000000.0 / srv_defragment_frequency)); + srv_defragment_interval = 1000000000ULL / srv_defragment_frequency; mutex_create(btr_defragment_mutex_key, &btr_defragment_mutex, SYNC_ANY_LATCH); } @@ -729,7 +726,7 @@ DECLARE_THREAD(btr_defragment_thread)(void*) } pcur = item->pcur; - ulonglong now = ut_timer_now(); + ulonglong now = my_interval_timer(); ulonglong elapsed = now - item->last_processed; if (elapsed < srv_defragment_interval) { @@ -739,11 +736,12 @@ DECLARE_THREAD(btr_defragment_thread)(void*) defragmentation of all indices queue up on a single thread, it's likely other indices that follow this one don't need to sleep again. */ - os_thread_sleep(((ulint)ut_timer_to_microseconds( - srv_defragment_interval - elapsed))); + os_thread_sleep(static_cast<ulint> + ((srv_defragment_interval - elapsed) + / 1000)); } - now = ut_timer_now(); + now = my_interval_timer(); mtr_start(&mtr); btr_pcur_restore_position(BTR_MODIFY_TREE, pcur, &mtr); cursor = btr_pcur_get_btr_cur(pcur); diff --git a/storage/xtradb/buf/buf0buddy.cc b/storage/xtradb/buf/buf0buddy.cc index a06d56a8d72..68629844067 100644 --- a/storage/xtradb/buf/buf0buddy.cc +++ b/storage/xtradb/buf/buf0buddy.cc @@ -612,7 +612,7 @@ buf_buddy_relocate( if (buf_page_can_relocate(bpage)) { /* Relocate the compressed page. */ - ullint usec = ut_time_us(NULL); + const ulonglong ns = my_interval_timer(); ut_a(bpage->zip.data == src); @@ -630,11 +630,8 @@ buf_buddy_relocate( reinterpret_cast<buf_buddy_free_t*>(src), i); buf_buddy_stat_t* buddy_stat = &buf_pool->buddy_stat[i]; - ++buddy_stat->relocated; - - buddy_stat->relocated_usec += ut_time_us(NULL) - usec; - + buddy_stat->relocated_usec+= (my_interval_timer() - ns) / 1000; return(true); } diff --git a/storage/xtradb/buf/buf0buf.cc b/storage/xtradb/buf/buf0buf.cc index 9815e4ba56a..9255f741b0f 100644 --- a/storage/xtradb/buf/buf0buf.cc +++ b/storage/xtradb/buf/buf0buf.cc @@ -1701,7 +1701,7 @@ buf_pool_init_instance( buf_pool->zip_hash = hash_create(2 * buf_pool->curr_size); - buf_pool->last_printout_time = ut_time(); + buf_pool->last_printout_time = time(NULL); } /* 2. Initialize flushing fields -------------------------------- */ @@ -2488,10 +2488,6 @@ buf_page_get_zip( ibool discard_attempted = FALSE; ibool must_read; trx_t* trx = NULL; - ulint sec; - ulint ms; - ib_uint64_t start_time; - ib_uint64_t finish_time; buf_pool_t* buf_pool = buf_pool_get(space, offset); if (UNIV_UNLIKELY(innobase_get_slow_log())) { @@ -2610,14 +2606,10 @@ got_block: if (must_read) { /* Let us wait until the read operation completes */ - - if (UNIV_UNLIKELY(trx && trx->take_stats)) - { - ut_usectime(&sec, &ms); - start_time = (ib_uint64_t)sec * 1000000 + ms; - } else { - start_time = 0; - } + const ulonglong start_time = UNIV_UNLIKELY(trx + && trx->take_stats) + ? my_interval_timer() + : 0; for (;;) { enum buf_io_fix io_fix; @@ -2632,11 +2624,9 @@ got_block: break; } } - if (UNIV_UNLIKELY(start_time != 0)) - { - ut_usectime(&sec, &ms); - finish_time = (ib_uint64_t)sec * 1000000 + ms; - trx->io_reads_wait_timer += (ulint)(finish_time - start_time); + if (UNIV_UNLIKELY(start_time != 0)) { + trx->io_reads_wait_timer += ulint( + (my_interval_timer() - start_time) / 1000); } } @@ -3016,21 +3006,13 @@ buf_wait_for_read(buf_block_t* block, trx_t* trx) if (buf_block_get_io_fix_unlocked(block) == BUF_IO_READ) { - ib_uint64_t start_time; - ulint sec; - ulint ms; - /* Wait until the read operation completes */ ib_mutex_t* mutex = buf_page_get_mutex(&block->page); - - if (UNIV_UNLIKELY(trx && trx->take_stats)) - { - ut_usectime(&sec, &ms); - start_time = (ib_uint64_t)sec * 1000000 + ms; - } else { - start_time = 0; - } + const ulonglong start_time = UNIV_UNLIKELY(trx + && trx->take_stats) + ? my_interval_timer() + : 0; for (;;) { buf_io_fix io_fix; @@ -3050,15 +3032,10 @@ buf_wait_for_read(buf_block_t* block, trx_t* trx) } } - if (UNIV_UNLIKELY(start_time != 0)) - { - ut_usectime(&sec, &ms); - ib_uint64_t finish_time - = (ib_uint64_t)sec * 1000000 + ms; - trx->io_reads_wait_timer - += (ulint)(finish_time - start_time); + if (UNIV_UNLIKELY(start_time != 0)) { + trx->io_reads_wait_timer += ulint( + (my_interval_timer() - start_time) / 1000); } - } } @@ -6226,7 +6203,7 @@ buf_refresh_io_stats( /*=================*/ buf_pool_t* buf_pool) /*!< in: buffer pool instance */ { - buf_pool->last_printout_time = ut_time(); + buf_pool->last_printout_time = time(NULL); buf_pool->old_stat = buf_pool->stat; } diff --git a/storage/xtradb/dict/dict0mem.cc b/storage/xtradb/dict/dict0mem.cc index c009ef0ca11..f4bbc5c8f06 100644 --- a/storage/xtradb/dict/dict0mem.cc +++ b/storage/xtradb/dict/dict0mem.cc @@ -751,7 +751,7 @@ void dict_mem_init(void) { /* Initialize a randomly distributed temporary file number */ - ib_uint32_t now = static_cast<ib_uint32_t>(ut_time()); + ib_uint32_t now = static_cast<ib_uint32_t>(time(NULL)); const byte* buf = reinterpret_cast<const byte*>(&now); ut_ad(ut_crc32 != NULL); diff --git a/storage/xtradb/dict/dict0stats.cc b/storage/xtradb/dict/dict0stats.cc index 3cbd88c0f0a..59c661514f5 100644 --- a/storage/xtradb/dict/dict0stats.cc +++ b/storage/xtradb/dict/dict0stats.cc @@ -45,7 +45,7 @@ Created Jan 06, 2010 Vasil Dimov #include "trx0trx.h" /* trx_create() */ #include "trx0roll.h" /* trx_rollback_to_savepoint() */ #include "ut0rnd.h" /* ut_rnd_interval() */ -#include "ut0ut.h" /* ut_format_name(), ut_time() */ +#include "ut0ut.h" /* ut_format_name() */ #include <algorithm> #include <map> @@ -1000,7 +1000,7 @@ dict_stats_update_transient( table->stat_sum_of_other_index_sizes = sum_of_index_sizes - index->stat_index_size; - table->stats_last_recalc = ut_time(); + table->stats_last_recalc = time(NULL); table->stat_modified_counter = 0; @@ -2325,7 +2325,7 @@ dict_stats_update_persistent( += index->stat_index_size; } - table->stats_last_recalc = ut_time(); + table->stats_last_recalc = time(NULL); table->stat_modified_counter = 0; @@ -2535,7 +2535,7 @@ dict_stats_save( /* MySQL's timestamp is 4 byte, so we use pars_info_add_int4_literal() which takes a lint arg, so "now" is lint */ - now = (lint) ut_time(); + now = (lint) time(NULL); pinfo = pars_info_create(); @@ -3980,7 +3980,7 @@ dict_stats_save_defrag_summary( dict_index_t* index) /*!< in: index */ { dberr_t ret; - lint now = (lint) ut_time(); + lint now = (lint) time(NULL); if (dict_index_is_univ(index)) { return DB_SUCCESS; } @@ -4017,7 +4017,7 @@ dict_stats_save_defrag_stats( return DB_SUCCESS; } - lint now = (lint) ut_time(); + lint now = (lint) time(NULL); mtr_t mtr; ulint n_leaf_pages; ulint n_leaf_reserved; diff --git a/storage/xtradb/dict/dict0stats_bg.cc b/storage/xtradb/dict/dict0stats_bg.cc index dad768a7c3b..b4923364cac 100644 --- a/storage/xtradb/dict/dict0stats_bg.cc +++ b/storage/xtradb/dict/dict0stats_bg.cc @@ -437,14 +437,14 @@ dict_stats_process_entry_from_recalc_pool() mutex_exit(&dict_sys->mutex); - /* ut_time() could be expensive, the current function + /* time() could be expensive, the current function is called once every time a table has been changed more than 10% and on a system with lots of small tables, this could become hot. If we find out that this is a problem, then the check below could eventually be replaced with something else, though a time interval is the natural approach. */ - if (ut_difftime(ut_time(), table->stats_last_recalc) + if (difftime(time(NULL), table->stats_last_recalc) < MIN_RECALC_INTERVAL) { /* Stats were (re)calculated not long ago. To avoid diff --git a/storage/xtradb/eval/eval0eval.cc b/storage/xtradb/eval/eval0eval.cc index ccb995f9d4f..d62febd466d 100644 --- a/storage/xtradb/eval/eval0eval.cc +++ b/storage/xtradb/eval/eval0eval.cc @@ -1,6 +1,7 @@ /***************************************************************************** Copyright (c) 1997, 2011, Oracle and/or its affiliates. All Rights Reserved. +Copyright (c) 2019, MariaDB Corporation. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software @@ -858,7 +859,7 @@ eval_predefined( dfield_get_data(que_node_get_val(arg1))); } else if (func == PARS_SYSDATE_TOKEN) { - int_val = (lint) ut_time(); + int_val = (lint) time(NULL); } else { eval_predefined_2(func_node); diff --git a/storage/xtradb/fil/fil0crypt.cc b/storage/xtradb/fil/fil0crypt.cc index 421bc78776e..874c6b4dd2e 100644 --- a/storage/xtradb/fil/fil0crypt.cc +++ b/storage/xtradb/fil/fil0crypt.cc @@ -1,6 +1,6 @@ /***************************************************************************** Copyright (C) 2013, 2015, Google Inc. All Rights Reserved. -Copyright (c) 2014, 2018, MariaDB Corporation. All Rights Reserved. +Copyright (c) 2014, 2019, MariaDB Corporation. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software @@ -1698,19 +1698,18 @@ fil_crypt_get_page_throttle_func( state->crypt_stat.pages_read_from_disk++; - ullint start = ut_time_us(NULL); + const ulonglong start = my_interval_timer(); block = buf_page_get_gen(space->id, zip_size, offset, RW_X_LATCH, NULL, BUF_GET_POSSIBLY_FREED, file, line, mtr); - ullint end = ut_time_us(NULL); - - if (end < start) { - end = start; // safety... - } + const ulonglong end = my_interval_timer(); state->cnt_waited++; - state->sum_waited_us += (end - start); + + if (end > start) { + state->sum_waited_us += (end - start) / 1000; + } /* average page load */ ulint add_sleeptime_ms = 0; @@ -2032,7 +2031,7 @@ fil_crypt_flush_space( bool success = false; ulint n_pages = 0; ulint sum_pages = 0; - ullint start = ut_time_us(NULL); + const ulonglong start = my_interval_timer(); do { success = buf_flush_list(ULINT_MAX, end_lsn, &n_pages); @@ -2040,11 +2039,11 @@ fil_crypt_flush_space( sum_pages += n_pages; } while (!success && !space->is_stopping()); - ullint end = ut_time_us(NULL); + const ulonglong end = my_interval_timer(); if (sum_pages && end > start) { state->cnt_waited += sum_pages; - state->sum_waited_us += (end - start); + state->sum_waited_us += (end - start) / 1000; /* statistics */ state->crypt_stat.pages_flushed += sum_pages; diff --git a/storage/xtradb/fil/fil0fil.cc b/storage/xtradb/fil/fil0fil.cc index d0d5e5abfcb..4a982df3fda 100644 --- a/storage/xtradb/fil/fil0fil.cc +++ b/storage/xtradb/fil/fil0fil.cc @@ -5128,7 +5128,7 @@ fil_load_single_table_tablespaces(ibool (*pred)(const char*, const char*)) ulint dbpath_len = 100; ulint files_read = 0; ulint files_read_at_last_check = 0; - ib_time_t prev_report_time = ut_time(); + time_t prev_report_time = time(NULL); os_file_dir_t dir; os_file_dir_t dbdir; os_file_stat_t dbinfo; @@ -5228,11 +5228,10 @@ fil_load_single_table_tablespaces(ibool (*pred)(const char*, const char*)) files_read++; if (files_read - files_read_at_last_check > CHECK_TIME_EVERY_N_FILES) { - ib_time_t cur_time= ut_time(); + time_t cur_time= time(NULL); files_read_at_last_check= files_read; - double time_elapsed= ut_difftime(cur_time, - prev_report_time); - if (time_elapsed > 15) { + if (cur_time - prev_report_time + > 15) { ib_logf(IB_LOG_LEVEL_INFO, "Processed %ld .ibd/.isl files", files_read); diff --git a/storage/xtradb/fts/fts0fts.cc b/storage/xtradb/fts/fts0fts.cc index beed1b99d6c..264c520bb1e 100644 --- a/storage/xtradb/fts/fts0fts.cc +++ b/storage/xtradb/fts/fts0fts.cc @@ -77,8 +77,8 @@ UNIV_INTERN ulong fts_min_token_size; // FIXME: testing -ib_time_t elapsed_time = 0; -ulint n_nodes = 0; +static time_t elapsed_time; +static ulint n_nodes; /** Error condition reported by fts_utf8_decode() */ const ulint UTF8_ERROR = 0xFFFFFFFF; @@ -3798,7 +3798,7 @@ fts_write_node( pars_info_t* info; dberr_t error; ib_uint32_t doc_count; - ib_time_t start_time; + time_t start_time; doc_id_t last_doc_id; doc_id_t first_doc_id; char table_name[MAX_FULL_NAME_LEN]; @@ -3845,9 +3845,9 @@ fts_write_node( " :last_doc_id, :doc_count, :ilist);"); } - start_time = ut_time(); + start_time = time(NULL); error = fts_eval_sql(trx, *graph); - elapsed_time += ut_time() - start_time; + elapsed_time += time(NULL) - start_time; ++n_nodes; return(error); @@ -4298,7 +4298,7 @@ fts_sync_begin( n_nodes = 0; elapsed_time = 0; - sync->start_time = ut_time(); + sync->start_time = time(NULL); sync->trx = trx_allocate_for_background(); @@ -4457,7 +4457,7 @@ fts_sync_commit( "SYNC for table %s: SYNC time : %lu secs: " "elapsed %lf ins/sec", sync->table->name, - (ulong) (ut_time() - sync->start_time), + (ulong) (time(NULL) - sync->start_time), (double) n_nodes/ (double) elapsed_time); } diff --git a/storage/xtradb/fts/fts0opt.cc b/storage/xtradb/fts/fts0opt.cc index 881b106f570..2f8739d3d2c 100644 --- a/storage/xtradb/fts/fts0opt.cc +++ b/storage/xtradb/fts/fts0opt.cc @@ -59,7 +59,7 @@ static bool fts_opt_start_shutdown = false; static const ulint FTS_WORD_NODES_INIT_SIZE = 64; /** Last time we did check whether system need a sync */ -static ib_time_t last_check_sync_time; +static time_t last_check_sync_time; /** FTS optimize thread message types. */ enum fts_msg_type_t { @@ -181,12 +181,11 @@ struct fts_slot_t { ulint deleted; /*!< Number of doc ids deleted since the last time this table was optimized */ - ib_time_t last_run; /*!< Time last run completed */ + /** time(NULL) of completing fts_optimize_table_bk() */ + time_t last_run; - ib_time_t completed; /*!< Optimize finish time */ - - ib_time_t interval_time; /*!< Minimum time to wait before - optimizing the table again. */ + /** time(NULL) of latest successful fts_optimize_table() */ + time_t completed; }; /** A table remove message for the FTS optimize thread. */ @@ -223,8 +222,8 @@ UNIV_INTERN char fts_enable_diag_print; /** ZLib compressed block size.*/ static ulint FTS_ZIP_BLOCK_SIZE = 1024; -/** The amount of time optimizing in a single pass, in milliseconds. */ -static ib_time_t fts_optimize_time_limit = 0; +/** The amount of time optimizing in a single pass, in seconds. */ +static ulint fts_optimize_time_limit; /** It's defined in fts0fts.cc */ extern const char* fts_common_tables[]; @@ -1553,7 +1552,7 @@ fts_optimize_compact( /*=================*/ fts_optimize_t* optim, /*!< in: optimize state data */ dict_index_t* index, /*!< in: current FTS being optimized */ - ib_time_t start_time) /*!< in: optimize start time */ + time_t start_time) /*!< in: optimize start time */ { ulint i; dberr_t error = DB_SUCCESS; @@ -1586,8 +1585,11 @@ fts_optimize_compact( /* Free the word that was optimized. */ fts_word_free(word); + ulint interval = ulint(time(NULL) - start_time); + if (fts_optimize_time_limit > 0 - && (ut_time() - start_time) > fts_optimize_time_limit) { + && (lint(interval) < 0 + || interval > fts_optimize_time_limit)) { optim->done = TRUE; } @@ -1646,7 +1648,7 @@ fts_optimize_get_index_start_time( /*==============================*/ trx_t* trx, /*!< in: transaction */ dict_index_t* index, /*!< in: FTS index */ - ib_time_t* start_time) /*!< out: time in secs */ + time_t* start_time) /*!< out: time in secs */ { return(fts_config_get_index_ulint( trx, index, FTS_OPTIMIZE_START_TIME, @@ -1662,7 +1664,7 @@ fts_optimize_set_index_start_time( /*==============================*/ trx_t* trx, /*!< in: transaction */ dict_index_t* index, /*!< in: FTS index */ - ib_time_t start_time) /*!< in: start time */ + time_t start_time) /*!< in: start time */ { return(fts_config_set_index_ulint( trx, index, FTS_OPTIMIZE_START_TIME, @@ -1678,7 +1680,7 @@ fts_optimize_get_index_end_time( /*============================*/ trx_t* trx, /*!< in: transaction */ dict_index_t* index, /*!< in: FTS index */ - ib_time_t* end_time) /*!< out: time in secs */ + time_t* end_time) /*!< out: time in secs */ { return(fts_config_get_index_ulint( trx, index, FTS_OPTIMIZE_END_TIME, (ulint*) end_time)); @@ -1693,7 +1695,7 @@ fts_optimize_set_index_end_time( /*============================*/ trx_t* trx, /*!< in: transaction */ dict_index_t* index, /*!< in: FTS index */ - ib_time_t end_time) /*!< in: end time */ + time_t end_time) /*!< in: end time */ { return(fts_config_set_index_ulint( trx, index, FTS_OPTIMIZE_END_TIME, (ulint) end_time)); @@ -1755,22 +1757,23 @@ fts_optimize_free( Get the max time optimize should run in millisecs. @return max optimize time limit in millisecs. */ static -ib_time_t +ulint fts_optimize_get_time_limit( /*========================*/ trx_t* trx, /*!< in: transaction */ fts_table_t* fts_table) /*!< in: aux table */ { - ib_time_t time_limit = 0; + ulint time_limit = 0; fts_config_get_ulint( trx, fts_table, - FTS_OPTIMIZE_LIMIT_IN_SECS, (ulint*) &time_limit); + FTS_OPTIMIZE_LIMIT_IN_SECS, &time_limit); + /* FIXME: This is returning milliseconds, while the variable + is being stored and interpreted as seconds! */ return(time_limit * 1000); } - /**********************************************************************//** Run OPTIMIZE on the given table. Note: this can take a very long time (hours). */ @@ -1783,7 +1786,6 @@ fts_optimize_words( fts_string_t* word) /*!< in: the starting word to optimize */ { fts_fetch_t fetch; - ib_time_t start_time; que_t* graph = NULL; CHARSET_INFO* charset = optim->fts_index_table.charset; @@ -1793,7 +1795,7 @@ fts_optimize_words( fts_optimize_time_limit = fts_optimize_get_time_limit( optim->trx, &optim->fts_common_table); - start_time = ut_time(); + const time_t start_time = time(NULL); /* Setup the callback to use for fetching the word ilist etc. */ fetch.read_arg = optim->words; @@ -1916,7 +1918,7 @@ fts_optimize_index_completed( dberr_t error; byte buf[sizeof(ulint)]; #ifdef FTS_OPTIMIZE_DEBUG - ib_time_t end_time = ut_time(); + time_t end_time = time(NULL); error = fts_optimize_set_index_end_time(optim->trx, index, end_time); #endif @@ -2314,8 +2316,8 @@ fts_optimize_indexes( dict_index_t* index; #ifdef FTS_OPTIMIZE_DEBUG - ib_time_t end_time; - ib_time_t start_time; + time_t end_time; + time_t start_time; /* Get the start and end optimize times for this index. */ error = fts_optimize_get_index_start_time( @@ -2335,14 +2337,14 @@ fts_optimize_indexes( /* Start time will be 0 only for the first time or after completing the optimization of all FTS indexes. */ if (start_time == 0) { - start_time = ut_time(); + start_time = time(NULL); error = fts_optimize_set_index_start_time( optim->trx, index, start_time); } /* Check if this index needs to be optimized or not. */ - if (ut_difftime(end_time, start_time) < 0) { + if (difftime(end_time, start_time) < 0) { error = fts_optimize_index(optim, index); if (error != DB_SUCCESS) { @@ -2414,7 +2416,7 @@ fts_optimize_reset_start_time( for (uint i = 0; i < ib_vector_size(fts->indexes); ++i) { dict_index_t* index; - ib_time_t start_time = 0; + time_t start_time = 0; /* Reset the start time to 0 for this index. */ error = fts_optimize_set_index_start_time( @@ -2443,11 +2445,13 @@ fts_optimize_table_bk( /*==================*/ fts_slot_t* slot) /*!< in: table to optimiza */ { - dberr_t error; + const time_t now = time(NULL); + const ulint interval = ulint(now - slot->last_run); /* Avoid optimizing tables that were optimized recently. */ if (slot->last_run > 0 - && (ut_time() - slot->last_run) < slot->interval_time) { + && lint(interval) >= 0 + && interval < FTS_OPTIMIZE_INTERVAL_IN_SECS) { return(DB_SUCCESS); } @@ -2455,12 +2459,19 @@ fts_optimize_table_bk( dict_table_t* table = dict_table_open_on_id( slot->table_id, FALSE, DICT_TABLE_OP_NORMAL); - if (table && fil_table_accessible(table) + if (!table) { + slot->last_run = now; + return DB_SUCCESS; + } + + dberr_t error; + + if (fil_table_accessible(table) && table->fts && table->fts->cache && table->fts->cache->deleted >= FTS_OPTIMIZE_THRESHOLD) { error = fts_optimize_table(table); - slot->last_run = ut_time(); + slot->last_run = time(NULL); if (error == DB_SUCCESS) { slot->running = false; @@ -2468,7 +2479,7 @@ fts_optimize_table_bk( } } else { /* Note time this run completed. */ - slot->last_run = ut_time(); + slot->last_run = now; error = DB_SUCCESS; } @@ -2720,7 +2731,6 @@ static bool fts_optimize_new_table(dict_table_t* table) slot->table_id = table->id; slot->running = false; - slot->interval_time = FTS_OPTIMIZE_INTERVAL_IN_SECS; return(TRUE); } @@ -2757,37 +2767,23 @@ Calculate how many tables in fts_slots need to be optimized. @return no. of tables to optimize */ static ulint fts_optimize_how_many() { - ulint i; - ib_time_t delta; - ulint n_tables = 0; - ib_time_t current_time; - - current_time = ut_time(); + ulint n_tables = 0; + const time_t current_time = time(NULL); - for (i = 0; i < ib_vector_size(fts_slots); ++i) { + for (ulint i = 0; i < ib_vector_size(fts_slots); ++i) { const fts_slot_t* slot = static_cast<const fts_slot_t*>( ib_vector_get_const(fts_slots, i)); if (slot->table_id == 0) { continue; } - if (!slot->running) { - ut_a(slot->completed <= current_time); - - delta = current_time - slot->completed; + const time_t end = slot->running + ? slot->last_run : slot->completed; + ulint interval = ulint(current_time - end); - /* Skip slots that have been optimized recently. */ - if (delta >= slot->interval_time) { - ++n_tables; - } - } else { - ut_a(slot->last_run <= current_time); - - delta = current_time - slot->last_run; - - if (delta > slot->interval_time) { - ++n_tables; - } + if (lint(interval) < 0 + || interval >= FTS_OPTIMIZE_INTERVAL_IN_SECS) { + ++n_tables; } } @@ -2800,13 +2796,14 @@ Check if the total memory used by all FTS table exceeds the maximum limit. static bool fts_is_sync_needed() { ulint total_memory = 0; - double time_diff = difftime(ut_time(), last_check_sync_time); + const time_t now = time(NULL); + double time_diff = difftime(now, last_check_sync_time); - if (fts_need_sync || time_diff < 5) { + if (fts_need_sync || (time_diff >= 0 && time_diff < 5)) { return(false); } - last_check_sync_time = ut_time(); + last_check_sync_time = now; for (ulint i = 0; i < ib_vector_size(fts_slots); ++i) { const fts_slot_t* slot = static_cast<const fts_slot_t*>( @@ -3004,7 +3001,7 @@ fts_optimize_init(void) fts_optimize_wq = ib_wqueue_create(); ut_a(fts_optimize_wq != NULL); - last_check_sync_time = ut_time(); + last_check_sync_time = time(NULL); os_thread_create(fts_optimize_thread, fts_optimize_wq, NULL); } diff --git a/storage/xtradb/handler/ha_innodb.cc b/storage/xtradb/handler/ha_innodb.cc index 7990d8bd1ef..9b324277acb 100644 --- a/storage/xtradb/handler/ha_innodb.cc +++ b/storage/xtradb/handler/ha_innodb.cc @@ -92,7 +92,6 @@ this program; if not, write to the Free Software Foundation, Inc., #include "dict0stats_bg.h" #include "ha_prototypes.h" #include "ut0mem.h" -#include "ut0timer.h" #include "ibuf0ibuf.h" #include "dict0dict.h" #include "srv0mon.h" @@ -1953,13 +1952,14 @@ innobase_srv_conc_enter_innodb( } else if (trx->mysql_thd != NULL && thd_is_replication_slave_thread(trx->mysql_thd)) { - - UT_WAIT_FOR( - srv_conc_get_active_threads() - < srv_thread_concurrency, - srv_replication_delay * 1000); - - } else { + const ulonglong end = my_interval_timer() + + ulonglong(srv_replication_delay) * 1000000; + while (srv_conc_get_active_threads() + >= srv_thread_concurrency + || my_interval_timer() >= end) { + os_thread_sleep(2000 /* 2 ms */); + } + } else { srv_conc_enter_innodb(trx); } } @@ -4545,14 +4545,6 @@ innobase_change_buffering_inited_ok: /* Turn on monitor counters that are default on */ srv_mon_default_on(); -#ifndef UNIV_HOTBACKUP -#ifdef _WIN32 - if (ut_win_init_time()) { - goto mem_free_and_error; - } -#endif /* _WIN32 */ -#endif /* !UNIV_HOTBACKUP */ - DBUG_RETURN(FALSE); error: DBUG_RETURN(TRUE); @@ -18707,8 +18699,7 @@ innodb_defragment_frequency_update( from check function */ { srv_defragment_frequency = (*static_cast<const uint*>(save)); - srv_defragment_interval = ut_microseconds_to_timer( - 1000000.0 / srv_defragment_frequency); + srv_defragment_interval = 1000000000ULL / srv_defragment_frequency; } /****************************************************************//** diff --git a/storage/xtradb/include/dict0mem.h b/storage/xtradb/include/dict0mem.h index f32400320e1..1dcc3ebdd0c 100644 --- a/storage/xtradb/include/dict0mem.h +++ b/storage/xtradb/include/dict0mem.h @@ -2,7 +2,7 @@ Copyright (c) 1996, 2017, Oracle and/or its affiliates. All Rights Reserved. Copyright (c) 2012, Facebook Inc. -Copyright (c) 2013, 2018, MariaDB Corporation. +Copyright (c) 2013, 2019, MariaDB Corporation. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software @@ -1198,7 +1198,7 @@ struct dict_table_t{ goes to zero. If it's -1, means there's DDL on the table, DML from memcached will be blocked. */ - ib_time_t stats_last_recalc; + time_t stats_last_recalc; /*!< Timestamp of last recalc of the stats */ ib_uint32_t stat_persistent; /*!< The two bits below are set in the diff --git a/storage/xtradb/include/fts0types.h b/storage/xtradb/include/fts0types.h index 0da9fe47955..3cb01a92df0 100644 --- a/storage/xtradb/include/fts0types.h +++ b/storage/xtradb/include/fts0types.h @@ -1,6 +1,7 @@ /***************************************************************************** Copyright (c) 2007, 2016, Oracle and/or its affiliates. All Rights Reserved. +Copyright (c) 2019, MariaDB Corporation. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software @@ -122,7 +123,8 @@ struct fts_sync_t { doc_id_t max_doc_id; /*!< The doc id at which the cache was noted as being full, we use this to set the upper_limit field */ - ib_time_t start_time; /*!< SYNC start time */ + time_t start_time; /*!< SYNC start time; only used if + fts_enable_diag_print */ bool in_progress; /*!< flag whether sync is in progress.*/ bool unlock_cache; /*!< flag whether unlock cache when write fts node */ diff --git a/storage/xtradb/include/lock0lock.h b/storage/xtradb/include/lock0lock.h index c57c25ae827..878a42ea81b 100644 --- a/storage/xtradb/include/lock0lock.h +++ b/storage/xtradb/include/lock0lock.h @@ -629,22 +629,6 @@ lock_report_trx_id_insanity( trx_id_t max_trx_id) /*!< in: trx_sys_get_max_trx_id() */ MY_ATTRIBUTE((nonnull)); /*********************************************************************//** -Prints info of a table lock. */ -UNIV_INTERN -void -lock_table_print( -/*=============*/ - FILE* file, /*!< in: file where to print */ - const lock_t* lock); /*!< in: table type lock */ -/*********************************************************************//** -Prints info of a record lock. */ -UNIV_INTERN -void -lock_rec_print( -/*===========*/ - FILE* file, /*!< in: file where to print */ - const lock_t* lock); /*!< in: record type lock */ -/*********************************************************************//** Prints info of locks for all transactions. @return FALSE if not able to obtain lock mutex and exits without printing info */ diff --git a/storage/xtradb/include/lock0priv.h b/storage/xtradb/include/lock0priv.h index 0107d7cd2ba..3b2c7f08020 100644 --- a/storage/xtradb/include/lock0priv.h +++ b/storage/xtradb/include/lock0priv.h @@ -74,10 +74,14 @@ struct lock_t { lock */ dict_index_t* index; /*!< index for a record lock */ - /* Statistics for how long lock has been held and time - how long this lock had to be waited before it was granted */ - time_t requested_time; /*!< Lock request time */ - ulint wait_time; /*!< Time waited this lock or 0 */ + /** time(NULL) of the lock request creation. + Used for computing wait_time and diagnostics only. + Note: bogus durations may be reported + when the system time is adjusted! */ + time_t requested_time; + /** Cumulated wait time in seconds. + Note: may be bogus when the system time is adjusted! */ + ulint wait_time; union { lock_table_t tab_lock;/*!< table lock */ diff --git a/storage/xtradb/include/log0recv.h b/storage/xtradb/include/log0recv.h index bc28bf94ae3..afdc5ccd98e 100644 --- a/storage/xtradb/include/log0recv.h +++ b/storage/xtradb/include/log0recv.h @@ -431,7 +431,7 @@ struct recv_sys_t{ log record, or there is a log parsing buffer overflow */ /** the time when progress was last reported */ - ib_time_t progress_time; + time_t progress_time; #ifdef UNIV_LOG_ARCHIVE log_group_t* archive_group; /*!< in archive recovery: the log group whose @@ -449,7 +449,7 @@ struct recv_sys_t{ @param[in] time the current time @return whether progress should be reported (the last report was at least 15 seconds ago) */ - bool report(ib_time_t time) + bool report(time_t time) { if (time - progress_time < 15) { return false; diff --git a/storage/xtradb/include/srv0mon.h b/storage/xtradb/include/srv0mon.h index 8d5bfad6f50..90930656791 100644 --- a/storage/xtradb/include/srv0mon.h +++ b/storage/xtradb/include/srv0mon.h @@ -2,7 +2,7 @@ Copyright (c) 2010, 2013, Oracle and/or its affiliates. All Rights Reserved. Copyright (c) 2012, Facebook Inc. -Copyright (c) 2013, 2017, MariaDB Corporation. +Copyright (c) 2013, 2019, MariaDB Corporation. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the @@ -58,9 +58,9 @@ create the internal counter ID in "monitor_id_t". */ /** Structure containing the actual values of a monitor counter. */ struct monitor_value_t { - ib_time_t mon_start_time; /*!< Start time of monitoring */ - ib_time_t mon_stop_time; /*!< Stop time of monitoring */ - ib_time_t mon_reset_time; /*!< Time counter resetted */ + time_t mon_start_time; /*!< Start time of monitoring */ + time_t mon_stop_time; /*!< Stop time of monitoring */ + time_t mon_reset_time; /*!< Time of resetting the counter */ mon_type_t mon_value; /*!< Current counter Value */ mon_type_t mon_max_value; /*!< Current Max value */ mon_type_t mon_min_value; /*!< Current Min value */ @@ -761,7 +761,7 @@ monitor counter MONITOR_CHECK_DEFINED(value); \ if (MONITOR_IS_ON(monitor)) { \ ullint old_time = (value); \ - value = ut_time_us(NULL); \ + value = microsecond_interval_timer(); \ MONITOR_VALUE(monitor) += (mon_type_t) (value - old_time);\ } diff --git a/storage/xtradb/include/srv0srv.h b/storage/xtradb/include/srv0srv.h index c8e55dc0da1..8461811db31 100644 --- a/storage/xtradb/include/srv0srv.h +++ b/storage/xtradb/include/srv0srv.h @@ -3,7 +3,7 @@ Copyright (c) 1995, 2017, Oracle and/or its affiliates. All rights reserved. Copyright (c) 2008, 2009, Google Inc. Copyright (c) 2009, Percona Inc. -Copyright (c) 2013, 2017, MariaDB Corporation. +Copyright (c) 2013, 2019, MariaDB Corporation. Portions of this file contain modifications contributed and copyrighted by Google, Inc. Those modifications are gratefully acknowledged and are described @@ -1326,10 +1326,14 @@ struct srv_slot_t{ ibool suspended; /*!< TRUE if the thread is waiting for the event of this slot */ - ib_time_t suspend_time; /*!< time when the thread was - suspended. Initialized by - lock_wait_table_reserve_slot() - for lock wait */ + /** time(NULL) when the thread was suspended. + FIXME: Use my_interval_timer() or similar, to avoid bogus + timeouts in lock_wait_check_and_cancel() or lock_wait_suspend_thread() + when the system time is adjusted to the past! + + FIXME: This is duplicating trx_lock_t::wait_started, + which is being used for diagnostic purposes only. */ + time_t suspend_time; ulong wait_timeout; /*!< wait time that if exceeded the thread will be timed out. Initialized by diff --git a/storage/xtradb/include/trx0i_s.h b/storage/xtradb/include/trx0i_s.h index c71def52b61..186b7069c09 100644 --- a/storage/xtradb/include/trx0i_s.h +++ b/storage/xtradb/include/trx0i_s.h @@ -1,6 +1,7 @@ /***************************************************************************** Copyright (c) 2007, 2011, Oracle and/or its affiliates. All Rights Reserved. +Copyright (c) 2019, MariaDB Corporation. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software @@ -128,12 +129,12 @@ struct i_s_trx_row_t { trx_id_t trx_id; /*!< transaction identifier */ const char* trx_state; /*!< transaction state from trx_get_que_state_str() */ - ib_time_t trx_started; /*!< trx_t::start_time */ + time_t trx_started; /*!< trx_t::start_time */ const i_s_locks_row_t* requested_lock_row; /*!< pointer to a row in innodb_locks if trx is waiting, or NULL */ - ib_time_t trx_wait_started; /*!< trx_t::wait_started */ + time_t trx_wait_started; /*!< trx->lock.wait_started */ ullint trx_weight; /*!< TRX_WEIGHT() */ ulint trx_mysql_thread_id; /*!< thd_get_thread_id() */ const char* trx_query; /*!< MySQL statement being diff --git a/storage/xtradb/include/trx0trx.h b/storage/xtradb/include/trx0trx.h index e6524fae48b..e833bd0341f 100644 --- a/storage/xtradb/include/trx0trx.h +++ b/storage/xtradb/include/trx0trx.h @@ -914,10 +914,11 @@ struct trx_t{ when trx->in_rw_trx_list. Initially set to TRX_ID_MAX. */ - time_t start_time; /*!< time the trx state last time became - TRX_STATE_ACTIVE */ - ib_uint64_t start_time_micro; /*!< start time of transaction in - microseconds */ + /** wall-clock time of the latest transition to TRX_STATE_ACTIVE; + used for diagnostic purposes only */ + time_t start_time; + /** microsecond_interval_timer() of transaction start */ + ulonglong start_time_micro; trx_id_t id; /*!< transaction id */ XID xid; /*!< X/Open XA transaction identification to identify a @@ -1099,7 +1100,7 @@ struct trx_t{ ulint io_reads; ib_uint64_t io_read; ulint io_reads_wait_timer; - ib_uint64_t lock_que_wait_ustarted; + ulonglong lock_que_wait_nstarted; ulint lock_que_wait_timer; ulint innodb_que_wait_timer; ulint distinct_page_access; diff --git a/storage/xtradb/include/ut0timer.h b/storage/xtradb/include/ut0timer.h deleted file mode 100644 index 405648fe3a2..00000000000 --- a/storage/xtradb/include/ut0timer.h +++ /dev/null @@ -1,69 +0,0 @@ -/***************************************************************************** - -Copyright (c) 2013, 2014, Facebook, Inc. All Rights Reserved. -Copyright (c) 2014, 2018, MariaDB Corporation. - -This program is free software; you can redistribute it and/or modify it under -the terms of the GNU General Public License as published by the Free Software -Foundation; version 2 of the License. - -This program is distributed in the hope that it will be useful, but WITHOUT -ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS -FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. - -You should have received a copy of the GNU General Public License along with -this program; if not, write to the Free Software Foundation, Inc., -51 Franklin Street, Fifth Floor, Boston, MA 02110-1335 USA - -*****************************************************************************/ - -/********************************************************************//** -@file include/ut0timer.h -Timer routines - -Created 30/07/2014 Jan Lindström jan.lindstrom@skysql.com -modified from https://github.com/facebook/mysql-5.6/commit/c75a413edeb96eb99bf11d7269bdfea06f96d6b6 -*************************************************************************/ -#ifndef ut0timer_h -#define ut0timer_h - -#include "univ.i" - -/* Current timer stats */ -extern struct my_timer_unit_info ut_timer; - -/**************************************************************//** -Function pointer to point selected timer function. -@return timer current value */ -extern ulonglong (*ut_timer_now)(void); - -/**************************************************************//** -Sets up the data required for use of my_timer_* functions. -Selects the best timer by high frequency, and tight resolution. -Points my_timer_now() to the selected timer function. -Initializes my_timer struct to contain the info for selected timer.*/ -UNIV_INTERN -void ut_init_timer(void); - -/**************************************************************//** -Convert native timer units in a ulonglong into microseconds in a double -@return time in microseconds */ -UNIV_INLINE -double -ut_timer_to_microseconds( -/*=====================*/ - ulonglong when); /*!< in: time where to calculate */ -/**************************************************************//** -Convert microseconds in a double to native timer units in a ulonglong -@return time in microseconds */ -UNIV_INLINE -ulonglong -ut_microseconds_to_timer( -/*=====================*/ - ulonglong when); /*!< in: time where to calculate */ - -#ifndef UNIV_NONINL -#include "ut0timer.ic" -#endif - -#endif diff --git a/storage/xtradb/include/ut0timer.ic b/storage/xtradb/include/ut0timer.ic deleted file mode 100644 index cfd39675b7c..00000000000 --- a/storage/xtradb/include/ut0timer.ic +++ /dev/null @@ -1,56 +0,0 @@ -/***************************************************************************** - -Copyright (c) 2013, 2014, Facebook, Inc. All Rights Reserved. -Copyright (c) 2014, 2018, MariaDB Corporation. - -This program is free software; you can redistribute it and/or modify it under -the terms of the GNU General Public License as published by the Free Software -Foundation; version 2 of the License. - -This program is distributed in the hope that it will be useful, but WITHOUT -ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS -FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. - -You should have received a copy of the GNU General Public License along with -this program; if not, write to the Free Software Foundation, Inc., -51 Franklin Street, Fifth Floor, Boston, MA 02110-1335 USA - -*****************************************************************************/ - -/********************************************************************//** -@file include/ut0timer.ic -Timer routines - -Created 30/07/2014 Jan Lindström jan.lindstrom@skysql.com -modified from https://github.com/facebook/mysql-5.6/commit/c75a413edeb96eb99bf11d7269bdfea06f96d6b6 -*************************************************************************/ - -/**************************************************************//** -Convert native timer units in a ulonglong into microseconds in a double -@return time in microseconds */ -UNIV_INLINE -double -ut_timer_to_microseconds( -/*=====================*/ - ulonglong when) /*!< in: time where to calculate */ -{ - double ret = (double)(when); - ret *= 1000000.0; - ret /= (double)(ut_timer.frequency); - return ret; -} - -/**************************************************************//** -Convert microseconds in a double to native timer units in a ulonglong -@return time in microseconds */ -UNIV_INLINE -ulonglong -ut_microseconds_to_timer( -/*=====================*/ - ulonglong when) /*!< in: time where to calculate */ -{ - double ret = (double)when; - ret *= (double)(ut_timer.frequency); - ret /= 1000000.0; - return (ulonglong)ret; -} diff --git a/storage/xtradb/include/ut0ut.h b/storage/xtradb/include/ut0ut.h index 13fb09108de..de8be1774c3 100644 --- a/storage/xtradb/include/ut0ut.h +++ b/storage/xtradb/include/ut0ut.h @@ -1,6 +1,7 @@ /***************************************************************************** Copyright (c) 1994, 2017, Oracle and/or its affiliates. All Rights Reserved. +Copyright (c) 2019, MariaDB Corporation. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software @@ -50,9 +51,6 @@ Created 1/20/1994 Heikki Tuuri /** Index name prefix in fast index creation, as a string constant */ #define TEMP_INDEX_PREFIX_STR "\377" -/** Time stamp */ -typedef time_t ib_time_t; - /* In order to call a piece of code, when a function returns or when the scope ends, use this utility class. It will invoke the given function object in its destructor. */ @@ -108,22 +106,6 @@ private: # define UT_LOW_PRIORITY_CPU() ((void)0) # define UT_RESUME_PRIORITY_CPU() ((void)0) # endif - -/*********************************************************************//** -Delays execution for at most max_wait_us microseconds or returns earlier -if cond becomes true. -@param cond in: condition to wait for; evaluated every 2 ms -@param max_wait_us in: maximum delay to wait, in microseconds */ -#define UT_WAIT_FOR(cond, max_wait_us) \ -do { \ - ullint start_us; \ - start_us = ut_time_us(NULL); \ - while (!(cond) \ - && ut_time_us(NULL) - start_us < (max_wait_us)) {\ - \ - os_thread_sleep(2000 /* 2 ms */); \ - } \ -} while (0) #endif /* !UNIV_HOTBACKUP */ template <class T> T ut_min(T a, T b) { return(a < b ? a : b); } @@ -242,39 +224,8 @@ store the given number of bits. @return number of bytes (octets) needed to represent b */ #define UT_BITS_IN_BYTES(b) (((b) + 7) / 8) -/**********************************************************//** -Returns system time. We do not specify the format of the time returned: -the only way to manipulate it is to use the function ut_difftime. -@return system time */ -UNIV_INTERN -ib_time_t -ut_time(void); -/*=========*/ #ifndef UNIV_HOTBACKUP /**********************************************************//** -Returns system time. -Upon successful completion, the value 0 is returned; otherwise the -value -1 is returned and the global variable errno is set to indicate the -error. -@return 0 on success, -1 otherwise */ -UNIV_INTERN -int -ut_usectime( -/*========*/ - ulint* sec, /*!< out: seconds since the Epoch */ - ulint* ms); /*!< out: microseconds since the Epoch+*sec */ - -/**********************************************************//** -Returns the number of microseconds since epoch. Similar to -time(3), the return value is also stored in *tloc, provided -that tloc is non-NULL. -@return us since epoch */ -UNIV_INTERN -ullint -ut_time_us( -/*=======*/ - ullint* tloc); /*!< out: us since epoch, if non-NULL */ -/**********************************************************//** Returns the number of milliseconds since some epoch. The value may wrap around. It should only be used for heuristic purposes. @@ -283,15 +234,6 @@ UNIV_INTERN ulint ut_time_ms(void); /*============*/ -#ifdef _WIN32 -/**********************************************************//** -Initialise highest available time resolution API on Windows -@return 0 if all OK else -1 */ -int -ut_win_init_time(); - -#endif /* _WIN32 */ - #endif /* !UNIV_HOTBACKUP */ /**********************************************************//** @@ -303,17 +245,6 @@ UNIV_INTERN ulint ut_time_ms(void); /*============*/ - -/**********************************************************//** -Returns the difference of two times in seconds. -@return time2 - time1 expressed in seconds */ -UNIV_INTERN -double -ut_difftime( -/*========*/ - ib_time_t time2, /*!< in: time */ - ib_time_t time1); /*!< in: time */ - #endif /* !UNIV_INNOCHECKSUM */ /**********************************************************//** @@ -343,15 +274,6 @@ void ut_sprintf_timestamp_without_extra_chars( /*=====================================*/ char* buf); /*!< in: buffer where to sprintf */ -/**********************************************************//** -Returns current year, month, day. */ -UNIV_INTERN -void -ut_get_year_month_day( -/*==================*/ - ulint* year, /*!< out: current year */ - ulint* month, /*!< out: month */ - ulint* day); /*!< out: day */ #else /* UNIV_HOTBACKUP */ /*************************************************************//** Runs an idle loop on CPU. The argument gives the desired delay diff --git a/storage/xtradb/include/ut0wqueue.h b/storage/xtradb/include/ut0wqueue.h index 53e75925ff9..74985618fa3 100644 --- a/storage/xtradb/include/ut0wqueue.h +++ b/storage/xtradb/include/ut0wqueue.h @@ -94,7 +94,7 @@ ib_wqueue_timedwait( /*================*/ /* out: work item or NULL on timeout*/ ib_wqueue_t* wq, /* in: work queue */ - ib_time_t wait_in_usecs); /* in: wait time in micro seconds */ + ulint wait_in_usecs); /* in: wait time in micro seconds */ /******************************************************************** Return first item on work queue or NULL if queue is empty diff --git a/storage/xtradb/lock/lock0lock.cc b/storage/xtradb/lock/lock0lock.cc index 41fda2df0d8..c110c83cbe7 100644 --- a/storage/xtradb/lock/lock0lock.cc +++ b/storage/xtradb/lock/lock0lock.cc @@ -383,6 +383,20 @@ struct lock_stack_t { ulint heap_no; /*!< heap number if rec lock */ }; +/** Pretty-print a table lock. +@param[in,out] file output stream +@param[in] lock table lock +@param[in] now current time */ +static void lock_table_print(FILE* file, const lock_t* lock, time_t now); + +/** Pretty-print a record lock. +@param[in,out] file output stream +@param[in] lock record lock +@param[in] now current time +@param[in,out] mtr mini-transaction */ +static void lock_rec_print(FILE* file, const lock_t* lock, time_t now, + mtr_t* mtr = NULL); + /*********************************************************************//** Checks if a waiting record lock request still has to wait in a queue. @return lock that is causing the wait */ @@ -466,20 +480,18 @@ UNIV_INTERN ibool lock_deadlock_found = FALSE; /** Only created if !srv_read_only_mode */ static FILE* lock_latest_err_file; -/********************************************************************//** -Checks if a joining lock request results in a deadlock. If a deadlock is +/** Check if a joining lock request results in a deadlock. If a deadlock is found this function will resolve the dadlock by choosing a victim transaction -and rolling it back. It will attempt to resolve all deadlocks. The returned -transaction id will be the joining transaction id or 0 if some other -transaction was chosen as a victim and rolled back or no deadlock found. - -@return id of transaction chosen as victim or 0 */ -static -trx_id_t -lock_deadlock_check_and_resolve( -/*===========================*/ - const lock_t* lock, /*!< in: lock the transaction is requesting */ - const trx_t* trx); /*!< in: transaction */ +and rolling it back. It will attempt to resolve all deadlocks. +@param[in] trx joining transaction +@param[in] lock the requested lock +@param[in] now current time +@return trx->id of the victim transaction +@retval 0 if some other transaction was chosen as a victim and +rolled back, or no deadlock was found. */ +static trx_id_t lock_deadlock_check_and_resolve(const trx_t* trx, + const lock_t* lock, + time_t now); /*********************************************************************//** Gets the nth bit of a record lock. @@ -1147,12 +1159,11 @@ lock_rec_has_to_wait( thread, we need to look at trx ordering and lock types */ if (wsrep_thd_is_BF(trx->mysql_thd, FALSE) && wsrep_thd_is_BF(lock2->trx->mysql_thd, TRUE)) { - if (wsrep_debug) { fprintf(stderr, "BF-BF lock conflict, locking: %lu\n", for_locking); - lock_rec_print(stderr, lock2); + lock_rec_print(stderr, lock2, time(NULL)); } if (wsrep_trx_order_before(trx->mysql_thd, @@ -1171,7 +1182,8 @@ lock_rec_has_to_wait( "conflicts states: my %d locked %d\n", wsrep_thd_conflict_state(trx->mysql_thd, FALSE), wsrep_thd_conflict_state(lock2->trx->mysql_thd, FALSE) ); - lock_rec_print(stderr, lock2); + lock_rec_print(stderr, lock2, + time(NULL)); if (for_locking) return FALSE; //abort(); } @@ -1797,10 +1809,12 @@ wsrep_kill_victim( fputs("*** WAITING FOR THIS LOCK TO BE GRANTED:\n", stderr); + time_t now = time(NULL); + if (lock_get_type(lock) == LOCK_REC) { - lock_rec_print(stderr, lock); + lock_rec_print(stderr, lock, now); } else { - lock_table_print(stderr, lock); + lock_table_print(stderr, lock, now); } } @@ -2055,16 +2069,20 @@ wsrep_print_wait_locks( { if (wsrep_debug && c_lock->trx->lock.wait_lock != c_lock) { fprintf(stderr, "WSREP: c_lock != wait lock\n"); + time_t now = time(NULL); + if (lock_get_type_low(c_lock) & LOCK_TABLE) { - lock_table_print(stderr, c_lock); + lock_table_print(stderr, c_lock, now); } else { - lock_rec_print(stderr, c_lock); + lock_rec_print(stderr, c_lock, now); } if (lock_get_type_low(c_lock->trx->lock.wait_lock) & LOCK_TABLE) { - lock_table_print(stderr, c_lock->trx->lock.wait_lock); + lock_table_print(stderr, c_lock->trx->lock.wait_lock, + now); } else { - lock_rec_print(stderr, c_lock->trx->lock.wait_lock); + lock_rec_print(stderr, c_lock->trx->lock.wait_lock, + now); } } } @@ -2077,10 +2095,7 @@ If neither of them is wait lock, the first one has higher priority. If only one of them is a wait lock, it has lower priority. Otherwise, the one with an older transaction has higher priority. @returns true if lock1 has higher priority, false otherwise. */ -bool -has_higher_priority( - lock_t *lock1, - lock_t *lock2) +static bool has_higher_priority(lock_t *lock1, lock_t *lock2) { if (lock1 == NULL) { return false; @@ -2295,7 +2310,7 @@ lock_rec_create( /* Set the bit corresponding to rec */ lock_rec_set_nth_bit(lock, heap_no); - lock->requested_time = ut_time(); + lock->requested_time = time(NULL); lock->wait_time = 0; index->table->n_rec_locks++; @@ -2448,8 +2463,6 @@ lock_rec_enqueue_waiting( trx_t* trx; lock_t* lock; trx_id_t victim_trx_id; - ulint sec; - ulint ms; ulint space; ulint page_no; dberr_t err; @@ -2508,7 +2521,8 @@ lock_rec_enqueue_waiting( trx_mutex_exit(trx); - victim_trx_id = lock_deadlock_check_and_resolve(lock, trx); + const time_t now = time(NULL); + victim_trx_id = lock_deadlock_check_and_resolve(trx, lock, now); trx_mutex_enter(trx); @@ -2532,11 +2546,10 @@ lock_rec_enqueue_waiting( trx->lock.que_state = TRX_QUE_LOCK_WAIT; trx->lock.was_chosen_as_deadlock_victim = FALSE; - trx->lock.wait_started = ut_time(); + trx->lock.wait_started = now; if (UNIV_UNLIKELY(trx->take_stats)) { - ut_usectime(&sec, &ms); - trx->lock_que_wait_ustarted = (ib_uint64_t)sec * 1000000 + ms; + trx->lock_que_wait_nstarted = my_interval_timer(); } ut_a(que_thr_stop(thr)); @@ -2678,7 +2691,8 @@ lock_rec_add_to_queue( "BF skipping wait: " TRX_ID_FMT "\n", trx->id); - lock_rec_print(stderr, lock); + lock_rec_print(stderr, lock, + time(NULL)); } } else #endif @@ -2997,13 +3011,14 @@ lock_rec_has_to_wait_in_queue( if (wsrep_thd_is_BF(wait_lock->trx->mysql_thd, FALSE) && wsrep_thd_is_BF(lock->trx->mysql_thd, TRUE)) { if (wsrep_debug) { + time_t now = time(NULL); fprintf(stderr, "BF-BF lock conflict " TRX_ID_FMT " : " TRX_ID_FMT "\n", wait_lock->trx->id, lock->trx->id); - lock_rec_print(stderr, wait_lock); - lock_rec_print(stderr, lock); + lock_rec_print(stderr, wait_lock, now); + lock_rec_print(stderr, lock, now); } /* don't wait for another BF lock */ continue; @@ -3070,16 +3085,18 @@ lock_grant( } } + const time_t now = time(NULL); + /* Cumulate total lock wait time for statistics */ if (lock_get_type_low(lock) & LOCK_TABLE) { lock->trx->total_table_lock_wait_time += - (ulint)difftime(ut_time(), lock->trx->lock.wait_started); + (ulint)difftime(now, lock->trx->lock.wait_started); } else { lock->trx->total_rec_lock_wait_time += - (ulint)difftime(ut_time(), lock->trx->lock.wait_started); + (ulint)difftime(now, lock->trx->lock.wait_started); } - lock->wait_time = (ulint)difftime(ut_time(), lock->requested_time); + lock->wait_time = (ulint)difftime(now, lock->requested_time); if (!owns_trx_mutex) { trx_mutex_exit(lock->trx); @@ -4334,28 +4351,26 @@ lock_deadlock_trx_print( mutex_exit(&trx_sys->mutex); } -/*********************************************************************//** -Print lock data to the deadlock file and possibly to stderr. */ -UNIV_INLINE -void -lock_deadlock_lock_print( -/*=====================*/ - const lock_t* lock) /*!< in: record or table type lock */ +/** Print lock data to the deadlock file and possibly to stderr. +@param[in] lock record or table lock +@param[in] now current time */ +static void lock_deadlock_lock_print(const lock_t* lock, time_t now) { ut_ad(lock_mutex_own()); ut_ad(!srv_read_only_mode); if (lock_get_type_low(lock) == LOCK_REC) { - lock_rec_print(lock_latest_err_file, lock); + mtr_t mtr; + lock_rec_print(lock_latest_err_file, lock, now, &mtr); if (srv_print_all_deadlocks) { - lock_rec_print(stderr, lock); + lock_rec_print(stderr, lock, now, &mtr); } } else { - lock_table_print(lock_latest_err_file, lock); + lock_table_print(lock_latest_err_file, lock, now); if (srv_print_all_deadlocks) { - lock_table_print(stderr, lock); + lock_table_print(stderr, lock, now); } } } @@ -4468,6 +4483,8 @@ lock_deadlock_notify( ut_ad(lock_mutex_own()); ut_ad(!srv_read_only_mode); + const time_t now = time(NULL); + lock_deadlock_start_print(); lock_deadlock_fputs("\n*** (1) TRANSACTION:\n"); @@ -4476,7 +4493,7 @@ lock_deadlock_notify( lock_deadlock_fputs("*** (1) WAITING FOR THIS LOCK TO BE GRANTED:\n"); - lock_deadlock_lock_print(ctx->wait_lock); + lock_deadlock_lock_print(ctx->wait_lock, now); lock_deadlock_fputs("*** (2) TRANSACTION:\n"); @@ -4484,7 +4501,7 @@ lock_deadlock_notify( lock_deadlock_fputs("*** (2) HOLDS THE LOCK(S):\n"); - lock_deadlock_lock_print(lock); + lock_deadlock_lock_print(lock, now); /* It is possible that the joining transaction was granted its lock when we rolled back some other waiting transaction. */ @@ -4493,7 +4510,7 @@ lock_deadlock_notify( lock_deadlock_fputs( "*** (2) WAITING FOR THIS LOCK TO BE GRANTED:\n"); - lock_deadlock_lock_print(ctx->start->lock.wait_lock); + lock_deadlock_lock_print(ctx->start->lock.wait_lock, now); } #ifdef UNIV_DEBUG @@ -4742,14 +4759,12 @@ lock_deadlock_search( return(0); } -/********************************************************************//** -Print info about transaction that was rolled back. */ -static -void -lock_deadlock_joining_trx_print( -/*============================*/ - const trx_t* trx, /*!< in: transaction rolled back */ - const lock_t* lock) /*!< in: lock trx wants */ +/** Print info about transaction that was rolled back. +@param[in] trx victim transaction +@param[in] lock the requested lock +@param[in] now current time */ +static void lock_deadlock_joining_trx_print(const trx_t* trx, + const lock_t* lock, time_t now) { ut_ad(lock_mutex_own()); ut_ad(!srv_read_only_mode); @@ -4769,7 +4784,7 @@ lock_deadlock_joining_trx_print( lock_deadlock_fputs("*** WAITING FOR THIS LOCK TO BE GRANTED:\n"); - lock_deadlock_lock_print(lock); + lock_deadlock_lock_print(lock, now); } /********************************************************************//** @@ -4839,20 +4854,17 @@ lock_report_waiters_to_mysql( } -/********************************************************************//** -Checks if a joining lock request results in a deadlock. If a deadlock is +/** Check if a joining lock request results in a deadlock. If a deadlock is found this function will resolve the dadlock by choosing a victim transaction -and rolling it back. It will attempt to resolve all deadlocks. The returned -transaction id will be the joining transaction id or 0 if some other -transaction was chosen as a victim and rolled back or no deadlock found. - -@return id of transaction chosen as victim or 0 */ -static -trx_id_t -lock_deadlock_check_and_resolve( -/*============================*/ - const lock_t* lock, /*!< in: lock the transaction is requesting */ - const trx_t* trx) /*!< in: transaction */ +and rolling it back. It will attempt to resolve all deadlocks. +@param[in] trx joining transaction +@param[in] lock the requested lock +@param[in] now current time +@return trx->id of the victim transaction +@retval 0 if some other transaction was chosen as a victim and +rolled back, or no deadlock was found. */ +static trx_id_t lock_deadlock_check_and_resolve(const trx_t* trx, + const lock_t* lock, time_t now) { trx_id_t victim_trx_id; struct thd_wait_reports waitee_buf; @@ -4904,18 +4916,12 @@ lock_deadlock_check_and_resolve( ut_a(victim_trx_id == trx->id); #ifdef WITH_WSREP - if (!wsrep_thd_is_BF(ctx.start->mysql_thd, TRUE)) - { + if (wsrep_thd_is_BF(ctx.start->mysql_thd, TRUE)); else #endif /* WITH_WSREP */ - if (!srv_read_only_mode) { - lock_deadlock_joining_trx_print(trx, lock); - } -#ifdef WITH_WSREP - } else { - /* BF processor */; + if (!srv_read_only_mode) { + lock_deadlock_joining_trx_print(trx, lock, + now); } -#endif /* WITH_WSREP */ - } else if (victim_trx_id != 0 && victim_trx_id != trx->id) { ut_ad(victim_trx_id == ctx.wait_lock->trx->id); @@ -4993,7 +4999,7 @@ lock_table_create( lock->type_mode = type_mode | LOCK_TABLE; lock->trx = trx; - lock->requested_time = ut_time(); + lock->requested_time = time(NULL); lock->wait_time = 0; lock->un_member.tab_lock.table = table; @@ -5205,8 +5211,6 @@ lock_table_enqueue_waiting( trx_t* trx; lock_t* lock; trx_id_t victim_trx_id; - ulint sec; - ulint ms; ut_ad(lock_mutex_own()); ut_ad(!srv_read_only_mode); @@ -5263,7 +5267,9 @@ lock_table_enqueue_waiting( trx_mutex_exit(trx); - victim_trx_id = lock_deadlock_check_and_resolve(lock, trx); + const time_t now = time(NULL); + + victim_trx_id = lock_deadlock_check_and_resolve(trx, lock, now); trx_mutex_enter(trx); @@ -5285,13 +5291,12 @@ lock_table_enqueue_waiting( trx->lock.que_state = TRX_QUE_LOCK_WAIT; - trx->lock.wait_started = ut_time(); + trx->lock.wait_started = now; trx->lock.was_chosen_as_deadlock_victim = FALSE; trx->n_table_lock_waits++; if (UNIV_UNLIKELY(trx->take_stats)) { - ut_usectime(&sec, &ms); - trx->lock_que_wait_ustarted = (ib_uint64_t)sec * 1000000 + ms; + trx->lock_que_wait_nstarted = my_interval_timer(); } ut_a(que_thr_stop(thr)); @@ -6038,14 +6043,11 @@ lock_remove_all_on_table( /*===================== VALIDATION AND DEBUGGING ====================*/ -/*********************************************************************//** -Prints info of a table lock. */ -UNIV_INTERN -void -lock_table_print( -/*=============*/ - FILE* file, /*!< in: file where to print */ - const lock_t* lock) /*!< in: table type lock */ +/** Pretty-print a table lock. +@param[in,out] file output stream +@param[in] lock table lock +@param[in] now current time */ +static void lock_table_print(FILE* file, const lock_t* lock, time_t now) { ut_ad(lock_mutex_own()); ut_a(lock_get_type_low(lock) == LOCK_TABLE); @@ -6075,30 +6077,22 @@ lock_table_print( } fprintf(file, " lock hold time %lu wait time before grant %lu ", - (ulint)difftime(ut_time(), lock->requested_time), + (ulint)difftime(now, lock->requested_time), lock->wait_time); putc('\n', file); } -/*********************************************************************//** -Prints info of a record lock. */ -UNIV_INTERN -void -lock_rec_print( -/*===========*/ - FILE* file, /*!< in: file where to print */ - const lock_t* lock) /*!< in: record type lock */ +/** Pretty-print a record lock. +@param[in,out] file output stream +@param[in] lock record lock +@param[in] now current time +@param[in,out] mtr mini-transaction */ +static void lock_rec_print(FILE* file, const lock_t* lock, time_t now, + mtr_t* mtr) { - const buf_block_t* block; ulint space; ulint page_no; - ulint i; - mtr_t mtr; - mem_heap_t* heap = NULL; - ulint offsets_[REC_OFFS_NORMAL_SIZE]; - ulint* offsets = offsets_; - rec_offs_init(offsets_); ut_ad(lock_mutex_own()); ut_a(lock_get_type_low(lock) == LOCK_REC); @@ -6143,18 +6137,25 @@ lock_rec_print( fputs(" waiting", file); } - mtr_start(&mtr); - fprintf(file, " lock hold time %lu wait time before grant %lu ", - (ulint)difftime(ut_time(), lock->requested_time), + (ulint)difftime(now, lock->requested_time), lock->wait_time); putc('\n', file); - if ( srv_show_verbose_locks ) { - block = buf_page_try_get(space, page_no, &mtr); + if (!srv_show_verbose_locks || !mtr) { + return; + } - for (i = 0; i < lock_rec_get_n_bits(lock); ++i) { + mem_heap_t* heap = NULL; + ulint offsets_[REC_OFFS_NORMAL_SIZE]; + ulint* offsets = offsets_; + rec_offs_init(offsets_); + + mtr_start(mtr); + const buf_block_t* block = buf_page_try_get(space, page_no, mtr); + + for (ulint i = 0; i < lock_rec_get_n_bits(lock); ++i) { if (!lock_rec_get_nth_bit(lock, i)) { continue; @@ -6178,9 +6179,8 @@ lock_rec_print( putc('\n', file); } - } - mtr_commit(&mtr); + mtr_commit(mtr); if (UNIV_LIKELY_NULL(heap)) { mem_heap_free(heap); } @@ -6336,6 +6336,8 @@ lock_print_info_all_transactions( ut_ad(lock_mutex_own()); + const time_t now = time(NULL); + mutex_enter(&trx_sys->mutex); /* First print info on non-active transactions */ @@ -6422,13 +6424,14 @@ loop: fprintf(file, "------- TRX HAS BEEN WAITING %lu SEC" " FOR THIS LOCK TO BE GRANTED:\n", - (ulong) difftime(ut_time(), - trx->lock.wait_started)); + (ulong) difftime(now, trx->lock.wait_started)); if (lock_get_type_low(trx->lock.wait_lock) == LOCK_REC) { - lock_rec_print(file, trx->lock.wait_lock); + lock_rec_print(file, trx->lock.wait_lock, now, + &mtr); } else { - lock_table_print(file, trx->lock.wait_lock); + lock_table_print(file, trx->lock.wait_lock, + now); } fputs("------------------\n", file); @@ -6517,11 +6520,11 @@ loop: } print_rec: - lock_rec_print(file, lock); + lock_rec_print(file, lock, now, &mtr); } else { ut_ad(lock_get_type_low(lock) & LOCK_TABLE); - lock_table_print(file, lock); + lock_table_print(file, lock, now); } load_page_first = TRUE; diff --git a/storage/xtradb/lock/lock0wait.cc b/storage/xtradb/lock/lock0wait.cc index c65b127f339..3efc28967db 100644 --- a/storage/xtradb/lock/lock0wait.cc +++ b/storage/xtradb/lock/lock0wait.cc @@ -1,7 +1,7 @@ /***************************************************************************** Copyright (c) 1996, 2016, Oracle and/or its affiliates. All Rights Reserved. -Copyright (c) 2014, 2017, MariaDB Corporation. +Copyright (c) 2014, 2019, MariaDB Corporation. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software @@ -74,7 +74,7 @@ lock_wait_table_print(void) (ulong) slot->in_use, (ulong) slot->suspended, slot->wait_timeout, - (ulong) difftime(ut_time(), slot->suspend_time)); + (ulong) difftime(time(NULL), slot->suspend_time)); } } @@ -171,7 +171,7 @@ lock_wait_table_reserve_slot( os_event_reset(slot->event); slot->suspended = TRUE; - slot->suspend_time = ut_time(); + slot->suspend_time = time(NULL); slot->wait_timeout = wait_timeout; if (slot == lock_sys->last_slot) { @@ -280,14 +280,9 @@ lock_wait_suspend_thread( user OS thread */ { srv_slot_t* slot; - double wait_time; trx_t* trx; ulint had_dict_lock; ibool was_declared_inside_innodb; - ib_int64_t start_time = 0; - ib_int64_t finish_time; - ulint sec; - ulint ms; ulong lock_wait_timeout; blocking_trx_info blocking[MAX_BLOCKING_TRX_IN_REPORT]; size_t blocking_count = 0; @@ -335,15 +330,12 @@ lock_wait_suspend_thread( lock_wait_mutex_exit(); trx_mutex_exit(trx); + ulonglong start_time = 0; + if (thr->lock_state == QUE_THR_LOCK_ROW) { srv_stats.n_lock_wait_count.inc(); srv_stats.n_lock_wait_current_count.inc(); - - if (ut_usectime(&sec, &ms) == -1) { - start_time = -1; - } else { - start_time = (ib_int64_t) sec * 1000000 + ms; - } + start_time = my_interval_timer(); } ulint lock_type = ULINT_UNDEFINED; @@ -423,39 +415,32 @@ lock_wait_suspend_thread( row_mysql_freeze_data_dictionary(trx); } - wait_time = ut_difftime(ut_time(), slot->suspend_time); + double wait_time = difftime(time(NULL), slot->suspend_time); /* Release the slot for others to use */ lock_wait_table_release_slot(slot); if (thr->lock_state == QUE_THR_LOCK_ROW) { - ulint diff_time; - - if (ut_usectime(&sec, &ms) == -1) { - finish_time = -1; - } else { - finish_time = (ib_int64_t) sec * 1000000 + ms; - } - - diff_time = (finish_time > start_time) ? - (ulint) (finish_time - start_time) : 0; - srv_stats.n_lock_wait_current_count.dec(); - srv_stats.n_lock_wait_time.add(diff_time); - /* Only update the variable if we successfully - retrieved the start and finish times. See Bug#36819. */ - if (diff_time > lock_sys->n_lock_max_wait_time - && start_time != -1 - && finish_time != -1) { + const ulonglong finish_time = my_interval_timer(); + ulint diff_time; - lock_sys->n_lock_max_wait_time = diff_time; + if (finish_time < start_time) { + diff_time = 0; + } else { + diff_time = ulint((finish_time - start_time) / 1000); + srv_stats.n_lock_wait_time.add(diff_time); + /* Only update the variable if we successfully + retrieved the start and finish times. See Bug#36819. */ + if (diff_time > lock_sys->n_lock_max_wait_time) { + lock_sys->n_lock_max_wait_time = diff_time; + } } /* Record the lock wait time for this thread */ thd_set_lock_wait_time(trx->mysql_thd, diff_time); - } if (lock_wait_timeout < 100000000 @@ -523,19 +508,12 @@ lock_wait_check_and_cancel( const srv_slot_t* slot) /*!< in: slot reserved by a user thread when the wait started */ { - trx_t* trx; - double wait_time; - ib_time_t suspend_time = slot->suspend_time; - ut_ad(lock_wait_mutex_own()); - ut_ad(slot->in_use); - ut_ad(slot->suspended); - wait_time = ut_difftime(ut_time(), suspend_time); - - trx = thr_get_trx(slot->thr); + double wait_time = difftime(time(NULL), slot->suspend_time); + trx_t* trx = thr_get_trx(slot->thr); if (trx_is_interrupted(trx) || (slot->wait_timeout < 100000000 @@ -569,7 +547,6 @@ lock_wait_check_and_cancel( trx_mutex_exit(trx); } - } /*********************************************************************//** diff --git a/storage/xtradb/log/log0log.cc b/storage/xtradb/log/log0log.cc index b5ae973bfcc..3e0c6ced14a 100644 --- a/storage/xtradb/log/log0log.cc +++ b/storage/xtradb/log/log0log.cc @@ -2,7 +2,7 @@ Copyright (c) 1995, 2017, Oracle and/or its affiliates. All Rights Reserved. Copyright (c) 2009, Google Inc. -Copyright (c) 2014, 2018, MariaDB Corporation. +Copyright (c) 2014, 2019, MariaDB Corporation. Portions of this file contain modifications contributed and copyrighted by Google, Inc. Those modifications are gratefully acknowledged and are described @@ -2591,7 +2591,8 @@ loop: start_lsn += len; buf += len; - if (recv_recovery_is_on() && recv_sys && recv_sys->report(ut_time())) { + if (recv_recovery_is_on() && recv_sys + && recv_sys->report(time(NULL))) { ib_logf(IB_LOG_LEVEL_INFO, "Read redo log up to LSN=" LSN_PF, start_lsn); service_manager_extend_timeout(INNODB_EXTEND_TIMEOUT_INTERVAL, diff --git a/storage/xtradb/log/log0recv.cc b/storage/xtradb/log/log0recv.cc index 0bec6f9577d..dd55d31218a 100644 --- a/storage/xtradb/log/log0recv.cc +++ b/storage/xtradb/log/log0recv.cc @@ -419,7 +419,7 @@ recv_sys_init( recv_sys->last_block_buf_start, OS_FILE_LOG_BLOCK_SIZE)); recv_sys->found_corrupt_log = FALSE; - recv_sys->progress_time = ut_time(); + recv_sys->progress_time = time(NULL); recv_max_page_lsn = 0; @@ -1789,7 +1789,7 @@ recv_recover_page_func( mtr_commit(&mtr); - ib_time_t time = ut_time(); + time_t now = time(NULL); mutex_enter(&(recv_sys->mutex)); @@ -1801,7 +1801,7 @@ recv_recover_page_func( ut_a(recv_sys->n_addrs > 0); if (ulint n = --recv_sys->n_addrs) { - if (recv_sys->report(time)) { + if (recv_sys->report(now)) { ib_logf(IB_LOG_LEVEL_INFO, "To recover: " ULINTPF " pages from log", n); service_manager_extend_timeout( diff --git a/storage/xtradb/os/os0file.cc b/storage/xtradb/os/os0file.cc index da5e8927320..1e0f28d393f 100644 --- a/storage/xtradb/os/os0file.cc +++ b/storage/xtradb/os/os0file.cc @@ -2,7 +2,7 @@ Copyright (c) 1995, 2017, Oracle and/or its affiliates. All Rights Reserved. Copyright (c) 2009, Percona Inc. -Copyright (c) 2013, 2018, MariaDB Corporation. +Copyright (c) 2013, 2019, MariaDB Corporation. Portions of this file contain modifications contributed and copyrighted by Percona Inc.. Those modifications are @@ -214,7 +214,10 @@ struct os_aio_slot_t{ ulint pos; /*!< index of the slot in the aio array */ ibool reserved; /*!< TRUE if this slot is reserved */ - time_t reservation_time;/*!< time when reserved */ + /** time(NULL) when reserved. + FIXME: os_aio_simulated_handle() may malfunction if + the system time is adjusted! */ + time_t reservation_time; ulint len; /*!< length of the block to read or write */ byte* buf; /*!< buffer used in i/o */ @@ -2968,10 +2971,6 @@ os_file_pread( trx_t* trx) { off_t offs; - ulint sec; - ulint ms; - ib_uint64_t start_time; - ib_uint64_t finish_time; ut_ad(n); @@ -2988,15 +2987,9 @@ os_file_pread( os_n_file_reads++; - if (UNIV_UNLIKELY(trx && trx->take_stats)) - { - trx->io_reads++; - trx->io_read += n; - ut_usectime(&sec, &ms); - start_time = (ib_uint64_t)sec * 1000000 + ms; - } else { - start_time = 0; - } + const ulonglong start_time = UNIV_UNLIKELY(trx && trx->take_stats) + ? my_interval_timer() + : 0; const bool monitor = MONITOR_IS_ON(MONITOR_OS_PENDING_READS); #ifdef HAVE_PREAD @@ -3022,9 +3015,8 @@ os_file_pread( if (UNIV_UNLIKELY(start_time != 0)) { - ut_usectime(&sec, &ms); - finish_time = (ib_uint64_t)sec * 1000000 + ms; - trx->io_reads_wait_timer += (ulint)(finish_time - start_time); + trx->io_reads_wait_timer += ulint((my_interval_timer() + - start_time) / 1000); } return(n_bytes); @@ -3071,9 +3063,8 @@ os_file_pread( if (UNIV_UNLIKELY(start_time != 0) { - ut_usectime(&sec, &ms); - finish_time = (ib_uint64_t)sec * 1000000 + ms; - trx->io_reads_wait_timer += (ulint)(finish_time - start_time); + trx->io_reads_wait_timer += ulint( + (my_interval_timer() - start_time) / 1000); } return(ret); @@ -4518,7 +4509,7 @@ os_aio_init( os_aio_validate(); - os_last_printout = ut_time(); + os_last_printout = time(NULL); #ifdef _WIN32 ut_a(completion_port == 0 && read_completion_port == 0); @@ -4846,7 +4837,7 @@ found: } slot->reserved = TRUE; - slot->reservation_time = ut_time(); + slot->reservation_time = time(NULL); slot->message1 = message1; slot->message2 = message2; slot->file = file; @@ -5988,7 +5979,7 @@ restart: if (slot->reserved) { age = (ulint) difftime( - ut_time(), slot->reservation_time); + time(NULL), slot->reservation_time); if ((age >= 2 && age > biggest_age) || (age >= 2 && age == biggest_age @@ -6401,7 +6392,7 @@ os_aio_print( } putc('\n', file); - current_time = ut_time(); + current_time = time(NULL); time_elapsed = 0.001 + difftime(current_time, os_last_printout); fprintf(file, diff --git a/storage/xtradb/os/os0sync.cc b/storage/xtradb/os/os0sync.cc index da66c09e7d8..675832c49e6 100644 --- a/storage/xtradb/os/os0sync.cc +++ b/storage/xtradb/os/os0sync.cc @@ -59,9 +59,6 @@ UNIV_INTERN ulint os_event_count = 0; UNIV_INTERN ulint os_mutex_count = 0; UNIV_INTERN ulint os_fast_mutex_count = 0; -/* The number of microsecnds in a second. */ -static const ulint MICROSECS_IN_A_SECOND = 1000000; - #ifdef UNIV_PFS_MUTEX UNIV_INTERN mysql_pfs_key_t event_os_mutex_key; UNIV_INTERN mysql_pfs_key_t os_mutex_key; @@ -398,26 +395,9 @@ os_event_wait_time_low( struct timespec abstime; if (time_in_usec != OS_SYNC_INFINITE_TIME) { - struct timeval tv; - int ret; - ulint sec; - ulint usec; - - ret = ut_usectime(&sec, &usec); - ut_a(ret == 0); - - tv.tv_sec = sec; - tv.tv_usec = usec; - - tv.tv_usec += time_in_usec; - - if ((ulint) tv.tv_usec >= MICROSECS_IN_A_SECOND) { - tv.tv_sec += tv.tv_usec / MICROSECS_IN_A_SECOND; - tv.tv_usec %= MICROSECS_IN_A_SECOND; - } - - abstime.tv_sec = tv.tv_sec; - abstime.tv_nsec = tv.tv_usec * 1000; + ulonglong usec = ulonglong(time_in_usec) + my_hrtime().val; + abstime.tv_sec = usec / 1000000; + abstime.tv_nsec = (usec % 1000000) * 1000; } else { abstime.tv_nsec = 999999999; abstime.tv_sec = (time_t) ULINT_MAX; diff --git a/storage/xtradb/page/page0cur.cc b/storage/xtradb/page/page0cur.cc index 767ae5cbf88..e9ac4b4bb04 100644 --- a/storage/xtradb/page/page0cur.cc +++ b/storage/xtradb/page/page0cur.cc @@ -48,7 +48,7 @@ number between 0 and 2^64-1 inclusive. The formula and the constants being used are: X[n+1] = (a * X[n] + c) mod m where: -X[0] = ut_time_us(NULL) +X[0] = my_interval_timer() a = 1103515245 (3^5 * 5 * 7 * 129749) c = 12345 (3 * 5 * 823) m = 18446744073709551616 (2^64) @@ -61,12 +61,10 @@ page_cur_lcg_prng(void) { #define LCG_a 1103515245 #define LCG_c 12345 - static ib_uint64_t lcg_current = 0; - static ibool initialized = FALSE; + static uint64_t lcg_current; - if (!initialized) { - lcg_current = (ib_uint64_t) ut_time_us(NULL); - initialized = TRUE; + if (!lcg_current) { + lcg_current = my_interval_timer(); } /* no need to "% 2^64" explicitly because lcg_current is diff --git a/storage/xtradb/page/page0zip.cc b/storage/xtradb/page/page0zip.cc index 852807dc239..0c7f9b6feff 100644 --- a/storage/xtradb/page/page0zip.cc +++ b/storage/xtradb/page/page0zip.cc @@ -2,7 +2,7 @@ Copyright (c) 2005, 2016, Oracle and/or its affiliates. All Rights Reserved. Copyright (c) 2012, Facebook Inc. -Copyright (c) 2014, 2018, MariaDB Corporation. +Copyright (c) 2014, 2019, MariaDB Corporation. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software @@ -1240,7 +1240,7 @@ page_zip_compress( ulint n_blobs = 0; byte* storage;/* storage of uncompressed columns */ #ifndef UNIV_HOTBACKUP - ullint usec = ut_time_us(NULL); + const ulonglong ns = my_interval_timer(); #endif /* !UNIV_HOTBACKUP */ #ifdef PAGE_ZIP_COMPRESS_DBG FILE* logfile = NULL; @@ -1489,7 +1489,7 @@ err_exit: dict_index_zip_failure(index); } - ullint time_diff = ut_time_us(NULL) - usec; + const ullint time_diff = (my_interval_timer() - ns) / 1000; page_zip_stat[page_zip->ssize - 1].compressed_usec += time_diff; if (cmp_per_index_enabled) { @@ -1557,7 +1557,7 @@ err_exit: } #endif /* PAGE_ZIP_COMPRESS_DBG */ #ifndef UNIV_HOTBACKUP - ullint time_diff = ut_time_us(NULL) - usec; + const ullint time_diff = (my_interval_timer() - ns) / 1000; page_zip_stat[page_zip->ssize - 1].compressed_ok++; page_zip_stat[page_zip->ssize - 1].compressed_usec += time_diff; if (cmp_per_index_enabled) { @@ -3006,7 +3006,7 @@ page_zip_decompress( mem_heap_t* heap; ulint* offsets; #ifndef UNIV_HOTBACKUP - ullint usec = ut_time_us(NULL); + const ulonglong ns = my_interval_timer(); #endif /* !UNIV_HOTBACKUP */ ut_ad(page_zip_simple_validate(page_zip)); @@ -3192,7 +3192,7 @@ err_exit: page_zip_fields_free(index); mem_heap_free(heap); #ifndef UNIV_HOTBACKUP - ullint time_diff = ut_time_us(NULL) - usec; + const uint64_t time_diff = (my_interval_timer() - ns) / 1000; page_zip_stat[page_zip->ssize - 1].decompressed++; page_zip_stat[page_zip->ssize - 1].decompressed_usec += time_diff; diff --git a/storage/xtradb/que/que0que.cc b/storage/xtradb/que/que0que.cc index 8cf66049088..090c5091a8d 100644 --- a/storage/xtradb/que/que0que.cc +++ b/storage/xtradb/que/que0que.cc @@ -204,9 +204,6 @@ que_thr_end_lock_wait( { que_thr_t* thr; ibool was_active; - ulint sec; - ulint ms; - ib_uint64_t now; ut_ad(lock_mutex_own()); ut_ad(trx_mutex_own(trx)); @@ -224,10 +221,9 @@ que_thr_end_lock_wait( que_thr_move_to_run_state(thr); if (UNIV_UNLIKELY(trx->take_stats)) { - ut_usectime(&sec, &ms); - now = (ib_uint64_t)sec * 1000000 + ms; - trx->lock_que_wait_timer - += (ulint)(now - trx->lock_que_wait_ustarted); + trx->lock_que_wait_timer += static_cast<ulint>( + (my_interval_timer() - trx->lock_que_wait_nstarted) + / 1000); } trx->lock.que_state = TRX_QUE_RUNNING; diff --git a/storage/xtradb/srv/srv0conc.cc b/storage/xtradb/srv/srv0conc.cc index 19c2f025b1b..1a198fceaec 100644 --- a/storage/xtradb/srv/srv0conc.cc +++ b/storage/xtradb/srv/srv0conc.cc @@ -401,8 +401,6 @@ srv_conc_enter_innodb_without_atomics( ulint i; srv_conc_slot_t* slot = NULL; ibool has_slept = FALSE; - ib_uint64_t start_time = 0L; - ib_uint64_t finish_time = 0L; ulint sec; ulint ms; @@ -537,12 +535,9 @@ retry: ut_ad(!sync_thread_levels_nonempty_trx(trx->has_search_latch)); #endif /* UNIV_SYNC_DEBUG */ - if (UNIV_UNLIKELY(trx->take_stats)) { - ut_usectime(&sec, &ms); - start_time = (ib_uint64_t)sec * 1000000 + ms; - } else { - start_time = 0; - } + const ulonglong start_time = UNIV_UNLIKELY(trx->take_stats) + ? my_interval_timer() + : 0; trx->op_info = "waiting in InnoDB queue"; @@ -557,9 +552,8 @@ retry: trx->op_info = ""; if (UNIV_UNLIKELY(start_time != 0)) { - ut_usectime(&sec, &ms); - finish_time = (ib_uint64_t)sec * 1000000 + ms; - trx->innodb_que_wait_timer += (ulint)(finish_time - start_time); + trx->innodb_que_wait_timer += ulint((my_interval_timer() + - start_time) / 1000); } os_fast_mutex_lock(&srv_conc_mutex); diff --git a/storage/xtradb/srv/srv0srv.cc b/storage/xtradb/srv/srv0srv.cc index d64d16fa865..8e534714ce8 100644 --- a/storage/xtradb/srv/srv0srv.cc +++ b/storage/xtradb/srv/srv0srv.cc @@ -2163,10 +2163,11 @@ DECLARE_THREAD(srv_monitor_thread)(void*) pfs_register_thread(srv_monitor_thread_key); #endif /* UNIV_PFS_THREAD */ - srv_last_monitor_time = ut_time(); - last_table_monitor_time = ut_time(); - last_tablespace_monitor_time = ut_time(); - last_monitor_time = ut_time(); + current_time = time(NULL); + srv_last_monitor_time = current_time; + last_table_monitor_time = current_time; + last_tablespace_monitor_time = current_time; + last_monitor_time = current_time; mutex_skipped = 0; last_srv_print_monitor = srv_print_innodb_monitor; loop: @@ -2177,12 +2178,12 @@ loop: os_event_wait_time_low(srv_monitor_event, 5000000, sig_count); - current_time = ut_time(); + current_time = time(NULL); time_elapsed = difftime(current_time, last_monitor_time); if (time_elapsed > 15) { - last_monitor_time = ut_time(); + last_monitor_time = current_time; if (srv_print_innodb_monitor) { /* Reset mutex_skipped counter everytime @@ -2229,7 +2230,7 @@ loop: if (srv_print_innodb_tablespace_monitor && difftime(current_time, last_tablespace_monitor_time) > 60) { - last_tablespace_monitor_time = ut_time(); + last_tablespace_monitor_time = current_time; fputs("========================" "========================\n", @@ -2255,7 +2256,7 @@ loop: if (srv_print_innodb_table_monitor && difftime(current_time, last_table_monitor_time) > 60) { - last_table_monitor_time = ut_time(); + last_table_monitor_time = current_time; fprintf(stderr, "Warning: %s\n", DEPRECATED_MSG_INNODB_TABLE_MONITOR); @@ -2849,20 +2850,16 @@ static void srv_shutdown_print_master_pending( /*==============================*/ - ib_time_t* last_print_time, /*!< last time the function + time_t* last_print_time, /*!< last time the function print the message */ ulint n_tables_to_drop, /*!< number of tables to be dropped */ ulint n_bytes_merged) /*!< number of change buffer just merged */ { - ib_time_t current_time; - double time_elapsed; + time_t current_time = time(NULL); - current_time = ut_time(); - time_elapsed = ut_difftime(current_time, *last_print_time); - - if (time_elapsed > 60) { + if (difftime(current_time, *last_print_time) > 60) { *last_print_time = current_time; if (n_tables_to_drop) { @@ -2897,8 +2894,8 @@ void srv_master_do_active_tasks(void) /*============================*/ { - ib_time_t cur_time = ut_time(); - ullint counter_time = ut_time_us(NULL); + time_t cur_time = time(NULL); + ulonglong counter_time = microsecond_interval_timer(); ulint n_evicted = 0; /* First do the tasks that we are suppose to do at each @@ -2927,7 +2924,7 @@ srv_master_do_active_tasks(void) /* Do an ibuf merge */ srv_main_thread_op_info = "doing insert buffer merge"; - counter_time = ut_time_us(NULL); + counter_time = microsecond_interval_timer(); ibuf_merge_in_background(false); MONITOR_INC_TIME_IN_MICRO_SECS( MONITOR_SRV_IBUF_MERGE_MICROSECOND, counter_time); @@ -2989,9 +2986,7 @@ void srv_master_do_idle_tasks(void) /*==========================*/ { - ullint counter_time; ulint n_evicted = 0; - ++srv_main_idle_loops; MONITOR_INC(MONITOR_MASTER_IDLE_LOOPS); @@ -3000,7 +2995,7 @@ srv_master_do_idle_tasks(void) /* ALTER TABLE in MySQL requires on Unix that the table handler can drop tables lazily after there no longer are SELECT queries to them. */ - counter_time = ut_time_us(NULL); + ulonglong counter_time = microsecond_interval_timer(); srv_main_thread_op_info = "doing background drop tables"; row_drop_tables_for_mysql_in_background(); MONITOR_INC_TIME_IN_MICRO_SECS( @@ -3017,7 +3012,7 @@ srv_master_do_idle_tasks(void) log_free_check(); /* Do an ibuf merge */ - counter_time = ut_time_us(NULL); + counter_time = microsecond_interval_timer(); srv_main_thread_op_info = "doing insert buffer merge"; ibuf_merge_in_background(true); MONITOR_INC_TIME_IN_MICRO_SECS( @@ -3055,7 +3050,7 @@ srv_master_do_idle_tasks(void) if (srv_log_arch_expire_sec) { srv_main_thread_op_info = "purging archived logs"; - purge_archived_logs(ut_time() - srv_log_arch_expire_sec, + purge_archived_logs(time(NULL) - srv_log_arch_expire_sec, 0); } } @@ -3068,7 +3063,7 @@ srv_shutdown(bool ibuf_merge) { ulint n_bytes_merged = 0; ulint n_tables_to_drop; - ib_time_t now = ut_time(); + time_t now = time(NULL); do { ut_ad(!srv_read_only_mode); @@ -3229,10 +3224,10 @@ srv_purge_should_exit(ulint n_purged) /* Slow shutdown was requested. */ if (n_purged) { #if defined HAVE_SYSTEMD && !defined EMBEDDED_LIBRARY - static ib_time_t progress_time; - ib_time_t time = ut_time(); - if (time - progress_time >= 15) { - progress_time = time; + static time_t progress_time; + time_t now = time(NULL); + if (now - progress_time >= 15) { + progress_time = now; service_manager_extend_timeout( INNODB_EXTEND_TIMEOUT_INTERVAL, "InnoDB: to purge " ULINTPF " transactions", diff --git a/storage/xtradb/srv/srv0start.cc b/storage/xtradb/srv/srv0start.cc index 62bf4c758b7..6ea430699d4 100644 --- a/storage/xtradb/srv/srv0start.cc +++ b/storage/xtradb/srv/srv0start.cc @@ -71,7 +71,6 @@ Created 2/16/1996 Heikki Tuuri #include "srv0srv.h" #include "buf0flu.h" #include "btr0defragment.h" -#include "ut0timer.h" #include "btr0scrub.h" #include "mysql/service_wsrep.h" /* wsrep_recovery */ @@ -1743,9 +1742,6 @@ innobase_start_or_create_for_mysql() os_fast_mutex_free(&srv_os_test_mutex); - /* This should be initialized early */ - ut_init_timer(); - if (srv_force_recovery == SRV_FORCE_NO_LOG_REDO) { srv_read_only_mode = 1; } diff --git a/storage/xtradb/sync/sync0arr.cc b/storage/xtradb/sync/sync0arr.cc index 170adaab3a6..c085e8ebcf5 100644 --- a/storage/xtradb/sync/sync0arr.cc +++ b/storage/xtradb/sync/sync0arr.cc @@ -2,7 +2,7 @@ Copyright (c) 1995, 2015, Oracle and/or its affiliates. All Rights Reserved. Copyright (c) 2008, Google Inc. -Copyright (c) 2013, 2015, MariaDB Corporation. All Rights Reserved. +Copyright (c) 2013, 2019, MariaDB Corporation. Portions of this file contain modifications contributed and copyrighted by Google, Inc. Those modifications are gratefully acknowledged and are described @@ -123,8 +123,10 @@ struct sync_cell_t { has not been signalled in the period between the reset and wait call. */ - time_t reservation_time;/*!< time when the thread reserved - the wait cell */ + /** time(NULL) when the wait cell was reserved. + FIXME: sync_array_print_long_waits_low() may display bogus + warnings when the system time is adjusted to the past! */ + time_t reservation_time; }; /* NOTE: It is allowed for a thread to wait @@ -412,7 +414,7 @@ sync_array_reserve_cell( event = sync_cell_get_event(cell); cell->signal_count = os_event_reset(event); - cell->reservation_time = ut_time(); + cell->reservation_time = time(NULL); cell->thread = os_thread_get_curr_id(); diff --git a/storage/xtradb/trx/trx0i_s.cc b/storage/xtradb/trx/trx0i_s.cc index fc6a1a1919a..16b91a6b2a8 100644 --- a/storage/xtradb/trx/trx0i_s.cc +++ b/storage/xtradb/trx/trx0i_s.cc @@ -1,6 +1,7 @@ /***************************************************************************** Copyright (c) 2007, 2012, Oracle and/or its affiliates. All Rights Reserved. +Copyright (c) 2019, MariaDB Corporation. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software @@ -152,9 +153,8 @@ struct i_s_table_cache_t { struct trx_i_s_cache_t { rw_lock_t rw_lock; /*!< read-write lock protecting the rest of this structure */ - ullint last_read; /*!< last time the cache was read; - measured in microseconds since - epoch */ + ulonglong last_read; /*!< last time the cache was read; + measured in nanoseconds */ ib_mutex_t last_read_mutex;/*!< mutex protecting the last_read member - it is updated inside a shared lock of the @@ -479,7 +479,7 @@ fill_trx_row( ut_ad(lock_mutex_own()); row->trx_id = trx->id; - row->trx_started = (ib_time_t) trx->start_time; + row->trx_started = trx->start_time; row->trx_state = trx_get_que_state_str(trx); row->requested_lock_row = requested_lock_row; ut_ad(requested_lock_row == NULL @@ -488,7 +488,7 @@ fill_trx_row( if (trx->lock.wait_lock != NULL) { ut_a(requested_lock_row != NULL); - row->trx_wait_started = (ib_time_t) trx->lock.wait_started; + row->trx_wait_started = trx->lock.wait_started; } else { ut_a(requested_lock_row == NULL); row->trx_wait_started = 0; @@ -1221,22 +1221,16 @@ add_trx_relevant_locks_to_cache( } /** The minimum time that a cache must not be updated after it has been -read for the last time; measured in microseconds. We use this technique +read for the last time; measured in nanoseconds. We use this technique to ensure that SELECTs which join several INFORMATION SCHEMA tables read the same version of the cache. */ -#define CACHE_MIN_IDLE_TIME_US 100000 /* 0.1 sec */ +#define CACHE_MIN_IDLE_TIME_NS 100000000 /* 0.1 sec */ /*******************************************************************//** Checks if the cache can safely be updated. -@return TRUE if can be updated */ -static -ibool -can_cache_be_updated( -/*=================*/ - trx_i_s_cache_t* cache) /*!< in: cache */ +@return whether the cache can be updated */ +static bool can_cache_be_updated(trx_i_s_cache_t* cache) { - ullint now; - /* Here we read cache->last_read without acquiring its mutex because last_read is only updated when a shared rw lock on the whole cache is being held (see trx_i_s_cache_end_read()) and @@ -1247,14 +1241,7 @@ can_cache_be_updated( #ifdef UNIV_SYNC_DEBUG ut_a(rw_lock_own(&cache->rw_lock, RW_LOCK_EX)); #endif - - now = ut_time_us(NULL); - if (now - cache->last_read > CACHE_MIN_IDLE_TIME_US) { - - return(TRUE); - } - - return(FALSE); + return my_interval_timer() - cache->last_read > CACHE_MIN_IDLE_TIME_NS; } /*******************************************************************//** @@ -1497,14 +1484,12 @@ trx_i_s_cache_end_read( /*===================*/ trx_i_s_cache_t* cache) /*!< in: cache */ { - ullint now; - #ifdef UNIV_SYNC_DEBUG ut_a(rw_lock_own(&cache->rw_lock, RW_LOCK_SHARED)); #endif /* update cache last read time */ - now = ut_time_us(NULL); + const ulonglong now = my_interval_timer(); mutex_enter(&cache->last_read_mutex); cache->last_read = now; mutex_exit(&cache->last_read_mutex); diff --git a/storage/xtradb/trx/trx0purge.cc b/storage/xtradb/trx/trx0purge.cc index 16f985833b5..f4e4d2f42ea 100644 --- a/storage/xtradb/trx/trx0purge.cc +++ b/storage/xtradb/trx/trx0purge.cc @@ -146,7 +146,8 @@ trx_purge_sys_create( here only because the query threads code requires it. It is otherwise quite unnecessary. We should get rid of it eventually. */ purge_sys->trx->id = 0; - purge_sys->trx->start_time = ut_time(); + purge_sys->trx->start_time = time(NULL); + purge_sys->trx->start_time_micro = microsecond_interval_timer(); purge_sys->trx->state = TRX_STATE_ACTIVE; purge_sys->trx->op_info = "purge trx"; diff --git a/storage/xtradb/trx/trx0roll.cc b/storage/xtradb/trx/trx0roll.cc index 0d15fd77198..97f08d1fa0c 100644 --- a/storage/xtradb/trx/trx0roll.cc +++ b/storage/xtradb/trx/trx0roll.cc @@ -750,11 +750,11 @@ trx_roll_must_shutdown() return true; } - ib_time_t time = ut_time(); + time_t now = time(NULL); mutex_enter(&trx_sys->mutex); mutex_enter(&recv_sys->mutex); - if (recv_sys->report(time)) { + if (recv_sys->report(now)) { ulint n_trx = 0; ulonglong n_rows = 0; for (const trx_t* t = UT_LIST_GET_FIRST(trx_sys->rw_trx_list); diff --git a/storage/xtradb/trx/trx0trx.cc b/storage/xtradb/trx/trx0trx.cc index fc979a9bff8..e072976d6cd 100644 --- a/storage/xtradb/trx/trx0trx.cc +++ b/storage/xtradb/trx/trx0trx.cc @@ -749,7 +749,8 @@ trx_resurrect_insert( /* trx_start_low() is not called with resurrect, so need to initialize start time here.*/ if (trx->state != TRX_STATE_COMMITTED_IN_MEMORY) { - trx->start_time = ut_time(); + trx->start_time = time(NULL); + trx->start_time_micro = microsecond_interval_timer(); } if (undo->dict_operation) { @@ -835,7 +836,8 @@ trx_resurrect_update( start time here.*/ if (trx->state == TRX_STATE_ACTIVE || trx->state == TRX_STATE_PREPARED) { - trx->start_time = ut_time(); + trx->start_time = time(NULL); + trx->start_time_micro = microsecond_interval_timer(); } if (undo->dict_operation) { @@ -1104,10 +1106,11 @@ trx_start_low( mutex_exit(&trx_sys->mutex); - trx->start_time = ut_time(); + trx->start_time = time(NULL); - trx->start_time_micro = - trx->mysql_thd ? thd_query_start_micro(trx->mysql_thd) : 0; + trx->start_time_micro = trx->mysql_thd + ? thd_query_start_micro(trx->mysql_thd) + : microsecond_interval_timer(); MONITOR_INC(MONITOR_TRX_ACTIVE); } @@ -1795,21 +1798,15 @@ trx_commit_or_rollback_prepare( query thread to the suspended state */ if (trx->lock.que_state == TRX_QUE_LOCK_WAIT) { - - ulint sec; - ulint ms; - ib_uint64_t now; - ut_a(trx->lock.wait_thr != NULL); trx->lock.wait_thr->state = QUE_THR_SUSPENDED; trx->lock.wait_thr = NULL; if (UNIV_UNLIKELY(trx->take_stats)) { - ut_usectime(&sec, &ms); - now = (ib_uint64_t)sec * 1000000 + ms; - trx->lock_que_wait_timer - += (ulint) - (now - trx->lock_que_wait_ustarted); + trx->lock_que_wait_timer += static_cast<ulint>( + (my_interval_timer() + - trx->lock_que_wait_nstarted) + / 1000); } trx->lock.que_state = TRX_QUE_RUNNING; diff --git a/storage/xtradb/ut/ut0timer.cc b/storage/xtradb/ut/ut0timer.cc deleted file mode 100644 index 7d458040d15..00000000000 --- a/storage/xtradb/ut/ut0timer.cc +++ /dev/null @@ -1,91 +0,0 @@ -/***************************************************************************** - -Copyright (c) 2013, 2014, Facebook, Inc. All Rights Reserved. -Copyright (c) 2014, SkySQL Ab. All Rights Reserved. - -This program is free software; you can redistribute it and/or modify it under -the terms of the GNU General Public License as published by the Free Software -Foundation; version 2 of the License. - -This program is distributed in the hope that it will be useful, but WITHOUT -ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS -FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. - -You should have received a copy of the GNU General Public License along with -this program; if not, write to the Free Software Foundation, Inc., -51 Franklin Street, Fifth Floor, Boston, MA 02110-1335 USA - -*****************************************************************************/ - -/********************************************************************//** -@file ut/ut0timer.cc -Timer rountines - -Created 30/07/2014 Jan Lindström jan.lindstrom@skysql.com -modified from https://github.com/facebook/mysql-5.6/commit/c75a413edeb96eb99bf11d7269bdfea06f96d6b6 -*************************************************************************/ - -#include "data0type.h" -#include <my_rdtsc.h> -#include <ut0timer.h> - -/**************************************************************//** -Initial timer definition -@return 0 */ -static -ulonglong -ut_timer_none(void) -/*===============*/ -{ - return 0; -} - -/**************************************************************//** -Function pointer to point selected timer function. -@return timer current value */ -ulonglong (*ut_timer_now)(void) = &ut_timer_none; - -struct my_timer_unit_info ut_timer; - -extern MYSQL_PLUGIN_IMPORT MY_TIMER_INFO sys_timer_info; - -/**************************************************************//** -Sets up the data required for use of my_timer_* functions. -Selects the best timer by high frequency, and tight resolution. -Points my_timer_now() to the selected timer function. -Initializes my_timer struct to contain the info for selected timer.*/ -UNIV_INTERN -void -ut_init_timer(void) -/*===============*/ -{ - if (sys_timer_info.cycles.frequency > 1000000 && - sys_timer_info.cycles.resolution == 1) { - ut_timer = sys_timer_info.cycles; - ut_timer_now = &my_timer_cycles; - } else if (sys_timer_info.nanoseconds.frequency > 1000000 && - sys_timer_info.nanoseconds.resolution == 1) { - ut_timer = sys_timer_info.nanoseconds; - ut_timer_now = &my_timer_nanoseconds; - } else if (sys_timer_info.microseconds.frequency >= 1000000 && - sys_timer_info.microseconds.resolution == 1) { - ut_timer = sys_timer_info.microseconds; - ut_timer_now = &my_timer_microseconds; - - } else if (sys_timer_info.milliseconds.frequency >= 1000 && - sys_timer_info.milliseconds.resolution == 1) { - ut_timer = sys_timer_info.milliseconds; - ut_timer_now = &my_timer_milliseconds; - } else if (sys_timer_info.ticks.frequency >= 1000 && - /* Will probably be false */ - sys_timer_info.ticks.resolution == 1) { - ut_timer = sys_timer_info.ticks; - ut_timer_now = &my_timer_ticks; - } else { - /* None are acceptable, so leave it as "None", and fill in struct */ - ut_timer.frequency = 1; /* Avoid div-by-zero */ - ut_timer.overhead = 0; /* Since it doesn't do anything */ - ut_timer.resolution = 10; /* Another sign it's bad */ - ut_timer.routine = 0; /* None */ - } -} diff --git a/storage/xtradb/ut/ut0ut.cc b/storage/xtradb/ut/ut0ut.cc index eda3921c5de..a9f24fcf18a 100644 --- a/storage/xtradb/ut/ut0ut.cc +++ b/storage/xtradb/ut/ut0ut.cc @@ -45,160 +45,6 @@ Created 5/11/1994 Heikki Tuuri # include "ha_prototypes.h" # include "mysql_com.h" /* NAME_LEN */ # include <string> -#endif /* UNIV_HOTBACKUP */ - -#ifdef __WIN__ -#include <innodb_priv.h> /* For sql_print_error */ -typedef VOID(WINAPI *time_fn)(LPFILETIME); -static time_fn ut_get_system_time_as_file_time = GetSystemTimeAsFileTime; - -/*****************************************************************//** -NOTE: The Windows epoch starts from 1601/01/01 whereas the Unix -epoch starts from 1970/1/1. For selection of constant see: -http://support.microsoft.com/kb/167296/ */ -#define WIN_TO_UNIX_DELTA_USEC ((ib_int64_t) 11644473600000000ULL) - - -/** -Initialise highest available time resolution API on Windows -@return 0 if all OK else -1 */ -int -ut_win_init_time() -{ - HMODULE h = LoadLibrary("kernel32.dll"); - if (h != NULL) - { - time_fn pfn = (time_fn)GetProcAddress(h, "GetSystemTimePreciseAsFileTime"); - if (pfn != NULL) - { - ut_get_system_time_as_file_time = pfn; - } - return false; - } - DWORD error = GetLastError(); - sql_print_error( - "LoadLibrary(\"kernel32.dll\") failed: GetLastError returns %lu", error); - return(-1); -} - -/*****************************************************************//** -This is the Windows version of gettimeofday(2). -@return 0 if all OK else -1 */ -static -int -ut_gettimeofday( -/*============*/ - struct timeval* tv, /*!< out: Values are relative to Unix epoch */ - void* tz) /*!< in: not used */ -{ - FILETIME ft; - ib_int64_t tm; - - if (!tv) { - errno = EINVAL; - return(-1); - } - - ut_get_system_time_as_file_time(&ft); - - tm = (ib_int64_t) ft.dwHighDateTime << 32; - tm |= ft.dwLowDateTime; - - ut_a(tm >= 0); /* If tm wraps over to negative, the quotient / 10 - does not work */ - - tm /= 10; /* Convert from 100 nsec periods to usec */ - - /* If we don't convert to the Unix epoch the value for - struct timeval::tv_sec will overflow.*/ - tm -= WIN_TO_UNIX_DELTA_USEC; - - tv->tv_sec = (long) (tm / 1000000L); - tv->tv_usec = (long) (tm % 1000000L); - - return(0); -} -#else -/** An alias for gettimeofday(2). On Microsoft Windows, we have to -reimplement this function. */ -#define ut_gettimeofday gettimeofday -#endif - -/**********************************************************//** -Returns system time. We do not specify the format of the time returned: -the only way to manipulate it is to use the function ut_difftime. -@return system time */ -UNIV_INTERN -ib_time_t -ut_time(void) -/*=========*/ -{ - return(time(NULL)); -} - -#ifndef UNIV_HOTBACKUP -/**********************************************************//** -Returns system time. -Upon successful completion, the value 0 is returned; otherwise the -value -1 is returned and the global variable errno is set to indicate the -error. -@return 0 on success, -1 otherwise */ -UNIV_INTERN -int -ut_usectime( -/*========*/ - ulint* sec, /*!< out: seconds since the Epoch */ - ulint* ms) /*!< out: microseconds since the Epoch+*sec */ -{ - struct timeval tv; - int ret; - int errno_gettimeofday; - int i; - - for (i = 0; i < 10; i++) { - - ret = ut_gettimeofday(&tv, NULL); - - if (ret == -1) { - errno_gettimeofday = errno; - ut_print_timestamp(stderr); - fprintf(stderr, " InnoDB: gettimeofday(): %s\n", - strerror(errno_gettimeofday)); - os_thread_sleep(100000); /* 0.1 sec */ - errno = errno_gettimeofday; - } else { - break; - } - } - - if (ret != -1) { - *sec = (ulint) tv.tv_sec; - *ms = (ulint) tv.tv_usec; - } - - return(ret); -} - -/**********************************************************//** -Returns the number of microseconds since epoch. Similar to -time(3), the return value is also stored in *tloc, provided -that tloc is non-NULL. -@return us since epoch */ -UNIV_INTERN -ullint -ut_time_us( -/*=======*/ - ullint* tloc) /*!< out: us since epoch, if non-NULL */ -{ - ullint us = my_interval_timer() / 1000; - - if (tloc != NULL) { - *tloc = us; - } - - return(us); -} - /**********************************************************//** Returns the number of milliseconds since some epoch. The value may wrap around. It should only be used for heuristic @@ -212,20 +58,6 @@ ut_time_ms(void) return static_cast<ulint>(my_interval_timer() / 1000000); } #endif /* !UNIV_HOTBACKUP */ - -/**********************************************************//** -Returns the difference of two times in seconds. -@return time2 - time1 expressed in seconds */ -UNIV_INTERN -double -ut_difftime( -/*========*/ - ib_time_t time2, /*!< in: time */ - ib_time_t time1) /*!< in: time */ -{ - return(difftime(time2, time1)); -} - #endif /* !UNIV_INNOCHECKSUM */ /**********************************************************//** @@ -368,43 +200,6 @@ ut_sprintf_timestamp_without_extra_chars( cal_tm_ptr->tm_sec); #endif } - -/**********************************************************//** -Returns current year, month, day. */ -UNIV_INTERN -void -ut_get_year_month_day( -/*==================*/ - ulint* year, /*!< out: current year */ - ulint* month, /*!< out: month */ - ulint* day) /*!< out: day */ -{ -#ifdef __WIN__ - SYSTEMTIME cal_tm; - - GetLocalTime(&cal_tm); - - *year = (ulint) cal_tm.wYear; - *month = (ulint) cal_tm.wMonth; - *day = (ulint) cal_tm.wDay; -#else - struct tm* cal_tm_ptr; - time_t tm; - -#ifdef HAVE_LOCALTIME_R - struct tm cal_tm; - time(&tm); - localtime_r(&tm, &cal_tm); - cal_tm_ptr = &cal_tm; -#else - time(&tm); - cal_tm_ptr = localtime(&tm); -#endif - *year = (ulint) cal_tm_ptr->tm_year + 1900; - *month = (ulint) cal_tm_ptr->tm_mon + 1; - *day = (ulint) cal_tm_ptr->tm_mday; -#endif -} #endif /* UNIV_HOTBACKUP */ #ifndef UNIV_HOTBACKUP diff --git a/storage/xtradb/ut/ut0wqueue.cc b/storage/xtradb/ut/ut0wqueue.cc index d5e1c52f0f2..99cecdd6317 100644 --- a/storage/xtradb/ut/ut0wqueue.cc +++ b/storage/xtradb/ut/ut0wqueue.cc @@ -126,7 +126,7 @@ ib_wqueue_timedwait( /*================*/ /* out: work item or NULL on timeout*/ ib_wqueue_t* wq, /* in: work queue */ - ib_time_t wait_in_usecs) /* in: wait time in micro seconds */ + ulint wait_in_usecs) /* in: wait time in micro seconds */ { ib_list_node_t* node = NULL; |