MySQL Lists are EOL. Please join:

List:Commits« Previous MessageNext Message »
From:Vladislav Vaintroub Date:March 10 2009 10:14am
Subject:bzr commit into mysql-6.0-falcon-team branch (vvaintroub:3059) WL#4380
View as plain text  
#At file:///D:/bzr/error_hooks/ based on revid:christopher.powers@strippedijqaiv9ei

 3059 Vladislav Vaintroub	2009-03-10
      WL#4380 : Hooks for crashing Falcon and its recovery
      This patch implements controlled way to crash Falcon
      on specific points.
      - ability to crash the server before or after writing each log entry
      - ability to crash recovery while reading each log entry during each 
      of the recovery phases.
      
      To use the functionality variable falcon_error_inject is provided.
      The value might look like
      --falcon_error_inject=type=SerialLogAppend,param=26,iterations=1000
      meaning that falcon will crash after 1000 log entries of type 26
      (SRLUpdateRecords) are written.
      
      The variable can be specified via command line or also set during 
      runtime with "set global falcon_error_inject"
      
      The strings currently accepted for type are 
      - SerialLogAppend (crash hook after log entry is written),
      - RecoveryPhase1  (crash hook after record is processed in phase 1
        of recovery)
      - RecoveryPhase2 (crash hook after record is processed in phase 2
        of recovery)
      - RecoveryPhase3 (crash hook after record is processed in phase 3
        of recovery)
     @ storage/falcon/CMakeLists.txt
        New files ErrorInjector.cpp and ErrorInjector.h
     @ storage/falcon/ErrorInjector.cpp
        New file ErrorInjector.cpp that implements error hook functionality
     @ storage/falcon/ErrorInjector.h
        New file ErrorInjector.h
     @ storage/falcon/Makefile.am
        New files ErrorInjector.cpp and ErrorInjector.h
     @ storage/falcon/SerialLog.cpp
        Add error hooks for each phase of recovery
     @ storage/falcon/SerialLogRecord.h
        Add error hook after serial log entry is written
     @ storage/falcon/ha_falcon.cpp
        new parameter falcon_error_inject

    added:
      storage/falcon/ErrorInjector.cpp
      storage/falcon/ErrorInjector.h
    modified:
      storage/falcon/CMakeLists.txt
      storage/falcon/Makefile.am
      storage/falcon/SerialLog.cpp
      storage/falcon/SerialLogRecord.h
      storage/falcon/ha_falcon.cpp
=== modified file 'storage/falcon/CMakeLists.txt'
--- a/storage/falcon/CMakeLists.txt	2009-02-18 17:41:40 +0000
+++ b/storage/falcon/CMakeLists.txt	2009-03-10 10:14:43 +0000
@@ -41,7 +41,8 @@ SET(FALCON_SOURCES 
 		Bitmap.cpp 
 		BlobReference.cpp 
 		Btn.cpp 
-		Cache.cpp 
+		Cache.cpp
+		ErrorInjector.cpp
 		CmdGen.cpp
 		CollationCaseless.cpp 
 		CollationUnknown.cpp 
@@ -324,6 +325,7 @@ SET(FALCON_SOURCES 
 		Context.h 
 		Coterie.h
 		CoterieRange.h 
+		ErrorInjector.h
 		Database.h 
 		DatabaseBackup.h 
 		DatabaseClone.h 

=== added file 'storage/falcon/ErrorInjector.cpp'
--- a/storage/falcon/ErrorInjector.cpp	1970-01-01 00:00:00 +0000
+++ b/storage/falcon/ErrorInjector.cpp	2009-03-10 10:14:43 +0000
@@ -0,0 +1,62 @@
+/* Copyright (C) 2009 Sun Microsystems
+   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., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA */
+
+#include "Engine.h"
+#include "ErrorInjector.h"
+#include "Error.h"
+#include <stdlib.h>
+#include <string.h>
+
+ErrorInjector::ErrorInjector():
+	iterations(-1),type(InjectorTypeMax),param(0)
+{
+}
+
+// Global ErrorInjector variable, accessed as singleton
+static ErrorInjector errorInjectorInstance;
+
+ErrorInjector *ErrorInjector::getInstance()
+{
+	return &errorInjectorInstance;
+}
+
+
+void ErrorInjector::parse(const char *spec)
+{
+	if (strstr(spec, "type=SerialLogAppend"))
+		type = InjectorSerialLogAppend;
+	else if (strstr(spec,"type=RecoveryPhase1"))
+		type = InjectorRecoveryPhase1;
+	else if (strstr(spec,"type=RecoveryPhase2"))
+		type = InjectorRecoveryPhase2;
+	else if (strstr(spec,"type=RecoveryPhase3"))
+		type = InjectorRecoveryPhase3;
+	
+	param=-1;
+	const char *p= strstr(spec,"param=");
+	if(p)
+		param = atoi(p+6);
+		
+	p= strstr(spec, "iterations=");
+	if(p)
+		iterations = atoi(p+11);
+}
+
+
+void ErrorInjector::processEvent(InjectorEventType eventType , int eventParam)
+{
+	if (eventType == type && eventParam == param  && iterations > 0)
+		if (--iterations <= 0)
+			FATAL("Crash due to error injection");
+}
\ No newline at end of file

=== added file 'storage/falcon/ErrorInjector.h'
--- a/storage/falcon/ErrorInjector.h	1970-01-01 00:00:00 +0000
+++ b/storage/falcon/ErrorInjector.h	2009-03-10 10:14:43 +0000
@@ -0,0 +1,61 @@
+/* Copyright (C) 2009 Sun Microsystems
+   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., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA */
+
+#ifndef ErrorInjector_H
+#define ErrorInjector_H
+
+enum InjectorEventType{
+	InjectorSerialLogAppend = 0,
+	InjectorRecoveryPhase1 = 1,
+	InjectorRecoveryPhase2 = 2,
+	InjectorRecoveryPhase3 = 3,
+	InjectorTypeMax = 4 
+};
+
+
+class ErrorInjector
+{
+private:
+	int iterations;
+	InjectorEventType type;
+	int param;
+public:
+	
+	ErrorInjector();
+	
+	// Set crash injector parameters
+	// Function accepts strings like "type=SerialLogAppend,param=1,iterations=100"
+	void parse(const char *spec);
+	
+	// Process event. If event type, param and number of event occurences match 
+	// the parsed specification, force crash
+	void processEvent(InjectorEventType eventType, int eventParam);
+	
+	// get the singleton object
+	static ErrorInjector* getInstance();
+}; 
+
+
+// Macros for error injection. Dummies if NO_ERROR_INJECTOR is defined
+#ifndef NO_ERROR_INJECTOR
+#define ERROR_INJECTOR_EVENT(type, param) \
+	ErrorInjector::getInstance()->processEvent(type, param)
+#define ERROR_INJECTOR_PARSE(spec) \
+	ErrorInjector::getInstance()->parse(spec)
+#else
+#define ERROR_INJECTOR_EVENT(type, param)
+#define ERROR_INJECTOR_PARSE(type, param)
+#endif
+
+#endif

=== modified file 'storage/falcon/Makefile.am'
--- a/storage/falcon/Makefile.am	2009-02-18 17:41:40 +0000
+++ b/storage/falcon/Makefile.am	2009-03-10 10:14:43 +0000
@@ -43,6 +43,7 @@ falcon_headers= Agent.h Alias.h Applicat
 		CompareAndSwapSparc.il \
 		CompiledStatement.h Configuration.h Connection.h Context.h \
 		Coterie.h CoterieRange.h \
+		ErrorInjector.h \
 		Database.h \
 		DatabaseBackup.h \
 		DatabaseClone.h \
@@ -225,6 +226,7 @@ falcon_sources= Agent.cpp Alias.cpp \
 		CollationManager.cpp \
 		CompiledStatement.cpp Configuration.cpp \
 		Connection.cpp Context.cpp Coterie.cpp \
+		ErrorInjector.cpp \
 		CoterieRange.cpp \
 		Database.cpp \
 		DatabaseBackup.cpp \

=== modified file 'storage/falcon/SerialLog.cpp'
--- a/storage/falcon/SerialLog.cpp	2009-02-18 17:41:40 +0000
+++ b/storage/falcon/SerialLog.cpp	2009-03-10 10:14:43 +0000
@@ -44,6 +44,7 @@
 #include "TableSpaceManager.h"
 #include "TableSpace.h"
 #include "Gopher.h"
+#include "ErrorInjector.h"
 
 #ifdef _DEBUG
 #undef THIS_FILE
@@ -366,8 +367,8 @@ void SerialLog::recover()
 		{
 		if (++recordCount % RECORD_MAX == 0)
 			Log::log("Processed: %8ld\n", recordCount);
-			
 		record->pass1();
+		ERROR_INJECTOR_EVENT(InjectorRecoveryPhase1,record->type);
 		}
 
 	Log::log("Processed: %8ld\n", recordCount);
@@ -395,6 +396,7 @@ void SerialLog::recover()
 			
 		if (!isTableSpaceDropped(record->tableSpaceId) || record->type == srlDropTableSpace)
 			record->pass2();
+		ERROR_INJECTOR_EVENT(InjectorRecoveryPhase2,record->type);
 		}
 
 	Log::log("Processed: %8ld\n", recordCount);
@@ -424,6 +426,7 @@ void SerialLog::recover()
 			
 		if (!isTableSpaceDropped(record->tableSpaceId))
 			record->redo();
+		ERROR_INJECTOR_EVENT(InjectorRecoveryPhase3,record->type);
 		}
 		
 	Log::log("Processed: %8ld\n", recordCount);

=== modified file 'storage/falcon/SerialLogRecord.h'
--- a/storage/falcon/SerialLogRecord.h	2009-02-18 17:41:40 +0000
+++ b/storage/falcon/SerialLogRecord.h	2009-03-10 10:14:43 +0000
@@ -26,12 +26,29 @@
 
 #include "SerialLog.h"
 #include "Sync.h"
+#include "ErrorInjector.h"
+
+//The purpose of thφs helper class is to supply event to error injector when a 
+//log entry is written. Event is fired, when destructor of the helper object is
+//called.
+class SRLErrorInjectorHelper
+{
+	int srlId;
+public:
+	SRLErrorInjectorHelper(int id):srlId(id) {};
+	~SRLErrorInjectorHelper()
+	{
+		ERROR_INJECTOR_EVENT(InjectorSerialLogAppend, srlId);
+	}
+};
 
 #define START_RECORD(id,where)\
 	Sync sync(&log->syncWrite, where);\
+	SRLErrorInjectorHelper inject(id); \
 	sync.lock(Exclusive);\
 	startRecord();\
 	putInt(id);
+	
 
 static const int srlEnd				= 0;
 static const int srlSwitchLog		= 1;

=== modified file 'storage/falcon/ha_falcon.cpp'
--- a/storage/falcon/ha_falcon.cpp	2009-03-05 10:51:03 +0000
+++ b/storage/falcon/ha_falcon.cpp	2009-03-10 10:14:43 +0000
@@ -36,6 +36,7 @@
 #include "Format.h"
 #include "Error.h"
 #include "Log.h"
+#include "ErrorInjector.h"
 
 #ifdef _WIN32
 #define I64FORMAT			"%I64d"
@@ -96,6 +97,7 @@ ulonglong	falcon_page_cache_size;
 char*		falcon_serial_log_dir;
 char*		falcon_checkpoint_schedule;
 char*		falcon_scavenge_schedule;
+char*		falcon_error_inject;
 FILE		*falcon_log_file;
 
 // Determine the largest memory address, assume 64-bits max
@@ -195,6 +197,9 @@ int StorageInterface::falcon_init(void *
 {
 	DBUG_ENTER("falcon_init");
 	falcon_hton = (handlerton *)p;
+	
+	ERROR_INJECTOR_PARSE(falcon_error_inject);
+	
 	my_bool error = false;
 
 	if (!checkExceptionSupport()) 
@@ -3840,6 +3845,11 @@ static void updateRecordChillThreshold(M
 		storageHandler->setRecordChillThreshold(falcon_record_chill_threshold);
 }
 
+static void updateErrorInject(MYSQL_THD thd, struct st_mysql_sys_var *var,
+	void *var_ptr, const void *save)
+{
+	ERROR_INJECTOR_PARSE(*(const char**)save);
+}
 void StorageInterface::updateRecordMemoryMax(MYSQL_THD thd, struct st_mysql_sys_var* variable, void* var_ptr, const void* save)
 {
 	falcon_record_memory_max = *(ulonglong*) save;
@@ -3931,6 +3941,11 @@ static MYSQL_SYSVAR_STR(checkpoint_sched
   "Falcon checkpoint schedule.",
   NULL, NULL, "7 * * * * *");
 
+static MYSQL_SYSVAR_STR(error_inject, falcon_error_inject,
+  PLUGIN_VAR_MEMALLOC,
+  "Used for testing purposes (error injection)",
+  NULL, &updateErrorInject, "");
+
 static MYSQL_SYSVAR_STR(scavenge_schedule, falcon_scavenge_schedule,
   PLUGIN_VAR_RQCMDARG| PLUGIN_VAR_READONLY | PLUGIN_VAR_MEMALLOC,
   "Falcon record scavenge schedule.",
@@ -4007,6 +4022,7 @@ static struct st_mysql_sys_var* falconVa
 	MYSQL_SYSVAR(page_cache_size),
 	MYSQL_SYSVAR(consistent_read),
 	MYSQL_SYSVAR(serial_log_file_size),
+	MYSQL_SYSVAR(error_inject),
 	NULL
 };
 

Attachment: [text/bzr-bundle] bzr/vvaintroub@mysql.com-20090310101443-12gg7w98kff7ian4.bundle
Thread
bzr commit into mysql-6.0-falcon-team branch (vvaintroub:3059) WL#4380Vladislav Vaintroub10 Mar
  • Re: bzr commit into mysql-6.0-falcon-team branch (vvaintroub:3059)WL#4380Kevin Lewis10 Mar