Below is the list of changes that have just been committed into a local
6.0-falcon repository of . When does a push these changes will
be propagated to the main repository and, within 24 hours after the
push, to the public repository.
For information on how to access the public repository
see http://dev.mysql.com/doc/mysql/en/installing-source-tree.html
ChangeSet@stripped, 2007-09-04 17:11:37-04:00, jas@rowvwade. +25 -0
Give up trying to track sizes of record age groups in favor
of taking a "record inventory" as part and parcel of a record
scavenge.
Also changed the terminology from "record age" to "record
generation" for clarity.
storage/falcon/CMakeLists.txt@stripped, 2007-09-04 17:11:13-04:00, jas@rowvwade. +2 -0
Add new class RecordScavenge to encapsuate record scavenging
code.
storage/falcon/Database.cpp@stripped, 2007-09-04 17:11:13-04:00, jas@rowvwade. +31 -59
Give up trying to track sizes of record age groups in favor
of taking a "record inventory" as part and parcel of a record
scavenge.
storage/falcon/Database.h@stripped, 2007-09-04 17:11:13-04:00, jas@rowvwade. +6 -8
Give up trying to track sizes of record age groups in favor
of taking a "record inventory" as part and parcel of a record
scavenge.
storage/falcon/Makefile.am@stripped, 2007-09-04 17:11:14-04:00, jas@rowvwade. +4 -1
Add new class RecordScavenge to encapsuate record scavenging
code.
storage/falcon/MemMgr.cpp@stripped, 2007-09-04 17:11:14-04:00, jas@rowvwade. +7 -2
Track space in use as "big blocks" (or all blocks, if big
block threshold is low). This is primary used to determine
scavenge threshold as part of record scavenge process.
storage/falcon/MemMgr.h@stripped, 2007-09-04 17:11:15-04:00, jas@rowvwade. +1 -0
Track space in use as "big blocks" (or all blocks, if big
block threshold is low). This is primary used to determine
scavenge threshold as part of record scavenge process.
storage/falcon/Record.cpp@stripped, 2007-09-04 17:11:15-04:00, jas@rowvwade. +21 -14
Give up trying to track sizes of record age groups in favor
of taking a "record inventory" as part and parcel of a record
scavenge.
storage/falcon/Record.h@stripped, 2007-09-04 17:11:15-04:00, jas@rowvwade. +5 -14
Give up trying to track sizes of record age groups in favor
of taking a "record inventory" as part and parcel of a record
scavenge.
storage/falcon/RecordGroup.cpp@stripped, 2007-09-04 17:11:16-04:00, jas@rowvwade. +7 -0
Give up trying to track sizes of record age groups in favor
of taking a "record inventory" as part and parcel of a record
scavenge.
storage/falcon/RecordGroup.h@stripped, 2007-09-04 17:11:16-04:00, jas@rowvwade. +6 -4
Give up trying to track sizes of record age groups in favor
of taking a "record inventory" as part and parcel of a record
scavenge.
storage/falcon/RecordLeaf.cpp@stripped, 2007-09-04 17:11:16-04:00, jas@rowvwade. +15 -4
Give up trying to track sizes of record age groups in favor
of taking a "record inventory" as part and parcel of a record
scavenge.
storage/falcon/RecordLeaf.h@stripped, 2007-09-04 17:11:17-04:00, jas@rowvwade. +1 -0
Give up trying to track sizes of record age groups in favor
of taking a "record inventory" as part and parcel of a record
scavenge.
storage/falcon/RecordScavenge.cpp@stripped, 2007-09-04 17:11:22-04:00, jas@rowvwade. +89 -0
New BitKeeper file ``storage/falcon/RecordScavenge.cpp''
storage/falcon/RecordScavenge.cpp@stripped, 2007-09-04 17:11:22-04:00, jas@rowvwade. +0 -0
storage/falcon/RecordScavenge.h@stripped, 2007-09-04 17:11:22-04:00, jas@rowvwade. +48 -0
New BitKeeper file ``storage/falcon/RecordScavenge.h''
storage/falcon/RecordScavenge.h@stripped, 2007-09-04 17:11:22-04:00, jas@rowvwade. +0 -0
storage/falcon/RecordSection.h@stripped, 2007-09-04 17:11:18-04:00, jas@rowvwade. +8 -6
Stylistic edit for clarity.
storage/falcon/RecordVersion.cpp@stripped, 2007-09-04 17:11:18-04:00, jas@rowvwade. +3 -1
Switch terminology from "record age" to "record generation".
storage/falcon/SerialLog.cpp@stripped, 2007-09-04 17:11:18-04:00, jas@rowvwade. +7 -7
Deactivate a large number of relatively expensive serial
log validations.
storage/falcon/SerialLogControl.cpp@stripped, 2007-09-04 17:11:19-04:00, jas@rowvwade. +5 -5
Deactivate a large number of relatively expensive serial
log validations.
storage/falcon/SerialLogWindow.cpp@stripped, 2007-09-04 17:11:19-04:00, jas@rowvwade. +1 -1
Deactivate a large number of relatively expensive serial
log validations.
storage/falcon/Table.cpp@stripped, 2007-09-04 17:11:19-04:00, jas@rowvwade. +15 -4
Give up trying to track sizes of record age groups in favor
of taking a "record inventory" as part and parcel of a record
scavenge.
storage/falcon/Table.h@stripped, 2007-09-04 17:11:20-04:00, jas@rowvwade. +2 -2
Give up trying to track sizes of record age groups in favor
of taking a "record inventory" as part and parcel of a record
scavenge.
storage/falcon/Transaction.cpp@stripped, 2007-09-04 17:11:20-04:00, jas@rowvwade. +8 -0
Put in debugging mechanism to print the transaction "wait for"
tree from the debugger.
storage/falcon/Transaction.h@stripped, 2007-09-04 17:11:21-04:00, jas@rowvwade. +6 -6
Put in debugging mechanism to print the transaction "wait for"
tree from the debugger.
storage/falcon/TransactionManager.cpp@stripped, 2007-09-04 17:11:21-04:00, jas@rowvwade. +17
-0
Put in debugging mechanism to print the transaction "wait for"
tree from the debugger.
storage/falcon/TransactionManager.h@stripped, 2007-09-04 17:11:21-04:00, jas@rowvwade. +2 -0
Put in debugging mechanism to print the transaction "wait for"
tree from the debugger.
diff -Nrup a/storage/falcon/CMakeLists.txt b/storage/falcon/CMakeLists.txt
--- a/storage/falcon/CMakeLists.txt 2007-08-25 16:32:19 -04:00
+++ b/storage/falcon/CMakeLists.txt 2007-09-04 17:11:13 -04:00
@@ -167,6 +167,7 @@ ADD_LIBRARY(ha_falcon
RecordLeaf.cpp
RecordLocatorPage.cpp
RecordSection.cpp
+ RecordScavenge.cpp
RecordVersion.cpp
RecoveryObjects.cpp
RecoveryPage.cpp
@@ -430,6 +431,7 @@ ADD_LIBRARY(ha_falcon
RecordGroup.h
RecordLeaf.h
RecordLocatorPage.h
+ RecordScavenge.h
RecordSection.h
RecordVersion.h
RecoveryObjects.h
diff -Nrup a/storage/falcon/Database.cpp b/storage/falcon/Database.cpp
--- a/storage/falcon/Database.cpp 2007-08-27 11:24:20 -04:00
+++ b/storage/falcon/Database.cpp 2007-09-04 17:11:13 -04:00
@@ -69,7 +69,8 @@
#include "TableSpace.h"
#include "InfoTable.h"
#include "MemoryManager.h"
-#include "Record.h"
+#include "MemMgr.h"
+#include "RecordScavenge.h"
#ifndef STORAGE_ENGINE
#include "Applications.h"
@@ -398,9 +399,9 @@ Database::Database(const char *dbName, C
memset(tablesModId, 0, sizeof (tablesModId));
memset(unTables, 0, sizeof (unTables));
memset(schemas, 0, sizeof (schemas));
- currentAgeGroup = 1;
- overflowSize = 0;
- memset((void*) ageGroupSizes, 0, sizeof (ageGroupSizes));
+ currentGeneration = 1;
+ //overflowSize = 0;
+ //memset((void*) ageGroupSizes, 0, sizeof (ageGroupSizes));
tableList = NULL;
recordMemoryMax = configuration->recordMemoryMax;
recordScavengeFloor = configuration->recordScavengeFloor;
@@ -1699,47 +1700,31 @@ void Database::retireRecords(bool forced
if (systemConnection->transaction)
commitSystemTransaction();
- int threshold = 0;
- int64 total = 0;
transactionManager->purgeTransactions();
TransId oldestActiveTransaction = transactionManager->findOldestActive();
- int n;
-
- // Compute record memory in use. Note point we pass lower limit
-
- for (n = 0; n < AGE_GROUPS; ++n)
- {
- int64 size = ageGroupSizes[n];
-
- if (size > 0)
- total += size;
-
- if (!threshold && total > (int64)recordScavengeFloor)
- threshold = currentAgeGroup - n;
- }
-
- total += overflowSize;
- RecordScavenge recordScavenge;
- memset(&recordScavenge, 0, sizeof(recordScavenge));
- recordScavenge.age = threshold;
- recordScavenge.transactionId = oldestActiveTransaction;
-
- if (forced)
- recordScavenge.age = MAX(threshold, currentAgeGroup - AGE_GROUPS / 2);
-
+ int threshold = 0;
+ uint64 total = recordDataPool->activeMemory;
+ RecordScavenge recordScavenge(this, oldestActiveTransaction);
+
// If we passed the upper limit, scavenge. If we didn't pick up
// a significant amount of memory since the last cycle, don't bother
// bumping the age group.
- if (forced || total > (int64)recordScavengeThreshold)
+ if (forced || total > recordScavengeThreshold)
{
- printRecordMemory (threshold, total);
- Sync sync (&syncTables, "Database::retireRecords");
- sync.lock (Shared);
+ Sync syncTbl (&syncTables, "Database::retireRecords");
+ syncTbl.lock (Shared);
+ Table *table;
+
+ for (table = tableList; table; table = table->next)
+ table->inventoryRecords(&recordScavenge);
+
+ threshold = recordScavenge.computeThreshold(recordScavengeFloor);
+ recordScavenge.printRecordMemory();
int count = 0;
int skipped = 0;
- for (Table *table = tableList; table; table = table->next)
+ for (table = tableList; table; table = table->next)
{
try
{
@@ -1752,53 +1737,39 @@ void Database::retireRecords(bool forced
}
catch (SQLException &exception)
{
- sync.unlock();
+ syncTbl.unlock();
Log::debug ("Exception during scavenger of table %s.%s: %s\n",
table->schemaName, table->name, exception.getText());
}
}
- sync.unlock();
- int64 newTotal = overflowSize;
-
- for (int n = 0; n < AGE_GROUPS; ++n)
- newTotal += ageGroupSizes [n];
-
+ syncTbl.unlock();
Log::log(LogScavenge, " %d records, " I64FORMAT " bytes reclaimed\n",
recordScavenge.recordsReclaimed, recordScavenge.spaceReclaimed);
- total = newTotal;
+ total = recordScavenge.spaceRemaining;
}
- else if ((total - lastRecordMemory) < (int64) recordScavengeThreshold / 4)
+ else if ((total - lastRecordMemory) < recordScavengeThreshold / 4)
{
- recordScavenge.age = -1;
+ recordScavenge.scavengeGeneration = -1;
cleanupRecords (&recordScavenge);
return;
}
else
{
- recordScavenge.age = -1;
+ recordScavenge.scavengeGeneration = -1;
cleanupRecords (&recordScavenge);
- printRecordMemory (threshold, total);
+ //printRecordMemory (threshold, total);
+ recordScavenge.printRecordMemory();
}
lastRecordMemory = total;
- INTERLOCKED_INCREMENT (currentAgeGroup);
- INTERLOCKED_ADD(&overflowSize, ageGroupSizes [AGE_GROUPS - 1]);
- //overflowSize += ageGroupSizes [AGE_GROUPS - 1];
-
- for (n = AGE_GROUPS - 1; n > 0; --n)
- {
- long size = ageGroupSizes [n - 1];
- INTERLOCKED_EXCHANGE(ageGroupSizes + n, (size >= 0) ? size : 0);
- }
-
- //ageGroupSizes [0] = 0;
- INTERLOCKED_EXCHANGE(ageGroupSizes + 0, 0);
+ INTERLOCKED_INCREMENT (currentGeneration);
lastRetireRecords = timestamp;
}
+/***
void Database::printRecordMemory(int64 threshold, int64 total)
{
Log::debug ("Record Memory usage for %s:\n", (const char*) name);
@@ -1815,6 +1786,7 @@ void Database::printRecordMemory(int64 t
Log::log(LogScavenge, " total: " I64FORMAT ", threshold " I64FORMAT "%s\n", total,
threshold,
(total > (int64)recordScavengeThreshold) ? " -- scavenge" : "");
}
+***/
void Database::ticker(void * database)
{
diff -Nrup a/storage/falcon/Database.h b/storage/falcon/Database.h
--- a/storage/falcon/Database.h 2007-08-26 13:08:57 -04:00
+++ b/storage/falcon/Database.h 2007-09-04 17:11:13 -04:00
@@ -35,7 +35,7 @@
#define ODS_MINOR_VERSION2 2 // Has SequencePages external to the section tree
#define ODS_MINOR_VERSION3 3 // Switch to variable length record numbers in index
#define ODS_MINOR_VERSION ODS_MINOR_VERSION3
-#define AGE_GROUPS 32
+//#define AGE_GROUPS 32
#define COMBINED_VERSION(major,minor) (major * 100 + minor)
#define VERSION_CURRENT COMBINED_VERSION(ODS_VERSION, ODS_MINOR_VERSION)
@@ -93,9 +93,9 @@ class IndexKey;
class InfoTable;
class TableSpace;
class MemMgr;
+class RecordScavenge;
struct JavaCallback;
-struct RecordScavenge;
class Database
{
@@ -119,7 +119,7 @@ public:
void licenseCheck();
void cleanupRecords (RecordScavenge *recordScavenge);
void serverOperation (int op, Parameters *parameters);
- void printRecordMemory(int64 threshold, int64 tota);
+ //void printRecordMemory(int64 threshold, int64 tota);
void retireRecords(bool forced);
int getMemorySize (const char *string);
JString analyze(int mask);
@@ -186,7 +186,6 @@ public:
void addRef();
PreparedStatement* prepareStatement (const char *sqlStr);
void addSystemTables();
- //int32 createSection(Transaction *transaction);
Table* addTable (User *owner, const char *name, const char *schema, TableSpace
*tableSpace);
Table* findTable (const char *schema, const char *name);
Statement* createStatement();
@@ -267,7 +266,6 @@ public:
PageWriter *pageWriter;
PreparedStatement *updateCardinality;
MemMgr *recordDataPool;
- //MemMgr *recordObjectPool;
volatile time_t timestamp;
volatile int numberQueries;
@@ -277,9 +275,9 @@ public:
int odsVersion;
int noSchedule;
- volatile INTERLOCK_TYPE currentAgeGroup;
- volatile long overflowSize;
- volatile long ageGroupSizes [AGE_GROUPS];
+ volatile INTERLOCK_TYPE currentGeneration;
+ //volatile long overflowSize;
+ //volatile long ageGroupSizes [AGE_GROUPS];
uint64 recordMemoryMax;
uint64 recordScavengeThreshold;
uint64 recordScavengeFloor;
diff -Nrup a/storage/falcon/Makefile.am b/storage/falcon/Makefile.am
--- a/storage/falcon/Makefile.am 2007-08-30 13:36:30 -04:00
+++ b/storage/falcon/Makefile.am 2007-09-04 17:11:14 -04:00
@@ -98,7 +98,9 @@ falcon_headers= Agent.h Alias.h Applicat
Protocol.h PStatement.h Queue.h QueryString.h RecordGroup.h \
Record.h RecordLeaf.h \
RecordLocatorPage.h \
- RecordSection.h RecordVersion.h \
+ RecordSection.h \
+ RecordScavenge.h \
+ RecordVersion.h \
RecoveryObjects.h \
RecoveryPage.h \
Registry.h Repository.h RepositoryManager.h RepositoryVolume.h \
@@ -248,6 +250,7 @@ falcon_sources= Agent.cpp Alias.cpp \
RecordGroup.cpp RecordLeaf.cpp \
RecordLocatorPage.cpp \
RecordSection.cpp \
+ RecordScavenge.cpp \
RecordVersion.cpp \
RecoveryObjects.cpp \
RecoveryPage.cpp \
diff -Nrup a/storage/falcon/MemMgr.cpp b/storage/falcon/MemMgr.cpp
--- a/storage/falcon/MemMgr.cpp 2007-08-30 21:04:06 -04:00
+++ b/storage/falcon/MemMgr.cpp 2007-09-04 17:11:14 -04:00
@@ -285,6 +285,7 @@ MemMgr::MemMgr(int rounding, int cutoff,
currentMemory = 0;
blocksAllocated = 0;
blocksActive = 0;
+ activeMemory = 0;
numberBigHunks = 0;
numberSmallHunks = 0;
bigHunks = NULL;
@@ -402,8 +403,6 @@ MemBlock* MemMgr::alloc(int length)
*/
- //Sync sync (&mutex, "MemMgr::alloc");
- //sync.lock(Exclusive);
MemFreeBlock *freeBlock;
if (length < (int) (OFFSET(MemBlock*, body) + sizeof (MemFreeBlock) - sizeof
(MemBigObject)))
@@ -424,6 +423,8 @@ MemBlock* MemMgr::alloc(int length)
if (tail < (int) sizeof (MemFreeBlock))
{
block->pool = this;
+ activeMemory += block->length;
+
return block;
}
@@ -434,6 +435,7 @@ MemBlock* MemMgr::alloc(int length)
freeBlock->memHeader.length = tail - sizeof (MemBigHeader);
block->length = length;
block->pool = this;
+ activeMemory += length;
if ( (freeBlock->next = newBlock->next) )
freeBlock->next->prior = freeBlock;
@@ -478,6 +480,7 @@ MemBlock* MemMgr::alloc(int length)
MemBlock *block = (MemBlock*) &newBlock->memHeader;
block->pool = this;
block->length = length;
+ activeMemory += length;
// If there is space left over, create a free block
@@ -631,6 +634,8 @@ void MemMgr::releaseBlock(MemBlock *bloc
sync.lock(Exclusive);
//validateFreeList();
block->pool = NULL;
+ ASSERT(length <= activeMemory);
+ activeMemory -= length;
if (freeBlock->next && !freeBlock->next->memHeader.pool)
{
diff -Nrup a/storage/falcon/MemMgr.h b/storage/falcon/MemMgr.h
--- a/storage/falcon/MemMgr.h 2007-08-23 11:20:45 -04:00
+++ b/storage/falcon/MemMgr.h 2007-09-04 17:11:15 -04:00
@@ -121,6 +121,7 @@ public:
MemFreeBlock junk;
Mutex mutex; // Win32 critical regions are faster than SyncObject
int64 currentMemory;
+ uint64 activeMemory;
int blocksAllocated;
int blocksActive;
diff -Nrup a/storage/falcon/Record.cpp b/storage/falcon/Record.cpp
--- a/storage/falcon/Record.cpp 2007-08-31 12:23:28 -04:00
+++ b/storage/falcon/Record.cpp 2007-09-04 17:11:15 -04:00
@@ -68,6 +68,7 @@ Record::Record(Table *tbl, int32 recordN
recordNumber = recordNum;
const short *p = (short*) stream->segments->address;
size = sizeof (*this);
+ generation = table->database->currentGeneration;
#ifdef CHECK_RECORD_ACTIVITY
active = false;
#endif
@@ -78,8 +79,8 @@ Record::Record(Table *tbl, int32 recordN
data.record = stream->decompress(table->tableId, recordNumber);
format = table->getFormat (*(short*) data.record);
size += format->length;
- setAgeGroup();
-
+ //setAgeGroup();
+
if (stream->decompressedLength != format->length)
throw SQLEXCEPTION (RUNTIME_ERROR,
"wrong length record (got %d, expected %d), table %s.%s, section %d, record %d",
@@ -109,7 +110,7 @@ Record::Record(Table * tbl, Format *fmt)
size = sizeof (RecordVersion);
encoding = noEncoding;
state = recData;
- ageGroup = table->database->currentAgeGroup; // to avoid a Valgrind warning
+ generation = table->database->currentGeneration;
#ifdef CHECK_RECORD_ACTIVITY
active = false;
@@ -130,10 +131,11 @@ Record::~Record()
#ifdef CHECK_RECORD_ACTIVITY
ASSERT(!active);
#endif
-
+ /***
if (table)
unsetAgeGroup();
-
+ ***/
+
deleteData();
}
@@ -677,7 +679,6 @@ int Record::setEncodedRecord(Stream *str
encoding = shortVector;
int vectorLength = format->count * sizeof(short);
int totalLength = vectorLength + stream->totalLength;
- //char *dataBuffer = ALLOCATE_RECORD(totalLength);
char *dataBuffer = allocRecordData(totalLength);
memset(dataBuffer, 0, vectorLength);
stream->getSegment(0, stream->totalLength, dataBuffer + vectorLength);
@@ -685,7 +686,8 @@ int Record::setEncodedRecord(Stream *str
highWater = 0;
size += vectorLength + stream->totalLength;
- setAgeGroup();
+ //setAgeGroup();
+ generation = table->database->currentGeneration;
if (interlocked)
{
@@ -798,21 +800,21 @@ bool Record::isNull(int fieldId)
// Set age group and add size to database
+/***
void Record::setAgeGroup()
{
Database *database = table->database;
- ageGroup = database->currentAgeGroup;
+ generation = database->currentGeneration;
//database->ageGroupSizes [0] += size;
INTERLOCKED_ADD(database->ageGroupSizes + 0, size);
}
-
void Record::unsetAgeGroup(void)
{
if (table)
{
Database *database = table->database;
- int n = database->currentAgeGroup - ageGroup;
+ int n = database->currentGeneration - generation;
if (n >= AGE_GROUPS)
INTERLOCKED_ADD(&database->overflowSize, -size);
@@ -821,18 +823,22 @@ void Record::unsetAgeGroup(void)
}
}
+***/
void Record::poke()
{
+ generation = table->database->currentGeneration;
+
+ /***
Database *database = table->database;
- int32 currentAgeGroup = database->currentAgeGroup;
- int32 n = currentAgeGroup - ageGroup;
+ int32 currentGeneration = database->currentGeneration;
+ int32 n = currentGeneration - generation;
if (n == 0)
return;
ASSERT (n > 0);
- ageGroup = currentAgeGroup;
+ generation = currentGeneration;
if (n >= AGE_GROUPS)
INTERLOCKED_ADD(&database->overflowSize, -size);
@@ -840,6 +846,7 @@ void Record::poke()
INTERLOCKED_ADD(database->ageGroupSizes + n, -size);
INTERLOCKED_ADD(database->ageGroupSizes + 0, size);
+ ***/
}
Record* Record::releaseNonRecursive(void)
@@ -911,7 +918,7 @@ void Record::deleteData(void)
void Record::print(void)
{
printf(" %p\tId %d, enc %d, state %d, use %d, grp %d\n",
- this, recordNumber, encoding, state, useCount, ageGroup);
+ this, recordNumber, encoding, state, useCount, generation);
}
void Record::printRecord(const char* header)
diff -Nrup a/storage/falcon/Record.h b/storage/falcon/Record.h
--- a/storage/falcon/Record.h 2007-08-25 16:32:22 -04:00
+++ b/storage/falcon/Record.h 2007-09-04 17:11:15 -04:00
@@ -29,17 +29,6 @@
#define CHECK_RECORD_ACTIVITY
-struct RecordScavenge
- {
- TransId transactionId;
- int age;
- uint recordsReclaimed;
- uint recordsRemaining;
- uint versionsRemaining;
- uint64 spaceReclaimed;
- uint64 spaceRemaining;
- };
-
enum RecordEncoding {
noEncoding = 0,
traditional,
@@ -64,6 +53,7 @@ class Transaction;
class Value;
class Stream;
class Database;
+class RecordScavenge;
CLASS(Field);
extern char *RecordAllocate (int size, const char *file, int line);
@@ -104,11 +94,13 @@ public:
void getEncodedValue (int fieldId, Value *value);
void getRecord (Stream *stream);
int getEncodedSize();
- void setAgeGroup();
void deleteData(void);
void printRecord(const char* header);
void validateData(void);
char* allocRecordData(int length);
+
+ //void setAgeGroup();
+ //void unsetAgeGroup(void);
Record (Table *table, Format *recordFormat);
Record(Table *table, int32 recordNumber, Stream *stream);
@@ -132,7 +124,7 @@ public:
Format *format;
int recordNumber;
int size;
- int ageGroup;
+ int generation;
short highWater;
UCHAR encoding;
UCHAR state;
@@ -140,7 +132,6 @@ public:
#ifdef CHECK_RECORD_ACTIVITY
UCHAR active; // this is for debugging only
#endif
- void unsetAgeGroup(void);
};
#endif // !defined(AFX_RECORD_H__02AD6A50_A433_11D2_AB5B_0000C01D2301__INCLUDED_)
diff -Nrup a/storage/falcon/RecordGroup.cpp b/storage/falcon/RecordGroup.cpp
--- a/storage/falcon/RecordGroup.cpp 2007-08-29 18:22:36 -04:00
+++ b/storage/falcon/RecordGroup.cpp 2007-09-04 17:11:16 -04:00
@@ -160,3 +160,10 @@ int RecordGroup::countActiveRecords()
return count;
}
+
+void RecordGroup::inventoryRecords(RecordScavenge* recordScavenge)
+{
+ for (RecordSection **section = records, **end = records + RECORD_SLOTS; section <
end; ++section)
+ if (*section)
+ (*section)->inventoryRecords(recordScavenge);
+}
diff -Nrup a/storage/falcon/RecordGroup.h b/storage/falcon/RecordGroup.h
--- a/storage/falcon/RecordGroup.h 2007-08-25 12:01:26 -04:00
+++ b/storage/falcon/RecordGroup.h 2007-09-04 17:11:16 -04:00
@@ -29,13 +29,15 @@
class RecordGroup : public RecordSection
{
public:
- virtual int countActiveRecords();
- virtual int retireRecords (Table *table, int base, RecordScavenge *recordScavenge);
RecordGroup (int32 base, int32 id, RecordSection *section);
RecordGroup(int32 base);
- virtual bool store (Record *record, Record *prior, int32 id, RecordSection **parentPtr);
- virtual Record* fetch (int32 id);
virtual ~RecordGroup();
+
+ virtual int countActiveRecords();
+ virtual int retireRecords (Table *table, int base, RecordScavenge *recordScavenge);
+ virtual bool store (Record *record, Record *prior, int32 id, RecordSection **parentPtr);
+ virtual void inventoryRecords(RecordScavenge* recordScavenge);
+ virtual Record* fetch (int32 id);
RecordSection *records [RECORD_SLOTS];
int32 base;
diff -Nrup a/storage/falcon/RecordLeaf.cpp b/storage/falcon/RecordLeaf.cpp
--- a/storage/falcon/RecordLeaf.cpp 2007-08-29 18:22:38 -04:00
+++ b/storage/falcon/RecordLeaf.cpp 2007-09-04 17:11:16 -04:00
@@ -26,6 +26,7 @@
#include "Table.h"
#include "Sync.h"
#include "Interlock.h"
+#include "RecordScavenge.h"
#ifdef _DEBUG
#undef THIS_FILE
@@ -129,7 +130,7 @@ int RecordLeaf::retireRecords (Table *ta
if (record->isVersion())
{
if ((record->scavenge(oldestActiveTransaction)) &&
- ((!record->hasRecord()) || ((record->useCount == 1) &&
(record->ageGroup <= age))))
+ ((!record->hasRecord()) || ((record->useCount == 1) &&
(record->generation <= age))))
{
redo = true;
@@ -138,7 +139,7 @@ int RecordLeaf::retireRecords (Table *ta
else
++count;
}
- else if (record->ageGroup <= age && record->useCount == 1)
+ else if (record->generation <= age && record->useCount == 1)
{
redo = true;
@@ -166,7 +167,7 @@ int RecordLeaf::retireRecords (Table *ta
if (record->isVersion())
{
if ((record->scavenge(recordScavenge)) &&
- ((!record->hasRecord()) || ((record->useCount == 1) &&
(record->ageGroup <= recordScavenge->age))))
+ ((!record->hasRecord()) || ((record->useCount == 1) &&
(record->generation <= recordScavenge->scavengeGeneration))))
{
*ptr = NULL;
recordScavenge->spaceReclaimed += record->size;
@@ -183,7 +184,7 @@ int RecordLeaf::retireRecords (Table *ta
++count;
}
}
- else if (record->ageGroup <= recordScavenge->age &&
record->useCount == 1)
+ else if (record->generation <= recordScavenge->scavengeGeneration &&
record->useCount == 1)
{
*ptr = NULL;
recordScavenge->spaceReclaimed += record->size;
@@ -220,4 +221,14 @@ int RecordLeaf::countActiveRecords()
++count;
return count;
+}
+
+void RecordLeaf::inventoryRecords(RecordScavenge* recordScavenge)
+{
+ Sync sync(&syncObject, "RecordLeaf::inventoryRecords");
+ sync.lock(Shared);
+
+ for (Record **ptr = records, **end = records + RECORD_SLOTS; ptr < end; ++ptr)
+ if (*ptr)
+ recordScavenge->inventoryRecord(*ptr);
}
diff -Nrup a/storage/falcon/RecordLeaf.h b/storage/falcon/RecordLeaf.h
--- a/storage/falcon/RecordLeaf.h 2007-08-25 12:01:27 -04:00
+++ b/storage/falcon/RecordLeaf.h 2007-09-04 17:11:17 -04:00
@@ -40,6 +40,7 @@ public:
Record *records [RECORD_SLOTS];
SyncObject syncObject;
+ void inventoryRecords(RecordScavenge* recordScavenge);
};
#endif // !defined(AFX_RECORDLEAF_H__02AD6A56_A433_11D2_AB5B_0000C01D2301__INCLUDED_)
diff -Nrup a/storage/falcon/RecordScavenge.cpp b/storage/falcon/RecordScavenge.cpp
--- /dev/null Wed Dec 31 16:00:00 196900
+++ b/storage/falcon/RecordScavenge.cpp 2007-09-04 17:11:22 -04:00
@@ -0,0 +1,89 @@
+/* Copyright (C) 2007 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
+
+#include <memory.h>
+#include "Engine.h"
+#include "RecordScavenge.h"
+#include "Database.h"
+#include "Record.h"
+#include "Log.h"
+
+
+RecordScavenge::RecordScavenge(Database *db, TransId oldestTransaction)
+{
+ database = db;
+ transactionId = oldestTransaction;
+ baseGeneration = database->currentGeneration;
+ memset(ageGroups, 0, sizeof(ageGroups));
+ recordsReclaimed = 0;
+ recordsRemaining = 0;
+ versionsRemaining = 0;
+ spaceReclaimed = 0;
+ spaceRemaining = 0;
+ overflowSpace = 0;
+
+}
+
+RecordScavenge::~RecordScavenge(void)
+{
+}
+
+void RecordScavenge::inventoryRecord(Record* record)
+{
+ for (Record *rec = record; rec; rec = rec->getPriorVersion())
+ {
+ int age = baseGeneration - record->generation;
+
+ if (age >= 0 && age < AGE_GROUPS)
+ ageGroups[age] += record->size;
+ else if (age >= AGE_GROUPS)
+ overflowSpace += record->size;
+ else
+ ageGroups[0] = record->size;
+ }
+}
+
+int RecordScavenge::computeThreshold(uint64 target)
+{
+ totalSpace = overflowSpace;
+ scavengeGeneration = 0;
+
+ for (int n = AGE_GROUPS - 1; n >= 0; --n)
+ {
+ totalSpace += ageGroups[n];
+
+ if (totalSpace >= target && scavengeGeneration == 0)
+ scavengeGeneration = baseGeneration + n;
+ }
+
+ return scavengeGeneration;
+}
+
+void RecordScavenge::printRecordMemory(void)
+{
+ Log::debug ("Record Memory usage for %s:\n", (const char*) database->name);
+ int max;
+
+ for (max = AGE_GROUPS - 1; max > 0; --max)
+ if (ageGroups[max])
+ break;
+
+ for (int n = 0; n <= max; ++n)
+ if (ageGroups [n])
+ Log::debug (" %d. %d\n", baseGeneration - n, ageGroups[n]);
+
+ Log::log(LogScavenge, " total: " I64FORMAT ", threshold %d%s\n", totalSpace,
scavengeGeneration,
+ (scavengeGeneration) ? " -- scavenge" : "");
+}
diff -Nrup a/storage/falcon/RecordScavenge.h b/storage/falcon/RecordScavenge.h
--- /dev/null Wed Dec 31 16:00:00 196900
+++ b/storage/falcon/RecordScavenge.h 2007-09-04 17:11:22 -04:00
@@ -0,0 +1,48 @@
+/* Copyright (C) 2007 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
+
+#ifndef _RECORD_SCAVENGE_H_
+#define _RECORD_SCAVENGE_H_
+
+static const int AGE_GROUPS = 20;
+
+class Database;
+class Record;
+
+class RecordScavenge
+{
+public:
+ Database *database;
+ TransId transactionId;
+ int scavengeGeneration;
+ int baseGeneration;
+ uint recordsReclaimed;
+ uint recordsRemaining;
+ uint versionsRemaining;
+ uint64 spaceReclaimed;
+ uint64 spaceRemaining;
+ uint64 ageGroups[AGE_GROUPS];
+ uint64 overflowSpace;
+ uint64 totalSpace;
+
+ RecordScavenge(Database *db, TransId oldestTransaction);
+ ~RecordScavenge(void);
+
+ void inventoryRecord(Record* record);
+ int computeThreshold(uint64 target);
+ void printRecordMemory(void);
+};
+
+#endif
diff -Nrup a/storage/falcon/RecordSection.h b/storage/falcon/RecordSection.h
--- a/storage/falcon/RecordSection.h 2007-08-25 12:01:27 -04:00
+++ b/storage/falcon/RecordSection.h 2007-09-04 17:11:18 -04:00
@@ -26,19 +26,21 @@
class Record;
class Table;
+class RecordScavenge;
-struct RecordScavenge;
#define RECORD_SLOTS 100
class RecordSection
{
public:
- virtual ~RecordSection();
- virtual Record* fetch (int32 id) = 0;
- virtual bool store (Record *record, Record *prior, int32 id, RecordSection **parentPtr)
= 0;
- virtual int retireRecords(Table *table, int base, RecordScavenge *recordScavenge) = 0;
- virtual int countActiveRecords() = 0;
+ virtual ~RecordSection();
+
+ virtual Record* fetch (int32 id) = 0;
+ virtual bool store (Record *record, Record *prior, int32 id, RecordSection **parentPtr)
= 0;
+ virtual int retireRecords(Table *table, int base, RecordScavenge *recordScavenge) = 0;
+ virtual void inventoryRecords(RecordScavenge* recordScavenge) = 0;
+ virtual int countActiveRecords() = 0;
};
#endif // !defined(AFX_RECORDSECTION_H__02AD6A54_A433_11D2_AB5B_0000C01D2301__INCLUDED_)
diff -Nrup a/storage/falcon/RecordVersion.cpp b/storage/falcon/RecordVersion.cpp
--- a/storage/falcon/RecordVersion.cpp 2007-08-25 12:44:15 -04:00
+++ b/storage/falcon/RecordVersion.cpp 2007-09-04 17:11:18 -04:00
@@ -28,6 +28,8 @@
#include "SerialLogControl.h"
#include "Stream.h"
#include "Dbb.h"
+#include "RecordScavenge.h"
+
//////////////////////////////////////////////////////////////////////
// Construction/Destruction
//////////////////////////////////////////////////////////////////////
@@ -331,7 +333,7 @@ void RecordVersion::print(void)
{
Log::debug(" %p\tId %d, enc %d, state %d, tid %d, use %d, grp %d, prior %p\n",
this, recordNumber, encoding, state, transactionId, useCount,
- ageGroup, priorVersion);
+ generation, priorVersion);
if (priorVersion)
priorVersion->print();
diff -Nrup a/storage/falcon/SerialLog.cpp b/storage/falcon/SerialLog.cpp
--- a/storage/falcon/SerialLog.cpp 2007-08-31 12:23:29 -04:00
+++ b/storage/falcon/SerialLog.cpp 2007-09-04 17:11:18 -04:00
@@ -442,7 +442,7 @@ void SerialLog::overflowFlush(void)
writeBlock->length = (int) (writePtr - (UCHAR*) writeBlock);
writeWindow->setLastBlock(writeBlock);
lastReadBlock = writeBlock->readBlockNumber = getReadBlock();
- ASSERT(writeWindow->validate(writeBlock));
+ //ASSERT(writeWindow->validate(writeBlock));
// Keep track of what needs to be written
@@ -463,7 +463,7 @@ void SerialLog::overflowFlush(void)
throw;
}
- ASSERT(flushWindow->validate(flushBlock));
+ //ASSERT(flushWindow->validate(flushBlock));
++physicalFlushes;
mutex.unlock();
@@ -570,7 +570,7 @@ uint64 SerialLog::flush(bool forceNewWin
throw;
}
- ASSERT(flushWindow->validate(flushBlock));
+ //ASSERT(flushWindow->validate(flushBlock));
++physicalFlushes;
mutex.unlock();
@@ -581,7 +581,7 @@ uint64 SerialLog::flush(bool forceNewWin
wakeupFlushQueue(thread);
ASSERT(writer != thread);
ASSERT(writer || !srlQueue);
- ASSERT(writeWindow->validate(writeBlock));
+ //ASSERT(writeWindow->validate(writeBlock));
syncPtr->unlock();
return nextBlockNumber;
@@ -619,7 +619,7 @@ void SerialLog::createNewWindow(void)
writeWindow->firstBlockNumber = nextBlockNumber;
initializeWriteBlock(writeWindow->firstBlock());
ASSERT(writeWindow->firstBlockNumber == writeBlock->blockNumber);
- ASSERT(writeWindow->validate(writeBlock));
+ //ASSERT(writeWindow->validate(writeBlock));
}
void SerialLog::shutdown()
@@ -686,7 +686,7 @@ void SerialLog::putData(uint32 length, c
writeBlock->length = (int) (writePtr - (UCHAR*) writeBlock);
writeWindow->currentLength = (int) (writePtr - writeWindow->buffer);
recordStart = writeBlock->data;
- ASSERT(writeWindow->validate(writeBlock));
+ //ASSERT(writeWindow->validate(writeBlock));
}
void SerialLog::startRecord()
@@ -988,7 +988,7 @@ void SerialLog::initializeWriteBlock(Ser
writeBlock->length = (int) (writePtr - (UCHAR*) writeBlock);
writeWindow->setLastBlock(writeBlock);
writeWarningTrack = writeWindow->warningTrack;
- ASSERT(writeWindow->validate(writeBlock));
+ //ASSERT(writeWindow->validate(writeBlock));
}
diff -Nrup a/storage/falcon/SerialLogControl.cpp b/storage/falcon/SerialLogControl.cpp
--- a/storage/falcon/SerialLogControl.cpp 2007-07-12 16:58:19 -04:00
+++ b/storage/falcon/SerialLogControl.cpp 2007-09-04 17:11:19 -04:00
@@ -170,10 +170,10 @@ SerialLogRecord* SerialLogControl::getRe
void SerialLogControl::setWindow(SerialLogWindow *window, SerialLogBlock *block, int
offset)
{
- ASSERT(window->validate(block));
+ //ASSERT(window->validate(block));
SerialLogWindow *priorWindow = inputWindow;
SerialLogBlock *priorBlock = inputBlock;
- ASSERT(!priorWindow || priorWindow->validate(priorBlock));
+ //ASSERT(!priorWindow || priorWindow->validate(priorBlock));
if (inputWindow != window)
{
@@ -186,8 +186,8 @@ void SerialLogControl::setWindow(SerialL
Sync sync(&log->syncWrite, "SerialLogControl::setWindow");
sync.lock(Shared);
- inputWindow->validate(block);
- ASSERT(inputWindow->validate(block));
+ //inputWindow->validate(block);
+ //ASSERT(inputWindow->validate(block));
inputBlock = block;
input = inputBlock->data;
inputEnd = (const UCHAR*) inputBlock + block->length;
@@ -196,7 +196,7 @@ void SerialLogControl::setWindow(SerialL
if (inputBlock == log->writeBlock && log->recordIncomplete)
inputEnd = log->recordStart;
- ASSERT(inputWindow->validate(inputEnd));
+ //ASSERT(inputWindow->validate(inputEnd));
version = srlVersion0;
if (input < inputEnd)
diff -Nrup a/storage/falcon/SerialLogWindow.cpp b/storage/falcon/SerialLogWindow.cpp
--- a/storage/falcon/SerialLogWindow.cpp 2007-08-29 18:23:19 -04:00
+++ b/storage/falcon/SerialLogWindow.cpp 2007-09-04 17:11:19 -04:00
@@ -184,7 +184,7 @@ SerialLogBlock* SerialLogWindow::nextBlo
nextBlk->creationTime == (uint32) log->creationTime &&
nextBlk->blockNumber == block->blockNumber + 1)
{
- ASSERT(validate(nextBlk));
+ //ASSERT(validate(nextBlk));
return nextBlk;
}
diff -Nrup a/storage/falcon/Table.cpp b/storage/falcon/Table.cpp
--- a/storage/falcon/Table.cpp 2007-08-31 12:23:30 -04:00
+++ b/storage/falcon/Table.cpp 2007-09-04 17:11:19 -04:00
@@ -53,6 +53,7 @@
#include "Interlock.h"
#include "Collation.h"
#include "TableSpace.h"
+#include "RecordScavenge.h"
#ifndef STORAGE_ENGINE
#include "Trigger.h"
@@ -584,7 +585,7 @@ Record* Table::fetchNext(int32 start)
Record* Table::databaseFetch(int32 recordNumber)
{
Stream stream;
- ageGroup = database->currentAgeGroup;
+ ageGroup = database->currentGeneration;
if (!dataSection)
dataSection = dbb->findSection(dataSectionId);
@@ -762,7 +763,7 @@ void Table::loadIndexes()
void Table::init(int id, const char *schema, const char *tableName, TableSpace *tblSpace)
{
- ageGroup = database->currentAgeGroup;
+ ageGroup = database->currentGeneration;
if ( (tableSpace = tblSpace) )
dbb = tableSpace->dbb;
@@ -1258,7 +1259,7 @@ void Table::deleteRecord(Transaction * t
}
record->state = recDeleted;
- record->setAgeGroup();
+ //record->setAgeGroup();
fireTriggers(transaction, PreDelete, oldRecord, NULL);
// Do any necessary cascading
@@ -1559,9 +1560,19 @@ int Table::retireRecords(RecordScavenge
return count;
}
+void Table::inventoryRecords(RecordScavenge* recordScavenge)
+{
+ if (!records)
+ return;
+
+ Sync sync(&syncObject, "Table::inventoryRecords");
+ sync.lock(Shared);
+ records->inventoryRecords(recordScavenge);
+}
+
bool Table::insert(Record * record, Record *prior, int recordNumber)
{
- ageGroup = database->currentAgeGroup;
+ ageGroup = database->currentGeneration;
Sync sync(&syncObject, "Table::insert");
if (record)
diff -Nrup a/storage/falcon/Table.h b/storage/falcon/Table.h
--- a/storage/falcon/Table.h 2007-08-25 12:44:16 -04:00
+++ b/storage/falcon/Table.h 2007-09-04 17:11:20 -04:00
@@ -67,8 +67,7 @@ class AsciiBlob;
class BinaryBlob;
class Section;
class TableSpace;
-
-struct RecordScavenge;
+class RecordScavenge;
class Table : public PrivilegeObject
{
@@ -246,6 +245,7 @@ protected:
public:
RecordVersion* allocRecordVersion(Format* format, Transaction* transaction, Record*
priorVersion);
Record* allocRecord(int recordNumber, Stream* stream);
+ void inventoryRecords(RecordScavenge* recordScavenge);
};
#endif // !defined(AFX_TABLE_H__02AD6A42_A433_11D2_AB5B_0000C01D2301__INCLUDED_)
diff -Nrup a/storage/falcon/Transaction.cpp b/storage/falcon/Transaction.cpp
--- a/storage/falcon/Transaction.cpp 2007-08-23 21:21:26 -04:00
+++ b/storage/falcon/Transaction.cpp 2007-09-04 17:11:20 -04:00
@@ -54,6 +54,8 @@ static const char *stateNames [] = {
"Initial"
};
+static const int INDENT = 5;
+
#ifdef _DEBUG
#undef THIS_FILE
static const char THIS_FILE[]=__FILE__;
@@ -1103,6 +1105,12 @@ void Transaction::print(void)
Log::debug(" %p Id %d, state %d, updates %d, wrtPend %d, states %d, dependencies %d,
records %d\n",
this, transactionId, state, hasUpdates, writePending,
numberStates, dependencies, firstRecord != NULL);
+}
+
+void Transaction::printBlocking(int level)
+{
+ Log::debug ("%*s Trans %p, id %d\n",
+ level * INDENT, "", this, transactionId);
}
void Transaction::getInfo(InfoTable* infoTable)
diff -Nrup a/storage/falcon/Transaction.h b/storage/falcon/Transaction.h
--- a/storage/falcon/Transaction.h 2007-08-22 13:49:08 -04:00
+++ b/storage/falcon/Transaction.h 2007-09-04 17:11:21 -04:00
@@ -120,6 +120,12 @@ public:
void thaw(DeferredIndex* deferredIndex);
void print(void);
void getInfo(InfoTable* infoTable);
+ void fullyCommitted(void);
+ void releaseCommittedTransaction(void);
+ void commitNoUpdates(void);
+ void validateDependencies(bool noDependencies);
+ void releaseSavePoints(void);
+ void printBlocking(int level);
inline bool isActive()
{
@@ -179,12 +185,6 @@ protected:
RecordVersion **recordPtr;
virtual ~Transaction();
-public:
- void fullyCommitted(void);
- void releaseCommittedTransaction(void);
- void commitNoUpdates(void);
- void validateDependencies(bool noDependencies);
- void releaseSavePoints(void);
};
#endif // !defined(AFX_TRANSACTION_H__02AD6A4D_A433_11D2_AB5B_0000C01D2301__INCLUDED_)
diff -Nrup a/storage/falcon/TransactionManager.cpp b/storage/falcon/TransactionManager.cpp
--- a/storage/falcon/TransactionManager.cpp 2007-08-23 21:21:26 -04:00
+++ b/storage/falcon/TransactionManager.cpp 2007-09-04 17:11:21 -04:00
@@ -427,3 +427,20 @@ void TransactionManager::removeTransacti
}
}
}
+
+void TransactionManager::printBlockage(void)
+{
+ Sync sync (&activeTransactions.syncObject, "TransactionManager::printBlockage");
+ sync.lock (Shared);
+
+ for (Transaction *trans = activeTransactions.first; trans; trans = trans->next)
+ if (trans->state == Active && !trans->waitingFor)
+ trans->printBlocking(1);
+}
+
+void TransactionManager::printBlocking(Transaction* transaction, int level)
+{
+ for (Transaction *trans = activeTransactions.first; trans; trans = trans->next)
+ if (trans->state == Active && trans->waitingFor == transaction)
+ trans->printBlocking(level + 1);
+}
diff -Nrup a/storage/falcon/TransactionManager.h b/storage/falcon/TransactionManager.h
--- a/storage/falcon/TransactionManager.h 2007-07-17 17:23:17 -04:00
+++ b/storage/falcon/TransactionManager.h 2007-09-04 17:11:21 -04:00
@@ -59,6 +59,8 @@ public:
int priorRolledBack;
Queue<Transaction> activeTransactions;
Queue<Transaction> committedTransactions;
+ void printBlockage(void);
+ void printBlocking(Transaction* transaction, int level);
};
#endif
| Thread |
|---|
| • bk commit into 6.0-falcon tree (jas:1.2591) | U-ROWVWADEjas | 4 Sep |