List:Commits« Previous MessageNext Message »
From:Kevin Lewis Date:May 14 2009 5:16am
Subject:bzr commit into mysql-6.0-falcon-team branch (kevin.lewis:2705)
Bug#44850
View as plain text  
#At file:///C:/Work/bzr/Merge/mysql-6.0-falcon-team/ based on revid:kevin.lewis@stripped

 2705 Kevin Lewis	2009-05-14
      Bug#44850 - Delete the member variable StorageTable::dataStream since it can point into Storagetable::record.data.record, which can be chilled while it exists.
      Instead, use local pointers that are protected by a CycleLock so that even if the data.record  is chilled, that buffer will be accessable until the next cycle.
      Fix Record::deleteData so that it works for chilled records.
      Also, fix Record::getDataMemUsage() so that it does not thaw.  That was an inadvertent change from a recent patch.

    modified:
      storage/falcon/Record.cpp
      storage/falcon/StorageTable.cpp
      storage/falcon/StorageTable.h
      storage/falcon/ha_falcon.cpp
=== modified file 'storage/falcon/Record.cpp'
--- a/storage/falcon/Record.cpp	2009-05-12 22:58:23 +0000
+++ b/storage/falcon/Record.cpp	2009-05-14 05:16:08 +0000
@@ -922,15 +922,11 @@ void Record::deleteData(bool now)
 {
 	// Detach the pointer from data.record
 
-	char* recordData = data.record;
-	while (isAllocated(recordData))
-		{
+	char* recordData;
+	while ((recordData = data.record))
 		if (COMPARE_EXCHANGE_POINTER(&data.record, recordData, NULL))
 			break;
 
-		recordData = data.record;
-		}
-
 	// Now free the detached buffer
 
 	if (isAllocated(recordData))
@@ -1096,9 +1092,9 @@ int Record::getSize(void)
 
 int Record::getDataMemUsage(void)
 {
-	char* recordData = getRecordData();
+	char* recordData = findRecordData();
 
-	return (recordData == NULL ? 0 : MemMgr::blockSize(recordData));
+	return (isAllocated(recordData) ? MemMgr::blockSize(recordData) : 0);
 }
 
 int Record::getMemUsage(void)

=== modified file 'storage/falcon/StorageTable.cpp'
--- a/storage/falcon/StorageTable.cpp	2009-04-16 11:25:48 +0000
+++ b/storage/falcon/StorageTable.cpp	2009-05-14 05:16:08 +0000
@@ -382,12 +382,21 @@ void StorageTable::setRecord(Record* new
 	record = newRecord;
 	recordLocked = locked;
 	format = record->format;
-	
+}
+
+// Use the curent StorageTable::record to set up an EncodedDataStream
+// Treat this like a temporary pointer kept alive by the CycleManager
+// since this data.record could be chilled.
+
+void StorageTable::setData(EncodedDataStream* dataStream)
+{
+	ASSERT(record);
+
 	// The following is confusing because Record::getEncodeRecord returns pointer to
 	// the actual data fields while Record::getEncodedSize return length of the data fields plus
 	// a two byte format number.
 	
-	dataStream.setData((const UCHAR*) record->getEncodedRecord(), record->getEncodedSize() - sizeof(USHORT));
+	dataStream->setData((const UCHAR*) record->getEncodedRecord(), record->getEncodedSize() - sizeof(USHORT));
 }
 
 void StorageTable::clearRecord(void)
@@ -399,12 +408,12 @@ void StorageTable::clearRecord(void)
 		}
 }
 
-void StorageTable::preInsert(void)
+void StorageTable::preInsert(EncodedDataStream* dataStream)
 {
 	insertStream.clear();
 	short version = -share->table->getFormatVersion();
 	insertStream.putSegment(sizeof(version), (char*) &version, true);
-	dataStream.setStream(&insertStream);
+	dataStream->setStream(&insertStream);
 }
 
 const UCHAR* StorageTable::getEncoding(int fieldIndex)

=== modified file 'storage/falcon/StorageTable.h'
--- a/storage/falcon/StorageTable.h	2009-03-20 19:28:10 +0000
+++ b/storage/falcon/StorageTable.h	2009-05-14 05:16:08 +0000
@@ -72,6 +72,7 @@ public:
 
 	void			transactionEnded(void);
 	void			setRecord(Record* record, bool locked);
+	void			setData(EncodedDataStream* dataStream);
 	int				alterCheck(void);
 	void			waitForWriteComplete();
 	void			clearAlter(void);
@@ -100,7 +101,7 @@ public:
 	virtual void	release(StorageBlob* blob);
 	virtual void	deleteStorageTable(void);
 	virtual void	freeBlob(StorageBlob* blob);
-	virtual void	preInsert(void);
+	virtual void	preInsert(EncodedDataStream* dataStream);
 	virtual int		insert(void);
 	
 	virtual int		next(int recordNumber, bool lockForUpdate);
@@ -145,7 +146,6 @@ public:
 	StorageKey			*upperBound;
 	Record				*record;
 	Format				*format;
-	EncodedDataStream	dataStream;
 	Stream				insertStream;
 	int					searchFlags;
 	bool				recordLocked;

=== modified file 'storage/falcon/ha_falcon.cpp'
--- a/storage/falcon/ha_falcon.cpp	2009-05-06 19:40:24 +0000
+++ b/storage/falcon/ha_falcon.cpp	2009-05-14 05:16:08 +0000
@@ -37,6 +37,7 @@
 #include "Error.h"
 #include "Log.h"
 #include "ErrorInjector.h"
+#include "CycleLock.h"
 
 #ifdef _WIN32
 #define I64FORMAT			"%I64d"
@@ -2971,10 +2972,10 @@ void StorageInterface::genKeyFields(KEY*
 
 void StorageInterface::encodeRecord(uchar *buf, bool updateFlag)
 {
-	storageTable->preInsert();
+	EncodedDataStream dataStream;
+	storageTable->preInsert(&dataStream);
 	my_ptrdiff_t ptrDiff = buf - table->record[0];
 	my_bitmap_map *old_map = dbug_tmp_use_all_columns(table, table->read_set);
-	EncodedDataStream *dataStream = &storageTable->dataStream;
 	FieldFormat *fieldFormat = storageShare->format->format;
 	int maxId = storageShare->format->maxId;
 	
@@ -2992,10 +2993,10 @@ void StorageInterface::encodeRecord(ucha
 		if (updateFlag && !bitmap_is_set(table->write_set, field->field_index))
 			{
 			const unsigned char *p = storageTable->getEncoding(n);
-			dataStream->encodeEncoding(p);
+			dataStream.encodeEncoding(p);
 			}
 		else if (field->is_null())
-			dataStream->encodeNull();
+			dataStream.encodeNull();
 		else
 			switch (field->real_type())
 				{
@@ -3007,7 +3008,7 @@ void StorageInterface::encodeRecord(ucha
 				case MYSQL_TYPE_ENUM:
 				case MYSQL_TYPE_SET:
 				case MYSQL_TYPE_BIT:
-					dataStream->encodeInt64(field->val_int());
+					dataStream.encodeInt64(field->val_int());
 					break;
 
 				case MYSQL_TYPE_LONGLONG:
@@ -3022,11 +3023,11 @@ void StorageInterface::encodeRecord(ucha
 						{
 						BigInt bigInt;
 						bigInt.set((uint64)temp);
-						dataStream->encodeBigInt(&bigInt);
+						dataStream.encodeBigInt(&bigInt);
 						}
 					else
 						{
-						dataStream->encodeInt64(temp);
+						dataStream.encodeInt64(temp);
 						}
 
 					}
@@ -3035,7 +3036,7 @@ void StorageInterface::encodeRecord(ucha
 				case MYSQL_TYPE_YEAR:
 					// Have to use the ptr directly to get the same number for
 					// both two and four digit YEAR
-					dataStream->encodeInt64((int) field->ptr[0]);
+					dataStream.encodeInt64((int) field->ptr[0]);
 					break;
 
 				case MYSQL_TYPE_NEWDECIMAL:
@@ -3048,7 +3049,7 @@ void StorageInterface::encodeRecord(ucha
 						int64 value = ScaledBinary::getInt64FromBinaryDecimal((const char *) field->ptr,
 																			precision,
 																			scale);
-						dataStream->encodeInt64(value, scale);
+						dataStream.encodeInt64(value, scale);
 						}
 					else
 						{
@@ -3061,42 +3062,42 @@ void StorageInterface::encodeRecord(ucha
 						if (bigInt.fitsInInt64() && scale < 19)
 							{
 							int64 value = bigInt.getInt();
-							dataStream->encodeInt64(value, scale);
+							dataStream.encodeInt64(value, scale);
 							}
 						else
-							dataStream->encodeBigInt(&bigInt);
+							dataStream.encodeBigInt(&bigInt);
 						}
 					}
 					break;
 
 				case MYSQL_TYPE_DOUBLE:
 				case MYSQL_TYPE_FLOAT:
-					dataStream->encodeDouble(field->val_real());
+					dataStream.encodeDouble(field->val_real());
 					break;
 
 				case MYSQL_TYPE_TIMESTAMP:
 					{
 					my_bool nullValue;
 					int64 value = ((Field_timestamp*) field)->get_timestamp(&nullValue);
-					dataStream->encodeDate(value * 1000);
+					dataStream.encodeDate(value * 1000);
 					}
 					break;
 
 				case MYSQL_TYPE_DATE:
-					dataStream->encodeInt64(field->val_int());
+					dataStream.encodeInt64(field->val_int());
 					break;
 
 				case MYSQL_TYPE_NEWDATE:
-					//dataStream->encodeInt64(field->val_int());
-					dataStream->encodeInt64(uint3korr(field->ptr));
+					//dataStream.encodeInt64(field->val_int());
+					dataStream.encodeInt64(uint3korr(field->ptr));
 					break;
 
 				case MYSQL_TYPE_TIME:
-					dataStream->encodeInt64(field->val_int());
+					dataStream.encodeInt64(field->val_int());
 					break;
 
 				case MYSQL_TYPE_DATETIME:
-					dataStream->encodeInt64(field->val_int());
+					dataStream.encodeInt64(field->val_int());
 					break;
 
 				case MYSQL_TYPE_VARCHAR:
@@ -3106,7 +3107,7 @@ void StorageInterface::encodeRecord(ucha
 					String string;
 					String buffer;
 					field->val_str(&buffer, &string);
-					dataStream->encodeOpaque(string.length(), string.ptr());
+					dataStream.encodeOpaque(string.length(), string.ptr());
 					}
 					break;
 
@@ -3116,7 +3117,7 @@ void StorageInterface::encodeRecord(ucha
 					uint length = blob->get_length();
 					uchar *ptr;
 					blob->get_ptr(&ptr);
-					dataStream->encodeOpaque(length, (const char*) ptr);
+					dataStream.encodeOpaque(length, (const char*) ptr);
 					}
 					break;
 
@@ -3148,12 +3149,12 @@ void StorageInterface::encodeRecord(ucha
 						blob->set_ptr(storageBlob.length, storageBlob.data);
 						}
 
-					dataStream->encodeBinaryBlob(blobId);
+					dataStream.encodeBinaryBlob(blobId);
 					}
 					break;
 
 				default:
-					dataStream->encodeOpaque(field->field_length, (const char*) field->ptr);
+					dataStream.encodeOpaque(field->field_length, (const char*) field->ptr);
 				}
 
 		if (ptrDiff)
@@ -3165,7 +3166,13 @@ void StorageInterface::encodeRecord(ucha
 
 void StorageInterface::decodeRecord(uchar *buf)
 {
-	EncodedDataStream *dataStream = &storageTable->dataStream;
+	// dataStream will point into the data buffer of StorageTable::record
+	// Use a cycleLock to hold that buffer in case it is chilled.
+
+	CycleLock cycleLock(storageConnection->database);
+	EncodedDataStream dataStream;
+	storageTable->setData(&dataStream);
+
 	my_ptrdiff_t ptrDiff = buf - table->record[0];
 	my_bitmap_map *old_map = dbug_tmp_use_all_columns(table, table->write_set);
 	DBUG_ENTER("StorageInterface::decodeRecord");
@@ -3204,7 +3211,7 @@ void StorageInterface::decodeRecord(ucha
 		if (fieldFormat->fieldId < 0 || fieldFormat->offset == 0)
 			continue;
 			
-		dataStream->decode();
+		dataStream.decode();
 		Field *field = fieldMap[fieldFormat->fieldId];
 
 		// If we don't have a field for the physical field, just skip over it and don't worry
@@ -3215,7 +3222,7 @@ void StorageInterface::decodeRecord(ucha
 		if (ptrDiff)
 			field->move_field_offset(ptrDiff);
 
-		if (dataStream->type == edsTypeNull || !bitmap_is_set(table->read_set, field->field_index))
+		if (dataStream.type == edsTypeNull || !bitmap_is_set(table->read_set, field->field_index))
 			{
 			field->set_null();
 			field->reset();
@@ -3234,7 +3241,7 @@ void StorageInterface::decodeRecord(ucha
 				case MYSQL_TYPE_ENUM:
 				case MYSQL_TYPE_SET:
 				case MYSQL_TYPE_BIT:
-					field->store(dataStream->getInt64(),
+					field->store(dataStream.getInt64(),
 								((Field_num*)field)->unsigned_flag);
 					break;
 
@@ -3246,14 +3253,14 @@ void StorageInterface::decodeRecord(ucha
 					// support unsigned values with the MSB set in
 					// the index
 
-					if (dataStream->type == edsTypeBigInt)
+					if (dataStream.type == edsTypeBigInt)
 						{
-						int64 value = dataStream->bigInt.getInt();
+						int64 value = dataStream.bigInt.getInt();
 						field->store(value, ((Field_num*)field)->unsigned_flag);
 						}
 					else
 						{
-						field->store(dataStream->getInt64(),
+						field->store(dataStream.getInt64(),
 									 ((Field_num*)field)->unsigned_flag);
 						}
 					}
@@ -3262,7 +3269,7 @@ void StorageInterface::decodeRecord(ucha
 				case MYSQL_TYPE_YEAR:
 					// Must add 1900 to give Field_year::store the value it
 					// expects. See also case 'MYSQL_TYPE_YEAR' in encodeRecord()
-					field->store(dataStream->getInt64() + 1900, ((Field_num*)field)->unsigned_flag);
+					field->store(dataStream.getInt64() + 1900, ((Field_num*)field)->unsigned_flag);
 					break;
 
 				case MYSQL_TYPE_NEWDECIMAL:
@@ -3270,11 +3277,11 @@ void StorageInterface::decodeRecord(ucha
 					int precision = ((Field_new_decimal*) field)->precision;
 					int scale = ((Field_new_decimal*) field)->dec;
 
-					if (dataStream->type == edsTypeBigInt)
-						ScaledBinary::putBigInt(&dataStream->bigInt, (char*) field->ptr, precision, scale);
+					if (dataStream.type == edsTypeBigInt)
+						ScaledBinary::putBigInt(&dataStream.bigInt, (char*) field->ptr, precision, scale);
 					else
 						{
-						int64 value = dataStream->getInt64(scale);
+						int64 value = dataStream.getInt64(scale);
 						ScaledBinary::putBinaryDecimal(value, (char*) field->ptr, precision, scale);
 						}
 					}
@@ -3282,44 +3289,44 @@ void StorageInterface::decodeRecord(ucha
 
 				case MYSQL_TYPE_DOUBLE:
 				case MYSQL_TYPE_FLOAT:
-					field->store(dataStream->value.dbl);
+					field->store(dataStream.value.dbl);
 					break;
 
 				case MYSQL_TYPE_TIMESTAMP:
 					{
-					int value = (int) (dataStream->value.integer64 / 1000);
+					int value = (int) (dataStream.value.integer64 / 1000);
 					((Field_timestamp*)field)->store_timestamp(value);
 					}
 					break;
 
 				case MYSQL_TYPE_DATE:
-					field->store(dataStream->getInt64(), false);
+					field->store(dataStream.getInt64(), false);
 					break;
 
 				case MYSQL_TYPE_NEWDATE:
-					int3store(field->ptr, dataStream->getInt32());
+					int3store(field->ptr, dataStream.getInt32());
 					break;
 
 				case MYSQL_TYPE_TIME:
-					field->store(dataStream->getInt64(), false);
+					field->store(dataStream.getInt64(), false);
 					break;
 
 				case MYSQL_TYPE_DATETIME:
-					int8store(field->ptr, dataStream->getInt64());
+					int8store(field->ptr, dataStream.getInt64());
 					break;
 
 				case MYSQL_TYPE_VARCHAR:
 				case MYSQL_TYPE_VAR_STRING:
 				case MYSQL_TYPE_STRING:
-					field->store((const char*) dataStream->value.string.data,
-								dataStream->value.string.length, field->charset());
+					field->store((const char*) dataStream.value.string.data,
+								dataStream.value.string.length, field->charset());
 					break;
 
 				case MYSQL_TYPE_TINY_BLOB:
 					{
 					Field_blob *blob = (Field_blob*) field;
-					blob->set_ptr(dataStream->value.string.length,
-					              (uchar*) dataStream->value.string.data);
+					blob->set_ptr(dataStream.value.string.length,
+					              (uchar*) dataStream.value.string.data);
 					}
 					break;
 
@@ -3338,7 +3345,7 @@ void StorageInterface::decodeRecord(ucha
 
 					storageBlob->next = activeBlobs;
 					activeBlobs = storageBlob;
-					storageBlob->blobId = dataStream->value.blobId;
+					storageBlob->blobId = dataStream.value.blobId;
 					storageTable->getBlob(storageBlob->blobId, storageBlob);
 					blob->set_ptr(storageBlob->length, (uchar*) storageBlob->data);
 					}
@@ -3346,12 +3353,12 @@ void StorageInterface::decodeRecord(ucha
 
 				default:
 					{
-					uint l = dataStream->value.string.length;
+					uint l = dataStream.value.string.length;
 
 					if (field->field_length < l)
 						l = field->field_length;
 
-					memcpy(field->ptr, dataStream->value.string.data, l);
+					memcpy(field->ptr, dataStream.value.string.data, l);
 					}
 				}
 			}


Attachment: [text/bzr-bundle] bzr/kevin.lewis@sun.com-20090514051608-ivmrbyaf7akqaeqf.bundle
Thread
bzr commit into mysql-6.0-falcon-team branch (kevin.lewis:2705)Bug#44850Kevin Lewis14 May