[PATCH] MDEV-31761: mariadb-binlog prints fractional timestamp part incorrectly
Fractional part < 100000 microseconds was printed without leading zeros, causing such timestamps to be applied incorrectly in mariadb-binlog | mysql Signed-off-by: Kristian Nielsen <knielsen@knielsen-hq.org> --- mysql-test/main/mysqlbinlog.result | 26 ++++++++++++++++++++++++ mysql-test/main/mysqlbinlog.test | 32 ++++++++++++++++++++++++++++++ sql/log_event_client.cc | 7 +++++-- 3 files changed, 63 insertions(+), 2 deletions(-) diff --git a/mysql-test/main/mysqlbinlog.result b/mysql-test/main/mysqlbinlog.result index c6d9ef97229..76ded3d31f8 100644 --- a/mysql-test/main/mysqlbinlog.result +++ b/mysql-test/main/mysqlbinlog.result @@ -1286,3 +1286,29 @@ ERROR: Bad syntax in rewrite-db: empty FROM db ERROR: Bad syntax in rewrite-db: empty FROM db +# +# MDEV-31761: Timestamp is written into binary log incorrectly +# +SET SESSION binlog_format= MIXED; +RESET MASTER; +CREATE TABLE t (a INT, +b TIMESTAMP(6) DEFAULT CURRENT_TIMESTAMP(6) ON UPDATE CURRENT_TIMESTAMP(6)); +set SESSION timestamp= 1689978980.012345; +INSERT INTO t (a) VALUES (1); +SELECT * from t; +a b +1 2023-07-22 00:36:20.012345 +FLUSH BINARY LOGS; +SET SESSION timestamp= 1689978980.567890; +SET SESSION binlog_format= ROW; +UPDATE t SET a = 2; +FLUSH BINARY LOGS; +SET SESSION binlog_format= STATEMENT; +DROP TABLE t; +SELECT * FROM t; +a b +1 2023-07-22 00:36:20.012345 +SELECT * FROM t; +a b +2 2023-07-22 00:36:20.567890 +DROP TABLE t; diff --git a/mysql-test/main/mysqlbinlog.test b/mysql-test/main/mysqlbinlog.test index 22a85393a35..1747d55d29d 100644 --- a/mysql-test/main/mysqlbinlog.test +++ b/mysql-test/main/mysqlbinlog.test @@ -637,3 +637,35 @@ FLUSH LOGS; --exec $MYSQL_BINLOG --rewrite-db=" ->" --short-form $MYSQLD_DATADIR/master-bin.000001 2>&1 --exec $MYSQL_BINLOG --rewrite-db=" test -> foo " --short-form $MYSQLD_DATADIR/master-bin.000001 > /dev/null 2> $MYSQLTEST_VARDIR/tmp/mysqlbinlog.warn + + +--echo # +--echo # MDEV-31761: Timestamp is written into binary log incorrectly +--echo # + +SET SESSION binlog_format= MIXED; + +RESET MASTER; +CREATE TABLE t (a INT, + b TIMESTAMP(6) DEFAULT CURRENT_TIMESTAMP(6) ON UPDATE CURRENT_TIMESTAMP(6)); +set SESSION timestamp= 1689978980.012345; +INSERT INTO t (a) VALUES (1); +SELECT * from t; +FLUSH BINARY LOGS; +SET SESSION timestamp= 1689978980.567890; +SET SESSION binlog_format= ROW; +UPDATE t SET a = 2; +FLUSH BINARY LOGS; +SET SESSION binlog_format= STATEMENT; + +# Replay to see that timestamps are applied correctly. +# The bug was that leading zeros on the fractional part were not included in +# the mysqlbinlog output, so 1689978980.012345 was applied as 1689978980.12345. + +DROP TABLE t; +--let $datadir= `select @@datadir` +--exec $MYSQL_BINLOG $datadir/master-bin.000001 | $MYSQL test +SELECT * FROM t; +--exec $MYSQL_BINLOG $datadir/master-bin.000002 | $MYSQL test +SELECT * FROM t; +DROP TABLE t; diff --git a/sql/log_event_client.cc b/sql/log_event_client.cc index 11fabbbca39..720cc5ab611 100644 --- a/sql/log_event_client.cc +++ b/sql/log_event_client.cc @@ -1851,8 +1851,11 @@ bool Query_log_event::print_query_header(IO_CACHE* file, end=int10_to_str((long) when, strmov(buff,"SET TIMESTAMP="),10); if (when_sec_part && when_sec_part <= TIME_MAX_SECOND_PART) { - *end++= '.'; - end=int10_to_str(when_sec_part, end, 10); + char buff2[1 + 6 + 1]; + /* Ensure values < 100000 are printed with leading zeros, MDEV-31761. */ + snprintf(buff2, sizeof(buff2), ".%06lu", when_sec_part); + DBUG_ASSERT(strlen(buff2) == 1 + 6); + end= strmov(end, buff2); } end= strmov(end, print_event_info->delimiter); *end++='\n'; -- 2.39.5
participants (1)
-
Kristian Nielsen