#At file:///C:/bzr/mysql-6.0-falcon/
2781 Vladislav Vaintroub 2008-08-27 [merge]
merge 6.0-falcon-team -> 6.0-falcon
modified:
configure.in
mysql-test/include/have_falcon.inc
mysql-test/suite/falcon/r/falcon_bug_22165.result
mysql-test/suite/falcon/t/falcon_bug_22165.test
storage/falcon/BackLog.cpp
storage/falcon/CMakeLists.txt
storage/falcon/Configuration.cpp
storage/falcon/IO.cpp
storage/falcon/Index.cpp
storage/falcon/Index2RootPage.cpp
storage/falcon/IndexRootPage.cpp
storage/falcon/Interlock.h
storage/falcon/MemMgr.cpp
storage/falcon/RepositoryVolume.cpp
storage/falcon/Statement.cpp
storage/falcon/StorageDatabase.cpp
storage/falcon/StorageDatabase.h
storage/falcon/StorageTable.cpp
storage/falcon/StorageTable.h
storage/falcon/StorageTableShare.cpp
storage/falcon/StorageTableShare.h
storage/falcon/Table.cpp
storage/falcon/Table.h
storage/falcon/TableSpace.cpp
storage/falcon/Transaction.cpp
storage/falcon/Transaction.h
storage/falcon/TransactionManager.cpp
storage/falcon/ha_falcon.cpp
storage/falcon/ha_falcon.h
storage/falcon/plug.in
=== modified file 'configure.in'
--- a/configure.in 2008-08-26 06:52:00 +0000
+++ b/configure.in 2008-08-27 09:49:44 +0000
@@ -1797,6 +1797,9 @@ if test "x$mysql_cv_gcc_atomic_builtins"
[Define to 1 if compiler provides atomic builtins.])
fi
+# Check if we have the atomic_* functions on Solaris
+AC_CHECK_FUNC(atomic_cas_32, AC_DEFINE([HAVE_SOLARIS_ATOMIC], [1], [Define to 1 if Solaris support atomic functions.]))
+
# Force static compilation to avoid linking problems/get more speed
AC_ARG_WITH(mysqld-ldflags,
[ --with-mysqld-ldflags Extra linking arguments for mysqld],
=== modified file 'mysql-test/include/have_falcon.inc'
--- a/mysql-test/include/have_falcon.inc 2008-03-30 13:57:32 +0000
+++ b/mysql-test/include/have_falcon.inc 2008-08-15 11:06:08 +0000
@@ -1,5 +1,18 @@
+##
+## Checks for the presence of the Falcon storage engine (plugin)
+## by querying the INFORMATION_SCHEMA.ENGINES table.
+##
+## If Falcon is not available, the test using this include file
+## is skipped.
+##
+
+# Do not echo these statements to test results
--disable_query_log
-# Ignore errors when trying to install the Falcon plugin
---require r/true.require
-SELECT (support = 'YES' OR support = 'DEFAULT' OR support = 'ENABLED') AS `TRUE` FROM INFORMATION_SCHEMA.ENGINES WHERE ENGINE = 'Falcon';
+
+# Check if Falcon is available
+let $have_falcon = `SELECT (support = 'YES' OR support = 'DEFAULT' OR support = 'ENABLED') AS 'HAVE_FALCON' FROM INFORMATION_SCHEMA.ENGINES WHERE ENGINE = 'Falcon'`;
+if (!$have_falcon)
+{
+ skip Test needs the Falcon storage engine;
+}
--enable_query_log
=== modified file 'mysql-test/suite/falcon/r/falcon_bug_22165.result'
--- a/mysql-test/suite/falcon/r/falcon_bug_22165.result 2008-08-04 15:53:52 +0000
+++ b/mysql-test/suite/falcon/r/falcon_bug_22165.result 2008-08-21 13:18:06 +0000
@@ -16,7 +16,10 @@ while v < 10 do
START TRANSACTION;
INSERT INTO t1 (a, b) VALUES (v, 'a');
UPDATE t1 SET c = current_timestamp WHERE a = v;
-COMMIT;
+IF (v < 5)
+THEN COMMIT;
+ELSE ROLLBACK;
+END IF;
SET v = v + 1;
end while;
end//
=== modified file 'mysql-test/suite/falcon/t/falcon_bug_22165.test'
--- a/mysql-test/suite/falcon/t/falcon_bug_22165.test 2008-08-04 15:53:52 +0000
+++ b/mysql-test/suite/falcon/t/falcon_bug_22165.test 2008-08-21 13:18:06 +0000
@@ -30,7 +30,10 @@ begin
START TRANSACTION;
INSERT INTO t1 (a, b) VALUES (v, 'a');
UPDATE t1 SET c = current_timestamp WHERE a = v;
- COMMIT;
+ IF (v < 5)
+ THEN COMMIT;
+ ELSE ROLLBACK;
+ END IF;
SET v = v + 1;
end while;
end//
@@ -57,7 +60,7 @@ while ($i)
--reap
connection conn2;
--reap
-
+
dec $i;
}
--enable_query_log
=== modified file 'storage/falcon/BackLog.cpp'
--- a/storage/falcon/BackLog.cpp 2008-07-17 13:52:17 +0000
+++ b/storage/falcon/BackLog.cpp 2008-08-18 20:17:15 +0000
@@ -37,7 +37,9 @@ BackLog::BackLog(Database *db, const cha
{
database = db;
dbb = new Dbb(database->dbb, 0);
+#ifndef FALCONDB
dbb->createPath(fileName);
+#endif
dbb->create(fileName, dbb->pageSize, 0, HdrTableSpace, 0, NULL);
dbb->noLog = true;
dbb->tableSpaceId = -1;
=== modified file 'storage/falcon/CMakeLists.txt'
--- a/storage/falcon/CMakeLists.txt 2008-08-26 18:57:58 +0000
+++ b/storage/falcon/CMakeLists.txt 2008-08-27 09:49:44 +0000
@@ -23,13 +23,11 @@ INCLUDE_DIRECTORIES(${CMAKE_SOURCE_DIR}/
. TransformLib
${CMAKE_SOURCE_DIR}/extra/yassl/include
${CMAKE_SOURCE_DIR}/zlib)
-IF(CMAKE_GENERATOR MATCHES "Visual Studio 7" OR
- CMAKE_GENERATOR MATCHES "Visual Studio 8")
+IF(MSVC)
SET(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} /EHsc")
SET(CMAKE_CXX_FLAGS_INIT "${CMAKE_CXX_FLAGS_INIT} /EHsc")
SET(CMAKE_CXX_FLAGS_DEBUG_INIT "${CMAKE_CXX_FLAGS_DEBUG_INIT} /EHsc")
-ENDIF(CMAKE_GENERATOR MATCHES "Visual Studio 7" OR
- CMAKE_GENERATOR MATCHES "Visual Studio 8")
+ENDIF(MSVC)
SET(FALCON_SOURCES
Agent.cpp
=== modified file 'storage/falcon/Configuration.cpp'
--- a/storage/falcon/Configuration.cpp 2008-07-17 13:52:17 +0000
+++ b/storage/falcon/Configuration.cpp 2008-08-19 14:27:42 +0000
@@ -151,8 +151,14 @@ Configuration::Configuration(const char
if (!scanDir.isDirectory())
{
- //throw SQLEXCEPTION (RUNTIME_ERROR, "Invalid serial log directory path \"%s\"", falcon_serial_log_dir);
- serialLogDir = "";
+ fprintf(stderr,
+ "Falcon: The specified serial log directory, \"%s\", "
+ "does not exist.\n"
+ "Falcon: The serial log directory must be created by "
+ "the user before initializing Falcon.\n",
+ falcon_serial_log_dir
+ );
+ throw SQLEXCEPTION (FILE_ACCESS_ERROR, "Invalid serial log directory path \"%s\"", falcon_serial_log_dir);
}
}
#else
=== modified file 'storage/falcon/IO.cpp'
--- a/storage/falcon/IO.cpp 2008-08-14 16:34:43 +0000
+++ b/storage/falcon/IO.cpp 2008-08-18 20:17:15 +0000
@@ -411,13 +411,17 @@ void IO::declareFatalError()
fatalError = true;
}
+
+#ifndef ENOSYS
+#define ENOSYS EEXIST
+#endif
+
+// Make sure parent directories for file exist
void IO::createPath(const char *fileName)
{
- // First, better make sure directories exists
JString fname = getPath(fileName);
char directory [256], *q = directory;
-
for (const char *p = fname.getString(); *p;)
{
char c = *p++;
@@ -427,9 +431,14 @@ void IO::createPath(const char *fileName
*q = 0;
if (q > directory && q [-1] != ':')
- if (MKDIR (directory) && errno != EEXIST)
+ {
+ if (MKDIR (directory) && errno != EEXIST && errno != ENOSYS)
+ // ENOSYS is a Solaris speficic workaround, mkdir returns it
+ // on existing automounted NFS directories, instead
+ // of EEXIST.
throw SQLError (IO_ERROR,
"can't create directory \"%s\"\n", directory);
+ }
}
*q++ = c;
}
=== modified file 'storage/falcon/Index.cpp'
--- a/storage/falcon/Index.cpp 2008-07-25 18:07:24 +0000
+++ b/storage/falcon/Index.cpp 2008-08-19 03:33:01 +0000
@@ -107,7 +107,6 @@ void Index::init(Table *tbl, const char
DIHashTable = NULL;
DIHashTableCounts = 0;
DIHashTableSlotsUsed = 0;
-
syncDIHash.setName("Index::syncDIHash");
syncUnique.setName("Index::syncUnique");
deferredIndexes.syncObject.setName("Index::deferredIndexes.syncObject");
=== modified file 'storage/falcon/Index2RootPage.cpp'
--- a/storage/falcon/Index2RootPage.cpp 2008-03-27 06:09:29 +0000
+++ b/storage/falcon/Index2RootPage.cpp 2008-08-25 22:09:13 +0000
@@ -518,9 +518,9 @@ bool Index2RootPage::splitIndexPage(Dbb
leftPage->parentPage = bdb->pageNumber;
splitPage->parentPage = bdb->pageNumber;
- Index2Page::logIndexPage(bdb, transId);
Index2Page::logIndexPage(splitBdb, transId);
Index2Page::logIndexPage(leftBdb, transId);
+ Index2Page::logIndexPage(bdb, transId);
splitBdb->release(REL_HISTORY);
leftBdb->release(REL_HISTORY);
=== modified file 'storage/falcon/IndexRootPage.cpp'
--- a/storage/falcon/IndexRootPage.cpp 2008-05-14 18:39:57 +0000
+++ b/storage/falcon/IndexRootPage.cpp 2008-08-25 22:09:13 +0000
@@ -552,12 +552,16 @@ bool IndexRootPage::splitIndexPage(Dbb *
page->addNode(dbb, &dummy, END_LEVEL);
page->addNode(dbb, &leftKey, leftBdb->pageNumber);
page->addNode(dbb, &splitKey, splitBdb->pageNumber);
-
+
leftPage->parentPage = bdb->pageNumber;
splitPage->parentPage = bdb->pageNumber;
- IndexPage::logIndexPage(bdb, transId);
+
+ // the order of adding these to the serial log is important.
+ // Recovery must write them in this order incase recovery itself crashes.
+
IndexPage::logIndexPage(splitBdb, transId);
IndexPage::logIndexPage(leftBdb, transId);
+ IndexPage::logIndexPage(bdb, transId);
/***
IndexPage::printPage(bdb, false);
=== modified file 'storage/falcon/Interlock.h'
--- a/storage/falcon/Interlock.h 2008-07-10 09:27:51 +0000
+++ b/storage/falcon/Interlock.h 2008-08-21 11:23:44 +0000
@@ -396,7 +396,7 @@ inline INTERLOCK_TYPE interlockedAdd(vol
{
INTERLOCK_TYPE current= *addend;
INTERLOCK_TYPE ret= current + value;
- if (COMPARE_EXCHANGE_POINTER(addend, current, ret))
+ if (COMPARE_EXCHANGE(addend, current, ret))
return ret;
}
#endif
=== modified file 'storage/falcon/MemMgr.cpp'
--- a/storage/falcon/MemMgr.cpp 2008-08-12 22:21:35 +0000
+++ b/storage/falcon/MemMgr.cpp 2008-08-20 16:28:44 +0000
@@ -694,7 +694,7 @@ void MemMgr::corrupt(const char* text)
#endif
MemMgrLogDump();
- throw SQLError (BUG_CHECK, "memory is corrupt: %s", text);
+ FATAL("memory is corrupt: %s", text);
}
void* MemMgr::memoryIsExhausted(void)
=== modified file 'storage/falcon/RepositoryVolume.cpp'
--- a/storage/falcon/RepositoryVolume.cpp 2008-07-24 08:45:03 +0000
+++ b/storage/falcon/RepositoryVolume.cpp 2008-08-18 20:17:15 +0000
@@ -232,7 +232,9 @@ void RepositoryVolume::makeWritable()
void RepositoryVolume::create()
{
+#ifndef FALCONDB
IO::createPath (fileName);
+#endif
dbb->create(fileName, dbb->pageSize, 0, HdrRepositoryFile, 0, NULL);
Sync syncDDL(&database->syncSysDDL, "RepositoryVolume::create");
Transaction *transaction = database->getSystemTransaction();
=== modified file 'storage/falcon/Statement.cpp'
--- a/storage/falcon/Statement.cpp 2008-07-24 08:45:03 +0000
+++ b/storage/falcon/Statement.cpp 2008-08-18 05:45:29 +0000
@@ -144,7 +144,6 @@ Statement::Statement(Connection *pConnec
special = false;
active = false;
memset (&stats, 0, sizeof (stats));
- syncObject.setName("Statement::syncObject");
}
Statement::~Statement()
@@ -2303,16 +2302,10 @@ void Statement::dropIndex(Syntax *syntax
throw SQLEXCEPTION (DDL_ERROR, "table %s.%s not defined", (const char*) tableName, schema);
checkAlterPriv (table);
- Index *index = table->findIndex (name);
- if (index)
- {
Transaction *sysTransaction = database->getSystemTransaction();
- table->dropIndex(index);
- index->deleteIndex(sysTransaction); /* transaction */
- delete index;
+ table->dropIndex(name, sysTransaction);
database->commitSystemTransaction();
- }
Index::deleteIndex (database, schema, name);
database->commitSystemTransaction();
=== modified file 'storage/falcon/StorageDatabase.cpp'
--- a/storage/falcon/StorageDatabase.cpp 2008-07-24 08:45:03 +0000
+++ b/storage/falcon/StorageDatabase.cpp 2008-08-18 20:17:15 +0000
@@ -156,7 +156,9 @@ Connection* StorageDatabase::createDatab
try
{
masterConnection = getConnection();
+#ifndef FALCONDB
IO::createPath(filename);
+#endif
masterConnection->createDatabase(name, filename, ACCOUNT, PASSWORD, threads);
Statement *statement = masterConnection->createStatement();
@@ -688,7 +690,7 @@ int StorageDatabase::updateRow(StorageCo
return 0;
}
-int StorageDatabase::createIndex(StorageConnection *storageConnection, Table* table, const char* indexName, const char* sql)
+int StorageDatabase::createIndex(StorageConnection *storageConnection, Table* table, const char* sql)
{
Connection *connection = storageConnection->connection;
Statement *statement = connection->createStatement();
@@ -713,7 +715,7 @@ int StorageDatabase::createIndex(Storage
return 0;
}
-int StorageDatabase::dropIndex(StorageConnection *storageConnection, Table* table, const char* indexName, const char* sql)
+int StorageDatabase::dropIndex(StorageConnection *storageConnection, Table* table, const char* sql)
{
Connection *connection = storageConnection->connection;
Statement *statement = connection->createStatement();
@@ -746,17 +748,6 @@ int StorageDatabase::renameTable(Storage
{
Database *database = connection->database;
Sequence *sequence = connection->findSequence(schemaName, table->name);
- int numberIndexes = 0;
- int firstIndex = 0;
- Index *index;
-
- for (index = table->indexes; index; index = index->next)
- {
- if (index->type == PrimaryKey)
- firstIndex = 1;
-
- ++numberIndexes;
- }
Sync syncDDL(&database->syncSysDDL, "StorageDatabase::renameTable(1)");
syncDDL.lock(Exclusive);
@@ -764,19 +755,6 @@ int StorageDatabase::renameTable(Storage
Sync syncTables(&database->syncTables, "StorageDatabase::renameTable(2)");
syncTables.lock(Exclusive);
- for (int n = firstIndex; n < numberIndexes; ++n)
- {
- char indexName[256];
- sprintf(indexName, "%s$%d", (const char*) table->name, n);
- Index *index = table->findIndex(indexName);
-
- if (index)
- {
- sprintf(indexName, "%s$%d", tableName, n);
- index->rename(indexName);
- }
- }
-
table->rename(schemaName, tableName);
if (sequence)
=== modified file 'storage/falcon/StorageDatabase.h'
--- a/storage/falcon/StorageDatabase.h 2008-07-24 08:45:03 +0000
+++ b/storage/falcon/StorageDatabase.h 2008-08-18 05:45:29 +0000
@@ -40,7 +40,7 @@ class IndexWalker;
CLASS(Field);
-struct StorageIndexDesc;
+class StorageIndexDesc;
struct StorageKey;
struct StorageBlob;
struct StorageSegment;
@@ -61,7 +61,6 @@ public:
int savepointRollback(Connection* connection, int savePoint);
int deleteTable(StorageConnection* storageConnection,StorageTableShare *tableShare);
int truncateTable(StorageConnection* storageConnection, StorageTableShare *tableShare);
- int createIndex(StorageConnection *storageConnection, Table* table, StorageIndexDesc* indexDesc);
int renameTable(StorageConnection* storageConnection, Table* table, const char* newName, const char *schemaName);
Bitmap* indexScan(Index* index, StorageKey *lower, StorageKey *upper, int searchFlags, StorageConnection* storageConnection, Bitmap *bitmap);
IndexWalker* indexPosition(Index* index, StorageKey* lower, StorageKey* upper, int searchFlags, StorageConnection* storageConnection);
@@ -74,8 +73,8 @@ public:
void freeBlob(StorageBlob *blob);
void close(void);
void validateCache(void);
- int createIndex(StorageConnection* storageConnection, Table* table, const char* indexName, const char* sql);
- int dropIndex(StorageConnection* storageConnection, Table* table, const char* indexName, const char* sql);
+ int createIndex(StorageConnection* storageConnection, Table* table, const char* sql);
+ int dropIndex(StorageConnection* storageConnection, Table* table, const char* sql);
int insert(Connection* connection, Table* table, Stream* stream);
int nextRow(StorageTable* storageTable, int recordNumber, bool lockForUpdate);
=== modified file 'storage/falcon/StorageTable.cpp'
--- a/storage/falcon/StorageTable.cpp 2008-08-11 13:22:53 +0000
+++ b/storage/falcon/StorageTable.cpp 2008-08-22 06:47:40 +0000
@@ -51,11 +51,13 @@ StorageTable::StorageTable(StorageConnec
upperBound = lowerBound = NULL;
record = NULL;
recordLocked = false;
- haveTruncateLock = false;
+ indexesLocked = false;
}
StorageTable::~StorageTable(void)
{
+ clearCurrentIndex();
+
if (bitmap)
((Bitmap*) bitmap)->release();
@@ -94,12 +96,12 @@ int StorageTable::deleteTable(void)
int StorageTable::truncateTable(void)
{
clearRecord();
+ clearCurrentIndex();
+
int ret = share->truncateTable(storageConnection);
return ret;
}
-
-
int StorageTable::insert(void)
{
try
@@ -139,6 +141,16 @@ int StorageTable::updateRow(int recordNu
return 0;
}
+int StorageTable::createIndex(StorageIndexDesc *indexDesc, const char *sql)
+{
+ return share->createIndex(storageConnection, indexDesc, sql);
+}
+
+int StorageTable::dropIndex(StorageIndexDesc *indexDesc, const char *sql)
+{
+ return share->dropIndex(storageConnection, indexDesc, sql);
+}
+
int StorageTable::next(int recordNumber, bool lockForUpdate)
{
recordLocked = false;
@@ -174,21 +186,51 @@ void StorageTable::transactionEnded(void
{
}
-int StorageTable::setIndex(int numberIndexes, int indexId, StorageIndexDesc* storageIndex)
+int StorageTable::setCurrentIndex(int indexId)
{
- if (!(currentIndex = share->getIndex(numberIndexes, indexId, storageIndex)))
+ if (!indexesLocked)
+ {
+ share->lockIndexes();
+ indexesLocked = true;
+ }
+
+ if (!(currentIndex = share->getIndex(indexId)))
+{
+ clearCurrentIndex();
return StorageErrorNoIndex;
-
+ }
+
upperBound = lowerBound = NULL;
searchFlags = 0;
+ return 0;
+}
+int StorageTable::clearCurrentIndex()
+{
+ if (indexesLocked)
+ {
+ share->unlockIndexes();
+ indexesLocked = false;
+ }
+
+ currentIndex = NULL;
+ upperBound = lowerBound = NULL;
+ searchFlags = 0;
return 0;
}
+int StorageTable::setIndex(StorageIndexDesc* indexDesc)
+{
+ return share->setIndex(indexDesc);
+}
+
int StorageTable::indexScan(int indexOrder)
{
if (!currentIndex)
+ {
+ clearCurrentIndex();
return StorageErrorNoIndex;
+ }
int numberSegments = (upperBound) ? upperBound->numberSegments : (lowerBound) ? lowerBound->numberSegments : 0;
@@ -203,26 +245,16 @@ int StorageTable::indexScan(int indexOrd
return 0;
}
-
void StorageTable::clearBitmap(void)
{
if (bitmap)
((Bitmap*) bitmap)->clear();
}
-int StorageTable::setIndex(int indexId)
-{
- if (!(currentIndex = share->getIndex(indexId)))
- return StorageErrorNoIndex;
-
- upperBound = lowerBound = NULL;
- searchFlags = 0;
-
- return 0;
-}
-
void StorageTable::indexEnd(void)
{
+ clearCurrentIndex();
+
if (bitmap)
clearBitmap();
@@ -236,7 +268,10 @@ void StorageTable::indexEnd(void)
int StorageTable::setIndexBound(const unsigned char* key, int keyLength, int which)
{
if (!currentIndex)
+ {
+ clearCurrentIndex();
return StorageErrorNoIndex;
+ }
if (which & LowerBound)
{
=== modified file 'storage/falcon/StorageTable.h'
--- a/storage/falcon/StorageTable.h 2008-08-11 13:22:53 +0000
+++ b/storage/falcon/StorageTable.h 2008-08-22 06:47:40 +0000
@@ -49,8 +49,7 @@ class Record;
class SyncObject;
class Format;
class IndexWalker;
-
-struct StorageIndexDesc;
+class StorageIndexDesc;
class StorageTable
{
@@ -65,8 +64,6 @@ public:
void clearAlter(void);
bool setAlter(void);
-
-
virtual void setConnection(StorageConnection* connection);
virtual void clearIndexBounds(void);
virtual void clearRecord(void);
@@ -78,9 +75,10 @@ public:
virtual int deleteTable(void);
virtual int deleteRow(int recordNumber);
virtual int truncateTable(void);
- virtual int setIndex(int numberIndexes, int indexId, StorageIndexDesc* storageIndex);
virtual int indexScan(int indexOrder);
- virtual int setIndex(int indexId);
+ virtual int setCurrentIndex(int indexId);
+ virtual int clearCurrentIndex();
+ virtual int setIndex(StorageIndexDesc* indexDesc);
virtual void indexEnd(void);
virtual int setIndexBound(const unsigned char* key, int keyLength, int which);
virtual int storeBlob(StorageBlob* blob);
@@ -96,6 +94,8 @@ public:
virtual int fetch(int recordNumber, bool lockForUpdate);
virtual int updateRow(int recordNumber);
+ virtual int createIndex(StorageIndexDesc *indexDesc, const char *sql);
+ virtual int dropIndex(StorageIndexDesc *indexDesc, const char *sql);
virtual const unsigned char* getEncoding(int fieldIndex);
virtual const char* getName(void);
virtual const char* getSchemaName(void);
@@ -128,7 +128,7 @@ public:
Stream insertStream;
int searchFlags;
bool recordLocked;
- bool haveTruncateLock;
+ bool indexesLocked;
};
#endif
=== modified file 'storage/falcon/StorageTableShare.cpp'
--- a/storage/falcon/StorageTableShare.cpp 2008-08-04 15:53:52 +0000
+++ b/storage/falcon/StorageTableShare.cpp 2008-08-22 06:47:40 +0000
@@ -33,14 +33,11 @@
#include "PreparedStatement.h"
#include "ResultSet.h"
#include "SQLException.h"
+#include "CmdGen.h"
static const char *FALCON_TEMPORARY = "/falcon_temporary";
static const char *DB_ROOT = ".fts";
-#ifndef ONLINE_ALTER
-//#define ONLINE_ALTER
-#endif
-
#if defined(_WIN32) && MYSQL_VERSION_ID < 0x50100
#define IS_SLASH(c) (c == '/' || c == '\\')
#else
@@ -52,6 +49,43 @@ static const char *DB_ROOT = ".fts";
static const char THIS_FILE[]=__FILE__;
#endif
+StorageIndexDesc::StorageIndexDesc()
+{
+ id = 0;
+ unique = 0;
+ primaryKey = 0;
+ numberSegments = 0;
+ index = NULL;
+ segmentRecordCounts = NULL;
+ next = NULL;
+ name[0] = '\0';
+ rawName[0] = '\0';
+};
+
+StorageIndexDesc::StorageIndexDesc(const StorageIndexDesc *indexInfo)
+{
+ if (indexInfo)
+ *this = *indexInfo;
+ else
+ {
+ id = 0;
+ unique = 0;
+ primaryKey = 0;
+ numberSegments = 0;
+ segmentRecordCounts = NULL;
+ name[0] = '\0';
+ rawName[0] = '\0';
+ }
+
+ index = NULL;
+ next = NULL;
+ prev = NULL;
+};
+
+StorageIndexDesc::~StorageIndexDesc(void)
+{
+}
+
//////////////////////////////////////////////////////////////////////
// Construction/Destruction
//////////////////////////////////////////////////////////////////////
@@ -63,13 +97,15 @@ StorageTableShare::StorageTableShare(Sto
impure = new UCHAR[lockSize];
initialized = false;
table = NULL;
- indexes = NULL;
format = NULL;
syncObject = new SyncObject;
syncObject->setName("StorageTableShare::syncObject");
+ syncIndexes = new SyncObject;
+ syncIndexes->setName("StorageTableShare::syncIndexes");
sequence = NULL;
tempTable = tempTbl;
setPath(path);
+ indexes = NULL;
if (tempTable)
tableSpace = TEMPORARY_TABLESPACE;
@@ -82,18 +118,16 @@ StorageTableShare::StorageTableShare(Sto
StorageTableShare::~StorageTableShare(void)
{
delete syncObject;
+ delete syncIndexes;
delete [] impure;
if (storageDatabase)
storageDatabase->release();
- if (indexes)
+ for (StorageIndexDesc *indexDesc; (indexDesc = indexes);)
{
- for (int n = 0; n < numberIndexes; ++n)
- delete indexes[n];
-
- delete [] indexes;
- indexes = NULL;
+ indexes = indexDesc->next;
+ delete indexDesc;
}
}
@@ -107,6 +141,16 @@ void StorageTableShare::unlock(void)
syncObject->unlock();
}
+void StorageTableShare::lockIndexes(bool exclusiveLock)
+{
+ syncIndexes->lock(NULL, (exclusiveLock) ? Exclusive : Shared);
+}
+
+void StorageTableShare::unlockIndexes(void)
+{
+ syncIndexes->unlock();
+}
+
int StorageTableShare::open(void)
{
if (!table)
@@ -189,7 +233,7 @@ int StorageTableShare::truncateTable(Sto
return res;
}
-void StorageTableShare::cleanupFieldName(const char* name, char* buffer, int bufferLength)
+const char* StorageTableShare::cleanupFieldName(const char* name, char* buffer, int bufferLength)
{
char *q = buffer;
char *end = buffer + bufferLength - 1;
@@ -211,6 +255,8 @@ void StorageTableShare::cleanupFieldName
}
*q = 0;
+
+ return buffer;
}
const char* StorageTableShare::cleanupTableName(const char* name, char* buffer, int bufferLength, char *schema, int schemaLength)
@@ -239,20 +285,96 @@ const char* StorageTableShare::cleanupTa
return buffer;
}
-int StorageTableShare::createIndex(StorageConnection *storageConnection, const char* name, const char* sql)
+char* StorageTableShare::createIndexName(const char *rawName, char *indexName)
+{
+ char nameBuffer[indexNameSize];
+ cleanupFieldName(rawName, nameBuffer, sizeof(nameBuffer));
+ sprintf(indexName, "%s$%s", name.getString(), nameBuffer);
+ return indexName;
+}
+
+int StorageTableShare::createIndex(StorageConnection *storageConnection, StorageIndexDesc *indexDesc, const char *sql)
{
if (!table)
open();
- return storageDatabase->createIndex(storageConnection, table, name, sql);
+ // Lock out other clients before locking the table
+
+ Sync syncIndex(syncIndexes, "StorageTableShare::createIndex(1)");
+ syncIndex.lock(Exclusive);
+
+ Sync syncObj(syncObject, "StorageTableShare::createIndex(2)");
+ syncObj.lock(Exclusive);
+
+ int ret = storageDatabase->createIndex(storageConnection, table, sql);
+
+ if (!ret)
+ ret = setIndex(indexDesc);
+
+ return ret;
}
-int StorageTableShare::dropIndex(StorageConnection *storageConnection, const char* name, const char* sql)
+void StorageTableShare::addIndex(StorageIndexDesc *indexDesc)
+{
+ if (!getIndex(indexDesc->id))
+ {
+ if (indexes)
+ {
+ indexDesc->next = indexes;
+ indexDesc->prev = NULL;
+ indexes->prev = indexDesc;
+ }
+
+ indexes = indexDesc;
+ }
+}
+
+void StorageTableShare::deleteIndex(int indexId)
+{
+ for (StorageIndexDesc *indexDesc = indexes; indexDesc; indexDesc = indexDesc->next)
+ if (indexDesc->id == indexId)
+ {
+ if (indexDesc->prev)
+ indexDesc->prev->next = indexDesc->next;
+ else
+ indexes = indexDesc->next;
+
+ if (indexDesc->next)
+ indexDesc->next->prev = indexDesc->prev;
+
+ delete indexDesc;
+ break;
+ }
+}
+
+int StorageTableShare::dropIndex(StorageConnection *storageConnection, StorageIndexDesc *indexDesc, const char *sql)
{
if (!table)
open();
- return storageDatabase->dropIndex(storageConnection, table, name, sql);
+ // Lock out other clients before locking the table
+
+ Sync syncIndex(syncIndexes, "StorageTableShare::dropIndex(1)");
+ syncIndex.lock(Exclusive);
+
+ Sync syncObj(syncObject, "StorageTableShare::dropIndex(2)");
+ syncObj.lock(Exclusive);
+
+ int ret = storageDatabase->dropIndex(storageConnection, table, sql);
+
+ if (!ret)
+ deleteIndex(indexDesc->id);
+
+ return ret;
+}
+
+void StorageTableShare::deleteIndexes()
+{
+ for (StorageIndexDesc *indexDesc; (indexDesc = indexes);)
+ {
+ indexes = indexDesc->next;
+ delete indexDesc;
+ }
}
int StorageTableShare::renameTable(StorageConnection *storageConnection, const char* newName)
@@ -274,72 +396,109 @@ int StorageTableShare::renameTable(Stora
return ret;
}
-StorageIndexDesc* StorageTableShare::getIndex(int indexCount, int indexId, StorageIndexDesc* indexDesc)
+int StorageTableShare::setIndex(const StorageIndexDesc *indexInfo)
{
- // Rebuild array if indexes have been added or dropped
-
-#ifdef ONLINE_ALTER
+ int ret = 0;
- // TODO: This does not work. It should be done at the time of index creation
+ if (!getIndex(indexInfo->id))
+ {
+ StorageIndexDesc *indexDesc = new StorageIndexDesc(indexInfo);
+ addIndex(indexDesc);
- if (indexes && (numberIndexes != indexCount))
+ // Find the corresponding Falcon index
+
+ if (indexDesc->primaryKey)
+ indexDesc->index = table->primaryKey;
+ else
{
- Sync sync(syncObject, "StorageTableShare::getIndex");
- sync.lock(Exclusive);
- StorageIndexDesc **oldIndexes = indexes;
- StorageIndexDesc **newIndexes = new StorageIndexDesc*[indexCount];
- memset(newIndexes, 0, indexCount * sizeof(StorageIndexDesc*));
+ char indexName[indexNameSize];
+ sprintf(indexName, "%s$%s", name.getString(), indexDesc->name);
+ indexDesc->index = table->findIndex(indexName);
+ }
+
+ if (indexDesc->index)
+ indexDesc->segmentRecordCounts = indexDesc->index->recordsPerSegment;
+ else
+ ret = StorageErrorNoIndex;
+ }
- for (int n = 0; n < numberIndexes; ++n)
- newIndexes[n] = indexes[n];
+ return ret;
+}
+
+StorageIndexDesc* StorageTableShare::getIndex(int indexId)
+{
+ if (!indexes)
+ return NULL;
+
+ for (StorageIndexDesc *indexDesc = indexes; indexDesc; indexDesc = indexDesc->next)
+ if (indexDesc->id == indexId)
+ return indexDesc;
- indexes = newIndexes;
- numberIndexes = indexCount;
- delete [] oldIndexes;
- }
-#endif
-
+ return NULL;
+}
+
+StorageIndexDesc* StorageTableShare::getIndex(int indexId, StorageIndexDesc *indexDesc)
+{
if (!indexes)
- {
- indexes = new StorageIndexDesc*[indexCount];
- memset(indexes, 0, indexCount * sizeof(StorageIndexDesc*));
- numberIndexes = indexCount;
- }
-
- if (indexId >= numberIndexes)
return NULL;
- StorageIndexDesc *index = indexes[indexId];
+ Sync sync(syncIndexes, "StorageTableShare::getIndex");
+ sync.lock(Shared);
+ StorageIndexDesc *index = getIndex(indexId);
+
if (index)
- return index;
+ *indexDesc = *index;
+
+ return index;
+}
- indexes[indexId] = index = new StorageIndexDesc;
- *index = *indexDesc;
+StorageIndexDesc* StorageTableShare::getIndex(const char *name)
+{
+ if (!indexes)
+ return NULL;
- if (indexDesc->primaryKey)
- index->index = table->primaryKey;
- else
- {
- char indexName[150];
- sprintf(indexName, "%s$%d", (const char*) name, indexId);
- index->index = storageDatabase->findIndex(table, indexName);
- }
+ Sync sync(syncIndexes, "StorageTableShare::getIndex(name)");
+ sync.lock(Shared);
+
+ for (StorageIndexDesc *indexDesc = indexes; indexDesc; indexDesc = indexDesc->next)
+ if (indexDesc->name == name)
+ return indexDesc;
+
+ return NULL;
+}
- if (index->index)
- index->segmentRecordCounts = index->index->recordsPerSegment;
- else
- index = NULL;
+int StorageTableShare::getIndexId(const char* schemaName, const char* indexName)
+{
+ if (!indexes)
+ return -1;
- return index;
+ for (StorageIndexDesc *indexDesc = indexes; indexDesc; indexDesc = indexDesc->next)
+ {
+ Index *index = indexDesc->index;
+
+ if (index)
+ if (strcmp(index->getIndexName(), indexName) == 0 &&
+ strcmp(index->getSchemaName(), schemaName) == 0)
+ return indexDesc->id;
+ }
+
+ return -1;
}
-StorageIndexDesc* StorageTableShare::getIndex(int indexId)
+int StorageTableShare::haveIndexes(int indexCount)
{
- if (!indexes || indexId >= numberIndexes)
- return NULL;
+ if (!indexes)
+ return false;
- return indexes[indexId];
+ int n = 0;
+ for (StorageIndexDesc *indexDesc = indexes; indexDesc; indexDesc = indexDesc->next, n++)
+ {
+ if (!indexDesc->index)
+ return false;
+ }
+
+ return (n == indexCount);
}
INT64 StorageTableShare::getSequenceValue(int delta)
@@ -363,38 +522,6 @@ int StorageTableShare::setSequenceValue(
sequence->update(value - current, NULL);
return 0;
-}
-
-int StorageTableShare::getIndexId(const char* schemaName, const char* indexName)
-{
- if (indexes)
- for (int n = 0; n < numberIndexes; ++n)
- {
- Index *index = indexes[n]->index;
-
- if (strcmp(index->getIndexName(), indexName) == 0 &&
- strcmp(index->getSchemaName(), schemaName) == 0)
- return n;
- }
-
- return -1;
-}
-
-int StorageTableShare::haveIndexes(int indexCount)
-{
- if (indexes == NULL)
- return false;
-
-#ifdef ONLINE_ALTER
- if (indexCount != numberIndexes)
- return false;
-#endif
-
- for (int n = 0; n < numberIndexes; ++n)
- if (indexes[n]== NULL)
- return false;
-
- return true;
}
void StorageTableShare::setTablePath(const char* path, bool tmp)
=== modified file 'storage/falcon/StorageTableShare.h'
--- a/storage/falcon/StorageTableShare.h 2008-08-04 15:53:52 +0000
+++ b/storage/falcon/StorageTableShare.h 2008-08-22 06:47:40 +0000
@@ -26,6 +26,7 @@
typedef __int64 INT64;
static const int MaxIndexSegments = 16;
+static const int indexNameSize = 257;
class StorageDatabase;
class StorageConnection;
@@ -47,14 +48,25 @@ struct StorageSegment {
void *mysql_charset;
};
-struct StorageIndexDesc {
+// StorageIndexDesc maps a server-side index to a Falcon index
+class StorageIndexDesc
+{
+public:
+ StorageIndexDesc();
+ StorageIndexDesc(const StorageIndexDesc *indexInfo);
+ virtual ~StorageIndexDesc(void);
+
+ int id;
int unique;
int primaryKey;
int numberSegments;
- const char *name;
+ char name[indexNameSize]; // clean name
+ char rawName[indexNameSize]; // original name
Index *index;
uint64 *segmentRecordCounts;
StorageSegment segments[MaxIndexSegments];
+ StorageIndexDesc *next;
+ StorageIndexDesc *prev;
};
@@ -95,22 +107,29 @@ public:
StorageTableShare(StorageHandler *handler, const char * path, const char *tableSpaceName, int lockSize, bool tempTbl);
virtual ~StorageTableShare(void);
- virtual void lock(bool exclusiveLock);
+ virtual void lock(bool exclusiveLock=false);
virtual void unlock(void);
- virtual int createIndex(StorageConnection *storageConnection, const char* name, const char* sql);
- virtual int dropIndex(StorageConnection *storageConnection, const char* name, const char* sql);
+ virtual void lockIndexes(bool exclusiveLock=false);
+ virtual void unlockIndexes(void);
+ virtual int createIndex(StorageConnection *storageConnection, StorageIndexDesc *indexDesc, const char *sql);
+ virtual int dropIndex(StorageConnection *storageConnection, StorageIndexDesc *indexDesc, const char *sql);
+ virtual void deleteIndexes();
virtual int renameTable(StorageConnection *storageConnection, const char* newName);
virtual INT64 getSequenceValue(int delta);
virtual int setSequenceValue(INT64 value);
virtual int haveIndexes(int indexCount);
- virtual void cleanupFieldName(const char* name, char* buffer, int bufferLength);
+ virtual const char* cleanupFieldName(const char* name, char* buffer, int bufferLength);
virtual void setTablePath(const char* path, bool tempTable);
virtual void registerCollation(const char* collationName, void* arg);
int open(void);
- StorageIndexDesc* getIndex(int indexCount, int indexId, StorageIndexDesc* indexDesc);
+ void addIndex(StorageIndexDesc *indexDesc);
+ void deleteIndex(int indexId);
+ int setIndex(const StorageIndexDesc* indexInfo);
+ void clearIndex(StorageIndexDesc *indexDesc);
StorageIndexDesc* getIndex(int indexId);
-
+ StorageIndexDesc* getIndex(int indexId, StorageIndexDesc *indexDesc);
+ StorageIndexDesc* getIndex(const char *name);
int getIndexId(const char* schemaName, const char* indexName);
int create(StorageConnection *storageConnection, const char* sql, int64 autoIncrementValue);
int upgrade(StorageConnection *storageConnection, const char* sql, int64 autoIncrementValue);
@@ -129,6 +148,7 @@ public:
static const char* getDefaultRoot(void);
static const char* cleanupTableName(const char* name, char* buffer, int bufferLength, char *schema, int schemaLength);
+ char* createIndexName(const char *rawName, char *indexName);
JString name;
JString schemaName;
@@ -140,13 +160,13 @@ public:
unsigned char *impure;
int initialized;
SyncObject *syncObject;
+ SyncObject *syncIndexes;
StorageDatabase *storageDatabase;
StorageHandler *storageHandler;
Table *table;
- StorageIndexDesc **indexes;
+ StorageIndexDesc *indexes;
Sequence *sequence;
Format *format; // format for insertion
- int numberIndexes;
bool tempTable;
int getFieldId(const char* fieldName);
};
=== modified file 'storage/falcon/Table.cpp'
--- a/storage/falcon/Table.cpp 2008-08-13 10:18:40 +0000
+++ b/storage/falcon/Table.cpp 2008-08-18 05:45:29 +0000
@@ -209,6 +209,34 @@ Index* Table::addIndex(const char * name
return index;
}
+void Table::dropIndex(const char* indexName, Transaction* transaction)
+{
+ Sync sync(&syncObject, "Table::dropIndex");
+ sync.lock(Exclusive);
+
+ Index *index = findIndex(indexName);
+
+ if (index)
+ deleteIndex(index, transaction);
+}
+
+void Table::renameIndexes(const char *newTableName)
+{
+ for (Index *index = indexes; index; index = index->next)
+ {
+ if (index->type != PrimaryKey)
+ {
+
+ // Assume that index name is <table>$<index>
+
+ char newIndexName[256];
+ const char *p = strchr((const char*)index->name, '$');
+ sprintf(newIndexName, "%s%s", newTableName, (const char *)p);
+ index->rename(newIndexName);
+ }
+ }
+}
+
const char* Table::getName()
{
return name;
@@ -1706,6 +1734,19 @@ void Table::addIndex(Index * index)
*ptr = index;
}
+void Table::dropIndex(Index *index)
+{
+ Sync sync(&syncObject, "Table::dropIndex");
+ sync.lock(Exclusive);
+
+ for (Index **ptr = &indexes; *ptr; ptr = &(*ptr)->next)
+ if (*ptr == index)
+ {
+ *ptr = index->next;
+ break;
+ }
+}
+
void Table::addAttachment(TableAttachment * attachment)
{
attachments.appendUnique(attachment);
@@ -2226,15 +2267,6 @@ void Table::dropTrigger(Trigger *trigger
#endif
}
-void Table::dropIndex(Index *index)
-{
- for (Index **ptr = &indexes; *ptr; ptr = &(*ptr)->next)
- if (*ptr == index)
- {
- *ptr = index->next;
- break;
- }
-}
int Table::nextColumnId(int previous)
{
@@ -3196,6 +3228,8 @@ void Table::rename(const char *newSchema
Index *primaryKey = getPrimaryKey();
database->renameTable(this, newSchema, newName);
+ renameIndexes(newName);
+
if (primaryKey)
primaryKey->rename(getPrimaryKeyName());
}
@@ -3491,7 +3525,7 @@ Record* Table::fetchForUpdate(Transactio
ASSERT(IS_CONSISTENT_READ(transaction->isolationLevel));
record->release();
- Log::debug("Table::fetchForUpdate: Update Conflict: TransId=%d, RecordNumber=%d, Table %s.%s",
+ Log::debug("Table::fetchForUpdate: Update Conflict: TransId=%d, RecordNumber=%d, Table %s.%s\n",
transaction->transactionId, record->recordNumber, schemaName, name);
throw SQLError(UPDATE_CONFLICT, "update conflict in table %s.%s", schemaName, name);
=== modified file 'storage/falcon/Table.h'
--- a/storage/falcon/Table.h 2008-08-11 13:22:53 +0000
+++ b/storage/falcon/Table.h 2008-08-18 05:45:29 +0000
@@ -180,6 +180,8 @@ public:
void create (const char *tableType, Transaction *transaction);
const char* getName();
Index* addIndex (const char *name, int numberFields, int type);
+ void dropIndex(const char* name, Transaction* transaction);
+ void renameIndexes(const char *newTableName);
Field* addField (const char *name, Type type, int length, int precision, int scale, int flags);
Field* findField (const char *name);
int getFormatVersion();
=== modified file 'storage/falcon/TableSpace.cpp'
--- a/storage/falcon/TableSpace.cpp 2008-07-17 13:52:17 +0000
+++ b/storage/falcon/TableSpace.cpp 2008-08-18 20:17:15 +0000
@@ -123,7 +123,9 @@ void TableSpace::open()
void TableSpace::create()
{
+#ifndef FALCONDB
dbb->createPath(filename);
+#endif
dbb->create(filename, dbb->pageSize, 0, HdrTableSpace, 0, NULL);
active = true;
dbb->flush();
=== modified file 'storage/falcon/Transaction.cpp'
--- a/storage/falcon/Transaction.cpp 2008-08-20 15:01:21 +0000
+++ b/storage/falcon/Transaction.cpp 2008-08-25 18:24:59 +0000
@@ -86,6 +86,7 @@ Transaction::Transaction(Connection *cnc
syncObject.setName("Transaction::syncObject");
syncActive.setName("Transaction::syncActive");
syncIndexes.setName("Transaction::syncIndexes");
+ syncRecords.setName("Transaction::syncRecords");
syncSavepoints.setName("Transaction::syncSavepoints");
firstRecord = NULL;
lastRecord = NULL;
@@ -216,20 +217,19 @@ Transaction::~Transaction()
delete backloggedRecords;
chillPoint = &firstRecord;
+ // We modify record list without locking.
+ // It is a destructor and if somebody accesses the list
+ // at this point, he is already lost.
for (RecordVersion *record; (record = firstRecord);)
{
- removeRecord(record);
+ removeRecordNoLock(record);
}
+ firstRecord = NULL;
releaseSavepoints();
if (deferredIndexes)
- {
- Sync sync(&syncIndexes, "Transaction::~Transaction");
- sync.lock(Exclusive);
-
releaseDeferredIndexes();
- }
}
void Transaction::commit()
@@ -279,6 +279,8 @@ void Transaction::commit()
+ Sync syncRec(&syncRecords,"Transaction::commit(1.5)");
+ syncRec.lock(Shared);
for (RecordVersion *record = firstRecord; record; record = record->nextInTrans)
{
Table * table = record->format->table;
@@ -295,7 +297,8 @@ void Transaction::commit()
if (record->state == recDeleted && table->cardinality > 0)
--table->cardinality;
}
-
+ syncRec.unlock();
+
releaseDependencies();
database->flushInversion(this);
@@ -341,11 +344,7 @@ void Transaction::commitNoUpdates(void)
++transactionManager->committed;
if (deferredIndexes)
- {
- Sync sync(&syncIndexes, "Transaction::commitNoUpdates(1)");
- sync.lock(Exclusive);
releaseDeferredIndexes();
- }
if (hasLocks)
releaseRecordLocks();
@@ -387,11 +386,7 @@ void Transaction::rollback()
throw SQLEXCEPTION (RUNTIME_ERROR, "transaction is not active");
if (deferredIndexes)
- {
- Sync sync(&syncIndexes, "Transaction::rollback(1)");
- sync.lock(Exclusive);
releaseDeferredIndexes();
- }
releaseSavepoints();
TransactionManager *transactionManager = database->transactionManager;
@@ -403,6 +398,9 @@ void Transaction::rollback()
// Rollback pending record versions from newest to oldest in case
// there are multiple record versions on a prior record chain
+ Sync syncRec(&syncRecords, "Transaction::rollback(1.5)");
+ syncRec.lock(Exclusive);
+
while (firstRecord)
{
record = firstRecord;
@@ -428,6 +426,8 @@ void Transaction::rollback()
record->transaction = rollbackTransaction;
record->release();
}
+ firstRecord = NULL;
+ syncRec.unlock();
for (SavePoint *savePoint = savePoints; savePoint; savePoint = savePoint->next)
if (savePoint->backloggedRecords)
@@ -621,6 +621,8 @@ void Transaction::addRecord(RecordVersio
record->addRef();
+ Sync syncRec(&syncRecords,"Transaction::addRecord");
+ syncRec.lock(Exclusive);
if ( (record->prevInTrans = lastRecord) )
lastRecord->nextInTrans = record;
else
@@ -628,6 +630,7 @@ void Transaction::addRecord(RecordVersio
record->nextInTrans = NULL;
lastRecord = record;
+ syncRec.unlock();
if (database->lowMemory && deletedRecords > MAX_LOW_MEMORY_RECORDS)
backlogRecords();
@@ -635,6 +638,12 @@ void Transaction::addRecord(RecordVersio
void Transaction::removeRecord(RecordVersion *record)
{
+ Sync syncRec(&syncRecords,"Transaction::removeRecord");
+ syncRec.lock(Exclusive);
+ removeRecordNoLock(record);
+}
+void Transaction::removeRecordNoLock(RecordVersion *record)
+{
RecordVersion **ptr;
if (record->nextInTrans)
@@ -800,6 +809,8 @@ void Transaction::releaseDependencies()
void Transaction::commitRecords()
{
+ Sync syncRec(&syncRecords,"Transaction::commitRecords");
+ syncRec.lock(Exclusive);
for (RecordVersion *recordList; (recordList = firstRecord);)
{
if (recordList && COMPARE_EXCHANGE_POINTER(&firstRecord, recordList, NULL))
@@ -903,13 +914,10 @@ State Transaction::getRelativeState(Tran
void Transaction::dropTable(Table* table)
{
- Sync sync(&syncIndexes, "Transaction::dropTable");
- sync.lock(Exclusive);
-
releaseDeferredIndexes(table);
- // Keep exclusive lock to avoid race condition with writeComplete
-
+ Sync syncRec(&syncRecords,"Transaction::dropTable(2)");
+ syncRec.lock(Exclusive);
for (RecordVersion **ptr = &firstRecord, *rec; (rec = *ptr);)
if (rec->format->table == table)
removeRecord(rec);
@@ -919,13 +927,9 @@ void Transaction::dropTable(Table* table
void Transaction::truncateTable(Table* table)
{
- Sync sync(&syncIndexes, "Transaction::truncateTable");
- sync.lock(Exclusive);
-
releaseDeferredIndexes(table);
-
- // Keep exclusive lock to avoid race condition with writeComplete
-
+ Sync syncRec(&syncRecords,"Transaction::truncateTable(2)");
+ syncRec.lock(Exclusive);
for (RecordVersion **ptr = &firstRecord, *rec; (rec = *ptr);)
if (rec->format->table == table)
removeRecord(rec);
@@ -935,9 +939,8 @@ void Transaction::truncateTable(Table* t
bool Transaction::hasRecords(Table* table)
{
- // This lock is to avoid race with writeComplete
- Sync sync(&syncIndexes, "Transaction::hasRecords");
- sync.lock(Exclusive);
+ Sync syncRec(&syncRecords, "Transaction::hasRecords");
+ syncRec.lock(Shared);
for (RecordVersion *rec = firstRecord; rec; rec = rec->nextInTrans)
if (rec->format->table == table)
return true;
@@ -949,17 +952,12 @@ void Transaction::writeComplete(void)
{
ASSERT(writePending);
ASSERT(state == Committed);
- Sync sync(&syncIndexes, "Transaction::writeComplete");
- sync.lock(Exclusive);
releaseDeferredIndexes();
-
- // Keep the synIndexes lock to avoid a race condition with dropTable
if (dependencies == 0)
commitRecords();
writePending = false;
- sync.unlock();
}
bool Transaction::waitForTransaction(TransId transId)
@@ -1243,6 +1241,7 @@ void Transaction::rollbackSavepoint(int
savePoint = savePoints;
+
while (savePoint)
{
//validateRecords();
@@ -1251,6 +1250,8 @@ void Transaction::rollbackSavepoint(int
break;
// Purge out records from this savepoint
+ Sync syncRec(&syncRecords,"Transaction::rollbackSavepoint(2)");
+ syncRec.lock(Exclusive);
RecordVersion *record = *savePoint->records;
RecordVersion *stack = NULL;
@@ -1290,6 +1291,7 @@ void Transaction::rollbackSavepoint(int
rec->transaction = NULL;
rec->release();
}
+ syncRec.unlock();
// Handle any backlogged records
@@ -1335,6 +1337,8 @@ void Transaction::releaseRecordLocks(voi
RecordVersion **ptr;
RecordVersion *record;
+ Sync syncRec(&syncRecords,"Transaction::releaseRecordLocks");
+ syncRec.lock(Exclusive);
for (ptr = &firstRecord; (record = *ptr);)
if (record->state == recLock)
{
@@ -1343,6 +1347,7 @@ void Transaction::releaseRecordLocks(voi
}
else
ptr = &record->nextInTrans;
+ syncRec.unlock();
}
void Transaction::print(void)
@@ -1360,6 +1365,8 @@ void Transaction::printBlocking(int leve
int deletes = 0;
RecordVersion *record;
+ Sync syncRec(&syncRecords,"Transaction::printBlocking");
+ syncRec.lock(Shared);
for (record = firstRecord; record; record = record->nextInTrans)
if (record->state == recLock)
++locks;
@@ -1407,7 +1414,7 @@ void Transaction::printBlocking(int leve
record->recordNumber,
what);
}
-
+ syncRec.unlock();
database->transactionManager->printBlocking(this, level);
}
@@ -1445,14 +1452,7 @@ void Transaction::releaseDependency(void
INTERLOCKED_DECREMENT(dependencies);
if ((dependencies == 0) && !writePending && firstRecord)
- {
- // The Sync is to avoid a race with writeComplete(). It looks whacko, but does the trick
-
- Sync sync(&syncIndexes, "Transaction::releaseDependency");
- sync.lock(Exclusive);
commitRecords();
- }
-
releaseCommittedTransaction();
}
@@ -1497,6 +1497,8 @@ void Transaction::printBlockage(void)
void Transaction::releaseDeferredIndexes(void)
{
+ Sync sync(&syncIndexes, "Transaction::releaseDeferredIndexes");
+ sync.lock(Exclusive);
for (DeferredIndex *deferredIndex; (deferredIndex = deferredIndexes);)
{
ASSERT(deferredIndex->transaction == this);
@@ -1554,7 +1556,8 @@ void Transaction::backlogRecords(void)
void Transaction::validateRecords(void)
{
RecordVersion *record;
-
+ Sync syncRec(&syncRecords,"Transaction::validateRecords");
+ syncRec.lock(Shared);
for (record = firstRecord; record && record->nextInTrans; record = record->nextInTrans)
;
=== modified file 'storage/falcon/Transaction.h'
--- a/storage/falcon/Transaction.h 2008-08-11 13:22:53 +0000
+++ b/storage/falcon/Transaction.h 2008-08-25 18:24:59 +0000
@@ -87,7 +87,8 @@ public:
State getRelativeState(Record* record, uint32 flags);
State getRelativeState (Transaction *transaction, TransId transId, uint32 flags);
- void removeRecord (RecordVersion *record);
+ void removeRecordNoLock (RecordVersion *record);
+ void removeRecord(RecordVersion *record);
void removeRecord (RecordVersion *record, RecordVersion **ptr);
void expungeTransaction (Transaction *transaction);
void commitRecords();
@@ -171,6 +172,7 @@ public:
SyncObject syncObject;
SyncObject syncActive;
SyncObject syncIndexes;
+ SyncObject syncRecords;
SyncObject syncSavepoints;
uint64 totalRecordData; // total bytes of record data for this transaction (unchilled + thawed)
uint32 totalRecords; // total record count
=== modified file 'storage/falcon/TransactionManager.cpp'
--- a/storage/falcon/TransactionManager.cpp 2008-08-14 12:08:37 +0000
+++ b/storage/falcon/TransactionManager.cpp 2008-08-25 21:51:46 +0000
@@ -74,26 +74,25 @@ TransId TransactionManager::findOldestAc
{
Sync syncCommitted(&committedTransactions.syncObject, "TransactionManager::findOldestActive(1)");
syncCommitted.lock(Shared);
- TransId oldestActive = transactionSequence;
+ TransId oldestCommitted = transactionSequence;
for (Transaction *trans = committedTransactions.first; trans; trans = trans->next)
- oldestActive = MIN(trans->transactionId, oldestActive);
+ oldestCommitted = MIN(trans->transactionId, oldestCommitted);
syncCommitted.unlock();
- Sync sync(&activeTransactions.syncObject, "TransactionManager::findOldestActive(2)");
- sync.lock(Shared);
+
Transaction *oldest = findOldest();
if (oldest)
{
- //Log::debug("Oldest transaction %d, oldest ancestor %d, oldest committed %d\n", oldest->transactionId, oldest->oldestActive, oldestActive);
-
- return MIN(oldest->oldestActive, oldestActive);
+ //Log::debug("Oldest transaction %d, oldest ancestor %d, oldest committed %d\n", oldest->transactionId, oldest->oldestActive, oldestCommitted);
+
+ return MIN(oldest->oldestActive, oldestCommitted);
}
//Log::debug("No active, current %d, oldest committed %d\n", transactionSequence, oldestActive);
- return oldestActive;
+ return oldestCommitted;
}
Transaction* TransactionManager::findOldest(void)
@@ -247,16 +246,20 @@ void TransactionManager::rollbackByXid(i
void TransactionManager::print(void)
{
- Sync sync (&activeTransactions.syncObject, "TransactionManager::print(1)");
- sync.lock (Exclusive);
- Sync committedTrans (&committedTransactions.syncObject, "TransactionManager::print(2)");
- committedTrans.lock (Exclusive);
+ Sync syncActive (&activeTransactions.syncObject, "TransactionManager::print(1)");
+ syncActive.lock (Exclusive);
+
+ Sync syncCommitted (&committedTransactions.syncObject, "TransactionManager::print(2)");
+ syncCommitted.lock (Exclusive);
+
Transaction *transaction;
Log::debug("Active Transaction:\n");
for (transaction = activeTransactions.first; transaction; transaction = transaction->next)
transaction->print();
-
+
+ syncActive.unlock();
+
Log::debug("Committed Transaction:\n");
for (transaction = committedTransactions.first; transaction; transaction = transaction->next)
@@ -266,15 +269,19 @@ void TransactionManager::print(void)
void TransactionManager::getTransactionInfo(InfoTable* infoTable)
{
- Sync sync (&activeTransactions.syncObject, "TransactionManager::getTransactionInfo(1)");
- sync.lock (Exclusive);
- Sync committedTrans (&committedTransactions.syncObject, "TransactionManager::getTransactionInfo(2)");
- committedTrans.lock (Exclusive);
+ Sync syncActive (&activeTransactions.syncObject, "TransactionManager::getTransactionInfo(2)");
+ syncActive.lock (Exclusive);
+
+ Sync syncCommitted (&committedTransactions.syncObject, "TransactionManager::getTransactionInfo(1)");
+ syncCommitted.lock (Exclusive);
+
Transaction *transaction;
for (transaction = activeTransactions.first; transaction; transaction = transaction->next)
transaction->getInfo(infoTable);
-
+
+ syncActive.unlock();
+
for (transaction = committedTransactions.first; transaction; transaction = transaction->next)
transaction->getInfo(infoTable);
}
@@ -307,10 +314,12 @@ void TransactionManager::purgeTransactio
void TransactionManager::getSummaryInfo(InfoTable* infoTable)
{
- Sync sync (&activeTransactions.syncObject, "TransactionManager::getSummaryInfo(1)");
- sync.lock (Exclusive);
- Sync committedTrans (&committedTransactions.syncObject, "TransactionManager::getSummaryInfo(2)");
- committedTrans.lock (Exclusive);
+ Sync syncActive (&activeTransactions.syncObject, "TransactionManager::getSummaryInfo(2)");
+ syncActive.lock (Exclusive);
+
+ Sync syncCommitted (&committedTransactions.syncObject, "TransactionManager::getSummaryInfo(1)");
+ syncCommitted.lock (Exclusive);
+
int numberCommitted = committed;
int numberRolledBack = rolledBack;
int numberActive = 0;
@@ -327,14 +336,14 @@ void TransactionManager::getSummaryInfo(
if (transaction->state == Committed)
++numberPendingCommit;
}
+ syncActive.unlock();
for (transaction = committedTransactions.first; transaction; transaction = transaction->next)
if (transaction->writePending)
++numberPendingCompletion;
- committedTrans.unlock();
- sync.unlock();
-
+ syncCommitted.unlock();
+
int n = 0;
infoTable->putInt(n++, numberCommitted);
infoTable->putInt(n++, numberRolledBack);
@@ -402,15 +411,16 @@ void TransactionManager::expungeTransact
Transaction* TransactionManager::findTransaction(TransId transactionId)
{
- Sync syncActiveTrans(&activeTransactions.syncObject, "TransactionManager::findTransaction(1)");
- syncActiveTrans.lock(Shared);
+ Sync syncActive(&activeTransactions.syncObject, "TransactionManager::findTransaction(1)");
+ syncActive.lock(Shared);
Transaction *transaction;
for (transaction = activeTransactions.first; transaction; transaction = transaction->next)
if (transaction->transactionId == transactionId)
return transaction;
- syncActiveTrans.unlock();
+ syncActive.unlock();
+
Sync syncCommitted(&committedTransactions.syncObject, "TransactionManager::findTransaction(2)");
syncCommitted.lock(Shared);
@@ -418,20 +428,21 @@ Transaction* TransactionManager::findTra
if (transaction->transactionId == transactionId)
return transaction;
- return NULL;
+ return NULL;
}
void TransactionManager::validateDependencies(void)
{
- Sync sync(&committedTransactions.syncObject, "TransactionManager::validateDepedendencies(1)");
- sync.lock(Shared);
+ Sync syncActive(&activeTransactions.syncObject, "TransactionManager::validateDepedendencies(1)");
+ syncActive.lock(Shared);
Transaction *transaction;
for (transaction = activeTransactions.first; transaction; transaction = transaction->next)
if (transaction->isActive())
transaction->validateDependencies(false);
- sync.unlock();
+ syncActive.unlock();
+
Sync syncCommitted(&committedTransactions.syncObject, "TransactionManager::validateDepedendencies(2)");
syncCommitted.lock(Shared);
=== modified file 'storage/falcon/ha_falcon.cpp'
--- a/storage/falcon/ha_falcon.cpp 2008-08-14 11:24:18 +0000
+++ b/storage/falcon/ha_falcon.cpp 2008-08-22 12:55:22 +0000
@@ -54,7 +54,7 @@
#endif
#ifndef ONLINE_ALTER
-//#define ONLINE_ALTER
+#define ONLINE_ALTER
#endif
#ifdef DEBUG_BACKLOG
@@ -216,13 +216,13 @@ int StorageInterface::falcon_init(void *
}
catch(SQLException &e)
{
- sql_print_error("Falcon : exception '%s'during initialization",
+ sql_print_error("Falcon: Exception '%s' during initialization",
e.getText());
error = true;
}
catch(...)
{
- sql_print_error(" Falcon : general exception in initialization");
+ sql_print_error(" Falcon: General exception in initialization");
error = true;
}
@@ -398,6 +398,7 @@ StorageInterface::StorageInterface(handl
ref_length = sizeof(lastRecord);
stats.records = 1000;
stats.data_file_length = 10000;
+ stats.index_file_length = 0;
tableLocked = false;
lockForUpdate = false;
storageTable = NULL;
@@ -424,6 +425,9 @@ StorageInterface::StorageInterface(handl
StorageInterface::~StorageInterface(void)
{
+ if (storageTable)
+ storageTable->clearCurrentIndex();
+
if (activeBlobs)
freeActiveBlobs();
@@ -482,6 +486,7 @@ int StorageInterface::open(const char *n
if (!storageShare->initialized)
{
+// storageShare->lockIndexes(true);
storageShare->lock(true);
if (!storageShare->initialized)
@@ -505,6 +510,7 @@ int StorageInterface::open(const char *n
}
storageShare->unlock();
+// storageShare->unlockIndexes();
}
}
@@ -535,6 +541,10 @@ StorageConnection* StorageInterface::get
int StorageInterface::close(void)
{
DBUG_ENTER("StorageInterface::close");
+
+ if (storageTable)
+ storageTable->clearCurrentIndex();
+
unmapFields();
// Temporarily comment out DTrace probes in Falcon, see bug #36403
@@ -672,23 +682,27 @@ void StorageInterface::getDemographics(v
stats.block_size = 4096;
+ storageShare->lockIndexes();
+
for (uint n = 0; n < table->s->keys; ++n)
{
KEY *key = table->s->key_info + n;
- StorageIndexDesc *desc = storageShare->getIndex(n);
+ StorageIndexDesc *indexDesc = storageShare->getIndex(n);
- if (desc)
+ if (indexDesc)
{
- ha_rows rows = 1 << desc->numberSegments;
+ ha_rows rows = 1 << indexDesc->numberSegments;
for (uint segment = 0; segment < key->key_parts; ++segment, rows >>= 1)
{
- ha_rows recordsPerSegment = (ha_rows) desc->segmentRecordCounts[segment];
+ ha_rows recordsPerSegment = (ha_rows)indexDesc->segmentRecordCounts[segment];
key->rec_per_key[segment] = (ulong) MAX(recordsPerSegment, rows);
}
}
}
+ storageShare->unlockIndexes();
+
DBUG_VOID_RETURN;
}
@@ -832,7 +846,7 @@ int StorageInterface::create(const char
for (n = 0; n < form->s->keys; ++n)
if (n != form->s->primary_key)
- if ((ret = createIndex(schemaName, tableName, form->key_info + n, n)))
+ if ((ret = createIndex(schemaName, tableName, form, n)))
{
storageTable->deleteTable();
@@ -847,32 +861,42 @@ int StorageInterface::create(const char
int StorageInterface::add_index(TABLE* table_arg, KEY* key_info, uint num_of_keys)
{
DBUG_ENTER("StorageInterface::add_index");
- int ret = createIndex(storageTable->getSchemaName(), storageTable->getName(), key_info, table_arg->s->keys);
+ int ret = createIndex(storageTable->getSchemaName(), storageTable->getName(), table_arg, table_arg->s->keys);
DBUG_RETURN(ret);
}
-int StorageInterface::createIndex(const char *schemaName, const char *tableName,
- KEY *key, int indexNumber)
+int StorageInterface::createIndex(const char *schemaName, const char *tableName, TABLE *table, int indexId)
{
+ KEY *key = table->key_info + indexId;
+ StorageIndexDesc indexDesc;
+ getKeyDesc(table, indexId, &indexDesc);
+
+ char indexName[indexNameSize];
+ storageShare->createIndexName(indexDesc.name, indexName);
+
CmdGen gen;
const char *unique = (key->flags & HA_NOSAME) ? "unique " : "";
- gen.gen("create %sindex \"%s$%d\" on %s.\"%s\" ", unique, tableName,
- indexNumber, schemaName, tableName);
+ gen.gen("create %sindex \"%s\" on %s.\"%s\" ", unique, indexName, schemaName, tableName);
genKeyFields(key, &gen);
const char *sql = gen.getString();
- return storageTable->share->createIndex(storageConnection, key->name, sql);
+ return storageTable->createIndex(&indexDesc, sql);
}
-int StorageInterface::dropIndex(const char *schemaName, const char *tableName,
- KEY *key, int indexNumber)
+int StorageInterface::dropIndex(const char *schemaName, const char *tableName, TABLE *table, int indexId)
{
+ StorageIndexDesc indexDesc;
+ getKeyDesc(table, indexId, &indexDesc);
+
+ char indexName[indexNameSize];
+ storageShare->createIndexName(indexDesc.name, indexName);
+
CmdGen gen;
- gen.gen("drop index %s.\"%s$%d\"", schemaName, tableName, indexNumber);
+ gen.gen("drop index %s.\"%s\"", schemaName, indexName);
const char *sql = gen.getString();
- return storageTable->share->dropIndex(storageConnection, key->name, sql);
+ return storageTable->dropIndex(&indexDesc, sql);
}
#if 0
@@ -916,6 +940,8 @@ THR_LOCK_DATA **StorageInterface::store_
&& !(thd_tablespace_op(thd))
&& (sql_command != SQLCOM_ALTER_TABLE)
&& (sql_command != SQLCOM_DROP_TABLE)
+ && (sql_command != SQLCOM_CREATE_INDEX)
+ && (sql_command != SQLCOM_DROP_INDEX)
&& (sql_command != SQLCOM_TRUNCATE)
&& (sql_command != SQLCOM_OPTIMIZE)
&& (sql_command != SQLCOM_CREATE_TABLE)
@@ -963,6 +989,10 @@ int StorageInterface::delete_table(const
if (storageShare)
{
+
+ // Lock out other clients before locking the table
+
+ storageShare->lockIndexes(true);
storageShare->lock(true);
if (storageShare->initialized)
@@ -973,6 +1003,7 @@ int StorageInterface::delete_table(const
}
storageShare->unlock();
+ storageShare->unlockIndexes();
}
int res = storageTable->deleteTable();
@@ -1358,7 +1389,6 @@ int StorageInterface::index_read(uchar *
}
}
-
int StorageInterface::index_init(uint idx, bool sorted)
{
DBUG_ENTER("StorageInterface::index_init");
@@ -1367,33 +1397,30 @@ int StorageInterface::index_init(uint id
haveStartKey = false;
haveEndKey = false;
- if (!storageTable->setIndex(idx))
- DBUG_RETURN(0);
-
- StorageIndexDesc indexDesc;
- getKeyDesc(table->key_info + idx, &indexDesc);
-
- if (idx == table->s->primary_key)
- indexDesc.primaryKey = true;
-
- int ret = storageTable->setIndex(table->s->keys, idx, &indexDesc);
+ int ret = storageTable->setCurrentIndex(idx);
if (ret)
+ {
+ setIndex(table, idx);
+ ret = storageTable->setCurrentIndex(idx);
+ }
+
+ if (ret)
DBUG_RETURN(error(ret));
- DBUG_RETURN(0);
+ DBUG_RETURN(ret);
}
-
int StorageInterface::index_end(void)
{
DBUG_ENTER("StorageInterface::index_end");
+
storageTable->indexEnd();
+
DBUG_RETURN(0);
}
-ha_rows StorageInterface::records_in_range(uint indexId, key_range *lower,
- key_range *upper)
+ha_rows StorageInterface::records_in_range(uint indexId, key_range *lower, key_range *upper)
{
DBUG_ENTER("StorageInterface::records_in_range");
@@ -1406,9 +1433,9 @@ ha_rows StorageInterface::records_in_ran
if (!lower)
DBUG_RETURN(MAX(cardinality, 2));
- StorageIndexDesc *index = storageShare->getIndex(indexId);
+ StorageIndexDesc indexDesc;
- if (!index)
+ if (!storageShare->getIndex(indexId, &indexDesc))
DBUG_RETURN(MAX(cardinality, 2));
int numberSegments = 0;
@@ -1416,10 +1443,10 @@ ha_rows StorageInterface::records_in_ran
for (int map = lower->keypart_map; map; map >>= 1)
++numberSegments;
- if (index->unique && numberSegments == index->numberSegments)
+ if (indexDesc.unique && numberSegments == indexDesc.numberSegments)
DBUG_RETURN(1);
- ha_rows segmentRecords = (ha_rows) index->segmentRecordCounts[numberSegments - 1];
+ ha_rows segmentRecords = (ha_rows)indexDesc.segmentRecordCounts[numberSegments - 1];
ha_rows guestimate = cardinality;
if (lower->flag == HA_READ_KEY_EXACT)
@@ -1436,22 +1463,34 @@ ha_rows StorageInterface::records_in_ran
DBUG_RETURN(MAX(guestimate, 2));
}
-
-void StorageInterface::getKeyDesc(KEY *keyInfo, StorageIndexDesc *indexInfo)
+void StorageInterface::getKeyDesc(TABLE *table, int indexId, StorageIndexDesc *indexDesc)
{
+ KEY *keyInfo = table->key_info + indexId;
int numberKeys = keyInfo->key_parts;
- indexInfo->numberSegments = numberKeys;
- indexInfo->name = keyInfo->name;
- indexInfo->unique = (keyInfo->flags & HA_NOSAME);
- indexInfo->primaryKey = false;
+ char nameBuffer[indexNameSize];
+
+ // Clean up the index name for internal use
+
+ strncpy(indexDesc->rawName, (const char*)keyInfo->name, MIN(indexNameSize, (int)strlen(keyInfo->name)+1));
+ storageShare->cleanupFieldName(indexDesc->rawName, nameBuffer, sizeof(nameBuffer));
+ indexDesc->rawName[indexNameSize-1] = '\0';
+
+ strncpy(indexDesc->name, (const char*)nameBuffer, MIN(indexNameSize, (int)strlen(nameBuffer)+1));
+ indexDesc->name[indexNameSize-1] = '\0';
+
+ indexDesc->id = indexId;
+ indexDesc->numberSegments = numberKeys;
+ indexDesc->unique = (keyInfo->flags & HA_NOSAME);
+ indexDesc->primaryKey = (table->s->primary_key == (uint)indexId);
for (int n = 0; n < numberKeys; ++n)
{
- StorageSegment *segment = indexInfo->segments + n;
+ StorageSegment *segment = indexDesc->segments + n;
KEY_PART_INFO *part = keyInfo->key_part + n;
- segment->offset = part->offset;
- segment->length = part->length;
- segment->type = part->field->key_type();
+
+ segment->offset = part->offset;
+ segment->length = part->length;
+ segment->type = part->field->key_type();
segment->nullBit = part->null_bit;
segment->isUnsigned = (part->field->flags & ENUM_FLAG) ?
true : ((Field_num*) part->field)->unsigned_flag;
@@ -1472,7 +1511,6 @@ void StorageInterface::getKeyDesc(KEY *k
}
}
-
int StorageInterface::rename_table(const char *from, const char *to)
{
DBUG_ENTER("StorageInterface::rename_table");
@@ -1489,17 +1527,14 @@ int StorageInterface::rename_table(const
DBUG_RETURN(error(ret));
DBUG_RETURN(ret);
-
}
-
double StorageInterface::read_time(uint index, uint ranges, ha_rows rows)
{
DBUG_ENTER("StorageInterface::read_time");
DBUG_RETURN(rows2double(rows / 3));
}
-
int StorageInterface::read_range_first(const key_range *start_key,
const key_range *end_key,
bool eq_range_arg, bool sorted)
@@ -1634,7 +1669,6 @@ int StorageInterface::index_next(uchar *
}
}
-
int StorageInterface::index_next_same(uchar *buf, const uchar *key, uint key_len)
{
DBUG_ENTER("StorageInterface::index_next_same");
@@ -1654,7 +1688,6 @@ int StorageInterface::index_next_same(uc
}
}
-
double StorageInterface::scan_time(void)
{
DBUG_ENTER("StorageInterface::scan_time");
@@ -1691,13 +1724,11 @@ bool StorageInterface::threadSwitch(THD*
return true;
}
-
int StorageInterface::threadSwitchError(void)
{
return 1;
}
-
int StorageInterface::error(int storageError)
{
DBUG_ENTER("StorageInterface::error");
@@ -1737,7 +1768,6 @@ int StorageInterface::error(int storageE
DBUG_RETURN(mySqlError);
}
-
int StorageInterface::getMySqlError(int storageError)
{
switch (storageError)
@@ -1856,8 +1886,6 @@ int StorageInterface::reset()
DBUG_RETURN(0);
}
-
-
int StorageInterface::external_lock(THD *thd, int lock_type)
{
DBUG_ENTER("StorageInterface::external_lock");
@@ -1873,7 +1901,10 @@ int StorageInterface::external_lock(THD
storageConnection->releaseVerb();
if (storageTable)
+ {
storageTable->clearStatement();
+ storageTable->clearCurrentIndex();
+ }
}
else
{
@@ -1894,6 +1925,9 @@ int StorageInterface::external_lock(THD
if (ret)
{
+ if (storageTable)
+ storageTable->clearCurrentIndex();
+
DBUG_RETURN(error(ret));
}
}
@@ -1910,9 +1944,7 @@ int StorageInterface::external_lock(THD
checkBinLog();
if (storageConnection->startTransaction(isolation))
- {
trans_register_ha(thd, true, falcon_hton);
- }
if (storageConnection->markVerb())
trans_register_ha(thd, false, falcon_hton);
@@ -1922,9 +1954,7 @@ int StorageInterface::external_lock(THD
checkBinLog();
if (storageConnection->startImplicitTransaction(isolation))
- {
trans_register_ha(thd, false, falcon_hton);
- }
}
switch (thd_tx_isolation(mySqlThread))
@@ -1937,13 +1967,11 @@ int StorageInterface::external_lock(THD
error(StorageWarningSerializable);
break;
}
-
}
DBUG_RETURN(0);
}
-
void StorageInterface::get_auto_increment(ulonglong offset, ulonglong increment,
ulonglong nb_desired_values,
ulonglong *first_value,
@@ -1956,7 +1984,6 @@ void StorageInterface::get_auto_incremen
DBUG_VOID_RETURN;
}
-
const char *StorageInterface::index_type(uint key_number)
{
DBUG_ENTER("StorageInterface::index_type");
@@ -1971,7 +1998,6 @@ void StorageInterface::dropDatabase(hand
DBUG_VOID_RETURN;
}
-
void StorageInterface::freeActiveBlobs(void)
{
for (StorageBlob *blob; (blob = activeBlobs); )
@@ -1983,14 +2009,12 @@ void StorageInterface::freeActiveBlobs(v
}
}
-
void StorageInterface::shutdown(handlerton *htons)
{
if(storageHandler)
storageHandler->shutdownHandler();
}
-
int StorageInterface::panic(handlerton* hton, ha_panic_function flag)
{
if(storageHandler)
@@ -1999,7 +2023,6 @@ int StorageInterface::panic(handlerton*
return 0;
}
-
int StorageInterface::closeConnection(handlerton *hton, THD *thd)
{
DBUG_ENTER("NfsStorageEngine::closeConnection");
@@ -2009,7 +2032,6 @@ int StorageInterface::closeConnection(ha
DBUG_RETURN(0);
}
-
int StorageInterface::alter_tablespace(handlerton* hton, THD* thd, st_alter_tablespace* ts_info)
{
DBUG_ENTER("NfsStorageEngine::alter_tablespace");
@@ -2224,10 +2246,15 @@ int StorageInterface::addColumn(THD* thd
int StorageInterface::addIndex(THD* thd, TABLE* alteredTable, HA_CREATE_INFO* createInfo, HA_ALTER_INFO* alterInfo, HA_ALTER_FLAGS* alterFlags)
{
- int ret;
+ int ret = 0;
const char *tableName = storageTable->getName();
const char *schemaName = storageTable->getSchemaName();
+ // Lock out other clients before locking the table
+
+ storageShare->lockIndexes(true);
+ storageShare->lock(true);
+
// Find indexes to be added by comparing table and alteredTable
for (unsigned int n = 0; n < alteredTable->s->keys; n++)
@@ -2243,19 +2270,33 @@ int StorageInterface::addIndex(THD* thd,
break;
if (tableKey >= tableEnd)
- if ((ret = createIndex(schemaName, tableName, key, n)))
- return (error(ret));
+ if ((ret = createIndex(schemaName, tableName, alteredTable, n)))
+ break;
}
}
- return 0;
+
+ // The server indexes may have been reordered, so remap to the Falcon indexes
+
+ if (!ret)
+ remapIndexes(alteredTable);
+
+ storageShare->unlock();
+ storageShare->unlockIndexes();
+
+ return error(ret);
}
int StorageInterface::dropIndex(THD* thd, TABLE* alteredTable, HA_CREATE_INFO* createInfo, HA_ALTER_INFO* alterInfo, HA_ALTER_FLAGS* alterFlags)
{
- int ret;
+ int ret = 0;
const char *tableName = storageTable->getName();
const char *schemaName = storageTable->getSchemaName();
+ // Lock out other clients before locking the table
+
+ storageShare->lockIndexes(true);
+ storageShare->lock(true);
+
// Find indexes to be dropped by comparing table and alteredTable
for (unsigned int n = 0; n < table->s->keys; n++)
@@ -2271,12 +2312,20 @@ int StorageInterface::dropIndex(THD* thd
break;
if (alterKey >= alterEnd)
- if ((ret = dropIndex(schemaName, tableName, key, n)))
- return (error(ret));
+ if ((ret = dropIndex(schemaName, tableName, table, n)))
+ break;
}
}
- return 0;
+ // The server indexes have been reordered, so remap to the Falcon indexes
+
+ if (!ret)
+ remapIndexes(alteredTable);
+
+ storageShare->unlock();
+ storageShare->unlockIndexes();
+
+ return error(ret);
}
uint StorageInterface::max_supported_key_length(void) const
@@ -2288,7 +2337,6 @@ uint StorageInterface::max_supported_key
return MAX_INDEX_KEY_LENGTH_4K; // Default value.
}
-
uint StorageInterface::max_supported_key_part_length(void) const
{
// Assume 4K page unless proven otherwise.
@@ -2298,7 +2346,6 @@ uint StorageInterface::max_supported_key
return MAX_INDEX_KEY_LENGTH_4K; // Default for future sizes.
}
-
void StorageInterface::logger(int mask, const char* text, void* arg)
{
if (mask & falcon_debug_mask)
@@ -2314,32 +2361,47 @@ void StorageInterface::logger(int mask,
}
}
+int StorageInterface::setIndex(TABLE *table, int indexId)
+{
+ StorageIndexDesc indexDesc;
+ getKeyDesc(table, indexId, &indexDesc);
+
+ return storageTable->setIndex(&indexDesc);
+}
+
int StorageInterface::setIndexes(void)
{
+ int ret = 0;
+
if (!table || storageShare->haveIndexes(table->s->keys))
- return 0;
+ return ret;
- storageShare->lock(true);
+ storageShare->lockIndexes(true);
if (!storageShare->haveIndexes(table->s->keys))
- {
- StorageIndexDesc indexDesc;
-
for (uint n = 0; n < table->s->keys; ++n)
- {
- getKeyDesc(table->key_info + n, &indexDesc);
+ if ((ret = setIndex(table, n)))
+ break;
- if (n == table->s->primary_key)
- indexDesc.primaryKey = true;
+ storageShare->unlockIndexes();
- int ret = storageTable->setIndex(table->s->keys, n, &indexDesc);
- if (ret)
- return ret;
- }
- }
+ return ret;
+}
- storageShare->unlock();
- return 0;
+int StorageInterface::remapIndexes(TABLE *table)
+{
+ int ret = 0;
+
+ if (!table)
+ return ret;
+
+ storageShare->deleteIndexes();
+
+ for (uint n = 0; n < table->s->keys; ++n)
+ if ((ret = setIndex(table, n)))
+ break;
+
+ return ret;
}
int StorageInterface::genTable(TABLE* table, CmdGen* gen)
@@ -2348,7 +2410,7 @@ int StorageInterface::genTable(TABLE* ta
const char *schemaName = storageTable->getSchemaName();
gen->gen("upgrade table \"%s\".\"%s\" (\n", schemaName, tableName);
const char *sep = "";
- char nameBuffer[129];
+ char nameBuffer[256];
for (uint n = 0; n < table->s->fields; ++n)
{
@@ -2495,18 +2557,16 @@ int StorageInterface::genType(Field* fie
return 0;
}
-
void StorageInterface::genKeyFields(KEY* key, CmdGen* gen)
{
const char *sep = "(";
- char nameBuffer[129];
+ char nameBuffer[256];
for (uint n = 0; n < key->key_parts; ++n)
{
KEY_PART_INFO *part = key->key_part + n;
Field *field = part->field;
- storageShare->cleanupFieldName(field->field_name, nameBuffer,
- sizeof(nameBuffer));
+ storageShare->cleanupFieldName(field->field_name, nameBuffer, sizeof(nameBuffer));
if (part->key_part_flag & HA_PART_KEY_SEG)
gen->gen("%s\"%s\"(%d)", sep, nameBuffer, part->length);
@@ -2519,7 +2579,6 @@ void StorageInterface::genKeyFields(KEY*
gen->gen(")");
}
-
void StorageInterface::encodeRecord(uchar *buf, bool updateFlag)
{
storageTable->preInsert();
@@ -3504,7 +3563,7 @@ void StorageInterface::mapFields(TABLE *
unmapFields();
fieldMap = new Field*[maxFields];
memset(fieldMap, 0, sizeof(fieldMap[0]) * maxFields);
- char nameBuffer[129];
+ char nameBuffer[256];
for (uint n = 0; n < table->s->fields; ++n)
{
=== modified file 'storage/falcon/ha_falcon.h'
--- a/storage/falcon/ha_falcon.h 2008-07-29 10:45:39 +0000
+++ b/storage/falcon/ha_falcon.h 2008-08-22 06:47:40 +0000
@@ -29,7 +29,7 @@ static const int TRANSACTION_CONSISTENT_
static const int TRANSACTION_SERIALIZABLE = 16; // Dirty reads, non-repeatable reads and phantom reads are prevented.
struct st_table_share;
-struct StorageIndexDesc;
+class StorageIndexDesc;
struct StorageBlob;
class StorageInterface : public handler
@@ -113,15 +113,18 @@ public:
int dropIndex(THD* thd, TABLE* alteredTable, HA_CREATE_INFO* createInfo, HA_ALTER_INFO* alterInfo, HA_ALTER_FLAGS* alterFlags);
void getDemographics(void);
- int createIndex(const char *schemaName, const char *tableName, KEY *key, int indexNumber);
- int dropIndex(const char *schemaName, const char *tableName, KEY *key, int indexNumber);
- void getKeyDesc(KEY *keyInfo, StorageIndexDesc *indexInfo);
+// int createIndex(const char *schemaName, const char *tableName, KEY *key, int indexId);
+ int createIndex(const char *schemaName, const char *tableName, TABLE *table, int indexId);
+ int dropIndex(const char *schemaName, const char *tableName, TABLE *table, int indexId);
+ void getKeyDesc(TABLE *table, int indexId, StorageIndexDesc *indexInfo);
void startTransaction(void);
bool threadSwitch(THD *newThread);
int threadSwitchError(void);
int error(int storageError);
void freeActiveBlobs(void);
+ int setIndex(TABLE *table, int indexId);
int setIndexes(void);
+ int remapIndexes(TABLE *table);
int genTable(TABLE* table, CmdGen* gen);
int genType(Field *field, CmdGen *gen);
void genKeyFields(KEY *key, CmdGen *gen);
=== modified file 'storage/falcon/plug.in'
--- a/storage/falcon/plug.in 2008-08-12 21:50:50 +0000
+++ b/storage/falcon/plug.in 2008-08-20 13:27:29 +0000
@@ -19,6 +19,18 @@ volatile int target= 0;
int compare= 1;
int exchange= 2;
],[
+#if defined(__SUNPRO_C) || defined(__SUNPRO_CC)
+ /* When compiling with Sun Studio compiler we need the Solaris atomic
+ functions. These were first introduced in Solaris 10. */
+#if defined(HAVE_SOLARIS_ATOMIC)
+ return 0;
+#else
+ /* Fail if the atomic functions are not available. Support for this
+ will be added when the fix for bug 37622 is completed. */
+#error Need Solaris atomic functions to use Sun Studio compiler
+#endif /* HAVE_SOLARIS_ATOMIC */
+#else
+ /* Use gcc style inline assembly when compiling with gcc */
char ret;
__asm__ __volatile__ (
"membar #LoadLoad | #LoadStore | #StoreLoad | #StoreStore\n\t"
@@ -32,6 +44,7 @@ int exchange= 2;
: "r" (&target), "0" (compare)
: "memory", "cc"
)
+#endif /* !__SUNPRO_C && !__SUNPRO_CC */
], falcon_supported_by_machine="yes",
falcon_supported_by_machine="no")
;;
| Thread |
|---|
| • bzr commit into mysql-6.0 branch (vvaintroub:2781) | Vladislav Vaintroub | 27 Aug |