From: Frazer Clement Date: September 12 2012 3:15pm Subject: bzr push into mysql-5.5-cluster-7.2 branch (frazer.clement:3986 to 3987) List-Archive: http://lists.mysql.com/commits/144741 Message-Id: <201209121515.q8CFFdE4000547@acsmt356.oracle.com> MIME-Version: 1.0 Content-Type: text/plain; charset="us-ascii" Content-Transfer-Encoding: 7bit 3987 Frazer Clement 2012-09-12 [merge] Merge 7.1->7.2 modified: sql/ha_ndb_index_stat.cc sql/ha_ndb_index_stat.h storage/ndb/include/kernel/signaldata/DumpStateOrd.hpp storage/ndb/include/util/NdbOut.hpp storage/ndb/src/kernel/blocks/dblqh/DblqhMain.cpp storage/ndb/src/kernel/blocks/dbtc/Dbtc.hpp storage/ndb/src/kernel/blocks/dbtc/DbtcMain.cpp storage/ndb/src/mgmapi/LocalConfig.cpp storage/ndb/src/mgmapi/LocalConfig.hpp storage/ndb/test/include/NDBT_Stats.hpp storage/ndb/test/ndbapi/testRedo.cpp storage/ndb/test/ndbapi/testScan.cpp storage/ndb/test/run-test/daily-basic-tests.txt 3986 Maitrayi Sabaratnam 2012-09-07 [merge] Merge 7.1->7.2 In addition to the fix for Bug 14582294 - SPJ: GETNODES DOES NOT RETURN CORRCT ERROR CODE and other merges, this adds a FI test case to testSpj, to verify the fix. This test case is not present in 7.0 and 7.1. modified: storage/ndb/src/kernel/blocks/dbdih/DbdihMain.cpp storage/ndb/src/kernel/blocks/dbspj/DbspjMain.cpp storage/ndb/test/ndbapi/testDict.cpp storage/ndb/test/ndbapi/testSpj.cpp === modified file 'sql/ha_ndb_index_stat.cc' --- a/sql/ha_ndb_index_stat.cc 2012-01-02 16:31:33 +0000 +++ b/sql/ha_ndb_index_stat.cc 2012-09-12 15:11:40 +0000 @@ -28,11 +28,11 @@ extern struct st_ndb_status g_ndb_status; extern pthread_mutex_t ndbcluster_mutex; -/* these have to live in ha_ndbcluster.cc */ +/* Implemented in ha_ndbcluster.cc */ extern bool ndb_index_stat_get_enable(THD *thd); extern const char* g_ndb_status_index_stat_status; extern long g_ndb_status_index_stat_cache_query; -extern long g_ndb_status_index_stat_cache_clean; +extern long g_ndb_status_index_stat_cache_clean; // Do we have waiter... static bool ndb_index_stat_waiter= false; @@ -120,9 +120,9 @@ struct Ndb_index_stat_list { extern Ndb_index_stat_list ndb_index_stat_list[]; -time_t ndb_index_stat_time_now= 0; +static time_t ndb_index_stat_time_now= 0; -time_t +static time_t ndb_index_stat_time() { time_t now= time(0); @@ -146,9 +146,9 @@ ndb_index_stat_time() and after it exits. This is only a pre-caution since mysqld should not allow clients at these times. */ -bool ndb_index_stat_allow_flag= false; +static bool ndb_index_stat_allow_flag= false; -bool +static bool ndb_index_stat_allow(int flag= -1) { if (flag != -1) @@ -160,7 +160,7 @@ ndb_index_stat_allow(int flag= -1) /* Options in string format buffer size */ static const uint ndb_index_stat_option_sz= 512; -void ndb_index_stat_opt2str(const struct Ndb_index_stat_opt&, char*); +static void ndb_index_stat_opt2str(const struct Ndb_index_stat_opt&, char*); struct Ndb_index_stat_opt { enum Unit { @@ -251,10 +251,10 @@ Ndb_index_stat_opt::Ndb_index_stat_opt(c static const uint ndb_index_stat_max_evict_batch = 32; char ndb_index_stat_option_buf[ndb_index_stat_option_sz]; -Ndb_index_stat_opt ndb_index_stat_opt(ndb_index_stat_option_buf); +static Ndb_index_stat_opt ndb_index_stat_opt(ndb_index_stat_option_buf); /* Copy option struct to string buffer */ -void +static void ndb_index_stat_opt2str(const Ndb_index_stat_opt& opt, char* str) { DBUG_ENTER("ndb_index_stat_opt2str"); @@ -336,7 +336,7 @@ ndb_index_stat_opt2str(const Ndb_index_s DBUG_VOID_RETURN; } -int +static int ndb_index_stat_option_parse(char* p, Ndb_index_stat_opt& opt) { DBUG_ENTER("ndb_index_stat_option_parse"); @@ -452,7 +452,7 @@ ndb_index_stat_option_parse(char* p, Ndb } /* Copy option string to option struct */ -int +static int ndb_index_stat_str2opt(const char *str, Ndb_index_stat_opt& opt) { DBUG_ENTER("ndb_index_stat_str2opt"); @@ -495,7 +495,7 @@ ndb_index_stat_str2opt(const char *str, /* Thanks to ha_innodb.cc */ /* Need storage between check and update (assume locked) */ -char ndb_index_stat_option_tmp[ndb_index_stat_option_sz]; +static char ndb_index_stat_option_tmp[ndb_index_stat_option_sz]; int ndb_index_stat_option_check(MYSQL_THD, @@ -711,7 +711,7 @@ Ndb_index_stat_glob::zero_total() cache_high_bytes= cache_query_bytes + cache_clean_bytes; } -Ndb_index_stat_glob ndb_index_stat_glob; +static Ndb_index_stat_glob ndb_index_stat_glob; /* Shared index entries */ @@ -754,7 +754,7 @@ Ndb_index_stat::Ndb_index_stat() since they are probably local e.g. bad range (internal error). Argument "from" is 0=stats thread 1=client. */ -void +static void ndb_index_stat_error(Ndb_index_stat *st, int from, const char* place, int line) { @@ -783,7 +783,7 @@ ndb_index_stat_error(Ndb_index_stat *st, place, line, error.code, error.line, error.extra)); } -void +static void ndb_index_stat_clear_error(Ndb_index_stat *st) { st->error.code= 0; @@ -812,7 +812,7 @@ Ndb_index_stat_list ndb_index_stat_list[ Ndb_index_stat_list(Ndb_index_stat::LT_Error, "error") }; -void +static void ndb_index_stat_list_add(Ndb_index_stat* st, int lt) { assert(st != 0 && st->lt == 0); @@ -840,7 +840,7 @@ ndb_index_stat_list_add(Ndb_index_stat* st->lt= lt; } -void +static void ndb_index_stat_list_remove(Ndb_index_stat* st) { assert(st != 0); @@ -871,7 +871,7 @@ ndb_index_stat_list_remove(Ndb_index_sta st->list_prev= 0; } -void +static void ndb_index_stat_list_move(Ndb_index_stat *st, int lt) { assert(st != 0); @@ -881,7 +881,7 @@ ndb_index_stat_list_move(Ndb_index_stat /* Stats entry changes (must hold stat_mutex) */ -void +static void ndb_index_stat_force_update(Ndb_index_stat *st, bool onoff) { safe_mutex_assert_owner(&ndb_index_stat_thread.stat_mutex); @@ -908,7 +908,7 @@ ndb_index_stat_force_update(Ndb_index_st } } -void +static void ndb_index_stat_no_stats(Ndb_index_stat *st, bool flag) { safe_mutex_assert_owner(&ndb_index_stat_thread.stat_mutex); @@ -931,7 +931,7 @@ ndb_index_stat_no_stats(Ndb_index_stat * } } -void +static void ndb_index_stat_ref_count(Ndb_index_stat *st, bool flag) { safe_mutex_assert_owner(&ndb_index_stat_thread.stat_mutex); @@ -961,7 +961,7 @@ struct Ndb_index_stat_snap { }; /* Subroutine, have lock */ -Ndb_index_stat* +static Ndb_index_stat* ndb_index_stat_alloc(const NDBINDEX *index, const NDBTAB *table, int &err_out) @@ -994,7 +994,7 @@ ndb_index_stat_alloc(const NDBINDEX *ind } /* Subroutine, have lock */ -Ndb_index_stat* +static Ndb_index_stat* ndb_index_stat_find_share(NDB_SHARE *share, const NDBINDEX *index, Ndb_index_stat *&st_last) @@ -1017,7 +1017,7 @@ ndb_index_stat_find_share(NDB_SHARE *sha } /* Subroutine, have lock */ -void +static void ndb_index_stat_add_share(NDB_SHARE *share, Ndb_index_stat *st, Ndb_index_stat *st_last) @@ -1029,7 +1029,7 @@ ndb_index_stat_add_share(NDB_SHARE *shar st_last->share_next= st; } -Ndb_index_stat* +static Ndb_index_stat* ndb_index_stat_get_share(NDB_SHARE *share, const NDBINDEX *index, const NDBTAB *table, @@ -1104,7 +1104,7 @@ ndb_index_stat_get_share(NDB_SHARE *shar */ /* caller must hold stat_mutex */ -void +static void ndb_index_stat_free(Ndb_index_stat *st) { safe_mutex_assert_owner(&ndb_index_stat_thread.stat_mutex); @@ -1218,7 +1218,7 @@ ndb_index_stat_free(NDB_SHARE *share) /* Find entry across shares */ /* wl4124_todo mutex overkill, hash table, can we find table share */ -Ndb_index_stat* +static Ndb_index_stat* ndb_index_stat_find_entry(int index_id, int index_version, int table_id) { DBUG_ENTER("ndb_index_stat_find_entry"); @@ -1251,7 +1251,7 @@ ndb_index_stat_find_entry(int index_id, /* Statistics thread sub-routines */ -void +static void ndb_index_stat_cache_move(Ndb_index_stat *st) { Ndb_index_stat_glob &glob= ndb_index_stat_glob; @@ -1276,7 +1276,7 @@ ndb_index_stat_cache_move(Ndb_index_stat glob.cache_high_bytes= cache_total; } -bool +static bool ndb_index_stat_cache_clean(Ndb_index_stat *st) { Ndb_index_stat_glob &glob= ndb_index_stat_glob; @@ -1296,7 +1296,7 @@ ndb_index_stat_cache_clean(Ndb_index_sta return true; } -void +static void ndb_index_stat_cache_evict(Ndb_index_stat *st) { NdbIndexStat::Head head; @@ -1349,7 +1349,7 @@ struct Ndb_index_stat_proc { {} }; -void +static void ndb_index_stat_proc_new(Ndb_index_stat_proc &pr, Ndb_index_stat *st) { assert(st->error.code == 0); @@ -1359,7 +1359,7 @@ ndb_index_stat_proc_new(Ndb_index_stat_p pr.lt= Ndb_index_stat::LT_Read; } -void +static void ndb_index_stat_proc_new(Ndb_index_stat_proc &pr) { Ndb_index_stat_glob &glob= ndb_index_stat_glob; @@ -1381,7 +1381,7 @@ ndb_index_stat_proc_new(Ndb_index_stat_p pthread_mutex_unlock(&ndb_index_stat_thread.stat_mutex); } -void +static void ndb_index_stat_proc_update(Ndb_index_stat_proc &pr, Ndb_index_stat *st) { if (st->is->update_stat(pr.ndb) == -1) @@ -1407,7 +1407,7 @@ ndb_index_stat_proc_update(Ndb_index_sta pr.lt= Ndb_index_stat::LT_Read; } -void +static void ndb_index_stat_proc_update(Ndb_index_stat_proc &pr) { Ndb_index_stat_glob &glob= ndb_index_stat_glob; @@ -1436,7 +1436,7 @@ ndb_index_stat_proc_update(Ndb_index_sta pr.busy= true; } -void +static void ndb_index_stat_proc_read(Ndb_index_stat_proc &pr, Ndb_index_stat *st) { Ndb_index_stat_glob &glob= ndb_index_stat_glob; @@ -1485,7 +1485,7 @@ ndb_index_stat_proc_read(Ndb_index_stat_ pthread_mutex_unlock(&ndb_index_stat_thread.stat_mutex); } -void +static void ndb_index_stat_proc_read(Ndb_index_stat_proc &pr) { Ndb_index_stat_glob &glob= ndb_index_stat_glob; @@ -1514,7 +1514,7 @@ ndb_index_stat_proc_read(Ndb_index_stat_ pr.busy= true; } -void +static void ndb_index_stat_proc_idle(Ndb_index_stat_proc &pr, Ndb_index_stat *st) { Ndb_index_stat_glob &glob= ndb_index_stat_glob; @@ -1568,7 +1568,7 @@ ndb_index_stat_proc_idle(Ndb_index_stat_ pr.lt= Ndb_index_stat::LT_Idle; } -void +static void ndb_index_stat_proc_idle(Ndb_index_stat_proc &pr) { Ndb_index_stat_glob &glob= ndb_index_stat_glob; @@ -1611,7 +1611,7 @@ ndb_index_stat_proc_idle(Ndb_index_stat_ pthread_mutex_unlock(&ndb_index_stat_thread.stat_mutex); } -void +static void ndb_index_stat_proc_check(Ndb_index_stat_proc &pr, Ndb_index_stat *st) { pr.now= ndb_index_stat_time(); @@ -1648,7 +1648,7 @@ ndb_index_stat_proc_check(Ndb_index_stat pr.lt= Ndb_index_stat::LT_Idle; } -void +static void ndb_index_stat_proc_check(Ndb_index_stat_proc &pr) { Ndb_index_stat_glob &glob= ndb_index_stat_glob; @@ -1678,7 +1678,7 @@ ndb_index_stat_proc_check(Ndb_index_stat } /* Check if need to evict more */ -bool +static bool ndb_index_stat_proc_evict() { const Ndb_index_stat_opt &opt= ndb_index_stat_opt; @@ -1697,7 +1697,7 @@ ndb_index_stat_proc_evict() } /* Check if st1 is better or as good to evict than st2 */ -bool +static bool ndb_index_stat_evict(const Ndb_index_stat *st1, const Ndb_index_stat *st2) { @@ -1710,7 +1710,7 @@ ndb_index_stat_evict(const Ndb_index_sta return false; } -void +static void ndb_index_stat_proc_evict(Ndb_index_stat_proc &pr, int lt) { Ndb_index_stat_glob &glob= ndb_index_stat_glob; @@ -1820,14 +1820,14 @@ ndb_index_stat_proc_evict(Ndb_index_stat pthread_mutex_unlock(&ndb_index_stat_thread.stat_mutex); } -void +static void ndb_index_stat_proc_evict(Ndb_index_stat_proc &pr) { ndb_index_stat_proc_evict(pr, Ndb_index_stat::LT_Error); ndb_index_stat_proc_evict(pr, Ndb_index_stat::LT_Idle); } -void +static void ndb_index_stat_proc_delete(Ndb_index_stat_proc &pr) { Ndb_index_stat_glob &glob= ndb_index_stat_glob; @@ -1881,7 +1881,7 @@ ndb_index_stat_proc_delete(Ndb_index_sta pthread_mutex_unlock(&ndb_index_stat_thread.stat_mutex); } -void +static void ndb_index_stat_proc_error(Ndb_index_stat_proc &pr, Ndb_index_stat *st) { const Ndb_index_stat_opt &opt= ndb_index_stat_opt; @@ -1916,7 +1916,7 @@ ndb_index_stat_proc_error(Ndb_index_stat pr.lt= Ndb_index_stat::LT_Error; } -void +static void ndb_index_stat_proc_error(Ndb_index_stat_proc &pr) { Ndb_index_stat_glob &glob= ndb_index_stat_glob; @@ -1947,7 +1947,7 @@ ndb_index_stat_proc_error(Ndb_index_stat pthread_mutex_unlock(&ndb_index_stat_thread.stat_mutex); } -void +static void ndb_index_stat_proc_event(Ndb_index_stat_proc &pr, Ndb_index_stat *st) { /* @@ -1979,7 +1979,7 @@ ndb_index_stat_proc_event(Ndb_index_stat } } -void +static void ndb_index_stat_proc_event(Ndb_index_stat_proc &pr) { Ndb_index_stat_glob &glob= ndb_index_stat_glob; @@ -2047,7 +2047,7 @@ ndb_index_stat_proc_event(Ndb_index_stat /* Control options */ -void +static void ndb_index_stat_proc_control(Ndb_index_stat_proc &pr) { Ndb_index_stat_glob &glob= ndb_index_stat_glob; @@ -2065,7 +2065,7 @@ ndb_index_stat_proc_control(Ndb_index_st } #ifndef DBUG_OFF -void +static void ndb_index_stat_entry_verify(Ndb_index_stat_proc &pr, const Ndb_index_stat *st) { const NDB_SHARE *share= st->share; @@ -2103,7 +2103,7 @@ ndb_index_stat_entry_verify(Ndb_index_st pr.cache_clean_bytes+= st->clean_bytes; } -void +static void ndb_index_stat_list_verify(Ndb_index_stat_proc &pr, int lt) { const Ndb_index_stat_list &list= ndb_index_stat_list[lt]; @@ -2154,7 +2154,7 @@ ndb_index_stat_list_verify(Ndb_index_sta assert(count == list.count); } -void +static void ndb_index_stat_list_verify(Ndb_index_stat_proc &pr) { const Ndb_index_stat_glob &glob= ndb_index_stat_glob; @@ -2170,7 +2170,7 @@ ndb_index_stat_list_verify(Ndb_index_sta pthread_mutex_unlock(&ndb_index_stat_thread.stat_mutex); } -void +static void ndb_index_stat_report(const Ndb_index_stat_glob& old_glob) { const Ndb_index_stat_glob &new_glob= ndb_index_stat_glob; @@ -2185,7 +2185,7 @@ ndb_index_stat_report(const Ndb_index_st } #endif -void +static void ndb_index_stat_proc(Ndb_index_stat_proc &pr) { DBUG_ENTER("ndb_index_stat_proc"); @@ -2255,7 +2255,7 @@ ndb_index_stat_end() /* Index stats thread */ -int +static int ndb_index_stat_check_or_create_systables(Ndb_index_stat_proc &pr) { DBUG_ENTER("ndb_index_stat_check_or_create_systables"); @@ -2290,7 +2290,7 @@ ndb_index_stat_check_or_create_systables DBUG_RETURN(-1); } -int +static int ndb_index_stat_check_or_create_sysevents(Ndb_index_stat_proc &pr) { DBUG_ENTER("ndb_index_stat_check_or_create_sysevents"); @@ -2323,7 +2323,7 @@ ndb_index_stat_check_or_create_sysevents DBUG_RETURN(-1); } -int +static int ndb_index_stat_start_listener(Ndb_index_stat_proc &pr) { DBUG_ENTER("ndb_index_stat_start_listener"); @@ -2348,7 +2348,7 @@ ndb_index_stat_start_listener(Ndb_index_ DBUG_RETURN(0); } -int +static int ndb_index_stat_stop_listener(Ndb_index_stat_proc &pr) { DBUG_ENTER("ndb_index_stat_stop_listener"); @@ -2659,7 +2659,7 @@ ndb_index_stat_round(double x) similar but separated for clarity. */ -int +static int ndb_index_stat_wait_query(Ndb_index_stat *st, const Ndb_index_stat_snap &snap) { @@ -2747,7 +2747,7 @@ ndb_index_stat_wait_query(Ndb_index_stat DBUG_RETURN(0); } -int +static int ndb_index_stat_wait_analyze(Ndb_index_stat *st, const Ndb_index_stat_snap &snap) { === modified file 'sql/ha_ndb_index_stat.h' --- a/sql/ha_ndb_index_stat.h 2011-12-18 12:20:44 +0000 +++ b/sql/ha_ndb_index_stat.h 2012-09-12 10:29:29 +0000 @@ -56,15 +56,9 @@ private: }; /* free entries from share or at end */ -extern void ndb_index_stat_free(NDB_SHARE*, int iudex_id, int index_version); -extern void ndb_index_stat_free(NDB_SHARE*); -extern void ndb_index_stat_end(); - -/* these have to live in ha_ndbcluster.cc */ -extern bool ndb_index_stat_get_enable(THD *thd); -extern const char* g_ndb_status_index_stat_status; -extern long g_ndb_status_index_stat_cache_query; -extern long g_ndb_status_index_stat_cache_clean; +void ndb_index_stat_free(NDB_SHARE*, int iudex_id, int index_version); +void ndb_index_stat_free(NDB_SHARE*); +void ndb_index_stat_end(); void compute_index_bounds(NdbIndexScanOperation::IndexBound & bound, === modified file 'storage/ndb/include/kernel/signaldata/DumpStateOrd.hpp' --- a/storage/ndb/include/kernel/signaldata/DumpStateOrd.hpp 2012-08-29 13:39:37 +0000 +++ b/storage/ndb/include/kernel/signaldata/DumpStateOrd.hpp 2012-09-12 15:11:40 +0000 @@ -101,6 +101,7 @@ public: LqhDumpAllActiveScanRec = 2302, LqhDumpLcpState = 2303, LqhErrorInsert5042 = 2315, + LqhDumpPoolLevels = 2353, AccDumpOneScanRec = 2400, AccDumpAllScanRec = 2401, @@ -121,6 +122,7 @@ public: TcSetApplTransactionTimeout = 2508, TcStartDumpIndexOpCount = 2512, TcDumpIndexOpCount = 2513, + TcDumpPoolLevels = 2555, CmvmiDumpConnections = 2600, CmvmiDumpLongSignalMemory = 2601, CmvmiSetRestartOnErrorInsert = 2602, === modified file 'storage/ndb/include/util/NdbOut.hpp' --- a/storage/ndb/include/util/NdbOut.hpp 2011-09-29 09:23:04 +0000 +++ b/storage/ndb/include/util/NdbOut.hpp 2012-09-12 15:11:40 +0000 @@ -93,11 +93,6 @@ private: bool m_autoflush; }; -#ifdef NDB_WIN -typedef int(*NdbOutF)(char*); -extern NdbOutF ndbout_svc; -#endif - inline NdbOut& NdbOut::operator<<(NdbOut& (* _f)(NdbOut&)) { (* _f)(*this); return * this; === modified file 'storage/ndb/src/kernel/blocks/dblqh/DblqhMain.cpp' --- a/storage/ndb/src/kernel/blocks/dblqh/DblqhMain.cpp 2012-08-22 11:15:43 +0000 +++ b/storage/ndb/src/kernel/blocks/dblqh/DblqhMain.cpp 2012-09-12 15:11:40 +0000 @@ -23695,6 +23695,74 @@ Dblqh::execDUMP_STATE_ORD(Signal* signal SET_ERROR_INSERT_VALUE2(5050, c_master_node_id); #endif } + + if (arg == DumpStateOrd::LqhDumpPoolLevels) + { + /* Dump some state info for internal buffers */ + if (signal->getLength() == 1) + { + signal->theData[1] = 1; + signal->theData[2] = 0; + signal->theData[3] = 0; + sendSignal(reference(), GSN_DUMP_STATE_ORD, signal, 4, JBB); + return; + } + if (signal->getLength() != 4) + { + ndbout_c("DUMP LqhDumpPoolLevels : Bad signal length : %u", signal->getLength()); + return; + } + + Uint32 resource = signal->theData[1]; + Uint32 position = signal->theData[2]; + Uint32 sum = signal->theData[3]; + /*const Uint32 MAX_ITER = 200; */ + + switch(resource) + { + case 1: + { + /* Must get all in one loop, as we're traversing a dynamic list */ + sum = 0; + TcConnectionrecPtr tcp; + tcp.i = cfirstfreeTcConrec; + while (tcp.i != RNIL) + { + sum++; + ptrCheckGuard(tcp, ctcConnectrecFileSize, tcConnectionrec); + tcp.i = tcp.p->nextTcConnectrec; + } + infoEvent("LQH : TcConnection (operation) records in use/total %u/%u (%u bytes each)", + ctcConnectrecFileSize - sum, ctcConnectrecFileSize, (Uint32) sizeof(TcConnectionrec)); + resource++; + position = 0; + sum = 0; + break; + } + case 2: + { + infoEvent("LQH : ScanRecord (Fragment) pool in use/total %u/%u (%u bytes each)", + c_scanRecordPool.getSize()- + c_scanRecordPool.getNoOfFree(), + c_scanRecordPool.getSize(), + (Uint32) sizeof(ScanRecord)); + resource++; + position = 0; + sum = 0; + break; + } + default: + return; + } + + signal->theData[0] = DumpStateOrd::LqhDumpPoolLevels; + signal->theData[1] = resource; + signal->theData[2] = position; + signal->theData[3] = sum; + sendSignal(reference(), GSN_DUMP_STATE_ORD, signal, 4, JBB); + return; + } + }//Dblqh::execDUMP_STATE_ORD() === modified file 'storage/ndb/src/kernel/blocks/dbtc/Dbtc.hpp' --- a/storage/ndb/src/kernel/blocks/dbtc/Dbtc.hpp 2012-08-24 12:07:17 +0000 +++ b/storage/ndb/src/kernel/blocks/dbtc/Dbtc.hpp 2012-09-12 15:11:40 +0000 @@ -1789,6 +1789,7 @@ private: // Resource usage counter(not monotonic) Uint32 cconcurrentOp; + Uint32 cconcurrentScans; MonotonicCounters() : cattrinfoCount(0), === modified file 'storage/ndb/src/kernel/blocks/dbtc/DbtcMain.cpp' --- a/storage/ndb/src/kernel/blocks/dbtc/DbtcMain.cpp 2012-08-24 12:07:17 +0000 +++ b/storage/ndb/src/kernel/blocks/dbtc/DbtcMain.cpp 2012-09-12 15:11:40 +0000 @@ -10824,12 +10824,29 @@ void Dbtc::scanKeyinfoLab(Signal* signal ndbassert( signal->getLength() == (KeyInfo::HeaderLength + wordsInSignal) ); - if (unlikely (! appendToSection(regCachePtr->keyInfoSectionI, - &signal->theData[KeyInfo::HeaderLength], - wordsInSignal))) - { - jam(); - seizeDatabuferrorLab(signal); + if (unlikely ((! appendToSection(regCachePtr->keyInfoSectionI, + &signal->theData[KeyInfo::HeaderLength], + wordsInSignal)) || + ERROR_INSERTED(8094))) + { + jam(); + Uint32 transid0 = apiConnectptr.p->transid[0]; + Uint32 transid1 = apiConnectptr.p->transid[1]; + ndbrequire(apiConnectptr.p->apiScanRec != RNIL); + ScanRecordPtr scanPtr; + scanPtr.i = apiConnectptr.p->apiScanRec; + ptrCheckGuard(scanPtr, cscanrecFileSize, scanRecord); + abortScanLab(signal, + scanPtr, + ZGET_DATAREC_ERROR, + true /* Not started */); + + /* Prepare for up coming ATTRINFO/KEYINFO */ + apiConnectptr.p->apiConnectstate = CS_ABORTING; + apiConnectptr.p->abortState = AS_IDLE; + apiConnectptr.p->transid[0] = transid0; + apiConnectptr.p->transid[1] = transid1; + return; } @@ -11253,6 +11270,7 @@ void Dbtc::releaseScanResources(Signal* scanPtr.p->scanTcrec = RNIL; scanPtr.p->scanApiRec = RNIL; cfirstfreeScanrec = scanPtr.i; + ndbassert(cConcScanCount > 0); cConcScanCount--; apiConnectptr.p->apiScanRec = RNIL; @@ -13522,6 +13540,69 @@ Dbtc::execDUMP_STATE_ORD(Signal* signal) ndbrequire(rss_cconcurrentOp == c_counters.cconcurrentOp); #endif } + + if (arg == DumpStateOrd::TcDumpPoolLevels) + { + if (signal->getLength() == 1) + { + signal->theData[1] = 1; + signal->theData[2] = 0; + signal->theData[3] = 0; + sendSignal(reference(), GSN_DUMP_STATE_ORD, signal, 4, JBB); + return; + } + if (signal->getLength() != 4) + { + ndbout_c("DUMP TcDumpPoolLevels : Bad signal length : %u", signal->getLength()); + return; + } + + Uint32 resource = signal->theData[1]; + Uint32 position = signal->theData[2]; + Uint32 sum = signal->theData[3]; + /* const Uint32 MAX_ITER = 200; */ + + switch(resource) + { + case 1: + infoEvent("TC : Concurrent operations in use/total : %u/%u (%u bytes each)", + c_counters.cconcurrentOp, + ctcConnectFilesize, + (Uint32) sizeof(TcConnectRecord)); + resource++; + position = 0; + sum = 0; + break; + case 2: + infoEvent("TC : Concurrent scans in use/total : %u/%u (%u bytes each)", + cConcScanCount, + cscanrecFileSize, + (Uint32) sizeof(ScanRecord)); + resource++; + position = 0; + sum = 0; + break; + case 3: + infoEvent("TC : Scan Frag records in use/total : %u/%u (%u bytes each)", + c_scan_frag_pool.getSize() - + c_scan_frag_pool.getNoOfFree(), + c_scan_frag_pool.getSize(), + (Uint32) sizeof(ScanFragRec)); + resource++; + position = 0; + sum = 0; + break; + default: + return; + } + + signal->theData[0] = DumpStateOrd::TcDumpPoolLevels; + signal->theData[1] = resource; + signal->theData[2] = position; + signal->theData[3] = sum; + sendSignal(reference(), GSN_DUMP_STATE_ORD, signal, 4, JBB); + return; + } }//Dbtc::execDUMP_STATE_ORD() void Dbtc::execDBINFO_SCANREQ(Signal *signal) === modified file 'storage/ndb/src/mgmapi/LocalConfig.cpp' --- a/storage/ndb/src/mgmapi/LocalConfig.cpp 2011-06-30 15:59:25 +0000 +++ b/storage/ndb/src/mgmapi/LocalConfig.cpp 2012-09-12 08:41:46 +0000 @@ -117,31 +117,6 @@ void LocalConfig::setError(int lineNumbe strncpy(error_msg, _msg, sizeof(error_msg)); } -void LocalConfig::printError() const { - ndbout << "Configuration error" << endl; - if (error_line) - ndbout << "Line: "<< error_line << ", "; - ndbout << error_msg << endl << endl; -} - -void LocalConfig::printUsage() const { - ndbout << "This node needs information on how to connect"<export NDB_CONNECTSTRING=\"host=localhost:"<= 0); - - double y = 0; - double s = 1; - double r = 0; - while(y <= x){ - y += s; - s += 2; - r += 1; - } - return r - 1; -} - #endif === modified file 'storage/ndb/test/ndbapi/testRedo.cpp' --- a/storage/ndb/test/ndbapi/testRedo.cpp 2012-09-03 12:31:01 +0000 +++ b/storage/ndb/test/ndbapi/testRedo.cpp 2012-09-12 15:11:40 +0000 @@ -25,8 +25,6 @@ #include #include -#include "../../../../storage/ndb/src/mgmapi/mgmapi_configuration.hpp" - static NdbMutex* g_msgmutex = 0; #undef require === modified file 'storage/ndb/test/ndbapi/testScan.cpp' --- a/storage/ndb/test/ndbapi/testScan.cpp 2012-08-24 12:07:17 +0000 +++ b/storage/ndb/test/ndbapi/testScan.cpp 2012-09-12 15:11:40 +0000 @@ -1390,6 +1390,220 @@ finalizeBug42559(NDBT_Context* ctx, NDBT return NDBT_OK; } +int takeResourceSnapshot(NDBT_Context* ctx, NDBT_Step* step) +{ + NdbRestarter restarter; + + int checksnapshot = DumpStateOrd::TcResourceSnapshot; + restarter.dumpStateAllNodes(&checksnapshot, 1); + + /* TODO : Check other block's resources? */ + return NDBT_OK; +} + +int runScanReadIndexWithBounds(NDBT_Context* ctx, NDBT_Step* step){ + int loops = ctx->getNumLoops(); + int records = ctx->getNumRecords(); + int numRanges = ctx->getProperty("NumRanges", 1); + int maxRunSecs = ctx->getProperty("MaxRunSecs", 60); + int maxRetries = ctx->getProperty("MaxRetries", 1000000); + + const NdbDictionary::Index * pIdx = + GETNDB(step)->getDictionary()->getIndex(orderedPkIdxName, + ctx->getTab()->getName()); + + int i = 0; + HugoCalculator calc(*ctx->getTab()); + NDBT_ResultRow row (*ctx->getTab()); + Ndb* ndb = GETNDB(step); + + Uint64 start = NdbTick_CurrentMillisecond(); + Uint64 end = start + (1000*maxRunSecs); + int retries = 0; + + /* Here we run an ordered index scan, with a bound. + * There are numRanges sub-scans with the same bound + * This is done to use up some KeyInfo, and expose bugs in that area + * If we run many of these in parallel we may exhaust the available KeyInfo storage, + * which may expose some bugs. + */ + while (pIdx && + iisTestStopped() && + NdbTick_CurrentMillisecond() < end) { + g_info << "Step " << step->getStepNo() + << "Loop : " << i << ": "; + + /* Use specific-partition variant of startTransaction to ensure a single + * TC node is used + */ + NdbTransaction* trans = ndb->startTransaction(ctx->getTab(), Uint32(0)); + if (trans == NULL) + { + g_err << "Transaction start failed " << ndb->getNdbError() << endl; + return NDBT_FAILED; + } + + NdbIndexScanOperation* iso = trans->getNdbIndexScanOperation(pIdx->getName(), + ctx->getTab()->getName()); + if (iso == NULL) + { + g_err << "Error obtaining IndexScanOperation : " << trans->getNdbError() << endl; + trans->close(); + return NDBT_FAILED; + } + + if (iso->readTuples(NdbOperation::LM_CommittedRead, + (NdbScanOperation::SF_OrderBy | + NdbScanOperation::SF_ReadRangeNo | + NdbScanOperation::SF_MultiRange), + 0) != 0) + { + g_err << "Error calling readTuples : " << iso->getNdbError() << endl; + trans->close(); + return NDBT_FAILED; + } + + for (int range = 0; range < numRanges; range++) + { + /* Now define a bound... */ + for (Uint32 k=0; kgetNoOfColumns(); k++) + { + const NdbDictionary::Column* idxCol = pIdx->getColumn(k); + const char* colName = idxCol->getName(); + /* Lower bound of <= NULL should return all rows */ + if (iso->setBound(colName, NdbIndexScanOperation::BoundLE, NULL) != 0) + { + g_err << "Error setting bound for column %s. " + << iso->getNdbError() << endl; + trans->close(); + return NDBT_FAILED; + } + } + + if (iso->end_of_bound(range) != 0) + { + g_err << "Error closing range " << range << endl; + g_err << iso->getNdbError() << endl; + return NDBT_FAILED; + } + } + + const NdbDictionary::Table& tab= *ctx->getTab(); + + /* Now request all columns in result projection */ + for (int a=0; agetValue(tab.getColumn(a)->getName())) == 0) { + g_err << "Error defining read value " << trans->getNdbError() << endl; + trans->close(); + return NDBT_FAILED; + } + } + + /* Ready to go... */ + trans->execute(NoCommit, AbortOnError); + + if (trans->getNdbError().code != 0) + { + if (trans->getNdbError().code == 218) + { + /* Out of KeyInfo buffers in TC - that's ok, let's try again */ + trans->close(); + if (retries++ < maxRetries) + { + g_err << "Step " << step->getStepNo() + << " TC out of Keyinfo buffers (218) - retrying" << endl; + continue; + } + } + + g_err << "Error on execution : " << trans->getNdbError() << endl; + trans->close(); + return NDBT_FAILED; + } + + int eof; + int rows = 0; + while ((eof = iso->nextResult(true)) == 0) + { + rows++; + if (calc.verifyRowValues(&row) != 0) + { + g_err << "Verification failed." << endl; + trans->close(); + return NDBT_FAILED; + } + +#ifdef BUG_14388257_FIXED + int rangeNum = (rows -1) / records; + if (iso->get_range_no() != rangeNum) + { + g_err << "Expected row " << rows + << " to be in range " << rangeNum + << " but it reports range num " << iso->get_range_no() + << " : " << row + << endl; + return NDBT_FAILED; + } +#endif + + //g_err << row << endl; + } + + if (eof != 1) + { + g_err << "nextResult() returned " << eof << endl; + g_err << "Scan error : " << iso->getNdbError() << endl; + + if (iso->getNdbError().status == NdbError::TemporaryError) + { + if (retries++ < maxRetries) + { + g_err << "Step " + << step->getStepNo() + << " Temporary, retrying on iteration " + << i << " rows so far : " << rows << endl; + trans->close(); + NdbSleep_MilliSleep(2500); + continue; + } + } + + trans->close(); + return NDBT_FAILED; + } + + g_err << "Read " << rows << " rows." << endl; + + if (records != 0 && rows != (numRanges * records)) + { + g_err << "Expected " << records << " rows" + << ", read " << rows << endl; +#ifdef BUG_14388257_FIXED + trans->close(); + assert(false); + return NDBT_FAILED; +#endif + } + + trans->close(); + i++; + } + return NDBT_OK; +} + +int checkResourceSnapshot(NDBT_Context* ctx, NDBT_Step* step) +{ + NdbRestarter restarter; + + int checksnapshot = DumpStateOrd::TcResourceCheckLeak; + restarter.dumpStateAllNodes(&checksnapshot, 1); + + /* TODO : Check other block's resources? */ + return NDBT_OK; +} + int runBug54945(NDBT_Context* ctx, NDBT_Step* step) @@ -2364,6 +2578,47 @@ TESTCASE("extraNextResultBug11748194", { INITIALIZER(runExtraNextResult); } +TESTCASE("ScanRealKeyInfoExhaust", + "Test behaviour when TC keyinfo buffers exhausted 4real") +{ + /* 55 threads, each setting 200 ranges in their keyinfo + * For the lightest single column PK case, each range should + * use 2 words, 200 ranges = 400 words per scan thread = + * 400/4 = 100 Databuffers used. + * 55 threads = 55*100 = 5500 Databuffers which is > + * the 4000 statically allocated in 6.3 + */ + TC_PROPERTY("NumRanges", 200); + TC_PROPERTY("MaxRunSecs", 120); + INITIALIZER(createOrderedPkIndex); + INITIALIZER(runLoadTable); + INITIALIZER(takeResourceSnapshot); + STEPS(runScanReadIndexWithBounds,55); + FINALIZER(checkResourceSnapshot); + FINALIZER(createOrderedPkIndex_Drop); + FINALIZER(runClearTable); +} +TESTCASE("ScanKeyInfoExhaust", + "Test behaviour when TC keyinfo buffers exhausted with error insert") +{ + /* Use error insert 8094 to cause keyinfo exhaustion, then run a single scan + * with keyinfo to hit the error path + */ + TC_PROPERTY("MaxRunSecs", 10); + INITIALIZER(createOrderedPkIndex); + INITIALIZER(runLoadTable); + INITIALIZER(takeResourceSnapshot); + TC_PROPERTY("ErrorCode", 8094); + INITIALIZER(runInsertError); + STEP(runScanReadIndexWithBounds); + FINALIZER(checkResourceSnapshot); + FINALIZER(runInsertError); + FINALIZER(createOrderedPkIndex_Drop); + FINALIZER(runClearTable); +} + + + NDBT_TESTSUITE_END(testScan); int main(int argc, const char** argv){ === modified file 'storage/ndb/test/run-test/daily-basic-tests.txt' --- a/storage/ndb/test/run-test/daily-basic-tests.txt 2012-08-22 11:15:43 +0000 +++ b/storage/ndb/test/run-test/daily-basic-tests.txt 2012-09-12 15:11:40 +0000 @@ -1883,3 +1883,7 @@ max-time: 600 cmd: testRedo args: -n RestartFD -l 2 T1 +max-time : 300 +cmd: testScan +args: -n ScanKeyInfoExhaust T1 + No bundle (reason: useless for push emails).