Commit b9e37ece authored by Rich Prohaska's avatar Rich Prohaska Committed by Yoni Fogel

link in the library constructors. closes #1685

git-svn-id: file:///svn/mysql/tokudb-engine/src@11284 c7de825b-a66e-492c-adef-691d508d4ae1
parent 255c8e22
...@@ -40,7 +40,7 @@ CXXFLAGS += -g $(OPTFLAGS) $(GCOV_FLAGS) $(MYSQL_CXXFLAGS) ...@@ -40,7 +40,7 @@ CXXFLAGS += -g $(OPTFLAGS) $(GCOV_FLAGS) $(MYSQL_CXXFLAGS)
CXXFLAGS += -fPIC CXXFLAGS += -fPIC
LDFLAGS = -fPIC -shared -Wl,-soname -Wl,libtokudb_engine.so LDFLAGS = -fPIC -shared -Wl,-soname -Wl,libtokudb_engine.so
ifeq ($(SINGLESO),1) ifeq ($(SINGLESO),1)
LIBS = $(TOKUDB)/lib/libtokudb.a $(TOKUDB)/lib/libtokuportability.a LIBS = $(TOKUDB)/src/ydb_lib.o $(TOKUDB)/lib/libtokudb.a $(TOKUDB)/lib/libtokuportability.a
else else
LIBS = -L$(TOKUDB)/lib -ltokudb -ltokuportability LIBS = -L$(TOKUDB)/lib -ltokudb -ltokuportability
endif endif
......
...@@ -44,6 +44,17 @@ static inline void thd_data_set(THD *thd, int slot, void *data) { ...@@ -44,6 +44,17 @@ static inline void thd_data_set(THD *thd, int slot, void *data) {
#include "hatoku_hton.h" #include "hatoku_hton.h"
#include <mysql/plugin.h> #include <mysql/plugin.h>
#define declare_lockretry \
int lockretrycount;
#define lockretryN(N) \
for (lockretrycount=0; lockretrycount<(N); lockretrycount++)
#define lockretry lockretryN(100)
#define lockretry_wait \
TOKUDB_TRACE("%s count=%d\n", __FUNCTION__, lockretrycount); \
usleep((lockretrycount<4 ? (1<<lockretrycount) : (1<<3)) * 1024)
/** @brief /** @brief
Simple lock controls. The "share" it creates is a structure we will Simple lock controls. The "share" it creates is a structure we will
...@@ -1698,7 +1709,7 @@ bool ha_tokudb::check_if_incompatible_data(HA_CREATE_INFO * info, uint table_cha ...@@ -1698,7 +1709,7 @@ bool ha_tokudb::check_if_incompatible_data(HA_CREATE_INFO * info, uint table_cha
return COMPATIBLE_DATA_NO; return COMPATIBLE_DATA_NO;
return COMPATIBLE_DATA_YES; return COMPATIBLE_DATA_YES;
} }
// //
// Stores a row in the table, called when handling an INSERT query // Stores a row in the table, called when handling an INSERT query
// Parameters: // Parameters:
...@@ -1716,6 +1727,8 @@ int ha_tokudb::write_row(uchar * record) { ...@@ -1716,6 +1727,8 @@ int ha_tokudb::write_row(uchar * record) {
bool has_null; bool has_null;
DB_TXN* sub_trans = NULL; DB_TXN* sub_trans = NULL;
DB_TXN* txn = NULL; DB_TXN* txn = NULL;
tokudb_trx_data *trx = NULL;
declare_lockretry;
// //
// some crap that needs to be done because MySQL does not properly abstract // some crap that needs to be done because MySQL does not properly abstract
...@@ -1775,13 +1788,29 @@ int ha_tokudb::write_row(uchar * record) { ...@@ -1775,13 +1788,29 @@ int ha_tokudb::write_row(uchar * record) {
if (thd_test_options(thd, OPTION_RELAXED_UNIQUE_CHECKS)) { if (thd_test_options(thd, OPTION_RELAXED_UNIQUE_CHECKS)) {
put_flags = DB_YESOVERWRITE; put_flags = DB_YESOVERWRITE;
} }
error = share->file->put(
share->file, trx = (tokudb_trx_data *) thd_data_get(thd, tokudb_hton->slot);
txn, if (trx->table_lock_wanted) {
create_dbt_key_from_table(&prim_key, primary_key, key_buff, record, &has_null), error = acquire_table_lock(trx->all ? trx->all : trx->stmt,
&row, (TABLE_LOCK_TYPE)trx->table_lock_type);
put_flags if (error)
); TOKUDB_TRACE(" acquire_table_lock trx=%p type=%d error=%d\n", trx, trx->table_lock_type, error);
trx->table_lock_wanted = false;
}
lockretry {
error = share->file->put(
share->file,
txn,
create_dbt_key_from_table(&prim_key, primary_key, key_buff, record, &has_null),
&row,
put_flags
);
if (error != DB_LOCK_NOTGRANTED)
break;
lockretry_wait;
}
if (error) { if (error) {
last_dup_key = primary_key; last_dup_key = primary_key;
goto cleanup; goto cleanup;
...@@ -1808,22 +1837,32 @@ int ha_tokudb::write_row(uchar * record) { ...@@ -1808,22 +1837,32 @@ int ha_tokudb::write_row(uchar * record) {
} }
cluster_row_created = true; cluster_row_created = true;
} }
error = share->key_file[keynr]->put( lockretry {
share->key_file[keynr], error = share->key_file[keynr]->put(
txn, share->key_file[keynr],
&key, txn,
&row, &key,
put_flags &row,
); put_flags
);
if (error != DB_LOCK_NOTGRANTED)
break;
lockretry_wait;
}
} }
else { else {
error = share->key_file[keynr]->put( lockretry {
share->key_file[keynr], error = share->key_file[keynr]->put(
txn, share->key_file[keynr],
&key, txn,
&prim_key, &key,
put_flags &prim_key,
); put_flags
);
if (error != DB_LOCK_NOTGRANTED)
break;
lockretry_wait;
}
} }
// //
// We break if we hit an error, unless it is a dup key error // We break if we hit an error, unless it is a dup key error
...@@ -3260,15 +3299,23 @@ int ha_tokudb::acquire_table_lock (DB_TXN* trans, TABLE_LOCK_TYPE lt) { ...@@ -3260,15 +3299,23 @@ int ha_tokudb::acquire_table_lock (DB_TXN* trans, TABLE_LOCK_TYPE lt) {
db->dbt_neg_infty(), db->dbt_neg_infty(), db->dbt_neg_infty(), db->dbt_neg_infty(),
db->dbt_pos_infty(), db->dbt_pos_infty() db->dbt_pos_infty(), db->dbt_pos_infty()
); );
if (error) { goto cleanup; } if (error) break;
} }
if (error) goto cleanup;
} }
else if (lt == lock_write) { else if (lt == lock_write) {
if (tokudb_debug & TOKUDB_DEBUG_LOCK)
TOKUDB_TRACE("%s\n", __FUNCTION__);
for (uint i = 0; i < curr_num_DBs; i++) { for (uint i = 0; i < curr_num_DBs; i++) {
DB* db = share->key_file[i]; DB* db = share->key_file[i];
error = db->pre_acquire_table_lock(db, trans); error = db->pre_acquire_table_lock(db, trans);
if (error) { goto cleanup; } if (error == EINVAL)
TOKUDB_TRACE("%s %d db=%p trans=%p\n", __FUNCTION__, i, db, trans);
if (error) break;
} }
if (tokudb_debug & TOKUDB_DEBUG_LOCK)
TOKUDB_TRACE("%s error=%d\n", __FUNCTION__, error);
if (error) goto cleanup;
} }
else { else {
error = ENOSYS; error = ENOSYS;
...@@ -3299,12 +3346,17 @@ cleanup: ...@@ -3299,12 +3346,17 @@ cleanup:
// error otherwise // error otherwise
// //
int ha_tokudb::external_lock(THD * thd, int lock_type) { int ha_tokudb::external_lock(THD * thd, int lock_type) {
TOKUDB_DBUG_ENTER("ha_tokudb::external_lock %d", thd_sql_command(thd)); TOKUDB_DBUG_ENTER("ha_tokudb::external_lock cmd=%d %d", thd_sql_command(thd), lock_type);
if (tokudb_debug & TOKUDB_DEBUG_LOCK)
TOKUDB_TRACE("%s cmd=%d %d\n", __FUNCTION__, thd_sql_command(thd), lock_type);
// QQQ this is here to allow experiments without transactions // QQQ this is here to allow experiments without transactions
int error = 0; int error = 0;
ulong tx_isolation = thd_tx_isolation(thd); ulong tx_isolation = thd_tx_isolation(thd);
HA_TOKU_ISO_LEVEL toku_iso_level = tx_to_toku_iso(tx_isolation); HA_TOKU_ISO_LEVEL toku_iso_level = tx_to_toku_iso(tx_isolation);
tokudb_trx_data *trx = NULL; tokudb_trx_data *trx = NULL;
#if 0
declare_lockretry;
#endif
// //
// reset per-stmt variables // reset per-stmt variables
...@@ -3352,21 +3404,8 @@ int ha_tokudb::external_lock(THD * thd, int lock_type) { ...@@ -3352,21 +3404,8 @@ int ha_tokudb::external_lock(THD * thd, int lock_type) {
trx->sp_level = trx->all; trx->sp_level = trx->all;
trans_register_ha(thd, TRUE, tokudb_hton); trans_register_ha(thd, TRUE, tokudb_hton);
if (thd->in_lock_tables && thd_sql_command(thd) == SQLCOM_LOCK_TABLES) { if (thd->in_lock_tables && thd_sql_command(thd) == SQLCOM_LOCK_TABLES) {
// trx->table_lock_wanted = true;
// grab table locks trx->table_lock_type = lock.type < TL_READ_NO_INSERT ? lock_read : lock_write;
// For the command "Lock tables foo read, bar read"
// This statement is grabbing the locks for the table
// foo. The locks for bar will be grabbed when
// trx->tokudb_lock_count has been initialized
//
if (lock.type <= TL_READ_NO_INSERT) {
error = acquire_table_lock(trx->all,lock_read);
}
else {
error = acquire_table_lock(trx->all,lock_write);
}
// Don't create stmt trans
if (error) {trx->tokudb_lock_count--;}
goto cleanup; goto cleanup;
} }
} }
...@@ -3396,20 +3435,8 @@ int ha_tokudb::external_lock(THD * thd, int lock_type) { ...@@ -3396,20 +3435,8 @@ int ha_tokudb::external_lock(THD * thd, int lock_type) {
else { else {
if (thd->in_lock_tables && thd_sql_command(thd) == SQLCOM_LOCK_TABLES) { if (thd->in_lock_tables && thd_sql_command(thd) == SQLCOM_LOCK_TABLES) {
assert(trx->all != NULL); assert(trx->all != NULL);
// trx->table_lock_wanted = true;
// For the command "Lock tables foo read, bar read" trx->table_lock_type = lock.type < TL_READ_NO_INSERT ? lock_read : lock_write;
// This statement is grabbing the locks for the table
// bar. The locks for foo will be grabbed when
// trx->tokudb_lock_count is 0 and we are initializing
// trx->all above
//
if (lock.type <= TL_READ_NO_INSERT) {
error = acquire_table_lock(trx->all,lock_read);
}
else {
error = acquire_table_lock(trx->all,lock_write);
}
if (error) {trx->tokudb_lock_count--; goto cleanup;}
} }
} }
transaction = trx->stmt; transaction = trx->stmt;
...@@ -3446,6 +3473,8 @@ int ha_tokudb::external_lock(THD * thd, int lock_type) { ...@@ -3446,6 +3473,8 @@ int ha_tokudb::external_lock(THD * thd, int lock_type) {
transaction = NULL; transaction = NULL;
} }
cleanup: cleanup:
if (tokudb_debug & TOKUDB_DEBUG_LOCK)
TOKUDB_TRACE("%s error=%d\n", __FUNCTION__, error);
TOKUDB_DBUG_RETURN(error); TOKUDB_DBUG_RETURN(error);
} }
...@@ -3516,6 +3545,8 @@ int ha_tokudb::start_stmt(THD * thd, thr_lock_type lock_type) { ...@@ -3516,6 +3545,8 @@ int ha_tokudb::start_stmt(THD * thd, thr_lock_type lock_type) {
THR_LOCK_DATA **ha_tokudb::store_lock(THD * thd, THR_LOCK_DATA ** to, enum thr_lock_type lock_type) { THR_LOCK_DATA **ha_tokudb::store_lock(THD * thd, THR_LOCK_DATA ** to, enum thr_lock_type lock_type) {
TOKUDB_DBUG_ENTER("ha_tokudb::store_lock, lock_type=%d cmd=%d", lock_type, thd_sql_command(thd)); TOKUDB_DBUG_ENTER("ha_tokudb::store_lock, lock_type=%d cmd=%d", lock_type, thd_sql_command(thd));
if (tokudb_debug & TOKUDB_DEBUG_LOCK)
TOKUDB_TRACE("%s lock_type=%d cmd=%d\n", __FUNCTION__, lock_type, thd_sql_command(thd));
if (lock_type != TL_IGNORE && lock.type == TL_UNLOCK) { if (lock_type != TL_IGNORE && lock.type == TL_UNLOCK) {
/* If we are not doing a LOCK TABLE, then allow multiple writers */ /* If we are not doing a LOCK TABLE, then allow multiple writers */
if ((lock_type >= TL_WRITE_CONCURRENT_INSERT && lock_type <= TL_WRITE) && if ((lock_type >= TL_WRITE_CONCURRENT_INSERT && lock_type <= TL_WRITE) &&
...@@ -3525,6 +3556,8 @@ THR_LOCK_DATA **ha_tokudb::store_lock(THD * thd, THR_LOCK_DATA ** to, enum thr_l ...@@ -3525,6 +3556,8 @@ THR_LOCK_DATA **ha_tokudb::store_lock(THD * thd, THR_LOCK_DATA ** to, enum thr_l
lock.type = lock_type; lock.type = lock_type;
} }
*to++ = &lock; *to++ = &lock;
if (tokudb_debug & TOKUDB_DEBUG_LOCK)
TOKUDB_TRACE("%s lock_type=%d\n", __FUNCTION__, lock_type);
DBUG_RETURN(to); DBUG_RETURN(to);
} }
......
...@@ -28,6 +28,7 @@ extern ulong tokudb_debug; ...@@ -28,6 +28,7 @@ extern ulong tokudb_debug;
#define TOKUDB_DEBUG_ERROR 16 #define TOKUDB_DEBUG_ERROR 16
#define TOKUDB_DEBUG_TXN 32 #define TOKUDB_DEBUG_TXN 32
#define TOKUDB_DEBUG_AUTO_INCREMENT 64 #define TOKUDB_DEBUG_AUTO_INCREMENT 64
#define TOKUDB_DEBUG_LOCK 256
#define TOKUDB_TRACE(f, ...) \ #define TOKUDB_TRACE(f, ...) \
printf("%d:%s:%d:" f, my_tid(), __FILE__, __LINE__, ##__VA_ARGS__); printf("%d:%s:%d:" f, my_tid(), __FILE__, __LINE__, ##__VA_ARGS__);
...@@ -82,6 +83,8 @@ typedef struct st_tokudb_trx_data { ...@@ -82,6 +83,8 @@ typedef struct st_tokudb_trx_data {
DB_TXN *sp_level; DB_TXN *sp_level;
uint tokudb_lock_count; uint tokudb_lock_count;
HA_TOKU_ISO_LEVEL iso_level; HA_TOKU_ISO_LEVEL iso_level;
bool table_lock_wanted;
int table_lock_type;
} tokudb_trx_data; } tokudb_trx_data;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment