Browse Source
MDEV-28487: sequences not respect value of binlog_row_image with select nextval(seq_gen)
MDEV-28487: sequences not respect value of binlog_row_image with select nextval(seq_gen)
Problem: ======== When using sequences, the function sequence_definition::write(TABLE *table, bool all_fields) is used to save DML/DDL updates to sequence tables (e.g. nextval, setval, and alter). Prior to this patch, the value all_fields was always false when invoked via nextval and setval, which forced the bitmap to only include changed columns. Solution: ======== Change all_fields when invoked via nextval and setval to be reliant on binlog_row_image, such that it is false when binlog_row_image is MINIMAL, and true otherwise. Reviewed By: =========== Andrei Elkin <andrei.elkin@mariadb.com>pull/2184/head
6 changed files with 2546 additions and 2 deletions
-
72mysql-test/include/ensure_binlog_row_event_columns.inc
-
90mysql-test/suite/rpl/include/rpl_row_img_sequence.inc
-
2290mysql-test/suite/rpl/r/rpl_row_img_sequence.result
-
21mysql-test/suite/rpl/t/rpl_row_img_sequence.cnf
-
65mysql-test/suite/rpl/t/rpl_row_img_sequence.test
-
10sql/sql_sequence.cc
@ -0,0 +1,72 @@ |
|||
# |
|||
# Helper file to ensure that a binary log file properly writes the expected |
|||
# fields based on the binlog_row_image value. |
|||
# |
|||
# ==== Usage ==== |
|||
# |
|||
# --let $expected_columns= (COLUMN_IDS) |
|||
# --let $binlog_filename= FILENAME |
|||
# --source include/count_binlog_row_event_columns.inc |
|||
# |
|||
# Parameters: |
|||
# expected_columns (list<uint>, in) : A list of positive integers which |
|||
# correspond to the column numbers that should be output in a binary |
|||
# log's write_rows event |
|||
# binlog_filename (string, in) : Name of the binary log file to analyze |
|||
# |
|||
|
|||
if (!$expected_columns) |
|||
{ |
|||
--die expected_columns parameter is required but was not set |
|||
} |
|||
|
|||
if (!$binlog_filename) |
|||
{ |
|||
--die binlog_filename parameter is required but was not set |
|||
} |
|||
|
|||
--let $include_filename= ensure_binlog_row_event_columns.inc [$expected_columns] |
|||
--source include/begin_include_file.inc |
|||
|
|||
--let $assert_file=$MYSQLTEST_VARDIR/tmp/binlog_decoded.out |
|||
--let mysqld_datadir=`select @@datadir` |
|||
|
|||
--echo # MYSQL_BINLOG mysqld_datadir/binlog_filename -vv > assert_file |
|||
--exec $MYSQL_BINLOG $mysqld_datadir/$binlog_filename -vv > $assert_file |
|||
|
|||
--echo # Verifying all expected column ids appear in binlog event output.. |
|||
--let num_cols_found=0 |
|||
--let last_expected_col= `SELECT GREATEST $expected_columns` |
|||
--let i= 1 |
|||
while($i <= $last_expected_col) |
|||
{ |
|||
# By default, assume the column is not expected to be in the binary log. |
|||
# If the column id is set in expected_columns, then override assertion |
|||
# parameters. |
|||
--let assert_count= 0 |
|||
--let assert_text= Column @$i should not be in binary log |
|||
|
|||
if (`SELECT $i IN $expected_columns`) |
|||
{ |
|||
--let assert_count= 1 |
|||
--let assert_text= Column @$i should be in binary log |
|||
|
|||
--inc $num_cols_found |
|||
} |
|||
|
|||
--let assert_select= @$i |
|||
--source include/assert_grep.inc |
|||
|
|||
--inc $i |
|||
} |
|||
--echo # ..success |
|||
|
|||
--echo # Verifying only expected column ids appear in binlog event output.. |
|||
--let assert_count= $num_cols_found |
|||
--let assert_text= The binlog event should only have $num_cols_found columns |
|||
--let assert_select= @[\d]+ |
|||
--source include/assert_grep.inc |
|||
--echo # ..success |
|||
|
|||
--let $include_filename= ensure_binlog_row_event_columns.inc [$expected_columns] |
|||
--source include/end_include_file.inc |
|||
@ -0,0 +1,90 @@ |
|||
# |
|||
# This include file validates that sequence events are properly binlogged |
|||
# and replicated. |
|||
# |
|||
# Parameters: |
|||
# expected_columns (list<uint>, in) : A list of positive integers which |
|||
# correspond to the column numbers that should be output in a binary |
|||
# log's write_rows event |
|||
# |
|||
|
|||
--echo # Create sequences with specific engines per server |
|||
--connection server_1 |
|||
--eval SET STATEMENT sql_log_bin=0 FOR create sequence s1 cache=0 engine=$server_1_engine |
|||
--source include/save_master_gtid.inc |
|||
|
|||
--connection server_2 |
|||
--eval SET STATEMENT sql_log_bin=0 FOR create sequence s1 cache=0 engine=$server_2_engine |
|||
--source include/sync_with_master_gtid.inc |
|||
|
|||
--connection server_3 |
|||
--eval SET STATEMENT sql_log_bin=0 FOR create sequence s1 cache=0 engine=$server_3_engine |
|||
--source include/sync_with_master_gtid.inc |
|||
|
|||
|
|||
--echo # Pt.1 Ensure SETVAL replicates and binlogs correctly |
|||
--connection server_1 |
|||
SELECT SETVAL(s1, 10); |
|||
--source include/save_master_gtid.inc |
|||
|
|||
--echo # Validate SETVAL replicated correctly to other servers |
|||
--connection server_3 |
|||
--source include/sync_with_master_gtid.inc |
|||
--let $diff_tables= server_1:test.s1,server_2:test.s1,server_3:test.s1 |
|||
--source include/diff_tables.inc |
|||
|
|||
--echo # Validate server_1 binlogged SETVAL with the correct columns |
|||
--connection server_1 |
|||
--let binlog_filenamE= query_get_value(SHOW MASTER STATUS, File, 1) |
|||
FLUSH LOGS; |
|||
--source include/ensure_binlog_row_event_columns.inc |
|||
|
|||
--echo # Validate server_2 binlogged SETVAL with the correct columns |
|||
--connection server_2 |
|||
--let binlog_filename= query_get_value(SHOW MASTER STATUS, File, 1) |
|||
FLUSH LOGS; |
|||
--source include/ensure_binlog_row_event_columns.inc |
|||
|
|||
--echo # Validate server_3 binlogged SETVAL with the correct columns |
|||
--connection server_3 |
|||
--let binlog_filename= query_get_value(SHOW MASTER STATUS, File, 1) |
|||
FLUSH LOGS; |
|||
--source include/ensure_binlog_row_event_columns.inc |
|||
|
|||
|
|||
--echo # Pt.2 Ensure NEXTVAL replicates and binlogs correctly |
|||
--connection server_1 |
|||
SELECT NEXTVAL(s1); |
|||
--source include/save_master_gtid.inc |
|||
|
|||
--echo # Validate NEXTVAL replicated correctly to other servers |
|||
--connection server_3 |
|||
--source include/sync_with_master_gtid.inc |
|||
--let $diff_tables= server_1:test.s1,server_2:test.s1,server_3:test.s1 |
|||
--source include/diff_tables.inc |
|||
|
|||
--echo # Validate server_1 binlogged NEXTVAL with the correct columns |
|||
--connection server_1 |
|||
--let binlog_filename= query_get_value(SHOW MASTER STATUS, File, 1) |
|||
FLUSH LOGS; |
|||
--source include/ensure_binlog_row_event_columns.inc |
|||
|
|||
--echo # Validate server_2 binlogged NEXTVAL with the correct columns |
|||
--connection server_2 |
|||
--let binlog_filename= query_get_value(SHOW MASTER STATUS, File, 1) |
|||
FLUSH LOGS; |
|||
--source include/ensure_binlog_row_event_columns.inc |
|||
|
|||
--echo # Validate server_3 binlogged NEXTVAL with the correct columns |
|||
--connection server_3 |
|||
--let binlog_filename= query_get_value(SHOW MASTER STATUS, File, 1) |
|||
FLUSH LOGS; |
|||
--source include/ensure_binlog_row_event_columns.inc |
|||
|
|||
|
|||
--echo # Cleanup |
|||
--connection server_1 |
|||
DROP TABLE s1; |
|||
--source include/save_master_gtid.inc |
|||
--connection server_3 |
|||
--source include/sync_with_master_gtid.inc |
|||
2290
mysql-test/suite/rpl/r/rpl_row_img_sequence.result
File diff suppressed because it is too large
View File
File diff suppressed because it is too large
View File
@ -0,0 +1,21 @@ |
|||
!include include/default_mysqld.cnf |
|||
|
|||
[mysqld.1] |
|||
log-slave-updates |
|||
innodb |
|||
gtid_domain_id=0 |
|||
|
|||
[mysqld.2] |
|||
log-slave-updates |
|||
innodb |
|||
gtid_domain_id=1 |
|||
|
|||
[mysqld.3] |
|||
log-slave-updates |
|||
innodb |
|||
gtid_domain_id=2 |
|||
|
|||
[ENV] |
|||
SERVER_MYPORT_1= @mysqld.1.port |
|||
SERVER_MYPORT_2= @mysqld.2.port |
|||
SERVER_MYPORT_3= @mysqld.3.port |
|||
@ -0,0 +1,65 @@ |
|||
# |
|||
# Purpose: |
|||
# This test verifies that sequence DML updates, i.e. NEXTVAL and SETVAL, |
|||
# respect the binlog_row_image variable value when written into the binary log. |
|||
# In particular, it ensures that only changed columns are written with MINIMAL |
|||
# image mode, and all columns are written otherwise. |
|||
# |
|||
# Methodology |
|||
# After issuing a sequence update, ensure that both 1) it was replicated |
|||
# correctly, and 2) it was binlogged respective to the binlog_row_image value. |
|||
# The sequence table does not use caching to ensure each update is immediately |
|||
# binlogged. Each command is binlogged into its own unique log file, and the |
|||
# entirety of the file is analyzed for correctness of its sequence event. |
|||
# Specifically, mysqlbinlog is used in verbose mode so it outputs the columns |
|||
# which belong to the event, and the columns are analyzed to ensure the correct |
|||
# ones were logged. rpl_row_img_general_loop.inc is used to test with multiple |
|||
# chained replicas, varying engines between InnoDB and MyISAM. |
|||
# |
|||
# References: |
|||
# MDEV-28487: sequences not respect value of binlog_row_image with select |
|||
# nextval(seq_gen) |
|||
# |
|||
|
|||
--let $rpl_topology= 1->2->3 |
|||
--source include/rpl_init.inc |
|||
--source include/have_binlog_format_row.inc |
|||
|
|||
--connection server_1 |
|||
--source include/have_innodb.inc |
|||
--connection server_2 |
|||
--source include/have_innodb.inc |
|||
--connection server_3 |
|||
--source include/have_innodb.inc |
|||
--connection server_1 |
|||
|
|||
--echo # |
|||
--echo # Test Case 1) binlog_row_image=MINIMAL should write only columns |
|||
--echo # 1 and 8 to the binary log |
|||
--echo # |
|||
--let $row_img_set=server_1:MINIMAL:N,server_2:MINIMAL:Y,server_3:MINIMAL:Y |
|||
--source include/rpl_row_img_set.inc |
|||
--let $expected_columns=(1,8) |
|||
--let row_img_test_script= include/rpl_row_img_sequence.inc |
|||
--source include/rpl_row_img_general_loop.inc |
|||
|
|||
--echo # |
|||
--echo # Test Case 2) binlog_row_image=NOBLOB should write all columns to the |
|||
--echo # binary log |
|||
--echo # |
|||
--let $row_img_set=server_1:NOBLOB:N,server_2:NOBLOB:Y,server_3:NOBLOB:Y |
|||
--source include/rpl_row_img_set.inc |
|||
--let $expected_columns=(1,2,3,4,5,6,7,8) |
|||
--source include/rpl_row_img_general_loop.inc |
|||
|
|||
--echo # |
|||
--echo # Test Case 3) binlog_row_image=NOBLOB should write all columns to the |
|||
--echo # binary log |
|||
--echo # |
|||
--let $row_img_set=server_1:FULL:N,server_2:FULL:Y,server_3:FULL:Y |
|||
--source include/rpl_row_img_set.inc |
|||
--let $expected_columns=(1,2,3,4,5,6,7,8) |
|||
--source include/rpl_row_img_general_loop.inc |
|||
|
|||
--source include/rpl_end.inc |
|||
--echo # End of tests |
|||
Write
Preview
Loading…
Cancel
Save
Reference in new issue