mirror of
				https://github.com/MariaDB/server.git
				synced 2025-10-31 19:06:14 +01:00 
			
		
		
		
	 cbf60dba74
			
		
	
	
	cbf60dba74
	
	
	
		
			
			I spent 4 hours on work and 12 hours of testing to try to find the reason for aria crashing in recovery when starting a new test, in which case the 'data directory' should be a copy of "install.db", but aria_log.00000001 content was not correct. The following changes are mostly done to make it a bit easier to find out more in case of future similar crashes: - Mark last_checkpoint_lsn volatile (safety). - Write checkpoint message to aria_recovery.trace - When compling with DBUG and with HAVE_DBUG_TRANSLOG_SRC, use checksum's for Aria log pages. We cannot have it on by default for DBUG servers yet as there is bugs when changing CRC between restarts. - Added a message to mtr --verbose when copying the data directory. - Removed extra linefeed in Aria recovery message (cleanup)
		
			
				
	
	
		
			149 lines
		
	
	
	
		
			4.9 KiB
		
	
	
	
		
			C
		
	
	
	
	
	
			
		
		
	
	
			149 lines
		
	
	
	
		
			4.9 KiB
		
	
	
	
		
			C
		
	
	
	
	
	
| /* Copyright (C) 2006,2007,2008 MySQL AB
 | |
| 
 | |
|    This program is free software; you can redistribute it and/or modify
 | |
|    it under the terms of the GNU General Public License as published by
 | |
|    the Free Software Foundation; version 2 of the License.
 | |
| 
 | |
|    This program is distributed in the hope that it will be useful,
 | |
|    but WITHOUT ANY WARRANTY; without even the implied warranty of
 | |
|    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 | |
|    GNU General Public License for more details.
 | |
| 
 | |
|    You should have received a copy of the GNU General Public License
 | |
|    along with this program; if not, write to the Free Software
 | |
|    Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1335 USA */
 | |
| 
 | |
| /*
 | |
|   Q: Why isn't ma_recovery_util.c simply moved to ma_recovery.c ?
 | |
| 
 | |
|   A: ma_recovery.c, because it invokes objects from ma_check.c (like
 | |
|   maria_chk_init()) causes the following problem:
 | |
|   if a source file a.c of a program invokes a function defined in
 | |
|   ma_recovery.c, then a.o depends on ma_recovery.o which depends on
 | |
|   ma_check.o: linker thus brings in ma_check.o. That brings in the
 | |
|   dependencies of ma_check.o which are definitions of _ma_check_print_info()
 | |
|   etc; if a.o does not define them then the ones of ha_maria.o are used
 | |
|   i.e. ha_maria.o is linked into the program, and this brings in dependencies
 | |
|   of ha_maria.o on mysqld.o into the program's linking which thus fails, as
 | |
|   the program is not linked with mysqld.o.
 | |
|   Thus, while several functions defined in ma_recovery.c could be useful to
 | |
|   other files, they cannot be used by them.
 | |
|   So we are going to gradually move a great share of ma_recovery.c's exported
 | |
|   functions into the present file, to isolate the problematic components and
 | |
|   avoid the problem.
 | |
| */
 | |
| 
 | |
| #include "maria_def.h"
 | |
| 
 | |
| HASH all_dirty_pages;
 | |
| struct st_dirty_page /* used only in the REDO phase */
 | |
| {
 | |
|   uint64 file_and_page_id;
 | |
|   LSN rec_lsn;
 | |
| };
 | |
| /*
 | |
|   LSN after which dirty pages list does not apply. Can be slightly before
 | |
|   when ma_checkpoint_execute() started.
 | |
| */
 | |
| LSN checkpoint_start= LSN_IMPOSSIBLE;
 | |
| 
 | |
| /** @todo looks like duplicate of recovery_message_printed */
 | |
| my_bool procent_printed;
 | |
| FILE *tracef; /**< trace file for debugging */
 | |
| 
 | |
| ulong recovery_found_crashed_tables;
 | |
| uint skipped_lsn_err_count;
 | |
| 
 | |
| /** @brief Prints to a trace file if it is not NULL */
 | |
| void tprint(FILE *trace_file __attribute__ ((unused)),
 | |
|             const char *format __attribute__ ((unused)), ...)
 | |
| {
 | |
|   va_list args;
 | |
| #ifndef DBUG_OFF
 | |
|   {
 | |
|     char buff[1024];
 | |
|     size_t length;
 | |
|     va_start(args, format);
 | |
|     length= my_vsnprintf(buff, sizeof(buff)-1, format, args);
 | |
|     if (length && buff[length-1] == '\n')
 | |
|       buff[length-1]= 0;                      /* Don't print end \n */
 | |
|     DBUG_PRINT("info", ("%s", buff));
 | |
|     va_end(args);
 | |
|   }
 | |
| #endif
 | |
|   va_start(args, format);
 | |
|   if (trace_file != NULL)
 | |
|     vfprintf(trace_file, format, args);
 | |
|   va_end(args);
 | |
| }
 | |
| 
 | |
| 
 | |
| void eprint(FILE *trace_file __attribute__ ((unused)),
 | |
|             const char *format __attribute__ ((unused)), ...)
 | |
| {
 | |
|   va_list args;
 | |
|   va_start(args, format);
 | |
|   DBUG_PRINT("error", ("%s", format));
 | |
|   if (!trace_file)
 | |
|     trace_file= stderr;
 | |
| 
 | |
|   if (procent_printed && trace_file == stderr)
 | |
|   {
 | |
|     procent_printed= 0;
 | |
|     /* In silent mode, print on another line than the 0% 10% 20% line */
 | |
|     fputc('\n', stderr);
 | |
|     fflush(stderr);
 | |
|   }
 | |
|   vfprintf(trace_file , format, args);
 | |
|   fputc('\n', trace_file);
 | |
|   if (trace_file != stderr)
 | |
|   {
 | |
|     va_start(args, format);
 | |
|     my_printv_error(HA_ERR_INITIALIZATION, format, MYF(0), args);
 | |
|   }
 | |
|   va_end(args);
 | |
|   fflush(trace_file);
 | |
| }
 | |
| 
 | |
| 
 | |
| /**
 | |
|    Tells if the dirty pages list found in checkpoint record allows to ignore a
 | |
|    REDO for a certain page.
 | |
| 
 | |
|    @param  shortid         short id of the table
 | |
|    @param  lsn             REDO record's LSN
 | |
|    @param  page            page number
 | |
|    @param  index           TRUE if index page, FALSE if data page
 | |
| */
 | |
| 
 | |
| my_bool _ma_redo_not_needed_for_page(uint16 shortid, LSN lsn,
 | |
|                                      pgcache_page_no_t page,
 | |
|                                      my_bool index)
 | |
| {
 | |
|   if (cmp_translog_addr(lsn, checkpoint_start) < 0)
 | |
|   {
 | |
|     /*
 | |
|       64-bit key is formed like this:
 | |
|       Most significant byte: 0 if data page, 1 if index page
 | |
|       Next 2 bytes: table's short id
 | |
|       Next 5 bytes: page number
 | |
|     */
 | |
|     char llbuf[22];
 | |
|     uint64 file_and_page_id=
 | |
|       (((uint64)((index << 16) | shortid)) << 40) | page;
 | |
|     struct st_dirty_page *dirty_page= (struct st_dirty_page *)
 | |
|       my_hash_search(&all_dirty_pages,
 | |
|                   (uchar *)&file_and_page_id, sizeof(file_and_page_id));
 | |
|     DBUG_PRINT("info", ("page %lld in dirty pages list: %d",
 | |
|                         (ulonglong) page,
 | |
|                         dirty_page != NULL));
 | |
|     if ((dirty_page == NULL) ||
 | |
|         cmp_translog_addr(lsn, dirty_page->rec_lsn) < 0)
 | |
|     {
 | |
|       tprint(tracef, ", ignoring page %s because of dirty_pages list\n",
 | |
|              llstr((ulonglong) page, llbuf));
 | |
|       return TRUE;
 | |
|     }
 | |
|   }
 | |
|   return FALSE;
 | |
| }
 |