mirror of
				https://github.com/MariaDB/server.git
				synced 2025-10-31 10:56:12 +01:00 
			
		
		
		
	 5797cbaf4a
			
		
	
	
	5797cbaf4a
	
	
	
		
			
			order with Galera and encrypt-tmp-files=1 Problem:- If trans_cache (IO_CACHE) uses encrypted tmp file then on next DML server will crash. Case:- Lets take a case , we have a table t1 , We try to do 2 inserts in t1 1. A really long insert so that trans_cache has to use temp_file 2. Just a small insert Analysis:- Actually server crashes from inside of galera library. /lib64/libc.so.6(abort+0x175)[0x7fb5ba779dc5] /usr/lib64/galera/libgalera_smm.so(_ZN6galera3FSMINS_9TrxHandle5State... mysys/stacktrace.c:247(my_print_stacktrace)[0x7fb5a714940e] sql/signal_handler.cc:160(handle_fatal_signal)[0x7fb5a715c1bd] sql/wsrep_hton.cc:257(wsrep_rollback)[0x7fb5bcce923a] sql/wsrep_hton.cc:268(wsrep_rollback)[0x7fb5bcce9368] sql/handler.cc:1658(ha_rollback_trans(THD*, bool))[0x7fb5bcd4f41a] sql/handler.cc:1483(ha_commit_trans(THD*, bool))[0x7fb5bcd4f804] but actual issue is not in galera but in mariadb, because for 2nd insert we should never call rollback. We are calling rollback because log_and_order fails it fails because write_cache fails , It fails because after reinit_io_cache(trans_cache) , my_b_bytes_in_cache says 0 so we look into tmp_file for data , which is obviously wrong since temp was used for previous insert and it no longer exist. wsrep_write_cache_inc() reads the IO_CACHE in a loop, filling it with my_b_fill() until it returns "0 bytes read". Later MYSQL_BIN_LOG::write_cache() does the same. wsrep_write_cache_inc() assumes that reading a zero bytes past EOF leaves the old data in the cache Solution:- There is two issue in my_b_encr_read 1st we should never equal read_end to info->buffer. I mean this does not make sense read_end should always point to end of buffer. 2nd For most of the case(apart from async IO_CACHE) info->pos_in_file should be equal to info->buffer position wrt to temp file , since in this case we are not changing info->buffer it should remain unchanged.
		
			
				
	
	
		
			57 lines
		
	
	
	
		
			1.8 KiB
		
	
	
	
		
			Text
		
	
	
	
	
	
			
		
		
	
	
			57 lines
		
	
	
	
		
			1.8 KiB
		
	
	
	
		
			Text
		
	
	
	
	
	
| #  This file tests that mariadb cluster should not crash when encrypt_tmp_file
 | |
| #  is enabled
 | |
| 
 | |
| --source include/galera_cluster.inc
 | |
| --source include/have_innodb.inc
 | |
| 
 | |
| SELECT VARIABLE_VALUE = 'Synced' FROM INFORMATION_SCHEMA.GLOBAL_STATUS WHERE VARIABLE_NAME = 'wsrep_local_state_comment';
 | |
| SELECT VARIABLE_VALUE = 2 FROM INFORMATION_SCHEMA.GLOBAL_STATUS WHERE VARIABLE_NAME = 'wsrep_cluster_size';
 | |
| 
 | |
| CREATE TABLE t1 (f1 INTEGER PRIMARY KEY) Engine=InnoDB;
 | |
| INSERT INTO t1 VALUES (1);
 | |
| 
 | |
| --connection node_2
 | |
| SELECT VARIABLE_VALUE = 'Synced' FROM INFORMATION_SCHEMA.GLOBAL_STATUS WHERE VARIABLE_NAME = 'wsrep_local_state_comment';
 | |
| SELECT VARIABLE_VALUE = 2 FROM INFORMATION_SCHEMA.GLOBAL_STATUS WHERE VARIABLE_NAME = 'wsrep_cluster_size';
 | |
| 
 | |
| SELECT COUNT(*) = 1 FROM t1;
 | |
| 
 | |
| DROP TABLE t1;
 | |
| 
 | |
| --connection node_1
 | |
| 
 | |
| CREATE TABLE `t1` (
 | |
|   `col1` int(11) NOT NULL,
 | |
|   `col2` varchar(64) NOT NULL DEFAULT '',
 | |
|   `col3` varchar(32) NOT NULL DEFAULT '0',
 | |
|   `col4` varchar(64) NOT NULL DEFAULT '',
 | |
|   `col5` tinyint(4) NOT NULL DEFAULT '0',
 | |
|   `col6` int(11) NOT NULL DEFAULT '0',
 | |
|   `col7` varchar(64) NOT NULL DEFAULT '',
 | |
|   `col8` tinyint(4) NOT NULL DEFAULT '0',
 | |
|   `col9` tinyint(4) NOT NULL DEFAULT '0',
 | |
|   `col10` text NOT NULL,
 | |
|   `col11` varchar(255) NOT NULL DEFAULT '',
 | |
|   `col12` tinyint(4) NOT NULL DEFAULT '1'
 | |
| ) ;
 | |
| 
 | |
| #Although we just need $counter >= 907 for IO_CACHE to use
 | |
| #encrypted temp file. Just on safe side I am using $counter
 | |
| # = 1100
 | |
| --disable_query_log
 | |
| --let $counter=1100
 | |
| --let $query= (1,'test','test','test',0,0,'-1',0,0,'','',-1)
 | |
| while($counter)
 | |
| {
 | |
|   --let $query= $query ,(1,'test','test','test',0,0,'-1',0,0,'','',-1)
 | |
|   --dec $counter
 | |
| }
 | |
| --let $query= INSERT INTO t1 values $query ;
 | |
| --eval $query
 | |
| --enable_query_log
 | |
| #INSERT INTO `t1` VALUE
 | |
| 
 | |
| create table t2 (test int);
 | |
| insert into t2 values (1);
 | |
| 
 | |
| drop table t1,t2;
 |