Below is the list of changes that have just been committed into a local
5.1 repository of mikron. When mikron 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-03-02 18:58:25+01:00, mikron@stripped +32 -0
Merge 21.37.251.10.in-addr.arpa:/Users/mikron/mysql_clones/latest_cluster
into 21.37.251.10.in-addr.arpa:/Users/mikron/mysql_clones/latest_wl3686
MERGE: 1.2409.2.12
configure.in@stripped, 2007-03-02 18:44:18+01:00, mikron@stripped +0 -0
Auto merged
MERGE: 1.420.3.5
sql/ha_ndbcluster.cc@stripped, 2007-03-02 18:58:20+01:00, mikron@stripped
+12 -16
manual merge
MERGE: 1.397.6.5
sql/ha_ndbcluster.h@stripped, 2007-03-02 18:44:19+01:00, mikron@stripped
+0 -0
Auto merged
MERGE: 1.165.1.4
sql/ha_partition.cc@stripped, 2007-03-02 18:44:19+01:00, mikron@stripped +0
-0
Auto merged
MERGE: 1.81.1.1
sql/handler.cc@stripped, 2007-03-02 18:44:20+01:00, mikron@stripped +0 -0
Auto merged
MERGE: 1.291.2.1
sql/mysql_priv.h@stripped, 2007-03-02 18:44:20+01:00, mikron@stripped +0
-0
Auto merged
MERGE: 1.470.5.1
sql/mysqld.cc@stripped, 2007-03-02 18:44:20+01:00, mikron@stripped +0 -0
Auto merged
MERGE: 1.609.1.1
sql/sql_base.cc@stripped, 2007-03-02 18:44:21+01:00, mikron@stripped +0 -0
Auto merged
MERGE: 1.371.1.1
sql/sql_class.cc@stripped, 2007-03-02 18:44:21+01:00, mikron@stripped +0
-0
Auto merged
MERGE: 1.308.2.3
sql/sql_delete.cc@stripped, 2007-03-02 18:44:22+01:00, mikron@stripped +0
-0
Auto merged
MERGE: 1.205.1.3
sql/sql_partition.cc@stripped, 2007-03-02 18:44:22+01:00, mikron@stripped
+0 -0
Auto merged
MERGE: 1.98.1.1
sql/sql_trigger.cc@stripped, 2007-03-02 18:58:21+01:00, mikron@stripped +1
-2
manual merge
MERGE: 1.82.1.1
sql/sql_update.cc@stripped, 2007-03-02 18:44:23+01:00, mikron@stripped +0
-0
Auto merged
MERGE: 1.219.1.4
sql/table.cc@stripped, 2007-03-02 18:44:23+01:00, mikron@stripped +0 -0
Auto merged
MERGE: 1.270.2.1
sql/table.h@stripped, 2007-03-02 18:44:23+01:00, mikron@stripped +0 -0
Auto merged
MERGE: 1.157.1.1
storage/ndb/include/kernel/GlobalSignalNumbers.h@stripped, 2007-03-02 18:44:24+01:00,
mikron@stripped +0 -0
Auto merged
MERGE: 1.32.1.2
storage/ndb/include/kernel/signaldata/DumpStateOrd.hpp@stripped, 2007-03-02 18:44:24+01:00,
mikron@stripped +0 -0
Auto merged
MERGE: 1.14.1.2
storage/ndb/src/kernel/blocks/dbdict/Dbdict.cpp@stripped, 2007-03-02 18:44:24+01:00,
mikron@stripped +0 -0
Auto merged
MERGE: 1.113.1.2
storage/ndb/src/kernel/blocks/dbdict/Dbdict.hpp@stripped, 2007-03-02 18:44:25+01:00,
mikron@stripped +0 -0
Auto merged
MERGE: 1.46.1.2
storage/ndb/src/kernel/blocks/dbdih/Dbdih.hpp@stripped, 2007-03-02 18:44:25+01:00,
mikron@stripped +0 -0
Auto merged
MERGE: 1.25.1.2
storage/ndb/src/kernel/blocks/dbdih/DbdihMain.cpp@stripped, 2007-03-02 18:44:25+01:00,
mikron@stripped +0 -0
Auto merged
MERGE: 1.99.1.5
storage/ndb/src/kernel/blocks/dblqh/Dblqh.hpp@stripped, 2007-03-02 18:44:25+01:00,
mikron@stripped +0 -0
Auto merged
MERGE: 1.57.2.1
storage/ndb/src/kernel/blocks/dblqh/DblqhMain.cpp@stripped, 2007-03-02 18:44:26+01:00,
mikron@stripped +0 -0
Auto merged
MERGE: 1.130.1.7
storage/ndb/src/kernel/blocks/dbtc/Dbtc.hpp@stripped, 2007-03-02 18:44:26+01:00,
mikron@stripped +0 -0
Auto merged
MERGE: 1.46.2.1
storage/ndb/src/kernel/blocks/dbtc/DbtcInit.cpp@stripped, 2007-03-02 18:44:26+01:00,
mikron@stripped +0 -0
Auto merged
MERGE: 1.19.1.1
storage/ndb/src/kernel/blocks/dbtc/DbtcMain.cpp@stripped, 2007-03-02 18:44:27+01:00,
mikron@stripped +0 -0
Auto merged
MERGE: 1.133.2.2
storage/ndb/src/kernel/blocks/qmgr/Qmgr.hpp@stripped, 2007-03-02 18:44:27+01:00,
mikron@stripped +0 -0
Auto merged
MERGE: 1.16.1.5
storage/ndb/src/kernel/blocks/qmgr/QmgrMain.cpp@stripped, 2007-03-02 18:44:27+01:00,
mikron@stripped +0 -0
Auto merged
MERGE: 1.47.1.7
storage/ndb/src/kernel/blocks/suma/Suma.cpp@stripped, 2007-03-02 18:44:28+01:00,
mikron@stripped +0 -0
Auto merged
MERGE: 1.51.1.5
storage/ndb/src/ndbapi/NdbScanOperation.cpp@stripped, 2007-03-02 18:44:28+01:00,
mikron@stripped +0 -0
Auto merged
MERGE: 1.105.1.6
storage/ndb/test/ndbapi/testNodeRestart.cpp@stripped, 2007-03-02 18:44:28+01:00,
mikron@stripped +0 -0
Auto merged
MERGE: 1.39.1.2
storage/ndb/test/run-test/daily-basic-tests.txt@stripped, 2007-03-02 18:44:28+01:00,
mikron@stripped +0 -0
Auto merged
MERGE: 1.64.1.4
# This is a BitKeeper patch. What follows are the unified diffs for the
# set of deltas contained in the patch. The rest of the patch, the part
# that BitKeeper cares about, is below these diffs.
# User: mikron
# Host: 21.37.251.10.in-addr.arpa
# Root: /Users/mikron/mysql_clones/latest_wl3686/RESYNC
--- 1.295/sql/handler.cc 2007-02-05 12:29:22 +01:00
+++ 1.296/sql/handler.cc 2007-03-02 18:44:20 +01:00
@@ -1924,10 +1924,10 @@
rnd_init() call is made as after this, MySQL will not use the bitmap
for any program logic checking.
*/
-void handler::column_bitmaps_signal()
+void handler::column_bitmaps_signal(uint sig_type)
{
DBUG_ENTER("column_bitmaps_signal");
- DBUG_PRINT("info", ("read_set: 0x%lx write_set: 0x%lx", (long) table->read_set,
+ DBUG_PRINT("enter", ("read_set: 0x%lx write_set: 0x%lx", (long) table->read_set,
(long) table->write_set));
DBUG_VOID_RETURN;
}
@@ -1961,7 +1961,7 @@
(void) extra(HA_EXTRA_KEYREAD);
table->mark_columns_used_by_index_no_reset(table->s->next_number_index,
table->read_set);
- column_bitmaps_signal();
+ column_bitmaps_signal(HA_CHANGE_TABLE_READ_BITMAP);
index_init(table->s->next_number_index, 1);
if (!table->s->next_number_key_offset)
{ // Autoincrement at key-start
--- 1.479/sql/mysql_priv.h 2007-02-06 15:52:24 +01:00
+++ 1.480/sql/mysql_priv.h 2007-03-02 18:44:20 +01:00
@@ -868,6 +868,9 @@
void set_key_field_ptr(KEY *key_info, const byte *new_buf,
const byte *old_buf);
+void include_partition_fields_in_used_fields(Field **ptr,
+ MY_BITMAP *read_set);
+
bool mysql_backup_table(THD* thd, TABLE_LIST* table_list);
bool mysql_restore_table(THD* thd, TABLE_LIST* table_list);
@@ -1389,6 +1392,7 @@
bool close_cached_tables(THD *thd, bool wait_for_refresh, TABLE_LIST *tables, bool
have_lock = FALSE);
void copy_field_from_tmp_record(Field *field,int offset);
+bool check_constant_expressions(List<Item> *values);
bool fill_record(THD *thd, Field **field, List<Item> &values,
bool ignore_errors);
bool fill_record_n_invoke_before_triggers(THD *thd, List<Item> &fields,
@@ -1452,7 +1456,7 @@
int find_ref_key(KEY *key, uint key_count, byte *record, Field *field,
uint *key_length);
void key_copy(byte *to_key, byte *from_record, KEY *key_info, uint key_length);
-void key_restore(byte *to_record, byte *from_key, KEY *key_info,
+void key_restore(byte *to_record, const byte *from_key, const KEY *key_info,
uint key_length);
bool key_cmp_if_same(TABLE *form,const byte *key,uint index,uint key_length);
void key_unpack(String *to,TABLE *form,uint index);
--- 1.374/sql/sql_base.cc 2007-02-02 07:19:32 +01:00
+++ 1.375/sql/sql_base.cc 2007-03-02 18:44:21 +01:00
@@ -5962,6 +5962,34 @@
** Returns : 1 if some field has wrong type
******************************************************************************/
+/*
+ Check if all expressions in list are constant expressions
+
+ SYNOPSIS
+ check_constant_expressions()
+ values List of expressions
+
+ RETURN
+ TRUE Only constant expressions
+ FALSE At least one non-constant expression
+*/
+
+bool check_constant_expressions(List<Item> *values)
+{
+ List_iterator_fast<Item> v(*values);
+ Item *value;
+ DBUG_ENTER("check_constant_expressions");
+
+ while (value= v++)
+ {
+ if (!value->const_item())
+ {
+ DBUG_RETURN(FALSE);
+ }
+ }
+ DBUG_RETURN(TRUE);
+}
+
/*
Fill fields with given items.
--- 1.208/sql/sql_delete.cc 2007-02-02 11:26:51 +01:00
+++ 1.209/sql/sql_delete.cc 2007-03-02 18:44:22 +01:00
@@ -35,6 +35,8 @@
READ_RECORD info;
bool using_limit=limit != HA_POS_ERROR;
bool transactional_table, safe_update, const_cond;
+ bool direct_delete_loop;
+ bool might_use_read_removal= FALSE;
ha_rows deleted= 0;
uint usable_index= MAX_KEY;
SELECT_LEX *select_lex= &thd->lex->select_lex;
@@ -172,7 +174,7 @@
free_underlaid_joins(thd, &thd->lex->select_lex);
DBUG_RETURN(TRUE);
}
-
+ table->file->column_bitmaps_signal(HA_COMPLETE_TABLE_BOTH_BITMAPS);
if ((!select || table->quick_keys.is_clear_all()) && limit !=
HA_POS_ERROR)
usable_index= get_index_for_order(table, (ORDER*)(order->first), limit);
@@ -200,6 +202,12 @@
free_underlaid_joins(thd, select_lex);
select= 0;
}
+ direct_delete_loop= FALSE;
+ }
+ else
+ {
+ direct_delete_loop= TRUE;
+ table->file->column_bitmaps_signal(HA_COMPLETE_TABLE_BOTH_BITMAPS);
}
/* If quick select is used, initialize it before retrieving rows. */
@@ -214,11 +222,19 @@
else
init_read_record_idx(&info, thd, table, 1, usable_index);
+ if (!table->triggers &&
+ info.using_quick &&
+ !using_limit &&
+ direct_delete_loop)
+ {
+ /* See comment in sql_update.cc for similar code */
+ might_use_read_removal=
+ table->file->read_before_write_removal_possible(NULL, NULL);
+ }
init_ftfuncs(thd, select_lex, 1);
thd->proc_info="updating";
will_batch= !table->file->start_bulk_delete();
-
table->mark_columns_needed_for_delete();
while (!(error=info.read_record(&info)) && !thd->killed &&
@@ -296,6 +312,12 @@
table->file->print_error(error2, MYF(0));
error= 1;
}
+ }
+
+ if (might_use_read_removal)
+ {
+ table->file->info(HA_STATUS_WRITTEN_ROWS);
+ deleted= table->file->stats.rows_deleted;
}
cleanup:
--- 1.222/sql/sql_update.cc 2007-01-29 00:51:40 +01:00
+++ 1.223/sql/sql_update.cc 2007-03-02 18:44:23 +01:00
@@ -117,6 +117,7 @@
bool safe_update= test(thd->options & OPTION_SAFE_UPDATES);
bool used_key_is_modified, transactional_table, will_batch;
bool can_compare_record;
+ bool might_use_read_removal= FALSE;
int res;
int error, loc_error;
uint used_index= MAX_KEY, dup_key_found;
@@ -132,6 +133,7 @@
READ_RECORD info;
SELECT_LEX *select_lex= &thd->lex->select_lex;
bool need_reopen;
+ bool direct_update_loop;
ulonglong id;
DBUG_ENTER("mysql_update");
@@ -267,7 +269,7 @@
}
}
init_ftfuncs(thd, select_lex, 1);
-
+ table->file->column_bitmaps_signal(HA_COMPLETE_TABLE_BOTH_BITMAPS);
table->mark_columns_needed_for_update();
/* Check if we are modifying a key that we are used to search with */
@@ -426,7 +428,10 @@
}
if (table->key_read)
table->restore_column_maps_after_mark_index();
+ direct_update_loop= FALSE;
}
+ else
+ direct_update_loop= TRUE;
if (ignore)
table->file->extra(HA_EXTRA_IGNORE_DUP_KEY);
@@ -436,6 +441,22 @@
table->file->try_semi_consistent_read(1);
init_read_record(&info,thd,table,select,0,1);
+ if (!table->triggers &&
+ info.using_quick &&
+ !ignore &&
+ !using_limit &&
+ direct_update_loop)
+ {
+ /*
+ In certain cases the handler can avoid doing a real read before
+ the update. It should still maintain the semantics of the
+ handler interface but can generate reads instead of performing
+ them for real. This extra call tells the handler that this
+ is possible for this handler until next reset of handler.
+ */
+ might_use_read_removal=
+ table->file->read_before_write_removal_possible(&fields, &values);
+ }
updated= found= 0;
thd->count_cuted_fields= CHECK_FIELD_WARN; /* calc cuted fields */
thd->cuted_fields=0L;
@@ -627,6 +648,21 @@
thd->proc_info= "end";
VOID(table->file->extra(HA_EXTRA_NO_IGNORE_DUP_KEY));
+ if (might_use_read_removal)
+ {
+ /*
+ updated counter is not valid when using read before write removal
+ optimisatisation so we read it from handler in info call.
+ More sophisticated handling of this would be required if it is
+ necessary to also support this optimisation in conjunction with
+ using LIMIT. Now the optimisation is disabled for IGNORE, LIMIT and
+ also when using BEFORE UPDATE triggers on table and also quite
+ hard checks on UPDATE statement. Still it is used very often with
+ all those limitations.
+ */
+ table->file->info(HA_STATUS_WRITTEN_ROWS);
+ updated= table->file->stats.rows_updated;
+ }
/*
Invalidate the table in the query cache if something changed.
This must be before binlog writing and ha_autocommit_...
--- 1.273/sql/table.cc 2007-02-13 10:27:24 +01:00
+++ 1.274/sql/table.cc 2007-03-02 18:44:23 +01:00
@@ -3853,7 +3853,7 @@
{
mark_columns_used_by_index_no_reset(s->primary_key, read_set);
/* signal change */
- file->column_bitmaps_signal();
+ file->column_bitmaps_signal(HA_CHANGE_TABLE_READ_BITMAP);
}
DBUG_VOID_RETURN;
}
@@ -3900,7 +3900,7 @@
key_read= 0;
(void) file->extra(HA_EXTRA_NO_KEYREAD);
default_column_bitmaps();
- file->column_bitmaps_signal();
+ file->column_bitmaps_signal(HA_CHANGE_TABLE_BOTH_BITMAPS);
DBUG_VOID_RETURN;
}
@@ -3939,7 +3939,7 @@
bitmap_set_bit(write_set, found_next_number_field->field_index);
if (s->next_number_key_offset)
mark_columns_used_by_index_no_reset(s->next_number_index, read_set);
- file->column_bitmaps_signal();
+ file->column_bitmaps_signal(HA_CHANGE_TABLE_BOTH_BITMAPS);
}
@@ -3973,7 +3973,7 @@
if ((*reg_field)->flags & PART_KEY_FLAG)
bitmap_set_bit(read_set, (*reg_field)->field_index);
}
- file->column_bitmaps_signal();
+ file->column_bitmaps_signal(HA_CHANGE_TABLE_READ_BITMAP);
}
if (file->ha_table_flags() & HA_PRIMARY_KEY_REQUIRED_FOR_DELETE)
{
@@ -3987,7 +3987,7 @@
else
{
mark_columns_used_by_index_no_reset(s->primary_key, read_set);
- file->column_bitmaps_signal();
+ file->column_bitmaps_signal(HA_CHANGE_TABLE_READ_BITMAP);
}
}
}
@@ -4026,7 +4026,7 @@
if (merge_keys.is_overlapping((*reg_field)->part_of_key))
bitmap_set_bit(read_set, (*reg_field)->field_index);
}
- file->column_bitmaps_signal();
+ file->column_bitmaps_signal(HA_CHANGE_TABLE_READ_BITMAP);
}
if (file->ha_table_flags() & HA_PRIMARY_KEY_REQUIRED_FOR_DELETE)
{
@@ -4040,7 +4040,7 @@
else
{
mark_columns_used_by_index_no_reset(s->primary_key, read_set);
- file->column_bitmaps_signal();
+ file->column_bitmaps_signal(HA_CHANGE_TABLE_READ_BITMAP);
}
}
DBUG_VOID_RETURN;
--- 1.160/sql/table.h 2007-01-30 18:07:37 +01:00
+++ 1.161/sql/table.h 2007-03-02 18:44:23 +01:00
@@ -451,7 +451,7 @@
read_set= read_set_arg;
write_set= write_set_arg;
if (file)
- file->column_bitmaps_signal();
+ file->column_bitmaps_signal(HA_CHANGE_TABLE_BOTH_BITMAPS);
}
inline void column_bitmaps_set_no_signal(MY_BITMAP *read_set_arg,
MY_BITMAP *write_set_arg)
--- 1.83/sql/sql_trigger.cc 2007-01-27 02:46:40 +01:00
+++ 1.84/sql/sql_trigger.cc 2007-03-02 18:58:21 +01:00
@@ -1631,7 +1631,7 @@
}
}
}
- trigger_table->file->column_bitmaps_signal();
+ trigger_table->file->column_bitmaps_signal(HA_CHANGE_TABLE_BOTH_BITMAPS);
}
--- 1.66/storage/ndb/test/run-test/daily-basic-tests.txt 2007-02-06 09:16:26 +01:00
+++ 1.67/storage/ndb/test/run-test/daily-basic-tests.txt 2007-03-02 18:44:28 +01:00
@@ -81,6 +81,10 @@
max-time: 500
cmd: testBasic
+args: -n DeleteRead
+
+max-time: 500
+cmd: testBasic
args: -n PkReadAndLocker T6 D1 D2
max-time: 500
@@ -461,7 +465,7 @@
cmd: testScan
args: -n Bug24447 T1
-max-time: 500
+max-time: 1000
cmd: testScan
args: -n ScanVariants
@@ -520,6 +524,10 @@
max-time: 1000
cmd: testNodeRestart
args: -n Bug25554 T1
+
+max-time: 1000
+cmd: testNodeRestart
+args: -n Bug25984
#
# DICT TESTS
--- 1.34/storage/ndb/include/kernel/GlobalSignalNumbers.h 2007-02-06 09:16:25 +01:00
+++ 1.35/storage/ndb/include/kernel/GlobalSignalNumbers.h 2007-03-02 18:44:24 +01:00
@@ -90,7 +90,8 @@
#define GSN_TCSEIZEREF 38
#define GSN_TCSEIZEREQ 39
-/* 40 unused */
+#define GSN_TCKEY_FAILREFCONF_R 40
+
/* 41 unused */
/* 42 unused */
/* 43 unused */
--- 1.16/storage/ndb/include/kernel/signaldata/DumpStateOrd.hpp 2007-02-06 09:16:25 +01:00
+++ 1.17/storage/ndb/include/kernel/signaldata/DumpStateOrd.hpp 2007-03-02 18:44:24 +01:00
@@ -107,7 +107,10 @@
CmvmiDumpLongSignalMemory = 2601,
CmvmiSetRestartOnErrorInsert = 2602,
CmvmiTestLongSigWithDelay = 2603,
-
+ CmvmiDumpSubscriptions = 2604, /* note: done to respective outfile
+ to be able to debug if events
+ for some reason does not end up
+ in clusterlog */
LCPContinue = 5900,
// 7000 DIH
// 7001 DIH
--- 1.115/storage/ndb/src/kernel/blocks/dbdict/Dbdict.cpp 2007-02-06 09:16:25 +01:00
+++ 1.116/storage/ndb/src/kernel/blocks/dbdict/Dbdict.cpp 2007-03-02 18:44:24 +01:00
@@ -6119,11 +6119,6 @@
tablePtr.p->defaultNoPartFlag = c_tableDesc.DefaultNoPartFlag;
tablePtr.p->linearHashFlag = c_tableDesc.LinearHashFlag;
- Uint64 maxRows =
- (((Uint64)tablePtr.p->maxRowsHigh) << 32) + tablePtr.p->maxRowsLow;
- Uint64 minRows =
- (((Uint64)tablePtr.p->minRowsHigh) << 32) + tablePtr.p->minRowsLow;
-
{
Rope frm(c_rope_pool, tablePtr.p->frmData);
tabRequire(frm.assign(c_tableDesc.FrmData, c_tableDesc.FrmLen),
--- 1.48/storage/ndb/src/kernel/blocks/dbdict/Dbdict.hpp 2007-02-06 09:16:25 +01:00
+++ 1.49/storage/ndb/src/kernel/blocks/dbdict/Dbdict.hpp 2007-03-02 18:44:25 +01:00
@@ -1131,6 +1131,7 @@
* seize/release invokes ctor/dtor automatically.
*/
struct OpRecordCommon {
+ OpRecordCommon() {}
Uint32 key; // key shared between master and slaves
Uint32 nextHash;
Uint32 prevHash;
@@ -1146,6 +1147,7 @@
* Create table record
*/
struct CreateTableRecord : OpRecordCommon {
+ CreateTableRecord() {}
Uint32 m_senderRef;
Uint32 m_senderData;
Uint32 m_coordinatorRef;
@@ -1189,6 +1191,7 @@
* Drop table record
*/
struct DropTableRecord : OpRecordCommon {
+ DropTableRecord() {}
DropTableReq m_request;
Uint32 m_requestType;
--- 1.27/storage/ndb/src/kernel/blocks/dbdih/Dbdih.hpp 2007-02-06 09:16:25 +01:00
+++ 1.28/storage/ndb/src/kernel/blocks/dbdih/Dbdih.hpp 2007-03-02 18:44:25 +01:00
@@ -1302,6 +1302,7 @@
private:
struct LcpState {
+ LcpState() {}
LcpStatus lcpStatus;
Uint32 lcpStatusUpdatedPlace;
@@ -1408,6 +1409,7 @@
private:
class MasterTakeOverState {
public:
+ MasterTakeOverState() {}
void set(LcpMasterTakeOverState s, Uint32 line) {
state = s; updatePlace = line;
}
@@ -1495,6 +1497,7 @@
* SwitchReplicaRecord - Should only be used by master
*/
struct SwitchReplicaRecord {
+ SwitchReplicaRecord() {}
void clear(){}
Uint32 nodeId;
--- 1.103/storage/ndb/src/kernel/blocks/dbdih/DbdihMain.cpp 2007-02-20 13:49:21 +01:00
+++ 1.104/storage/ndb/src/kernel/blocks/dbdih/DbdihMain.cpp 2007-03-02 18:44:25 +01:00
@@ -1194,11 +1194,58 @@
void Dbdih::execDIH_RESTARTREQ(Signal* signal)
{
jamEntry();
- cntrlblockref = signal->theData[0];
- if(m_ctx.m_config.getInitialStart()){
- sendSignal(cntrlblockref, GSN_DIH_RESTARTREF, signal, 1, JBB);
- } else {
- readGciFileLab(signal);
+ if (signal->theData[0])
+ {
+ jam();
+ cntrlblockref = signal->theData[0];
+ if(m_ctx.m_config.getInitialStart()){
+ sendSignal(cntrlblockref, GSN_DIH_RESTARTREF, signal, 1, JBB);
+ } else {
+ readGciFileLab(signal);
+ }
+ }
+ else
+ {
+ /**
+ * Precondition, (not checked)
+ * atleast 1 node in each node group
+ */
+ Uint32 i;
+ NdbNodeBitmask mask;
+ mask.assign(NdbNodeBitmask::Size, signal->theData + 1);
+ Uint32 *node_gcis = signal->theData+1+NdbNodeBitmask::Size;
+ Uint32 node_group_gcis[MAX_NDB_NODES+1];
+ bzero(node_group_gcis, sizeof(node_group_gcis));
+ for (i = 0; i<MAX_NDB_NODES; i++)
+ {
+ if (mask.get(i))
+ {
+ jam();
+ Uint32 ng = Sysfile::getNodeGroup(i, SYSFILE->nodeGroups);
+ ndbrequire(ng < MAX_NDB_NODES);
+ Uint32 gci = node_gcis[i];
+ if (gci > node_group_gcis[ng])
+ {
+ jam();
+ node_group_gcis[ng] = gci;
+ }
+ }
+ }
+ for (i = 0; i<MAX_NDB_NODES && node_group_gcis[i] == 0; i++);
+
+ Uint32 gci = node_group_gcis[i];
+ for (i++ ; i<MAX_NDB_NODES; i++)
+ {
+ jam();
+ if (node_group_gcis[i] && node_group_gcis[i] != gci)
+ {
+ jam();
+ signal->theData[0] = i;
+ return;
+ }
+ }
+ signal->theData[0] = MAX_NDB_NODES;
+ return;
}
return;
}//Dbdih::execDIH_RESTARTREQ()
@@ -1525,10 +1572,26 @@
*/
SYSFILE->lastCompletedGCI[nodePtr.i] = 0;
ndbrequire(nodePtr.p->nodeStatus != NodeRecord::ALIVE);
- warningEvent("Making filesystem for node %d unusable",
+ warningEvent("Making filesystem for node %d unusable (need --initial)",
nodePtr.i);
}
+ else if (nodePtr.p->nodeStatus == NodeRecord::ALIVE &&
+ SYSFILE->lastCompletedGCI[nodePtr.i] == 0)
+ {
+ jam();
+ CRASH_INSERTION(7170);
+ char buf[255];
+ BaseString::snprintf(buf, sizeof(buf),
+ "Cluster requires this node to be started "
+ " with --initial as partial start has been performed"
+ " and this filesystem is unusable");
+ progError(__LINE__,
+ NDBD_EXIT_SR_RESTARTCONFLICT,
+ buf);
+ ndbrequire(false);
+ }
}
+
/**
* This set which GCI we will try to restart to
*/
@@ -1820,8 +1883,8 @@
return;
}//if
if (getNodeStatus(nodeId) != NodeRecord::DEAD){
- ndbout << "nodeStatus in START_PERMREQ = "
- << (Uint32) getNodeStatus(nodeId) << endl;
+ g_eventLogger.error("nodeStatus in START_PERMREQ = %u",
+ (Uint32) getNodeStatus(nodeId));
ndbrequire(false);
}//if
@@ -4234,9 +4297,9 @@
jam();
break;
default:
- ndbout_c("outstanding gsn: %s(%d)",
- getSignalName(c_nodeStartMaster.m_outstandingGsn),
- c_nodeStartMaster.m_outstandingGsn);
+ g_eventLogger.error("outstanding gsn: %s(%d)",
+ getSignalName(c_nodeStartMaster.m_outstandingGsn),
+ c_nodeStartMaster.m_outstandingGsn);
ndbrequire(false);
}
@@ -4689,9 +4752,10 @@
failedNodePtr.p->activeStatus = Sysfile::NS_NotActive_NotTakenOver;
break;
default:
- ndbout << "activeStatus = " << (Uint32)
failedNodePtr.p->activeStatus;
- ndbout << " at failure after NODE_FAILREP of node = ";
- ndbout << failedNodePtr.i << endl;
+ g_eventLogger.error("activeStatus = %u "
+ "at failure after NODE_FAILREP of node = %u",
+ (Uint32) failedNodePtr.p->activeStatus,
+ failedNodePtr.i);
ndbrequire(false);
break;
}//switch
@@ -4846,7 +4910,7 @@
/**
* Node failure during master take over...
*/
- ndbout_c("Nodefail during master take over");
+ g_eventLogger.info("Nodefail during master take over");
}
setLocalNodefailHandling(signal, nodeId, NF_LCP_TAKE_OVER);
@@ -5086,7 +5150,8 @@
if (latestLcpId > SYSFILE->latestLCP_ID) {
jam();
#if 0
- ndbout_c("Dbdih: Setting SYSFILE->latestLCP_ID to %d", latestLcpId);
+ g_eventLogger.info("Dbdih: Setting SYSFILE->latestLCP_ID to %d",
+ latestLcpId);
SYSFILE->latestLCP_ID = latestLcpId;
#endif
SYSFILE->keepGCI = oldestKeepGci;
@@ -5745,7 +5810,7 @@
if (ERROR_INSERTED(7030))
{
- ndbout_c("Reenable GCP_PREPARE");
+ g_eventLogger.info("Reenable GCP_PREPARE");
CLEAR_ERROR_INSERT_VALUE;
}
@@ -5918,7 +5983,7 @@
c_lcpState.setLcpStatus(LCP_STATUS_IDLE, __LINE__);
#if 0
if(c_copyGCISlave.m_copyReason == CopyGCIReq::LOCAL_CHECKPOINT){
- ndbout_c("Dbdih: Also resetting c_copyGCISlave");
+ g_eventLogger.info("Dbdih: Also resetting c_copyGCISlave");
c_copyGCISlave.m_copyReason = CopyGCIReq::IDLE;
c_copyGCISlave.m_expectedNextWord = 0;
}
@@ -6003,7 +6068,7 @@
if(c_lcpState.lcpStatus == LCP_TAB_SAVED){
#ifdef VM_TRACE
- ndbout_c("Sending extra GSN_LCP_COMPLETE_REP to new master");
+ g_eventLogger.info("Sending extra GSN_LCP_COMPLETE_REP to new master");
#endif
sendLCP_COMPLETE_REP(signal);
}
@@ -6159,7 +6224,7 @@
nodePtr.p->lcpStateAtTakeOver = lcpState;
#ifdef VM_TRACE
- ndbout_c("MASTER_LCPCONF");
+ g_eventLogger.info("MASTER_LCPCONF");
printMASTER_LCP_CONF(stdout, &signal->theData[0], 0, 0);
#endif
@@ -6236,7 +6301,7 @@
// protocol.
/* --------------------------------------------------------------------- */
#ifdef VM_TRACE
- ndbout_c("MASTER_LCPhandling:: LMTOS_ALL_IDLE -> checkLcpStart");
+ g_eventLogger.info("MASTER_LCPhandling:: LMTOS_ALL_IDLE -> checkLcpStart");
#endif
checkLcpStart(signal, __LINE__);
break;
@@ -6247,7 +6312,7 @@
// protocol by calculating the keep gci and storing the new lcp id.
/* --------------------------------------------------------------------- */
#ifdef VM_TRACE
- ndbout_c("MASTER_LCPhandling:: LMTOS_COPY_ONGOING -> storeNewLcpId");
+ g_eventLogger.info("MASTER_LCPhandling:: LMTOS_COPY_ONGOING -> storeNewLcpId");
#endif
if (c_lcpState.lcpStatus == LCP_STATUS_ACTIVE) {
jam();
@@ -6258,7 +6323,7 @@
/*---------------------------------------------------------------------*/
Uint32 lcpId = SYSFILE->latestLCP_ID;
#ifdef VM_TRACE
- ndbout_c("Decreasing latestLCP_ID from %d to %d", lcpId, lcpId - 1);
+ g_eventLogger.info("Decreasing latestLCP_ID from %d to %d", lcpId, lcpId - 1);
#endif
SYSFILE->latestLCP_ID--;
}//if
@@ -6275,10 +6340,10 @@
* complete before finalising the LCP process.
* ------------------------------------------------------------------ */
#ifdef VM_TRACE
- ndbout_c("MASTER_LCPhandling:: LMTOS_ALL_ACTIVE -> "
- "startLcpRoundLoopLab(table=%u, fragment=%u)",
- c_lcpMasterTakeOverState.minTableId,
- c_lcpMasterTakeOverState.minFragId);
+ g_eventLogger.info("MASTER_LCPhandling:: LMTOS_ALL_ACTIVE -> "
+ "startLcpRoundLoopLab(table=%u, fragment=%u)",
+ c_lcpMasterTakeOverState.minTableId,
+ c_lcpMasterTakeOverState.minFragId);
#endif
c_lcpState.keepGci = SYSFILE->keepGCI;
@@ -7683,8 +7748,8 @@
if (cgcpSameCounter == 1200) {
jam();
#ifdef VM_TRACE
- ndbout << "System crash due to GCP Stop in state = ";
- ndbout << (Uint32) cgcpStatus << endl;
+ g_eventLogger.error("System crash due to GCP Stop in state = %u",
+ (Uint32) cgcpStatus);
#endif
crashSystemAtGcpStop(signal);
return;
@@ -7697,8 +7762,8 @@
if (cgcpSameCounter == 1200) {
jam();
#ifdef VM_TRACE
- ndbout << "System crash due to GCP Stop in state = ";
- ndbout << (Uint32) cgcpStatus << endl;
+ g_eventLogger.error("System crash due to GCP Stop in state = %u",
+ (Uint32) cgcpStatus);
#endif
crashSystemAtGcpStop(signal);
return;
@@ -7889,7 +7954,7 @@
getNodeState().startLevel == NodeState::SL_STARTED){
jam();
#if 0
- ndbout_c("Dbdih: Clearing initial start ongoing");
+ g_eventLogger.info("Dbdih: Clearing initial start ongoing");
#endif
Sysfile::clearInitialStartOngoing(SYSFILE->systemRestartBits);
}
@@ -7908,7 +7973,7 @@
if (ERROR_INSERTED(7030))
{
cgckptflag = true;
- ndbout_c("Delayed GCP_PREPARE 5s");
+ g_eventLogger.info("Delayed GCP_PREPARE 5s");
sendSignalWithDelay(reference(), GSN_GCP_PREPARE, signal, 5000,
signal->getLength());
return;
@@ -7928,7 +7993,7 @@
if (ERROR_INSERTED(7031))
{
- ndbout_c("Crashing delayed in GCP_PREPARE 3s");
+ g_eventLogger.info("Crashing delayed in GCP_PREPARE 3s");
signal->theData[0] = 9999;
sendSignalWithDelay(CMVMI_REF, GSN_NDB_TAMPER, signal, 3000, 1);
return;
@@ -8452,7 +8517,7 @@
* This is LCP master takeover
*/
#ifdef VM_TRACE
- ndbout_c("initLcpLab aborted due to LCP master takeover - 1");
+ g_eventLogger.info("initLcpLab aborted due to LCP master takeover - 1");
#endif
c_lcpState.setLcpStatus(LCP_STATUS_IDLE, __LINE__);
sendMASTER_LCPCONF(signal);
@@ -8465,7 +8530,7 @@
* Master take over but has not yet received MASTER_LCPREQ
*/
#ifdef VM_TRACE
- ndbout_c("initLcpLab aborted due to LCP master takeover - 2");
+ g_eventLogger.info("initLcpLab aborted due to LCP master takeover - 2");
#endif
return;
}
@@ -9774,9 +9839,10 @@
{
CRASH_INSERTION(7009);
if (c_lcpState.lcpStatus != LCP_STATUS_IDLE) {
- ndbout << "lcpStatus = " << (Uint32) c_lcpState.lcpStatus;
- ndbout << "lcpStatusUpdatedPlace = " <<
- c_lcpState.lcpStatusUpdatedPlace << endl;
+ g_eventLogger.error("lcpStatus = %u"
+ "lcpStatusUpdatedPlace = %d",
+ (Uint32) c_lcpState.lcpStatus,
+ c_lcpState.lcpStatusUpdatedPlace);
ndbrequire(false);
return;
}//if
@@ -10359,9 +10425,8 @@
if(tabPtr.p->tabStatus == TabRecord::TS_DROPPING){
jam();
- ndbout_c("TS_DROPPING - Neglecting to save Table: %d Frag: %d - ",
- tableId,
- fragId);
+ g_eventLogger.info("TS_DROPPING - Neglecting to save Table: %d Frag: %d - ",
+ tableId, fragId);
} else {
jam();
/**
@@ -10491,7 +10556,7 @@
};
#ifdef VM_TRACE
- ndbout_c("Fragment Replica(node=%d) not found", nodeId);
+ g_eventLogger.info("Fragment Replica(node=%d) not found", nodeId);
replicaPtr.i = fragPtrP->oldStoredReplicas;
while(replicaPtr.i != RNIL){
ptrCheckGuard(replicaPtr, creplicaFileSize, replicaRecord);
@@ -10504,9 +10569,9 @@
}//if
};
if(replicaPtr.i != RNIL){
- ndbout_c("...But was found in oldStoredReplicas");
+ g_eventLogger.info("...But was found in oldStoredReplicas");
} else {
- ndbout_c("...And wasn't found in oldStoredReplicas");
+ g_eventLogger.info("...And wasn't found in oldStoredReplicas");
}
#endif
ndbrequire(false);
@@ -10573,8 +10638,8 @@
if(lcpNo != replicaPtr.p->nextLcp){
if (handle_invalid_lcp_no(lcpReport, replicaPtr))
{
- ndbout_c("lcpNo = %d replicaPtr.p->nextLcp = %d",
- lcpNo, replicaPtr.p->nextLcp);
+ g_eventLogger.error("lcpNo = %d replicaPtr.p->nextLcp = %d",
+ lcpNo, replicaPtr.p->nextLcp);
ndbrequire(false);
}
}
@@ -10610,7 +10675,7 @@
// Not all fragments in table have been checkpointed.
/* ----------------------------------------------------------------- */
if(0)
- ndbout_c("reportLcpCompletion: fragment %d not ready", fid);
+ g_eventLogger.info("reportLcpCompletion: fragment %d not ready", fid);
return false;
}//if
}//for
@@ -10727,7 +10792,7 @@
jamEntry();
#if 0
- ndbout_c("LCP_COMPLETE_REP");
+ g_eventLogger.info("LCP_COMPLETE_REP");
printLCP_COMPLETE_REP(stdout,
signal->getDataPtr(),
signal->length(), number());
@@ -10813,7 +10878,7 @@
if(c_lcpMasterTakeOverState.state != LMTOS_IDLE){
jam();
#ifdef VM_TRACE
- ndbout_c("Exiting from allNodesLcpCompletedLab");
+ g_eventLogger.info("Exiting from allNodesLcpCompletedLab");
#endif
return;
}
@@ -11050,14 +11115,14 @@
infoEvent("Detected GCP stop...sending kill to %s",
c_GCP_SAVEREQ_Counter.getText());
- ndbout_c("Detected GCP stop...sending kill to %s",
- c_GCP_SAVEREQ_Counter.getText());
+ g_eventLogger.error("Detected GCP stop...sending kill to %s",
+ c_GCP_SAVEREQ_Counter.getText());
return;
}
case GCP_SAVE_LQH_FINISHED:
- ndbout_c("m_copyReason: %d m_waiting: %d",
- c_copyGCIMaster.m_copyReason,
- c_copyGCIMaster.m_waiting);
+ g_eventLogger.error("m_copyReason: %d m_waiting: %d",
+ c_copyGCIMaster.m_copyReason,
+ c_copyGCIMaster.m_waiting);
break;
case GCP_READY: // shut up lint
case GCP_PREPARE_SENT:
@@ -11065,11 +11130,11 @@
break;
}
- ndbout_c("c_copyGCISlave: sender{Data, Ref} %d %x reason: %d nextWord: %d",
- c_copyGCISlave.m_senderData,
- c_copyGCISlave.m_senderRef,
- c_copyGCISlave.m_copyReason,
- c_copyGCISlave.m_expectedNextWord);
+ g_eventLogger.error("c_copyGCISlave: sender{Data, Ref} %d %x reason: %d nextWord: %d",
+ c_copyGCISlave.m_senderData,
+ c_copyGCISlave.m_senderRef,
+ c_copyGCISlave.m_copyReason,
+ c_copyGCISlave.m_expectedNextWord);
FileRecordPtr file0Ptr;
file0Ptr.i = crestartInfoFile[0];
@@ -12376,7 +12441,7 @@
(buf, sizeof(buf),
"Illegal initial start, no alive node in nodegroup %u", i);
progError(__LINE__,
- NDBD_EXIT_SR_RESTARTCONFLICT,
+ NDBD_EXIT_INSUFFICENT_NODES,
buf);
}
@@ -12516,14 +12581,23 @@
/* THAT THE NEW REPLICA IS NOT STARTED YET AND REPLICA_LAST_GCI IS*/
/* SET TO -1 TO INDICATE THAT IT IS NOT DEAD YET. */
/*----------------------------------------------------------------------*/
+ Uint32 lastGCI = SYSFILE->lastCompletedGCI[nodeId];
arrGuardErr(ncrReplicaPtr.p->noCrashedReplicas + 1, 8,
NDBD_EXIT_MAX_CRASHED_REPLICAS);
ncrReplicaPtr.p->replicaLastGci[ncrReplicaPtr.p->noCrashedReplicas] =
- SYSFILE->lastCompletedGCI[nodeId];
+ lastGCI;
ncrReplicaPtr.p->noCrashedReplicas = ncrReplicaPtr.p->noCrashedReplicas + 1;
ncrReplicaPtr.p->createGci[ncrReplicaPtr.p->noCrashedReplicas] = 0;
ncrReplicaPtr.p->replicaLastGci[ncrReplicaPtr.p->noCrashedReplicas] =
(Uint32)-1;
+
+ if (ncrReplicaPtr.p->noCrashedReplicas == 7 && lastGCI)
+ {
+ jam();
+ SYSFILE->lastCompletedGCI[nodeId] = 0;
+ warningEvent("Making filesystem for node %d unusable (need --initial)",
+ nodeId);
+ }
}//Dbdih::newCrashedReplica()
/*************************************************************************/
@@ -13279,9 +13353,9 @@
nodePtr.i = getOwnNodeId();
ptrAss(nodePtr, nodeRecord);
ndbrequire(nodePtr.p->activeStatus == Sysfile::NS_Active);
- ndbout_c("NR: setLcpActiveStatusEnd - m_participatingLQH");
+ g_eventLogger.info("NR: setLcpActiveStatusEnd - m_participatingLQH");
} else {
- ndbout_c("NR: setLcpActiveStatusEnd - !m_participatingLQH");
+ g_eventLogger.info("NR: setLcpActiveStatusEnd - !m_participatingLQH");
}
}
@@ -14113,8 +14187,8 @@
}
if(arg == DumpStateOrd::EnableUndoDelayDataWrite){
- ndbout << "Dbdih:: delay write of datapages for table = "
- << dumpState->args[1]<< endl;
+ g_eventLogger.info("Dbdih:: delay write of datapages for table = %s",
+ dumpState->args[1]);
// Send this dump to ACC and TUP
EXECUTE_DIRECT(DBACC, GSN_DUMP_STATE_ORD, signal, 2);
EXECUTE_DIRECT(DBTUP, GSN_DUMP_STATE_ORD, signal, 2);
@@ -14131,13 +14205,13 @@
}//if
if (signal->theData[0] == DumpStateOrd::DihMinTimeBetweenLCP) {
// Set time between LCP to min value
- ndbout << "Set time between LCP to min value" << endl;
+ g_eventLogger.info("Set time between LCP to min value");
c_lcpState.clcpDelay = 0; // TimeBetweenLocalCheckpoints.min
return;
}
if (signal->theData[0] == DumpStateOrd::DihMaxTimeBetweenLCP) {
// Set time between LCP to max value
- ndbout << "Set time between LCP to max value" << endl;
+ g_eventLogger.info("Set time between LCP to max value");
c_lcpState.clcpDelay = 31; // TimeBetweenLocalCheckpoints.max
return;
}
@@ -14173,7 +14247,7 @@
{
cgcpDelay = signal->theData[1];
}
- ndbout_c("Setting time between gcp : %d", cgcpDelay);
+ g_eventLogger.info("Setting time between gcp : %d", cgcpDelay);
}
if (arg == 7021 && signal->getLength() == 2)
@@ -14296,7 +14370,7 @@
while(index < count){
if(nodePtr.p->queuedChkpt[index].tableId == tabPtr.i){
jam();
- // ndbout_c("Unqueuing %d", index);
+ // g_eventLogger.info("Unqueuing %d", index);
count--;
for(Uint32 i = index; i<count; i++){
@@ -14336,7 +14410,7 @@
if(checkLcpAllTablesDoneInLqh()){
jam();
- ndbout_c("This is the last table");
+ g_eventLogger.info("This is the last table");
/**
* Then check if saving of tab info is done for all tables
@@ -14345,7 +14419,7 @@
checkLcpCompletedLab(signal);
if(a != c_lcpState.lcpStatus){
- ndbout_c("And all tables are written to already written disk");
+ g_eventLogger.info("And all tables are written to already written disk");
}
}
break;
--- 1.59/storage/ndb/src/kernel/blocks/dblqh/Dblqh.hpp 2007-02-12 08:29:54 +01:00
+++ 1.60/storage/ndb/src/kernel/blocks/dblqh/Dblqh.hpp 2007-03-02 18:44:25 +01:00
@@ -2538,7 +2538,8 @@
void sendAddAttrReq(Signal* signal);
void checkDropTab(Signal*);
Uint32 checkDropTabState(Tablerec::TableStatus, Uint32) const;
-
+
+ void remove_commit_marker(TcConnectionrec * const regTcPtr);
// Initialisation
void initData();
void initRecords();
@@ -2911,6 +2912,7 @@
Uint32 tcNodeId;
union { Uint32 nextPool; Uint32 nextHash; };
Uint32 prevHash;
+ Uint32 reference_count;
inline bool equal(const CommitAckMarker & p) const {
return ((p.transid1 == transid1) && (p.transid2 == transid2));
--- 1.136/storage/ndb/src/kernel/blocks/dblqh/DblqhMain.cpp 2007-02-20 14:56:33 +01:00
+++ 1.137/storage/ndb/src/kernel/blocks/dblqh/DblqhMain.cpp 2007-03-02 18:44:26 +01:00
@@ -582,6 +582,26 @@
{
jamEntry();
m_backup_ptr = RNIL;
+ DefineBackupRef* ref = (DefineBackupRef*)signal->getDataPtrSend();
+ int err_code = 0;
+ char * extra_msg = NULL;
+
+ switch(ref->errorCode){
+ case DefineBackupRef::Undefined:
+ case DefineBackupRef::FailedToSetupFsBuffers:
+ case DefineBackupRef::FailedToAllocateBuffers:
+ case DefineBackupRef::FailedToAllocateTables:
+ case DefineBackupRef::FailedAllocateTableMem:
+ case DefineBackupRef::FailedToAllocateFileRecord:
+ case DefineBackupRef::FailedToAllocateAttributeRecord:
+ case DefineBackupRef::FailedInsertFileHeader:
+ case DefineBackupRef::FailedInsertTableList:
+ jam();
+ err_code = NDBD_EXIT_INVALID_CONFIG;
+ extra_msg = "Probably Backup parameters configuration error, Please consult the
manual";
+ progError(__LINE__, err_code, extra_msg);
+ }
+
sendsttorryLab(signal);
}
@@ -3146,20 +3166,23 @@
{
TcConnectionrec * const regTcPtr = tcConnectptr.p;
if (regTcPtr->operation != ZREAD) {
- if (regTcPtr->opExec != 1) {
- if (saveTupattrbuf(signal, dataPtr, length) == ZOK) {
- ;
- } else {
- jam();
+ if (regTcPtr->operation != ZDELETE)
+ {
+ if (regTcPtr->opExec != 1) {
+ if (saveTupattrbuf(signal, dataPtr, length) == ZOK) {
+ ;
+ } else {
+ jam();
/* ------------------------------------------------------------------------- */
/* WE MIGHT BE WAITING FOR RESPONSE FROM SOME BLOCK HERE. THUS WE NEED TO */
/* GO THROUGH THE STATE MACHINE FOR THE OPERATION. */
/* ------------------------------------------------------------------------- */
- localAbortStateHandlerLab(signal);
- return;
+ localAbortStateHandlerLab(signal);
+ return;
+ }//if
}//if
}//if
- }//if
+ }
c_tup->receive_attrinfo(signal, regTcPtr->tupConnectrec, dataPtr, length);
}//Dblqh::lqhAttrinfoLab()
@@ -5712,6 +5735,8 @@
ptrCheckGuard(nextHashptr, ctcConnectrecFileSize, tcConnectionrec);
nextHashptr.p->prevHashRec = prevHashptr.i;
}//if
+
+ regTcPtr->prevHashRec = regTcPtr->nextHashRec = RNIL;
}//Dblqh::deleteTransidHash()
/* -------------------------------------------------------------------------
@@ -7212,7 +7237,8 @@
TRACE_OP(regTcPtr, "ACC_ABORTCONF");
signal->theData[0] = regTcPtr->tupConnectrec;
EXECUTE_DIRECT(DBTUP, GSN_TUP_ABORTREQ, signal, 1);
-
+
+ jamEntry();
continueAbortLab(signal);
return;
}//Dblqh::execACC_ABORTCONF()
@@ -8340,7 +8366,6 @@
const Uint32 scanLockMode = ScanFragReq::getLockMode(reqinfo);
const Uint8 keyinfo = ScanFragReq::getKeyinfoFlag(reqinfo);
const Uint8 rangeScan = ScanFragReq::getRangeScanFlag(reqinfo);
- const Uint8 tupScan = ScanFragReq::getTupScanFlag(reqinfo);
ptrCheckGuard(tabptr, ctabrecFileSize, tablerec);
if(tabptr.p->tableStatus != Tablerec::TABLE_DEFINED){
@@ -8401,6 +8426,7 @@
ZNIL);
tcConnectptr.p->save1 = 4;
tcConnectptr.p->primKeyLen = keyLen + 4; // hard coded in execKEYINFO
+ tcConnectptr.p->applRef = scanFragReq->resultRef;
errorCode = initScanrec(scanFragReq);
if (errorCode != ZOK) {
jam();
@@ -9829,9 +9855,11 @@
const Uint32 scanOp = scanP->m_curr_batch_size_rows;
const Uint32 nodeId = refToNode(ref);
const bool connectedToNode = getNodeInfo(nodeId).m_connected;
- //const Uint32 type = getNodeInfo(nodeId).m_type;
- //const bool is_api= (type >= NodeInfo::API && type <= NodeInfo::REP);
- //const bool old_dest= (getNodeInfo(nodeId).m_version < MAKE_VERSION(3,5,0));
+#ifdef NOT_USED
+ const Uint32 type = getNodeInfo(nodeId).m_type;
+ const bool is_api= (type >= NodeInfo::API && type <= NodeInfo::REP);
+ const bool old_dest= (getNodeInfo(nodeId).m_version < MAKE_VERSION(3,5,0));
+#endif
const bool longable = true; // TODO is_api && !old_dest;
Uint32 * dst = keyInfo->keyData;
@@ -9932,7 +9960,9 @@
return;
}
ScanFragConf * conf = (ScanFragConf*)&signal->theData[0];
- //NodeId tc_node_id= refToNode(tcConnectptr.p->clientBlockref);
+#ifdef NOT_USED
+ NodeId tc_node_id= refToNode(tcConnectptr.p->clientBlockref);
+#endif
Uint32 trans_id1= tcConnectptr.p->transid[0];
Uint32 trans_id2= tcConnectptr.p->transid[1];
@@ -10077,6 +10107,7 @@
tcConnectptr.p->tcOprec = tcConnectptr.i;
tcConnectptr.p->schemaVersion = scanptr.p->scanSchemaVersion;
tcConnectptr.p->savePointId = gci;
+ tcConnectptr.p->applRef = 0;
scanptr.p->scanState = ScanRecord::WAIT_ACC_COPY;
AccScanReq * req = (AccScanReq*)&signal->theData[0];
req->senderData = scanptr.i;
@@ -15202,8 +15233,6 @@
2.5 TEMPORARY VARIABLES
-----------------------
*/
- UintR tdebug;
-
jamEntry();
//logPagePtr.i = signal->theData[0];
//tdebug = logPagePtr.p->logPageWord[0];
@@ -18377,6 +18406,220 @@
}//if
}//Dblqh::writeNextLog()
+bool
+Dblqh::validate_filter(Signal* signal)
+{
+ Uint32 * start = signal->theData + 1;
+ Uint32 * end = signal->theData + signal->getLength();
+ if (start == end)
+ {
+ infoEvent("No filter specified, not listing...");
+ return false;
+ }
+
+ while(start < end)
+ {
+ switch(* start){
+ case 0: // Table
+ case 1: // API Node
+ case 3: // TC Node
+ start += 2;
+ break;
+ case 2: // Transid
+ start += 3;
+ break;
+ default:
+ infoEvent("Invalid filter op: 0x%x pos: %d",
+ * start,
+ start - (signal->theData + 1));
+ return false;
+ }
+ }
+
+ if (start != end)
+ {
+ infoEvent("Invalid filter, unexpected end");
+ return false;
+ }
+
+ return true;
+}
+
+bool
+Dblqh::match_and_print(Signal* signal, Ptr<TcConnectionrec> tcRec)
+{
+ Uint32 len = signal->getLength();
+ Uint32* start = signal->theData + 3;
+ Uint32* end = signal->theData + len;
+ while (start < end)
+ {
+ switch(* start){
+ case 0:
+ if (tcRec.p->tableref != * (start + 1))
+ return false;
+ start += 2;
+ break;
+ case 1:
+ if (refToNode(tcRec.p->applRef) != * (start + 1))
+ return false;
+ start += 2;
+ break;
+ case 2:
+ if (tcRec.p->transid[0] != * (start + 1) ||
+ tcRec.p->transid[1] != * (start + 2))
+ return false;
+ start += 3;
+ break;
+ case 3:
+ if (refToNode(tcRec.p->tcBlockref) != * (start + 1))
+ return false;
+ start += 2;
+ break;
+ default:
+ ndbassert(false);
+ return false;
+ }
+ }
+
+ if (start != end)
+ {
+ ndbassert(false);
+ return false;
+ }
+
+ /**
+ * Do print
+ */
+ Uint32 *temp = signal->theData + 25;
+ memcpy(temp, signal->theData, 4 * len);
+
+ char state[20];
+ const char* op = "<Unknown>";
+ if (tcRec.p->tcScanRec != RNIL)
+ {
+ ScanRecordPtr sp;
+ sp.i = tcRec.p->tcScanRec;
+ c_scanRecordPool.getPtr(sp);
+
+ if (sp.p->scanLockMode)
+ op = "SCAN-EX";
+ else if(sp.p->scanLockHold)
+ op = "SCAN-SH";
+ else
+ op = "SCAN";
+
+ switch(sp.p->scanState){
+ case ScanRecord::WAIT_NEXT_SCAN:
+ BaseString::snprintf(state, sizeof(state), "WaitNextScan");
+ break;
+ case ScanRecord::IN_QUEUE:
+ BaseString::snprintf(state, sizeof(state), "InQueue");
+ break;
+ case ScanRecord::SCAN_FREE:
+ case ScanRecord::WAIT_STORED_PROC_COPY:
+ case ScanRecord::WAIT_STORED_PROC_SCAN:
+ case ScanRecord::WAIT_NEXT_SCAN_COPY:
+ case ScanRecord::WAIT_DELETE_STORED_PROC_ID_SCAN:
+ case ScanRecord::WAIT_DELETE_STORED_PROC_ID_COPY:
+ case ScanRecord::WAIT_ACC_COPY:
+ case ScanRecord::WAIT_ACC_SCAN:
+ case ScanRecord::WAIT_SCAN_NEXTREQ:
+ case ScanRecord::WAIT_CLOSE_SCAN:
+ case ScanRecord::WAIT_CLOSE_COPY:
+ case ScanRecord::WAIT_RELEASE_LOCK:
+ case ScanRecord::WAIT_TUPKEY_COPY:
+ case ScanRecord::WAIT_LQHKEY_COPY:
+ BaseString::snprintf(state, sizeof(state), "%u", sp.p->scanState);
+ }
+ }
+ else
+ {
+ switch(tcRec.p->operation){
+ case ZREAD:
+ if (tcRec.p->lockType)
+ op = "READ-EX";
+ else if(!tcRec.p->dirtyOp)
+ op = "READ-SH";
+ else
+ op = "READ";
+ break;
+ case ZINSERT: op = "INSERT"; break;
+ case ZUPDATE: op = "UPDATE"; break;
+ case ZDELETE: op = "DELETE"; break;
+ case ZWRITE: op = "WRITE"; break;
+ }
+
+ switch(tcRec.p->transactionState){
+ case TcConnectionrec::IDLE:
+ case TcConnectionrec::WAIT_ACC:
+ BaseString::snprintf(state, sizeof(state), "In lock queue");
+ break;
+ case TcConnectionrec::WAIT_TUPKEYINFO:
+ case TcConnectionrec::WAIT_ATTR:
+ BaseString::snprintf(state, sizeof(state), "WaitData");
+ break;
+ case TcConnectionrec::WAIT_TUP:
+ BaseString::snprintf(state, sizeof(state), "Running");
+ break;
+ case TcConnectionrec::PREPARED:
+ BaseString::snprintf(state, sizeof(state), "Prepared");
+ break;
+ case TcConnectionrec::COMMITTED:
+ BaseString::snprintf(state, sizeof(state), "Committed");
+ break;
+ case TcConnectionrec::STOPPED:
+ case TcConnectionrec::LOG_QUEUED:
+ case TcConnectionrec::LOG_COMMIT_WRITTEN_WAIT_SIGNAL:
+ case TcConnectionrec::LOG_COMMIT_QUEUED_WAIT_SIGNAL:
+ case TcConnectionrec::COMMIT_STOPPED:
+ case TcConnectionrec::LOG_COMMIT_QUEUED:
+ case TcConnectionrec::COMMIT_QUEUED:
+ case TcConnectionrec::WAIT_ACC_ABORT:
+ case TcConnectionrec::ABORT_QUEUED:
+ case TcConnectionrec::ABORT_STOPPED:
+ case TcConnectionrec::WAIT_AI_AFTER_ABORT:
+ case TcConnectionrec::LOG_ABORT_QUEUED:
+ case TcConnectionrec::WAIT_TUP_TO_ABORT:
+ case TcConnectionrec::WAIT_SCAN_AI:
+ case TcConnectionrec::SCAN_STATE_USED:
+ case TcConnectionrec::SCAN_FIRST_STOPPED:
+ case TcConnectionrec::SCAN_CHECK_STOPPED:
+ case TcConnectionrec::SCAN_STOPPED:
+ case TcConnectionrec::SCAN_RELEASE_STOPPED:
+ case TcConnectionrec::SCAN_CLOSE_STOPPED:
+ case TcConnectionrec::COPY_CLOSE_STOPPED:
+ case TcConnectionrec::COPY_FIRST_STOPPED:
+ case TcConnectionrec::COPY_STOPPED:
+ case TcConnectionrec::SCAN_TUPKEY:
+ case TcConnectionrec::COPY_TUPKEY:
+ case TcConnectionrec::TC_NOT_CONNECTED:
+ case TcConnectionrec::PREPARED_RECEIVED_COMMIT:
+ case TcConnectionrec::LOG_COMMIT_WRITTEN:
+ BaseString::snprintf(state, sizeof(state), "%u",
+ tcRec.p->transactionState);
+ }
+ }
+
+ char buf[100];
+ BaseString::snprintf(buf, sizeof(buf),
+ "OP[%u]: Tab: %d frag: %d TC: %u API: %d(0x%x)"
+ "transid: 0x%x 0x%x op: %s state: %s",
+ tcRec.i,
+ tcRec.p->tableref,
+ tcRec.p->fragmentid,
+ refToNode(tcRec.p->tcBlockref),
+ refToNode(tcRec.p->applRef),
+ refToBlock(tcRec.p->applRef),
+ tcRec.p->transid[0], tcRec.p->transid[1],
+ op,
+ state);
+
+ infoEvent(buf);
+
+ memcpy(signal->theData, temp, 4*len);
+ return true;
+}
+
void
Dblqh::execDUMP_STATE_ORD(Signal* signal)
{
@@ -18477,7 +18720,7 @@
ScanRecordPtr sp;
sp.i = recordNo;
- c_scanRecordPool.getPtr(scanptr);
+ c_scanRecordPool.getPtr(sp);
if (sp.p->scanState != ScanRecord::SCAN_FREE){
dumpState->args[0] = DumpStateOrd::LqhDumpOneScanRec;
dumpState->args[1] = recordNo;
@@ -18836,6 +19079,183 @@
}
#endif
+ if (arg == 2350)
+ {
+ jam();
+ Uint32 len = signal->getLength() - 1;
+ if (len + 3 > 25)
+ {
+ jam();
+ infoEvent("Too long filter");
+ return;
+ }
+ if (validate_filter(signal))
+ {
+ jam();
+ memmove(signal->theData + 3, signal->theData + 1, 4 * len);
+ signal->theData[0] = 2351;
+ signal->theData[1] = 0; // Bucket
+ signal->theData[2] = RNIL; // Record
+ sendSignal(reference(), GSN_DUMP_STATE_ORD, signal, len + 3, JBB);
+
+ infoEvent("Starting dump of operations");
+ }
+ return;
+ }
+
+ if (arg == 2351)
+ {
+ jam();
+ Uint32 bucket = signal->theData[1];
+ Uint32 record = signal->theData[2];
+ Uint32 len = signal->getLength();
+ TcConnectionrecPtr tcRec;
+ if (record != RNIL)
+ {
+ jam();
+ /**
+ * Check that record is still in use...
+ */
+ tcRec.i = record;
+ ptrCheckGuard(tcRec, ttcConnectrecFileSize, regTcConnectionrec);
+
+ Uint32 hashIndex = (tcRec.p->transid[0] ^ tcRec.p->tcOprec) & 1023;
+ if (hashIndex != bucket)
+ {
+ jam();
+ record = RNIL;
+ }
+ else
+ {
+ jam();
+ if (tcRec.p->nextHashRec == RNIL &&
+ tcRec.p->prevHashRec == RNIL &&
+ ctransidHash[hashIndex] != record)
+ {
+ jam();
+ record = RNIL;
+ }
+ }
+
+ if (record == RNIL)
+ {
+ jam();
+ signal->theData[2] = RNIL;
+ sendSignal(reference(), GSN_DUMP_STATE_ORD, signal,
+ signal->getLength(), JBB);
+ return;
+ }
+ }
+ else if ((record = ctransidHash[bucket]) == RNIL)
+ {
+ jam();
+ bucket++;
+ if (bucket < 1024)
+ {
+ jam();
+ signal->theData[1] = bucket;
+ signal->theData[2] = RNIL;
+ sendSignal(reference(), GSN_DUMP_STATE_ORD, signal,
+ signal->getLength(), JBB);
+ }
+ else
+ {
+ jam();
+ infoEvent("End of operation dump");
+ }
+
+ return;
+ }
+ else
+ {
+ jam();
+ tcRec.i = record;
+ ptrCheckGuard(tcRec, ttcConnectrecFileSize, regTcConnectionrec);
+ }
+
+ for (Uint32 i = 0; i<32; i++)
+ {
+ jam();
+ bool print = match_and_print(signal, tcRec);
+
+ tcRec.i = tcRec.p->nextHashRec;
+ if (tcRec.i == RNIL || print)
+ {
+ jam();
+ break;
+ }
+
+ ptrCheckGuard(tcRec, ttcConnectrecFileSize, regTcConnectionrec);
+ }
+
+ if (tcRec.i == RNIL)
+ {
+ jam();
+ bucket++;
+ if (bucket < 1024)
+ {
+ jam();
+ signal->theData[1] = bucket;
+ signal->theData[2] = RNIL;
+ sendSignal(reference(), GSN_DUMP_STATE_ORD, signal, len, JBB);
+ }
+ else
+ {
+ jam();
+ infoEvent("End of operation dump");
+ }
+
+ return;
+ }
+ else
+ {
+ jam();
+ signal->theData[2] = tcRec.i;
+ sendSignalWithDelay(reference(), GSN_DUMP_STATE_ORD, signal, 200, len);
+ return;
+ }
+ }
+
+ if (arg == 2352 && signal->getLength() == 2)
+ {
+ jam();
+ Uint32 i;
+ Uint32 opNo = signal->theData[1];
+ TcConnectionrecPtr tcRec;
+ if (opNo < ttcConnectrecFileSize)
+ {
+ jam();
+ tcRec.i = opNo;
+ ptrCheckGuard(tcRec, ttcConnectrecFileSize, regTcConnectionrec);
+
+ Uint32 keyLen = tcRec.p->primKeyLen;
+ BaseString key;
+ for(i = 0; i<keyLen && i < 4; i++)
+ {
+ jam();
+ key.appfmt("0x%x ", tcRec.p->tupkeyData[i]);
+ }
+
+ if (keyLen > 4)
+ {
+ jam();
+ tcConnectptr = tcRec;
+ sendKeyinfoAcc(signal, 4);
+ for (i = 4; i<keyLen; i++)
+ {
+ jam();
+ key.appfmt("0x%x ", signal->theData[i]);
+ }
+ }
+
+ char buf[100];
+ BaseString::snprintf(buf, sizeof(buf),
+ "OP[%u]: transid: 0x%x 0x%x key: %s",
+ tcRec.i,
+ tcRec.p->transid[0], tcRec.p->transid[1], key.c_str());
+ infoEvent(buf);
+ }
+ }
}//Dblqh::execDUMP_STATE_ORD()
void Dblqh::execSET_VAR_REQ(Signal* signal)
--- 1.48/storage/ndb/src/kernel/blocks/dbtc/Dbtc.hpp 2007-02-12 08:29:55 +01:00
+++ 1.49/storage/ndb/src/kernel/blocks/dbtc/Dbtc.hpp 2007-03-02 18:44:26 +01:00
@@ -626,7 +626,7 @@
ApiConnectRecord(ArrayPool<TcFiredTriggerData> & firedTriggerPool,
ArrayPool<TcIndexOperation> & seizedIndexOpPool):
theFiredTriggers(firedTriggerPool),
- isIndexOp(false),
+ isIndexOp(FALSE),
theSeizedIndexOperations(seizedIndexOpPool)
{}
@@ -636,7 +636,6 @@
ConnectionState apiConnectstate;
UintR transid[2];
UintR firstTcConnect;
- NdbNodeBitmask m_transaction_nodes;
//---------------------------------------------------
// Second 16 byte cache line. Hot variables.
@@ -672,26 +671,39 @@
//---------------------------------------------------
UintR lastTcConnect;
UintR lqhkeyreqrec;
- AbortState abortState;
Uint32 buddyPtr;
+ union {
+ UintR apiScanRec;
+ UintR commitAckMarker;
+ };
+
+ Uint32 no_commit_ack_markers;
+ ReturnSignal returnsignal;
+ AbortState abortState;
+ Uint8 indexOpReturn;
+ Uint8 triggerPending; // Used to mark waiting for a CONTINUEB
+
Uint8 m_exec_flag;
- Uint8 unused2;
+ Uint8 isIndexOp; // Used to mark on-going TcKeyReq as indx table access
Uint8 takeOverRec;
Uint8 currentReplicaNo;
+ Uint8 m_commit_ack_marker_received;
+
+ Uint8 tckeyrec; // Ändrad från R
+ Uint8 tcindxrec;
+ Uint8 apiFailState; // Ändrad från R
+ Uint8 timeOutCounter;
+ Uint16 returncode;
+ Uint16 takeOverInd;
//---------------------------------------------------
// Error Handling variables. If cache line 32 bytes
// ensures that cache line is still only read in
// early phases.
//---------------------------------------------------
- union {
- UintR apiScanRec;
- UintR commitAckMarker;
- };
UintR currentTcConnect;
BlockReference tcBlockref;
- Uint16 returncode;
- Uint16 takeOverInd;
+ UintR failureNr;
//---------------------------------------------------
// Second 64 byte cache line. Third 16 byte cache line
@@ -706,14 +718,8 @@
// timeOutCounter is used waiting for ABORTCONF, COMMITCONF
// and COMPLETECONF
//---------------------------------------------------
- UintR failureNr;
- Uint8 tckeyrec; // Ändrad från R
- Uint8 tcindxrec;
- Uint8 apiFailState; // Ändrad från R
- ReturnSignal returnsignal;
- Uint8 timeOutCounter;
-
UintR tcSendArray[6];
+ NdbNodeBitmask m_transaction_nodes;
// Trigger data
@@ -722,12 +728,9 @@
*/
DLFifoList<TcFiredTriggerData> theFiredTriggers;
- bool triggerPending; // Used to mark waiting for a CONTINUEB
// Index data
- Uint8 isIndexOp; // Used to mark on-going TcKeyReq as indx table access
- bool indexOpReturn;
UintR noIndexOp; // No outstanding index ops
// Index op return context
@@ -1818,8 +1821,7 @@
Uint32 prevHash;
Uint32 apiConnectPtr;
Uint16 apiNodeId;
- Uint16 noOfLqhs;
- Uint16 lqhNodeId[MAX_REPLICAS];
+ NdbNodeBitmask m_commit_ack_marker_nodes;
inline bool equal(const CommitAckMarker & p) const {
return ((p.transid1 == transid1) && (p.transid2 == transid2));
--- 1.20/storage/ndb/src/kernel/blocks/dbtc/DbtcInit.cpp 2007-01-31 08:32:12 +01:00
+++ 1.21/storage/ndb/src/kernel/blocks/dbtc/DbtcInit.cpp 2007-03-02 18:44:26 +01:00
@@ -113,8 +113,8 @@
sizeof(TcConnectRecord),
ctcConnectFilesize);
- m_commitAckMarkerPool.setSize(capiConnectFilesize);
- m_commitAckMarkerHash.setSize(512);
+ m_commitAckMarkerPool.setSize(2 * capiConnectFilesize);
+ m_commitAckMarkerHash.setSize(1024);
hostRecord = (HostRecord*)allocRecord("HostRecord",
sizeof(HostRecord),
--- 1.136/storage/ndb/src/kernel/blocks/dbtc/DbtcMain.cpp 2007-02-12 08:29:55 +01:00
+++ 1.137/storage/ndb/src/kernel/blocks/dbtc/DbtcMain.cpp 2007-03-02 18:44:27 +01:00
@@ -21,6 +21,7 @@
#include <ndb_limits.h>
#include <my_sys.h>
+#include <signaldata/DiGetNodes.hpp>
#include <signaldata/EventReport.hpp>
#include <signaldata/TcKeyReq.hpp>
#include <signaldata/TcKeyConf.hpp>
@@ -282,7 +283,7 @@
ApiConnectRecordPtr transPtr;
transPtr.i = Tdata0;
ptrCheckGuard(transPtr, capiConnectFilesize, apiConnectRecord);
- transPtr.p->triggerPending = false;
+ transPtr.p->triggerPending = FALSE;
executeTriggers(signal, &transPtr);
return;
case TcContinueB::DelayTCKEYCONF:
@@ -2371,6 +2372,8 @@
regApiPtr->lqhkeyreqrec = 0;
regApiPtr->tckeyrec = 0;
regApiPtr->tcindxrec = 0;
+ regApiPtr->m_commit_ack_marker_received = 0;
+ regApiPtr->no_commit_ack_markers = 0;
regApiPtr->failureNr = TfailureNr;
regApiPtr->transid[0] = Ttransid0;
regApiPtr->transid[1] = Ttransid1;
@@ -2381,7 +2384,7 @@
// Trigger data
releaseFiredTriggerData(®ApiPtr->theFiredTriggers),
// Index data
- regApiPtr->indexOpReturn = false;
+ regApiPtr->indexOpReturn = FALSE;
regApiPtr->noIndexOp = 0;
if(releaseIndexOperations)
releaseAllSeizedIndexOperations(regApiPtr);
@@ -2428,7 +2431,7 @@
regTcPtr->noReceivedTriggers = 0;
regTcPtr->triggerExecutionCount = 0;
regTcPtr->triggeringOperation = RNIL;
- regTcPtr->isIndexOp = false;
+ regTcPtr->isIndexOp = FALSE;
regTcPtr->indexOp = RNIL;
regTcPtr->currentIndexId = RNIL;
@@ -2528,7 +2531,7 @@
Uint8 isIndexOp = regApiPtr->isIndexOp;
bool isIndexOpReturn = regApiPtr->indexOpReturn;
- regApiPtr->isIndexOp = false; // Reset marker
+ regApiPtr->isIndexOp = FALSE; // Reset marker
regApiPtr->m_exec_flag |= TexecFlag;
switch (regApiPtr->apiConnectstate) {
case CS_CONNECTED:{
@@ -2810,29 +2813,38 @@
Uint32 TreadCount = c_counters.creadCount;
jam();
c_counters.creadCount = TreadCount + 1;
- } else {
- if(regApiPtr->commitAckMarker == RNIL){
- jam();
- CommitAckMarkerPtr tmp;
- if(!m_commitAckMarkerHash.seize(tmp)){
- TCKEY_abort(signal, 56);
- return;
- } else {
- regTcPtr->commitAckMarker = tmp.i;
- regApiPtr->commitAckMarker = tmp.i;
- tmp.p->transid1 = tcKeyReq->transId1;
- tmp.p->transid2 = tcKeyReq->transId2;
- tmp.p->apiNodeId = refToNode(regApiPtr->ndbapiBlockref);
- tmp.p->apiConnectPtr = TapiIndex;
- tmp.p->noOfLqhs = 0;
+ }
+ else
+ {
+ if (!regApiPtr->m_commit_ack_marker_received)
+ {
+ if(regApiPtr->commitAckMarker == RNIL)
+ {
+ jam();
+ CommitAckMarkerPtr tmp;
+ if(!m_commitAckMarkerHash.seize(tmp)){
+ TCKEY_abort(signal, 56);
+ return;
+ } else {
+ regTcPtr->commitAckMarker = tmp.i;
+ regApiPtr->commitAckMarker = tmp.i;
+ tmp.p->transid1 = tcKeyReq->transId1;
+ tmp.p->transid2 = tcKeyReq->transId2;
+ tmp.p->apiNodeId = refToNode(regApiPtr->ndbapiBlockref);
+ tmp.p->apiConnectPtr = TapiIndex;
+ tmp.p->m_commit_ack_marker_nodes.clear();
#if defined VM_TRACE || defined ERROR_INSERT
- {
- CommitAckMarkerPtr check;
- ndbrequire(!m_commitAckMarkerHash.find(check, *tmp.p));
- }
+ {
+ CommitAckMarkerPtr check;
+ ndbrequire(!m_commitAckMarkerHash.find(check, *tmp.p));
+ }
#endif
- m_commitAckMarkerHash.add(tmp);
+ m_commitAckMarkerHash.add(tmp);
+ }
}
+ else
+ regTcPtr->commitAckMarker = regApiPtr->commitAckMarker;
+ regApiPtr->no_commit_ack_markers++;
}
UintR TwriteCount = c_counters.cwriteCount;
@@ -2856,8 +2868,8 @@
default:
TCKEY_abort(signal, 9);
return;
- }//switch
- }//if
+ }
+ }
Uint32 TabortOption = TcKeyReq::getAbortOption(Treqinfo);
regTcPtr->m_execAbortOption = TabortOption;
@@ -2938,12 +2950,6 @@
hash(signal); /* NOW IT IS TIME TO CALCULATE THE HASH VALUE*/
- if (unlikely(terrorCode))
- {
- releaseAtErrorLab(signal);
- return;
- }
-
CacheRecord * const regCachePtr = cachePtr.p;
TcConnectRecord * const regTcPtr = tcConnectptr.p;
ApiConnectRecord * const regApiPtr = apiConnectptr.p;
@@ -2951,7 +2957,6 @@
UintR TtcTimer = ctcTimer;
UintR ThashValue = thashValue;
UintR TdistrHashValue = tdistrHashValue;
- UintR TdihConnectptr = regTcPtr->dihConnectptr;
UintR Ttableref = regCachePtr->tableref;
TableRecordPtr localTabptr;
@@ -2969,13 +2974,10 @@
setApiConTimer(apiConnectptr.i, TtcTimer, __LINE__);
regCachePtr->hashValue = ThashValue;
- signal->theData[0] = TdihConnectptr;
- signal->theData[1] = Ttableref;
- signal->theData[2] = TdistrHashValue;
- signal->theData[3] = 0;
- signal->theData[4] = 0;
- signal->theData[5] = 0;
- signal->theData[6] = 0;
+ DiGetNodesReq * const req = (DiGetNodesReq *)&signal->theData[0];
+ req->tableId = Ttableref;
+ req->hashValue = TdistrHashValue;
+ req->distr_key_indicator = regCachePtr->distributionKeyIndicator;
/*-------------------------------------------------------------*/
/* FOR EFFICIENCY REASONS WE AVOID THE SIGNAL SENDING HERE AND */
@@ -2985,7 +2987,8 @@
/* TO DIH IN TRAFFIC IT SHOULD BE OK (3% OF THE EXECUTION TIME */
/* IS SPENT IN DIH AND EVEN LESS IN REPLICATED NDB. */
/*-------------------------------------------------------------*/
- EXECUTE_DIRECT(DBDIH, GSN_DIGETNODESREQ, signal, 3);
+ EXECUTE_DIRECT(DBDIH, GSN_DIGETNODESREQ, signal,
+ DiGetNodesReq::SignalLength);
UintR TerrorIndicator = signal->theData[0];
jamEntry();
if (TerrorIndicator != 0) {
@@ -3005,12 +3008,13 @@
/* DIGETNODESCONF >*/
/* ***************>*/
- UintR Tdata1 = signal->theData[1];
- UintR Tdata2 = signal->theData[2];
- UintR Tdata3 = signal->theData[3];
- UintR Tdata4 = signal->theData[4];
- UintR Tdata5 = signal->theData[5];
- UintR Tdata6 = signal->theData[6];
+ const DiGetNodesConf * const conf = (DiGetNodesConf *)&signal->theData[0];
+ UintR Tdata1 = conf->fragId;
+ UintR Tdata2 = conf->reqinfo;
+ UintR Tdata3 = conf->nodes[0];
+ UintR Tdata4 = conf->nodes[1];
+ UintR Tdata5 = conf->nodes[2];
+ UintR Tdata6 = conf->nodes[3];
regCachePtr->fragmentid = Tdata1;
tnodeinfo = Tdata2;
@@ -3138,6 +3142,7 @@
UintR Tkeylen = regCachePtr->keylen;
UintR TfirstAttrbuf = regCachePtr->firstAttrbuf;
sendlqhkeyreq(signal, TBRef);
+ jam();
if (Tkeylen > 4) {
packKeyData000Lab(signal, TBRef, Tkeylen - 4);
releaseKeys();
@@ -3145,6 +3150,7 @@
packLqhkeyreq040Lab(signal,
TfirstAttrbuf,
TBRef);
+ jam();
}//Dbtc::packLqhkeyreq()
void Dbtc::sendlqhkeyreq(Signal* signal,
@@ -3226,22 +3232,7 @@
* Bit 28 == 0 since readLenAi can only be set after reading in LQH.
* ----------------------------------------------------------------------- */
//LqhKeyReq::setAPIVersion(Tdata10, regCachePtr->apiVersionNo);
- Uint32 commitAckMarker = regTcPtr->commitAckMarker;
- const Uint32 noOfLqhs = regTcPtr->noOfNodes;
- if(commitAckMarker != RNIL){
- jam();
- LqhKeyReq::setMarkerFlag(Tdata10, 1);
-
- CommitAckMarker * tmp = m_commitAckMarkerHash.getPtr(commitAckMarker);
-
- /**
- * Populate LQH array
- */
- tmp->noOfLqhs = noOfLqhs;
- for(Uint32 i = 0; i<noOfLqhs; i++){
- tmp->lqhNodeId[i] = regTcPtr->tcNodedata[i];
- }
- }
+ LqhKeyReq::setMarkerFlag(Tdata10, regTcPtr->commitAckMarker != RNIL ? 1 : 0);
/* ************************************************************> */
/* NO READ LENGTH SENT FROM TC. SEQUENTIAL NUMBER IS 1 AND IT */
@@ -3365,6 +3356,7 @@
UintR TattrbufFilesize = cattrbufFilesize;
AttrbufRecord *localAttrbufRecord = attrbufRecord;
while (1) {
+ jam();
if (anAttrBufIndex == RNIL) {
UintR TtcTimer = ctcTimer;
UintR Tread = (regTcPtr->operation == ZREAD);
@@ -3385,6 +3377,7 @@
return;
}//if
if (anAttrBufIndex < TattrbufFilesize) {
+ jam();
AttrbufRecord * const regAttrPtr = &localAttrbufRecord[anAttrBufIndex];
anAttrBufIndex = regAttrPtr->attrbuf[ZINBUF_NEXT];
sendAttrinfo(signal,
@@ -3526,7 +3519,7 @@
regTcPtr->tcConnectstate = OS_CONNECTED;
regTcPtr->nextTcConnect = TfirstfreeTcConnect;
regTcPtr->apiConnect = RNIL;
- regTcPtr->isIndexOp = false;
+ regTcPtr->isIndexOp = FALSE;
regTcPtr->indexOp = RNIL;
cfirstfreeTcConnect = TtcConnectptrIndex;
c_counters.cconcurrentOp = TconcurrentOp - 1;
@@ -3728,8 +3721,20 @@
return;
}//if
+ Uint32 commitAckMarker = regTcPtr->commitAckMarker;
setApiConTimer(apiConnectptr.i, TtcTimer, __LINE__);
+ if(commitAckMarker != RNIL){
+ const Uint32 noOfLqhs = regTcPtr->noOfNodes;
+ CommitAckMarker * tmp = m_commitAckMarkerHash.getPtr(commitAckMarker);
+ jam();
+ regApiPtr->m_commit_ack_marker_received = TRUE;
+ /**
+ * Populate LQH array
+ */
+ for(Uint32 i = 0; i<noOfLqhs; i++)
+ tmp->m_commit_ack_marker_nodes.set(regTcPtr->tcNodedata[i]);
+ }
if (regTcPtr->isIndexOp) {
jam();
// This was an internal TCKEYREQ
@@ -3812,7 +3817,7 @@
void Dbtc::setupIndexOpReturn(ApiConnectRecord* regApiPtr,
TcConnectRecord* regTcPtr)
{
- regApiPtr->indexOpReturn = true;
+ regApiPtr->indexOpReturn = TRUE;
regApiPtr->indexOp = regTcPtr->indexOp;
regApiPtr->clientData = regTcPtr->clientData;
regApiPtr->attrInfoLen = regTcPtr->attrInfoLen;
@@ -3957,7 +3962,7 @@
tcKeyConf->operations[0].attrInfoLen = regApiPtr->attrInfoLen;
Uint32 sigLen = TcKeyConf::StaticLength + TcKeyConf::OperationLength;
EXECUTE_DIRECT(DBTC, GSN_TCKEYCONF, signal, sigLen);
- regApiPtr->indexOpReturn = false;
+ regApiPtr->indexOpReturn = FALSE;
if (TopWords == 0) {
jam();
return; // No queued TcKeyConf
@@ -4213,8 +4218,8 @@
cfirstfreeApiConnectCopy = locApiConnectptr.p->nextApiConnect;
locApiConnectptr.p->nextApiConnect = RNIL;
regApiPtr->apiCopyRecord = locApiConnectptr.i;
- regApiPtr->triggerPending = false;
- regApiPtr->isIndexOp = false;
+ regApiPtr->triggerPending = FALSE;
+ regApiPtr->isIndexOp = FALSE;
}//Dbtc::seizeApiConnectCopy()
void Dbtc::execDIVERIFYCONF(Signal* signal)
@@ -4816,16 +4821,17 @@
}
void
-Dbtc::sendRemoveMarkers(Signal* signal, const CommitAckMarker * marker){
+Dbtc::sendRemoveMarkers(Signal* signal, const CommitAckMarker * marker)
+{
jam();
- const Uint32 noOfLqhs = marker->noOfLqhs;
const Uint32 transId1 = marker->transid1;
const Uint32 transId2 = marker->transid2;
- for(Uint32 i = 0; i<noOfLqhs; i++){
+ for(Uint32 node_id = 1; node_id < MAX_NDB_NODES; node_id++)
+ {
jam();
- const NodeId nodeId = marker->lqhNodeId[i];
- sendRemoveMarker(signal, nodeId, transId1, transId2);
+ if (marker->m_commit_ack_marker_nodes.get(node_id))
+ sendRemoveMarker(signal, node_id, transId1, transId2);
}
}
@@ -5127,7 +5133,6 @@
}
}
- Uint32 marker = regTcPtr->commitAckMarker;
markOperationAborted(regApiPtr, regTcPtr);
if(regApiPtr->apiConnectstate == CS_ABORTING){
@@ -5147,16 +5152,6 @@
return;
}//if
- if (marker != RNIL){
- /**
- * This was an insert/update/delete/write which failed
- * that contained the marker
- * Currently unsupported to place new marker
- */
- TCKEY_abort(signal, 49);
- return;
- }
-
/* Only ref in certain situations */
{
const Uint32 opType = regTcPtr->operation;
@@ -5240,13 +5235,18 @@
const Uint32 commitAckMarker = regTcPtr->commitAckMarker;
if (regApiPtr->commitAckMarker == RNIL)
ndbassert(commitAckMarker == RNIL);
- if (commitAckMarker != RNIL)
- ndbassert(regApiPtr->commitAckMarker != RNIL);
if(commitAckMarker != RNIL){
jam();
- m_commitAckMarkerHash.release(commitAckMarker);
+ ndbassert(regApiPtr->commitAckMarker != RNIL);
+ ndbrequire(regApiPtr->no_commit_ack_markers > 0);
+ regApiPtr->no_commit_ack_markers--;
regTcPtr->commitAckMarker = RNIL;
- regApiPtr->commitAckMarker = RNIL;
+ if (regApiPtr->no_commit_ack_markers == 0)
+ {
+ regApiPtr->commitAckMarker = RNIL;
+ regApiPtr->m_commit_ack_marker_received = FALSE;
+ m_commitAckMarkerHash.release(commitAckMarker);
+ }
}
}
@@ -7756,12 +7756,7 @@
const Uint32 marker = apiConnectptr.p->commitAckMarker;
if(marker != RNIL){
jam();
-
- CommitAckMarkerPtr tmp;
- tmp.i = marker;
- tmp.p = m_commitAckMarkerHash.getPtr(tmp.i);
-
- m_commitAckMarkerHash.release(tmp);
+ m_commitAckMarkerHash.release(marker);
apiConnectptr.p->commitAckMarker = RNIL;
}
@@ -8214,8 +8209,7 @@
tmp.p->transid1 = ttransid1;
tmp.p->transid2 = ttransid2;
tmp.p->apiNodeId = refToNode(tapplRef);
- tmp.p->noOfLqhs = 1;
- tmp.p->lqhNodeId[0] = tnodeid;
+ tmp.p->m_commit_ack_marker_nodes.set(tnodeid);
tmp.p->apiConnectPtr = apiConnectptr.i;
#if defined VM_TRACE || defined ERROR_INSERT
@@ -8363,13 +8357,14 @@
/*----------------------------------------------------------*/
void Dbtc::updateApiStateFail(Signal* signal)
{
- if(LqhTransConf::getMarkerFlag(treqinfo)){
- jam();
+ if(LqhTransConf::getMarkerFlag(treqinfo))
+ {
+ CommitAckMarkerPtr tmp;
const Uint32 marker = apiConnectptr.p->commitAckMarker;
- if(marker == RNIL){
+ if(marker == RNIL)
+ {
jam();
- CommitAckMarkerPtr tmp;
m_commitAckMarkerHash.seize(tmp);
ndbrequire(tmp.i != RNIL);
@@ -8377,8 +8372,6 @@
tmp.p->transid1 = ttransid1;
tmp.p->transid2 = ttransid2;
tmp.p->apiNodeId = refToNode(tapplRef);
- tmp.p->noOfLqhs = 1;
- tmp.p->lqhNodeId[0] = tnodeid;
tmp.p->apiConnectPtr = apiConnectptr.i;
#if defined VM_TRACE || defined ERROR_INSERT
{
@@ -8389,16 +8382,10 @@
m_commitAckMarkerHash.add(tmp);
} else {
jam();
-
- CommitAckMarkerPtr tmp;
tmp.i = marker;
tmp.p = m_commitAckMarkerHash.getPtr(marker);
-
- const Uint32 noOfLqhs = tmp.p->noOfLqhs;
- ndbrequire(noOfLqhs < MAX_REPLICAS);
- tmp.p->lqhNodeId[noOfLqhs] = tnodeid;
- tmp.p->noOfLqhs = (noOfLqhs + 1);
}
+ tmp.p->m_commit_ack_marker_nodes.set(tnodeid);
}
switch (ttransStatus) {
@@ -9052,10 +9039,13 @@
}
else
{
- signal->theData[0] = tcConnectptr.p->dihConnectptr;
- signal->theData[1] = tabPtr.i;
- signal->theData[2] = cachePtr.p->distributionKey;
- EXECUTE_DIRECT(DBDIH, GSN_DIGETNODESREQ, signal, 3);
+ DiGetNodesReq * const req = (DiGetNodesReq *)&signal->theData[0];
+ const DiGetNodesConf * const get_conf = (DiGetNodesConf *)&signal->theData[0];
+ req->tableId = tabPtr.i;
+ req->hashValue = cachePtr.p->distributionKey;
+ req->distr_key_indicator = TRUE;
+ EXECUTE_DIRECT(DBDIH, GSN_DIGETNODESREQ, signal,
+ DiGetNodesReq::SignalLength);
UintR TerrorIndicator = signal->theData[0];
jamEntry();
if (TerrorIndicator != 0) {
@@ -9066,8 +9056,7 @@
return;
}
- UintR Tdata1 = signal->theData[1];
- scanptr.p->scanNextFragId = Tdata1;
+ scanptr.p->scanNextFragId = get_conf->fragId;
DihFragCountConf * const conf = (DihFragCountConf*)signal->getDataPtr();
conf->m_connectionData = tcConnectptr.i;
conf->m_fragmentCount = 1; // Frag count
@@ -10078,8 +10067,8 @@
apiConnectptr.p->commitAckMarker = RNIL;
apiConnectptr.p->firstTcConnect = RNIL;
apiConnectptr.p->lastTcConnect = RNIL;
- apiConnectptr.p->triggerPending = false;
- apiConnectptr.p->isIndexOp = false;
+ apiConnectptr.p->triggerPending = FALSE;
+ apiConnectptr.p->isIndexOp = FALSE;
apiConnectptr.p->accumulatingIndexOp = RNIL;
apiConnectptr.p->executingIndexOp = RNIL;
apiConnectptr.p->buddyPtr = RNIL;
@@ -10106,8 +10095,8 @@
apiConnectptr.p->commitAckMarker = RNIL;
apiConnectptr.p->firstTcConnect = RNIL;
apiConnectptr.p->lastTcConnect = RNIL;
- apiConnectptr.p->triggerPending = false;
- apiConnectptr.p->isIndexOp = false;
+ apiConnectptr.p->triggerPending = FALSE;
+ apiConnectptr.p->isIndexOp = FALSE;
apiConnectptr.p->accumulatingIndexOp = RNIL;
apiConnectptr.p->executingIndexOp = RNIL;
apiConnectptr.p->buddyPtr = RNIL;
@@ -10134,8 +10123,8 @@
apiConnectptr.p->commitAckMarker = RNIL;
apiConnectptr.p->firstTcConnect = RNIL;
apiConnectptr.p->lastTcConnect = RNIL;
- apiConnectptr.p->triggerPending = false;
- apiConnectptr.p->isIndexOp = false;
+ apiConnectptr.p->triggerPending = FALSE;
+ apiConnectptr.p->isIndexOp = FALSE;
apiConnectptr.p->accumulatingIndexOp = RNIL;
apiConnectptr.p->executingIndexOp = RNIL;
apiConnectptr.p->buddyPtr = RNIL;
@@ -10590,8 +10579,8 @@
apiConnectptr.p->nextApiConnect = RNIL;
setApiConTimer(apiConnectptr.i, 0, __LINE__);
apiConnectptr.p->apiConnectstate = CS_CONNECTED; /* STATE OF CONNECTION */
- apiConnectptr.p->triggerPending = false;
- apiConnectptr.p->isIndexOp = false;
+ apiConnectptr.p->triggerPending = FALSE;
+ apiConnectptr.p->isIndexOp = FALSE;
} else {
jam();
terrorCode = ZNO_FREE_API_CONNECTION;
@@ -10619,7 +10608,7 @@
ptrCheckGuard(tcConnectptr, ctcConnectFilesize, tcConnectRecord);
cfirstfreeTcConnect = tcConnectptr.p->nextTcConnect;
c_counters.cconcurrentOp++;
- tcConnectptr.p->isIndexOp = false;
+ tcConnectptr.p->isIndexOp = FALSE;
}//Dbtc::seizeTcConnect()
void Dbtc::seizeTcConnectFail(Signal* signal)
@@ -10789,16 +10778,15 @@
for(m_commitAckMarkerHash.first(iter); iter.curr.i != RNIL;
m_commitAckMarkerHash.next(iter)){
infoEvent("CommitAckMarker: i = %d (0x%x, 0x%x)"
- " Api: %d Lghs(%d): %d %d %d %d bucket = %d",
+ " Api: %d %x %x %x %x bucket = %d",
iter.curr.i,
iter.curr.p->transid1,
iter.curr.p->transid2,
iter.curr.p->apiNodeId,
- iter.curr.p->noOfLqhs,
- iter.curr.p->lqhNodeId[0],
- iter.curr.p->lqhNodeId[1],
- iter.curr.p->lqhNodeId[2],
- iter.curr.p->lqhNodeId[3],
+ iter.curr.p->m_commit_ack_marker_nodes.getWord(0),
+ iter.curr.p->m_commit_ack_marker_nodes.getWord(1),
+ iter.curr.p->m_commit_ack_marker_nodes.getWord(2),
+ iter.curr.p->m_commit_ack_marker_nodes.getWord(3),
iter.bucket);
}
}
@@ -12899,7 +12887,7 @@
jam();
if (!regApiPtr->triggerPending) {
jam();
- regApiPtr->triggerPending = true;
+ regApiPtr->triggerPending = TRUE;
signal->theData[0] = TcContinueB::TRIGGER_PENDING;
signal->theData[1] = transPtr->i;
sendSignal(reference(), GSN_CONTINUEB, signal, 3, JBB);
--- 1.18/storage/ndb/src/kernel/blocks/qmgr/Qmgr.hpp 2007-02-06 09:16:26 +01:00
+++ 1.19/storage/ndb/src/kernel/blocks/qmgr/Qmgr.hpp 2007-03-02 18:44:27 +01:00
@@ -105,6 +105,7 @@
};
struct StartRecord {
+ StartRecord() {}
void reset(){
m_startKey++;
m_startNode = 0;
@@ -128,6 +129,7 @@
Uint32 m_president_candidate_gci;
Uint16 m_regReqReqSent;
Uint16 m_regReqReqRecv;
+ Uint32 m_node_gci[MAX_NDB_NODES];
} c_start;
NdbNodeBitmask c_definedNodes; // DB nodes in config
@@ -173,6 +175,7 @@
};
struct ArbitRec {
+ ArbitRec() {}
ArbitState state; // state
bool newstate; // flag to initialize new state
unsigned thread; // identifies a continueB "thread"
@@ -182,6 +185,7 @@
NdbNodeBitmask newMask; // new nodes to process in RUN state
Uint8 sendCount; // control send/recv of signals
Uint8 recvCount;
+ Uint8 m_disabled;
NdbNodeBitmask recvMask; // left to recv
Uint32 code; // code field from signal
Uint32 failureNr; // cfailureNr at arbitration start
--- 1.49/storage/ndb/src/kernel/blocks/qmgr/QmgrMain.cpp 2007-02-06 09:16:26 +01:00
+++ 1.50/storage/ndb/src/kernel/blocks/qmgr/QmgrMain.cpp 2007-03-02 18:44:27 +01:00
@@ -269,7 +269,18 @@
* we have all nodes (or a winning majority).
*/
if (cpresident == getOwnNodeId())
- handleArbitStart(signal);
+ {
+ if (arbitRec.m_disabled == false)
+ {
+ jam();
+ handleArbitStart(signal);
+ }
+ else
+ {
+ jam();
+ infoEvent("Arbitration disabled");
+ }
+ }
break;
}
@@ -862,7 +873,6 @@
jamEntry();
const CmRegConf * const cmRegConf = (CmRegConf *)&signal->theData[0];
- Uint32 presidentNodeId = cmRegConf->presidentNodeId;
if (!ndbCompatible_ndb_ndb(NDB_VERSION, cmRegConf->presidentVersion)) {
jam();
@@ -1107,7 +1117,8 @@
jam();
c_start.m_starting_nodes_w_log.set(TaddNodeno);
}
-
+ c_start.m_node_gci[TaddNodeno] = node_gci;
+
skip_nodes.bitAND(c_definedNodes);
c_start.m_skip_nodes.bitOR(skip_nodes);
@@ -1256,6 +1267,7 @@
wait.bitANDC(tmp);
Uint32 retVal = 0;
+ Uint32 incompleteng = MAX_NDB_NODES; // Illegal value
NdbNodeBitmask report_mask;
if ((c_start.m_latest_gci == 0) ||
@@ -1288,7 +1300,6 @@
/**
* Check for missing node group directly
*/
- char buf[100];
NdbNodeBitmask check;
check.assign(c_definedNodes);
check.bitANDC(c_start.m_starting_nodes); // Not connected nodes
@@ -1341,7 +1352,7 @@
report_mask.assign(c_definedNodes);
report_mask.bitANDC(c_start.m_starting_nodes);
retVal = 1;
- goto start_report;
+ goto check_log;
case CheckNodeGroups::Partitioning:
ndbrequire(result != CheckNodeGroups::Lose);
signal->theData[1] =
@@ -1349,7 +1360,7 @@
report_mask.assign(c_definedNodes);
report_mask.bitANDC(c_start.m_starting_nodes);
retVal = 1;
- goto start_report;
+ goto check_log;
}
}
@@ -1373,12 +1384,7 @@
case CheckNodeGroups::Partitioning:
if (now < partitioned_timeout && result != CheckNodeGroups::Win)
{
- signal->theData[1] = c_restartPartionedTimeout == (Uint32) ~0 ? 4 : 5;
- signal->theData[2] = Uint32((partitioned_timeout - now + 500) / 1000);
- report_mask.assign(c_definedNodes);
- report_mask.bitANDC(c_start.m_starting_nodes);
- retVal = 0;
- goto start_report;
+ goto missinglog;
}
// Fall through...
case CheckNodeGroups::Win:
@@ -1386,12 +1392,61 @@
all ? 0x8001 : (result == CheckNodeGroups::Win ? 0x8002 : 0x8003);
report_mask.assign(c_definedNodes);
report_mask.bitANDC(c_start.m_starting_nodes);
- retVal = 1;
- goto start_report;
+ retVal = 2;
+ goto check_log;
}
}
ndbrequire(false);
+check_log:
+ jam();
+ {
+ Uint32 save[4+4*NdbNodeBitmask::Size];
+ memcpy(save, signal->theData, sizeof(save));
+
+ signal->theData[0] = 0;
+ c_start.m_starting_nodes.copyto(NdbNodeBitmask::Size, signal->theData+1);
+ memcpy(signal->theData+1+NdbNodeBitmask::Size, c_start.m_node_gci,
+ 4*MAX_NDB_NODES);
+ EXECUTE_DIRECT(DBDIH, GSN_DIH_RESTARTREQ, signal,
+ 1+NdbNodeBitmask::Size+MAX_NDB_NODES);
+
+ incompleteng = signal->theData[0];
+ memcpy(signal->theData, save, sizeof(save));
+
+ if (incompleteng != MAX_NDB_NODES)
+ {
+ jam();
+ if (retVal == 1)
+ {
+ jam();
+ goto incomplete_log;
+ }
+ else if (retVal == 2)
+ {
+ if (now <= partitioned_timeout)
+ {
+ jam();
+ goto missinglog;
+ }
+ else
+ {
+ goto incomplete_log;
+ }
+ }
+ ndbrequire(false);
+ }
+ }
+ goto start_report;
+
+missinglog:
+ signal->theData[1] = c_restartPartionedTimeout == (Uint32) ~0 ? 4 : 5;
+ signal->theData[2] = Uint32((partitioned_timeout - now + 500) / 1000);
+ report_mask.assign(c_definedNodes);
+ report_mask.bitANDC(c_start.m_starting_nodes);
+ retVal = 0;
+ goto start_report;
+
start_report:
jam();
{
@@ -1410,17 +1465,32 @@
missing_nodegroup:
jam();
- char buf[100], mask1[100], mask2[100];
- c_start.m_starting_nodes.getText(mask1);
- tmp.assign(c_start.m_starting_nodes);
- tmp.bitANDC(c_start.m_starting_nodes_w_log);
- tmp.getText(mask2);
- BaseString::snprintf(buf, sizeof(buf),
- "Unable to start missing node group! "
- " starting: %s (missing fs for: %s)",
- mask1, mask2);
- progError(__LINE__, NDBD_EXIT_SR_RESTARTCONFLICT, buf);
- return 0; // Deadcode
+ {
+ char buf[100], mask1[100], mask2[100];
+ c_start.m_starting_nodes.getText(mask1);
+ tmp.assign(c_start.m_starting_nodes);
+ tmp.bitANDC(c_start.m_starting_nodes_w_log);
+ tmp.getText(mask2);
+ BaseString::snprintf(buf, sizeof(buf),
+ "Unable to start missing node group! "
+ " starting: %s (missing fs for: %s)",
+ mask1, mask2);
+ progError(__LINE__, NDBD_EXIT_INSUFFICENT_NODES, buf);
+ return 0; // Deadcode
+ }
+
+incomplete_log:
+ jam();
+ {
+ char buf[100], mask1[100];
+ c_start.m_starting_nodes.getText(mask1);
+ BaseString::snprintf(buf, sizeof(buf),
+ "Incomplete log for node group: %d! "
+ " starting nodes: %s",
+ incompleteng, mask1);
+ progError(__LINE__, NDBD_EXIT_INSUFFICENT_NODES, buf);
+ return 0; // Deadcode
+ }
}
void
@@ -2151,9 +2221,11 @@
setHbApiDelay(hbDBAPI);
setArbitTimeout(arbitTimeout);
+ arbitRec.m_disabled = false;
arbitRec.state = ARBIT_NULL; // start state for all nodes
arbitRec.apiMask[0].clear(); // prepare for ARBIT_CFG
+ Uint32 sum = 0;
ArbitSignalData* const sd = (ArbitSignalData*)&signal->theData[0];
for (unsigned rank = 1; rank <= 2; rank++) {
sd->sender = getOwnNodeId();
@@ -2172,9 +2244,19 @@
sd->mask.set(nodeId);
}
}
-
+ sum += sd->mask.count();
execARBIT_CFG(signal);
}
+
+ if (sum == 0)
+ {
+ jam();
+ /**
+ * Disabled arbitration
+ */
+ arbitRec.m_disabled = true;
+ }
+
setNodeInfo(getOwnNodeId()).m_version = NDB_VERSION;
setNodeInfo(getOwnNodeId()).m_mysql_version = NDB_MYSQL_VERSION_D;
}//Qmgr::initData()
@@ -3375,7 +3457,17 @@
*/
return;
}
- handleArbitCheck(signal);
+
+ if (arbitRec.m_disabled == false)
+ {
+ jam();
+ handleArbitCheck(signal);
+ }
+ else
+ {
+ jam();
+ sendCommitFailReq(signal);
+ }
return;
}//Qmgr::execPREP_FAILCONF()
@@ -3571,8 +3663,10 @@
nodePtr.p->phase = ZFAIL_CLOSING;
nodePtr.p->failState = WAITING_FOR_NDB_FAILCONF;
setNodeInfo(nodePtr.i).m_heartbeat_cnt= 0;
+ setNodeInfo(nodePtr.i).m_version = 0;
c_clusterNodes.clear(nodePtr.i);
}//for
+ recompute_version_info(NodeInfo::DB);
/*----------------------------------------------------------------------*/
/* WE INFORM THE API'S WE HAVE CONNECTED ABOUT THE FAILED NODES. */
/*----------------------------------------------------------------------*/
--- 1.53/storage/ndb/src/kernel/blocks/suma/Suma.cpp 2007-02-06 09:16:26 +01:00
+++ 1.54/storage/ndb/src/kernel/blocks/suma/Suma.cpp 2007-03-02 18:44:28 +01:00
@@ -614,6 +614,8 @@
bool found = false;
KeyTable<Table>::Iterator it;
+ LINT_INIT(it.bucket);
+ LINT_INIT(it.curr.p);
for(c_tables.first(it);!it.isNull();c_tables.next(it))
{
LocalDLList<Subscriber> subbs(c_subscriberPool,it.curr.p->c_subscribers);
@@ -1265,7 +1267,7 @@
jam();
syncPtr.p->m_tableList.append(&subPtr.p->m_tableId, 1);
if(signal->getNoOfSections() > 0){
- SegmentedSectionPtr ptr;
+ SegmentedSectionPtr ptr(0,0,0);
signal->getSection(ptr, SubSyncReq::ATTRIBUTE_LIST);
LocalDataBuffer<15> attrBuf(c_dataBufferPool,syncPtr.p->m_attributeList);
append(attrBuf, ptr, getSectionSegmentPool());
@@ -1711,7 +1713,7 @@
Uint32 tableId = conf->tableId;
TablePtr tabPtr;
c_tablePool.getPtr(tabPtr, conf->senderData);
- SegmentedSectionPtr ptr;
+ SegmentedSectionPtr ptr(0,0,0);
signal->getSection(ptr, GetTabInfoConf::DICT_TAB_INFO);
ndbrequire(tabPtr.p->parseTable(ptr, *this));
releaseSections(signal);
@@ -3626,7 +3628,6 @@
if(c_buckets[i].m_buffer_tail != RNIL)
{
- Uint32* dst;
get_buffer_ptr(signal, i, gci, 0);
}
}
@@ -3971,9 +3972,6 @@
Suma::completeSubRemove(SubscriptionPtr subPtr)
{
DBUG_ENTER("Suma::completeSubRemove");
- Uint32 subscriptionId = subPtr.p->m_subscriptionId;
- Uint32 subscriptionKey = subPtr.p->m_subscriptionKey;
-
c_subscriptions.release(subPtr);
DBUG_PRINT("info",("c_subscriptionPool size: %d free: %d",
c_subscriptionPool.getSize(),
@@ -4566,6 +4564,7 @@
DBUG_VOID_RETURN;
}
+#ifdef NOT_USED
static
NdbOut&
operator<<(NdbOut & out, const Suma::Page_pos & pos)
@@ -4577,6 +4576,7 @@
<< " ]";
return out;
}
+#endif
Uint32*
Suma::get_buffer_ptr(Signal* signal, Uint32 buck, Uint32 gci, Uint32 sz)
@@ -4668,9 +4668,7 @@
m_out_of_buffer_gci = m_last_complete_gci - 1;
infoEvent("Out of event buffer: nodefailure will cause event failures");
- signal->theData[0] = SumaContinueB::OUT_OF_BUFFER_RELEASE;
- signal->theData[1] = 0;
- sendSignal(SUMA_REF, GSN_CONTINUEB, signal, 2, JBB);
+ out_of_buffer_release(signal, 0);
}
void
@@ -4738,7 +4736,8 @@
Uint32 count;
m_tup->allocConsPages(16, count, ref);
- ndbrequire(count > 0);
+ if (count == 0)
+ return RNIL;
ndbout_c("alloc_chunk(%d %d) - ", ref, count);
@@ -4747,6 +4746,7 @@
ptr.p->m_free = count;
Buffer_page* page;
+ LINT_INIT(page);
for(Uint32 i = 0; i<count; i++)
{
page = (Buffer_page*)m_tup->c_page_pool.getPtr(ref);
--- 1.107/storage/ndb/src/ndbapi/NdbScanOperation.cpp 2007-02-06 09:16:26 +01:00
+++ 1.108/storage/ndb/src/ndbapi/NdbScanOperation.cpp 2007-03-02 18:44:28 +01:00
@@ -852,7 +852,6 @@
tSignal = theSCAN_TABREQ;
Uint32 tupKeyLen = theTupKeyLen;
- Uint32 len = theTotalNrOfKeyWordInSignal;
Uint32 aTC_ConnectPtr = theNdbCon->theTCConPtr;
Uint64 transId = theNdbCon->theTransactionId;
@@ -995,6 +994,7 @@
newOp->theTupKeyLen = len;
newOp->theOperationType = opType;
+ newOp->m_abortOption = AbortOnError;
switch (opType) {
case (ReadRequest):
newOp->theLockMode = theLockMode;
@@ -1225,7 +1225,7 @@
* so it's safe to use [tIndexAttrId]
* (instead of looping as is NdbOperation::equal_impl)
*/
- if(type == BoundEQ && tDistrKey)
+ if(type == BoundEQ && tDistrKey && !m_multi_range)
{
theNoOfTupKeyLeft--;
return handle_distribution_key(valPtr, sizeInWords);
@@ -1311,7 +1311,8 @@
const bool order_by = scan_flags & SF_OrderBy;
const bool order_desc = scan_flags & SF_Descending;
const bool read_range_no = scan_flags & SF_ReadRangeNo;
-
+ m_multi_range = scan_flags & SF_MultiRange;
+
int res = NdbScanOperation::readTuples(lm, scan_flags, parallel, batch);
if(!res && read_range_no)
{
@@ -1361,8 +1362,6 @@
Uint32 cnt = m_accessTable->getNoOfColumns() - 1;
assert(cnt < NDB_MAX_NO_OF_ATTRIBUTES_IN_KEY);
- const NdbIndexImpl * idx = m_accessTable->m_index;
- const NdbTableImpl * tab = m_currentTable;
for(Uint32 i = 0; i<cnt; i++){
Uint32 val = theTupleKeyDefined[i][0];
switch(val){
@@ -1794,6 +1793,12 @@
int
NdbIndexScanOperation::end_of_bound(Uint32 no)
{
+ DBUG_ENTER("end_of_bound");
+ DBUG_PRINT("info", ("Range number %u", no));
+ /* Check that SF_MultiRange has been specified if more
+ than one range is specified */
+ if (no > 0 && !m_multi_range)
+ DBUG_RETURN(-1);
if(no < (1 << 13)) // Only 12-bits no of ranges
{
Uint32 bound_head = * m_first_bound_word;
@@ -1802,9 +1807,9 @@
m_first_bound_word = theKEYINFOptr + theTotalNrOfKeyWordInSignal;;
m_this_bound_start = theTupKeyLen;
- return 0;
+ DBUG_RETURN(0);
}
- return -1;
+ DBUG_RETURN(-1);
}
int
--- 1.41/storage/ndb/test/ndbapi/testNodeRestart.cpp 2007-02-06 09:16:26 +01:00
+++ 1.42/storage/ndb/test/ndbapi/testNodeRestart.cpp 2007-03-02 18:44:28 +01:00
@@ -1178,6 +1178,101 @@
return NDBT_OK;
}
+int runBug25984(NDBT_Context* ctx, NDBT_Step* step){
+
+ int result = NDBT_OK;
+ int loops = ctx->getNumLoops();
+ int records = ctx->getNumRecords();
+ NdbRestarter restarter;
+
+ if (restarter.getNumDbNodes() < 2)
+ return NDBT_OK;
+
+ if (restarter.restartAll(true, true, true))
+ return NDBT_FAILED;
+
+ if (restarter.waitClusterNoStart())
+ return NDBT_FAILED;
+
+ if (restarter.startAll())
+ return NDBT_FAILED;
+
+ if (restarter.waitClusterStarted())
+ return NDBT_FAILED;
+
+ int val2[] = { DumpStateOrd::CmvmiSetRestartOnErrorInsert, 1 };
+ int master = restarter.getMasterNodeId();
+ int victim = restarter.getRandomNodeOtherNodeGroup(master, rand());
+ if (victim == -1)
+ victim = restarter.getRandomNodeSameNodeGroup(master, rand());
+
+ restarter.restartOneDbNode(victim, false, true, true);
+
+ for (Uint32 i = 0; i<6; i++)
+ {
+ ndbout_c("Loop: %d", i);
+ if (restarter.waitNodesNoStart(&victim, 1))
+ return NDBT_FAILED;
+
+ if (restarter.dumpStateOneNode(victim, val2, 2))
+ return NDBT_FAILED;
+
+ if (restarter.insertErrorInNode(victim, 7016))
+ return NDBT_FAILED;
+
+ if (restarter.startNodes(&victim, 1))
+ return NDBT_FAILED;
+
+ if (restarter.waitNodesStartPhase(&victim, 1, 2))
+ return NDBT_FAILED;
+ }
+
+ if (restarter.waitNodesNoStart(&victim, 1))
+ return NDBT_FAILED;
+
+ if (restarter.dumpStateOneNode(victim, val2, 2))
+ return NDBT_FAILED;
+
+ if (restarter.insertErrorInNode(victim, 7170))
+ return NDBT_FAILED;
+
+ if (restarter.startNodes(&victim, 1))
+ return NDBT_FAILED;
+
+ if (restarter.waitNodesNoStart(&victim, 1))
+ return NDBT_FAILED;
+
+ if (restarter.restartAll(false, true, true))
+ return NDBT_FAILED;
+
+ if (restarter.insertErrorInAllNodes(932))
+ return NDBT_FAILED;
+
+ if (restarter.insertErrorInNode(master, 7170))
+ return NDBT_FAILED;
+
+ if (restarter.dumpStateAllNodes(val2, 2))
+ return NDBT_FAILED;
+
+ restarter.startNodes(&master, 1);
+ NdbSleep_MilliSleep(3000);
+ restarter.startAll();
+
+ if (restarter.waitClusterNoStart())
+ return NDBT_FAILED;
+
+ if (restarter.restartOneDbNode(victim, true, true, true))
+ return NDBT_FAILED;
+
+ if (restarter.startAll())
+ return NDBT_FAILED;
+
+ if (restarter.waitClusterStarted())
+ return NDBT_FAILED;
+
+ return NDBT_OK;
+}
+
NDBT_TESTSUITE(testNodeRestart);
TESTCASE("NoLoad",
@@ -1513,6 +1608,9 @@
}
TESTCASE("Bug25554", ""){
INITIALIZER(runBug25554);
+}
+TESTCASE("Bug25984", ""){
+ INITIALIZER(runBug25984);
}
NDBT_TESTSUITE_END(testNodeRestart);
--- 1.412/sql/ha_ndbcluster.cc 2007-02-14 09:11:20 +01:00
+++ 1.413/sql/ha_ndbcluster.cc 2007-03-02 18:58:20 +01:00
@@ -264,7 +264,8 @@
return error;
}
-int execute_no_commit_ignore_no_key(ha_ndbcluster *h, NdbTransaction *trans)
+int execute_no_commit_ignore_no_key(ha_ndbcluster *h, NdbTransaction *trans,
+ bool &ignored_error)
{
if (trans->execute(NdbTransaction::NoCommit,
NdbOperation::AO_IgnoreError,
@@ -276,14 +277,24 @@
err.classification != NdbError::ConstraintViolation &&
err.classification != NdbError::NoDataFound)
return -1;
-
+ ignored_error= TRUE;
return 0;
}
inline
+int execute_no_commit_ignore_error(ha_ndbcluster *h, NdbTransaction *trans,
+ bool force_release,
+ bool &ignored_error)
+{
+ h->release_completed_operations(trans, force_release);
+ return execute_no_commit_ignore_no_key(h, trans, ignored_error);
+}
+
+inline
int execute_no_commit(ha_ndbcluster *h, NdbTransaction *trans,
bool force_release)
{
+ bool not_used;
#ifdef NOT_USED
int m_batch_execute= 0;
if (m_batch_execute)
@@ -291,7 +302,7 @@
#endif
h->release_completed_operations(trans, force_release);
return h->m_ignore_no_key ?
- execute_no_commit_ignore_no_key(h,trans) :
+ execute_no_commit_ignore_no_key(h,trans, not_used) :
trans->execute(NdbTransaction::NoCommit,
NdbOperation::AbortOnError,
h->m_force_send);
@@ -1580,7 +1591,8 @@
}
-int ha_ndbcluster::set_primary_key_from_record(NdbOperation *op, const byte *record)
+int ha_ndbcluster::set_primary_key_from_record(NdbOperation *op,
+ const byte *record)
{
KEY* key_info= table->key_info + table_share->primary_key;
KEY_PART_INFO* key_part= key_info->key_part;
@@ -1883,6 +1895,22 @@
}
+bool ha_ndbcluster::is_key_updated(KEY_PART_INFO *key_part_info,
+ uint key_parts)
+{
+ uint i;
+ DBUG_ENTER("is_key_updated");
+
+ for (i= 0; i < key_parts; i++, key_part_info++)
+ {
+ if (bitmap_is_set(table->write_set, key_part_info->fieldnr-1))
+ {
+ DBUG_RETURN(TRUE);
+ }
+ }
+ DBUG_RETURN(FALSE);
+}
+
/*
* Peek to check if any rows already exist with conflicting
* primary key or unique index values
@@ -1935,16 +1963,19 @@
*/
KEY* key_info;
KEY_PART_INFO *key_part, *end;
+ uint key_parts;
for (i= 0, key_info= table->key_info; i < table->s->keys; i++, key_info++)
{
+ key_part= key_info->key_part;
+ key_parts= key_info->key_parts;
if (i != table->s->primary_key &&
- key_info->flags & HA_NOSAME)
+ key_info->flags & HA_NOSAME &&
+ is_key_updated(key_part, key_parts))
{
- // A unique index is defined on table
+ // A unique index is defined on table and it's being updated
NdbIndexOperation *iop;
const NDBINDEX *unique_index = m_index[i].unique_index;
- key_part= key_info->key_part;
- end= key_part + key_info->key_parts;
+ end= key_part + key_parts;
if (!(iop= trans->getNdbIndexOperation(unique_index, m_table)) ||
iop->readTuple(lm) != 0)
ERR_RETURN(trans->getNdbError());
@@ -2835,7 +2866,9 @@
uint32 old_part_id= 0, new_part_id= 0;
int error;
longlong func_value;
- bool pk_update= (table_share->primary_key != MAX_KEY &&
+ bool ignored_error= FALSE;
+ bool pk_update= (!m_read_before_write_removal_possible &&
+ table_share->primary_key != MAX_KEY &&
key_cmp(table_share->primary_key, old_data, new_data));
DBUG_ENTER("update_row");
m_write_op= TRUE;
@@ -2921,6 +2954,7 @@
DBUG_RETURN(insert_res);
}
DBUG_PRINT("info", ("delete+insert succeeded"));
+ m_rows_updated++;
DBUG_RETURN(0);
}
@@ -2944,31 +2978,46 @@
cursor->setPartitionId(new_part_id);
}
else
- {
- if (!(op= trans->getNdbOperation(m_table)) ||
- op->updateTuple() != 0)
- ERR_RETURN(trans->getNdbError());
-
- if (m_use_partition_function)
- op->setPartitionId(new_part_id);
- if (table_share->primary_key == MAX_KEY)
- {
- // This table has no primary key, use "hidden" primary key
- DBUG_PRINT("info", ("Using hidden key"));
-
- // Require that the PK for this record has previously been
- // read into m_ref
- DBUG_DUMP("key", m_ref, NDB_HIDDEN_PRIMARY_KEY_LENGTH);
-
- if (set_hidden_key(op, table->s->fields, m_ref))
- ERR_RETURN(op->getNdbError());
- }
- else
+ {
+ if (m_read_before_write_removal_possible &&
+ active_index != table_share->primary_key)
{
int res;
- if ((res= set_primary_key_from_record(op, old_data)))
+ if (!(op= trans->getNdbIndexOperation(
+ m_index[active_index].unique_index,
+ m_table)) ||
+ op->updateTuple() != 0)
+ ERR_RETURN(trans->getNdbError());
+ if ((res= set_index_key_from_record(op, old_data, active_index)))
DBUG_RETURN(res);
}
+ else
+ {
+ if (!(op= trans->getNdbOperation(m_table)) ||
+ op->updateTuple() != 0)
+ ERR_RETURN(trans->getNdbError());
+
+ if (m_use_partition_function)
+ op->setPartitionId(new_part_id);
+ if (table_share->primary_key == MAX_KEY)
+ {
+ // This table has no primary key, use "hidden" primary key
+ DBUG_PRINT("info", ("Using hidden key"));
+
+ // Require that the PK for this record has previously been
+ // read into m_ref
+ DBUG_DUMP("key", m_ref, NDB_HIDDEN_PRIMARY_KEY_LENGTH);
+
+ if (set_hidden_key(op, table->s->fields, m_ref))
+ ERR_RETURN(op->getNdbError());
+ }
+ else
+ {
+ int res;
+ if ((res= set_primary_key_from_record(op, old_data)))
+ DBUG_RETURN(res);
+ }
+ }
}
m_rows_changed++;
@@ -2999,11 +3048,16 @@
op->setValue(no_fields, part_func_value);
}
// Execute update operation
- if (!cursor && execute_no_commit(this,trans,FALSE) != 0) {
+ if (!cursor &&
+ ((m_read_before_write_removal_possible ?
+ execute_no_commit_ignore_error(this,trans,FALSE, ignored_error) :
+ execute_no_commit(this,trans,FALSE)) != 0))
+ {
no_uncommitted_rows_execute_failure();
DBUG_RETURN(ndb_err(trans));
}
-
+ if (!ignored_error)
+ m_rows_updated++;
DBUG_RETURN(0);
}
@@ -3020,6 +3074,7 @@
NdbOperation *op;
uint32 part_id;
int error;
+ bool ignored_error= FALSE;
DBUG_ENTER("delete_row");
m_write_op= TRUE;
@@ -3054,41 +3109,62 @@
no_uncommitted_rows_update(-1);
if (!m_primary_key_update)
+ {
// If deleting from cursor, NoCommit will be handled in next_result
+ m_rows_deleted++;
DBUG_RETURN(0);
+ }
}
else
{
+ if (m_read_before_write_removal_possible &&
+ active_index != table_share->primary_key)
+ {
+ if (!(op=trans->getNdbIndexOperation(
+ m_index[active_index].unique_index,
+ m_table)) ||
+ op->deleteTuple() != 0)
+ ERR_RETURN(trans->getNdbError());
+ if ((error= set_index_key_from_record(op, record, active_index)))
+ DBUG_RETURN(error);
+ }
+ else
+ {
+ if (!(op=trans->getNdbOperation(m_table)) ||
+ op->deleteTuple() != 0)
+ ERR_RETURN(trans->getNdbError());
- if (!(op=trans->getNdbOperation(m_table)) ||
- op->deleteTuple() != 0)
- ERR_RETURN(trans->getNdbError());
-
- if (m_use_partition_function)
- op->setPartitionId(part_id);
+ if (m_use_partition_function)
+ op->setPartitionId(part_id);
- no_uncommitted_rows_update(-1);
+ no_uncommitted_rows_update(-1);
- if (table_share->primary_key == MAX_KEY)
- {
- // This table has no primary key, use "hidden" primary key
- DBUG_PRINT("info", ("Using hidden key"));
+ if (table_share->primary_key == MAX_KEY)
+ {
+ // This table has no primary key, use "hidden" primary key
+ DBUG_PRINT("info", ("Using hidden key"));
- if (set_hidden_key(op, table->s->fields, m_ref))
- ERR_RETURN(op->getNdbError());
- }
- else
- {
- if ((error= set_primary_key_from_record(op, record)))
- DBUG_RETURN(error);
+ if (set_hidden_key(op, table->s->fields, m_ref))
+ ERR_RETURN(op->getNdbError());
+ }
+ else
+ {
+ if ((error= set_primary_key_from_record(op, record)))
+ DBUG_RETURN(error);
+ }
}
}
// Execute delete operation
- if (execute_no_commit(this,trans,FALSE) != 0) {
+ if ((m_read_before_write_removal_possible ?
+ execute_no_commit_ignore_error(this,trans,FALSE, ignored_error) :
+ execute_no_commit(this,trans,FALSE)) != 0)
+ {
no_uncommitted_rows_execute_failure();
DBUG_RETURN(ndb_err(trans));
}
+ if (!m_primary_key_update && !ignored_error)
+ m_rows_deleted++;
DBUG_RETURN(0);
}
@@ -3314,6 +3390,11 @@
and no sub-sequent call to unlock_row()
*/
m_lock_tuple= FALSE;
+ if (table_share->primary_key == MAX_KEY &&
+ m_use_partition_function)
+ include_partition_fields_in_used_fields(
+ m_part_info->full_part_field_array,
+ table->read_set);
DBUG_RETURN(0);
}
@@ -3835,6 +3916,11 @@
stats.auto_increment_value= (ulonglong)auto_increment_value64;
}
}
+ if (flag & HA_STATUS_WRITTEN_ROWS)
+ {
+ stats.rows_updated= m_rows_updated;
+ stats.rows_deleted= m_rows_deleted;
+ }
if(result == -1)
result= HA_ERR_NO_CONNECTION;
@@ -3899,6 +3985,41 @@
DBUG_RETURN(0);
}
+void ha_ndbcluster::column_bitmaps_signal(uint sig_type)
+{
+ DBUG_ENTER("column_bitmaps_signal");
+ DBUG_PRINT("enter", ("read_set: 0x%lx write_set: 0x%lx", (long) table->read_set,
+ (long) table->write_set));
+ if (sig_type & HA_COMPLETE_TABLE_READ_BITMAP)
+ {
+ bitmap_copy(&m_save_read_set, table->read_set);
+ }
+ DBUG_VOID_RETURN;
+}
+
+bool ha_ndbcluster::read_before_write_removal_possible(List<Item> *fields,
+ List<Item> *values)
+{
+ DBUG_ENTER("read_before_write_removal_possible");
+ m_write_op= TRUE;
+ if (table_share->primary_key != MAX_KEY &&
+ !bitmap_is_overlapping(table->write_set, &m_primary_key_fields) &&
+ !uses_blob_value())
+ {
+ /*
+ Not a primary key update. We also check that the SET expressions
+ are all constant expressions, non-constant expressions requires
+ more work on handling push-down of expressions to NDB kernel.
+ */
+ if (!values || check_constant_expressions(values))
+ {
+ DBUG_PRINT("info", ("read_before_write_removal_possible TRUE"));
+ m_read_before_write_removal_possible= TRUE;
+ }
+ }
+ DBUG_RETURN(m_read_before_write_removal_possible);
+}
+
int ha_ndbcluster::reset()
{
@@ -3911,6 +4032,8 @@
*/
if (m_part_info)
bitmap_set_all(&m_part_info->used_partitions);
+ m_read_before_write_removal_possible= FALSE;
+ m_rows_updated= m_rows_deleted= 0;
DBUG_RETURN(0);
}
@@ -5827,6 +5950,7 @@
m_has_unique_index(FALSE),
m_primary_key_update(FALSE),
m_ignore_no_key(FALSE),
+ m_read_before_write_removal_possible(FALSE),
m_rows_to_insert((ha_rows) 1),
m_rows_inserted((ha_rows) 0),
m_bulk_insert_rows((ha_rows) 1024),
@@ -5925,6 +6049,8 @@
{
int res;
KEY *key;
+ KEY_PART_INFO *key_part_info;
+ uint key_parts, i;
DBUG_ENTER("ha_ndbcluster::open");
DBUG_PRINT("enter", ("name: %s mode: %d test_if_locked: %d",
name, mode, test_if_locked));
@@ -5934,10 +6060,20 @@
primary key to be written in the ref variable
*/
+ if (bitmap_init(&m_save_read_set, NULL,
+ table_share->fields, TRUE))
+ DBUG_RETURN(1);
if (table_share->primary_key != MAX_KEY)
{
key= table->key_info+table_share->primary_key;
+ key_part_info= key->key_part;
+ key_parts= key->key_parts;
ref_length= key->key_length;
+ if (bitmap_init(&m_primary_key_fields, NULL,
+ table_share->fields, TRUE))
+ DBUG_RETURN(1);
+ for (i= 0; i < key_parts; i++, key_part_info++)
+ bitmap_set_bit(&m_primary_key_fields, key_part_info->fieldnr-1);
}
else // (table_share->primary_key == MAX_KEY)
{
@@ -5952,7 +6088,10 @@
// Init table lock structure
/* ndb_share reference handler */
if (!(m_share=get_share(name, table)))
+ {
+ close();
DBUG_RETURN(1);
+ }
DBUG_PRINT("NDB_SHARE", ("%s handler use_count: %u",
m_share->key, m_share->use_count));
thr_lock_data_init(&m_share->lock,&m_lock,(void*) 0);
@@ -5965,11 +6104,10 @@
/* ndb_share reference handler free */
DBUG_PRINT("NDB_SHARE", ("%s handler free use_count: %u",
m_share->key, m_share->use_count));
- free_share(&m_share);
- m_share= 0;
+ close();
DBUG_RETURN(HA_ERR_NO_CONNECTION);
}
-
+
res= get_metadata(name);
if (!res)
{
@@ -5983,13 +6121,18 @@
if(!res)
res= info(HA_STATUS_CONST);
}
+ if (res)
+ {
+ close();
+ DBUG_RETURN(res);
+ }
#ifdef HAVE_NDB_BINLOG
if (!ndb_binlog_tables_inited && ndb_binlog_running)
table->db_stat|= HA_READ_ONLY;
#endif
- DBUG_RETURN(res);
+ DBUG_RETURN(0);
}
/*
@@ -6025,12 +6168,17 @@
DBUG_ENTER("close");
THD *thd= current_thd;
Ndb *ndb= thd ? check_ndb_in_thd(thd) : g_ndb;
- /* ndb_share reference handler free */
- DBUG_PRINT("NDB_SHARE", ("%s handler free use_count: %u",
- m_share->key, m_share->use_count));
- free_share(&m_share);
+ if (m_share)
+ {
+ /* ndb_share reference handler free */
+ DBUG_PRINT("NDB_SHARE", ("%s handler free use_count: %u",
+ m_share->key, m_share->use_count));
+ free_share(&m_share);
+ }
m_share= 0;
release_metadata(thd, ndb);
+ if (table_share->primary_key != MAX_KEY)
+ bitmap_free(&m_primary_key_fields);
DBUG_RETURN(0);
}
@@ -8117,6 +8265,53 @@
DBUG_RETURN(FALSE);
}
+void ha_ndbcluster::check_read_before_write_removal()
+{
+ DBUG_ENTER("check_read_before_write_removal");
+ /*
+ We are doing an update or delete and it is possible that we
+ can ignore the read before the update or delete. This is
+ possible here since we are not updating the primary key and
+ if the index used is unique or primary and if the WHERE clause
+ only involves fields from this index we are ok to go. At this
+ moment we can only updates where all SET expressions are
+ constants. Thus no read set will come from SET expressions.
+ */
+ if (table_share->primary_key == active_index)
+ {
+ if (!bitmap_is_subset(&m_save_read_set, &m_primary_key_fields))
+ m_read_before_write_removal_possible= FALSE;
+ }
+ else
+ {
+ KEY *key= table->key_info+active_index;
+ if (!(key->flags & HA_NOSAME))
+ {
+ /* Optimisation not applicable on non-unique indexes */
+ m_read_before_write_removal_possible= FALSE;
+ }
+ else
+ {
+ /* Unique index bitmaps are built on the fly */
+ KEY_PART_INFO *key_part_info= key->key_part;
+ uint key_parts= key->key_parts;
+ MY_BITMAP index_map;
+ uint32 index_bitmap[NDB_MAX_ATTRIBUTES_IN_TABLE/32];
+ uint32 i;
+
+ bitmap_init(&index_map, (my_bitmap_map*)index_bitmap,
+ table_share->fields, FALSE);
+ for (i= 0; i < key_parts; i++, key_part_info++)
+ bitmap_set_bit(&index_map, key_part_info->fieldnr-1);
+ if (!bitmap_is_subset(&m_save_read_set, &index_map))
+ m_read_before_write_removal_possible= FALSE;
+ }
+ }
+ DBUG_PRINT("info", ("m_read_before_write_removal_possible = %d",
+ m_read_before_write_removal_possible));
+ DBUG_VOID_RETURN;
+}
+
int
ha_ndbcluster::read_multi_range_first(KEY_MULTI_RANGE **found_range_p,
KEY_MULTI_RANGE *ranges,
@@ -8181,11 +8376,16 @@
NdbOperation::LockMode lm=
(NdbOperation::LockMode)get_ndb_lock_type(m_lock.type);
bool need_pk = (lm == NdbOperation::LM_Read);
+ bool any_real_read= FALSE;
const NDBTAB *tab= m_table;
const NDBINDEX *unique_idx= m_index[active_index].unique_index;
const NDBINDEX *idx= m_index[active_index].index;
const NdbOperation* lastOp= m_active_trans->getLastDefinedOperation();
NdbIndexScanOperation* scanOp= 0;
+
+ if (m_read_before_write_removal_possible)
+ check_read_before_write_removal();
+
for (; multi_range_curr<multi_range_end && curr+reclength <=
end_of_buffer;
multi_range_curr++)
{
@@ -8220,16 +8420,25 @@
// else fall through
case PRIMARY_KEY_INDEX:
{
- multi_range_curr->range_flag |= UNIQUE_RANGE;
- if ((op= m_active_trans->getNdbOperation(tab)) &&
- !op->readTuple(lm) &&
- !set_primary_key(op, multi_range_curr->start_key.key) &&
- !define_read_attrs(curr, op) &&
- (!m_use_partition_function ||
- (op->setPartitionId(part_spec.start_part), TRUE)))
- curr += reclength;
+ if (!m_read_before_write_removal_possible)
+ {
+ any_real_read= TRUE;
+ multi_range_curr->range_flag |= UNIQUE_RANGE;
+ if ((op= m_active_trans->getNdbOperation(tab)) &&
+ !op->readTuple(lm) &&
+ !set_primary_key(op, multi_range_curr->start_key.key) &&
+ !define_read_attrs(curr, op) &&
+ (!m_use_partition_function ||
+ (op->setPartitionId(part_spec.start_part), TRUE)))
+ curr += reclength;
+ else
+ ERR_RETURN(op ? op->getNdbError() : m_active_trans->getNdbError());
+ }
else
- ERR_RETURN(op ? op->getNdbError() : m_active_trans->getNdbError());
+ {
+ multi_range_curr->range_flag|= READ_KEY_FROM_RANGE;
+ continue;
+ }
break;
}
break;
@@ -8242,19 +8451,29 @@
// else fall through
case UNIQUE_INDEX:
{
- multi_range_curr->range_flag |= UNIQUE_RANGE;
- if ((op= m_active_trans->getNdbIndexOperation(unique_idx, tab)) &&
- !op->readTuple(lm) &&
- !set_index_key(op, key_info, multi_range_curr->start_key.key) &&
- !define_read_attrs(curr, op))
- curr += reclength;
+ if (!m_read_before_write_removal_possible)
+ {
+ any_real_read= TRUE;
+ multi_range_curr->range_flag |= UNIQUE_RANGE;
+ if ((op= m_active_trans->getNdbIndexOperation(unique_idx, tab)) &&
+ !op->readTuple(lm) &&
+ !set_index_key(op, key_info, multi_range_curr->start_key.key) &&
+ !define_read_attrs(curr, op))
+ curr += reclength;
+ else
+ ERR_RETURN(op ? op->getNdbError() : m_active_trans->getNdbError());
+ }
else
- ERR_RETURN(op ? op->getNdbError() : m_active_trans->getNdbError());
+ {
+ multi_range_curr->range_flag|= READ_KEY_FROM_RANGE;
+ continue;
+ }
break;
}
case ORDERED_INDEX: {
range:
multi_range_curr->range_flag &= ~(uint)UNIQUE_RANGE;
+ any_real_read= TRUE;
if (scanOp == 0)
{
if (m_multi_cursor)
@@ -8316,13 +8535,17 @@
/**
* Set first operation in multi range
*/
- m_current_multi_operation=
- lastOp ? lastOp->next() : m_active_trans->getFirstDefinedOperation();
- if (!(res= execute_no_commit_ie(this, m_active_trans,true)))
+ if (any_real_read)
+ {
+ m_current_multi_operation=
+ lastOp ? lastOp->next() : m_active_trans->getFirstDefinedOperation();
+ }
+ if (!any_real_read ||
+ !(res= execute_no_commit_ie(this, m_active_trans,true)))
{
m_multi_range_defined= multi_range_curr;
- multi_range_curr= ranges;
m_multi_range_result_ptr= (byte*)buffer->buffer;
+ multi_range_curr= ranges;
DBUG_RETURN(read_multi_range_next(found_range_p));
}
ERR_RETURN(m_active_trans->getNdbError());
@@ -8337,6 +8560,7 @@
int
ha_ndbcluster::read_multi_range_next(KEY_MULTI_RANGE ** multi_range_found_p)
{
+ uint range_flag;
DBUG_ENTER("ha_ndbcluster::read_multi_range_next");
if (m_disable_multi_read)
{
@@ -8351,9 +8575,20 @@
for (;multi_range_curr < m_multi_range_defined; multi_range_curr++)
{
DBUG_MULTI_RANGE(12);
- if (multi_range_curr->range_flag & SKIP_RANGE)
+ range_flag= multi_range_curr->range_flag;
+ if (range_flag & SKIP_RANGE)
continue;
- if (multi_range_curr->range_flag & UNIQUE_RANGE)
+ if (range_flag & READ_KEY_FROM_RANGE)
+ {
+ DBUG_PRINT("info", ("using read before write removal optimisation"));
+ KEY* key_info= table->key_info + active_index;
+ key_restore(table->record[0], multi_range_curr->start_key.key,
+ key_info, key_info->key_length);
+ table->status= 0;
+ multi_range_curr++;
+ DBUG_RETURN(0);
+ }
+ if (range_flag & UNIQUE_RANGE)
{
if (op->getNdbError().code == 0)
{
--- 1.171/sql/ha_ndbcluster.h 2007-02-14 09:11:21 +01:00
+++ 1.172/sql/ha_ndbcluster.h 2007-03-02 18:44:19 +01:00
@@ -681,6 +681,9 @@
{ return HA_POS_ERROR; }
int info(uint);
void get_dynamic_partition_info(PARTITION_INFO *stat_info, uint part_id);
+ bool read_before_write_removal_possible(List<Item> *fields,
+ List<Item> *values);
+ void column_bitmaps_signal(uint sig_type);
int extra(enum ha_extra_function operation);
int extra_opt(enum ha_extra_function operation, ulong cache_size);
int reset();
@@ -798,6 +801,8 @@
Ndb *ndb, NdbEventOperation *pOp,
NDB_SHARE *share);
+ void check_read_before_write_removal();
+ bool is_key_updated(KEY_PART_INFO *key_part_info, uint key_parts);
static int delete_table(ha_ndbcluster *h, Ndb *ndb,
const char *path,
const char *db,
@@ -923,9 +928,14 @@
byte *buf);
friend int execute_commit(ha_ndbcluster*, NdbTransaction*);
- friend int execute_no_commit_ignore_no_key(ha_ndbcluster*, NdbTransaction*);
+ friend int execute_no_commit_ignore_no_key(ha_ndbcluster*, NdbTransaction*,
+ bool &ignored_error);
friend int execute_no_commit(ha_ndbcluster*, NdbTransaction*, bool);
- friend int execute_no_commit_ie(ha_ndbcluster*, NdbTransaction*, bool);
+ friend int execute_no_commit_ignore_error(ha_ndbcluster*, NdbTransaction*,
+ bool force_release,
+ bool &ignored_error);
+ friend int execute_no_commit_ie(ha_ndbcluster*, NdbTransaction*,
+ bool force_release);
NdbTransaction *m_active_trans;
NdbScanOperation *m_active_cursor;
@@ -940,6 +950,8 @@
NDB_SHARE *m_share;
NDB_INDEX_DATA m_index[MAX_KEY];
THD_NDB_SHARE *m_thd_ndb_share;
+ MY_BITMAP m_primary_key_fields;
+ MY_BITMAP m_save_read_set;
// NdbRecAttr has no reference to blob
NdbValue m_value[NDB_MAX_ATTRIBUTES_IN_TABLE];
byte m_ref[NDB_HIDDEN_PRIMARY_KEY_LENGTH];
@@ -955,9 +967,12 @@
bool m_primary_key_update;
bool m_write_op;
bool m_ignore_no_key;
+ bool m_read_before_write_removal_possible;
ha_rows m_rows_to_insert; // TODO: merge it with handler::estimation_rows_to_insert?
ha_rows m_rows_inserted;
ha_rows m_bulk_insert_rows;
+ ha_rows m_rows_updated;
+ ha_rows m_rows_deleted;
ha_rows m_rows_changed;
bool m_bulk_insert_not_flushed;
ha_rows m_ops_pending;
--- 1.83/sql/ha_partition.cc 2007-01-29 00:51:37 +01:00
+++ 1.84/sql/ha_partition.cc 2007-03-02 18:44:19 +01:00
@@ -2928,7 +2928,8 @@
uint32 part_id;
DBUG_ENTER("ha_partition::rnd_init");
- include_partition_fields_in_used_fields();
+ include_partition_fields_in_used_fields(m_part_field_array,
+ table->read_set);
/* Now we see what the index of our first important partition is */
DBUG_PRINT("info", ("m_part_info->used_partitions: 0x%lx",
@@ -3242,7 +3243,8 @@
m_start_key.length= 0;
m_ordered= sorted;
m_curr_key_info= table->key_info+inx;
- include_partition_fields_in_used_fields();
+ include_partition_fields_in_used_fields(m_part_field_array,
+ table->read_set);
file= m_file;
do
{
@@ -4130,35 +4132,6 @@
return_top_record(buf);
DBUG_PRINT("info", ("Record returned from partition %d", m_top_entry));
DBUG_RETURN(0);
-}
-
-
-/*
- Set fields in partition functions in read set for underlying handlers
-
- SYNOPSIS
- include_partition_fields_in_used_fields()
-
- RETURN VALUE
- NONE
-
- DESCRIPTION
- Some handlers only read fields as specified by the bitmap for the
- read set. For partitioned handlers we always require that the
- fields of the partition functions are read such that we can
- calculate the partition id to place updated and deleted records.
-*/
-
-void ha_partition::include_partition_fields_in_used_fields()
-{
- Field **ptr= m_part_field_array;
- DBUG_ENTER("ha_partition::include_partition_fields_in_used_fields");
-
- do
- {
- bitmap_set_bit(table->read_set, (*ptr)->field_index);
- } while (*(++ptr));
- DBUG_VOID_RETURN;
}
--- 1.99/sql/sql_partition.cc 2007-01-24 16:11:27 +01:00
+++ 1.100/sql/sql_partition.cc 2007-03-02 18:44:22 +01:00
@@ -2002,7 +2002,6 @@
{
uint i,j, tot_no_parts, no_subparts;
partition_element *part_elem;
- partition_element *save_part_elem= NULL;
ulonglong buffer_length;
char path[FN_REFLEN];
int err= 0;
@@ -5369,7 +5368,6 @@
List_iterator<partition_element> temp_it(part_info->temp_partitions);
uint no_temp_partitions= part_info->temp_partitions.elements;
uint no_elements= part_info->partitions.elements;
- uint i= 0;
DBUG_ENTER("write_log_dropped_partitions");
ddl_log_entry.action_type= DDL_LOG_DELETE_ACTION;
@@ -5742,7 +5740,6 @@
bool dont_crash)
{
partition_info *part_info= lpt->part_info;
- uint count_loop= 0;
DDL_LOG_MEMORY_ENTRY *log_entry= part_info->exec_log_entry;
DBUG_ENTER("write_log_completed");
@@ -6016,8 +6013,6 @@
uint fast_alter_partition)
{
/* Set-up struct used to write frm files */
- ulonglong copied= 0;
- ulonglong deleted= 0;
partition_info *part_info= table->part_info;
ALTER_PARTITION_PARAM_TYPE lpt_obj;
ALTER_PARTITION_PARAM_TYPE *lpt= &lpt_obj;
| Thread |
|---|
| • bk commit into 5.1 tree (mikron:1.2433) | mikael | 2 Mar |