summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorBrandon Nesterenko <brandon.nesterenko@mariadb.com>2021-06-03 11:24:34 -0600
committerBrandon Nesterenko <brandon.nesterenko@mariadb.com>2021-06-23 08:35:30 -0600
commit79d2cd9c71cc3b640cd38ceadd9541703ad5a62c (patch)
tree2f39b578be02ad747542c082e7c04bff8b113f68
parent1deb630484caf572c9cdf1b3c2d5bdd4eedc51d0 (diff)
downloadmariadb-git-bb-10.3-MDEV-25277.tar.gz
MDEV-25277: mysqlbinlog --verbose cannot read row events with compressed columns: Don't know how to handle column type: 140bb-10.3-MDEV-25277
Problem: ======= Mysqlbinlog cannot show the type of a compressed column when two levels of verbosity is provided. Solution: ======== Extend the log event printing logic to handle and tag compressed types. Behavioral Changes: ================== Old: When mysqlbinlog is called in verbose mode and the database uses compressed columns, an error is returned to the user. New: The output will append “ COMPRESSED” on the type of compressed columns Reviewed By: =========== <TODO>
-rw-r--r--mysql-test/suite/binlog/r/binlog_verbose_compressed_fields.result85
-rw-r--r--mysql-test/suite/binlog/t/binlog_verbose_compressed_fields-master.opt1
-rw-r--r--mysql-test/suite/binlog/t/binlog_verbose_compressed_fields.test56
-rw-r--r--sql/log_event.cc17
4 files changed, 154 insertions, 5 deletions
diff --git a/mysql-test/suite/binlog/r/binlog_verbose_compressed_fields.result b/mysql-test/suite/binlog/r/binlog_verbose_compressed_fields.result
new file mode 100644
index 00000000000..9f1c45a5b31
--- /dev/null
+++ b/mysql-test/suite/binlog/r/binlog_verbose_compressed_fields.result
@@ -0,0 +1,85 @@
+#
+# Preparatory cleanup.
+#
+DROP TABLE IF EXISTS t1;
+#
+# We need a fixed timestamp to avoid varying results.
+#
+SET timestamp=1000000000;
+#
+# Delete all existing binary logs.
+#
+RESET MASTER;
+CREATE TABLE t1 (a TEXT, ac TEXT COMPRESSED, b TINYTEXT, bc TINYTEXT COMPRESSED, c MEDIUMTEXT, cc MEDIUMTEXT COMPRESSED, d LONGTEXT, dc LONGTEXT COMPRESSED, e VARCHAR(10), ec VARCHAR(10) COMPRESSED);
+INSERT INTO t1 VALUES ('mya', 'myac', 'myb', 'mybc', 'myc', 'mycc', 'myd', 'mydc', 'mye', 'myec');
+FLUSH BINARY LOGS;
+# Running mysqlbinlog --base64-output=decode-rows -vv <binlog>
+/*!50530 SET @@SESSION.PSEUDO_SLAVE_MODE=1*/;
+/*!40019 SET @@session.max_insert_delayed_threads=0*/;
+/*!50003 SET @OLD_COMPLETION_TYPE=@@COMPLETION_TYPE,COMPLETION_TYPE=0*/;
+DELIMITER /*!*/;
+# at #
+#010909 9:46:40 server id 1 end_log_pos # CRC32 XXX Start: binlog v 4, server v #.##.## created 010909 9:46:40 at startup
+ROLLBACK/*!*/;
+# at #
+#010909 9:46:40 server id 1 end_log_pos # CRC32 XXX Gtid list []
+# at #
+#010909 9:46:40 server id 1 end_log_pos # CRC32 XXX Binlog checkpoint master-bin.000001
+# at #
+#010909 9:46:40 server id 1 end_log_pos # CRC32 XXX GTID 0-1-1 ddl
+/*!100101 SET @@session.skip_parallel_replication=0*//*!*/;
+/*!100001 SET @@session.gtid_domain_id=0*//*!*/;
+/*!100001 SET @@session.server_id=1*//*!*/;
+/*!100001 SET @@session.gtid_seq_no=1*//*!*/;
+# at #
+#010909 9:46:40 server id 1 end_log_pos # CRC32 XXX Query thread_id=# exec_time=# error_code=0
+use `test`/*!*/;
+SET TIMESTAMP=1000000000/*!*/;
+SET @@session.pseudo_thread_id=#/*!*/;
+SET @@session.foreign_key_checks=1, @@session.sql_auto_is_null=0, @@session.unique_checks=1, @@session.autocommit=1, @@session.check_constraint_checks=1/*!*/;
+SET @@session.sql_mode=1411383296/*!*/;
+SET @@session.auto_increment_increment=1, @@session.auto_increment_offset=1/*!*/;
+/*!\C latin1 *//*!*/;
+SET @@session.character_set_client=X,@@session.collation_connection=X,@@session.collation_server=X/*!*/;
+SET @@session.lc_time_names=0/*!*/;
+SET @@session.collation_database=DEFAULT/*!*/;
+CREATE TABLE t1 (a TEXT, ac TEXT COMPRESSED, b TINYTEXT, bc TINYTEXT COMPRESSED, c MEDIUMTEXT, cc MEDIUMTEXT COMPRESSED, d LONGTEXT, dc LONGTEXT COMPRESSED, e VARCHAR(10), ec VARCHAR(10) COMPRESSED)
+/*!*/;
+# at #
+#010909 9:46:40 server id 1 end_log_pos # CRC32 XXX GTID 0-1-2
+/*!100001 SET @@session.gtid_seq_no=2*//*!*/;
+START TRANSACTION
+/*!*/;
+# at #
+# at #
+#010909 9:46:40 server id 1 end_log_pos # CRC32 XXX Annotate_rows:
+#Q> INSERT INTO t1 VALUES ('mya', 'myac', 'myb', 'mybc', 'myc', 'mycc', 'myd', 'mydc', 'mye', 'myec')
+#010909 9:46:40 server id 1 end_log_pos # CRC32 XXX Table_map: `test`.`t1` mapped to number #
+# at #
+#010909 9:46:40 server id 1 end_log_pos # CRC32 XXX Write_rows: table id # flags: STMT_END_F
+### INSERT INTO `test`.`t1`
+### SET
+### @1='mya' /* BLOB/TEXT meta=2 nullable=1 is_null=0 */
+### @2='\x00myac' /* BLOB/TEXT COMPRESSED meta=2 nullable=1 is_null=0 */
+### @3='myb' /* TINYBLOB/TINYTEXT meta=1 nullable=1 is_null=0 */
+### @4='\x00mybc' /* TINYBLOB/TINYTEXT COMPRESSED meta=1 nullable=1 is_null=0 */
+### @5='myc' /* MEDIUMBLOB/MEDIUMTEXT meta=3 nullable=1 is_null=0 */
+### @6='\x00mycc' /* MEDIUMBLOB/MEDIUMTEXT COMPRESSED meta=3 nullable=1 is_null=0 */
+### @7='myd' /* LONGBLOB/LONGTEXT meta=4 nullable=1 is_null=0 */
+### @8='\x00mydc' /* LONGBLOB/LONGTEXT COMPRESSED meta=4 nullable=1 is_null=0 */
+### @9='mye' /* VARSTRING(10) meta=10 nullable=1 is_null=0 */
+### @10='\x00myec' /* VARSTRING(11) COMPRESSED meta=11 nullable=1 is_null=0 */
+# Number of rows: 1
+# at #
+#010909 9:46:40 server id 1 end_log_pos # CRC32 XXX Query thread_id=# exec_time=# error_code=0
+SET TIMESTAMP=1000000000/*!*/;
+COMMIT
+/*!*/;
+# at #
+#010909 9:46:40 server id 1 end_log_pos # CRC32 XXX Rotate to master-bin.000002 pos: 4
+DELIMITER ;
+# End of log file
+ROLLBACK /* added by mysqlbinlog */;
+/*!50003 SET COMPLETION_TYPE=@OLD_COMPLETION_TYPE*/;
+/*!50530 SET @@SESSION.PSEUDO_SLAVE_MODE=0*/;
+DROP TABLE t1;
diff --git a/mysql-test/suite/binlog/t/binlog_verbose_compressed_fields-master.opt b/mysql-test/suite/binlog/t/binlog_verbose_compressed_fields-master.opt
new file mode 100644
index 00000000000..7377dd80169
--- /dev/null
+++ b/mysql-test/suite/binlog/t/binlog_verbose_compressed_fields-master.opt
@@ -0,0 +1 @@
+--timezone=GMT-8
diff --git a/mysql-test/suite/binlog/t/binlog_verbose_compressed_fields.test b/mysql-test/suite/binlog/t/binlog_verbose_compressed_fields.test
new file mode 100644
index 00000000000..80fc8ad177b
--- /dev/null
+++ b/mysql-test/suite/binlog/t/binlog_verbose_compressed_fields.test
@@ -0,0 +1,56 @@
+#
+# Purpose:
+#
+# This test validates that mysqlbinlog is able to annotate
+# compressed column types when two levels of verbosity is
+# provided
+#
+#
+# Methodology:
+#
+# Validate that the output from mysqlbinlog -vv after
+# creating and inserting into a table with compressed and
+# uncompressed fields correctly annotates which columns are
+# compressed
+#
+#
+# References:
+# MDEV-25277: mysqlbinlog --verbose cannot read row events
+# with compressed columns: Don't know how to
+# handle column type: 140
+#
+--source include/have_binlog_format_row.inc
+
+--echo #
+--echo # Preparatory cleanup.
+--echo #
+--disable_warnings
+DROP TABLE IF EXISTS t1;
+--enable_warnings
+
+--echo #
+--echo # We need a fixed timestamp to avoid varying results.
+--echo #
+SET timestamp=1000000000;
+
+--echo #
+--echo # Delete all existing binary logs.
+--echo #
+RESET MASTER;
+
+CREATE TABLE t1 (a TEXT, ac TEXT COMPRESSED, b TINYTEXT, bc TINYTEXT COMPRESSED, c MEDIUMTEXT, cc MEDIUMTEXT COMPRESSED, d LONGTEXT, dc LONGTEXT COMPRESSED, e VARCHAR(10), ec VARCHAR(10) COMPRESSED);
+
+INSERT INTO t1 VALUES ('mya', 'myac', 'myb', 'mybc', 'myc', 'mycc', 'myd', 'mydc', 'mye', 'myec');
+
+FLUSH BINARY LOGS;
+
+--let $binlog= query_get_value(SHOW BINARY LOGS, Log_name, 1)
+--let $datadir= `SELECT @@datadir`
+
+--echo # Running mysqlbinlog --base64-output=decode-rows -vv <binlog>
+--replace_result $MYSQLTEST_VARDIR MYSQLTEST_VARDIR
+--replace_regex /SQL_LOAD_MB-[0-9]-[0-9]/SQL_LOAD_MB-#-#/ /exec_time=[0-9]*/exec_time=#/ /end_log_pos [0-9]*/end_log_pos #/ /# at [0-9]*/# at #/ /Xid = [0-9]*/Xid = #/ /thread_id=[0-9]*/thread_id=#/ /table id [0-9]*/table id #/ /mapped to number [0-9]*/mapped to number #/ /server v [^ ]*/server v #.##.##/ /CRC32 0x[0-9a-f]*/CRC32 XXX/ /collation_server=[0-9]+/collation_server=X/ /character_set_client=[0-9]+/character_set_client=X/ /collation_connection=[0-9]+/collation_connection=X/
+--exec $MYSQL_BINLOG --base64-output=decode-rows -vv $datadir/$binlog
+
+# Cleanup
+DROP TABLE t1; \ No newline at end of file
diff --git a/sql/log_event.cc b/sql/log_event.cc
index c82a721708b..96db9d1d40d 100644
--- a/sql/log_event.cc
+++ b/sql/log_event.cc
@@ -2985,10 +2985,12 @@ log_event_print_value(IO_CACHE *file, PRINT_EVENT_INFO *print_event_info,
my_b_write_bit(file, ptr , (meta & 0xFF) * 8);
return meta & 0xFF;
+ case MYSQL_TYPE_BLOB_COMPRESSED:
case MYSQL_TYPE_BLOB:
switch (meta) {
case 1:
- strmake(typestr, "TINYBLOB/TINYTEXT", typestr_length);
+ my_snprintf(typestr, typestr_length, "TINYBLOB/TINYTEXT%s",
+ type == MYSQL_TYPE_BLOB_COMPRESSED ? " COMPRESSED" : "");
if (!ptr)
goto return_null;
@@ -2996,7 +2998,8 @@ log_event_print_value(IO_CACHE *file, PRINT_EVENT_INFO *print_event_info,
my_b_write_quoted(file, ptr + 1, length);
return length + 1;
case 2:
- strmake(typestr, "BLOB/TEXT", typestr_length);
+ my_snprintf(typestr, typestr_length, "BLOB/TEXT%s",
+ type == MYSQL_TYPE_BLOB_COMPRESSED ? " COMPRESSED" : "");
if (!ptr)
goto return_null;
@@ -3004,7 +3007,8 @@ log_event_print_value(IO_CACHE *file, PRINT_EVENT_INFO *print_event_info,
my_b_write_quoted(file, ptr + 2, length);
return length + 2;
case 3:
- strmake(typestr, "MEDIUMBLOB/MEDIUMTEXT", typestr_length);
+ my_snprintf(typestr, typestr_length, "MEDIUMBLOB/MEDIUMTEXT%s",
+ type == MYSQL_TYPE_BLOB_COMPRESSED ? " COMPRESSED" : "");
if (!ptr)
goto return_null;
@@ -3012,7 +3016,8 @@ log_event_print_value(IO_CACHE *file, PRINT_EVENT_INFO *print_event_info,
my_b_write_quoted(file, ptr + 3, length);
return length + 3;
case 4:
- strmake(typestr, "LONGBLOB/LONGTEXT", typestr_length);
+ my_snprintf(typestr, typestr_length, "LONGBLOB/LONGTEXT%s",
+ type == MYSQL_TYPE_BLOB_COMPRESSED ? " COMPRESSED" : "");
if (!ptr)
goto return_null;
@@ -3024,10 +3029,12 @@ log_event_print_value(IO_CACHE *file, PRINT_EVENT_INFO *print_event_info,
return 0;
}
+ case MYSQL_TYPE_VARCHAR_COMPRESSED:
case MYSQL_TYPE_VARCHAR:
case MYSQL_TYPE_VAR_STRING:
length= meta;
- my_snprintf(typestr, typestr_length, "VARSTRING(%d)", length);
+ my_snprintf(typestr, typestr_length, "VARSTRING(%d)%s", length,
+ type == MYSQL_TYPE_VARCHAR_COMPRESSED ? " COMPRESSED" : "");
if (!ptr)
goto return_null;