 3dd9298b18
			
		
	
	3dd9298b18
	
	
	
		
			
			Added a test that makes sure the transaction replay cap is respected. Also improved the logging to show how many transaction replay attemps have been done and to log if a replay is not done due to too many attempts.
		
			
				
	
	
		
			84 lines
		
	
	
		
			2.4 KiB
		
	
	
	
		
			C++
		
	
	
	
	
	
			
		
		
	
	
			84 lines
		
	
	
		
			2.4 KiB
		
	
	
	
		
			C++
		
	
	
	
	
	
| /**
 | |
|  * MXS-2456: Cap transaction replay attempts
 | |
|  * https://jira.mariadb.org/browse/MXS-2456
 | |
|  */
 | |
| 
 | |
| #include "testconnections.h"
 | |
| 
 | |
| #define EXPECT(a) test.expect(a, "%s", "Assertion failed: " #a)
 | |
| 
 | |
| void test_replay_ok(TestConnections& test)
 | |
| {
 | |
|     Connection c = test.maxscales->rwsplit();
 | |
|     EXPECT(c.connect());
 | |
|     EXPECT(c.query("BEGIN"));
 | |
|     EXPECT(c.query("SELECT 1"));
 | |
|     EXPECT(c.query("SELECT SLEEP(15)"));
 | |
| 
 | |
|     // Block the node where the transaction was started
 | |
|     test.repl->block_node(0);
 | |
|     test.maxscales->wait_for_monitor();
 | |
|     sleep(5);
 | |
| 
 | |
|     // Then block the node where the transaction replay is attempted before the last statement finishes
 | |
|     test.repl->block_node(1);
 | |
|     test.maxscales->wait_for_monitor();
 | |
|     sleep(5);
 | |
| 
 | |
|     // The next query should succeed as we do two replay attempts
 | |
|     test.expect(c.query("SELECT 2"), "Two transaction replays should work");
 | |
| 
 | |
|     // Reset the replication
 | |
|     test.repl->unblock_node(1);
 | |
|     test.repl->unblock_node(0);
 | |
|     test.maxscales->wait_for_monitor();
 | |
|     test.check_maxctrl("call command mariadbmon reset-replication MariaDB-Monitor server1");
 | |
|     test.maxscales->wait_for_monitor();
 | |
| }
 | |
| 
 | |
| void test_replay_failure(TestConnections& test)
 | |
| {
 | |
|     Connection c = test.maxscales->rwsplit();
 | |
|     c.connect();
 | |
|     c.query("BEGIN");
 | |
|     c.query("SELECT 1");
 | |
|     c.query("SELECT SLEEP(15)");
 | |
| 
 | |
|     // Block the node where the transaction was started
 | |
|     test.repl->block_node(0);
 | |
|     test.maxscales->wait_for_monitor();
 | |
|     sleep(5);
 | |
| 
 | |
|     // Then block the node where the first transaction replay is attempted
 | |
|     test.repl->block_node(1);
 | |
|     test.maxscales->wait_for_monitor();
 | |
|     sleep(5);
 | |
| 
 | |
|     // Block the final node before the replay completes
 | |
|     test.repl->block_node(2);
 | |
|     test.maxscales->wait_for_monitor();
 | |
|     sleep(5);
 | |
| 
 | |
|     // The next query should fail as we exceeded the cap of two replays
 | |
|     test.expect(!c.query("SELECT 2"), "Three transaction replays should NOT work");
 | |
| 
 | |
|     // Reset the replication
 | |
|     test.repl->unblock_node(2);
 | |
|     test.repl->unblock_node(1);
 | |
|     test.repl->unblock_node(0);
 | |
|     test.maxscales->wait_for_monitor();
 | |
|     test.check_maxctrl("call command mariadbmon reset-replication MariaDB-Monitor server1");
 | |
|     test.maxscales->wait_for_monitor();
 | |
| }
 | |
| 
 | |
| int main(int argc, char* argv[])
 | |
| {
 | |
|     Mariadb_nodes::require_gtid(true);
 | |
|     TestConnections test(argc, argv);
 | |
| 
 | |
|     test_replay_ok(test);
 | |
|     test_replay_failure(test);
 | |
| 
 | |
|     return test.global_result;
 | |
| }
 |