Linux ip-172-26-2-223 5.4.0-1018-aws #18-Ubuntu SMP Wed Jun 24 01:15:00 UTC 2020 x86_64
Apache
: 172.26.2.223 | : 3.23.61.205
Cant Read [ /etc/named.conf ]
8.1.13
www
www.github.com/MadExploits
Terminal
AUTO ROOT
Adminer
Backdoor Destroyer
Linux Exploit
Lock Shell
Lock File
Create User
CREATE RDP
PHP Mailer
BACKCONNECT
UNLOCK SHELL
HASH IDENTIFIER
CPANEL RESET
CREATE WP USER
BLACK DEFEND!
README
+ Create Folder
+ Create File
/
www /
server /
mysql /
mysql-test /
suite /
ndb_rpl /
r /
[ HOME SHELL ]
Name
Size
Permission
Action
ndb_dist_priv_common.result
2.33
KB
-rw-r--r--
ndb_rpl_2innodb.result
41.34
KB
-rw-r--r--
ndb_rpl_2myisam.result
41.34
KB
-rw-r--r--
ndb_rpl_2ndb.result
16.17
KB
-rw-r--r--
ndb_rpl_2other.result
32.71
KB
-rw-r--r--
ndb_rpl_add_column.result
5.99
KB
-rw-r--r--
ndb_rpl_apply_status.result
907
B
-rw-r--r--
ndb_rpl_auto_inc.result
3.72
KB
-rw-r--r--
ndb_rpl_bank.result
10.82
KB
-rw-r--r--
ndb_rpl_basic.result
13.52
KB
-rw-r--r--
ndb_rpl_batch.result
2.48
KB
-rw-r--r--
ndb_rpl_batch_handling.result
1.91
KB
-rw-r--r--
ndb_rpl_binlog_format_errors.r...
1.27
KB
-rw-r--r--
ndb_rpl_bitfield.result
14.48
KB
-rw-r--r--
ndb_rpl_blob.result
7.29
KB
-rw-r--r--
ndb_rpl_break_3_chain.result
3.17
KB
-rw-r--r--
ndb_rpl_bug22045.result
2.56
KB
-rw-r--r--
ndb_rpl_bug_13440282.result
2.3
KB
-rw-r--r--
ndb_rpl_check_for_mixed.result
483
B
-rw-r--r--
ndb_rpl_checksum.result
6.31
KB
-rw-r--r--
ndb_rpl_circular.result
5.13
KB
-rw-r--r--
ndb_rpl_circular_2ch.result
2.27
KB
-rw-r--r--
ndb_rpl_circular_2ch_rep_statu...
7.47
KB
-rw-r--r--
ndb_rpl_circular_simplex.resul...
1.28
KB
-rw-r--r--
ndb_rpl_conflict_basic.result
18.2
KB
-rw-r--r--
ndb_rpl_conflict_epoch.result
71.03
KB
-rw-r--r--
ndb_rpl_conflict_epoch2.result
143.62
KB
-rw-r--r--
ndb_rpl_conflict_epoch2_extra....
63.18
KB
-rw-r--r--
ndb_rpl_conflict_epoch2_trans....
47.12
KB
-rw-r--r--
ndb_rpl_conflict_epoch_ext.res...
106.6
KB
-rw-r--r--
ndb_rpl_conflict_epoch_extende...
13.51
KB
-rw-r--r--
ndb_rpl_conflict_epoch_trans.r...
23.13
KB
-rw-r--r--
ndb_rpl_conflict_epoch_trans_e...
23.62
KB
-rw-r--r--
ndb_rpl_conflict_max.result
36.46
KB
-rw-r--r--
ndb_rpl_conflict_max_delete_wi...
35.68
KB
-rw-r--r--
ndb_rpl_conflict_old.result
36.65
KB
-rw-r--r--
ndb_rpl_conflict_read_tracking...
29.94
KB
-rw-r--r--
ndb_rpl_ctype_ucs2_def.result
703
B
-rw-r--r--
ndb_rpl_dd_advance.result
8.9
KB
-rw-r--r--
ndb_rpl_dd_basic.result
2.4
KB
-rw-r--r--
ndb_rpl_dd_partitions.result
35.75
KB
-rw-r--r--
ndb_rpl_ddl_open_trans.result
1.87
KB
-rw-r--r--
ndb_rpl_dist_priv.result
11.31
KB
-rw-r--r--
ndb_rpl_do_db.result
1.44
KB
-rw-r--r--
ndb_rpl_do_table.result
1.13
KB
-rw-r--r--
ndb_rpl_empty_epoch.result
1.17
KB
-rw-r--r--
ndb_rpl_gap_event.result
1.38
KB
-rw-r--r--
ndb_rpl_idempotent.result
3.06
KB
-rw-r--r--
ndb_rpl_ignore_db.result
1.08
KB
-rw-r--r--
ndb_rpl_init_rep_status.result
2.17
KB
-rw-r--r--
ndb_rpl_innodb2ndb.result
41
KB
-rw-r--r--
ndb_rpl_innodb_trans.result
3.08
KB
-rw-r--r--
ndb_rpl_last_conflict_epoch_va...
2.06
KB
-rw-r--r--
ndb_rpl_load.result
1.27
KB
-rw-r--r--
ndb_rpl_logging.result
2.66
KB
-rw-r--r--
ndb_rpl_mix_eng_trans.result
10.51
KB
-rw-r--r--
ndb_rpl_mix_innodb.result
4.35
KB
-rw-r--r--
ndb_rpl_mixed_tables.result
7.28
KB
-rw-r--r--
ndb_rpl_multi.result
2.33
KB
-rw-r--r--
ndb_rpl_myisam2ndb.result
41
KB
-rw-r--r--
ndb_rpl_ndbapi-examples.result
522
B
-rw-r--r--
ndb_rpl_rep_error.result
16.79
KB
-rw-r--r--
ndb_rpl_rep_ignore.result
1.4
KB
-rw-r--r--
ndb_rpl_skip_gap_event.result
1.27
KB
-rw-r--r--
ndb_rpl_slave_binlog_index.res...
1.83
KB
-rw-r--r--
ndb_rpl_slave_conflict_role_va...
9.63
KB
-rw-r--r--
ndb_rpl_slave_lsu.result
53.8
KB
-rw-r--r--
ndb_rpl_slave_lsu_anyval.resul...
54.73
KB
-rw-r--r--
ndb_rpl_slave_replay.result
6.42
KB
-rw-r--r--
ndb_rpl_slave_restart.result
1.93
KB
-rw-r--r--
ndb_rpl_stm_innodb.result
4.38
KB
-rw-r--r--
ndb_rpl_sync.result
2.38
KB
-rw-r--r--
ndb_rpl_ui.result
1.86
KB
-rw-r--r--
ndb_rpl_ui2.result
813
B
-rw-r--r--
ndb_rpl_ui3.result
1.22
KB
-rw-r--r--
rpl_truncate_7ndb.result
3.27
KB
-rw-r--r--
rpl_truncate_7ndb_2.result
3.27
KB
-rw-r--r--
Delete
Unzip
Zip
${this.title}
Close
Code Editor : ndb_rpl_conflict_epoch2_extra.result
include/master-slave.inc Warnings: Note #### Sending passwords in plain text without SSL/TLS is extremely insecure. Note #### Storing MySQL user name or password information in the master info repository is not secure and is therefore not recommended. Please consider using the USER and PASSWORD connection options for START SLAVE; see the 'START SLAVE Syntax' in the MySQL Manual for more information. [connection master] Setup circular replication The circle is setup between Primary and Secondary Setup ndb_replication and t1 exceptions table Populate ndb_replication table create table test.t1$EX( ndb$server_id int unsigned, ndb$master_server_id int unsigned, ndb$master_epoch bigint unsigned, ndb$count int unsigned, k int not null, v$old int, v$new int, c$old varchar(2000), c$new varchar(2000), ndb$op_type enum('write_row','update_row', 'delete_row') not null, ndb$cft_cause enum('row_does_not_exist','row_already_exists','data_in_conflict','trans_in_conflict') not null, primary key(ndb$server_id, ndb$master_server_id, ndb$master_epoch, ndb$count)) engine ndb; create table test.t1 ( k int primary key, v int, c varchar(2000)) engine=ndb; Setup conflict roles -------------------- STOP SLAVE; set global ndb_slave_conflict_role="PRIMARY"; START SLAVE; STOP SLAVE; set global ndb_slave_conflict_role="SECONDARY"; START SLAVE; Create some initial data ------------------------ insert into test.t1 values (1,10, "Swimming"), (2,20, "Cycling"), (3,30, "Running"), (4,40, "Triathlon"); Content on PRIMARY select * from test.t1 order by k; k v c 1 10 Swimming 2 20 Cycling 3 30 Running 4 40 Triathlon Content on SECONDARY select * from test.t1 order by k; k v c 1 10 Swimming 2 20 Cycling 3 30 Running 4 40 Triathlon Basic delete-delete cases ------------------------- Stop Slave on SECONDARY STOP SLAVE; Delete row 3 on PRIMARY delete from t1 where k=3; Delete row 3 on SECONDARY delete from t1 where k=3; Insert replacement row on SECONDARY This is likely to go in the same SECONDARY epoch transaction insert into t1 values (3,31, "Judo"); Wait for SECONDARY change to apply on PRIMARY Expect it to apply correctly here as the PRIMARY has no track of its outstanding DELETE PRIMARY content select * from test.t1 order by k; k v c 1 10 Swimming 2 20 Cycling 3 31 Judo 4 40 Triathlon PRIMARY counters Conflict algorithm counter diff : ndb_conflict_fn_epoch2 1 ndb_conflict_fn_epoch2_trans 0 ndb_conflict_trans_reject_count 0 ndb_conflict_epoch_delete_delete_count 1 ndb_conflict_refresh_op_count 0 reflected_op_prepare_count_greater_than_zero 0 any_reflected_ops_applied 0 last_conflict_epoch_increased 1 conflict_handling_in_progess 1 stable_epoch_is_older_than_max_replicated 0 Re-enable SECONDARY Slave, and check state there START SLAVE; SECONDARY content select * from test.t1 order by k; k v c 1 10 Swimming 2 20 Cycling 3 31 Judo 4 40 Triathlon SECONDARY counters Conflict algorithm counter diff : ndb_conflict_fn_epoch2 0 ndb_conflict_fn_epoch2_trans 0 ndb_conflict_trans_reject_count 0 ndb_conflict_epoch_delete_delete_count 0 ndb_conflict_refresh_op_count 0 reflected_op_prepare_count_greater_than_zero 1 any_reflected_ops_applied 1 last_conflict_epoch_increased 1 conflict_handling_in_progess 1 stable_epoch_is_older_than_max_replicated 1 Look at PRIMARY exceptions table content SELECT k, v$old, v$new, c$old, c$new, ndb$op_type, ndb$cft_cause from test.t1$EX order by ndb$count; k v$old v$new c$old c$new ndb$op_type ndb$cft_cause 3 30 NULL Running NULL delete_row row_already_exists Now check behaviour of Secondary when reflected ops should not be applied ------------------------------------------------------------------------- The interpreted program attached to reflected ops at the Secondary slave is intended to avoid an 'old' reflected op overwriting a 'new' locally inserted row value. The end result should still be the same (the new value will be applied later, but we should avoid having every modification made at the secondary applied twice with some time lag as that will cause chaos for Secondary applications) Stop Slave on SECONDARY STOP SLAVE; Stop Slave on PRIMARY STOP SLAVE; Delete row 4 on PRIMARY DELETE from test.t1 where k=4; Primary state select * from test.t1 order by k; k v c 1 10 Swimming 2 20 Cycling 3 31 Judo Delete row 4 on SECONDARY DELETE from test.t1 where k=4; Follow with INSERT on SECONDARY INSERT into test.t1 values (4, 440, "Fell running"); Secondary state : select * from test.t1 order by k; k v c 1 10 Swimming 2 20 Cycling 3 31 Judo 4 440 Fell running Allow Primary change to propagate to Secondary (Which will delete the new, updated row on the Secondary) START SLAVE; Examine data on the SECONDARY - row 4 deleted select * from test.t1 order by k; k v c 1 10 Swimming 2 20 Cycling 3 31 Judo Now allow the SECONDARY Binlog to propagate back to the PRIMARY while blocking the return path... STOP SLAVE; START SLAVE; Examine data on the PRIMARY - row 4 exists as the PRIMARY's delete is not applied if present select * from test.t1 order by k; k v c 1 10 Swimming 2 20 Cycling 3 31 Judo 4 440 Fell running Now stop the PRIMARY Slave - changes from the SECONDARY cannot now reach the PRIMARY STOP SLAVE; Now go back to the SECONDARY and create a new row version First show there is no row 4 on the SECONDARY select * from test.t1 order by k; k v c 1 10 Swimming 2 20 Cycling 3 31 Judo INSERT into test.t1 values (4, 4444, "Cyclo-cross"); select * from test.t1 order by k; k v c 1 10 Swimming 2 20 Cycling 3 31 Judo 4 4444 Cyclo-cross Now allow the Binlog of the PRIMARY (containing the reflected DELETE + Insert (4, 440, "Fell running") to be applied locally The SECONDARY should reject this application START SLAVE; Examine data on the SECONDARY : Row 4 should be untouched (4, 4444, "Cyclo-cross"). Insert will be rejected as row already exists. select * from test.t1 order by k; k v c 1 10 Swimming 2 20 Cycling 3 31 Judo 4 4444 Cyclo-cross Show operation counter diff on the SECONDARY Should show reflected op prepared + rejected. Should show equal, non-zero reflected op prep+reject counts Conflict algorithm counter diff : ndb_conflict_fn_epoch2 0 ndb_conflict_fn_epoch2_trans 0 ndb_conflict_trans_reject_count 0 ndb_conflict_epoch_delete_delete_count 0 ndb_conflict_refresh_op_count 0 reflected_op_prepare_count_greater_than_zero 1 any_reflected_ops_applied 0 last_conflict_epoch_increased 0 conflict_handling_in_progess 0 stable_epoch_is_older_than_max_replicated 0 Ok, now allow SECONDARY Binlog to propagate to Primary and realign it START SLAVE; Show data on PRIMARY select * from test.t1 order by k; k v c 1 10 Swimming 2 20 Cycling 3 31 Judo 4 440 Fell running Allow reflection back to the SECONDARY... Now show same for UPDATE, then DELETE ------------------------------------- First stop SLAVEs STOP SLAVE; STOP SLAVE; Now perform UPDATE 1 at Secondary UPDATE test.t1 SET c="Bathing" where k=1; Show data on Secondary select * from test.t1 order by k; k v c 1 10 Bathing 2 20 Cycling 3 31 Judo 4 440 Fell running Data on Primary select * from test.t1 order by k; k v c 1 10 Swimming 2 20 Cycling 3 31 Judo 4 440 Fell running Now propagate to Primary... START SLAVE; Updated data on Primary select * from test.t1 order by k; k v c 1 10 Bathing 2 20 Cycling 3 31 Judo 4 440 Fell running Now stop Primary slave to stop further propagation STOP SLAVE; Now make update 2 on Secondary update test.t1 SET c="Paddling" where k=1; Data on Secondary select * from test.t1 order by k; k v c 1 10 Paddling 2 20 Cycling 3 31 Judo 4 440 Fell running Now allow Primary binlog, containing reflected update op setting column c of row 1 to "Bathing" to be applied it should be rejected by the Secondary, and increment the defined + rejected counts START SLAVE; Data on Secondary (should be unchanged) select * from test.t1 order by k; k v c 1 10 Paddling 2 20 Cycling 3 31 Judo 4 440 Fell running Conflict counts on Secondary (incremented preped + rejected) Conflict algorithm counter diff : ndb_conflict_fn_epoch2 0 ndb_conflict_fn_epoch2_trans 0 ndb_conflict_trans_reject_count 0 ndb_conflict_epoch_delete_delete_count 0 ndb_conflict_refresh_op_count 1 reflected_op_prepare_count_greater_than_zero 1 any_reflected_ops_applied 0 last_conflict_epoch_increased 1 conflict_handling_in_progess 0 stable_epoch_is_older_than_max_replicated 0 Now allow sync... START SLAVE; Allowing the sync should have allowed the second update (To 'Paddling') to be reflected, and rejected Data on Secondary (should be unchanged) select * from test.t1 order by k; k v c 1 10 Paddling 2 20 Cycling 3 31 Judo 4 440 Fell running Conflict counts on Secondary (incremented preped + rejected) Conflict algorithm counter diff : ndb_conflict_fn_epoch2 0 ndb_conflict_fn_epoch2_trans 0 ndb_conflict_trans_reject_count 0 ndb_conflict_epoch_delete_delete_count 0 ndb_conflict_refresh_op_count 1 reflected_op_prepare_count_greater_than_zero 1 any_reflected_ops_applied 0 last_conflict_epoch_increased 1 conflict_handling_in_progess 0 stable_epoch_is_older_than_max_replicated 0 Show same for DELETE -------------------- First stop SLAVEs STOP SLAVE; STOP SLAVE; Now perform DELETE of row 2 at Secondary DELETE from test.t1 where k=2; Show data on Secondary select * from test.t1 order by k; k v c 1 10 Paddling 3 31 Judo 4 440 Fell running Data on Primary select * from test.t1 order by k; k v c 1 10 Paddling 2 20 Cycling 3 31 Judo 4 440 Fell running Now propagate to Primary... START SLAVE; Updated data on Primary select * from test.t1 order by k; k v c 1 10 Paddling 3 31 Judo 4 440 Fell running Now stop Primary slave to stop further propagation STOP SLAVE; Now make a further change on Secondary INSERT into test.t1 VALUES (2, 22, "Rock-climbing"); Data on Secondary select * from test.t1 order by k; k v c 1 10 Paddling 2 22 Rock-climbing 3 31 Judo 4 440 Fell running Now allow Primary binlog, containing reflected delete op on row 2 to be applied it should be rejected by the Secondary, and increment the defined + rejected counts START SLAVE; Data on Secondary (should be unchanged) select * from test.t1 order by k; k v c 1 10 Paddling 2 22 Rock-climbing 3 31 Judo 4 440 Fell running Conflict counts on Secondary (incremented preped + rejected) Conflict algorithm counter diff : ndb_conflict_fn_epoch2 0 ndb_conflict_fn_epoch2_trans 0 ndb_conflict_trans_reject_count 0 ndb_conflict_epoch_delete_delete_count 0 ndb_conflict_refresh_op_count 0 reflected_op_prepare_count_greater_than_zero 1 any_reflected_ops_applied 0 last_conflict_epoch_increased 0 conflict_handling_in_progess 0 stable_epoch_is_older_than_max_replicated 0 Now allow sync... START SLAVE; Allowing the sync should have allowed the insert (To 'Rock-climbing') to be reflected, and rejected Data on Secondary (should be unchanged) select * from test.t1 order by k; k v c 1 10 Paddling 2 22 Rock-climbing 3 31 Judo 4 440 Fell running Conflict counts on Secondary (incremented preped + rejected) Conflict algorithm counter diff : ndb_conflict_fn_epoch2 0 ndb_conflict_fn_epoch2_trans 0 ndb_conflict_trans_reject_count 0 ndb_conflict_epoch_delete_delete_count 0 ndb_conflict_refresh_op_count 0 reflected_op_prepare_count_greater_than_zero 1 any_reflected_ops_applied 0 last_conflict_epoch_increased 0 conflict_handling_in_progess 0 stable_epoch_is_older_than_max_replicated 0 Primary insert-delete obscures Secondary insert problem ------------------------------------------------------- Stop slaves in both directions STOP SLAVE; STOP SLAVE; Start with non-existent row (5, 50, "Disco dancing") on primary insert into test.t1 values (5, 50, "Disco dancing"); select * from test.t1 order by k; k v c 1 10 Paddling 2 22 Rock-climbing 3 31 Judo 4 440 Fell running 5 50 Disco dancing Reset conflict counters on Primary Empty exceptions table on Primary DELETE from test.t1$EX; Insert non-existent row (5, 500, "Line dancing") on secondary insert into test.t1 values (5, 500, "Line dancing"); select * from test.t1 order by k; k v c 1 10 Paddling 2 22 Rock-climbing 3 31 Judo 4 440 Fell running 5 500 Line dancing Reset conflict counters on Secondary Allow Primary insert to trample Secondary insert. START SLAVE; select * from test.t1 order by k; k v c 1 10 Paddling 2 22 Rock-climbing 3 31 Judo 4 440 Fell running 5 50 Disco dancing Secondary now updates the row set by the Primary update test.t1 set v=v+5 where k=5; select * from test.t1 order by k; k v c 1 10 Paddling 2 22 Rock-climbing 3 31 Judo 4 440 Fell running 5 55 Disco dancing Stop Secondary Slave again STOP SLAVE; Now delete row from the primary delete from test.t1 where k=5; select * from test.t1 order by k; k v c 1 10 Paddling 2 22 Rock-climbing 3 31 Judo 4 440 Fell running Now allow Secondary writes to propagate to Primary START SLAVE; Expect that the Secondary insert succeeded as no row existed on arrival, but then the secondary row was trampled by the primary, and then a secondary update was applied... So what do we see at the Primary? select * from test.t1 order by k; k v c 1 10 Paddling 2 22 Rock-climbing 3 31 Judo 4 440 Fell running 5 55 Disco dancing Show primary conflict info counter diff - expect nothing. Conflict algorithm counter diff : ndb_conflict_fn_epoch2 0 ndb_conflict_fn_epoch2_trans 0 ndb_conflict_trans_reject_count 0 ndb_conflict_epoch_delete_delete_count 0 ndb_conflict_refresh_op_count 0 reflected_op_prepare_count_greater_than_zero 0 any_reflected_ops_applied 0 last_conflict_epoch_increased 0 conflict_handling_in_progess 0 stable_epoch_is_older_than_max_replicated 0 Show primary's exceptions table content - expect there to be none. SELECT k, v$old, v$new, c$old, c$new, ndb$op_type, ndb$cft_cause from test.t1$EX order by ndb$count; k v$old v$new c$old c$new ndb$op_type ndb$cft_cause Now allow Primary changes to propagate back to Secondary START SLAVE; Look at Secondary content select * from test.t1 order by k; k v c 1 10 Paddling 2 22 Rock-climbing 3 31 Judo 4 440 Fell running 5 55 Disco dancing Look at Secondary conflict counters diff - showing reflected ops applied on Secondary Conflict algorithm counter diff : ndb_conflict_fn_epoch2 0 ndb_conflict_fn_epoch2_trans 0 ndb_conflict_trans_reject_count 0 ndb_conflict_epoch_delete_delete_count 0 ndb_conflict_refresh_op_count 0 reflected_op_prepare_count_greater_than_zero 1 any_reflected_ops_applied 1 last_conflict_epoch_increased 1 conflict_handling_in_progess 1 stable_epoch_is_older_than_max_replicated 1 select * from test.t1 order by k; k v c 1 10 Paddling 2 22 Rock-climbing 3 31 Judo 4 440 Fell running 5 55 Disco dancing Iteration 3 STOP SLAVE; DELETE FROM test.t1$EX; set global ndb_slave_conflict_role="SECONDARY"; STOP SLAVE; DELETE FROM test.t1$EX; set global ndb_slave_conflict_role="PRIMARY"; Setup S1 P2 delete from test.t1; insert into test.t1 values (1,10, "Swimming"), (2,20, "Cycling"), (3,30, "Running"), (4,40, "Triathlon"); START SLAVE; START SLAVE; Content on PRIMARY select * from test.t1 order by k; k v c 1 10 Swimming 2 20 Cycling 3 30 Running 4 40 Triathlon Content on SECONDARY select * from test.t1 order by k; k v c 1 10 Swimming 2 20 Cycling 3 30 Running 4 40 Triathlon Basic delete-delete cases ------------------------- Stop Slave on SECONDARY STOP SLAVE; Delete row 3 on PRIMARY delete from t1 where k=3; Delete row 3 on SECONDARY delete from t1 where k=3; Insert replacement row on SECONDARY This is likely to go in the same SECONDARY epoch transaction insert into t1 values (3,31, "Judo"); Wait for SECONDARY change to apply on PRIMARY Expect it to apply correctly here as the PRIMARY has no track of its outstanding DELETE PRIMARY content select * from test.t1 order by k; k v c 1 10 Swimming 2 20 Cycling 3 31 Judo 4 40 Triathlon PRIMARY counters Conflict algorithm counter diff : ndb_conflict_fn_epoch2 1 ndb_conflict_fn_epoch2_trans 0 ndb_conflict_trans_reject_count 0 ndb_conflict_epoch_delete_delete_count 1 ndb_conflict_refresh_op_count 0 reflected_op_prepare_count_greater_than_zero 0 any_reflected_ops_applied 0 last_conflict_epoch_increased 1 conflict_handling_in_progess 1 stable_epoch_is_older_than_max_replicated 0 Re-enable SECONDARY Slave, and check state there START SLAVE; SECONDARY content select * from test.t1 order by k; k v c 1 10 Swimming 2 20 Cycling 3 31 Judo 4 40 Triathlon SECONDARY counters Conflict algorithm counter diff : ndb_conflict_fn_epoch2 0 ndb_conflict_fn_epoch2_trans 0 ndb_conflict_trans_reject_count 0 ndb_conflict_epoch_delete_delete_count 0 ndb_conflict_refresh_op_count 0 reflected_op_prepare_count_greater_than_zero 1 any_reflected_ops_applied 1 last_conflict_epoch_increased 1 conflict_handling_in_progess 1 stable_epoch_is_older_than_max_replicated 1 Look at PRIMARY exceptions table content SELECT k, v$old, v$new, c$old, c$new, ndb$op_type, ndb$cft_cause from test.t1$EX order by ndb$count; k v$old v$new c$old c$new ndb$op_type ndb$cft_cause 3 30 NULL Running NULL delete_row row_already_exists Now check behaviour of Secondary when reflected ops should not be applied ------------------------------------------------------------------------- The interpreted program attached to reflected ops at the Secondary slave is intended to avoid an 'old' reflected op overwriting a 'new' locally inserted row value. The end result should still be the same (the new value will be applied later, but we should avoid having every modification made at the secondary applied twice with some time lag as that will cause chaos for Secondary applications) Stop Slave on SECONDARY STOP SLAVE; Stop Slave on PRIMARY STOP SLAVE; Delete row 4 on PRIMARY DELETE from test.t1 where k=4; Primary state select * from test.t1 order by k; k v c 1 10 Swimming 2 20 Cycling 3 31 Judo Delete row 4 on SECONDARY DELETE from test.t1 where k=4; Follow with INSERT on SECONDARY INSERT into test.t1 values (4, 440, "Fell running"); Secondary state : select * from test.t1 order by k; k v c 1 10 Swimming 2 20 Cycling 3 31 Judo 4 440 Fell running Allow Primary change to propagate to Secondary (Which will delete the new, updated row on the Secondary) START SLAVE; Examine data on the SECONDARY - row 4 deleted select * from test.t1 order by k; k v c 1 10 Swimming 2 20 Cycling 3 31 Judo Now allow the SECONDARY Binlog to propagate back to the PRIMARY while blocking the return path... STOP SLAVE; START SLAVE; Examine data on the PRIMARY - row 4 exists as the PRIMARY's delete is not applied if present select * from test.t1 order by k; k v c 1 10 Swimming 2 20 Cycling 3 31 Judo 4 440 Fell running Now stop the PRIMARY Slave - changes from the SECONDARY cannot now reach the PRIMARY STOP SLAVE; Now go back to the SECONDARY and create a new row version First show there is no row 4 on the SECONDARY select * from test.t1 order by k; k v c 1 10 Swimming 2 20 Cycling 3 31 Judo INSERT into test.t1 values (4, 4444, "Cyclo-cross"); select * from test.t1 order by k; k v c 1 10 Swimming 2 20 Cycling 3 31 Judo 4 4444 Cyclo-cross Now allow the Binlog of the PRIMARY (containing the reflected DELETE + Insert (4, 440, "Fell running") to be applied locally The SECONDARY should reject this application START SLAVE; Examine data on the SECONDARY : Row 4 should be untouched (4, 4444, "Cyclo-cross"). Insert will be rejected as row already exists. select * from test.t1 order by k; k v c 1 10 Swimming 2 20 Cycling 3 31 Judo 4 4444 Cyclo-cross Show operation counter diff on the SECONDARY Should show reflected op prepared + rejected. Should show equal, non-zero reflected op prep+reject counts Conflict algorithm counter diff : ndb_conflict_fn_epoch2 0 ndb_conflict_fn_epoch2_trans 0 ndb_conflict_trans_reject_count 0 ndb_conflict_epoch_delete_delete_count 0 ndb_conflict_refresh_op_count 0 reflected_op_prepare_count_greater_than_zero 1 any_reflected_ops_applied 0 last_conflict_epoch_increased 0 conflict_handling_in_progess 0 stable_epoch_is_older_than_max_replicated 0 Ok, now allow SECONDARY Binlog to propagate to Primary and realign it START SLAVE; Show data on PRIMARY select * from test.t1 order by k; k v c 1 10 Swimming 2 20 Cycling 3 31 Judo 4 440 Fell running Allow reflection back to the SECONDARY... Now show same for UPDATE, then DELETE ------------------------------------- First stop SLAVEs STOP SLAVE; STOP SLAVE; Now perform UPDATE 1 at Secondary UPDATE test.t1 SET c="Bathing" where k=1; Show data on Secondary select * from test.t1 order by k; k v c 1 10 Bathing 2 20 Cycling 3 31 Judo 4 440 Fell running Data on Primary select * from test.t1 order by k; k v c 1 10 Swimming 2 20 Cycling 3 31 Judo 4 440 Fell running Now propagate to Primary... START SLAVE; Updated data on Primary select * from test.t1 order by k; k v c 1 10 Bathing 2 20 Cycling 3 31 Judo 4 440 Fell running Now stop Primary slave to stop further propagation STOP SLAVE; Now make update 2 on Secondary update test.t1 SET c="Paddling" where k=1; Data on Secondary select * from test.t1 order by k; k v c 1 10 Paddling 2 20 Cycling 3 31 Judo 4 440 Fell running Now allow Primary binlog, containing reflected update op setting column c of row 1 to "Bathing" to be applied it should be rejected by the Secondary, and increment the defined + rejected counts START SLAVE; Data on Secondary (should be unchanged) select * from test.t1 order by k; k v c 1 10 Paddling 2 20 Cycling 3 31 Judo 4 440 Fell running Conflict counts on Secondary (incremented preped + rejected) Conflict algorithm counter diff : ndb_conflict_fn_epoch2 0 ndb_conflict_fn_epoch2_trans 0 ndb_conflict_trans_reject_count 0 ndb_conflict_epoch_delete_delete_count 0 ndb_conflict_refresh_op_count 1 reflected_op_prepare_count_greater_than_zero 1 any_reflected_ops_applied 0 last_conflict_epoch_increased 1 conflict_handling_in_progess 0 stable_epoch_is_older_than_max_replicated 0 Now allow sync... START SLAVE; Allowing the sync should have allowed the second update (To 'Paddling') to be reflected, and rejected Data on Secondary (should be unchanged) select * from test.t1 order by k; k v c 1 10 Paddling 2 20 Cycling 3 31 Judo 4 440 Fell running Conflict counts on Secondary (incremented preped + rejected) Conflict algorithm counter diff : ndb_conflict_fn_epoch2 0 ndb_conflict_fn_epoch2_trans 0 ndb_conflict_trans_reject_count 0 ndb_conflict_epoch_delete_delete_count 0 ndb_conflict_refresh_op_count 1 reflected_op_prepare_count_greater_than_zero 1 any_reflected_ops_applied 0 last_conflict_epoch_increased 1 conflict_handling_in_progess 0 stable_epoch_is_older_than_max_replicated 0 Show same for DELETE -------------------- First stop SLAVEs STOP SLAVE; STOP SLAVE; Now perform DELETE of row 2 at Secondary DELETE from test.t1 where k=2; Show data on Secondary select * from test.t1 order by k; k v c 1 10 Paddling 3 31 Judo 4 440 Fell running Data on Primary select * from test.t1 order by k; k v c 1 10 Paddling 2 20 Cycling 3 31 Judo 4 440 Fell running Now propagate to Primary... START SLAVE; Updated data on Primary select * from test.t1 order by k; k v c 1 10 Paddling 3 31 Judo 4 440 Fell running Now stop Primary slave to stop further propagation STOP SLAVE; Now make a further change on Secondary INSERT into test.t1 VALUES (2, 22, "Rock-climbing"); Data on Secondary select * from test.t1 order by k; k v c 1 10 Paddling 2 22 Rock-climbing 3 31 Judo 4 440 Fell running Now allow Primary binlog, containing reflected delete op on row 2 to be applied it should be rejected by the Secondary, and increment the defined + rejected counts START SLAVE; Data on Secondary (should be unchanged) select * from test.t1 order by k; k v c 1 10 Paddling 2 22 Rock-climbing 3 31 Judo 4 440 Fell running Conflict counts on Secondary (incremented preped + rejected) Conflict algorithm counter diff : ndb_conflict_fn_epoch2 0 ndb_conflict_fn_epoch2_trans 0 ndb_conflict_trans_reject_count 0 ndb_conflict_epoch_delete_delete_count 0 ndb_conflict_refresh_op_count 0 reflected_op_prepare_count_greater_than_zero 1 any_reflected_ops_applied 0 last_conflict_epoch_increased 0 conflict_handling_in_progess 0 stable_epoch_is_older_than_max_replicated 0 Now allow sync... START SLAVE; Allowing the sync should have allowed the insert (To 'Rock-climbing') to be reflected, and rejected Data on Secondary (should be unchanged) select * from test.t1 order by k; k v c 1 10 Paddling 2 22 Rock-climbing 3 31 Judo 4 440 Fell running Conflict counts on Secondary (incremented preped + rejected) Conflict algorithm counter diff : ndb_conflict_fn_epoch2 0 ndb_conflict_fn_epoch2_trans 0 ndb_conflict_trans_reject_count 0 ndb_conflict_epoch_delete_delete_count 0 ndb_conflict_refresh_op_count 0 reflected_op_prepare_count_greater_than_zero 1 any_reflected_ops_applied 0 last_conflict_epoch_increased 0 conflict_handling_in_progess 0 stable_epoch_is_older_than_max_replicated 0 Primary insert-delete obscures Secondary insert problem ------------------------------------------------------- Stop slaves in both directions STOP SLAVE; STOP SLAVE; Start with non-existent row (5, 50, "Disco dancing") on primary insert into test.t1 values (5, 50, "Disco dancing"); select * from test.t1 order by k; k v c 1 10 Paddling 2 22 Rock-climbing 3 31 Judo 4 440 Fell running 5 50 Disco dancing Reset conflict counters on Primary Empty exceptions table on Primary DELETE from test.t1$EX; Insert non-existent row (5, 500, "Line dancing") on secondary insert into test.t1 values (5, 500, "Line dancing"); select * from test.t1 order by k; k v c 1 10 Paddling 2 22 Rock-climbing 3 31 Judo 4 440 Fell running 5 500 Line dancing Reset conflict counters on Secondary Allow Primary insert to trample Secondary insert. START SLAVE; select * from test.t1 order by k; k v c 1 10 Paddling 2 22 Rock-climbing 3 31 Judo 4 440 Fell running 5 50 Disco dancing Secondary now updates the row set by the Primary update test.t1 set v=v+5 where k=5; select * from test.t1 order by k; k v c 1 10 Paddling 2 22 Rock-climbing 3 31 Judo 4 440 Fell running 5 55 Disco dancing Stop Secondary Slave again STOP SLAVE; Now delete row from the primary delete from test.t1 where k=5; select * from test.t1 order by k; k v c 1 10 Paddling 2 22 Rock-climbing 3 31 Judo 4 440 Fell running Now allow Secondary writes to propagate to Primary START SLAVE; Expect that the Secondary insert succeeded as no row existed on arrival, but then the secondary row was trampled by the primary, and then a secondary update was applied... So what do we see at the Primary? select * from test.t1 order by k; k v c 1 10 Paddling 2 22 Rock-climbing 3 31 Judo 4 440 Fell running 5 55 Disco dancing Show primary conflict info counter diff - expect nothing. Conflict algorithm counter diff : ndb_conflict_fn_epoch2 0 ndb_conflict_fn_epoch2_trans 0 ndb_conflict_trans_reject_count 0 ndb_conflict_epoch_delete_delete_count 0 ndb_conflict_refresh_op_count 0 reflected_op_prepare_count_greater_than_zero 0 any_reflected_ops_applied 0 last_conflict_epoch_increased 0 conflict_handling_in_progess 0 stable_epoch_is_older_than_max_replicated 0 Show primary's exceptions table content - expect there to be none. SELECT k, v$old, v$new, c$old, c$new, ndb$op_type, ndb$cft_cause from test.t1$EX order by ndb$count; k v$old v$new c$old c$new ndb$op_type ndb$cft_cause Now allow Primary changes to propagate back to Secondary START SLAVE; Look at Secondary content select * from test.t1 order by k; k v c 1 10 Paddling 2 22 Rock-climbing 3 31 Judo 4 440 Fell running 5 55 Disco dancing Look at Secondary conflict counters diff - showing reflected ops applied on Secondary Conflict algorithm counter diff : ndb_conflict_fn_epoch2 0 ndb_conflict_fn_epoch2_trans 0 ndb_conflict_trans_reject_count 0 ndb_conflict_epoch_delete_delete_count 0 ndb_conflict_refresh_op_count 0 reflected_op_prepare_count_greater_than_zero 1 any_reflected_ops_applied 1 last_conflict_epoch_increased 1 conflict_handling_in_progess 1 stable_epoch_is_older_than_max_replicated 1 select * from test.t1 order by k; k v c 1 10 Paddling 2 22 Rock-climbing 3 31 Judo 4 440 Fell running 5 55 Disco dancing Iteration 2 STOP SLAVE; DELETE FROM test.t1$EX; set global ndb_slave_conflict_role="SECONDARY"; STOP SLAVE; DELETE FROM test.t1$EX; set global ndb_slave_conflict_role="PRIMARY"; Setup P1 S2 delete from test.t1; insert into test.t1 values (1,10, "Swimming"), (2,20, "Cycling"), (3,30, "Running"), (4,40, "Triathlon"); START SLAVE; START SLAVE; Content on PRIMARY select * from test.t1 order by k; k v c 1 10 Swimming 2 20 Cycling 3 30 Running 4 40 Triathlon Content on SECONDARY select * from test.t1 order by k; k v c 1 10 Swimming 2 20 Cycling 3 30 Running 4 40 Triathlon Basic delete-delete cases ------------------------- Stop Slave on SECONDARY STOP SLAVE; Delete row 3 on PRIMARY delete from t1 where k=3; Delete row 3 on SECONDARY delete from t1 where k=3; Insert replacement row on SECONDARY This is likely to go in the same SECONDARY epoch transaction insert into t1 values (3,31, "Judo"); Wait for SECONDARY change to apply on PRIMARY Expect it to apply correctly here as the PRIMARY has no track of its outstanding DELETE PRIMARY content select * from test.t1 order by k; k v c 1 10 Swimming 2 20 Cycling 3 31 Judo 4 40 Triathlon PRIMARY counters Conflict algorithm counter diff : ndb_conflict_fn_epoch2 1 ndb_conflict_fn_epoch2_trans 0 ndb_conflict_trans_reject_count 0 ndb_conflict_epoch_delete_delete_count 1 ndb_conflict_refresh_op_count 0 reflected_op_prepare_count_greater_than_zero 0 any_reflected_ops_applied 0 last_conflict_epoch_increased 1 conflict_handling_in_progess 1 stable_epoch_is_older_than_max_replicated 0 Re-enable SECONDARY Slave, and check state there START SLAVE; SECONDARY content select * from test.t1 order by k; k v c 1 10 Swimming 2 20 Cycling 3 31 Judo 4 40 Triathlon SECONDARY counters Conflict algorithm counter diff : ndb_conflict_fn_epoch2 0 ndb_conflict_fn_epoch2_trans 0 ndb_conflict_trans_reject_count 0 ndb_conflict_epoch_delete_delete_count 0 ndb_conflict_refresh_op_count 0 reflected_op_prepare_count_greater_than_zero 1 any_reflected_ops_applied 1 last_conflict_epoch_increased 1 conflict_handling_in_progess 1 stable_epoch_is_older_than_max_replicated 1 Look at PRIMARY exceptions table content SELECT k, v$old, v$new, c$old, c$new, ndb$op_type, ndb$cft_cause from test.t1$EX order by ndb$count; k v$old v$new c$old c$new ndb$op_type ndb$cft_cause 3 30 NULL Running NULL delete_row row_already_exists Now check behaviour of Secondary when reflected ops should not be applied ------------------------------------------------------------------------- The interpreted program attached to reflected ops at the Secondary slave is intended to avoid an 'old' reflected op overwriting a 'new' locally inserted row value. The end result should still be the same (the new value will be applied later, but we should avoid having every modification made at the secondary applied twice with some time lag as that will cause chaos for Secondary applications) Stop Slave on SECONDARY STOP SLAVE; Stop Slave on PRIMARY STOP SLAVE; Delete row 4 on PRIMARY DELETE from test.t1 where k=4; Primary state select * from test.t1 order by k; k v c 1 10 Swimming 2 20 Cycling 3 31 Judo Delete row 4 on SECONDARY DELETE from test.t1 where k=4; Follow with INSERT on SECONDARY INSERT into test.t1 values (4, 440, "Fell running"); Secondary state : select * from test.t1 order by k; k v c 1 10 Swimming 2 20 Cycling 3 31 Judo 4 440 Fell running Allow Primary change to propagate to Secondary (Which will delete the new, updated row on the Secondary) START SLAVE; Examine data on the SECONDARY - row 4 deleted select * from test.t1 order by k; k v c 1 10 Swimming 2 20 Cycling 3 31 Judo Now allow the SECONDARY Binlog to propagate back to the PRIMARY while blocking the return path... STOP SLAVE; START SLAVE; Examine data on the PRIMARY - row 4 exists as the PRIMARY's delete is not applied if present select * from test.t1 order by k; k v c 1 10 Swimming 2 20 Cycling 3 31 Judo 4 440 Fell running Now stop the PRIMARY Slave - changes from the SECONDARY cannot now reach the PRIMARY STOP SLAVE; Now go back to the SECONDARY and create a new row version First show there is no row 4 on the SECONDARY select * from test.t1 order by k; k v c 1 10 Swimming 2 20 Cycling 3 31 Judo INSERT into test.t1 values (4, 4444, "Cyclo-cross"); select * from test.t1 order by k; k v c 1 10 Swimming 2 20 Cycling 3 31 Judo 4 4444 Cyclo-cross Now allow the Binlog of the PRIMARY (containing the reflected DELETE + Insert (4, 440, "Fell running") to be applied locally The SECONDARY should reject this application START SLAVE; Examine data on the SECONDARY : Row 4 should be untouched (4, 4444, "Cyclo-cross"). Insert will be rejected as row already exists. select * from test.t1 order by k; k v c 1 10 Swimming 2 20 Cycling 3 31 Judo 4 4444 Cyclo-cross Show operation counter diff on the SECONDARY Should show reflected op prepared + rejected. Should show equal, non-zero reflected op prep+reject counts Conflict algorithm counter diff : ndb_conflict_fn_epoch2 0 ndb_conflict_fn_epoch2_trans 0 ndb_conflict_trans_reject_count 0 ndb_conflict_epoch_delete_delete_count 0 ndb_conflict_refresh_op_count 0 reflected_op_prepare_count_greater_than_zero 1 any_reflected_ops_applied 0 last_conflict_epoch_increased 0 conflict_handling_in_progess 0 stable_epoch_is_older_than_max_replicated 0 Ok, now allow SECONDARY Binlog to propagate to Primary and realign it START SLAVE; Show data on PRIMARY select * from test.t1 order by k; k v c 1 10 Swimming 2 20 Cycling 3 31 Judo 4 440 Fell running Allow reflection back to the SECONDARY... Now show same for UPDATE, then DELETE ------------------------------------- First stop SLAVEs STOP SLAVE; STOP SLAVE; Now perform UPDATE 1 at Secondary UPDATE test.t1 SET c="Bathing" where k=1; Show data on Secondary select * from test.t1 order by k; k v c 1 10 Bathing 2 20 Cycling 3 31 Judo 4 440 Fell running Data on Primary select * from test.t1 order by k; k v c 1 10 Swimming 2 20 Cycling 3 31 Judo 4 440 Fell running Now propagate to Primary... START SLAVE; Updated data on Primary select * from test.t1 order by k; k v c 1 10 Bathing 2 20 Cycling 3 31 Judo 4 440 Fell running Now stop Primary slave to stop further propagation STOP SLAVE; Now make update 2 on Secondary update test.t1 SET c="Paddling" where k=1; Data on Secondary select * from test.t1 order by k; k v c 1 10 Paddling 2 20 Cycling 3 31 Judo 4 440 Fell running Now allow Primary binlog, containing reflected update op setting column c of row 1 to "Bathing" to be applied it should be rejected by the Secondary, and increment the defined + rejected counts START SLAVE; Data on Secondary (should be unchanged) select * from test.t1 order by k; k v c 1 10 Paddling 2 20 Cycling 3 31 Judo 4 440 Fell running Conflict counts on Secondary (incremented preped + rejected) Conflict algorithm counter diff : ndb_conflict_fn_epoch2 0 ndb_conflict_fn_epoch2_trans 0 ndb_conflict_trans_reject_count 0 ndb_conflict_epoch_delete_delete_count 0 ndb_conflict_refresh_op_count 1 reflected_op_prepare_count_greater_than_zero 1 any_reflected_ops_applied 0 last_conflict_epoch_increased 1 conflict_handling_in_progess 0 stable_epoch_is_older_than_max_replicated 0 Now allow sync... START SLAVE; Allowing the sync should have allowed the second update (To 'Paddling') to be reflected, and rejected Data on Secondary (should be unchanged) select * from test.t1 order by k; k v c 1 10 Paddling 2 20 Cycling 3 31 Judo 4 440 Fell running Conflict counts on Secondary (incremented preped + rejected) Conflict algorithm counter diff : ndb_conflict_fn_epoch2 0 ndb_conflict_fn_epoch2_trans 0 ndb_conflict_trans_reject_count 0 ndb_conflict_epoch_delete_delete_count 0 ndb_conflict_refresh_op_count 1 reflected_op_prepare_count_greater_than_zero 1 any_reflected_ops_applied 0 last_conflict_epoch_increased 1 conflict_handling_in_progess 0 stable_epoch_is_older_than_max_replicated 0 Show same for DELETE -------------------- First stop SLAVEs STOP SLAVE; STOP SLAVE; Now perform DELETE of row 2 at Secondary DELETE from test.t1 where k=2; Show data on Secondary select * from test.t1 order by k; k v c 1 10 Paddling 3 31 Judo 4 440 Fell running Data on Primary select * from test.t1 order by k; k v c 1 10 Paddling 2 20 Cycling 3 31 Judo 4 440 Fell running Now propagate to Primary... START SLAVE; Updated data on Primary select * from test.t1 order by k; k v c 1 10 Paddling 3 31 Judo 4 440 Fell running Now stop Primary slave to stop further propagation STOP SLAVE; Now make a further change on Secondary INSERT into test.t1 VALUES (2, 22, "Rock-climbing"); Data on Secondary select * from test.t1 order by k; k v c 1 10 Paddling 2 22 Rock-climbing 3 31 Judo 4 440 Fell running Now allow Primary binlog, containing reflected delete op on row 2 to be applied it should be rejected by the Secondary, and increment the defined + rejected counts START SLAVE; Data on Secondary (should be unchanged) select * from test.t1 order by k; k v c 1 10 Paddling 2 22 Rock-climbing 3 31 Judo 4 440 Fell running Conflict counts on Secondary (incremented preped + rejected) Conflict algorithm counter diff : ndb_conflict_fn_epoch2 0 ndb_conflict_fn_epoch2_trans 0 ndb_conflict_trans_reject_count 0 ndb_conflict_epoch_delete_delete_count 0 ndb_conflict_refresh_op_count 0 reflected_op_prepare_count_greater_than_zero 1 any_reflected_ops_applied 0 last_conflict_epoch_increased 0 conflict_handling_in_progess 0 stable_epoch_is_older_than_max_replicated 0 Now allow sync... START SLAVE; Allowing the sync should have allowed the insert (To 'Rock-climbing') to be reflected, and rejected Data on Secondary (should be unchanged) select * from test.t1 order by k; k v c 1 10 Paddling 2 22 Rock-climbing 3 31 Judo 4 440 Fell running Conflict counts on Secondary (incremented preped + rejected) Conflict algorithm counter diff : ndb_conflict_fn_epoch2 0 ndb_conflict_fn_epoch2_trans 0 ndb_conflict_trans_reject_count 0 ndb_conflict_epoch_delete_delete_count 0 ndb_conflict_refresh_op_count 0 reflected_op_prepare_count_greater_than_zero 1 any_reflected_ops_applied 0 last_conflict_epoch_increased 0 conflict_handling_in_progess 0 stable_epoch_is_older_than_max_replicated 0 Primary insert-delete obscures Secondary insert problem ------------------------------------------------------- Stop slaves in both directions STOP SLAVE; STOP SLAVE; Start with non-existent row (5, 50, "Disco dancing") on primary insert into test.t1 values (5, 50, "Disco dancing"); select * from test.t1 order by k; k v c 1 10 Paddling 2 22 Rock-climbing 3 31 Judo 4 440 Fell running 5 50 Disco dancing Reset conflict counters on Primary Empty exceptions table on Primary DELETE from test.t1$EX; Insert non-existent row (5, 500, "Line dancing") on secondary insert into test.t1 values (5, 500, "Line dancing"); select * from test.t1 order by k; k v c 1 10 Paddling 2 22 Rock-climbing 3 31 Judo 4 440 Fell running 5 500 Line dancing Reset conflict counters on Secondary Allow Primary insert to trample Secondary insert. START SLAVE; select * from test.t1 order by k; k v c 1 10 Paddling 2 22 Rock-climbing 3 31 Judo 4 440 Fell running 5 50 Disco dancing Secondary now updates the row set by the Primary update test.t1 set v=v+5 where k=5; select * from test.t1 order by k; k v c 1 10 Paddling 2 22 Rock-climbing 3 31 Judo 4 440 Fell running 5 55 Disco dancing Stop Secondary Slave again STOP SLAVE; Now delete row from the primary delete from test.t1 where k=5; select * from test.t1 order by k; k v c 1 10 Paddling 2 22 Rock-climbing 3 31 Judo 4 440 Fell running Now allow Secondary writes to propagate to Primary START SLAVE; Expect that the Secondary insert succeeded as no row existed on arrival, but then the secondary row was trampled by the primary, and then a secondary update was applied... So what do we see at the Primary? select * from test.t1 order by k; k v c 1 10 Paddling 2 22 Rock-climbing 3 31 Judo 4 440 Fell running 5 55 Disco dancing Show primary conflict info counter diff - expect nothing. Conflict algorithm counter diff : ndb_conflict_fn_epoch2 0 ndb_conflict_fn_epoch2_trans 0 ndb_conflict_trans_reject_count 0 ndb_conflict_epoch_delete_delete_count 0 ndb_conflict_refresh_op_count 0 reflected_op_prepare_count_greater_than_zero 0 any_reflected_ops_applied 0 last_conflict_epoch_increased 0 conflict_handling_in_progess 0 stable_epoch_is_older_than_max_replicated 0 Show primary's exceptions table content - expect there to be none. SELECT k, v$old, v$new, c$old, c$new, ndb$op_type, ndb$cft_cause from test.t1$EX order by ndb$count; k v$old v$new c$old c$new ndb$op_type ndb$cft_cause Now allow Primary changes to propagate back to Secondary START SLAVE; Look at Secondary content select * from test.t1 order by k; k v c 1 10 Paddling 2 22 Rock-climbing 3 31 Judo 4 440 Fell running 5 55 Disco dancing Look at Secondary conflict counters diff - showing reflected ops applied on Secondary Conflict algorithm counter diff : ndb_conflict_fn_epoch2 0 ndb_conflict_fn_epoch2_trans 0 ndb_conflict_trans_reject_count 0 ndb_conflict_epoch_delete_delete_count 0 ndb_conflict_refresh_op_count 0 reflected_op_prepare_count_greater_than_zero 1 any_reflected_ops_applied 1 last_conflict_epoch_increased 1 conflict_handling_in_progess 1 stable_epoch_is_older_than_max_replicated 1 select * from test.t1 order by k; k v c 1 10 Paddling 2 22 Rock-climbing 3 31 Judo 4 440 Fell running 5 55 Disco dancing Iteration 1 STOP SLAVE; DELETE FROM test.t1$EX; set global ndb_slave_conflict_role="SECONDARY"; STOP SLAVE; DELETE FROM test.t1$EX; set global ndb_slave_conflict_role="PRIMARY"; Setup S1 P2 delete from test.t1; insert into test.t1 values (1,10, "Swimming"), (2,20, "Cycling"), (3,30, "Running"), (4,40, "Triathlon"); START SLAVE; START SLAVE; Content on PRIMARY select * from test.t1 order by k; k v c 1 10 Swimming 2 20 Cycling 3 30 Running 4 40 Triathlon Content on SECONDARY select * from test.t1 order by k; k v c 1 10 Swimming 2 20 Cycling 3 30 Running 4 40 Triathlon Basic delete-delete cases ------------------------- Stop Slave on SECONDARY STOP SLAVE; Delete row 3 on PRIMARY delete from t1 where k=3; Delete row 3 on SECONDARY delete from t1 where k=3; Insert replacement row on SECONDARY This is likely to go in the same SECONDARY epoch transaction insert into t1 values (3,31, "Judo"); Wait for SECONDARY change to apply on PRIMARY Expect it to apply correctly here as the PRIMARY has no track of its outstanding DELETE PRIMARY content select * from test.t1 order by k; k v c 1 10 Swimming 2 20 Cycling 3 31 Judo 4 40 Triathlon PRIMARY counters Conflict algorithm counter diff : ndb_conflict_fn_epoch2 1 ndb_conflict_fn_epoch2_trans 0 ndb_conflict_trans_reject_count 0 ndb_conflict_epoch_delete_delete_count 1 ndb_conflict_refresh_op_count 0 reflected_op_prepare_count_greater_than_zero 0 any_reflected_ops_applied 0 last_conflict_epoch_increased 1 conflict_handling_in_progess 1 stable_epoch_is_older_than_max_replicated 0 Re-enable SECONDARY Slave, and check state there START SLAVE; SECONDARY content select * from test.t1 order by k; k v c 1 10 Swimming 2 20 Cycling 3 31 Judo 4 40 Triathlon SECONDARY counters Conflict algorithm counter diff : ndb_conflict_fn_epoch2 0 ndb_conflict_fn_epoch2_trans 0 ndb_conflict_trans_reject_count 0 ndb_conflict_epoch_delete_delete_count 0 ndb_conflict_refresh_op_count 0 reflected_op_prepare_count_greater_than_zero 1 any_reflected_ops_applied 1 last_conflict_epoch_increased 1 conflict_handling_in_progess 1 stable_epoch_is_older_than_max_replicated 1 Look at PRIMARY exceptions table content SELECT k, v$old, v$new, c$old, c$new, ndb$op_type, ndb$cft_cause from test.t1$EX order by ndb$count; k v$old v$new c$old c$new ndb$op_type ndb$cft_cause 3 30 NULL Running NULL delete_row row_already_exists Now check behaviour of Secondary when reflected ops should not be applied ------------------------------------------------------------------------- The interpreted program attached to reflected ops at the Secondary slave is intended to avoid an 'old' reflected op overwriting a 'new' locally inserted row value. The end result should still be the same (the new value will be applied later, but we should avoid having every modification made at the secondary applied twice with some time lag as that will cause chaos for Secondary applications) Stop Slave on SECONDARY STOP SLAVE; Stop Slave on PRIMARY STOP SLAVE; Delete row 4 on PRIMARY DELETE from test.t1 where k=4; Primary state select * from test.t1 order by k; k v c 1 10 Swimming 2 20 Cycling 3 31 Judo Delete row 4 on SECONDARY DELETE from test.t1 where k=4; Follow with INSERT on SECONDARY INSERT into test.t1 values (4, 440, "Fell running"); Secondary state : select * from test.t1 order by k; k v c 1 10 Swimming 2 20 Cycling 3 31 Judo 4 440 Fell running Allow Primary change to propagate to Secondary (Which will delete the new, updated row on the Secondary) START SLAVE; Examine data on the SECONDARY - row 4 deleted select * from test.t1 order by k; k v c 1 10 Swimming 2 20 Cycling 3 31 Judo Now allow the SECONDARY Binlog to propagate back to the PRIMARY while blocking the return path... STOP SLAVE; START SLAVE; Examine data on the PRIMARY - row 4 exists as the PRIMARY's delete is not applied if present select * from test.t1 order by k; k v c 1 10 Swimming 2 20 Cycling 3 31 Judo 4 440 Fell running Now stop the PRIMARY Slave - changes from the SECONDARY cannot now reach the PRIMARY STOP SLAVE; Now go back to the SECONDARY and create a new row version First show there is no row 4 on the SECONDARY select * from test.t1 order by k; k v c 1 10 Swimming 2 20 Cycling 3 31 Judo INSERT into test.t1 values (4, 4444, "Cyclo-cross"); select * from test.t1 order by k; k v c 1 10 Swimming 2 20 Cycling 3 31 Judo 4 4444 Cyclo-cross Now allow the Binlog of the PRIMARY (containing the reflected DELETE + Insert (4, 440, "Fell running") to be applied locally The SECONDARY should reject this application START SLAVE; Examine data on the SECONDARY : Row 4 should be untouched (4, 4444, "Cyclo-cross"). Insert will be rejected as row already exists. select * from test.t1 order by k; k v c 1 10 Swimming 2 20 Cycling 3 31 Judo 4 4444 Cyclo-cross Show operation counter diff on the SECONDARY Should show reflected op prepared + rejected. Should show equal, non-zero reflected op prep+reject counts Conflict algorithm counter diff : ndb_conflict_fn_epoch2 0 ndb_conflict_fn_epoch2_trans 0 ndb_conflict_trans_reject_count 0 ndb_conflict_epoch_delete_delete_count 0 ndb_conflict_refresh_op_count 0 reflected_op_prepare_count_greater_than_zero 1 any_reflected_ops_applied 0 last_conflict_epoch_increased 0 conflict_handling_in_progess 0 stable_epoch_is_older_than_max_replicated 0 Ok, now allow SECONDARY Binlog to propagate to Primary and realign it START SLAVE; Show data on PRIMARY select * from test.t1 order by k; k v c 1 10 Swimming 2 20 Cycling 3 31 Judo 4 440 Fell running Allow reflection back to the SECONDARY... Now show same for UPDATE, then DELETE ------------------------------------- First stop SLAVEs STOP SLAVE; STOP SLAVE; Now perform UPDATE 1 at Secondary UPDATE test.t1 SET c="Bathing" where k=1; Show data on Secondary select * from test.t1 order by k; k v c 1 10 Bathing 2 20 Cycling 3 31 Judo 4 440 Fell running Data on Primary select * from test.t1 order by k; k v c 1 10 Swimming 2 20 Cycling 3 31 Judo 4 440 Fell running Now propagate to Primary... START SLAVE; Updated data on Primary select * from test.t1 order by k; k v c 1 10 Bathing 2 20 Cycling 3 31 Judo 4 440 Fell running Now stop Primary slave to stop further propagation STOP SLAVE; Now make update 2 on Secondary update test.t1 SET c="Paddling" where k=1; Data on Secondary select * from test.t1 order by k; k v c 1 10 Paddling 2 20 Cycling 3 31 Judo 4 440 Fell running Now allow Primary binlog, containing reflected update op setting column c of row 1 to "Bathing" to be applied it should be rejected by the Secondary, and increment the defined + rejected counts START SLAVE; Data on Secondary (should be unchanged) select * from test.t1 order by k; k v c 1 10 Paddling 2 20 Cycling 3 31 Judo 4 440 Fell running Conflict counts on Secondary (incremented preped + rejected) Conflict algorithm counter diff : ndb_conflict_fn_epoch2 0 ndb_conflict_fn_epoch2_trans 0 ndb_conflict_trans_reject_count 0 ndb_conflict_epoch_delete_delete_count 0 ndb_conflict_refresh_op_count 1 reflected_op_prepare_count_greater_than_zero 1 any_reflected_ops_applied 0 last_conflict_epoch_increased 1 conflict_handling_in_progess 0 stable_epoch_is_older_than_max_replicated 0 Now allow sync... START SLAVE; Allowing the sync should have allowed the second update (To 'Paddling') to be reflected, and rejected Data on Secondary (should be unchanged) select * from test.t1 order by k; k v c 1 10 Paddling 2 20 Cycling 3 31 Judo 4 440 Fell running Conflict counts on Secondary (incremented preped + rejected) Conflict algorithm counter diff : ndb_conflict_fn_epoch2 0 ndb_conflict_fn_epoch2_trans 0 ndb_conflict_trans_reject_count 0 ndb_conflict_epoch_delete_delete_count 0 ndb_conflict_refresh_op_count 1 reflected_op_prepare_count_greater_than_zero 1 any_reflected_ops_applied 0 last_conflict_epoch_increased 1 conflict_handling_in_progess 0 stable_epoch_is_older_than_max_replicated 0 Show same for DELETE -------------------- First stop SLAVEs STOP SLAVE; STOP SLAVE; Now perform DELETE of row 2 at Secondary DELETE from test.t1 where k=2; Show data on Secondary select * from test.t1 order by k; k v c 1 10 Paddling 3 31 Judo 4 440 Fell running Data on Primary select * from test.t1 order by k; k v c 1 10 Paddling 2 20 Cycling 3 31 Judo 4 440 Fell running Now propagate to Primary... START SLAVE; Updated data on Primary select * from test.t1 order by k; k v c 1 10 Paddling 3 31 Judo 4 440 Fell running Now stop Primary slave to stop further propagation STOP SLAVE; Now make a further change on Secondary INSERT into test.t1 VALUES (2, 22, "Rock-climbing"); Data on Secondary select * from test.t1 order by k; k v c 1 10 Paddling 2 22 Rock-climbing 3 31 Judo 4 440 Fell running Now allow Primary binlog, containing reflected delete op on row 2 to be applied it should be rejected by the Secondary, and increment the defined + rejected counts START SLAVE; Data on Secondary (should be unchanged) select * from test.t1 order by k; k v c 1 10 Paddling 2 22 Rock-climbing 3 31 Judo 4 440 Fell running Conflict counts on Secondary (incremented preped + rejected) Conflict algorithm counter diff : ndb_conflict_fn_epoch2 0 ndb_conflict_fn_epoch2_trans 0 ndb_conflict_trans_reject_count 0 ndb_conflict_epoch_delete_delete_count 0 ndb_conflict_refresh_op_count 0 reflected_op_prepare_count_greater_than_zero 1 any_reflected_ops_applied 0 last_conflict_epoch_increased 0 conflict_handling_in_progess 0 stable_epoch_is_older_than_max_replicated 0 Now allow sync... START SLAVE; Allowing the sync should have allowed the insert (To 'Rock-climbing') to be reflected, and rejected Data on Secondary (should be unchanged) select * from test.t1 order by k; k v c 1 10 Paddling 2 22 Rock-climbing 3 31 Judo 4 440 Fell running Conflict counts on Secondary (incremented preped + rejected) Conflict algorithm counter diff : ndb_conflict_fn_epoch2 0 ndb_conflict_fn_epoch2_trans 0 ndb_conflict_trans_reject_count 0 ndb_conflict_epoch_delete_delete_count 0 ndb_conflict_refresh_op_count 0 reflected_op_prepare_count_greater_than_zero 1 any_reflected_ops_applied 0 last_conflict_epoch_increased 0 conflict_handling_in_progess 0 stable_epoch_is_older_than_max_replicated 0 Primary insert-delete obscures Secondary insert problem ------------------------------------------------------- Stop slaves in both directions STOP SLAVE; STOP SLAVE; Start with non-existent row (5, 50, "Disco dancing") on primary insert into test.t1 values (5, 50, "Disco dancing"); select * from test.t1 order by k; k v c 1 10 Paddling 2 22 Rock-climbing 3 31 Judo 4 440 Fell running 5 50 Disco dancing Reset conflict counters on Primary Empty exceptions table on Primary DELETE from test.t1$EX; Insert non-existent row (5, 500, "Line dancing") on secondary insert into test.t1 values (5, 500, "Line dancing"); select * from test.t1 order by k; k v c 1 10 Paddling 2 22 Rock-climbing 3 31 Judo 4 440 Fell running 5 500 Line dancing Reset conflict counters on Secondary Allow Primary insert to trample Secondary insert. START SLAVE; select * from test.t1 order by k; k v c 1 10 Paddling 2 22 Rock-climbing 3 31 Judo 4 440 Fell running 5 50 Disco dancing Secondary now updates the row set by the Primary update test.t1 set v=v+5 where k=5; select * from test.t1 order by k; k v c 1 10 Paddling 2 22 Rock-climbing 3 31 Judo 4 440 Fell running 5 55 Disco dancing Stop Secondary Slave again STOP SLAVE; Now delete row from the primary delete from test.t1 where k=5; select * from test.t1 order by k; k v c 1 10 Paddling 2 22 Rock-climbing 3 31 Judo 4 440 Fell running Now allow Secondary writes to propagate to Primary START SLAVE; Expect that the Secondary insert succeeded as no row existed on arrival, but then the secondary row was trampled by the primary, and then a secondary update was applied... So what do we see at the Primary? select * from test.t1 order by k; k v c 1 10 Paddling 2 22 Rock-climbing 3 31 Judo 4 440 Fell running 5 55 Disco dancing Show primary conflict info counter diff - expect nothing. Conflict algorithm counter diff : ndb_conflict_fn_epoch2 0 ndb_conflict_fn_epoch2_trans 0 ndb_conflict_trans_reject_count 0 ndb_conflict_epoch_delete_delete_count 0 ndb_conflict_refresh_op_count 0 reflected_op_prepare_count_greater_than_zero 0 any_reflected_ops_applied 0 last_conflict_epoch_increased 0 conflict_handling_in_progess 0 stable_epoch_is_older_than_max_replicated 0 Show primary's exceptions table content - expect there to be none. SELECT k, v$old, v$new, c$old, c$new, ndb$op_type, ndb$cft_cause from test.t1$EX order by ndb$count; k v$old v$new c$old c$new ndb$op_type ndb$cft_cause Now allow Primary changes to propagate back to Secondary START SLAVE; Look at Secondary content select * from test.t1 order by k; k v c 1 10 Paddling 2 22 Rock-climbing 3 31 Judo 4 440 Fell running 5 55 Disco dancing Look at Secondary conflict counters diff - showing reflected ops applied on Secondary Conflict algorithm counter diff : ndb_conflict_fn_epoch2 0 ndb_conflict_fn_epoch2_trans 0 ndb_conflict_trans_reject_count 0 ndb_conflict_epoch_delete_delete_count 0 ndb_conflict_refresh_op_count 0 reflected_op_prepare_count_greater_than_zero 1 any_reflected_ops_applied 1 last_conflict_epoch_increased 1 conflict_handling_in_progess 1 stable_epoch_is_older_than_max_replicated 1 select * from test.t1 order by k; k v c 1 10 Paddling 2 22 Rock-climbing 3 31 Judo 4 440 Fell running 5 55 Disco dancing Now test SCR_PASS ----------------- SCR_PASS is a slave conflict role which should act as a filterless pass-through of replication events, with no conflict detection etc. The idea is that it might be useful for failover situations etc. Here we test that it does not detect conflicts, and allows divergence etc. Lets set it up STOP SLAVE; set global ndb_slave_conflict_role="NONE"; set global ndb_slave_conflict_role="PASS"; START SLAVE; STOP SLAVE; set global ndb_slave_conflict_role="NONE"; set global ndb_slave_conflict_role="PASS"; START SLAVE; Initial data on Primary select * from test.t1 order by k; k v c 1 10 Paddling 2 22 Rock-climbing 3 31 Judo 4 440 Fell running 5 55 Disco dancing Initial data on Secondary select * from test.t1 order by k; k v c 1 10 Paddling 2 22 Rock-climbing 3 31 Judo 4 440 Fell running 5 55 Disco dancing STOP SLAVE on Secondary STOP SLAVE; Create a conflict between two updates First at the primary update test.t1 set c="Capoiera" where c="Judo"; select * from test.t1 order by k; k v c 1 10 Paddling 2 22 Rock-climbing 3 31 Capoiera 4 440 Fell running 5 55 Disco dancing Now at the secondary update test.t1 set c="Wing chun" where c="Judo"; select * from test.t1 order by k; k v c 1 10 Paddling 2 22 Rock-climbing 3 31 Wing chun 4 440 Fell running 5 55 Disco dancing Now restart the secondary slave and allow propagation START SLAVE; Synchronise Now look at primary content and conflict counters select * from test.t1 order by k; k v c 1 10 Paddling 2 22 Rock-climbing 3 31 Wing chun 4 440 Fell running 5 55 Disco dancing Conflict algorithm counter diff : ndb_conflict_fn_epoch2 0 ndb_conflict_fn_epoch2_trans 0 ndb_conflict_trans_reject_count 0 ndb_conflict_epoch_delete_delete_count 0 ndb_conflict_refresh_op_count 0 reflected_op_prepare_count_greater_than_zero 0 any_reflected_ops_applied 0 last_conflict_epoch_increased 0 conflict_handling_in_progess 0 stable_epoch_is_older_than_max_replicated 0 Now look at secondary content and conflict counters select * from test.t1 order by k; k v c 1 10 Paddling 2 22 Rock-climbing 3 31 Capoiera 4 440 Fell running 5 55 Disco dancing Conflict algorithm counter diff : ndb_conflict_fn_epoch2 0 ndb_conflict_fn_epoch2_trans 0 ndb_conflict_trans_reject_count 0 ndb_conflict_epoch_delete_delete_count 0 ndb_conflict_refresh_op_count 0 reflected_op_prepare_count_greater_than_zero 0 any_reflected_ops_applied 0 last_conflict_epoch_increased 0 conflict_handling_in_progess 0 stable_epoch_is_older_than_max_replicated 0 Now look at how row existence errors are handled PRIMARY insert into test.t1 values (6, 60, "Cigars"); insert into test.t1 values (7, 70, "Whisky"); Synchronise Cause misalignment via 'secret' deletes. PRIMARY set sql_log_bin=0; delete from test.t1 where k=7; set sql_log_bin=1; SECONDARY set sql_log_bin=0; delete from test.t1 where k=6; set sql_log_bin=1; Synchronise Show start state Primary : select * from test.t1 order by k; k v c 1 10 Paddling 2 22 Rock-climbing 3 31 Wing chun 4 440 Fell running 5 55 Disco dancing 6 60 Cigars Secondary : select * from test.t1 order by k; k v c 1 10 Paddling 2 22 Rock-climbing 3 31 Capoiera 4 440 Fell running 5 55 Disco dancing 7 70 Whisky Now insert a row on the Secondary which already exists on the Primary insert into test.t1 values (6,66, "Snuff"); select * from test.t1 order by k; k v c 1 10 Paddling 2 22 Rock-climbing 3 31 Capoiera 4 440 Fell running 5 55 Disco dancing 6 66 Snuff 7 70 Whisky Show that the primary was overwritten with the Secondary's value, and no conflict reported. select * from test.t1 order by k; k v c 1 10 Paddling 2 22 Rock-climbing 3 31 Wing chun 4 440 Fell running 5 55 Disco dancing 6 66 Snuff Conflict algorithm counter diff : ndb_conflict_fn_epoch2 0 ndb_conflict_fn_epoch2_trans 0 ndb_conflict_trans_reject_count 0 ndb_conflict_epoch_delete_delete_count 0 ndb_conflict_refresh_op_count 0 reflected_op_prepare_count_greater_than_zero 0 any_reflected_ops_applied 0 last_conflict_epoch_increased 0 conflict_handling_in_progess 0 stable_epoch_is_older_than_max_replicated 0 Same for a Secondary sourced update of a row which doesn't exist on the primary. update test.t1 set c="Tawny Port" where c="Whisky"; select * from test.t1 order by k; k v c 1 10 Paddling 2 22 Rock-climbing 3 31 Capoiera 4 440 Fell running 5 55 Disco dancing 6 66 Snuff 7 70 Tawny Port Show state on Primary. No row, but also no conflicts or slave errors. select * from test.t1 order by k; k v c 1 10 Paddling 2 22 Rock-climbing 3 31 Wing chun 4 440 Fell running 5 55 Disco dancing 6 66 Snuff Conflict algorithm counter diff : ndb_conflict_fn_epoch2 0 ndb_conflict_fn_epoch2_trans 0 ndb_conflict_trans_reject_count 0 ndb_conflict_epoch_delete_delete_count 0 ndb_conflict_refresh_op_count 0 reflected_op_prepare_count_greater_than_zero 0 any_reflected_ops_applied 0 last_conflict_epoch_increased 0 conflict_handling_in_progess 0 stable_epoch_is_older_than_max_replicated 0 Now show a row delete from the secondary for a row which does not exist on the primary delete from test.t1 where k=7; select * from test.t1 order by k; k v c 1 10 Paddling 2 22 Rock-climbing 3 31 Capoiera 4 440 Fell running 5 55 Disco dancing 6 66 Snuff Show state on Primary. No conflicts or slave errors select * from test.t1 order by k; k v c 1 10 Paddling 2 22 Rock-climbing 3 31 Wing chun 4 440 Fell running 5 55 Disco dancing 6 66 Snuff Conflict algorithm counter diff : ndb_conflict_fn_epoch2 0 ndb_conflict_fn_epoch2_trans 0 ndb_conflict_trans_reject_count 0 ndb_conflict_epoch_delete_delete_count 0 ndb_conflict_refresh_op_count 0 reflected_op_prepare_count_greater_than_zero 0 any_reflected_ops_applied 0 last_conflict_epoch_increased 0 conflict_handling_in_progess 0 stable_epoch_is_older_than_max_replicated 0 Remove inconsistencies from the table delete from test.t1 where k in (3, 6); STOP SLAVE; set global ndb_slave_conflict_role="NONE"; set global ndb_slave_conflict_role="PRIMARY"; START SLAVE; STOP SLAVE; set global ndb_slave_conflict_role="NONE"; set global ndb_slave_conflict_role="SECONDARY"; START SLAVE; Test ndb_conflict_last_stable_epoch This status var is intended to help in situations where there is an unexpected PRIMARY failure, and the SECONDARY can determine that there were in-flight realignment ops (conflicts), based on ndb_conflict_last_conflict_epoch > ndb_slave_max_replicated_epoch ndb_conflict_last_stable_epoch will contain the last (highest) SECONDARY epoch which is known to have replicated via the PRIMARY with no conflicts being discovered. This is then a consistent baseline from which to potentially resolve any partial realignments. How to resolve them is an exercise left for the reader :) Testcase to show the variable in action Stop SECONDARY slave STOP SLAVE; Change on Primary, won't propagate to Secondary as SLAVE is stopped. update test.t1 set c="Loafing" where k=1; Conflicting change on Secondary update test.t1 set c="Idling" where k=1; Add some epochs after the conflicting modification insert into t1 values (10 + 10, 10, "Sequencing"); insert into t1 values (9 + 10, 10, "Sequencing"); insert into t1 values (8 + 10, 10, "Sequencing"); insert into t1 values (7 + 10, 10, "Sequencing"); insert into t1 values (6 + 10, 10, "Sequencing"); insert into t1 values (5 + 10, 10, "Sequencing"); insert into t1 values (4 + 10, 10, "Sequencing"); insert into t1 values (3 + 10, 10, "Sequencing"); insert into t1 values (2 + 10, 10, "Sequencing"); insert into t1 values (1 + 10, 10, "Sequencing"); Now look at Secondary values, should have Max_Replicated_Epoch == Last_Stable_Epoch Expect 1,0,1 - all is well. SELECT (@ndb_last_conflict_epoch+0) <= (@ndb_max_replicated_epoch+0) AS SECONDARY_IS_CURRENTLY_CONFLICT_FREE; SECONDARY_IS_CURRENTLY_CONFLICT_FREE 1 SELECT (@ndb_last_stable_epoch+0) < (@ndb_max_replicated_epoch+0) AS STABLE_EPOCH_LAGS_MAX_REPLICATED_EPOCH; STABLE_EPOCH_LAGS_MAX_REPLICATED_EPOCH 0 SELECT (@ndb_last_stable_epoch+0) = (@ndb_max_replicated_epoch+0) AS STABLE_EPOCH_IS_MAX_REPLICATED_EPOCH; STABLE_EPOCH_IS_MAX_REPLICATED_EPOCH 1 Stop PRIMARY slave just to have control STOP SLAVE; Conflict algorithm counter diff : ndb_conflict_fn_epoch2 1 ndb_conflict_fn_epoch2_trans 0 ndb_conflict_trans_reject_count 0 ndb_conflict_epoch_delete_delete_count 0 ndb_conflict_refresh_op_count 0 reflected_op_prepare_count_greater_than_zero 0 any_reflected_ops_applied 0 last_conflict_epoch_increased 1 conflict_handling_in_progess 1 stable_epoch_is_older_than_max_replicated 0 Now Start SECONDARY slave, to get conflict realignment and following SECONDARY epochs re-applied on the SEOCNDARY START SLAVE; Now look at variables on the SECONDARY again Expect 0,1,0 - Conflict handling open, stable epoch is old, most recent replicated epochs are not yet stable. SELECT (@ndb_last_conflict_epoch+0) <= (@ndb_max_replicated_epoch+0) AS SECONDARY_IS_CURRENTLY_CONFLICT_FREE; SECONDARY_IS_CURRENTLY_CONFLICT_FREE 0 SELECT (@ndb_last_stable_epoch+0) < (@ndb_max_replicated_epoch+0) AS STABLE_EPOCH_LAGS_MAX_REPLICATED_EPOCH; STABLE_EPOCH_LAGS_MAX_REPLICATED_EPOCH 1 SELECT (@ndb_last_stable_epoch+0) = (@ndb_max_replicated_epoch+0) AS STABLE_EPOCH_IS_MAX_REPLICATED_EPOCH; STABLE_EPOCH_IS_MAX_REPLICATED_EPOCH 0 Now make a SECONDARY change and allow it to flow START SLAVE; delete from test.t1 where k >=10; Now look at variables on the SECONDARY for third time Expect 1,0,1 - stability has returned SELECT (@ndb_last_conflict_epoch+0) <= (@ndb_max_replicated_epoch+0) AS SECONDARY_IS_CURRENTLY_CONFLICT_FREE; SECONDARY_IS_CURRENTLY_CONFLICT_FREE 1 SELECT (@ndb_last_stable_epoch+0) < (@ndb_max_replicated_epoch+0) AS STABLE_EPOCH_LAGS_MAX_REPLICATED_EPOCH; STABLE_EPOCH_LAGS_MAX_REPLICATED_EPOCH 0 SELECT (@ndb_last_stable_epoch+0) = (@ndb_max_replicated_epoch+0) AS STABLE_EPOCH_IS_MAX_REPLICATED_EPOCH; STABLE_EPOCH_IS_MAX_REPLICATED_EPOCH 1 Done. Cleanup conflict roles -------------------- STOP SLAVE; set global ndb_slave_conflict_role="NONE"; START SLAVE; STOP SLAVE; set global ndb_slave_conflict_role="NONE"; START SLAVE; stop slave; reset slave; drop table test.t1; drop table test.t1$EX; drop table mysql.ndb_replication; include/rpl_end.inc
Close