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>2023-01-11 10:37:49 -0700
commitb194c83b7bd2f4e861fdce041a9ea3de18f4d227 (patch)
tree297f216dc7e0a82395f80194578425f28f4bc271
parent53c4be7bc02949e178b31fd89c4b196dd7f24bd0 (diff)
downloadmariadb-git-b194c83b7bd2f4e861fdce041a9ea3de18f4d227.tar.gz
MDEV-25277: mysqlbinlog --verbose cannot read row events with compressed columns: Don't know how to handle column type: 140
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 =========== Andrei Elkin <andrei.elkin@mariadb.com>
-rw-r--r--mysql-test/suite/binlog/r/binlog_verbose_compressed_fields.result15
-rw-r--r--mysql-test/suite/binlog/t/binlog_verbose_compressed_fields.test70
-rw-r--r--sql/log_event.cc17
3 files changed, 97 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..6ee11754935
--- /dev/null
+++ b/mysql-test/suite/binlog/r/binlog_verbose_compressed_fields.result
@@ -0,0 +1,15 @@
+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);
+# Isolate row event into its own binary log
+FLUSH BINARY LOGS;
+INSERT INTO t1 VALUES ('mya', 'myac', 'myb', 'mybc', 'myc', 'mycc', 'myd', 'mydc', 'mye', 'myec');
+FLUSH BINARY LOGS;
+# MYSQLBINLOG --base64-output=decode-rows -vv datadir/binlog_file --result-file=result_binlog
+include/assert_grep.inc [Ensure compressed TEXT fields are annotated correctly]
+include/assert_grep.inc [Ensure compressed TINYTEXT fields are annotated correctly]
+include/assert_grep.inc [Ensure compressed MEDIUMTEXT fields are annotated correctly]
+include/assert_grep.inc [Ensure compressed LONGTEXT fields are annotated correctly]
+include/assert_grep.inc [Ensure compressed VARSTRING fields are annotated correctly]
+include/assert_grep.inc [Ensure COMPRESSED only shows up for corresponding fields]
+include/assert_grep.inc [Ensure non-compressed TEXT fields are annotated correctly]
+include/assert_grep.inc [Ensure non-compressed VARSTRING fields are annotated correctly]
+DROP TABLE t1;
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..8cbcdbef601
--- /dev/null
+++ b/mysql-test/suite/binlog/t/binlog_verbose_compressed_fields.test
@@ -0,0 +1,70 @@
+#
+# Purpose:
+# This test validates that mysqlbinlog is able to annotate compressed column
+# types with two levels of verbosity.
+#
+# 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
+
+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);
+
+--echo # Isolate row event into its own binary log
+FLUSH BINARY LOGS;
+INSERT INTO t1 VALUES ('mya', 'myac', 'myb', 'mybc', 'myc', 'mycc', 'myd', 'mydc', 'mye', 'myec');
+FLUSH BINARY LOGS;
+
+--let $binlog_file= query_get_value(SHOW BINARY LOGS, Log_name, 2)
+--let $datadir= `SELECT @@datadir`
+--let $result_binlog= $MYSQLTEST_VARDIR/tmp/$binlog_file
+
+--echo # MYSQLBINLOG --base64-output=decode-rows -vv datadir/binlog_file --result-file=result_binlog
+--exec $MYSQL_BINLOG --base64-output=decode-rows -vv $datadir/$binlog_file --result-file=$result_binlog
+
+--let $assert_file= $result_binlog
+--let $assert_count= 1
+
+--let $assert_text= Ensure compressed TEXT fields are annotated correctly
+--let $assert_select=\WTEXT COMPRESSED
+--source include/assert_grep.inc
+
+--let $assert_text= Ensure compressed TINYTEXT fields are annotated correctly
+--let $assert_select=\WTINYTEXT COMPRESSED
+--source include/assert_grep.inc
+
+--let $assert_text= Ensure compressed MEDIUMTEXT fields are annotated correctly
+--let $assert_select=\WMEDIUMTEXT COMPRESSED
+--source include/assert_grep.inc
+
+--let $assert_text= Ensure compressed LONGTEXT fields are annotated correctly
+--let $assert_select=\WLONGTEXT COMPRESSED
+--source include/assert_grep.inc
+
+--let $assert_text= Ensure compressed VARSTRING fields are annotated correctly
+--let $assert_select=\WVARSTRING\(\d+\) COMPRESSED
+--source include/assert_grep.inc
+
+--let $assert_text= Ensure COMPRESSED only shows up for corresponding fields
+--let $assert_count= 5
+--let $assert_select= COMPRESSED
+--source include/assert_grep.inc
+
+--let $assert_text= Ensure non-compressed TEXT fields are annotated correctly
+--let $assert_count= 8
+--let $assert_select=/*.*TEXT
+--source include/assert_grep.inc
+
+--let $assert_text= Ensure non-compressed VARSTRING fields are annotated correctly
+--let $assert_count= 2
+--let $assert_select=/*.*VARSTRING
+--source include/assert_grep.inc
+
+# Cleanup
+DROP TABLE t1;
diff --git a/sql/log_event.cc b/sql/log_event.cc
index a5a31d57ed2..b2b1adc1558 100644
--- a/sql/log_event.cc
+++ b/sql/log_event.cc
@@ -2986,10 +2986,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;
@@ -2997,7 +2999,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;
@@ -3005,7 +3008,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;
@@ -3013,7 +3017,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;
@@ -3025,10 +3030,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;