merge [TRAFODION-3147]
diff --git a/core/conn/odbc/src/odbc/nsksrvrcore/srvrothers.cpp b/core/conn/odbc/src/odbc/nsksrvrcore/srvrothers.cpp
index b489afb..1af8f1e 100644
--- a/core/conn/odbc/src/odbc/nsksrvrcore/srvrothers.cpp
+++ b/core/conn/odbc/src/odbc/nsksrvrcore/srvrothers.cpp
@@ -5511,6 +5511,80 @@
, inputParam[4], inputParam[5]
);
break;
+ case SQL_API_SQLCOLUMNPRIVILEGES:
+ convertWildcard(metadataId, TRUE, catalogNm, expCatalogNm);
+ convertWildcardNoEsc(metadataId, TRUE, catalogNm, catalogNmNoEsc);
+ convertWildcard(metadataId, TRUE, schemaNm, expSchemaNm);
+ convertWildcardNoEsc(metadataId, TRUE, schemaNm, schemaNmNoEsc);
+ convertWildcard(metadataId, TRUE, tableNm, expTableNm);
+ convertWildcardNoEsc(metadataId, TRUE, tableNm, tableNmNoEsc);
+ convertWildcard(metadataId, TRUE, columnNm, expColumnNm);
+ convertWildcardNoEsc(metadataId, TRUE, columnNm, columnNmNoEsc);
+ inputParam[0] = catalogNmNoEsc;
+ inputParam[1] = expCatalogNm;
+ inputParam[2] = schemaNmNoEsc;
+ inputParam[3] = expSchemaNm;
+ inputParam[4] = tableNmNoEsc;
+ inputParam[5] = expTableNm;
+ inputParam[6] = columnNmNoEsc;
+ inputParam[7] = expColumnNm;
+ snprintf(CatalogQuery, sizeof(CatalogQuery), "select cast(mob.CATALOG_NAME as varchar(128)) TABLE_CAT,"
+ "cast(mob.SCHEMA_NAME as varchar(128)) TABLE_SCHEM,"
+ "cast(mob.OBJECT_NAME as varchar(128)) TABLE_NAME,"
+ "cast(mco.COLUMN_NAME as varchar(128)) COLUMN_NAME,"
+ "cast(pmcp.GRANTOR_NAME as varchar(128)) GRANTOR,"
+ "cast(pmcp.GRANTEE_NAME as varchar(128)) GRANTEE,"
+ "cast(trim(case pmcp.PRIVILEGES_BITMAP "
+ "when 1 then 'SELECT' "
+ "when 2 then 'INSERT' "
+ "when 3 then 'SELECT,INSERT' "
+ "when 4 then 'DELETE' "
+ "when 5 then 'SELECT,DELETE' "
+ "when 6 then 'INSERT,DELETE' "
+ "when 7 then 'SELECT,INSERT,DELETE' "
+ "when 8 then 'UPDATE' "
+ "when 9 then 'SELECT,UPDATE' "
+ "when 10 then 'INSERT,UPDATE' "
+ "when 11 then 'SELECT,INSERT,UPDATE' "
+ "when 12 then 'DELETE,UPDATE' "
+ "when 13 then 'SELECT,DELETE,UPDATE' "
+ "when 14 then 'INSERT,DELETE,UPDATE' "
+ "when 15 then 'SELECT,INSERT,DELETE,UPDATE' "
+ "when 32 then 'REFERENCES' "
+ "when 33 then 'SELECT,REFERENCES' "
+ "when 34 then 'INSERT,REFERENCES' "
+ "when 35 then 'SELECT,INSERT,REFERENCES' "
+ "when 36 then 'DELETE,REFERENCES' "
+ "when 37 then 'SELECT,DELETE,REFERENCES' "
+ "when 38 then 'INSERT,DELETE,REFERENCES' "
+ "when 39 then 'SELECT,INSERT,DELETE,REFERENCES' "
+ "when 40 then 'UPDATE,REFERENCES' "
+ "when 41 then 'SELECT,UPDATE,REFERENCES' "
+ "when 42 then 'INSERT,UPDATE,REFERENCES' "
+ "when 43 then 'SELECT,INSERT,UPDATE,REFERENCES' "
+ "when 44 then 'DELETE,UPDATE,REFERENCES' "
+ "when 45 then 'SELECT,DELETE,UPDATE,REFERENCES' "
+ "when 46 then 'INSERT,DELETE,UPDATE,REFERENCES' "
+ "when 47 then 'SELECT,INSERT,DELETE,UPDATE,REFERENCES' end) as varchar(128)) PRIVILEGE, "
+ "cast (trim(case pmcp.GRANTABLE_BITMAP "
+ "when 0 then 'NO' else 'YES' "
+ "end) as varchar(128)) IS_GRANTABLE "
+ "from TRAFODION.\"_MD_\".OBJECTS as mob, TRAFODION.\"_MD_\".COLUMNS as mco, TRAFODION.\"_PRIVMGR_MD_\".COLUMN_PRIVILEGES as pmcp "
+ "where pmcp.OBJECT_UID = mob.OBJECT_UID "
+ "and pmcp.OBJECT_UID = mco.OBJECT_UID "
+ "and pmcp.COLUMN_NUMBER = mco.COLUMN_NUMBER "
+ "and mco.COLUMN_NAME <> 'SYSKEY' "
+ "and (mob.CATALOG_NAME = '%s' or trim(mob.CATALOG_NAME) LIKE '%s' ESCAPE '\\') "
+ "and (mob.SCHEMA_NAME = '%s' or trim(mob.SCHEMA_NAME) LIKE '%s' ESCAPE '\\') "
+ "and (mob.OBJECT_NAME = '%s' or trim(mob.OBJECT_NAME) LIKE '%s' ESCAPE '\\') "
+ "and (mco.COLUMN_NAME = '%s' or trim(mco.COLUMN_NAME) LIKE '%s' ESCAPE '\\') "
+ "order by pmcp.COLUMN_NUMBER;",
+ inputParam[0], inputParam[1],
+ inputParam[2], inputParam[3],
+ inputParam[4], inputParam[5],
+ inputParam[6], inputParam[7]);
+
+ break;
default :
exception_->exception_nr = odbc_SQLSvc_GetSQLCatalogs_ParamError_exn_;
exception_->u.ParamError.ParamDesc = SQLSVC_EXCEPTION_UNSUPPORTED_SMD_API_TYPE;
diff --git a/core/conn/unixodbc/odbc/odbcclient/unixcli/cli/ctosqlconv.cpp b/core/conn/unixodbc/odbc/odbcclient/unixcli/cli/ctosqlconv.cpp
index 6b4c5eb..c26fbbb 100644
--- a/core/conn/unixodbc/odbc/odbcclient/unixcli/cli/ctosqlconv.cpp
+++ b/core/conn/unixodbc/odbc/odbcclient/unixcli/cli/ctosqlconv.cpp
@@ -353,10 +353,6 @@
if (errorMsg)
*errorMsg = '\0';
- //if (targetPrecision < 19)
- if(((SQLDataType == SQLTYPECODE_NUMERIC) && (targetPrecision <= 18)) ||
- ((SQLDataType == SQLTYPECODE_NUMERIC_UNSIGNED) && (targetPrecision <= 9)))
- getMaxNum(targetPrecision, targetScale, integralMax, decimalMax);
switch (ODBCDataType)
{
@@ -850,6 +846,7 @@
}
if(negative && targetUnsigned)
return IDS_22_003_02;
+ getMaxNum(targetPrecision, targetScale, integralMax, decimalMax);
if ((integralPart < 0) || (integralPart > integralMax))
return IDS_22_003;
decimalDigits = 0;
@@ -943,6 +940,7 @@
}
if(negative && targetUnsigned)
return IDS_22_003_02;
+ getMaxNum(targetPrecision, targetScale, integralMax, decimalMax);
if ((integralPart < 0) || (integralPart > integralMax))
return IDS_22_003;
decimalDigits = 0;
@@ -1539,6 +1537,7 @@
}
if(negative && targetUnsigned)
return IDS_22_003_02;
+ getMaxNum(targetPrecision, targetScale, integralMax, decimalMax);
if ((integralPart < 0) || (integralPart > integralMax))
return IDS_22_003;
decimalDigits = 0;
@@ -1595,6 +1594,7 @@
}
if(negative && targetUnsigned)
return IDS_22_003_02;
+ getMaxNum(targetPrecision, targetScale, integralMax, decimalMax);
if ((integralPart < 0) || (integralPart > integralMax))
return IDS_22_003;
decimalDigits = 0;
@@ -1704,6 +1704,7 @@
integralPart = (integralPart < 0)? -integralPart: integralPart;
decimalPart = 0;
leadZeros = 0;
+ getMaxNum(targetPrecision, targetScale, integralMax, decimalMax);
if ( integralPart > integralMax )
return IDS_22_003;
diff --git a/core/sqf/export/include/common/evl_sqlog_eventnum.h b/core/sqf/export/include/common/evl_sqlog_eventnum.h
index 8930ccc..10268d8 100644
--- a/core/sqf/export/include/common/evl_sqlog_eventnum.h
+++ b/core/sqf/export/include/common/evl_sqlog_eventnum.h
@@ -84,6 +84,7 @@
#define MON_CLUSTER_MARKDOWN_1 101011101
#define MON_CLUSTER_MARKDOWN_2 101011102
#define MON_CLUSTER_MARKDOWN_3 101011103
+#define MON_CLUSTER_MARKDOWN_4 101011104
//#define MON_CLUSTER_MARKUP 101011201
#define MON_CLUSTER_NODE_TM_READY_1 101011301
#define MON_CLUSTER_NODE_TM_READY_2 101011302
@@ -253,8 +254,16 @@
#define MON_CLUSTER_ASSIGNMONITORLEADER_2 101015302
#define MON_CLUSTER_ASSIGNMONITORLEADER_3 101015303
#define MON_CLUSTER_ASSIGNMONITORLEADER_4 101015304
+
#define MON_CLUSTER_CHECKIFDONE_1 101015401
+#define MON_CLUSTER_HARDNODEUPNS_1 101015501
+#define MON_CLUSTER_HARDNODEUPNS_2 101015502
+
+#define MON_CLUSTER_RECEIVESOCK_1 101015601
+
+#define MON_CLUSTER_SENDSOCK_1 101015701
+
/* Module: monitor.cxx = 02 */
#define MON_MONITOR_MAIN_1 101020101
@@ -1016,24 +1025,30 @@
#define ZCONFIG_DELETECONFIGZNODE_3 101381003
/* Module nameserver.cxx = 39 */
-#define MON_NAMESERVER_MKCLTSOCK_1 101390101
-#define MON_NAMESERVER_MKCLTSOCK_2 101390102
-#define MON_NAMESERVER_MKCLTSOCK_3 101390103
-#define MON_NAMESERVER_MKCLTSOCK_4 101390104
-#define MON_NAMESERVER_MKCLTSOCK_5 101390105
-#define MON_NAMESERVER_MKCLTSOCK_6 101390106
+#define NAMESERVER_CLIENTSOCKCREATE_1 101390101
+#define NAMESERVER_CLIENTSOCKCREATE_2 101390102
+#define NAMESERVER_CLIENTSOCKCREATE_3 101390103
+#define NAMESERVER_CLIENTSOCKCREATE_4 101390104
+#define NAMESERVER_CLIENTSOCKCREATE_5 101390105
+#define NAMESERVER_CLIENTSOCKCREATE_6 101390106
+#define NAMESERVER_SENDTONS_1 101390201
+#define NAMESERVER_SENDTONS_2 101390202
+#define NAMESERVER_SOCKRECEIVE_1 101390301
+#define NAMESERVER_SOCKSEND_1 101390401
+#define NAMESERVER_GETM2NPORT_1 101390501
+#define NAMESERVER_CHOOSENEXTNS_1 101390601
/* Module nscommaccept.cxx = 40 */
-#define NS_COMMACCEPT_1 101400101
-#define NS_COMMACCEPT_3 101400102
-#define NS_COMMACCEPT_2 101400103
-#define NS_COMMACCEPT_4 101400104
-#define NS_COMMACCEPT_5 101400105
-#define NS_COMMACCEPT_6 101400106
-#define NS_COMMACCEPT_7 101400107
-#define NS_COMMACCEPT_8 101400108
-#define NS_COMMACCEPT_9 101400109
-#define NS_COMMACCEPT_10 101400110
+#define NS_COMMACCEPT_PROCESSMONREQS_1 101400101
+#define NS_COMMACCEPT_PROCESSMONREQS_2 101400102
+#define NS_COMMACCEPT_PROCESSMONREQS_3 101400103
+#define NS_COMMACCEPT_PROCESSMONREQS_4 101400104
+#define NS_COMMACCEPT_PROCESSMONREQS_5 101400105
+#define NS_COMMACCEPT_PROCESSNEWSOCK_1 101400201
+#define NS_COMMACCEPT_COMMACCEPTORSOCK_1 101400301
+#define NS_COMMACCEPT_MON2NSACCEPTMON_1 101400401
+#define NS_COMMACCEPT_MON2NSPROCESS_1 101400501
+#define NS_COMMACCEPT_START_1 101400601
/* Module: reqnodedown.cxx = 41 */
#define MON_EXT_NAMESERVERDOWN_REQ 101410101
@@ -1067,6 +1082,8 @@
#define PTPCLIENT_STDINREQ_2 101930202
#define PTPCLIENT_STDIODATA_1 101930301
#define PTPCLIENT_STDIODATA_2 101930302
+#define PTPCLIENT_SENDTOMON_1 101930401
+#define PTPCLIENT_SENDTOMON_2 101930402
/* Module ptpcommaccept.cxx = 94 */
#define PTP_COMMACCEPT_1 101940101
diff --git a/core/sqf/monitor/linux/cluster.cxx b/core/sqf/monitor/linux/cluster.cxx
index 4d0d3c2..762c1a0 100644
--- a/core/sqf/monitor/linux/cluster.cxx
+++ b/core/sqf/monitor/linux/cluster.cxx
@@ -69,6 +69,7 @@
#include "nscommacceptmon.h"
#else
#include "nameserver.h"
+#include "ptpclient.h"
#endif
extern bool IAmIntegrating;
@@ -88,7 +89,9 @@
extern CCommAcceptMon CommAcceptMon;
extern char MyMon2NsPort[MPI_MAX_PORT_NAME];
#else
+extern CProcess *NameServerProcess;
extern CNameServer *NameServer;
+extern CPtpClient *PtpClient;
extern bool NameServerEnabled;
extern char MyPtPPort[MPI_MAX_PORT_NAME];
#endif
@@ -1069,12 +1072,11 @@
}
+#ifndef NAMESERVER_PROCESS
void CCluster::HardNodeDown (int pnid, bool communicate_state)
{
-#ifndef NAMESERVER_PROCESS
char port_fname[MAX_PROCESS_PATH];
char temp_fname[MAX_PROCESS_PATH];
-#endif
CNode *node;
CLNode *lnode;
char buf[MON_STRING_BUF_SIZE];
@@ -1130,7 +1132,6 @@
return;
}
-#ifndef NAMESERVER_PROCESS
if ( !Emulate_Down )
{
if( !IsRealCluster )
@@ -1161,7 +1162,6 @@
remove(temp_fname);
rename(port_fname, temp_fname);
}
-#endif
if (node->GetState() != State_Down || !node->isInQuiesceState())
{
@@ -1194,9 +1194,7 @@
if ( ! Emulate_Down )
{
// make sure no processes are alive if in the middle of re-integration
-#ifndef NAMESERVER_PROCESS
node->KillAllDown();
-#endif
snprintf(buf, sizeof(buf),
"[CCluster::HardNodeDown], Node %s (%d)is down.\n",
node->GetName(), node->GetPNid());
@@ -1212,29 +1210,29 @@
}
else
{
- if ( node->GetPNid() == integratingPNid_ )
+ if (node->GetState() != State_Down)
{
- ResetIntegratingPNid();
- }
-#ifndef NAMESERVER_PROCESS
- node->KillAllDown();
-#endif
- node->SetState( State_Down );
- // Send node down message to local node's processes
- lnode = node->GetFirstLNode();
- for ( ; lnode; lnode = lnode->GetNextP() )
- {
- lnode->Down();
- }
- if ( ZClientEnabled )
- {
- ZClient->WatchNodeDelete( node->GetName() );
- ZClient->WatchNodeMasterDelete( node->GetName() );
+ if ( node->GetPNid() == integratingPNid_ )
+ {
+ ResetIntegratingPNid();
+ }
+ node->KillAllDown();
+ node->SetState( State_Down );
+ // Send node down message to local node's processes
+ lnode = node->GetFirstLNode();
+ for ( ; lnode; lnode = lnode->GetNextP() )
+ {
+ lnode->Down();
+ }
+ if ( ZClientEnabled )
+ {
+ ZClient->WatchNodeDelete( node->GetName() );
+ ZClient->WatchNodeMasterDelete( node->GetName() );
+ }
}
}
}
-#ifndef NAMESERVER_PROCESS
// we need to abort any active TmSync
if (( MyNode->GetTmSyncState() == SyncState_Start ) ||
( MyNode->GetTmSyncState() == SyncState_Continue ) ||
@@ -1245,21 +1243,79 @@
if (trace_settings & (TRACE_RECOVERY | TRACE_REQUEST | TRACE_SYNC | TRACE_TMSYNC))
trace_printf("%s@%d - Node %s (pnid=%d) TmSyncState updated (%d)(%s)\n", method_name, __LINE__, MyNode->GetName(), MyPNID, MyNode->GetTmSyncState(), SyncStateString( MyNode->GetTmSyncState() ));
}
-#endif
-#ifndef NAMESERVER_PROCESS
if ( Emulate_Down )
{
AssignTmLeader(pnid, false);
}
else
-#endif
{
AssignLeaders(pnid, node->GetName(), false);
}
TRACE_EXIT;
}
+#endif
+
+#ifdef NAMESERVER_PROCESS
+void CCluster::HardNodeDownNs( int pnid )
+{
+ CNode *node;
+ char buf[MON_STRING_BUF_SIZE];
+
+ const char method_name[] = "CCluster::HardNodeDownNs";
+ TRACE_ENTRY;
+
+ node = Nodes->GetNode(pnid);
+
+ if (trace_settings & (TRACE_REQUEST | TRACE_INIT | TRACE_RECOVERY))
+ trace_printf( "%s@%d - pnid=%d, state=%s, isInQuiesceState=%d,"
+ " (local pnid=%d, state=%s, isInQuiesceState=%d, "
+ "shutdown level=%d)\n", method_name, __LINE__,
+ pnid, StateString(node->GetState()),
+ node->isInQuiesceState(),
+ MyPNID, StateString(MyNode->GetState()),
+ MyNode->isInQuiesceState(), MyNode->GetShutdownLevel() );
+
+ if (( MyPNID == pnid ) &&
+ ( MyNode->GetState() == State_Down ||
+ MyNode->IsKillingNode() ) )
+ {
+ // we are coming down ... don't process it
+ if ( !IsRealCluster && MyNode->isInQuiesceState())
+ {
+ // in virtual env, this would be called after node quiescing,
+ // so continue with mark down processing.
+ }
+ else
+ {
+ return;
+ }
+ }
+
+ if (node->GetState() != State_Down)
+ {
+ snprintf( buf, sizeof(buf)
+ , "[%s], Node %s (%d) is going down.\n"
+ , method_name, node->GetName(), node->GetPNid());
+ mon_log_write(MON_CLUSTER_MARKDOWN_4, SQ_LOG_INFO, buf);
+
+ node->SetKillingNode( true );
+ node->DeleteAllDown();
+ node->SetState( State_Down );
+
+ if ( ZClientEnabled )
+ {
+ //ZClient->WatchNodeDelete( node->GetName() );
+ ZClient->WatchNodeMasterDelete( node->GetName() );
+ }
+ }
+
+ AssignLeaders(pnid, node->GetName(), false);
+
+ TRACE_EXIT;
+}
+#endif
void CCluster::SoftNodeDown( int pnid )
{
@@ -1651,8 +1707,10 @@
if ( nodeState == State_Down )
{
node->SetKillingNode( false );
+#ifndef NAMESERVER_PROCESS
if ( Emulate_Down )
{
+#endif
// Any DTMs running?
for ( int i=0; !tmCount && i < Nodes->GetPNodesCount(); i++ )
{
@@ -1706,6 +1764,7 @@
}
}
}
+#ifndef NAMESERVER_PROCESS
}
else
{
@@ -1714,6 +1773,7 @@
method_name, __LINE__ );
}
+#endif
}
else if ( nodeState == State_Merged )
{
@@ -1866,6 +1926,74 @@
return( rc );
}
+#ifdef NAMESERVER_PROCESS
+int CCluster::HardNodeUpNs( int pnid )
+{
+ int rc = 0;
+ CNode *node;
+ STATE nodeState;
+
+ const char method_name[] = "CCluster::HardNodeUpNs";
+ TRACE_ENTRY;
+
+ if (trace_settings & (TRACE_REQUEST | TRACE_INIT | TRACE_RECOVERY))
+ trace_printf( "%s@%d - pnid=%d, MyPNID = %d, currentNodes_=%d\n"
+ , method_name, __LINE__, pnid, MyPNID, currentNodes_ );
+
+ node = Nodes->GetNode( pnid );
+ if ( node == NULL )
+ {
+ if ( rc )
+ { // Handle error
+ char buf[MON_STRING_BUF_SIZE];
+ snprintf( buf, sizeof(buf)
+ , "[%s], Invalid node, pnid=%d\n"
+ , method_name, pnid );
+ mon_log_write(MON_CLUSTER_HARDNODEUPNS_1, SQ_LOG_ERR, buf);
+ return( -1 );
+ }
+ }
+
+ nodeState = node->GetState();
+
+ if (trace_settings & (TRACE_REQUEST | TRACE_INIT | TRACE_RECOVERY))
+ trace_printf( "%s@%d" " - Node state=%s" "\n"
+ , method_name, __LINE__, StateString( nodeState ) );
+
+ if ( nodeState != State_Up )
+ {
+ if ( nodeState == State_Down )
+ {
+ node->SetKillingNode( false );
+ // We need to remove any old process objects before we restart the node.
+ node->CleanUpProcesses();
+ node->SetState( State_Up );
+ if ( MyPNID != pnid )
+ {
+ // Let other monitors know this node is up
+ CReplNodeUp *repl = new CReplNodeUp(pnid);
+ Replicator.addItem(repl);
+ }
+ }
+ }
+ else
+ { // Handle error
+ char buf[MON_STRING_BUF_SIZE];
+ snprintf( buf, sizeof(buf)
+ , "[%s], Invalid node state, node %s, pnid=%d, state=%s\n"
+ , method_name
+ , node->GetName()
+ , node->GetPNid()
+ , StateString( nodeState ) );
+ mon_log_write(MON_CLUSTER_HARDNODEUPNS_2, SQ_LOG_ERR, buf);
+ return( -1 );
+ }
+
+ TRACE_EXIT;
+ return( rc );
+}
+#endif
+
int CCluster::SoftNodeUpPrepare( int pnid )
{
char buf[MON_STRING_BUF_SIZE];
@@ -7456,7 +7584,10 @@
case State_Unknown:
break;
case State_Down:
- doShutdown = true;
+ if (IsRealCluster)
+ {
+ doShutdown = true;
+ }
break;
case State_Stopped:
case State_Shutdown:
@@ -7780,19 +7911,23 @@
// let the watchdog process exit
HealthCheck.setState(MON_EXIT_PRIMITIVES);
}
- else if ( (MyNode->GetNumProcs() <= // only My Name Server alive
- myNameServerCount )
+ else if ( NameServerProcess != NULL
+ && myNameServerCount > 0
+ && (MyNode->GetNumProcs() <= myNameServerCount ) // only My Name Server alive
&& !MyNode->isInQuiesceState() // post-quiescing will
// expire WDG (cluster)
&& !waitForNameServerExit_ ) // Name Server not yet exiting
{
if (trace_settings & (TRACE_PROCESS | TRACE_PROCESS_DETAIL | TRACE_SYNC))
- trace_printf("%s@%d - Stopping Name Server process. "
- "(process count: cluster=%d, MyNode=%d)\n",
- method_name, __LINE__,
- Nodes->ProcessCount(), MyNode->ProcessCount());
-
+ {
+ trace_printf("%s@%d - Stopping Name Server process. "
+ "(process count: cluster=%d, MyNode=%d)\n",
+ method_name, __LINE__,
+ Nodes->ProcessCount(), MyNode->ProcessCount());
+ }
+
waitForNameServerExit_ = true;
+ MyNode->SetProcessState( NameServerProcess, State_Down, false );
int rc = NameServer->ProcessShutdown();
if (rc)
{
@@ -10196,6 +10331,14 @@
if ( errno != EINTR)
{
error = errno;
+ char la_buf[MON_STRING_BUF_SIZE];
+ sprintf( la_buf, "[%s], recv(), received=%d, sock=%d, error=%d(%s), desc=%s\n"
+ , method_name
+ , received
+ , sockFd
+ , error, strerror(error)
+ , desc );
+ mon_log_write(MON_CLUSTER_RECEIVESOCK_1, SQ_LOG_ERR, la_buf);
readAgain = false;
}
else
@@ -10264,6 +10407,14 @@
if ( errno != EINTR)
{
error = errno;
+ char la_buf[MON_STRING_BUF_SIZE];
+ sprintf( la_buf, "[%s], send(), sent=%d, sock=%d, error=%d(%s), desc=%s\n"
+ , method_name
+ , sent
+ , sockFd
+ , error, strerror(error)
+ , desc );
+ mon_log_write(MON_CLUSTER_SENDSOCK_1, SQ_LOG_ERR, la_buf);
sendAgain = false;
}
else
diff --git a/core/sqf/monitor/linux/cluster.h b/core/sqf/monitor/linux/cluster.h
index 970cf4c..2dfbfb8 100644
--- a/core/sqf/monitor/linux/cluster.h
+++ b/core/sqf/monitor/linux/cluster.h
@@ -163,7 +163,11 @@
int GetConfigPNodesMax() { return configPNodesMax_; }
bool ImAlive( bool needed=false, struct sync_def *sync = NULL );
int MapRank( int current_rank );
+#ifndef NAMESERVER_PROCESS
void HardNodeDown( int nid, bool communicate_state=false );
+#else
+ void HardNodeDownNs( int nid );
+#endif
void SoftNodeDown( int pnid );
int SoftNodeUpPrepare( int pnid );
bool CheckSpareSet( int pnid );
@@ -174,6 +178,9 @@
void ResetIntegratingPNid( void );
void SetIntegratingPNid( int pnid );
int HardNodeUp( int pnid, char *node_name );
+#ifdef NAMESERVER_PROCESS
+ int HardNodeUpNs( int pnid );
+#endif
inline CNode *GetIntegratingNode() { return Node[integratingPNid_]; }
inline CNode *GetNode( int pnid ) { return Node[pnid]; }
static char *Timestamp( void );
diff --git a/core/sqf/monitor/linux/commaccept.cxx b/core/sqf/monitor/linux/commaccept.cxx
index 5c4e3a5..13c2ebd 100644
--- a/core/sqf/monitor/linux/commaccept.cxx
+++ b/core/sqf/monitor/linux/commaccept.cxx
@@ -220,12 +220,18 @@
, i, node->GetPNid(), node->GetName());
}
- nodeInfo[i].pnid = -1;
nodeInfo[i].nodeName[0] = '\0';
nodeInfo[i].commPort[0] = '\0';
nodeInfo[i].syncPort[0] = '\0';
+ nodeInfo[i].pnid = -1;
nodeInfo[i].creatorPNid = -1;
}
+ nodeInfo[i].creatorShellPid = -1;
+ nodeInfo[i].creatorShellVerifier = -1;
+ nodeInfo[i].creator = false;
+ nodeInfo[i].ping = false;
+ nodeInfo[i].nsPid = -1;
+ nodeInfo[i].nsPNid = -1;
}
if (trace_settings & (TRACE_INIT | TRACE_RECOVERY))
diff --git a/core/sqf/monitor/linux/config.cxx b/core/sqf/monitor/linux/config.cxx
index 4ef9b72..9794199 100644
--- a/core/sqf/monitor/linux/config.cxx
+++ b/core/sqf/monitor/linux/config.cxx
@@ -1193,7 +1193,7 @@
regClusterEntry->valueLength = strlen (regClusterConfig[i].value);
if (trace_settings & (TRACE_INIT | TRACE_REQUEST))
{
- trace_printf ("%s%d pack type %d, scope %s (%d), key %s (%d), value %s(%d)\n",method_name, __LINE__,
+ trace_printf ("%s@%d pack type %d, scope %s (%d), key %s (%d), value %s(%d)\n",method_name, __LINE__,
regClusterEntry->type, regClusterConfig[i].scope,
regClusterEntry->scopeLength,regClusterConfig[i].key,regClusterEntry->keyLength,
regClusterConfig[i].value, regClusterEntry->valueLength);
@@ -1226,7 +1226,7 @@
if (regClusterConfig)
{
- delete regClusterConfig;
+ delete [] regClusterConfig;
}
return numberOfEntries;
@@ -1258,7 +1258,7 @@
if (trace_settings & (TRACE_INIT | TRACE_REQUEST))
{
- trace_printf ("%s%d scope length %d, key length %d, value length %d\n", method_name, __LINE__,
+ trace_printf ("%s@%d scope length %d, key length %d, value length %d\n", method_name, __LINE__,
clusterObj2->scopeLength,
clusterObj2->keyLength, clusterObj2->valueLength);
}
@@ -1317,7 +1317,7 @@
stringObj->stringLength = strlen(unique_string);
if (trace_settings & (TRACE_INIT | TRACE_REQUEST))
{
- trace_printf ("%s%d packing nid %d, unique id %d, stringt %s (length %d)\n", method_name, __LINE__,
+ trace_printf ("%s@%d packing nid %d, unique id %d, stringt %s (length %d)\n", method_name, __LINE__,
pnid, maxId, unique_string,stringObj->stringLength );
}
stringObj->unique_id = maxId;
diff --git a/core/sqf/monitor/linux/healthcheck.cxx b/core/sqf/monitor/linux/healthcheck.cxx
index 1f344fc..203465c 100644
--- a/core/sqf/monitor/linux/healthcheck.cxx
+++ b/core/sqf/monitor/linux/healthcheck.cxx
@@ -54,7 +54,6 @@
#include "redirector.h"
#include "replicate.h"
-
extern CReqQueue ReqQueue;
extern CMonitor *Monitor;
extern CNode *MyNode;
@@ -64,6 +63,7 @@
extern CHealthCheck HealthCheck;
extern CReplicate Replicator;
extern int MyPNID;
+extern bool IsRealCluster;
// constructor
CHealthCheck::CHealthCheck()
@@ -229,7 +229,6 @@
TRACE_ENTRY;
HealthCheckStates state;
-
struct timespec ts;
if (trace_settings & TRACE_HEALTH)
diff --git a/core/sqf/monitor/linux/internal.h b/core/sqf/monitor/linux/internal.h
index 35fa32a..5dc6456 100644
--- a/core/sqf/monitor/linux/internal.h
+++ b/core/sqf/monitor/linux/internal.h
@@ -537,5 +537,10 @@
char msg[MAX_SYNC_SIZE];
};
+typedef struct ptpMsgInfo
+{
+ int pnid; // Current offset into the msg buffer
+ int size; // Number if messages to replicate
+} ptpMsgInfo_t;
#endif
diff --git a/core/sqf/monitor/linux/lnode.cxx b/core/sqf/monitor/linux/lnode.cxx
index 69a186d..bbe5ac4 100644
--- a/core/sqf/monitor/linux/lnode.cxx
+++ b/core/sqf/monitor/linux/lnode.cxx
@@ -41,6 +41,7 @@
#include "lnode.h"
#include "pnode.h"
#include "mlio.h"
+#include "nameserver.h"
extern bool IsRealCluster;
extern CommType_t CommType;
@@ -50,6 +51,10 @@
extern CMonStats *MonStats;
extern bool usingCpuAffinity;
extern bool usingTseCpuAffinity;
+#ifndef NAMESERVER_PROCESS
+extern CNameServer *NameServer;
+extern bool NameServerEnabled;
+#endif
void CoreMaskString( char *str, cpu_set_t coreMask, int totalCores )
{
@@ -396,7 +401,12 @@
, method_name, __LINE__, GetNid()
, GetNode()->GetName(), msg->u.request.u.down.takeover );
}
-
+#ifndef NAMESERVER_PROCESS
+ if ( NameServerEnabled )
+ {
+ NameServer->ProcessNodeDown( Nid, msg->u.request.u.down.node_name );
+ }
+#endif
MyNode->Bcast( msg );
delete msg;
}
diff --git a/core/sqf/monitor/linux/makefile b/core/sqf/monitor/linux/makefile
index 73127e4..3d16bab 100644
--- a/core/sqf/monitor/linux/makefile
+++ b/core/sqf/monitor/linux/makefile
@@ -265,6 +265,7 @@
NSOBJS += $(OUTDIR)/nsreqdelproc.o
NSOBJS += $(OUTDIR)/nsreqstop.o
NSOBJS += $(OUTDIR)/nsreqnewproc.o
+NSOBJS += $(OUTDIR)/nsreqnodedown.o
NSOBJS += $(OUTDIR)/nsreqprocinfo.o
NSOBJS += $(OUTDIR)/nsreqprocinfons.o
NSOBJS += $(OUTDIR)/nsreqstart.o
diff --git a/core/sqf/monitor/linux/monitor.cxx b/core/sqf/monitor/linux/monitor.cxx
index d588945..2ad0528 100755
--- a/core/sqf/monitor/linux/monitor.cxx
+++ b/core/sqf/monitor/linux/monitor.cxx
@@ -1367,7 +1367,8 @@
env = getenv("SQ_NAMESERVER_ENABLED");
if ( env && isdigit(*env) )
{
- NameServerEnabled = atoi(env);
+ int val = atoi(env);
+ NameServerEnabled = (val != 0) ? true : false;
}
#endif
@@ -1605,6 +1606,7 @@
}
setlinebuf(stdout);
+#ifndef NAMESERVER_PROCESS
// Send stderr output to same file as stdout. (Note: the monitor does
// not write to stderr but perhaps there could be components included in
// the monitor build that do write to stderr.)
@@ -1612,6 +1614,10 @@
{
printf ( "dup2 failed for stderr: %s (%d)\n", strerror(errno), errno);
}
+#else
+ // Name Server is a child process of the monitor, the process create logic
+ // will establish IO redirection between the monitor process and the child.
+#endif
switch( CommType )
{
@@ -2052,13 +2058,15 @@
#ifdef NAMESERVER_PROCESS
Monitor = new CMonitor ();
#else
- Monitor = new CMonitor (procTermSig);
-#endif
-#ifndef NAMESERVER_PROCESS
if (NameServerEnabled)
{
+ PtpClient = new CPtpClient ();
+ Monitor = new CMonitor (procTermSig);
NameServer = new CNameServer ();
- PtpClient = new CPtpClient ();
+ }
+ else
+ {
+ Monitor = new CMonitor (procTermSig);
}
#endif
diff --git a/core/sqf/monitor/linux/msgdef.h b/core/sqf/monitor/linux/msgdef.h
index 639c15c..8218a8e 100644
--- a/core/sqf/monitor/linux/msgdef.h
+++ b/core/sqf/monitor/linux/msgdef.h
@@ -89,7 +89,7 @@
#define MAX_PROCINFO_LIST 64
#define MAX_PROC_CONTEXT 5
#define MAX_PROCESS_NAME MAX_KEY_NAME
-#define MAX_PROCESS_NAME_STR 12
+#define MAX_PROCESS_NAME_STR 13
#define MAX_PROCESS_PATH 256
#define MAX_PROCESSOR_NAME 128
#define MAX_RECONN_PING_WAIT_TIMEOUT 5
diff --git a/core/sqf/monitor/linux/nameserver.cxx b/core/sqf/monitor/linux/nameserver.cxx
index e9f1900..ad024f6 100644
--- a/core/sqf/monitor/linux/nameserver.cxx
+++ b/core/sqf/monitor/linux/nameserver.cxx
@@ -44,6 +44,7 @@
#include <limits.h>
#include <unistd.h>
+#include "trafconf/trafconfig.h"
#include "lnode.h"
#include "pnode.h"
#include "nameserver.h"
@@ -51,21 +52,24 @@
#include "montrace.h"
#include "nameserverconfig.h"
#include "meas.h"
+#include "reqqueue.h"
extern CNode *MyNode;
extern CProcess *NameServerProcess;
extern CNodeContainer *Nodes;
+extern CReqQueue ReqQueue;
extern bool IsRealCluster;
extern int MyPNID;
extern CNameServerConfigContainer *NameServerConfig;
extern CMeas Meas;
+#define NAMESERVER_IO_RETRIES 3
+
CNameServer::CNameServer( void )
-: mon2nsSock_(-1)
-, nsConfigInx_(-1)
-, nsStartupComplete_(false)
-, seqNum_(0)
-, shutdown_(false)
+ : mon2nsSock_(-1)
+ , nsStartupComplete_(false)
+ , seqNum_(0)
+ , shutdown_(false)
{
const char method_name[] = "CNameServer::CNameServer";
TRACE_ENTRY;
@@ -84,7 +88,7 @@
TRACE_EXIT;
}
-void CNameServer::ChooseNextNs( void )
+int CNameServer::ChooseNextNs( void )
{
const char method_name[] = "CNameServer::ChooseNextNs";
TRACE_ENTRY;
@@ -103,17 +107,58 @@
{
config = config->GetNext();
}
- strcpy( mon2nsHost_, config->GetName() );
- if ( trace_settings & TRACE_NS )
+ CNode *node = Nodes->GetNode( (char*) config->GetName() );
+ if (node && node->GetState() == State_Up)
{
- trace_printf( "%s@%d - nameserver=%s, rnd=%d, cnt=%d\n"
- , method_name, __LINE__
- , mon2nsHost_
- , rnd
- , cnt );
+ strcpy( mon2nsHost_, config->GetName() );
+ if ( trace_settings & TRACE_NS )
+ {
+ trace_printf( "%s@%d - nameserver=%s, rnd=%d, cnt=%d\n"
+ , method_name, __LINE__
+ , mon2nsHost_
+ , rnd
+ , cnt );
+ }
+ }
+ else
+ {
+ config = config->GetNext()?config->GetNext():NameServerConfig->GetFirstConfig();
+ while (config)
+ {
+ node = Nodes->GetNode( (char*) config->GetName() );
+ if (node && node->GetState() != State_Up)
+ {
+ config = config->GetNext();
+ continue;
+ }
+
+ strcpy( mon2nsHost_, config->GetName() );
+ if ( trace_settings & TRACE_NS )
+ {
+ trace_printf( "%s@%d - selected alternate nameserver=%s\n"
+ , method_name, __LINE__
+ , mon2nsHost_ );
+ }
+ break;
+ }
+ }
+
+ if (strlen(mon2nsHost_) == 0)
+ {
+ char la_buf[MON_STRING_BUF_SIZE];
+ sprintf( la_buf
+ , "[%s], No Name Server nodes available.\n"
+ "Scheduling shutdown (abrupt)!\n"
+ , method_name );
+ mon_log_write(NAMESERVER_CHOOSENEXTNS_1, SQ_LOG_CRIT, la_buf );
+ ReqQueue.enqueueShutdownReq( ShutdownLevel_Abrupt );
+
+ TRACE_EXIT;
+ return( -2 );
}
TRACE_EXIT;
+ return( 0 );
}
int CNameServer::ConnectToNs( bool *retry )
@@ -123,21 +168,32 @@
int err = 0;
+reconnect:
+
if ( !mon2nsPort_[0] )
- CNameServer::GetM2NPort( -1 );
- if ( !mon2nsHost_[0] )
- ChooseNextNs();
+ {
+ err = GetM2NPort( -1 );
+ }
+ if ( err == 0 && !mon2nsHost_[0] )
+ {
+ err = ChooseNextNs();
+ }
int sock = 0;
if ( shutdown_ )
+ {
err = -1;
+ }
if ( err == 0 )
{
- sock = SockCreate();
+ sock = ClientSockCreate();
if ( sock < 0 )
+ {
err = sock;
+ goto reconnect;
+ }
}
if ( err == 0 )
{
@@ -191,7 +247,7 @@
, nodeId.ping );
}
err = SockSend( ( char *) &nodeId, sizeof(nodeId) );
- if ( err == 0 )
+ if (err == 0)
{
if ( trace_settings & TRACE_NS )
{
@@ -252,7 +308,7 @@
if ( IsRealCluster )
{
CNode *node = Nodes->GetNode( nodeId.nsPNid );
- if ( node )
+ if (node && node->GetState() == State_Up)
{
strcpy( mon2nsHost_, node->GetName() );
GetM2NPort( nodeId.nsPNid );
@@ -273,50 +329,123 @@
return err;
}
-void CNameServer::GetM2NPort( int PNid )
+int CNameServer::GetM2NPort( int nsPNid )
{
+ const char method_name[] = "CNameServer::GetM2NPort";
+ TRACE_ENTRY;
+
+ bool done = false;
int port;
char *p = getenv( "NS_M2N_COMM_PORT" );
if ( p )
+ {
port = atoi(p);
+ }
else
+ {
port = 0;
+ }
if ( !IsRealCluster )
- port += PNid < 0 ? MyPNID : PNid;
+ {
+ // choose initial port
+ int nsMax = NameServerConfig->GetCount();
+ int candidatePNid = nsPNid < 0 ? MyPNID : nsPNid;
+ int chosenPNid =
+ candidatePNid < nsMax ? candidatePNid : candidatePNid%nsMax;
+ int lastChosenPNid = chosenPNid;
+ while (!done)
+ {
+ // check that corresponding node is UP
+ // node is up, chosen is good to go
+ // not up,
+ // round-robin on other name server nodes and chose 1st up node
+ // no name server nodes available
+ // log event and down my node (MyPNID)
+ CNode *node = Nodes->GetNode( chosenPNid );
+ if (node && node->GetState() == State_Up)
+ {
+ port += chosenPNid;
+
+ if ( trace_settings & TRACE_NS )
+ {
+ trace_printf( "%s@%d - nsMax=%d, nsPNid=%d, MyPNID=%d, "
+ "candidatePNid=%d, chosenPNid=%d, port=%d\n"
+ , method_name, __LINE__
+ , nsMax
+ , nsPNid
+ , MyPNID
+ , candidatePNid
+ , chosenPNid
+ , port );
+ }
+ done = true;
+ }
+ else
+ {
+ chosenPNid = (chosenPNid+1) < nsMax ? (chosenPNid+1) : 0;
+ if (chosenPNid == lastChosenPNid)
+ {
+ char la_buf[MON_STRING_BUF_SIZE];
+ sprintf( la_buf
+ , "[%s], No Name Server nodes available, "
+ "chosenPNid=%d, lastChosenPNid=%d.\n"
+ "Scheduling shutdown (abrupt)!\n"
+ , method_name
+ , chosenPNid, lastChosenPNid );
+ mon_log_write(NAMESERVER_GETM2NPORT_1, SQ_LOG_CRIT, la_buf );
+ ReqQueue.enqueueShutdownReq( ShutdownLevel_Abrupt );
+ done = true;
+ }
+ port += chosenPNid;
+ TRACE_EXIT;
+ return( -2 );
+ }
+ }
+ }
sprintf( mon2nsPort_, "%d", port );
-}
-
-void CNameServer::SetLocalHost( void )
-{
- gethostname( mon2nsHost_, MAX_PROCESSOR_NAME );
-}
-
-void CNameServer::SetShutdown( bool shutdown )
-{
- const char method_name[] = "CNameServer::SetShutdown";
- TRACE_ENTRY;
-
- if ( trace_settings & TRACE_NS )
- trace_printf( "%s@%d - set shutdown_=%d\n"
- , method_name, __LINE__, shutdown );
- shutdown_ = shutdown;
TRACE_EXIT;
+ return( 0 );
}
-void CNameServer::SockClose( void )
+bool CNameServer::IsNameServerConfigured( int pnid )
{
- const char method_name[] = "CNameServer::SockClose";
+ const char method_name[] = "CNameServer::IsNameServerConfigured";
TRACE_ENTRY;
- close( mon2nsSock_ );
- mon2nsSock_ = -1;
+ bool rs = false;
+
+ if ( IsRealCluster )
+ {
+ CNameServerConfig *config;
+ CNode *node = Nodes->GetNode( pnid );
+ if ( node )
+ {
+ config = NameServerConfig->GetConfig( node->GetName() );
+ if ( config )
+ {
+ rs = true;
+ }
+ }
+ }
+ else
+ {
+ rs = pnid < NameServerConfig->GetCount() ? true : false;
+ }
+
+ if (trace_settings & (TRACE_INIT | TRACE_RECOVERY))
+ {
+ trace_printf( "%s@%d - pnid=%d, configured=%s\n"
+ , method_name, __LINE__, pnid, rs?"True":"False" );
+ }
+
TRACE_EXIT;
+ return(rs);
}
-int CNameServer::SockCreate( void )
+int CNameServer::ClientSockCreate( void )
{
- const char method_name[] = "CNameServer::SockCreate";
+ const char method_name[] = "CNameServer::ClientSockCreate";
TRACE_ENTRY;
int sock; // socket
@@ -363,7 +492,8 @@
snprintf( la_buf, sizeof(la_buf)
, "[%s], socket() failed! errno=%d (%s)\n"
, method_name, err, strerror(err) );
- mon_log_write( MON_NAMESERVER_MKCLTSOCK_1, SQ_LOG_ERR, la_buf );
+ mon_log_write( NAMESERVER_CLIENTSOCKCREATE_1, SQ_LOG_ERR, la_buf );
+ TRACE_EXIT;
return ( -1 );
}
@@ -375,8 +505,9 @@
snprintf( la_buf, sizeof(la_buf ),
"[%s] gethostbyname(%s) failed! errno=%d (%s)\n"
, method_name, host, err, strerror(err) );
- mon_log_write(MON_NAMESERVER_MKCLTSOCK_2, SQ_LOG_ERR, la_buf );
+ mon_log_write(NAMESERVER_CLIENTSOCKCREATE_2, SQ_LOG_ERR, la_buf );
close( sock );
+ TRACE_EXIT;
return ( -1 );
}
@@ -418,7 +549,7 @@
int err = errno;
sprintf( la_buf, "[%s], connect() failed! errno=%d (%s)\n"
, method_name, err, strerror(err) );
- mon_log_write(MON_NAMESERVER_MKCLTSOCK_3, SQ_LOG_ERR, la_buf );
+ mon_log_write(NAMESERVER_CLIENTSOCKCREATE_3, SQ_LOG_ERR, la_buf );
struct timespec req, rem;
req.tv_sec = 0;
req.tv_nsec = 500000000L; // 500,000,000
@@ -439,8 +570,9 @@
char la_buf[MON_STRING_BUF_SIZE];
sprintf( la_buf, "[%s], connect() exceeded retries! count=%d\n"
, method_name, retries );
- mon_log_write(MON_NAMESERVER_MKCLTSOCK_4, SQ_LOG_ERR, la_buf );
+ mon_log_write(NAMESERVER_CLIENTSOCKCREATE_4, SQ_LOG_ERR, la_buf );
close( sock );
+ TRACE_EXIT;
return ( -1 );
}
struct timespec req, rem;
@@ -449,6 +581,8 @@
nanosleep( &req, &rem );
}
close( sock );
+ TRACE_EXIT;
+ return( -1 );
}
if ( trace_settings & TRACE_NS )
@@ -470,8 +604,9 @@
int err = errno;
sprintf( la_buf, "[%s], setsockopt() failed! errno=%d (%s)\n"
, method_name, err, strerror(err) );
- mon_log_write(MON_NAMESERVER_MKCLTSOCK_5, SQ_LOG_ERR, la_buf );
+ mon_log_write(NAMESERVER_CLIENTSOCKCREATE_5, SQ_LOG_ERR, la_buf );
close( sock );
+ TRACE_EXIT;
return ( -2 );
}
@@ -481,8 +616,9 @@
int err = errno;
sprintf( la_buf, "[%s], setsockopt() failed! errno=%d (%s)\n"
, method_name, err, strerror(err) );
- mon_log_write(MON_NAMESERVER_MKCLTSOCK_6, SQ_LOG_ERR, la_buf );
+ mon_log_write(NAMESERVER_CLIENTSOCKCREATE_6, SQ_LOG_ERR, la_buf );
close( sock );
+ TRACE_EXIT;
return ( -2 );
}
@@ -490,6 +626,19 @@
return ( sock );
}
+void CNameServer::NameServerExited( void )
+{
+ const char method_name[] = "CNameServer::NameServerExited";
+ TRACE_ENTRY;
+
+ mon2nsHost_[0] = '\0';
+ mon2nsPort_[0] = '\0';
+ nsStartupComplete_ = false;
+ SockClose();
+
+ TRACE_EXIT;
+}
+
int CNameServer::NameServerStop( struct message_def* msg )
{
const char method_name[] = "CNameServer::NameServerStop";
@@ -599,9 +748,6 @@
msgnew->unhooked = process->IsUnhooked();
msgnew->event_messages = process->IsEventMessages();
msgnew->system_messages = process->IsSystemMessages();
-// msgnew->pathStrId = process->pathStrId();
-// msgnew->ldpathStrId = process->ldPathStrId();
-// msgnew->programStrId = process->programStrId();
strcpy( msgnew->path, process->path() );
strcpy( msgnew->ldpath, process->ldpath() );
strcpy( msgnew->program, process->program() );
@@ -682,6 +828,45 @@
return error;
}
+int CNameServer::ProcessNodeDown( int nid, char *nodeName )
+{
+ const char method_name[] = "CNameServer::ProcessNodeDown";
+ TRACE_ENTRY;
+
+ int error = 0;
+ CProcess *process = MyNode->GetProcessByType( ProcessType_NameServer );
+ if (process)
+ {
+ struct message_def msg;
+ memset(&msg, 0, sizeof(msg) ); // TODO: remove!
+ msg.type = MsgType_Service;
+ msg.noreply = false;
+ msg.reply_tag = seqNum_++;
+ msg.u.request.type = ReqType_NodeDown;
+ struct NodeDown_def *msgdown = &msg.u.request.u.down;
+ msgdown->nid = nid;
+ strcpy( msgdown->node_name, nodeName );
+ msgdown->takeover = 0;
+ msgdown->reason[0] = 0;
+
+ if ( trace_settings & TRACE_NS )
+ {
+ trace_printf( "%s@%d - sending node-down request to nameserver=%s:%s\n"
+ " msg.down.nid=%d\n"
+ " msg.down.node_name=%s\n"
+ , method_name, __LINE__
+ , mon2nsHost_, mon2nsPort_
+ , msgdown->nid
+ , msgdown->node_name );
+ }
+
+ error = SendReceive(&msg );
+ }
+
+ TRACE_EXIT;
+ return error;
+}
+
int CNameServer::ProcessShutdown( void )
{
const char method_name[] = "CNameServer::ProcessShutdown";
@@ -696,7 +881,6 @@
struct ShutdownNs_def *msgshutdown = &msg.u.request.u.shutdown_ns;
msgshutdown->nid = -1;
msgshutdown->pid = -1;
- //msgshutdown->level = msgIn->u.request.u.shutdown.level;
msgshutdown->level = ShutdownLevel_Normal;
int error = SendReceive(&msg );
@@ -711,16 +895,20 @@
int CNameServer::SendReceive( struct message_def* msg )
{
const char method_name[] = "CNameServer::SendReceive";
+ TRACE_ENTRY;
+
+ int retryCount = 0;
char desc[256];
char* descp;
- struct DelProcessNs_def *msgdel;
- struct NewProcessNs_def *msgnew;
- struct ShutdownNs_def *msgshutdown;
- struct NameServerStart_def *msgstart;
- struct NameServerStop_def *msgstop;
- struct ProcessInfo_def *msginfo;
-
- TRACE_ENTRY;
+ struct DelProcessNs_def* msgdel;
+ struct NameServerStart_def* msgstart;
+ struct NameServerStop_def* msgstop;
+ struct NewProcessNs_def* msgnew;
+ struct NodeDown_def* msgdown;
+ struct ProcessInfo_def* msginfo;
+ struct ShutdownNs_def* msgshutdown;
+ struct message_def msg_reply;
+ struct message_def* pmsg_reply = &msg_reply;
descp = desc;
int size = offsetof(struct message_def, u.request.u);
@@ -750,6 +938,13 @@
msgnew->nid, msgnew->pid, msgnew->verifier, msgnew->process_name );
size += sizeof(msg->u.request.u.new_process_ns);
break;
+ case ReqType_NodeDown:
+ msgdown = &msg->u.request.u.down;
+ sprintf( desc, "node-down (nid=%d, node-name=%s, takeover=%d, reason=%s)",
+ msgdown->nid, msgdown->node_name,
+ msgdown->takeover, msgdown->reason );
+ size += sizeof(msg->u.request.u.down);
+ break;
case ReqType_ProcessInfo:
msginfo = &msg->u.request.u.process_info;
sprintf( desc, "process-info (nid=%d, pid=%d, verifier=%d, name=%s)\n"
@@ -774,7 +969,7 @@
break;
case ReqType_ShutdownNs:
msgshutdown = &msg->u.request.u.shutdown_ns;
- sprintf( desc, "shutdown (nid=%d, pid=%d, level=%d)",
+ sprintf( desc, "shutdown-ns (nid=%d, pid=%d, level=%d)",
msgshutdown->nid, msgshutdown->pid, msgshutdown->level );
size += sizeof(msg->u.request.u.shutdown_ns);
break;
@@ -783,13 +978,16 @@
break;
}
+retryIO:
+
int error = SendToNs( descp, msg, size );
if ( error == 0 )
error = SockReceive( (char *) &size, sizeof(size ) );
if ( error == 0 )
- error = SockReceive( (char *) msg, size );
+ error = SockReceive( (char *) pmsg_reply, size );
if ( error == 0 )
{
+ memcpy( msg, pmsg_reply, size );
if ( trace_settings & ( TRACE_NS | TRACE_PROCESS ) )
{
char desc[2048];
@@ -827,7 +1025,6 @@
msg->u.reply.u.process_info.more_data );
break;
case ReplyType_ProcessInfoNs:
-// int argvLen = sizeof(msg->u.reply.u.process_info_ns.argv);
sprintf( desc,
"process-info-ns reply:\n"
" process_info_ns.nid=%d\n"
@@ -847,18 +1044,14 @@
" process_info_ns.path=%s\n"
" process_info_ns.ldpath=%s\n"
" process_info_ns.program=%s\n"
-// " process_info_ns.pathStrId=%d:%d\n"
-// " process_info_ns.ldpathStrId=%d:%d\n"
-// " process_info_ns.programStrId=%d:%d\n"
" process_info_ns.port_name=%s\n"
" process_info_ns.argc=%d\n"
-// " process_info_ns.argv=[%.*s]\n"
" process_info_ns.infile=%s\n"
" process_info_ns.outfile=%s\n"
-//#if 0
-// " process_info_ns.creation_time=%ld(secs)\n",
-// " process_info_ns.creation_time=%ld(secs):%ld(nsecs)\n",
-//#endif
+#if 0
+ " process_info_ns.creation_time=%ld(secs)\n",
+ " process_info_ns.creation_time=%ld(secs):%ld(nsecs)\n",
+#endif
" process_info_ns.return_code=%d"
, msg->u.reply.u.process_info_ns.nid
, msg->u.reply.u.process_info_ns.pid
@@ -877,21 +1070,14 @@
, msg->u.reply.u.process_info_ns.path
, msg->u.reply.u.process_info_ns.ldpath
, msg->u.reply.u.process_info_ns.program
-// , msg->u.reply.u.process_info_ns.pathStrId.nid
-// , msg->u.reply.u.process_info_ns.pathStrId.id
-// , msg->u.reply.u.process_info_ns.ldpathStrId.nid
-// , msg->u.reply.u.process_info_ns.ldpathStrId.id
-// , msg->u.reply.u.process_info_ns.programStrId.nid
-// , msg->u.reply.u.process_info_ns.programStrId.id
, msg->u.reply.u.process_info_ns.port_name
, msg->u.reply.u.process_info_ns.argc
-// , &msg->u.reply.u.process_info_ns.argv
, msg->u.reply.u.process_info_ns.infile
, msg->u.reply.u.process_info_ns.outfile
-//#if 0
-// , msg->u.reply.u.process_info_ns.creation_time.tv_sec
-// , msg->u.reply.u.process_info_ns.creation_time.tv_nsec
-//#endif
+#if 0
+ , msg->u.reply.u.process_info_ns.creation_time.tv_sec
+ , msg->u.reply.u.process_info_ns.creation_time.tv_nsec
+#endif
, msg->u.reply.u.process_info_ns.return_code );
break;
default:
@@ -905,7 +1091,20 @@
);
}
}
- else
+ else if ( error != -2 && retryCount < NAMESERVER_IO_RETRIES )
+ {
+ retryCount++;
+ if ( trace_settings & TRACE_NS )
+ {
+ trace_printf( "%s@%d - retrying IO (%d) to nameserver=%s:%s\n"
+ , method_name, __LINE__
+ , retryCount
+ , mon2nsHost_, mon2nsPort_ );
+ }
+ goto retryIO;
+ }
+
+ if ( error )
{
// create a synthetic reply
msg->u.reply.u.generic.nid = -1;
@@ -943,9 +1142,10 @@
if ( trace_settings & TRACE_NS )
{
- trace_printf( "%s@%d - sending %s REQ to nameserver=%s:%s, sock=%d, shutdown=%d\n"
+ trace_printf( "%s@%d - sending %s\tREQ (size=%d) to nameserver=%s:%s, sock=%d, shutdown=%d\n"
, method_name, __LINE__
, reqType
+ , size
, mon2nsHost_
, mon2nsPort_
, mon2nsSock_
@@ -967,15 +1167,72 @@
error = ConnectToNs( &retry );
}
}
+
if ( error == 0 )
+ {
error = SockSend( (char *) &size, sizeof(size) );
- if ( error == 0 )
- error = SockSend( (char *) msg, size );
+ if (error)
+ {
+ int err = error;
+ char buf[MON_STRING_BUF_SIZE];
+ snprintf( buf, sizeof(buf)
+ , "[%s], unable to send %s request size %d to "
+ "nameserver=%s:%s, error: %d(%s)\n"
+ , method_name, reqType, size, mon2nsHost_, mon2nsPort_, err, strerror(err) );
+ mon_log_write(NAMESERVER_SENDTONS_1, SQ_LOG_ERR, buf);
+ }
+ else
+ {
+ error = SockSend( (char *) msg, size );
+ if (error)
+ {
+ int err = error;
+ char buf[MON_STRING_BUF_SIZE];
+ snprintf( buf, sizeof(buf)
+ , "[%s], unable to send %s request to "
+ "nameserver=%s:%s, error: %d(%s)\n"
+ , method_name, reqType, mon2nsHost_, mon2nsPort_, err, strerror(err) );
+ mon_log_write(NAMESERVER_SENDTONS_2, SQ_LOG_ERR, buf);
+ }
+ }
+ }
TRACE_EXIT;
return error;
}
+void CNameServer::SetLocalHost( void )
+{
+ gethostname( mon2nsHost_, MAX_PROCESSOR_NAME );
+}
+
+void CNameServer::SetShutdown( bool shutdown )
+{
+ const char method_name[] = "CNameServer::SetShutdown";
+ TRACE_ENTRY;
+
+ if ( trace_settings & TRACE_NS )
+ trace_printf( "%s@%d - set shutdown_=%d\n"
+ , method_name, __LINE__, shutdown );
+ shutdown_ = shutdown;
+
+ TRACE_EXIT;
+}
+
+void CNameServer::SockClose( void )
+{
+ const char method_name[] = "CNameServer::SockClose";
+ TRACE_ENTRY;
+
+ if (mon2nsSock_ != -1)
+ {
+ close( mon2nsSock_ );
+ mon2nsSock_ = -1;
+ }
+
+ TRACE_EXIT;
+}
+
int CNameServer::SockReceive( char *buf, int size )
{
const char method_name[] = "CNameServer::SockReceive";
@@ -1045,9 +1302,29 @@
, error, strerror(error) );
}
- if ( error )
+ if (error)
+ {
SockClose();
+ int err = error;
+ char buf[MON_STRING_BUF_SIZE];
+ snprintf( buf, sizeof(buf)
+ , "[%s], unable to receive request size %d to "
+ "nameserver=%s:%s, error: %d(%s)\n"
+ , method_name, size, mon2nsHost_, mon2nsPort_, err, strerror(err) );
+ mon_log_write(NAMESERVER_SOCKRECEIVE_1, SQ_LOG_ERR, buf);
+
+ // Choose another name server on IO retry
+ if (IsRealCluster)
+ {
+ mon2nsHost_[0] = 0;
+ }
+ else
+ {
+ mon2nsPort_[0] = 0;
+ }
+ }
+
TRACE_EXIT;
return error;
}
@@ -1112,9 +1389,28 @@
, error, strerror(error) );
}
- if ( error )
+ if (error)
+ {
SockClose();
+ int err = error;
+ char buf[MON_STRING_BUF_SIZE];
+ snprintf( buf, sizeof(buf)
+ , "[%s], unable to send request size %d to "
+ "nameserver=%s:%s, error: %d(%s)\n"
+ , method_name, size, mon2nsHost_, mon2nsPort_, err, strerror(err) );
+ mon_log_write(NAMESERVER_SOCKSEND_1, SQ_LOG_ERR, buf);
+ // Choose another name server on IO retry
+ if (IsRealCluster)
+ {
+ mon2nsHost_[0] = 0;
+ }
+ else
+ {
+ mon2nsPort_[0] = 0;
+ }
+ }
+
TRACE_EXIT;
return error;
}
diff --git a/core/sqf/monitor/linux/nameserver.h b/core/sqf/monitor/linux/nameserver.h
index a8ccb4b..009eced 100644
--- a/core/sqf/monitor/linux/nameserver.h
+++ b/core/sqf/monitor/linux/nameserver.h
@@ -40,12 +40,15 @@
CNameServer( void );
virtual ~CNameServer( void );
+ bool IsNameServerConfigured( int pnid );
+ void NameServerExited( void );
int NameServerStop( struct message_def* msg );
int ProcessDelete(CProcess* process );
int ProcessInfo( struct message_def* msg );
int ProcessInfoCont( struct message_def* msg );
int ProcessInfoNs( struct message_def* msg );
int ProcessNew(CProcess* process );
+ int ProcessNodeDown( int nid, char* nodeName );
int ProcessShutdown( void );
void SetLocalHost( void );
@@ -53,21 +56,20 @@
char mon2nsHost_[MAX_PROCESSOR_NAME];
char mon2nsPort_[10];
int mon2nsSock_;
- int nsConfigInx_;
bool nsStartupComplete_;
int seqNum_;
bool shutdown_;
- void ChooseNextNs( void );
- int ConnectToNs( bool *retry );
- void GetM2NPort( int PNid );
+ int ChooseNextNs( void );
+ int ClientSockCreate();
+ int ConnectToNs( bool* retry );
+ int GetM2NPort( int PNid );
int SendReceive( struct message_def* msg );
- int SendToNs( const char *reqType, struct message_def *msg, int size );
+ int SendToNs( const char* reqType, struct message_def* msg, int size );
void SetShutdown( bool shutdown );
void SockClose( void );
- int SockCreate();
- int SockReceive( char *buf, int size );
- int SockSend( char *buf, int size );
+ int SockReceive( char* buf, int size );
+ int SockSend( char* buf, int size );
};
#endif
diff --git a/core/sqf/monitor/linux/nscommacceptmon.cxx b/core/sqf/monitor/linux/nscommacceptmon.cxx
index edddca7..0857cc9 100644
--- a/core/sqf/monitor/linux/nscommacceptmon.cxx
+++ b/core/sqf/monitor/linux/nscommacceptmon.cxx
@@ -155,6 +155,36 @@
TRACE_EXIT;
}
+void CCommAcceptMon::monReqNodeDown( struct message_def* msg, int sockFd )
+{
+ const char method_name[] = "CCommAcceptMon::monReqNodeDown";
+ TRACE_ENTRY;
+
+ if ( trace_settings & ( TRACE_NS | TRACE_REQUEST) )
+ {
+ trace_printf( "%s@%d - Received monitor node-down request.\n"
+ " msg.down.nid=%d\n"
+ " msg.down.node_name=%s\n"
+ " msg.down.takeover=%d\n"
+ " msg.down.reason=%s\n"
+ , method_name, __LINE__
+ , msg->u.request.u.down.nid
+ , msg->u.request.u.down.node_name
+ , msg->u.request.u.down.takeover
+ , msg->u.request.u.down.reason
+ );
+ }
+
+ CExternalReq::reqQueueMsg_t msgType;
+ msgType = CExternalReq::NonStartupMsg;
+ int nid = msg->u.request.u.down.nid;
+ int pid = -1;
+ // Place new request on request queue
+ ReqQueue.enqueueReq(msgType, nid, pid, sockFd, msg);
+
+ TRACE_EXIT;
+}
+
void CCommAcceptMon::monReqProcessInfo( struct message_def* msg, int sockFd )
{
const char method_name[] = "CCommAcceptMon::monReqProcessInfo";
@@ -412,12 +442,12 @@
void CCommAcceptMon::processMonReqs( int sockFd )
{
const char method_name[] = "CCommAcceptMon::processMonReqs";
+ TRACE_ENTRY;
+
int rc;
nodeId_t nodeId;
struct message_def msg;
- TRACE_ENTRY;
-
if ( trace_settings & ( TRACE_NS ) )
{
trace_printf( "%s@%d - Accepted connection sock=%d\n"
@@ -435,7 +465,7 @@
char buf[MON_STRING_BUF_SIZE];
snprintf(buf, sizeof(buf), "[%s], unable to obtain node id from new "
"monitor: %s.\n", method_name, ErrorMsg(rc));
- mon_log_write(NS_COMMACCEPT_2, SQ_LOG_ERR, buf);
+ mon_log_write(NS_COMMACCEPT_PROCESSMONREQS_1, SQ_LOG_ERR, buf);
return;
}
@@ -462,6 +492,36 @@
, nodeId.ping );
}
+ CNode *node;
+ node = Nodes->GetNode( nodeId.pnid );
+ if ( node != NULL )
+ {
+ if ( node->GetState() != State_Up )
+ {
+ if ( trace_settings & ( TRACE_NS ) )
+ {
+ trace_printf( "%s@%d - Bringing node up, node=%s, pnid=%d\n"
+ , method_name, __LINE__
+ , node->GetName(), node->GetPNid() );
+ }
+ rc = Monitor->HardNodeUpNs( node->GetPNid() );
+ if ( rc )
+ { // Handle error
+ close( sockFd );
+ return;
+ }
+ }
+ }
+ else
+ { // Handle error
+ close( sockFd );
+ char buf[MON_STRING_BUF_SIZE];
+ snprintf(buf, sizeof(buf), "[%s], invalid physical node id, "
+ "pnid: %d\n", method_name, nodeId.pnid );
+ mon_log_write(NS_COMMACCEPT_PROCESSMONREQS_2, SQ_LOG_ERR, buf);
+ return;
+ }
+
strcpy(nodeId.nodeName, MyNode->GetName());
strcpy(nodeId.commPort, MyNode->GetCommPort());
strcpy(nodeId.syncPort, MyNode->GetSyncPort());
@@ -504,7 +564,7 @@
char buf[MON_STRING_BUF_SIZE];
snprintf(buf, sizeof(buf), "[%s], unable to send node id from new "
"monitor: %s.\n", method_name, ErrorMsg(rc));
- mon_log_write(NS_COMMACCEPT_3, SQ_LOG_ERR, buf);
+ mon_log_write(NS_COMMACCEPT_PROCESSMONREQS_3, SQ_LOG_ERR, buf);
return;
}
@@ -517,9 +577,9 @@
{ // Handle error
close( sockFd );
char buf[MON_STRING_BUF_SIZE];
- snprintf(buf, sizeof(buf), "[%s], unable to obtain node id from new "
+ snprintf(buf, sizeof(buf), "[%s], unable to obtain message size from "
"monitor: %s.\n", method_name, ErrorMsg(rc));
- mon_log_write(NS_COMMACCEPT_4, SQ_LOG_ERR, buf);
+ mon_log_write(NS_COMMACCEPT_PROCESSMONREQS_4, SQ_LOG_ERR, buf);
return;
}
@@ -528,9 +588,9 @@
{ // Handle error
close( sockFd );
char buf[MON_STRING_BUF_SIZE];
- snprintf(buf, sizeof(buf), "[%s], unable to obtain node id from new "
+ snprintf(buf, sizeof(buf), "[%s], unable to obtain message from "
"monitor: %s.\n", method_name, ErrorMsg(rc));
- mon_log_write(NS_COMMACCEPT_5, SQ_LOG_ERR, buf);
+ mon_log_write(NS_COMMACCEPT_PROCESSMONREQS_5, SQ_LOG_ERR, buf);
return;
}
if ( trace_settings & ( TRACE_NS ) )
@@ -591,6 +651,10 @@
monReqNameServerStop(&msg, sockFd);
break;
+ case ReqType_NodeDown:
+ monReqNodeDown(&msg, sockFd);
+ break;
+
case ReqType_ProcessInfo:
monReqProcessInfo(&msg, sockFd);
break;
@@ -663,9 +727,9 @@
if (rc != 0)
{
char buf[MON_STRING_BUF_SIZE];
- snprintf(buf, sizeof(buf), "[%s], thread create error=%d\n",
+ snprintf(buf, sizeof(buf), "[%s], mon2nsProcess thread create error=%d\n",
method_name, rc);
- mon_log_write(NS_COMMACCEPT_6, SQ_LOG_ERR, buf);
+ mon_log_write(NS_COMMACCEPT_PROCESSNEWSOCK_1, SQ_LOG_ERR, buf);
}
TRACE_EXIT;
@@ -743,7 +807,7 @@
char buf[MON_STRING_BUF_SIZE];
snprintf(buf, sizeof(buf), "[%s], cannot accept new monitor: %s.\n",
method_name, strerror(errno));
- mon_log_write(NS_COMMACCEPT_7, SQ_LOG_ERR, buf);
+ mon_log_write(NS_COMMACCEPT_COMMACCEPTORSOCK_1, SQ_LOG_ERR, buf);
}
else
@@ -800,7 +864,7 @@
char buf[MON_STRING_BUF_SIZE];
snprintf(buf, sizeof(buf), "[%s], pthread_sigmask error=%d\n",
method_name, rc);
- mon_log_write(NS_COMMACCEPT_8, SQ_LOG_ERR, buf);
+ mon_log_write(NS_COMMACCEPT_MON2NSACCEPTMON_1, SQ_LOG_ERR, buf);
}
// Enter thread processing loop
@@ -830,7 +894,7 @@
char buf[MON_STRING_BUF_SIZE];
snprintf(buf, sizeof(buf), "[%s], pthread_sigmask error=%d\n",
method_name, rc);
- mon_log_write(NS_COMMACCEPT_9, SQ_LOG_ERR, buf);
+ mon_log_write(NS_COMMACCEPT_MON2NSPROCESS_1, SQ_LOG_ERR, buf);
}
MyNode->AddMonConnCount(1);
@@ -858,7 +922,7 @@
char buf[MON_STRING_BUF_SIZE];
snprintf(buf, sizeof(buf), "[%s], thread create error=%d\n",
method_name, rc);
- mon_log_write(NS_COMMACCEPT_10, SQ_LOG_ERR, buf);
+ mon_log_write(NS_COMMACCEPT_START_1, SQ_LOG_ERR, buf);
}
TRACE_EXIT;
diff --git a/core/sqf/monitor/linux/nscommacceptmon.h b/core/sqf/monitor/linux/nscommacceptmon.h
index 41b2c9b..1749b16 100644
--- a/core/sqf/monitor/linux/nscommacceptmon.h
+++ b/core/sqf/monitor/linux/nscommacceptmon.h
@@ -46,6 +46,7 @@
void monReqExec( CExternalReq * request );
void monReqNameServerStop( struct message_def* msg, int sockFd );
void monReqNewProcess( struct message_def* msg, int sockFd );
+ void monReqNodeDown( struct message_def* msg, int sockFd );
void monReqProcessInfo( struct message_def* msg, int sockFd );
void monReqProcessInfoCont( struct message_def* msg, int sockFd );
void monReqProcessInfoNs( struct message_def* msg, int sockFd );
@@ -68,9 +69,9 @@
bool accepting_;
bool shutdown_;
- // commAccept thread's id
+ // mon2nsAcceptMon thread's id
pthread_t thread_id_;
- // commAccept thread's id
+ // mon2nsProcess thread's id
pthread_t process_thread_id_;
enum { HEURISTIC_COUNT = 10 };
diff --git a/core/sqf/monitor/linux/nsreqnodedown.cxx b/core/sqf/monitor/linux/nsreqnodedown.cxx
new file mode 100644
index 0000000..9b5ddc2
--- /dev/null
+++ b/core/sqf/monitor/linux/nsreqnodedown.cxx
@@ -0,0 +1,100 @@
+///////////////////////////////////////////////////////////////////////////////
+//
+// @@@ START COPYRIGHT @@@
+//
+// Licensed to the Apache Software Foundation (ASF) under one
+// or more contributor license agreements. See the NOTICE file
+// distributed with this work for additional information
+// regarding copyright ownership. The ASF licenses this file
+// to you under the Apache License, Version 2.0 (the
+// "License"); you may not use this file except in compliance
+// with the License. You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing,
+// software distributed under the License is distributed on an
+// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+// KIND, either express or implied. See the License for the
+// specific language governing permissions and limitations
+// under the License.
+//
+// @@@ END COPYRIGHT @@@
+//
+///////////////////////////////////////////////////////////////////////////////
+
+#include "nstype.h"
+
+#include <stdio.h>
+#include "reqqueue.h"
+#include "montrace.h"
+#include "monsonar.h"
+#include "monlogging.h"
+
+extern CMonStats *MonStats;
+extern CNode *MyNode;
+extern CNodeContainer *Nodes;
+extern CMonitor *Monitor;
+
+CExtNodeDownNsReq::CExtNodeDownNsReq( reqQueueMsg_t msgType
+ , int pid
+ , int sockFd
+ , struct message_def *msg )
+ : CExternalReq(msgType, -1, pid, sockFd, msg)
+{
+ // Add eyecatcher sequence as a debugging aid
+ memcpy(&eyecatcher_, "RqEJ", 4);
+
+ priority_ = High;
+}
+
+CExtNodeDownNsReq::~CExtNodeDownNsReq()
+{
+ // Alter eyecatcher sequence as a debugging aid to identify deleted object
+ memcpy(&eyecatcher_, "rQej", 4);
+}
+
+void CExtNodeDownNsReq::populateRequestString( void )
+{
+ char strBuf[MON_STRING_BUF_SIZE/2] = { 0 };
+
+ snprintf( strBuf, sizeof(strBuf),
+ "ExtReq(%s) req #=%ld requester(pid=%d) (nid=%d)"
+ , CReqQueue::svcReqType[reqType_], getId(), pid_
+ , msg_->u.request.u.down.nid );
+ requestString_.assign( strBuf );
+}
+
+void CExtNodeDownNsReq::performRequest()
+{
+ const char method_name[] = "CExtNodeDownNsReq::performRequest";
+ TRACE_ENTRY;
+
+ CNode *node = NULL;
+
+ // Record statistics (sonar counters)
+ if (sonar_verify_state(SONAR_ENABLED | SONAR_MONITOR_ENABLED))
+ MonStats->req_type_nodedown_Incr();
+
+ // Trace info about request
+ if (trace_settings & (TRACE_REQUEST | TRACE_PROCESS))
+ {
+ trace_printf("%s@%d request #%ld: NodeDown, nid=%d\n", method_name,
+ __LINE__, id_, msg_->u.request.u.down.nid);
+ }
+
+ node = Nodes->GetLNode( msg_->u.request.u.down.nid )->GetNode();
+ Monitor->HardNodeDownNs( node->GetPNid() );
+
+ msg_->u.reply.type = ReplyType_Generic;
+ msg_->u.reply.u.generic.nid = -1;
+ msg_->u.reply.u.generic.pid = pid_;
+ msg_->u.reply.u.generic.verifier = -1;
+ msg_->u.reply.u.generic.process_name[0] = '\0';
+ msg_->u.reply.u.generic.return_code = MPI_SUCCESS;
+
+ // Send reply to monitor
+ monreply(msg_, sockFd_);
+
+ TRACE_EXIT;
+}
diff --git a/core/sqf/monitor/linux/nsreqprocinfons.cxx b/core/sqf/monitor/linux/nsreqprocinfons.cxx
index aa53437..37c09f6 100644
--- a/core/sqf/monitor/linux/nsreqprocinfons.cxx
+++ b/core/sqf/monitor/linux/nsreqprocinfons.cxx
@@ -222,18 +222,21 @@
if (trace_settings & (TRACE_REQUEST | TRACE_PROCESS))
{
- trace_printf( "%s@%d request #%ld: ProcessInfoNs, for (%d, %d:%d), "
+ trace_printf( "%s@%d request #%ld: ProcessInfoNs, for %s (%d, %d:%d), "
"process type=%s\n"
, method_name, __LINE__, id_
- , target_nid, target_pid, target_verifier
+ , target_process_name.c_str(), target_nid, target_pid, target_verifier
, ProcessTypeString(target_type));
}
if (target_process_name.size())
{ // find by name (don't check node state, don't check process state, not backup)
- process = Nodes->GetProcess( target_process_name.c_str()
- , target_verifier
- , false, false, false );
+ if (msg_->u.request.u.process_info.target_process_name[0] == '$' )
+ {
+ process = Nodes->GetProcess( target_process_name.c_str()
+ , target_verifier
+ , false, false, false );
+ }
}
else
{
diff --git a/core/sqf/monitor/linux/nsreqshutdown.cxx b/core/sqf/monitor/linux/nsreqshutdown.cxx
index e5888d2..63d9400 100644
--- a/core/sqf/monitor/linux/nsreqshutdown.cxx
+++ b/core/sqf/monitor/linux/nsreqshutdown.cxx
@@ -30,12 +30,10 @@
#include "montrace.h"
#include "monsonar.h"
#include "monlogging.h"
-#include "replicate.h"
extern CMonStats *MonStats;
extern CNode *MyNode;
extern CNodeContainer *Nodes;
-extern CReplicate Replicator;
CExtShutdownNsReq::CExtShutdownNsReq (reqQueueMsg_t msgType,
int nid, int pid, int sockFd,
@@ -43,7 +41,7 @@
: CExternalReq(msgType, nid, pid, sockFd, msg)
{
// Add eyecatcher sequence as a debugging aid
- memcpy(&eyecatcher_, "RQER", 4); // TODO
+ memcpy(&eyecatcher_, "RqER", 4);
priority_ = High;
}
@@ -51,7 +49,7 @@
CExtShutdownNsReq::~CExtShutdownNsReq()
{
// Alter eyecatcher sequence as a debugging aid to identify deleted object
- memcpy(&eyecatcher_, "rqer", 4); // TODO
+ memcpy(&eyecatcher_, "rQer", 4);
}
void CExtShutdownNsReq::populateRequestString( void )
diff --git a/core/sqf/monitor/linux/nsreqstop.cxx b/core/sqf/monitor/linux/nsreqstop.cxx
index 4ff46ce..a20e9bd 100644
--- a/core/sqf/monitor/linux/nsreqstop.cxx
+++ b/core/sqf/monitor/linux/nsreqstop.cxx
@@ -90,7 +90,7 @@
int nid = atoi( msg_->u.request.u.nameserver_stop.node_name );
node = Nodes->GetLNode( nid )->GetNode();
}
- Monitor->HardNodeDown( node->GetPNid(), true );
+ Monitor->HardNodeDownNs( node->GetPNid() );
char la_buf[MON_STRING_BUF_SIZE*2];
snprintf( la_buf, sizeof(la_buf)
diff --git a/core/sqf/monitor/linux/pnode.cxx b/core/sqf/monitor/linux/pnode.cxx
index 4a4b8c4..364837b 100644
--- a/core/sqf/monitor/linux/pnode.cxx
+++ b/core/sqf/monitor/linux/pnode.cxx
@@ -1065,11 +1065,11 @@
!MyNode->IsMyNode(targetLNode->GetNid()))
{
// Forward the unique string to the target node
- int rc = PtpClient->AddUniqStr( id.nid
- , id.id
- , candidate
- , targetLNode->GetNid()
- , targetLNode->GetNode()->GetName() );
+ int rc = PtpClient->ProcessAddUniqStr( id.nid
+ , id.id
+ , candidate
+ , targetLNode->GetNid()
+ , targetLNode->GetNode()->GetName() );
if (rc)
{
char la_buf[MON_STRING_BUF_SIZE];
@@ -1110,11 +1110,11 @@
!MyNode->IsMyNode(targetLNode->GetNid()))
{
// Forward the unique string to the target node
- int rc = PtpClient->AddUniqStr( id.nid
- , id.id
- , candidate
- , targetLNode->GetNid()
- , targetLNode->GetNode()->GetName());
+ int rc = PtpClient->ProcessAddUniqStr( id.nid
+ , id.id
+ , candidate
+ , targetLNode->GetNid()
+ , targetLNode->GetNode()->GetName());
if (rc)
{
char la_buf[MON_STRING_BUF_SIZE];
@@ -1240,6 +1240,16 @@
const char method_name[] = "CNode::StartNameServerProcess";
TRACE_ENTRY;
+ if ( !NameServer->IsNameServerConfigured( MyPNID ) )
+ {
+ if (trace_settings & (TRACE_INIT | TRACE_RECOVERY))
+ {
+ trace_printf( "%s@%d" " - NameServer is not configured in my node\n"
+ , method_name, __LINE__);
+ }
+ return;
+ }
+
char path[MAX_SEARCH_PATH];
char *ldpath = NULL; // = getenv("LD_LIBRARY_PATH");
char filename[MAX_PROCESS_PATH];
@@ -1250,7 +1260,9 @@
snprintf( stdout, sizeof(stdout), "stdout_TNS%d", MyNode->GetZone() );
if (trace_settings & (TRACE_INIT | TRACE_RECOVERY))
- trace_printf("%s@%d" " - Creating NameService Process\n", method_name, __LINE__);
+ {
+ trace_printf("%s@%d" " - Creating NameServer Process\n", method_name, __LINE__);
+ }
strcpy(path,getenv("PATH"));
strcat(path,":");
@@ -1281,12 +1293,14 @@
if ( NameServerProcess )
{
if (trace_settings & (TRACE_INIT | TRACE_RECOVERY))
- trace_printf("%s@%d" " - NameService Process created\n", method_name, __LINE__);
+ {
+ trace_printf("%s@%d" " - NameServer Process created\n", method_name, __LINE__);
+ }
}
else
{
char la_buf[MON_STRING_BUF_SIZE];
- sprintf(la_buf, "[%s], NameService Process creation failed.\n", method_name);
+ sprintf(la_buf, "[%s], NameServer Process creation failed.\n", method_name);
mon_log_write( MON_NODE_STARTNAMESERVER_1, SQ_LOG_ERR, la_buf );
}
@@ -2556,11 +2570,27 @@
}
else
{
- char buf[MON_STRING_BUF_SIZE];
- snprintf( buf, sizeof(buf),
- "[%s] ProcessInfo failed, rc=%d\n"
- , method_name, msg.u.reply.u.process_info_ns.return_code );
- mon_log_write( MON_NODE_CLONEPROCESSNS_1, SQ_LOG_ERR, buf );
+ if (trace_settings & (TRACE_REQUEST | TRACE_PROCESS))
+ {
+ trace_printf( "%s@%d - ProcessInfoNs(%d, %d:%d) -- can't find target process\n"
+ , method_name, __LINE__
+ , msg.u.reply.u.process_info_ns.nid
+ , msg.u.reply.u.process_info_ns.pid
+ , msg.u.reply.u.process_info_ns.verifier);
+ }
+
+ if ( msg.u.reply.u.process_info_ns.return_code != MPI_ERR_NAME )
+ {
+ char buf[MON_STRING_BUF_SIZE];
+ snprintf( buf, sizeof(buf),
+ "[%s] ProcessInfo(%d, %d:%d) failed, rc=%d\n"
+ , method_name
+ , msg.u.reply.u.process_info_ns.nid
+ , msg.u.reply.u.process_info_ns.pid
+ , msg.u.reply.u.process_info_ns.verifier
+ , msg.u.reply.u.process_info_ns.return_code );
+ mon_log_write( MON_NODE_CLONEPROCESSNS_1, SQ_LOG_ERR, buf );
+ }
}
}
else
@@ -2625,11 +2655,25 @@
}
else
{
- char buf[MON_STRING_BUF_SIZE];
- snprintf( buf, sizeof(buf),
- "[%s] ProcessInfo failed, rc=%d\n"
- , method_name, msg.u.reply.u.process_info_ns.return_code );
- mon_log_write( MON_NODE_CLONEPROCESSNS_4, SQ_LOG_ERR, buf );
+ if (trace_settings & (TRACE_REQUEST | TRACE_PROCESS))
+ {
+ trace_printf( "%s@%d - ProcessInfoNs(%s:%d) -- can't find target process\n"
+ , method_name, __LINE__
+ , msg.u.reply.u.process_info_ns.process_name
+ , msg.u.reply.u.process_info_ns.verifier);
+ }
+
+ if ( msg.u.reply.u.process_info_ns.return_code != MPI_ERR_NAME )
+ {
+ char buf[MON_STRING_BUF_SIZE];
+ snprintf( buf, sizeof(buf),
+ "[%s] ProcessInfo(%s:%d) failed, rc=%d\n"
+ , method_name
+ , msg.u.reply.u.process_info_ns.process_name
+ , msg.u.reply.u.process_info_ns.verifier
+ , msg.u.reply.u.process_info_ns.return_code );
+ mon_log_write( MON_NODE_CLONEPROCESSNS_4, SQ_LOG_ERR, buf );
+ }
}
}
else
diff --git a/core/sqf/monitor/linux/process.cxx b/core/sqf/monitor/linux/process.cxx
index 9b9ee00..a39a589 100644
--- a/core/sqf/monitor/linux/process.cxx
+++ b/core/sqf/monitor/linux/process.cxx
@@ -2589,27 +2589,46 @@
// Take fork semaphore. We need to wait until parent indicates
// it is ok to proceed. Pipes between parent and child need to
// be set up before child can continue.
+ bool sem_log_error = false;
int sem_rc;
+ int err = 0;
struct timeval logTime;
struct tm *ltime;
-
- gettimeofday(&logTime, NULL);
- ltime = localtime(&logTime.tv_sec);
-
struct timespec ts;
- ts.tv_sec = 1;
- ts.tv_nsec = 0;
+
+ if (clock_gettime(CLOCK_REALTIME, &ts) == -1)
+ {
+ err = errno;
+ gettimeofday(&logTime, NULL);
+ ltime = localtime(&logTime.tv_sec);
+ snprintf(la_buf, sizeof(la_buf),
+ "%02d/%02d/%02d-%02d:%02d:%02d "
+ "[CProcess::Create], clock_gettime(CLOCK_REALTIME),"
+ " Child can't get time, %s (%d), program %s, (pid=%d).\n"
+ , ltime->tm_mon+1, ltime->tm_mday, ltime->tm_year-100, ltime->tm_hour, ltime->tm_min, ltime->tm_sec
+ , strerror(err), err
+ , filename, getpid());
+ write (2, la_buf, strlen(la_buf));
+ }
+ ts.tv_sec += 1;
+
env = getenv( "MON_CREATE_SEM_DELAY" );
if (env && isdigit(*env))
{
ts.tv_sec = atol(env);
}
- int err;
+
+ env = getenv( "MON_CREATE_SEM_LOG_ERROR" );
+ if (env && isdigit(*env))
+ {
+ int val = atoi(env);
+ sem_log_error = (val != 0) ? true : false;
+ }
do
{
sem_rc = sem_timedwait(MyNode->GetMutex(), &ts);
err = errno;
- if ( err == ETIMEDOUT )
+ if ( sem_log_error && err == ETIMEDOUT )
{
gettimeofday(&logTime, NULL);
ltime = localtime(&logTime.tv_sec);
@@ -2625,7 +2644,7 @@
}
while (sem_rc == -1 && (err == EINTR || err == ETIMEDOUT));
- if ( sem_rc == -1 && !(err == EINTR || err == ETIMEDOUT))
+ if ( sem_log_error && sem_rc == -1 && !(err == EINTR || err == ETIMEDOUT))
{
gettimeofday(&logTime, NULL);
ltime = localtime(&logTime.tv_sec);
@@ -3319,6 +3338,10 @@
case ProcessType_NameServer:
if ( IsAbended() )
{
+ if (!Clone)
+ {
+ NameServer->NameServerExited();
+ }
if (trace_settings & (TRACE_SYNC | TRACE_REQUEST | TRACE_PROCESS))
trace_printf("%s@%d" " - NameServer abended" "\n", method_name, __LINE__);
}
@@ -4095,6 +4118,7 @@
CProcessContainer::CProcessContainer (void)
:numProcs_(0)
,nodeContainer_(false)
+ ,processNameFormatLong_(true)
,nameMap_(NULL)
,pidMap_(NULL)
,head_(NULL)
@@ -4121,12 +4145,22 @@
abort();
}
+#ifndef NAMESERVER_PROCESS
+ char *env = getenv("SQ_MON_PROCESS_NAME_FORMAT_LONG");
+ if ( env && isdigit(*env) )
+ {
+ int val = atoi(env);
+ processNameFormatLong_ = (val != 0) ? true : false;
+ }
+#endif
+
TRACE_EXIT;
}
CProcessContainer::CProcessContainer( bool nodeContainer )
:numProcs_(0)
,nodeContainer_(nodeContainer)
+ ,processNameFormatLong_(true)
,nameMap_(NULL)
,pidMap_(NULL)
,head_(NULL)
@@ -4161,6 +4195,15 @@
abort();
}
+#ifndef NAMESERVER_PROCESS
+ char *env = getenv("SQ_MON_PROCESS_NAME_FORMAT_LONG");
+ if ( env && isdigit(*env) )
+ {
+ int val = atoi(env);
+ processNameFormatLong_ = (val != 0) ? true : false;
+ }
+#endif
+
if ( nodeContainer_ )
{
nameMap_ = new nameMap_t;
@@ -4775,46 +4818,85 @@
char *CProcessContainer::BuildOurName( int nid, int pid, char *name )
{
- int i;
- int rem;
- int cnt[4];
-
const char method_name[] = "CProcessContainer::BuildOurName";
TRACE_ENTRY;
- // Convert Pid into base 35 acsii
- cnt[0] = pid / 42875;
- rem = pid - ( cnt[0] * 42875 );
- cnt[1] = rem / 1225;
- rem -= ( cnt[1] * 1225 );
- cnt[2] = rem / 35;
- rem -= ( cnt[2] * 35 );
- cnt[3] = rem;
+ int i;
+ int rem;
+ int cnt[6];
- // Convert Nid into base 16 acsii
- sprintf(name,"$Z%2.2X",nid);
- for(i=3; i>=0; i--)
+ if (!processNameFormatLong_)
{
- if( cnt[i] < 10 )
+ // Convert Pid into base 35 acsii
+ cnt[0] = pid / 42875; // (35 * 35 * 35)
+ rem = pid - ( cnt[0] * 42875 );
+ cnt[1] = rem / 1225; // (35 * 35)
+ rem -= ( cnt[1] * 1225 );
+ cnt[2] = rem / 35;
+ rem -= ( cnt[2] * 35 );
+ cnt[3] = rem;
+
+ // Process name format long: '$Zxxpppp' xx = nid, pppp = pid
+
+ // Convert Nid into base 16 acsii
+ sprintf(name,"$Z%2.2X",nid);
+
+ // Convert Pid into base 36 ascii
+ for(i=3; i>=0; i--)
{
- name[i+4] = '0'+cnt[i];
- }
- else
- {
- cnt[i] -= 10;
- // we are skipping cap 'o' because it looks like zero.
- if( cnt[i] >= 14 )
+ if( cnt[i] < 10 )
{
- name[i+4] = 'P'+(cnt[i]-14);
+ name[i+4] = '0'+cnt[i];
}
else
{
- name[i+4] = 'A'+cnt[i];
+ cnt[i] -= 10;
+ // we are skipping cap 'o' because it looks like zero.
+ if( cnt[i] >= 14 )
+ {
+ name[i+4] = 'P'+(cnt[i]-14);
+ }
+ else
+ {
+ name[i+4] = 'A'+cnt[i];
+ }
}
}
+ name[8] = '\0';
}
- name[8] = '\0';
-
+ else
+ {
+ // We are skipping 'A', 'I', 'O', and 'U' to distinguish between zero
+ // and one digits, and for political correctness in generated names
+ char b32table[32] = {'0','1','2','3','4','5','6','7','8','9'
+ ,'B','C','D','E','F','G','H','J','K','L','M'
+ ,'N','P','Q','R','S','T','V','W','X','Y','Z' };
+
+ // Convert Pid into base 32 ascii
+ cnt[0] = pid / 33554432; // (32 * 32 * 32 * 32 * 32)
+ rem = pid - ( cnt[0] * 33554432 );
+ cnt[1] = rem / 1048576; // (32 * 32 * 32 * 32)
+ rem -= ( cnt[1] * 1048576 );
+ cnt[2] = rem / 32768; // (32 * 32 * 32)
+ rem -= ( cnt[2] * 32768 );
+ cnt[3] = rem / 1024; // (32 * 32)
+ rem -= ( cnt[3] * 1024 );
+ cnt[4] = rem / 32;
+ rem -= ( cnt[4] * 32 );
+ cnt[5] = rem;
+
+ // Process name format long: '$Zxxxxpppppp' xxxx = nid, pppppp = pid
+
+ // Convert Nid into base 16 ascii
+ sprintf(name,"$Z%4.4X",nid);
+
+ // Convert Pid into base 32 ascii
+ for(i=5; i>=0; i--)
+ {
+ name[i+6] = static_cast<char>(b32table[cnt[i]]);
+ }
+ name[12] = '\0';
+ }
TRACE_EXIT;
return name;
@@ -5398,6 +5480,65 @@
}
#endif
+#ifdef NAMESERVER_PROCESS
+void CProcessContainer::DeleteAllDown()
+{
+ CProcess *process = NULL;
+ int nid = -1;
+ int pid = -1;
+
+ const char method_name[] = "CProcessContainer::DeleteAllDown";
+ TRACE_ENTRY;
+
+ nameMap_t::iterator nameMapIt;
+
+ while ( true )
+ {
+ nameMapLock_.lock();
+ nameMapIt = nameMap_->begin();
+
+ if (nameMap_->size() == 0)
+ {
+ nameMapLock_.unlock();
+ break; // all done
+ }
+
+ process = nameMapIt->second;
+
+ // Delete name map entry
+ nameMap_->erase (nameMapIt);
+
+ nameMapLock_.unlock();
+
+ nid = process->GetNid();
+ pid = process->GetPid();
+
+ if (trace_settings & (TRACE_PROCESS | TRACE_PROCESS_DETAIL))
+ {
+ trace_printf("%s@%d removed from nameMap %p: %s (%d, %d)\n",
+ method_name, __LINE__, nameMap_,
+ process->GetName(), nid, pid);
+ }
+
+ // Delete pid map entry
+ DelFromPidMap ( process );
+
+ if (trace_settings & (TRACE_SYNC | TRACE_REQUEST | TRACE_PROCESS))
+ {
+ trace_printf( "%s@%d - Completed delete for %s (%d, %d)\n"
+ , method_name, __LINE__
+ , process->GetName(), nid, pid);
+ }
+
+ // Remove all processes
+ // PSD will re-create persistent processes on spare node activation
+ Exit_Process( process, true, nid );
+ }
+
+ TRACE_EXIT;
+}
+#endif
+
void CProcessContainer::DeleteFromList( CProcess *process )
{
const char method_name[] = "CProcessContainer::DeleteFromList";
@@ -7086,7 +7227,9 @@
// Note: Exit_Process() will delete the process object, so
// save the process information needed before the call
+#ifndef NAMESERVER_PROCESS
PROCESSTYPE processType = process->GetType();
+#endif
string processName = process->GetName();
int processNid = process->GetNid();
int processPid = process->GetPid();
@@ -7101,6 +7244,7 @@
, processName.c_str(), processNid, processPid, processVerifier
, abend, downNode
, MyNode->IsKillingNode(), MyNode->IsDTMAborted(), MyNode->IsSMSAborted());
+#ifndef NAMESERVER_PROCESS
if ( !MyNode->IsKillingNode() )
{
switch ( processType )
@@ -7147,6 +7291,7 @@
break;
}
}
+#endif
}
break;
default:
diff --git a/core/sqf/monitor/linux/process.h b/core/sqf/monitor/linux/process.h
index 3cde3e5..736ddcc 100644
--- a/core/sqf/monitor/linux/process.h
+++ b/core/sqf/monitor/linux/process.h
@@ -139,6 +139,9 @@
, void *tag
, int & result
);
+#ifdef NAMESERVER_PROCESS
+ void DeleteAllDown();
+#endif
bool Dump_Process( CProcess *dumper, CProcess *process, char *core_path );
void DumpCallback( int nid, pid_t pid, int status );
void Exit_Process( CProcess *process, bool abend, int downNode );
@@ -185,10 +188,12 @@
inline void SetNumProcs( int numProcs ) { numProcs_ = numProcs; };
private:
- int numProcs_; // Number of processes in container
+ int numProcs_; // Number of processes in container
sem_t *Mutex;
- bool nodeContainer_; // true when physical node process container
+ bool nodeContainer_; // true when physical node process container
+ bool processNameFormatLong_; // when true process name format is:
+ // '$Zxxxxpppppp' xxxx = nid, pppppp = pid
nameMap_t *nameMap_;
pidMap_t *pidMap_;
CLock pidMapLock_;
diff --git a/core/sqf/monitor/linux/pstartd.cxx b/core/sqf/monitor/linux/pstartd.cxx
index 99343e1..74b35f3 100644
--- a/core/sqf/monitor/linux/pstartd.cxx
+++ b/core/sqf/monitor/linux/pstartd.cxx
@@ -1037,7 +1037,6 @@
case ProcessType_TMID:
case ProcessType_PERSIST:
case ProcessType_SSMP:
- case ProcessType_NameServer:
if ( persistConfig->GetRequiresDTM() && !requiresDTM )
{
if ( tracing )
@@ -1114,6 +1113,7 @@
break;
case ProcessType_DTM:
case ProcessType_PSD:
+ case ProcessType_NameServer:
case ProcessType_Watchdog:
default:
// Skip these, they are managed by DTM Lead and monitor processes
diff --git a/core/sqf/monitor/linux/ptpclient.cxx b/core/sqf/monitor/linux/ptpclient.cxx
index a88e2d2..39e4443 100644
--- a/core/sqf/monitor/linux/ptpclient.cxx
+++ b/core/sqf/monitor/linux/ptpclient.cxx
@@ -57,9 +57,13 @@
extern CNodeContainer *Nodes;
extern bool IsRealCluster;
extern CMeas Meas;
+extern int MyPNID;
+
+#define MON2MON_IO_RETRIES 3
CPtpClient::CPtpClient (void)
- : ptpSock_(0)
+ : ptpCommPort_(0)
+ , ptpClusterSocks_(NULL)
, seqNum_(0)
{
const char method_name[] = "CPtpClient::CPtpClient";
@@ -72,11 +76,10 @@
SetLocalHost();
}
-
- char * p = getenv( "MON2MON_COMM_PORT" );
- if ( p )
+ char * env = getenv( "MON2MON_COMM_PORT" );
+ if ( env )
{
- basePort_ = atoi( p );
+ ptpCommPort_ = atoi( env );
}
else
{
@@ -88,6 +91,12 @@
abort();
}
+ ptpClusterSocks_ = new int[MAX_NODES];
+ for (int i=0; i < MAX_NODES; ++i)
+ {
+ ptpClusterSocks_[i] = -1;
+ }
+
TRACE_EXIT;
}
@@ -96,17 +105,83 @@
const char method_name[] = "CPtpClient::~CPtpClient";
TRACE_ENTRY;
+ delete [] ptpClusterSocks_;
+
TRACE_EXIT;
}
-int CPtpClient::AddUniqStr( int nid
- , int id
- , const char *stringValue
- , int targetNid
- , const char *targetNodeName )
+int CPtpClient::InitializePtpClient( int pnid, char * ptpPort )
{
- const char method_name[] = "CPtpClient::AddUniqStr";
+ const char method_name[] = "CPtpClient::InitializePtpClient";
TRACE_ENTRY;
+ int err = 0;
+
+ if (ptpClusterSocks_[pnid] == -1)
+ {
+ int sock = Monitor->MkCltSock( ptpPort );
+ if (sock < 0)
+ {
+ err = sock;
+ if (trace_settings & (TRACE_REQUEST | TRACE_PROCESS))
+ {
+ trace_printf( "%s@%d - MkCltSock failed with error %d\n"
+ , method_name, __LINE__, err );
+ }
+ }
+ else
+ {
+ ptpClusterSocks_[pnid] = sock;
+ if (trace_settings & (TRACE_REQUEST | TRACE_PROCESS))
+ {
+ trace_printf( "%s@%d - connected to monitor node=%d(%s), sock=%d, "
+ "ptpClusterSocks_[%d]=%d\n"
+ , method_name, __LINE__
+ , pnid
+ , ptpPort
+ , sock
+ , pnid
+ , ptpClusterSocks_[pnid] );
+ }
+ }
+ }
+
+ TRACE_EXIT;
+ return err;
+}
+
+bool CPtpClient::IsTargetRemote( int targetNid )
+{
+ const char method_name[] = "CPtpClient::IsTargetRemote";
+ TRACE_ENTRY;
+
+ CLNode *targetLNode = Nodes->GetLNode( targetNid );
+ CNode *targetNode = targetLNode->GetNode();
+ bool rs = (targetNode && targetNode->GetPNid() == MyPNID) ? false : true ;
+
+ TRACE_EXIT;
+ return(rs);
+}
+
+int CPtpClient::ProcessAddUniqStr( int nid
+ , int id
+ , const char *stringValue
+ , int targetNid
+ , const char *targetNodeName )
+{
+ const char method_name[] = "CPtpClient::ProcessAddUniqStr";
+ TRACE_ENTRY;
+
+ if (!IsTargetRemote( targetNid ))
+ {
+ if (trace_settings & (TRACE_REQUEST | TRACE_PROCESS))
+ {
+ trace_printf( "%s@%d - Not Sending InternalType_UniqStr request to "
+ "local nid=%d\n"
+ , method_name, __LINE__
+ , targetNid );
+ }
+ return(0);
+ }
if (trace_settings & (TRACE_REQUEST | TRACE_PROCESS))
{
@@ -129,59 +204,32 @@
// Copy the string
memcpy( stringData, stringValue, stringDataLen );
- int size = offsetof(struct internal_msg_def, u);
- size += sizeof(msg.u.uniqstr);
- size += stringDataLen;
-
+ ptpMsgInfo_t myInfo;
+ myInfo.pnid = MyPNID;
+ myInfo.size = offsetof(struct internal_msg_def, u);
+ myInfo.size += sizeof(msg.u.uniqstr);
+ myInfo.size += stringDataLen;
+
if (trace_settings & TRACE_PROCESS_DETAIL)
{
trace_printf( "%s@%d - size_=%d, forwarding unique string [%d, %d] (%s)\n"
, method_name, __LINE__
- , size
+ , myInfo.size
, msg.u.uniqstr.nid
, msg.u.uniqstr.id
, &msg.u.uniqstr.valueData );
}
- int error = SendToMon("add-unique-string", &msg, size, targetNid, targetNodeName);
+ int error = SendToMon( "process-add-unique-string"
+ , &msg
+ , myInfo
+ , targetNid
+ , targetNodeName);
TRACE_EXIT;
return error;
}
-int CPtpClient::InitializePtpClient( char * ptpPort )
-{
- const char method_name[] = "CPtpClient::InitializePtpClient";
- TRACE_ENTRY;
- int err = 0;
-
- int sock = Monitor->MkCltSock( ptpPort );
- if (sock < 0)
- {
- err = sock;
-
- if (trace_settings & (TRACE_REQUEST | TRACE_PROCESS))
- {
- trace_printf( "%s@%d - MkCltSock failed with error %d\n"
- , method_name, __LINE__, err );
- }
- }
- else
- {
- ptpSock_ = sock;
- if (trace_settings & (TRACE_REQUEST | TRACE_PROCESS))
- {
- trace_printf( "%s@%d - connected to monitor node=%s, sock=%d\n"
- , method_name, __LINE__
- , ptpPort
- , ptpSock_ );
- }
- }
-
- TRACE_EXIT;
- return err;
-}
-
int CPtpClient::ProcessClone( CProcess *process )
{
const char method_name[] = "CPtpClient::ProcessClone";
@@ -209,6 +257,18 @@
return(0);
}
+ if (!IsTargetRemote( process->GetParentNid() ))
+ {
+ if (trace_settings & (TRACE_REQUEST | TRACE_PROCESS))
+ {
+ trace_printf( "%s@%d - Not Sending InternalType_Clone request to "
+ "local nid=%d\n"
+ , method_name, __LINE__
+ , process->GetParentNid() );
+ }
+ return(0);
+ }
+
if (trace_settings & (TRACE_REQUEST | TRACE_PROCESS))
{
trace_printf( "%s@%d - Sending InternalType_Clone request to %s, parentNid=%d"
@@ -281,13 +341,15 @@
msg.u.clone.argvLen = argvLen;
memcpy( stringData, process->userArgv(), argvLen );
- int size = offsetof(struct internal_msg_def, u);
- size += sizeof(msg.u.clone);
- size += nameLen ;
- size += portLen ;
- size += infileLen ;
- size += outfileLen ;
- size += argvLen ;
+ ptpMsgInfo_t myInfo;
+ myInfo.pnid = MyPNID;
+ myInfo.size = offsetof(struct internal_msg_def, u);
+ myInfo.size += sizeof(msg.u.clone);
+ myInfo.size += nameLen ;
+ myInfo.size += portLen ;
+ myInfo.size += infileLen ;
+ myInfo.size += outfileLen ;
+ myInfo.size += argvLen ;
if (trace_settings & TRACE_PROCESS_DETAIL)
{
@@ -299,7 +361,7 @@
"outfile=%s, strlen(outfile)=%d, "
"argc=%d, strlen(total argv)=%d, args=[%.*s]\n"
, method_name, __LINE__
- , size
+ , myInfo.size
, msg.u.clone.programStrId.nid
, msg.u.clone.programStrId.id
, msg.u.clone.pathStrId.nid
@@ -322,7 +384,7 @@
int error = SendToMon( "process-clone"
, &msg
- , size
+ , myInfo
, process->GetParentNid()
, parentLNode->GetNode()->GetName());
@@ -337,6 +399,18 @@
const char method_name[] = "CPtpClient::ProcessExit";
TRACE_ENTRY;
+ if (!IsTargetRemote( targetNid ))
+ {
+ if (trace_settings & (TRACE_REQUEST | TRACE_PROCESS))
+ {
+ trace_printf( "%s@%d - Not Sending InternalType_Exit request to "
+ "local nid=%d\n"
+ , method_name, __LINE__
+ , targetNid );
+ }
+ return(0);
+ }
+
if (trace_settings & (TRACE_REQUEST | TRACE_PROCESS))
{
trace_printf( "%s@%d - Sending InternalType_Exit request to %s, targetNid=%d"
@@ -359,15 +433,17 @@
strcpy(msg.u.exit.name, process->GetName());
msg.u.exit.abended = process->IsAbended();
- int size = offsetof(struct internal_msg_def, u);
- size += sizeof(msg.u.exit);
+ ptpMsgInfo_t myInfo;
+ myInfo.pnid = MyPNID;
+ myInfo.size = offsetof(struct internal_msg_def, u);
+ myInfo.size += sizeof(msg.u.exit);
if (trace_settings & TRACE_PROCESS_DETAIL)
{
trace_printf( "%s@%d - size_=%d, process %s (%d,%d:%d) "
"abended=%d\n"
, method_name, __LINE__
- , size
+ , myInfo.size
, msg.u.exit.name
, msg.u.exit.nid
, msg.u.exit.pid
@@ -375,7 +451,11 @@
, msg.u.exit.abended );
}
- int error = SendToMon("process-exit", &msg, size, targetNid, targetNodeName);
+ int error = SendToMon( "process-exit"
+ , &msg
+ , myInfo
+ , targetNid
+ , targetNodeName);
TRACE_EXIT;
return error;
@@ -411,6 +491,18 @@
return(0);
}
+ if (!IsTargetRemote( process->GetParentNid() ))
+ {
+ if (trace_settings & (TRACE_REQUEST | TRACE_PROCESS))
+ {
+ trace_printf( "%s@%d - Not Sending InternalType_ProcessInit request to "
+ "local nid=%d\n"
+ , method_name, __LINE__
+ , process->GetParentNid() );
+ }
+ return(0);
+ }
+
if (trace_settings & (TRACE_REQUEST | TRACE_PROCESS))
{
trace_printf( "%s@%d" " - Sending InternalType_ProcessInit to parent node %s, parentNid=%d"
@@ -438,12 +530,14 @@
msg.u.processInit.tag = tag;
msg.u.processInit.origNid = process->GetParentNid();
- int size = offsetof(struct internal_msg_def, u);
- size += sizeof(msg.u.processInit);
+ ptpMsgInfo_t myInfo;
+ myInfo.pnid = MyPNID;
+ myInfo.size = offsetof(struct internal_msg_def, u);
+ myInfo.size += sizeof(msg.u.processInit);
int error = SendToMon( "process-init"
, &msg
- , size
+ , myInfo
, parentNid
, parentLNode->GetNode()->GetName() );
@@ -460,6 +554,18 @@
const char method_name[] = "CPtpClient::ProcessKill";
TRACE_ENTRY;
+ if (!IsTargetRemote( targetNid ))
+ {
+ if (trace_settings & (TRACE_REQUEST | TRACE_PROCESS))
+ {
+ trace_printf( "%s@%d - Not Sending InternalType_Kill request to "
+ "local nid=%d\n"
+ , method_name, __LINE__
+ , targetNid );
+ }
+ return(0);
+ }
+
if (trace_settings & (TRACE_REQUEST | TRACE_PROCESS))
{
trace_printf( "%s@%d - Sending InternalType_Kill request to %s, targetNid=%d"
@@ -480,22 +586,28 @@
msg.u.kill.verifier = process->GetVerifier();
msg.u.kill.persistent_abort = abort;
- int size = offsetof(struct internal_msg_def, u);
- size += sizeof(msg.u.exit);
+ ptpMsgInfo_t myInfo;
+ myInfo.pnid = MyPNID;
+ myInfo.size = offsetof(struct internal_msg_def, u);
+ myInfo.size += sizeof(msg.u.exit);
if (trace_settings & TRACE_PROCESS_DETAIL)
{
trace_printf( "%s@%d - size_=%d, process (%d,%d:%d) "
"persistent_abort=%d\n"
, method_name, __LINE__
- , size
+ , myInfo.size
, msg.u.kill.nid
, msg.u.kill.pid
, msg.u.kill.verifier
, msg.u.kill.persistent_abort );
}
- int error = SendToMon("process-kill", &msg, size, targetNid, targetNodeName);
+ int error = SendToMon( "process-kill"
+ , &msg
+ , myInfo
+ , targetNid
+ , targetNodeName);
TRACE_EXIT;
return error;
@@ -508,6 +620,18 @@
const char method_name[] = "CPtpClient::ProcessNew";
TRACE_ENTRY;
+ if (!IsTargetRemote( targetNid ))
+ {
+ if (trace_settings & (TRACE_REQUEST | TRACE_PROCESS))
+ {
+ trace_printf( "%s@%d - Not Sending InternalType_Process request to "
+ "local nid=%d\n"
+ , method_name, __LINE__
+ , targetNid );
+ }
+ return(0);
+ }
+
if (trace_settings & (TRACE_REQUEST | TRACE_PROCESS))
{
trace_printf( "%s@%d - Sending InternalType_Process request to %s, targetNid=%d"
@@ -567,12 +691,14 @@
msg.u.process.argvLen = argvLen;
memcpy( stringData, process->userArgv(), argvLen );
- int size = offsetof(struct internal_msg_def, u);
- size += sizeof(msg.u.process);
- size += nameLen ;
- size += infileLen ;
- size += outfileLen ;
- size += argvLen ;
+ ptpMsgInfo_t myInfo;
+ myInfo.pnid = MyPNID;
+ myInfo.size = offsetof(struct internal_msg_def, u);
+ myInfo.size += sizeof(msg.u.process);
+ myInfo.size += nameLen ;
+ myInfo.size += infileLen ;
+ myInfo.size += outfileLen ;
+ myInfo.size += argvLen ;
if (trace_settings & TRACE_PROCESS_DETAIL)
{
@@ -583,7 +709,7 @@
"outfile=%s, strlen(outfile)=%d, "
"argc=%d, strlen(total argv)=%d, args=[%.*s]\n"
, method_name, __LINE__
- , size
+ , myInfo.size
, msg.u.process.programStrId.nid
, msg.u.process.programStrId.id
, msg.u.process.pathStrId.nid
@@ -602,7 +728,11 @@
, &msg.u.process.stringData+nameLen+infileLen+outfileLen);
}
- int error = SendToMon("process-new", &msg, size, targetNid, targetNodeName);
+ int error = SendToMon( "process-new"
+ , &msg
+ , myInfo
+ , targetNid
+ , targetNodeName);
TRACE_EXIT;
return error;
@@ -620,6 +750,18 @@
const char method_name[] = "CPtpClient::ProcessNotify";
TRACE_ENTRY;
+ if (!IsTargetRemote( targetNid ))
+ {
+ if (trace_settings & (TRACE_REQUEST | TRACE_PROCESS))
+ {
+ trace_printf( "%s@%d - Not Sending InternalType_Notify request to "
+ "local nid=%d\n"
+ , method_name, __LINE__
+ , targetNid );
+ }
+ return(0);
+ }
+
if (trace_settings & (TRACE_REQUEST | TRACE_PROCESS))
{
trace_printf( "%s@%d - Sending InternalType_Notify request to %s"
@@ -682,18 +824,342 @@
}
}
- int size = offsetof(struct internal_msg_def, u);
- size += sizeof(msg.u.notify);
+ ptpMsgInfo_t myInfo;
+ myInfo.pnid = MyPNID;
+ myInfo.size = offsetof(struct internal_msg_def, u);
+ myInfo.size += sizeof(msg.u.notify);
- int error = SendToMon("process-notify", &msg, size, targetNid, targetNodeName);
+ int error = SendToMon( "process-notify"
+ , &msg
+ , myInfo
+ , targetNid
+ , targetNodeName);
TRACE_EXIT;
return error;
}
-int CPtpClient::ReceiveSock(char *buf, int size, int sockFd)
+int CPtpClient::ProcessStdInReq( int nid
+ , int pid
+ , StdinReqType type
+ , int supplierNid
+ , int supplierPid )
{
- const char method_name[] = "CPtpClient::ReceiveSock";
+ const char method_name[] = "CPtpClient::ProcessStdInReq";
+ TRACE_ENTRY;
+
+ if (trace_settings & (TRACE_REDIRECTION | TRACE_PROCESS))
+ {
+ trace_printf( "%s@%d - Sending InternalType_StdinReq request type =%d "
+ "from (%d,%d), for supplier (%d,%d)\n"
+ , method_name, __LINE__
+ , type
+ , nid
+ , pid
+ , supplierNid
+ , supplierPid );
+ }
+
+ CLNode *lnode = Nodes->GetLNode( supplierNid );
+ if (lnode == NULL)
+ {
+ char buf[MON_STRING_BUF_SIZE];
+ snprintf( buf, sizeof(buf)
+ , "[%s], Can't find supplier node nid=%d "
+ "for stdin data request.\n"
+ , method_name
+ , supplierNid );
+ mon_log_write(PTPCLIENT_STDINREQ_1, SQ_LOG_ERR, buf);
+
+ TRACE_EXIT;
+ return -1;
+ }
+
+ CProcess *process = lnode->GetProcessL( supplierPid );
+ if (process == NULL)
+ {
+ char buf[MON_STRING_BUF_SIZE];
+ snprintf( buf, sizeof(buf)
+ , "[%s], Can't find process nid=%d, "
+ "pid=%d for stdin data request.\n"
+ , method_name
+ , supplierNid
+ , supplierPid );
+ mon_log_write(PTPCLIENT_STDINREQ_2, SQ_LOG_ERR, buf);
+
+ TRACE_EXIT;
+ return -1;
+ }
+
+ struct internal_msg_def msg;
+ memset(&msg, 0, sizeof(msg));
+ msg.type = InternalType_StdinReq;
+ msg.u.stdin_req.nid = nid;
+ msg.u.stdin_req.pid = pid;
+ msg.u.stdin_req.reqType = type;
+ msg.u.stdin_req.supplier_nid = supplierNid;
+ msg.u.stdin_req.supplier_pid = supplierPid;
+
+ ptpMsgInfo_t myInfo;
+ myInfo.pnid = MyPNID;
+ myInfo.size = offsetof(struct internal_msg_def, u);
+ myInfo.size += sizeof(msg.u.stdin_req);
+
+ if (trace_settings & (TRACE_REDIRECTION | TRACE_PROCESS_DETAIL))
+ {
+ trace_printf( "%s@%d - size_=%d, type =%d "
+ "from (%d,%d), for supplier (%d,%d)\n"
+ , method_name, __LINE__
+ , myInfo.size
+ , msg.u.stdin_req.reqType
+ , msg.u.stdin_req.nid
+ , msg.u.stdin_req.pid
+ , msg.u.stdin_req.supplier_nid
+ , msg.u.stdin_req.supplier_pid );
+ }
+
+ int error = SendToMon( "process-stdin"
+ , &msg
+ , myInfo
+ , process->GetNid()
+ , lnode->GetNode()->GetName());
+
+ TRACE_EXIT;
+ return error;
+}
+
+int CPtpClient::ProcessStdIoData( int nid
+ , int pid
+ , StdIoType type
+ , ssize_t count
+ , char *data )
+{
+ const char method_name[] = "CPtpClient::ProcessStdIoData";
+ TRACE_ENTRY;
+
+ if (trace_settings & (TRACE_REDIRECTION | TRACE_PROCESS))
+ {
+ trace_printf( "%s@%d - Sending InternalType_IoData request type =%d "
+ "to (%d,%d), count=%ld\n"
+ , method_name, __LINE__
+ , type
+ , nid
+ , pid
+ , count );
+ }
+
+ CLNode *lnode = Nodes->GetLNode( nid );
+ if (lnode == NULL)
+ {
+ char buf[MON_STRING_BUF_SIZE];
+ snprintf( buf, sizeof(buf)
+ , "[%s], Can't find supplier node nid=%d "
+ "for stdin data request.\n"
+ , method_name
+ , nid );
+ mon_log_write(PTPCLIENT_STDIODATA_1, SQ_LOG_ERR, buf);
+
+ TRACE_EXIT;
+ return -1;
+ }
+
+ CProcess *process = lnode->GetProcessL( pid );
+ if (process == NULL)
+ {
+ char buf[MON_STRING_BUF_SIZE];
+ snprintf( buf, sizeof(buf)
+ , "[%s], Can't find process nid=%d, "
+ "pid=%d for stdin data request.\n"
+ , method_name
+ , nid
+ , pid );
+ mon_log_write(PTPCLIENT_STDIODATA_2, SQ_LOG_ERR, buf);
+
+ TRACE_EXIT;
+ return -1;
+ }
+
+ struct internal_msg_def msg;
+ memset(&msg, 0, sizeof(msg));
+ msg.type = InternalType_IoData;
+ msg.u.iodata.nid = nid ;
+ msg.u.iodata.pid = pid ;
+ msg.u.iodata.ioType = type ;
+ msg.u.iodata.length = count;
+ memcpy(&msg.u.iodata.data, data, count);
+
+ ptpMsgInfo_t myInfo;
+ myInfo.pnid = MyPNID;
+ myInfo.size = offsetof(struct internal_msg_def, u);
+ myInfo.size += sizeof(msg.u.iodata);
+
+ if (trace_settings & (TRACE_REDIRECTION | TRACE_PROCESS_DETAIL))
+ {
+ trace_printf( "%s@%d - size_=%d, type =%d "
+ "to (%d,%d), count=%d\n(%s)"
+ , method_name, __LINE__
+ , myInfo.size
+ , msg.u.iodata.ioType
+ , msg.u.iodata.nid
+ , msg.u.iodata.pid
+ , msg.u.iodata.length
+ , msg.u.iodata.length?msg.u.iodata.data:"\n" );
+ }
+
+ int error = SendToMon( "process-stdio-data"
+ , &msg
+ , myInfo
+ , process->GetNid()
+ , lnode->GetNode()->GetName());
+
+ TRACE_EXIT;
+ return error;
+}
+
+int CPtpClient::SendToMon(const char *reqType, internal_msg_def *msg
+ , ptpMsgInfo_t &myInfo
+ , int targetNid, const char *hostName)
+{
+ const char method_name[] = "CPtpClient::SendToMon";
+ TRACE_ENTRY;
+
+ char ptpHost[MAX_PROCESSOR_NAME];
+ char ptpPort[MAX_PROCESSOR_NAME];
+ int error = 0;
+ int tempPort = ptpCommPort_;
+ int pnid = 0;
+ int sendSock = -1;
+ int retryCount = 0;
+ CNode *node = NULL;
+ CLNode *lnode = NULL;
+
+ ptpHost[0] = '\0';
+ lnode = Nodes->GetLNode( targetNid );
+ node = lnode->GetNode();
+ pnid = node->GetPNid();
+
+ // For virtual env
+ if (!IsRealCluster)
+ {
+ tempPort += targetNid;
+ strcat( ptpHost, ptpHost_ );
+ }
+ else
+ {
+ strcat( ptpHost, hostName );
+ }
+
+ if (trace_settings & (TRACE_REQUEST | TRACE_PROCESS))
+ {
+ trace_printf( "%s@%d - reqType=%s, hostName=%s, targetNid=%d, "
+ "ptpHost=%s, tempPort=%d, ptpCommPort_=%d\n"
+ , method_name, __LINE__
+ , reqType
+ , hostName
+ , targetNid
+ , ptpHost
+ , tempPort
+ , ptpCommPort_ );
+ }
+
+ memset( &ptpPort, 0, MAX_PROCESSOR_NAME );
+ memset( &ptpPortBase_, 0, MAX_PROCESSOR_NAME+100 );
+ sprintf( ptpPortBase_,"%s:", ptpHost );
+ sprintf( ptpPort,"%s%d", ptpPortBase_, tempPort );
+
+retryIO:
+
+ if (ptpClusterSocks_[pnid] == -1)
+ {
+ error = InitializePtpClient( pnid, ptpPort );
+ if (error < 0)
+ {
+ ptpClusterSocks_[pnid] = -1;
+ TRACE_EXIT;
+ return error;
+ }
+ }
+
+ sendSock = ptpClusterSocks_[pnid];
+
+ if (trace_settings & (TRACE_REQUEST | TRACE_PROCESS))
+ {
+ trace_printf( "%s@%d - sending %s REQ to Monitor=%s, sock=%d\n"
+ , method_name, __LINE__
+ , reqType
+ , ptpPort
+ , sendSock );
+ }
+
+ error = SockSend((char *) &myInfo, sizeof(ptpMsgInfo_t), sendSock);
+ if (error)
+ {
+ int err = error;
+ char buf[MON_STRING_BUF_SIZE];
+ snprintf( buf, sizeof(buf)
+ , "[%s], unable to send %s request size %ld to "
+ "node %s, error: %d(%s)\n"
+ , method_name, reqType, sizeof(ptpMsgInfo_t), ptpHost, err, strerror(err) );
+ mon_log_write(PTPCLIENT_SENDTOMON_1, SQ_LOG_ERR, buf);
+ }
+ else
+ {
+ error = SockSend((char *) msg, myInfo.size, sendSock);
+ if (error)
+ {
+ int err = error;
+ char buf[MON_STRING_BUF_SIZE];
+ snprintf( buf, sizeof(buf)
+ , "[%s], unable to send %s request to "
+ "node %s, error: %d(%s)\n"
+ , method_name, reqType, ptpHost, err, strerror(err) );
+ mon_log_write(PTPCLIENT_SENDTOMON_2, SQ_LOG_ERR, buf);
+ }
+ }
+
+ if (error)
+ {
+ SockClose( pnid );
+ if ( retryCount < MON2MON_IO_RETRIES )
+ {
+ retryCount++;
+ if (trace_settings & (TRACE_REQUEST | TRACE_PROCESS))
+ {
+ trace_printf( "%s@%d - retrying IO (%d) to node %s\n"
+ , method_name, __LINE__
+ , retryCount
+ , ptpHost );
+ }
+ goto retryIO;
+ }
+ }
+
+ TRACE_EXIT;
+ return error;
+}
+
+void CPtpClient::SockClose( int pnid )
+{
+ const char method_name[] = "CPtpClient::SockClose";
+ TRACE_ENTRY;
+
+ if (ptpClusterSocks_[pnid] != -1)
+ {
+ close( ptpClusterSocks_[pnid] );
+ ptpClusterSocks_[pnid] = -1;
+ }
+
+ TRACE_EXIT;
+}
+
+void CPtpClient::SetLocalHost( void )
+{
+ gethostname( ptpHost_, MAX_PROCESSOR_NAME );
+}
+
+int CPtpClient::SockReceive(char *buf, int size, int sockFd)
+{
+ const char method_name[] = "CPtpClient::SockReceive";
TRACE_ENTRY;
bool readAgain = false;
@@ -764,14 +1230,9 @@
return error;
}
-void CPtpClient::SetLocalHost( void )
+int CPtpClient::SockSend(char *buf, int size, int sockFd)
{
- gethostname( ptpHost_, MAX_PROCESSOR_NAME );
-}
-
-int CPtpClient::SendSock(char *buf, int size, int sockFd)
-{
- const char method_name[] = "CPtpClient::SendSock";
+ const char method_name[] = "CPtpClient::SockSend";
TRACE_ENTRY;
bool sendAgain = false;
@@ -833,270 +1294,3 @@
return error;
}
-int CPtpClient::SendToMon(const char *reqType, internal_msg_def *msg, int size,
- int receiveNode, const char *hostName)
-{
- const char method_name[] = "CPtpClient::SendToMon";
- TRACE_ENTRY;
-
- char monPortString[MAX_PROCESSOR_NAME];
- char ptpHost[MAX_PROCESSOR_NAME];
- char ptpPort[MAX_PROCESSOR_NAME];
- int tempPort = basePort_;
-
- ptpHost[0] = '\0';
-
- // For virtual env
- if (!IsRealCluster)
- {
- tempPort += receiveNode;
- strcat( ptpHost, ptpHost_ );
- }
- else
- {
- strcat( ptpHost, hostName );
- }
-
- if (trace_settings & (TRACE_REQUEST | TRACE_PROCESS))
- {
- trace_printf( "%s@%d - reqType=%s, hostName=%s, receiveNode=%d, "
- "ptpHost=%s, tempPort=%d, basePort_=%d\n"
- , method_name, __LINE__
- , reqType
- , hostName
- , receiveNode
- , ptpHost
- , tempPort
- , basePort_ );
- }
-
- memset( &ptpPort, 0, MAX_PROCESSOR_NAME );
- memset( &ptpPortBase_, 0, MAX_PROCESSOR_NAME+100 );
-
- strcat( ptpPortBase_, ptpHost );
- strcat( ptpPortBase_, ":" );
- sprintf( monPortString,"%d", tempPort );
- strcat( ptpPort, ptpPortBase_ );
- strcat( ptpPort, monPortString );
-
- int error = InitializePtpClient( ptpPort );
- if (error < 0)
- {
- TRACE_EXIT;
- return error;
- }
-
- if (trace_settings & (TRACE_REQUEST | TRACE_PROCESS))
- {
- trace_printf( "%s@%d - sending %s REQ to Monitor=%s, sock=%d\n"
- , method_name, __LINE__
- , reqType
- , ptpPort
- , ptpSock_);
- }
-
- error = SendSock((char *) &size, sizeof(size), ptpSock_);
- if (error)
- {
- if (trace_settings & (TRACE_REQUEST | TRACE_PROCESS))
- {
- trace_printf( "%s@%d - error sending to Monitor=%s, sock=%d, error=%d\n"
- , method_name, __LINE__
- , ptpPort
- , ptpSock_
- , error );
- }
- }
-
- error = SendSock((char *) msg, size, ptpSock_);
- if (error)
- {
- if (trace_settings & (TRACE_REQUEST | TRACE_PROCESS))
- {
- trace_printf( "%s@%d - error sending to nameserver=%s, sock=%d, error=%d\n"
- , method_name, __LINE__
- , ptpPort
- , ptpSock_
- , error );
- }
- }
-
- close( ptpSock_ );
-
- TRACE_EXIT;
- return error;
-}
-
-int CPtpClient::StdInReq( int nid
- , int pid
- , StdinReqType type
- , int supplierNid
- , int supplierPid )
-{
- const char method_name[] = "CPtpClient::StdInReq";
- TRACE_ENTRY;
-
- if (trace_settings & (TRACE_REDIRECTION | TRACE_PROCESS))
- {
- trace_printf( "%s@%d - Sending InternalType_StdinReq request type =%d "
- "from (%d,%d), for supplier (%d,%d)\n"
- , method_name, __LINE__
- , type
- , nid
- , pid
- , supplierNid
- , supplierPid );
- }
-
- CLNode *lnode = Nodes->GetLNode( supplierNid );
- if (lnode == NULL)
- {
- char buf[MON_STRING_BUF_SIZE];
- snprintf( buf, sizeof(buf)
- , "[%s], Can't find supplier node nid=%d "
- "for stdin data request.\n"
- , method_name
- , supplierNid );
- mon_log_write(PTPCLIENT_STDINREQ_1, SQ_LOG_ERR, buf);
-
- TRACE_EXIT;
- return -1;
- }
-
- CProcess *process = lnode->GetProcessL( supplierPid );
- if (process == NULL)
- {
- char buf[MON_STRING_BUF_SIZE];
- snprintf( buf, sizeof(buf)
- , "[%s], Can't find process nid=%d, "
- "pid=%d for stdin data request.\n"
- , method_name
- , supplierNid
- , supplierPid );
- mon_log_write(PTPCLIENT_STDINREQ_2, SQ_LOG_ERR, buf);
-
- TRACE_EXIT;
- return -1;
- }
-
- struct internal_msg_def msg;
- memset(&msg, 0, sizeof(msg));
- msg.type = InternalType_StdinReq;
- msg.u.stdin_req.nid = nid;
- msg.u.stdin_req.pid = pid;
- msg.u.stdin_req.reqType = type;
- msg.u.stdin_req.supplier_nid = supplierNid;
- msg.u.stdin_req.supplier_pid = supplierPid;
-
- int size = offsetof(struct internal_msg_def, u);
- size += sizeof(msg.u.stdin_req);
-
- if (trace_settings & (TRACE_REDIRECTION | TRACE_PROCESS_DETAIL))
- {
- trace_printf( "%s@%d - size_=%d, type =%d "
- "from (%d,%d), for supplier (%d,%d)\n"
- , method_name, __LINE__
- , size
- , msg.u.stdin_req.reqType
- , msg.u.stdin_req.nid
- , msg.u.stdin_req.pid
- , msg.u.stdin_req.supplier_nid
- , msg.u.stdin_req.supplier_pid );
- }
-
- int error = SendToMon("stdin"
- , &msg
- , size
- , process->GetNid()
- , lnode->GetNode()->GetName());
-
- TRACE_EXIT;
- return error;
-}
-
-int CPtpClient::StdIoData( int nid
- , int pid
- , StdIoType type
- , ssize_t count
- , char *data )
-{
- const char method_name[] = "CPtpClient::StdIoData";
- TRACE_ENTRY;
-
- if (trace_settings & (TRACE_REDIRECTION | TRACE_PROCESS))
- {
- trace_printf( "%s@%d - Sending InternalType_IoData request type =%d "
- "to (%d,%d), count=%ld\n"
- , method_name, __LINE__
- , type
- , nid
- , pid
- , count );
- }
-
- CLNode *lnode = Nodes->GetLNode( nid );
- if (lnode == NULL)
- {
- char buf[MON_STRING_BUF_SIZE];
- snprintf( buf, sizeof(buf)
- , "[%s], Can't find supplier node nid=%d "
- "for stdin data request.\n"
- , method_name
- , nid );
- mon_log_write(PTPCLIENT_STDIODATA_1, SQ_LOG_ERR, buf);
-
- TRACE_EXIT;
- return -1;
- }
-
- CProcess *process = lnode->GetProcessL( pid );
- if (process == NULL)
- {
- char buf[MON_STRING_BUF_SIZE];
- snprintf( buf, sizeof(buf)
- , "[%s], Can't find process nid=%d, "
- "pid=%d for stdin data request.\n"
- , method_name
- , nid
- , pid );
- mon_log_write(PTPCLIENT_STDIODATA_2, SQ_LOG_ERR, buf);
-
- TRACE_EXIT;
- return -1;
- }
-
- struct internal_msg_def msg;
- memset(&msg, 0, sizeof(msg));
- msg.type = InternalType_IoData;
- msg.u.iodata.nid = nid ;
- msg.u.iodata.pid = pid ;
- msg.u.iodata.ioType = type ;
- msg.u.iodata.length = count;
- memcpy(&msg.u.iodata.data, data, count);
-
- int size = offsetof(struct internal_msg_def, u);
- size += sizeof(msg.u.iodata);
-
- if (trace_settings & (TRACE_REDIRECTION | TRACE_PROCESS_DETAIL))
- {
- trace_printf( "%s@%d - size_=%d, type =%d "
- "to (%d,%d), count=%d\n(%s)"
- , method_name, __LINE__
- , size
- , msg.u.iodata.ioType
- , msg.u.iodata.nid
- , msg.u.iodata.pid
- , msg.u.iodata.length
- , msg.u.iodata.length?msg.u.iodata.data:"\n" );
- }
-
- int error = SendToMon("stdio-data"
- , &msg
- , size
- , process->GetNid()
- , lnode->GetNode()->GetName());
-
- TRACE_EXIT;
- return error;
-}
-
diff --git a/core/sqf/monitor/linux/ptpclient.h b/core/sqf/monitor/linux/ptpclient.h
index e6ddeb4..5239c78 100644
--- a/core/sqf/monitor/linux/ptpclient.h
+++ b/core/sqf/monitor/linux/ptpclient.h
@@ -40,58 +40,66 @@
CPtpClient( void );
virtual ~CPtpClient( void );
- int AddUniqStr( int nid
- , int id
- , const char *stringValue
- , int targetNid
- , const char *targetNodeName );
- int InitializePtpClient( char * ptpPort );
- int ProcessClone( CProcess *process );
+ int InitializePtpClient( int pnid, char* ptpPort );
+ int ProcessAddUniqStr( int nid
+ , int id
+ , const char* stringValue
+ , int targetNid
+ , const char* targetNodeName );
+ int ProcessClone( CProcess* process );
int ProcessExit( CProcess* process
, int parentNid
- , const char *targetNodeName );
- int ProcessInit( CProcess *process
- , void *tag
+ , const char* targetNodeName );
+ int ProcessInit( CProcess* process
+ , void* tag
, int result
, int parentNid );
int ProcessKill( CProcess* process
, bool abort
, int targetNid
- , const char *targetNodeName );
+ , const char* targetNodeName );
int ProcessNew( CProcess* process
, int targetNid
- , const char *targetNodeName );
+ , const char* targetNodeName );
int ProcessNotify( int nid
, int pid
, Verifier_t verifier
, _TM_Txid_External transId
, bool canceled
- , CProcess *targetProcess
+ , CProcess* targetProcess
, int targetNid
- , const char *targetNodeName );
- int StdInReq( int nid
- , int pid
- , StdinReqType type
- , int supplierNid
- , int supplierPid );
- int StdIoData( int nid
- , int pid
- , StdIoType type
- , ssize_t count
- , char *data );
+ , const char* targetNodeName );
+ int ProcessStdInReq( int nid
+ , int pid
+ , StdinReqType type
+ , int supplierNid
+ , int supplierPid );
+ int ProcessStdIoData( int nid
+ , int pid
+ , StdIoType type
+ , ssize_t count
+ , char* data );
private:
- int basePort_;
+ int ptpCommPort_;
char ptpHost_[MAX_PROCESSOR_NAME];
char ptpPortBase_[MAX_PROCESSOR_NAME+100];
- int ptpSock_;
+ int *ptpClusterSocks_;
int seqNum_;
- int ReceiveSock(char *buf, int size, int sockFd);
- int SendSock(char *buf, int size, int sockFd);
- int SendToMon(const char *reqType, internal_msg_def *msg, int size, int receiveNode, const char *hostName);
+ bool IsTargetRemote( int targetNid );
+ int SendToMon( const char* reqType
+ , internal_msg_def* msg
+ , ptpMsgInfo_t &myInfo
+ , int receiveNode
+ , const char* hostName);
void SetLocalHost( void );
+ void SockClose( int pnid );
+ int SockReceive(char* buf, int size, int sockFd);
+ int SockSend( char* buf
+ , int size
+ , int sockFd);
};
#endif
diff --git a/core/sqf/monitor/linux/ptpcommaccept.cxx b/core/sqf/monitor/linux/ptpcommaccept.cxx
index d380d3a..15933dd 100644
--- a/core/sqf/monitor/linux/ptpcommaccept.cxx
+++ b/core/sqf/monitor/linux/ptpcommaccept.cxx
@@ -47,6 +47,7 @@
extern const char *StateString( STATE state);
extern CommType_t CommType;
+static void *ptpProcess( void *arg );
CPtpCommAccept::CPtpCommAccept()
: accepting_(true)
@@ -71,156 +72,206 @@
{
const char method_name[] = "CPtpCommAccept::processNewSock";
TRACE_ENTRY;
-
- struct internal_msg_def msg;
- int rc;
-
- mem_log_write(CMonLog::MON_CONNTONEWMON_2);
- int size;
- rc = Monitor->ReceiveSock( (char *) &size, sizeof(size), sockFd, method_name );
- if ( rc )
- { // Handle error
- close( sockFd );
- char buf[MON_STRING_BUF_SIZE];
- snprintf(buf, sizeof(buf), "[%s], unable to obtain node id from new "
- "monitor: %s.\n", method_name, ErrorMsg(rc));
- mon_log_write(PTP_COMMACCEPT_1, SQ_LOG_ERR, buf);
- return;
- }
- // Get info about connecting monitor
- rc = Monitor->ReceiveSock( (char *) &msg
- , size
- , sockFd
- , method_name );
-
- if ( rc )
- { // Handle error
- close( sockFd );
- char buf[MON_STRING_BUF_SIZE];
- snprintf(buf, sizeof(buf), "[%s], unable to obtain node id from new "
- "monitor: %s.\n", method_name, ErrorMsg(rc));
- mon_log_write(PTP_COMMACCEPT_2, SQ_LOG_ERR, buf);
- return;
- }
- else
+ int rc;
+
+ mem_log_write(CMonLog::MON_CONNTONEWMON_1);
+
+ // need to create context in case back-to-back accept is too fast
+ Context *ctx = new Context();
+ ctx->this_ = this;
+ ctx->pendingFd_ = sockFd;
+ rc = pthread_create(&process_thread_id_, NULL, ptpProcess, ctx);
+ if (rc != 0)
{
- switch ( msg.type )
+ char buf[MON_STRING_BUF_SIZE];
+ snprintf(buf, sizeof(buf), "[%s], ptpProcess thread create error=%d\n",
+ method_name, rc);
+ mon_log_write(PTP_COMMACCEPT_1, SQ_LOG_ERR, buf);
+ }
+
+ TRACE_EXIT;
+}
+
+void CPtpCommAccept::processMonReqs( int sockFd )
+{
+ const char method_name[] = "CPtpCommAccept::processMonReqs";
+ TRACE_ENTRY;
+
+ int rc;
+ struct internal_msg_def msg;
+
+ while ( true )
+ {
+ mem_log_write(CMonLog::MON_CONNTONEWMON_2);
+ ptpMsgInfo_t remoteInfo;
+
+ // Get info about connecting monitor
+ rc = Monitor->ReceiveSock( (char *) &remoteInfo
+ , sizeof(ptpMsgInfo_t)
+ , sockFd
+ , method_name );
+ if ( rc )
+ { // Handle error
+ char buf[MON_STRING_BUF_SIZE];
+ snprintf(buf, sizeof(buf), "[%s], unable to obtain message size and pnid "
+ "from remote monitor: %s.\n", method_name, ErrorMsg(rc));
+ mon_log_write(PTP_COMMACCEPT_2, SQ_LOG_ERR, buf);
+ return;
+ }
+
+ // Get info about connecting monitor
+ rc = Monitor->ReceiveSock( (char *) &msg
+ , remoteInfo.size
+ , sockFd
+ , method_name );
+ if ( rc )
+ { // Handle error
+ char buf[MON_STRING_BUF_SIZE];
+ CNode *node = Nodes->GetNode(remoteInfo.pnid);
+ snprintf( buf, sizeof(buf)
+ , "[%s], unable to obtain message size (%d) from remote "
+ "monitor %d(%s), error: %s.\n"
+ , method_name
+ , remoteInfo.size
+ , remoteInfo.pnid
+ , node ? node->GetName() : ""
+ , ErrorMsg(rc));
+ mon_log_write(PTP_COMMACCEPT_3, SQ_LOG_ERR, buf);
+ return;
+ }
+ else
{
- case InternalType_UniqStr:
+ switch ( msg.type )
{
- if (trace_settings & (TRACE_REQUEST | TRACE_PROCESS))
+ case InternalType_UniqStr:
{
- trace_printf( "%s@%d" " - Received InternalType_UniqStr\n"
- , method_name, __LINE__ );
+ if (trace_settings & (TRACE_REQUEST | TRACE_PROCESS))
+ {
+ trace_printf( "%s@%d" " - Received InternalType_UniqStr\n"
+ , method_name, __LINE__ );
+ }
+ ReqQueue.enqueueUniqStrReq( &msg.u.uniqstr);
+ break;
}
- ReqQueue.enqueueUniqStrReq( &msg.u.uniqstr);
- break;
- }
- case InternalType_Process:
- {
- if (trace_settings & (TRACE_REQUEST | TRACE_PROCESS))
+ case InternalType_Process:
{
- trace_printf( "%s@%d" " - Received InternalType_Process\n"
- , method_name, __LINE__ );
+ if (trace_settings & (TRACE_REQUEST | TRACE_PROCESS))
+ {
+ trace_printf( "%s@%d" " - Received InternalType_Process\n"
+ , method_name, __LINE__ );
+ }
+ ReqQueue.enqueueNewProcReq( &msg.u.process);
+ break;
}
- ReqQueue.enqueueNewProcReq( &msg.u.process);
- break;
- }
- case InternalType_ProcessInit:
- {
- if (trace_settings & (TRACE_REQUEST | TRACE_PROCESS))
+ case InternalType_ProcessInit:
{
- trace_printf( "%s@%d" " - Received InternalType_ProcessInit\n"
- , method_name, __LINE__ );
+ if (trace_settings & (TRACE_REQUEST | TRACE_PROCESS))
+ {
+ trace_printf( "%s@%d" " - Received InternalType_ProcessInit\n"
+ , method_name, __LINE__ );
+ }
+ if ( MyNode->IsMyNode(msg.u.processInit.origNid) )
+ { // New process request originated on this node
+ ReqQueue.enqueueProcInitReq( &msg.u.processInit);
+ }
+ else
+ {
+ abort();
+ }
+ break;
}
- if ( MyNode->IsMyNode(msg.u.processInit.origNid) )
- { // New process request originated on this node
- ReqQueue.enqueueProcInitReq( &msg.u.processInit);
- }
- else
+ case InternalType_Clone:
{
+ if (trace_settings & (TRACE_REQUEST | TRACE_PROCESS))
+ {
+ trace_printf( "%s@%d" " - Received InternalType_Clone\n"
+ , method_name, __LINE__ );
+ }
+ ReqQueue.enqueueCloneReq( &msg.u.clone );
+ break;
+ }
+ case InternalType_Open:
+ {
+ if (trace_settings & (TRACE_REQUEST | TRACE_PROCESS))
+ {
+ trace_printf( "%s@%d" " - Received InternalType_Open\n"
+ , method_name, __LINE__ );
+ }
+ ReqQueue.enqueueOpenReq( &msg.u.open );
+ break;
+ }
+ case InternalType_Notify:
+ {
+ if (trace_settings & (TRACE_REQUEST | TRACE_PROCESS))
+ {
+ trace_printf( "%s@%d" " - Received InternalType_Notify\n"
+ , method_name, __LINE__ );
+ }
+ ReqQueue.enqueueNotifyReq( &msg.u.notify );
+ break;
+ }
+ case InternalType_Exit:
+ {
+ if (trace_settings & (TRACE_REQUEST | TRACE_PROCESS))
+ {
+ trace_printf( "%s@%d" " - Received InternalType_Exit\n"
+ , method_name, __LINE__ );
+ }
+ ReqQueue.enqueueExitReq( &msg.u.exit );
+ break;
+ }
+ case InternalType_Kill:
+ {
+ if (trace_settings & (TRACE_REQUEST | TRACE_PROCESS))
+ {
+ trace_printf( "%s@%d" " - Received InternalType_Kill\n"
+ , method_name, __LINE__ );
+ }
+ ReqQueue.enqueueKillReq( &msg.u.kill );
+ break;
+ }
+ case InternalType_IoData:
+ {
+ if (trace_settings & (TRACE_REDIRECTION | TRACE_PROCESS))
+ {
+ trace_printf( "%s@%d" " - Received InternalType_IoData\n"
+ , method_name, __LINE__ );
+ }
+ ReqQueue.enqueueIoDataReq( &msg.u.iodata );
+ break;
+ }
+ case InternalType_StdinReq:
+ {
+ if (trace_settings & (TRACE_REDIRECTION | TRACE_PROCESS))
+ {
+ trace_printf( "%s@%d" " - Received InternalType_StdinReq\n"
+ , method_name, __LINE__ );
+ }
+ ReqQueue.enqueueStdInReq( &msg.u.stdin_req );
+ break;
+ }
+ default:
+ {
+ char buf[MON_STRING_BUF_SIZE];
+ CNode *node = Nodes->GetNode(remoteInfo.pnid);
+ snprintf( buf, sizeof(buf)
+ , "[%s], Invalid msg.type: %d, msg size=%d, "
+ "remote monitor %d(%s)\n"
+ , method_name
+ , msg.type
+ , remoteInfo.size
+ , remoteInfo.pnid
+ , node ? node->GetName() : "" );
+ mon_log_write(PTP_COMMACCEPT_4, SQ_LOG_ERR, buf);
abort();
}
- break;
- }
- case InternalType_Clone:
- {
- if (trace_settings & (TRACE_REQUEST | TRACE_PROCESS))
- {
- trace_printf( "%s@%d" " - Received InternalType_Clone\n"
- , method_name, __LINE__ );
- }
- ReqQueue.enqueueCloneReq( &msg.u.clone );
- break;
- }
- case InternalType_Open:
- {
- if (trace_settings & (TRACE_REQUEST | TRACE_PROCESS))
- {
- trace_printf( "%s@%d" " - Received InternalType_Open\n"
- , method_name, __LINE__ );
- }
- ReqQueue.enqueueOpenReq( &msg.u.open );
- break;
- }
- case InternalType_Notify:
- {
- if (trace_settings & (TRACE_REQUEST | TRACE_PROCESS))
- {
- trace_printf( "%s@%d" " - Received InternalType_Notify\n"
- , method_name, __LINE__ );
- }
- ReqQueue.enqueueNotifyReq( &msg.u.notify );
- break;
- }
- case InternalType_Exit:
- {
- if (trace_settings & (TRACE_REQUEST | TRACE_PROCESS))
- {
- trace_printf( "%s@%d" " - Received InternalType_Exit\n"
- , method_name, __LINE__ );
- }
- ReqQueue.enqueueExitReq( &msg.u.exit );
- break;
- }
- case InternalType_Kill:
- {
- if (trace_settings & (TRACE_REQUEST | TRACE_PROCESS))
- {
- trace_printf( "%s@%d" " - Received InternalType_Kill\n"
- , method_name, __LINE__ );
- }
- ReqQueue.enqueueKillReq( &msg.u.kill );
- break;
- }
- case InternalType_IoData:
- {
- if (trace_settings & (TRACE_REDIRECTION | TRACE_PROCESS))
- {
- trace_printf( "%s@%d" " - Received InternalType_IoData\n"
- , method_name, __LINE__ );
- }
- ReqQueue.enqueueIoDataReq( &msg.u.iodata );
- break;
- }
- case InternalType_StdinReq:
- {
- if (trace_settings & (TRACE_REDIRECTION | TRACE_PROCESS))
- {
- trace_printf( "%s@%d" " - Received InternalType_StdinReq\n"
- , method_name, __LINE__ );
- }
- ReqQueue.enqueueStdInReq( &msg.u.stdin_req );
- break;
- }
- default:
- {
- abort();
}
}
}
+ close( sockFd );
+
TRACE_EXIT;
}
@@ -285,7 +336,7 @@
continue; // Ok to accept another connection
}
}
-
+
if (shutdown_)
{ // We are being notified to exit.
break;
@@ -296,12 +347,12 @@
char buf[MON_STRING_BUF_SIZE];
snprintf(buf, sizeof(buf), "[%s], cannot accept new monitor: %s.\n",
method_name, strerror(errno));
- mon_log_write(PTP_COMMACCEPT_6, SQ_LOG_ERR, buf);
+ mon_log_write(PTP_COMMACCEPT_5, SQ_LOG_ERR, buf);
}
else
{
processNewSock( sockFd );
- close( sockFd );
+ //close( sockFd );
}
}
@@ -334,7 +385,7 @@
TRACE_EXIT;
}
-// Initialize PtpCommAcceptor thread
+// Initialize ptpCommAcceptor thread
static void *ptpCommAccept(void *arg)
{
const char method_name[] = "ptpCommAccept";
@@ -353,7 +404,7 @@
char buf[MON_STRING_BUF_SIZE];
snprintf(buf, sizeof(buf), "[%s], pthread_sigmask error=%d\n",
method_name, rc);
- mon_log_write(PTP_COMMACCEPT_7, SQ_LOG_ERR, buf);
+ mon_log_write(PTP_COMMACCEPT_6, SQ_LOG_ERR, buf);
}
// Enter thread processing loop
@@ -364,7 +415,38 @@
}
-// Create a commAcceptor thread
+// Initialize ptpProcess thread
+static void *ptpProcess(void *arg)
+{
+ const char method_name[] = "ptpProcess";
+ TRACE_ENTRY;
+
+ // Parameter passed to the thread is an context
+ CPtpCommAccept::Context *ctx = (CPtpCommAccept::Context *) arg;
+ CPtpCommAccept *cao = ctx->this_;
+
+ // Mask all allowed signals
+ sigset_t mask;
+ sigfillset(&mask);
+ sigdelset(&mask, SIGPROF); // allows profiling such as google profiler
+ int rc = pthread_sigmask(SIG_SETMASK, &mask, NULL);
+ if (rc != 0)
+ {
+ char buf[MON_STRING_BUF_SIZE];
+ snprintf(buf, sizeof(buf), "[%s], pthread_sigmask error=%d\n",
+ method_name, rc);
+ mon_log_write(PTP_COMMACCEPT_7, SQ_LOG_ERR, buf);
+ }
+
+ // Enter thread processing loop
+ cao->processMonReqs(ctx->pendingFd_);
+ delete ctx;
+
+ TRACE_EXIT;
+ return NULL;
+}
+
+// Create a ptpCommAccept thread
void CPtpCommAccept::start()
{
const char method_name[] = "CPtpCommAccept::start";
diff --git a/core/sqf/monitor/linux/ptpcommaccept.h b/core/sqf/monitor/linux/ptpcommaccept.h
index ca58139..78e9fe0 100644
--- a/core/sqf/monitor/linux/ptpcommaccept.h
+++ b/core/sqf/monitor/linux/ptpcommaccept.h
@@ -41,12 +41,19 @@
bool isAccepting( void ) { CAutoLock lock(getLocker()); return( accepting_ ); }
void monReqExec( void *req ); //stupid compiler and circular header files
+ void processMonReqs( int sockFd );
void processNewSock( int sockFd );
void startAccepting( void );
void stopAccepting( void );
void start( void );
void shutdownWork( void );
+ typedef struct
+ {
+ CPtpCommAccept *this_;
+ int pendingFd_;
+ } Context;
+
private:
void commAcceptorSock( void );
@@ -54,9 +61,10 @@
bool accepting_;
bool shutdown_;
- // commAccept thread's id
+ // ptpCommAccept thread's id
pthread_t thread_id_;
-
+ // ptpProcess thread's id
+ pthread_t process_thread_id_;
};
#endif
diff --git a/core/sqf/monitor/linux/redirector.cxx b/core/sqf/monitor/linux/redirector.cxx
index 43bb231..70e8f9c 100644
--- a/core/sqf/monitor/linux/redirector.cxx
+++ b/core/sqf/monitor/linux/redirector.cxx
@@ -564,7 +564,10 @@
TRACE_ENTRY;
// Delete pending buffer (if any)
- delete buffer_;
+ if (buffer_)
+ {
+ delete [] buffer_;
+ }
// Delete queued data (if any)
while (!ioDataList_.empty())
@@ -572,7 +575,7 @@
// Get first data buffer from list
buffer_ = ioDataList_.front();
ioDataList_.pop_front();
- delete buffer_;
+ delete [] buffer_;
}
// Alter eyecatcher sequence as a debugging aid to identify deleted object
@@ -646,7 +649,7 @@
retVal = -1;
bufferPos_ = 0;
- delete buffer_;
+ delete [] buffer_;
buffer_ = NULL;
reqType = STDIN_FLOW_ON;
@@ -659,7 +662,7 @@
else
{ // Have written all data, will need to get more.
bufferPos_ = 0;
- delete buffer_;
+ delete [] buffer_;
buffer_ = NULL;
reqType = STDIN_FLOW_ON;
@@ -667,11 +670,11 @@
if (NameServerEnabled)
{
- PtpClient->StdInReq( MyPNID
- , pid_
- , reqType
- , ancestorNid_
- , ancestorPid_ );
+ PtpClient->ProcessStdInReq( MyPNID
+ , pid_
+ , reqType
+ , ancestorNid_
+ , ancestorPid_ );
}
else
{
@@ -792,7 +795,7 @@
char buf[MON_STRING_BUF_SIZE];
sprintf(buf, "[%s], %s is an unsupported file type.\n",
method_name, filename);
- mon_log_write(MON_REDIR_STDINREMOTE_2, SQ_LOG_ERR, buf);
+ mon_log_write(MON_REDIR_STDINREMOTE_2, SQ_LOG_INFO, buf);
close(fd_);
fd_ = -1;
@@ -874,11 +877,11 @@
if (NameServerEnabled)
{
- PtpClient->StdIoData( requesterNid_
- , pid_
- , STDIN_DATA
- , count
- , buffer );
+ PtpClient->ProcessStdIoData( requesterNid_
+ , pid_
+ , STDIN_DATA
+ , count
+ , buffer );
}
else
{
@@ -1177,11 +1180,11 @@
if (NameServerEnabled)
{
- PtpClient->StdIoData( ancestor_nid_
- , ancestor_pid_
- , STDOUT_DATA
- , count
- , buffer );
+ PtpClient->ProcessStdIoData( ancestor_nid_
+ , ancestor_pid_
+ , STDOUT_DATA
+ , count
+ , buffer );
}
else
{
@@ -1654,11 +1657,11 @@
if (NameServerEnabled)
{
- PtpClient->StdInReq( nid
- , pid
- , STDIN_REQ_DATA
- , ancestor_nid
- , ancestor_pid );
+ PtpClient->ProcessStdInReq( nid
+ , pid
+ , STDIN_REQ_DATA
+ , ancestor_nid
+ , ancestor_pid );
}
else
{
diff --git a/core/sqf/monitor/linux/reqdump.cxx b/core/sqf/monitor/linux/reqdump.cxx
index 5d2dd5e..fda3cea 100644
--- a/core/sqf/monitor/linux/reqdump.cxx
+++ b/core/sqf/monitor/linux/reqdump.cxx
@@ -129,8 +129,11 @@
{
if ( target_process_name.size() )
{ // find by name
- targetProcess = Nodes->GetProcess( target_process_name.c_str()
- , target_verifier );
+ if (msg_->u.request.u.dump.target_process_name[0] == '$' )
+ {
+ targetProcess = Nodes->GetProcess( target_process_name.c_str()
+ , target_verifier );
+ }
}
else
{ // find by nid, pid
@@ -152,9 +155,12 @@
, target_process_name.c_str()
, target_verifier );
}
- cloneProcess = Nodes->CloneProcessNs( target_process_name.c_str()
- , target_verifier );
- targetProcess = cloneProcess;
+ if (msg_->u.request.u.dump.target_process_name[0] == '$' )
+ {
+ cloneProcess = Nodes->CloneProcessNs( target_process_name.c_str()
+ , target_verifier );
+ targetProcess = cloneProcess;
+ }
}
else
{ // Name Server find by nid,pid:verifier
diff --git a/core/sqf/monitor/linux/reqevent.cxx b/core/sqf/monitor/linux/reqevent.cxx
index 01c9067..f86582d 100644
--- a/core/sqf/monitor/linux/reqevent.cxx
+++ b/core/sqf/monitor/linux/reqevent.cxx
@@ -163,8 +163,11 @@
if ( target_process_name.size() )
{ // find by name
- targetProcess = Nodes->GetProcess( target_process_name.c_str()
- , target_verifier );
+ if (msg_->u.request.u.event.target_process_name[0] == '$' )
+ {
+ targetProcess = Nodes->GetProcess( target_process_name.c_str()
+ , target_verifier );
+ }
if ( !targetProcess )
{
if (NameServerEnabled)
@@ -176,9 +179,12 @@
, target_process_name.c_str()
, target_verifier );
}
- cloneProcess = Nodes->CloneProcessNs( target_process_name.c_str()
- , target_verifier );
- targetProcess = cloneProcess;
+ if (msg_->u.request.u.event.target_process_name[0] == '$' )
+ {
+ cloneProcess = Nodes->CloneProcessNs( target_process_name.c_str()
+ , target_verifier );
+ targetProcess = cloneProcess;
+ }
}
}
if ( targetProcess && trace_settings & (TRACE_REQUEST | TRACE_PROCESS))
diff --git a/core/sqf/monitor/linux/reqkill.cxx b/core/sqf/monitor/linux/reqkill.cxx
index b59cae2..a7f7b62 100644
--- a/core/sqf/monitor/linux/reqkill.cxx
+++ b/core/sqf/monitor/linux/reqkill.cxx
@@ -211,14 +211,17 @@
{
if ( target_process_name.size() )
{ // find by name (check node state, don't check process state, not backup)
- targetProcess = Nodes->GetProcess( target_process_name.c_str()
- , target_verifier
- , true, false, false );
- if ( targetProcess &&
- (msg_->u.request.u.kill.target_nid == -1 ||
- msg_->u.request.u.kill.target_pid == -1))
+ if (msg_->u.request.u.kill.target_process_name[0] == '$' )
{
- backup = targetProcess->GetBackup ();
+ targetProcess = Nodes->GetProcess( target_process_name.c_str()
+ , target_verifier
+ , true, false, false );
+ if ( targetProcess &&
+ (msg_->u.request.u.kill.target_nid == -1 ||
+ msg_->u.request.u.kill.target_pid == -1))
+ {
+ backup = targetProcess->GetBackup ();
+ }
}
}
else
@@ -256,9 +259,12 @@
, target_process_name.c_str()
, target_verifier );
}
- cloneProcess = Nodes->CloneProcessNs( target_process_name.c_str()
- , target_verifier );
- targetProcess = cloneProcess;
+ if (msg_->u.request.u.kill.target_process_name[0] == '$' )
+ {
+ cloneProcess = Nodes->CloneProcessNs( target_process_name.c_str()
+ , target_verifier );
+ targetProcess = cloneProcess;
+ }
}
else
{ // Name Server find by nid,pid:verifier
diff --git a/core/sqf/monitor/linux/reqnotify.cxx b/core/sqf/monitor/linux/reqnotify.cxx
index 4d278ce..5e69681 100644
--- a/core/sqf/monitor/linux/reqnotify.cxx
+++ b/core/sqf/monitor/linux/reqnotify.cxx
@@ -180,9 +180,12 @@
, target_process_name.c_str()
, target_verifier );
}
- targetProcess = Nodes->GetProcess( target_process_name.c_str()
- , target_verifier
- , true, false, false );
+ if (msg_->u.request.u.notify.target_process_name[0] == '$' )
+ {
+ targetProcess = Nodes->GetProcess( target_process_name.c_str()
+ , target_verifier
+ , true, false, false );
+ }
}
else
{ // find by nid (check node state, don't check process state, backup is Ok)
@@ -226,8 +229,11 @@
, target_process_name.c_str()
, target_verifier );
}
- targetProcess = Nodes->CloneProcessNs( target_process_name.c_str()
- , target_verifier );
+ if (msg_->u.request.u.notify.target_process_name[0] == '$' )
+ {
+ targetProcess = Nodes->CloneProcessNs( target_process_name.c_str()
+ , target_verifier );
+ }
}
else
{ // Name Server find by nid,pid:verifier
@@ -319,7 +325,7 @@
{
if (trace_settings & TRACE_REQUEST)
{
- trace_printf("%s@%d" " - Can't find targerProcess" "\n", method_name, __LINE__);
+ trace_printf("%s@%d" " - Can't find targetProcess" "\n", method_name, __LINE__);
}
}
}
diff --git a/core/sqf/monitor/linux/reqopen.cxx b/core/sqf/monitor/linux/reqopen.cxx
index f131a08..f44b8d4 100644
--- a/core/sqf/monitor/linux/reqopen.cxx
+++ b/core/sqf/monitor/linux/reqopen.cxx
@@ -229,8 +229,8 @@
return false;
}
- CProcess * openerProcess;
- CProcess * openedProcess;
+ CProcess * openerProcess = NULL;
+ CProcess * openedProcess = NULL;
// Get process object for opener process
if ( msg_->u.request.u.open.process_name[0] )
@@ -263,9 +263,12 @@
// Get process object for process to open
if ( msg_->u.request.u.open.target_process_name[0] )
{ // find by name (check node state, don't check process state, backup is NOT Ok)
- openedProcess = Nodes->GetProcess( msg_->u.request.u.open.target_process_name
- , msg_->u.request.u.open.target_verifier
- , true, false, false );
+ if (msg_->u.request.u.open.target_process_name[0] == '$' )
+ {
+ openedProcess = Nodes->GetProcess( msg_->u.request.u.open.target_process_name
+ , msg_->u.request.u.open.target_verifier
+ , true, false, false );
+ }
}
else
{ // find by pid (check node state, don't check process state, backup is Ok)
@@ -291,8 +294,11 @@
, method_name, __LINE__
, target_process_name.c_str()
, target_verifier );
- openedProcess = Nodes->CloneProcessNs( target_process_name.c_str()
- , target_verifier );
+ if (msg_->u.request.u.open.target_process_name[0] == '$' )
+ {
+ openedProcess = Nodes->CloneProcessNs( target_process_name.c_str()
+ , target_verifier );
+ }
}
else
{ // Name Server find by nid,pid:verifier
diff --git a/core/sqf/monitor/linux/reqprocinfo.cxx b/core/sqf/monitor/linux/reqprocinfo.cxx
index d3f04e2..c49a877 100644
--- a/core/sqf/monitor/linux/reqprocinfo.cxx
+++ b/core/sqf/monitor/linux/reqprocinfo.cxx
@@ -417,9 +417,6 @@
requester =
Nodes->GetProcess( nid_ , pid_ , verifier_
, false, false, true );
-// CLNode *lnode = Nodes->GetLNode( nid_ );
-// CNode *node = lnode->GetNode();
-// requester = node->GetProcess( pid_, verifier_ );
#else
requester = MyNode->GetProcess( pid_
, verifier_ );
@@ -483,12 +480,16 @@
, false, false
, target_verifier == -1 ? false : true );
#else
+ CProcess *process = NULL;
// find by name (check node state, don't check process state,
// if verifier is -1, backup is NOT Ok, else is Ok)
- CProcess *process = Nodes->GetProcess( target_process_name.c_str()
- , target_verifier
- , true, false
- , target_verifier == -1 ? false : true );
+ if (msg_->u.request.u.process_info.target_process_name[0] == '$' )
+ {
+ process = Nodes->GetProcess( target_process_name.c_str()
+ , target_verifier
+ , true, false
+ , target_verifier == -1 ? false : true );
+ }
#endif
if (process)
{
diff --git a/core/sqf/monitor/linux/reqqueue.cxx b/core/sqf/monitor/linux/reqqueue.cxx
index 2238d71..3d425f2 100644
--- a/core/sqf/monitor/linux/reqqueue.cxx
+++ b/core/sqf/monitor/linux/reqqueue.cxx
@@ -64,6 +64,7 @@
extern CRedirector Redirector;
extern bool NameServerEnabled;
extern CPtpClient *PtpClient;
+extern CProcess *NameServerProcess;
extern CNameServer *NameServer;
extern CNameServerConfigContainer *NameServerConfig;
#endif
@@ -1578,15 +1579,18 @@
{
if (NameServerEnabled)
{
- if (trace_settings & TRACE_REQUEST)
- trace_printf( "%s@%d" " - Getting parent process from Name Server (%d,%d:%d)\n"
- , method_name, __LINE__
- , parentNid_
- , parentPid_
- , parentVerifier_ );
- parentProcess = Nodes->CloneProcessNs( parentNid_
- , parentPid_
- , parentVerifier_ );
+ if (parentNid_ != -1 && parentPid_ != -1)
+ {
+ if (trace_settings & TRACE_REQUEST)
+ trace_printf( "%s@%d" " - Getting parent process from Name Server (%d,%d:%d)\n"
+ , method_name, __LINE__
+ , parentNid_
+ , parentPid_
+ , parentVerifier_ );
+ parentProcess = Nodes->CloneProcessNs( parentNid_
+ , parentPid_
+ , parentVerifier_ );
+ }
}
}
}
@@ -2598,7 +2602,7 @@
, process_->GetVerifier() );
}
#ifndef NAMESERVER_PROCESS
- if ( NameServerEnabled )
+ if ( NameServerEnabled && process_ != NameServerProcess)
{
int rc = NameServer->ProcessDelete(process_); // in reqQueue thread (CIntChildDeathReq)
if (rc)
@@ -2713,9 +2717,11 @@
else
{
// Stop all processes
- Monitor->HardNodeDown( MyPNID );
#ifndef NAMESERVER_PROCESS
+ Monitor->HardNodeDown( MyPNID );
MyNode->EmptyQuiescingPids();
+#else
+ Monitor->HardNodeDownNs( MyPNID );
#endif
// now stop the Watchdog process
HealthCheck.setState(MON_NODE_DOWN);
@@ -3261,7 +3267,11 @@
if (trace_settings & (TRACE_SYNC | TRACE_REQUEST))
trace_printf("%s@%d - Node down request, pnid=%d\n",
method_name, __LINE__, pnid_);
+#ifndef NAMESERVER_PROCESS
Monitor->HardNodeDown( pnid_ );
+#else
+ Monitor->HardNodeDownNs( pnid_ );
+#endif
TRACE_EXIT;
}
@@ -4063,7 +4073,11 @@
else
{
// Stop all processes
+#ifndef NAMESERVER_PROCESS
Monitor->HardNodeDown( MyPNID );
+#else
+ Monitor->HardNodeDownNs( MyPNID );
+#endif
#ifndef NAMESERVER_PROCESS
MyNode->EmptyQuiescingPids();
#endif
@@ -4241,6 +4255,11 @@
request->setConcurrent(reqConcurrent[msg->u.request.type]);
break;
+ case ReqType_NodeDown:
+ request = new CExtNodeDownNsReq(msgType, pid, sockFd, msg);
+ request->setConcurrent(reqConcurrent[msg->u.request.type]);
+ break;
+
case ReqType_NewProcessNs:
request = new CExtNewProcNsReq(msgType, nid, pid, sockFd, msg);
request->setConcurrent(reqConcurrent[msg->u.request.type]);
@@ -5376,7 +5395,7 @@
}
}
- if (!request->isShutdown())
+ if (request && !request->isShutdown())
{
// Take request out of list
reqQueue_.erase (it);
diff --git a/core/sqf/monitor/linux/reqqueue.h b/core/sqf/monitor/linux/reqqueue.h
index 2f6f030..b600a0f 100644
--- a/core/sqf/monitor/linux/reqqueue.h
+++ b/core/sqf/monitor/linux/reqqueue.h
@@ -456,6 +456,23 @@
};
#endif
+#ifdef NAMESERVER_PROCESS
+class CExtNodeDownNsReq: public CExternalReq
+{
+public:
+ CExtNodeDownNsReq( reqQueueMsg_t msgType
+ , int pid
+ , int sockFd
+ , struct message_def *msg );
+ virtual ~CExtNodeDownNsReq();
+
+ void performRequest();
+
+private:
+ void populateRequestString( void );
+};
+#endif
+
#ifndef NAMESERVER_PROCESS
class CExtNameServerAddReq: public CExternalReq
{
@@ -1801,6 +1818,7 @@
RQEI CExtNewProcReq
RqEB CExtNewProcessNsReq
RQEJ CExtNodeDownReq
+ RqEJ CExtNodeDownNsReq
RQEK CExtNodeInfoReq
RQEK CExtPNodeInfoReq
RQEL CExtNodeUpReq
@@ -1816,6 +1834,7 @@
RQEP CExtProcInfoContReq
RQEQ CExtSetReq
RQER CExtShutdownReq
+ RqER CExtShutdownNsReq
RQES CExtStartupReq
RQET CExtTmLeaderReq
RQEV CExtTmSyncReq
diff --git a/core/sqf/monitor/linux/shell.cxx b/core/sqf/monitor/linux/shell.cxx
index 6c5f14b..0da8c32 100644
--- a/core/sqf/monitor/linux/shell.cxx
+++ b/core/sqf/monitor/linux/shell.cxx
@@ -80,7 +80,7 @@
char LDpath[MAX_SEARCH_PATH];
char Path[MAX_SEARCH_PATH];
char Wdir[MAX_SEARCH_PATH];
-char prompt[13];
+char prompt[MAX_PROCESS_NAME];
int VirtualNodes = 0;
int VirtualNid = -1;
int NumNodes = 0;
@@ -394,51 +394,41 @@
{
bool rs = true;
bool isNameServerEnabled = false;
+ bool isAgentModeEnabled = false;
char* env;
char msgString[MAX_BUFFER] = { 0 };
int val = 0;
- env = getenv("MONITOR_COMM_PORT");
- if ( env )
+ env = getenv("SQ_MON_RUN_MODE");
+ if ( env && (strcmp(env, "AGENT") == 0) )
{
- val = atoi(env);
- if ( val <= 0)
+ isAgentModeEnabled = true;
+ }
+
+ if (isAgentModeEnabled)
+ {
+ env = getenv("MONITOR_COMM_PORT");
+ if ( env )
{
- if (VirtualNodes)
+ val = atoi(env);
+ if ( val <= 0)
{
sprintf( msgString, "[%s] Warning: MONITOR_COMM_PORT value is invalid (%s)!", MyName, env );
write_startup_log( msgString );
printf("%s\n", msgString );
}
- else
- {
- sprintf( msgString, "[%s] Error: MONITOR_COMM_PORT value is invalid (%s)! Set MONITOR_COMM_PORT environment variable and try again.", MyName, env );
- write_startup_log( msgString );
- printf("%s\n", msgString );
- rs = false;
- }
}
- }
-
- env = getenv("MONITOR_SYNC_PORT");
- if ( env )
- {
- val = atoi(env);
- if ( val <= 0)
+
+ env = getenv("MONITOR_SYNC_PORT");
+ if ( env )
{
- if (VirtualNodes)
+ val = atoi(env);
+ if ( val <= 0)
{
sprintf( msgString, "[%s] Warning: MONITOR_SYNC_PORT value is invalid (%s)!", MyName, env );
write_startup_log( msgString );
printf("%s\n", msgString );
}
- else
- {
- sprintf( msgString, "[%s] Error: MONITOR_SYNC_PORT value is invalid (%s)! Set MONITOR_COMM_PORT environment variable and try again.", MyName, env );
- write_startup_log( msgString );
- printf("%s\n", msgString );
- rs = false;
- }
}
}
@@ -446,10 +436,7 @@
if ( env )
{
val = atoi(env);
- if ( val > 0)
- {
- isNameServerEnabled = (val != 0);
- }
+ isNameServerEnabled = (val != 0) ? true : false;
}
if (isNameServerEnabled)
@@ -2391,8 +2378,8 @@
{
if (displayHeader)
{
- printf("[%s] NID,PID(os) PRI TYPE STATES NAME PARENT PROGRAM\n",MyName);
- printf("[%s] ------------ --- ---- ------- ----------- ----------- ---------------\n",MyName);
+ printf("[%s] NID,PID(os) PRI TYPE STATES NAME PARENT PROGRAM\n",MyName);
+ printf("[%s] ------------ --- ---- ------- ------------ ------------ ---------------\n",MyName);
}
show_proc_info();
@@ -5257,7 +5244,7 @@
msg->u.reply.u.process_info.process[i].type
= ProcessType_Undefined;
}
- printf("%3.3d %-4s %c%c%c%c%c%c%c %-11s %-11s %-15s\n",
+ printf("%3.3d %-4s %c%c%c%c%c%c%c %-12s %-12s %-15s\n",
msg->u.reply.u.process_info.process[i].priority,
processTypeStr[msg->u.reply.u.process_info.process[i].type],
(msg->u.reply.u.process_info.process[i].event_messages?'E':'-'),
@@ -9572,14 +9559,8 @@
env = getenv("SQ_NAMESERVER_ENABLED");
if ( env && isdigit(*env) )
{
- if ( strcmp(env,"0") == 0 )
- {
- NameServerEnabled = false;
- }
- else
- {
- NameServerEnabled = true;
- }
+ int val = atoi(env);
+ NameServerEnabled = (val != 0) ? true : false;
}
if ( !VirtualNodes )
diff --git a/core/sqf/monitor/linux/tmsync.cxx b/core/sqf/monitor/linux/tmsync.cxx
index 548ae81..b56c5f8 100644
--- a/core/sqf/monitor/linux/tmsync.cxx
+++ b/core/sqf/monitor/linux/tmsync.cxx
@@ -1012,7 +1012,8 @@
}
if (NameServerEnabled)
{
- if (!MyNode->IsMyNode( tm->GetNid() ))
+ if (!MyNode->IsMyNode( tm->GetNid() )
+ && (req->GetNext() && req->GetNext()->Nid != tm->GetNid() ) )
{
if (trace_settings & (TRACE_INIT | TRACE_RECOVERY | TRACE_REQUEST | TRACE_SYNC | TRACE_TMSYNC))
{
@@ -1024,6 +1025,7 @@
, tm->GetVerifier() );
}
Nodes->DeleteCloneProcess( tm );
+ tm = NULL;
}
}
diff --git a/core/sqf/monitor/linux/zclient.cxx b/core/sqf/monitor/linux/zclient.cxx
index f9bd698..19a7679 100644
--- a/core/sqf/monitor/linux/zclient.cxx
+++ b/core/sqf/monitor/linux/zclient.cxx
@@ -506,7 +506,7 @@
string masterMonitor( ss.str( ) );
// wait for 3 minutes for giving up.
- while ( (!found) && (retries < 180))
+ while ( (GetState() != ZC_SHUTDOWN) && (!found) && (retries < 180))
{
if (trace_settings & (TRACE_INIT | TRACE_RECOVERY))
{
diff --git a/core/sqf/sqenvcom.sh b/core/sqf/sqenvcom.sh
index cd2ea37..0bac47c 100644
--- a/core/sqf/sqenvcom.sh
+++ b/core/sqf/sqenvcom.sh
@@ -681,11 +681,14 @@
# (meaning that mpirun is the parent process of the monitor process)
# AGENT - monitor process runs in agent mode versus MPI collective
#
-# Uncomment the next four environment variables
-#export SQ_MON_CREATOR=MPIRUN
-#export SQ_MON_RUN_MODE=AGENT
-#export MONITOR_COMM_PORT=23390
-#export MONITOR_SYNC_PORT=23380
+# Uncomment the next environment variable
+export SQ_MON_CREATOR=MPIRUN
+if [[ "$SQ_MON_CREATOR" == "MPIRUN" ]]; then
+ export SQ_MON_RUN_MODE=${SQ_MON_RUN_MODE:-AGENT}
+ export MONITOR_COMM_PORT=${MONITOR_COMM_PORT:-23390}
+ export MONITOR_SYNC_PORT=${MONITOR_SYNC_PORT:-23380}
+ export TRAF_SCALING_FACTOR=${TRAF_SCALING_FACTOR:-0.75}
+fi
#
# NAME-SERVER - to disable process replication and enable the name-server
@@ -743,6 +746,11 @@
# set to 0 to disable phandle verifier
export SQ_PHANDLE_VERIFIER=1
+# set to 0 to disable process name long format in clusters larger that 256 nodes
+#export SQ_MON_PROCESS_NAME_FORMAT_LONG=0
+# short format: '$Zxxpppp' xx = nid, pppp = pid
+# long format: '$Zxxxxpppppp' xxxx = nid, pppppp = pid (default)
+
# set to 0 to disable or 1 to enable configuration of DTM as a persistent process
# must re-execute 'sqgen' to effect change
export SQ_DTM_PERSISTENT_PROCESS=1
diff --git a/core/sqf/sql/scripts/gomon.cold b/core/sqf/sql/scripts/gomon.cold
index 6055490..f963e29 100755
--- a/core/sqf/sql/scripts/gomon.cold
+++ b/core/sqf/sql/scripts/gomon.cold
@@ -90,15 +90,24 @@
echo `date`" - Continuing with Startup ..."
echo
fi
+fi
+
+if (
+ [[ $TRAF_AGENT == "CM" ]] ||
+ [[ $SQ_MON_RUN_MODE == "AGENT" ]]
+ )
+then
+ export TRAF_SCALING_FACTOR=${TRAF_SCALING_FACTOR:-0.75}
# Set the number of nodes configured
let node_count=`trafconf -nid-count`
+ #echo "***"
#echo "*** node_count = ${node_count}"
- #echo "*** TRAF_SCALING_FACTOR = $TRAF_SCALING_FACTOR"
+ #echo "*** TRAF_SCALING_FACTOR = ${TRAF_SCALING_FACTOR}"
# allow time for other nodes to integrate, scaled to cluster size
# scaling factor may be non-integer, so use awk to evaluate
- start_delay=$( echo "${node_count} $TRAF_SCALING_FACTOR" | awk '{print $1 * $2}')
+ start_delay=$( echo "${node_count} ${TRAF_SCALING_FACTOR}" | awk '{print $1 * $2}')
echo "***"
echo "***" %`date`" - Waiting ${start_delay} seconds for Monitor processes to integrate"
echo "***"
diff --git a/core/sql/cli/sqlcli.h b/core/sql/cli/sqlcli.h
index 2bfbfcb..00ae7b2 100644
--- a/core/sql/cli/sqlcli.h
+++ b/core/sql/cli/sqlcli.h
@@ -1028,9 +1028,10 @@
SQLSTATS_DESC_REPLICATOR_STATS = 20,
SQLSTATS_DESC_FAST_EXTRACT_STATS = 21,
SQLSTATS_DESC_REORG_STATS = 22,
+ SQLSTATS_DESC_SE_STATS = 23,
SQLSTATS_DESC_HDFSSCAN_STATS = 23,
- SQLSTATS_DESC_HBASE_ACCESS_STATS = 24,
- SQLSTATS_DESC_PROCESS_STATS = 25
+ SQLSTATS_DESC_HBASE_ACCESS_STATS = 23,
+ SQLSTATS_DESC_PROCESS_STATS = 25,
};
diff --git a/core/sql/executor/ExExeUtil.h b/core/sql/executor/ExExeUtil.h
index 49261a6..435dfb5 100644
--- a/core/sql/executor/ExExeUtil.h
+++ b/core/sql/executor/ExExeUtil.h
@@ -2128,6 +2128,7 @@
GET_PROCESS_STATS_ENTRY_,
FORMAT_AND_RETURN_PROCESS_STATS_,
GET_HBASE_STATS_ENTRY_,
+ GET_SE_STATS_ENTRY_ = GET_HBASE_STATS_ENTRY_,
DISPLAY_HBASE_STATS_HEADING_,
FORMAT_AND_RETURN_HBASE_STATS_,
GET_HIVE_STATS_ENTRY_,
@@ -2812,6 +2813,8 @@
virtual short work();
virtual ~ExExeUtilLobExtractTcb();
virtual void freeResources();
+ virtual ExOperStats *doAllocateStatsEntry(CollHeap *heap,
+ ComTdb *tdb);
ExExeUtilLobExtractTdb & lobTdb() const
{
@@ -2921,6 +2924,8 @@
virtual short work();
virtual ~ExExeUtilLobUpdateTcb();
virtual void freeResources();
+ virtual ExOperStats *doAllocateStatsEntry(CollHeap *heap,
+ ComTdb *tdb);
ExExeUtilLobUpdateTdb & lobTdb() const
{
return (ExExeUtilLobUpdateTdb &) tdb;
@@ -2997,6 +3002,8 @@
const ex_tcb * child_tcb,
ex_globals * glob = 0);
+ virtual ExOperStats *doAllocateStatsEntry(CollHeap *heap,
+ ComTdb *tdb);
virtual short work();
private:
diff --git a/core/sql/executor/ExExeUtilGetStats.cpp b/core/sql/executor/ExExeUtilGetStats.cpp
index a8a128d..ead8cfd 100644
--- a/core/sql/executor/ExExeUtilGetStats.cpp
+++ b/core/sql/executor/ExExeUtilGetStats.cpp
@@ -1920,12 +1920,9 @@
case SQLSTATS_DESC_UDR_BASE_STATS:
step_ = GET_UDR_BASE_STATS_ENTRY_;
break;
- case SQLSTATS_DESC_HBASE_ACCESS_STATS:
+ case SQLSTATS_DESC_SE_STATS:
step_ = GET_HBASE_STATS_ENTRY_;
break;
- case SQLSTATS_DESC_HDFSSCAN_STATS:
- step_ = GET_HIVE_STATS_ENTRY_;
- break;
default:
step_ = GET_NEXT_STATS_DESC_ENTRY_;
break;
diff --git a/core/sql/executor/ExExeUtilLoad.cpp b/core/sql/executor/ExExeUtilLoad.cpp
index 960c31f..7c051c4 100644
--- a/core/sql/executor/ExExeUtilLoad.cpp
+++ b/core/sql/executor/ExExeUtilLoad.cpp
@@ -2563,6 +2563,7 @@
if (lobHandle_ and lobName_)
retcode = ExpLOBInterfaceSelectCursor
(lobGlobs,
+ (getStatsEntry() != NULL ? getStatsEntry()->castToExHdfsScanStats() : NULL),
lobName_,
lobLoc_,
lobType_,
@@ -2590,6 +2591,23 @@
freeResources();
}
+ExOperStats * ExExeUtilLobExtractTcb::doAllocateStatsEntry(CollHeap *heap,
+ ComTdb *tdb)
+{
+ ExEspStmtGlobals *espGlobals = getGlobals()->castToExExeStmtGlobals()->castToExEspStmtGlobals();
+ StmtStats *ss;
+ if (espGlobals != NULL)
+ ss = espGlobals->getStmtStats();
+ else
+ ss = getGlobals()->castToExExeStmtGlobals()->castToExMasterStmtGlobals()->getStatement()->getStmtStats();
+ ExHdfsScanStats *hdfsScanStats = new(heap) ExHdfsScanStats(heap,
+ this,
+ tdb);
+ if (ss != NULL)
+ hdfsScanStats->setQueryId(ss->getQueryId(), ss->getQueryIdLen());
+ return hdfsScanStats;
+}
+
short ExExeUtilLobExtractTcb::work()
{
Lng32 cliRC = 0;
@@ -3023,6 +3041,7 @@
if(lobTdb().appendOrCreate())
tgtFlags = Lob_Append_Or_Create;
retcode = ExpLOBInterfaceSelect(lobGlobs,
+ (getStatsEntry() != NULL ? getStatsEntry()->castToExHdfsScanStats() : NULL),
lobName_,
lobLoc_,
lobType_,
@@ -3067,6 +3086,7 @@
{
retcode = ExpLOBInterfaceSelectCursor
(lobGlobs,
+ (getStatsEntry() != NULL ? getStatsEntry()->castToExHdfsScanStats() : NULL),
lobName_,
lobLoc_,
lobType_,
@@ -3117,6 +3137,7 @@
retcode = ExpLOBInterfaceSelectCursor
(lobGlobs,
+ (getStatsEntry() != NULL ? getStatsEntry()->castToExHdfsScanStats() : NULL),
lobName_,
lobLoc_,
lobType_,
@@ -3186,6 +3207,7 @@
{
retcode = ExpLOBInterfaceSelectCursor
(lobGlobs,
+ (getStatsEntry() != NULL ? getStatsEntry()->castToExHdfsScanStats() : NULL),
lobName_,
lobLoc_,
lobType_,
@@ -3334,6 +3356,23 @@
exLobGlobals_ = NULL;
}
+ExOperStats * ExExeUtilLobUpdateTcb::doAllocateStatsEntry(CollHeap *heap,
+ ComTdb *tdb)
+{
+ ExEspStmtGlobals *espGlobals = getGlobals()->castToExExeStmtGlobals()->castToExEspStmtGlobals();
+ StmtStats *ss;
+ if (espGlobals != NULL)
+ ss = espGlobals->getStmtStats();
+ else
+ ss = getGlobals()->castToExExeStmtGlobals()->castToExMasterStmtGlobals()->getStatement()->getStmtStats();
+ ExHdfsScanStats *hdfsScanStats = new(heap) ExHdfsScanStats(heap,
+ this,
+ tdb);
+ if (ss != NULL)
+ hdfsScanStats->setQueryId(ss->getQueryId(), ss->getQueryIdLen());
+ return hdfsScanStats;
+}
+
short ExExeUtilLobUpdateTcb::work()
{
Lng32 cliRC = 0;
@@ -3467,6 +3506,7 @@
}
}
retcode = ExpLOBInterfaceUpdate(lobGlobs,
+ (getStatsEntry() != NULL ? getStatsEntry()->castToExHdfsScanStats() : NULL),
lobTdb().getLobHdfsServer(),
lobTdb().getLobHdfsPort(),
lobName_,
@@ -3550,6 +3590,7 @@
Int32 outHandleLen;
Int64 requestTag = 0;
retcode = ExpLOBInterfaceUpdateAppend(lobGlobs,
+ (getStatsEntry() != NULL ? getStatsEntry()->castToExHdfsScanStats() : NULL),
lobTdb().getLobHdfsServer(),
lobTdb().getLobHdfsPort(),
lobName_,
@@ -3635,6 +3676,7 @@
Int64 requestTag = 0;
retcode = ExpLOBInterfaceUpdate(lobGlobs,
+ (getStatsEntry() != NULL ? getStatsEntry()->castToExHdfsScanStats() : NULL),
lobTdb().getLobHdfsServer(),
lobTdb().getLobHdfsPort(),
lobName_,
@@ -3735,8 +3777,7 @@
return FALSE;
}
-ExOperStats * ExExeUtilFileExtractTcb::doAllocateStatsEntry(
- CollHeap *heap,
+ExOperStats * ExExeUtilFileExtractTcb::doAllocateStatsEntry(CollHeap *heap,
ComTdb *tdb)
{
ExEspStmtGlobals *espGlobals = getGlobals()->castToExExeStmtGlobals()->castToExEspStmtGlobals();
@@ -3745,7 +3786,6 @@
ss = espGlobals->getStmtStats();
else
ss = getGlobals()->castToExExeStmtGlobals()->castToExMasterStmtGlobals()->getStatement()->getStmtStats();
-
ExHdfsScanStats *hdfsScanStats = new(heap) ExHdfsScanStats(heap,
this,
tdb);
@@ -3811,6 +3851,7 @@
retcode = ExpLOBInterfaceSelectCursor
(lobGlobs,
+ (getStatsEntry() != NULL ? getStatsEntry()->castToExHdfsScanStats() : NULL),
lobName_,
lobLoc_,
lobType_,
@@ -3857,6 +3898,7 @@
retcode = ExpLOBInterfaceSelectCursor
(lobGlobs,
+ (getStatsEntry() != NULL ? getStatsEntry()->castToExHdfsScanStats() : NULL),
lobName_,
lobLoc_,
lobType_,
@@ -3914,6 +3956,7 @@
{
retcode = ExpLOBInterfaceSelectCursor
(lobGlobs,
+ (getStatsEntry() != NULL ? getStatsEntry()->castToExHdfsScanStats() : NULL),
lobName_,
lobLoc_,
lobType_,
@@ -3943,7 +3986,7 @@
break;
}
- step_ = COLLECT_STATS_;
+ step_ = DONE_;
}
break;
@@ -3957,30 +4000,6 @@
}
break;
- case COLLECT_STATS_:
- {
- if (! getStatsEntry())
- {
- step_ = DONE_;
- break;
- }
-
- ExHdfsScanStats * stats =
- getStatsEntry()->castToExHdfsScanStats();
-
- retcode = ExpLOBinterfaceStats
- (lobGlobs,
- stats->lobStats(),
- lobName_,
- lobLoc_,
- lobType_,
- lobTdb().getLobHdfsServer(),
- lobTdb().getLobHdfsPort());
-
- step_ = DONE_;
- }
- break;
-
case DONE_:
{
retcode = handleDone();
@@ -4006,6 +4025,23 @@
{
}
+ExOperStats * ExExeUtilFileLoadTcb::doAllocateStatsEntry(CollHeap *heap,
+ ComTdb *tdb)
+{
+ ExEspStmtGlobals *espGlobals = getGlobals()->castToExExeStmtGlobals()->castToExEspStmtGlobals();
+ StmtStats *ss;
+ if (espGlobals != NULL)
+ ss = espGlobals->getStmtStats();
+ else
+ ss = getGlobals()->castToExExeStmtGlobals()->castToExMasterStmtGlobals()->getStatement()->getStmtStats();
+ ExHdfsScanStats *hdfsScanStats = new(heap) ExHdfsScanStats(heap,
+ this,
+ tdb);
+ if (ss != NULL)
+ hdfsScanStats->setQueryId(ss->getQueryId(), ss->getQueryIdLen());
+ return hdfsScanStats;
+}
+
short ExExeUtilFileLoadTcb::work()
{
Lng32 cliRC = 0;
@@ -4162,6 +4198,7 @@
Int64 dummy;
retcode = ExpLOBInterfaceInsert
(lobGlobs,
+ (getStatsEntry() != NULL ? getStatsEntry()->castToExHdfsScanStats() : NULL),
lobName_,
lobLoc_,
lobType_,
@@ -4204,6 +4241,7 @@
{
retcode = ExpLOBinterfaceCloseFile
(lobGlobs,
+ (getStatsEntry() != NULL ? getStatsEntry()->castToExHdfsScanStats() : NULL),
lobName_,
lobLoc_,
lobType_,
diff --git a/core/sql/executor/ExFastTransport.cpp b/core/sql/executor/ExFastTransport.cpp
index 7849746..a2eaa94 100644
--- a/core/sql/executor/ExFastTransport.cpp
+++ b/core/sql/executor/ExFastTransport.cpp
@@ -422,7 +422,16 @@
if (statsType == ComTdb::OPERATOR_STATS)
{
- return ex_tcb::doAllocateStatsEntry(heap, tdb);;
+ ExEspStmtGlobals *espGlobals = getGlobals()->castToExExeStmtGlobals()->castToExEspStmtGlobals();
+ StmtStats *ss;
+ if (espGlobals != NULL)
+ ss = espGlobals->getStmtStats();
+ else
+ ss = getGlobals()->castToExExeStmtGlobals()->castToExMasterStmtGlobals()->getStatement()->getStmtStats();
+ ExHdfsScanStats *hdfsScanStats = new (heap) ExHdfsScanStats(heap, this, tdb);
+ if (ss != NULL)
+ hdfsScanStats->setQueryId(ss->getQueryId(), ss->getQueryIdLen());
+ return hdfsScanStats;
}
else
{
@@ -622,6 +631,7 @@
ExOperStats *stats = NULL;
ExFastExtractStats *feStats = getFastExtractStats();
+ ExHdfsScanStats *hdfsStats = getHdfsScanStats();
while (TRUE)
{
@@ -790,7 +800,7 @@
}
else if (!isSequenceFile() && hdfsClient_ == NULL)
{
- hdfsClient_ = HdfsClient::newInstance((NAHeap *)getHeap(), NULL, hdfsClientRetCode);
+ hdfsClient_ = HdfsClient::newInstance((NAHeap *)getHeap(), (ExHdfsScanStats *)getHdfsScanStats(), hdfsClientRetCode);
if (hdfsClientRetCode != HDFS_CLIENT_OK)
{
createHdfsClientFileError(hdfsClientRetCode);
@@ -978,6 +988,10 @@
{
feStats->incProcessedRowsCount();
}
+ if (hdfsStats != NULL) {
+ hdfsStats->incUsedRows();
+ hdfsStats->incAccessedRows();
+ }
pstate.successRowCount_ ++;
}
else
@@ -986,6 +1000,8 @@
{
feStats->incErrorRowsCount();
}
+ if (hdfsStats != NULL)
+ hdfsStats->incAccessedRows();
pstate.errorRowCount_ ++;
}
if (currBuffer_->bytesLeft_ < (Int32) maxExtractRowLength_)
@@ -1243,7 +1259,6 @@
g->setRowsAffected(privateState.matchCount_);
}
-
//
// Insert into up queue
qParent_.up->insert();
diff --git a/core/sql/executor/ExFastTransport.h b/core/sql/executor/ExFastTransport.h
index 5bf1219..37d7875 100644
--- a/core/sql/executor/ExFastTransport.h
+++ b/core/sql/executor/ExFastTransport.h
@@ -327,6 +327,14 @@
return NULL;
}
+ ExHdfsScanStats * getHdfsScanStats()
+ {
+ if (getStatsEntry())
+ return getStatsEntry()->castToExHdfsScanStats();
+ else
+ return NULL;
+ }
+
protected:
@@ -359,6 +367,7 @@
NABoolean endOfData_;
CollHeap *heap_;
ExFastExtractStats *feStats_;
+ ExHdfsScanStats *hdfsStats_;
time_t tstart_;
diff --git a/core/sql/executor/ExHbaseAccess.h b/core/sql/executor/ExHbaseAccess.h
index 7be1551..071b8c0 100644
--- a/core/sql/executor/ExHbaseAccess.h
+++ b/core/sql/executor/ExHbaseAccess.h
@@ -47,7 +47,6 @@
// Classes referenced in this file
// -----------------------------------------------------------------------
class ex_tcb;
-class ExHbaseAccessStats;
class ExpHbaseInterface;
class ExHbaseAccessSelectTcb;
class ExHbaseAccessUMDTcb;
diff --git a/core/sql/executor/ExHbaseIUD.cpp b/core/sql/executor/ExHbaseIUD.cpp
index 6a52457..bad439d 100644
--- a/core/sql/executor/ExHbaseIUD.cpp
+++ b/core/sql/executor/ExHbaseIUD.cpp
@@ -34,6 +34,7 @@
#include "ExHdfsScan.h"
#include "Context.h"
#include "HdfsClient_JNI.h"
+#include "ExStats.h"
ExHbaseAccessInsertTcb::ExHbaseAccessInsertTcb(
const ExHbaseAccessTdb &hbaseAccessTdb,
@@ -1012,8 +1013,7 @@
break;
}
if (getHbaseAccessStats()) {
- getHbaseAccessStats()->lobStats()->numReadReqs++;
- getHbaseAccessStats()->incUsedRows(numRowsInVsbbBuffer_);
+ getHbaseAccessStats()->incUsedRows((Int64)numRowsInVsbbBuffer_);
}
rowsInserted_ += numRowsInVsbbBuffer_;
if (asyncOperation_) {
@@ -1611,7 +1611,6 @@
if (getHbaseAccessStats())
{
- getHbaseAccessStats()->lobStats()->numReadReqs++;
getHbaseAccessStats()->incUsedRows(numRowsInVsbbBuffer_);
}
@@ -4247,7 +4246,6 @@
break;
}
if (getHbaseAccessStats()) {
- getHbaseAccessStats()->lobStats()->numReadReqs++;
getHbaseAccessStats()->incUsedRows(numRowsInVsbbBuffer_);
}
step_ = RS_CLOSE;
@@ -4271,10 +4269,6 @@
}
step_ = NEXT_ROW;
- if (getHbaseAccessStats())
- {
- getHbaseAccessStats()->lobStats()->numReadReqs++;
- }
}
else
step_ = SETUP_SELECT;
@@ -4345,7 +4339,6 @@
break;
}
if (getHbaseAccessStats()) {
- getHbaseAccessStats()->lobStats()->numReadReqs++;
getHbaseAccessStats()->incUsedRows(numRowsInVsbbBuffer_);
}
step_ = RS_CLOSE;
@@ -4385,7 +4378,6 @@
if (step_ == HANDLE_ERROR)
break;
if (getHbaseAccessStats()) {
- getHbaseAccessStats()->lobStats()->numReadReqs++;
getHbaseAccessStats()->incUsedRows(numRowsInVsbbBuffer_);
}
step_ = RS_CLOSE;
diff --git a/core/sql/executor/ExHdfsScan.cpp b/core/sql/executor/ExHdfsScan.cpp
index 4db5a1d..b09cffd 100644
--- a/core/sql/executor/ExHdfsScan.cpp
+++ b/core/sql/executor/ExHdfsScan.cpp
@@ -771,6 +771,7 @@
openType = 2; // must open
retcode = ExpLOBInterfaceSelectCursor
(lobGlob_,
+ (getStatsEntry() != NULL ? getStatsEntry()->castToExHdfsScanStats() : NULL),
hdfsFileName_, //hdfsScanTdb().hdfsFileName_,
NULL, //(char*)"",
(Lng32)Lob_External_HDFS_File,
@@ -830,6 +831,7 @@
retcode = ExpLOBInterfaceSelectCursor
(lobGlob_,
+ (getStatsEntry() != NULL ? getStatsEntry()->castToExHdfsScanStats() : NULL),
hdfsFileName_, //hdfsScanTdb().hdfsFileName_,
NULL, //(char*)"",
(Lng32)Lob_External_HDFS_File,
@@ -940,6 +942,7 @@
Int32 hdfsErrorDetail = 0;///this is the errno returned from the underlying hdfs call.
retcode = ExpLOBInterfaceSelectCursor
(lobGlob_,
+ (getStatsEntry() != NULL ? getStatsEntry()->castToExHdfsScanStats() : NULL),
hdfsFileName_,
NULL,
(Lng32)Lob_External_HDFS_File,
@@ -1511,6 +1514,7 @@
{
retcode = ExpLOBInterfaceSelectCursor
(lobGlob_,
+ (getStatsEntry() != NULL ? getStatsEntry()->castToExHdfsScanStats() : NULL),
hdfsFileName_,
NULL,
(Lng32)Lob_External_HDFS_File,
@@ -1640,29 +1644,6 @@
case CLOSE_FILE:
case ERROR_CLOSE_FILE:
{
- if (getStatsEntry())
- {
- ExHdfsScanStats * stats =
- getStatsEntry()->castToExHdfsScanStats();
-
- if (stats)
- {
- ExLobStats s;
- s.init();
-
- retcode = ExpLOBinterfaceStats
- (lobGlob_,
- &s,
- hdfsFileName_, //hdfsScanTdb().hdfsFileName_,
- NULL, //(char*)"",
- (Lng32)Lob_External_HDFS_File,
- hdfsScanTdb().hostName_,
- hdfsScanTdb().port_);
-
- *stats->lobStats() = *stats->lobStats() + s;
- }
- }
-
// if next file is not same as current file, then close the current file.
bool closeFile = true;
@@ -1679,6 +1660,7 @@
{
retcode = ExpLOBinterfaceCloseFile
(lobGlob_,
+ (getStatsEntry() != NULL ? getStatsEntry()->castToExHdfsScanStats() : NULL),
hdfsFileName_,
NULL,
(Lng32)Lob_External_HDFS_File,
diff --git a/core/sql/executor/ExHdfsScan.h b/core/sql/executor/ExHdfsScan.h
index 371b6b5..a9bd86e 100644
--- a/core/sql/executor/ExHdfsScan.h
+++ b/core/sql/executor/ExHdfsScan.h
@@ -50,7 +50,6 @@
// Classes referenced in this file
// -----------------------------------------------------------------------
class ex_tcb;
-class ExHdfsScanStats;
class SequenceFileReader;
class ExpORCinterface;
diff --git a/core/sql/executor/ExStats.cpp b/core/sql/executor/ExStats.cpp
index 663d2bf..d5aaf9f 100644
--- a/core/sql/executor/ExStats.cpp
+++ b/core/sql/executor/ExStats.cpp
@@ -62,6 +62,7 @@
#include "ComTdbExeUtil.h"
#include "ComTdbHdfsScan.h"
#include "ComTdbHbaseAccess.h"
+#include "ComTdbFastTransport.h"
#include "ex_exe_stmt_globals.h"
#include "exp_clause_derived.h"
#include "Int64.h"
@@ -1314,10 +1315,6 @@
case SQLSTATS_DOP:
sqlStats_item->int64_value = dop_;
break;
- case SQLSTATS_DETAIL:
- if (sqlStats_item->str_value != NULL)
- sqlStats_item->str_ret_len = 0;
- break;
default:
sqlStats_item->error_code = -EXE_STAT_NOT_FOUND;
break;
@@ -1761,11 +1758,8 @@
case BMO_STATS:
merge((ExBMOStats *)other);
break;
- case HBASE_ACCESS_STATS:
- merge((ExHbaseAccessStats *)other);
- break;
- case HDFSSCAN_STATS:
- merge((ExHdfsScanStats *)other);
+ case SE_STATS:
+ merge((ExStorageEngineStats *)other);
break;
default:
// do nothing - This type of stat has no merge data
@@ -1815,11 +1809,11 @@
case 1:
return "OperCpuTime";
case 2:
- return "CpuTime";
+ return "messageBytes";
case 3:
- return "waitTime";
+ return "messageCount";
case 4:
- return "Timestamp";
+ return "memoryAllocated";
}
return NULL;
}
@@ -1831,11 +1825,11 @@
case 1:
return ExOperStats::getNumVal(i);
case 2:
- return cpuTime_ + espCpuTime_;
+ return reqMsgBytes_ + replyMsgBytes_;
case 3:
- return ((ExFragRootOperStats *)this)->getAvgWaitTime();
+ return reqMsgCnt_ + replyMsgCnt_;
case 4:
- return timestamp_;
+ return heapAlloc_+espHeapAlloc_+spaceAlloc_+espSpaceAlloc_;
}
return 0;
}
@@ -1921,24 +1915,7 @@
{
char tmpBuf[100];
Int32 len;
- if (sqlStats_item->statsItem_id == SQLSTATS_DETAIL)
- {
- if (sqlStats_item->str_value != NULL)
- {
- sprintf(tmpBuf, "%ld",
- cpuTime_ + espCpuTime_);
- len = str_len(tmpBuf);
- if (len > sqlStats_item->str_max_len)
- sqlStats_item->error_code = EXE_ERROR_IN_STAT_ITEM;
- else
- str_cpy(sqlStats_item->str_value, tmpBuf, len);
- sqlStats_item->str_ret_len = len;
- }
- return 0;
- }
- ExOperStats::getStatsItem(sqlStats_item);
- if(sqlStats_item -> error_code == -EXE_STAT_NOT_FOUND)
- {
+ Lng32 retcode = 0;
sqlStats_item->error_code = 0;
switch (sqlStats_item->statsItem_id)
{
@@ -2020,12 +1997,25 @@
case SQLSTATS_SQL_MAX_WAIT_TIME:
sqlStats_item->int64_value = maxWaitTime_;
break;
+ case SQLSTATS_DETAIL:
+ if (sqlStats_item->str_value != NULL)
+ {
+ sprintf(tmpBuf, "%ld|%ld|%ld|%ld|",
+ cpuTime_ + espCpuTime_, getNumVal(2), getNumVal(3), getNumVal(4));
+ len = strlen(tmpBuf);
+
+ if (len > sqlStats_item->str_max_len)
+ sqlStats_item->error_code = EXE_ERROR_IN_STAT_ITEM;
+ else
+ str_cpy(sqlStats_item->str_value, tmpBuf, len);
+ sqlStats_item->str_ret_len = len;
+ }
+ break;
default:
- sqlStats_item->error_code = -EXE_STAT_NOT_FOUND;
- break;
+ retcode = ExOperStats::getStatsItem(sqlStats_item);
+ break;
}
- }
- return 0;
+ return retcode;
}
NABoolean ExFragRootOperStats::filterForCpuStats()
@@ -2045,10 +2035,10 @@
}
//////////////////////////////////////////////////////////////////
-// class ExHdfsScanStats
+// class ExStorageEngineStats
//////////////////////////////////////////////////////////////////
-ExHdfsScanStats::ExHdfsScanStats(NAMemory * heap,
+ExStorageEngineStats::ExStorageEngineStats(NAMemory * heap,
ex_tcb *tcb,
ComTdb * tdb)
: ExOperStats(heap,
@@ -2057,10 +2047,32 @@
tdb)
, timer_(CLOCK_MONOTONIC)
{
- ComTdbHdfsScan *hdfsTdb = (ComTdbHdfsScan *) tdb;
-
+ const char * name;
+ switch (tdb->getNodeType())
+ {
+ case ComTdb::ex_HBASE_ACCESS:
+ {
+ ComTdbHbaseAccess *hbaseTdb = (ComTdbHbaseAccess *) tdb;
+ name = hbaseTdb->getTableName();
+ break;
+ }
+ case ComTdb::ex_HDFS_SCAN:
+ {
+ ComTdbHdfsScan *hdfsTdb = (ComTdbHdfsScan *) tdb;
+ name = hdfsTdb->tableName();
+ break;
+ }
+ case ComTdb::ex_FAST_EXTRACT:
+ {
+ ComTdbFastExtract *feTdb = (ComTdbFastExtract *)tdb;
+ name = feTdb->getTargetName();
+ break;
+ }
+ default:
+ name = "";
+ }
+
// allocate memory and copy the ansi name into the stats entry
- const char * name = hdfsTdb->tableName();
Lng32 len = (Lng32)str_len(name);
tableName_ = (char *)heap_->allocateMemory(len + 1);
sprintf(tableName_, "%s", name);
@@ -2070,9 +2082,9 @@
init(FALSE);
}
-ExHdfsScanStats::ExHdfsScanStats(NAMemory * heap)
+ExStorageEngineStats::ExStorageEngineStats(NAMemory * heap)
: ExOperStats(heap,
- HDFSSCAN_STATS)
+ SE_STATS)
, tableName_(NULL)
, timer_(CLOCK_MONOTONIC)
{
@@ -2081,22 +2093,20 @@
init(FALSE);
}
-void ExHdfsScanStats::init(NABoolean resetDop)
+void ExStorageEngineStats::init(NABoolean resetDop)
{
ExOperStats::init(resetDop);
timer_.reset();
- lobStats_.init();
-
numBytesRead_ = 0;
accessedRows_ = 0;
usedRows_ = 0;
- numHdfsCalls_ = 0;
- maxHdfsIOTime_ = 0;
+ numIOCalls_ = 0;
+ maxIOTime_ = 0;
blockTime_ = 0;
}
-ExHdfsScanStats::~ExHdfsScanStats()
+ExStorageEngineStats::~ExStorageEngineStats()
{
if (tableName_ != NULL)
{
@@ -2110,19 +2120,18 @@
}
}
-UInt32 ExHdfsScanStats::packedLength()
+UInt32 ExStorageEngineStats::packedLength()
{
UInt32 size = ExOperStats::packedLength();
size += sizeof(timer_);
- size += sizeof(lobStats_);
advanceSize2(size, tableName_);
size += sizeof(numBytesRead_);
size += sizeof(accessedRows_);
size += sizeof(usedRows_);
- size += sizeof(numHdfsCalls_);
- size += sizeof(maxHdfsIOTime_);
+ size += sizeof(numIOCalls_);
+ size += sizeof(maxIOTime_);
if ((Int32)getCollectStatsType() == SQLCLI_SE_OFFENDER_STATS)
{
size += sizeof(blockTime_);
@@ -2132,20 +2141,19 @@
return size;
}
-UInt32 ExHdfsScanStats::pack(char *buffer)
+UInt32 ExStorageEngineStats::pack(char *buffer)
{
UInt32 size = ExOperStats::pack(buffer);
buffer += size;
size += packIntoBuffer(buffer, timer_);
- size += packIntoBuffer(buffer, lobStats_);
size += packCharStarIntoBuffer(buffer, tableName_);
size += packIntoBuffer(buffer, numBytesRead_);
size += packIntoBuffer(buffer, accessedRows_);
size += packIntoBuffer(buffer, usedRows_);
- size += packIntoBuffer(buffer, numHdfsCalls_);
- size += packIntoBuffer(buffer, maxHdfsIOTime_);
+ size += packIntoBuffer(buffer, numIOCalls_);
+ size += packIntoBuffer(buffer, maxIOTime_);
if ((Int32)getCollectStatsType() == SQLCLI_SE_OFFENDER_STATS)
{
size += packIntoBuffer(buffer, blockTime_);
@@ -2157,20 +2165,19 @@
return size;
}
-void ExHdfsScanStats::unpack(const char* &buffer)
+void ExStorageEngineStats::unpack(const char* &buffer)
{
ExOperStats::unpack(buffer);
unpackBuffer(buffer, timer_);
- unpackBuffer(buffer, lobStats_);
unpackBuffer(buffer, tableName_, heap_);
unpackBuffer(buffer, numBytesRead_);
unpackBuffer(buffer, accessedRows_);
unpackBuffer(buffer, usedRows_);
- unpackBuffer(buffer, numHdfsCalls_);
- unpackBuffer(buffer, maxHdfsIOTime_);
+ unpackBuffer(buffer, numIOCalls_);
+ unpackBuffer(buffer, maxIOTime_);
if ((Int32)getCollectStatsType() == SQLCLI_SE_OFFENDER_STATS)
{
unpackBuffer(buffer, blockTime_);
@@ -2184,20 +2191,19 @@
}
}
-void ExHdfsScanStats::merge(ExHdfsScanStats *other)
+void ExStorageEngineStats::merge(ExStorageEngineStats *other)
{
ExOperStats::merge(other);
timer_ = timer_ + other->timer_;
- lobStats_ = lobStats_ + other->lobStats_;
numBytesRead_ += other->numBytesRead_;
accessedRows_ += other->accessedRows_;
usedRows_ += other->usedRows_;
- numHdfsCalls_ += other->numHdfsCalls_;
- if (maxHdfsIOTime_ < other->maxHdfsIOTime_) // take the larger value
- maxHdfsIOTime_ = other->maxHdfsIOTime_;
+ numIOCalls_ += other->numIOCalls_;
+ if (maxIOTime_ < other->maxIOTime_) // take the larger value
+ maxIOTime_ = other->maxIOTime_;
}
-void ExHdfsScanStats::copyContents(ExHdfsScanStats *other)
+void ExStorageEngineStats::copyContents(ExStorageEngineStats *other)
{
ExOperStats::copyContents(other);
@@ -2211,12 +2217,11 @@
}
timer_ = other->timer_;
- lobStats_ = other->lobStats_;
numBytesRead_ = other->numBytesRead_;
accessedRows_ = other->accessedRows_;
usedRows_ = other->usedRows_;
- numHdfsCalls_ = other->numHdfsCalls_;
- maxHdfsIOTime_ = other->maxHdfsIOTime_;
+ numIOCalls_ = other->numIOCalls_;
+ maxIOTime_ = other->maxIOTime_;
if ((Int32)getCollectStatsType() == SQLCLI_SE_OFFENDER_STATS)
{
blockTime_ = other->blockTime_;
@@ -2237,9 +2242,9 @@
}
}
-ExOperStats * ExHdfsScanStats::copyOper(NAMemory * heap)
+ExOperStats * ExStorageEngineStats::copyOper(NAMemory * heap)
{
- ExHdfsScanStats *stat = new(heap) ExHdfsScanStats(heap);
+ ExStorageEngineStats *stat = new(heap) ExStorageEngineStats(heap);
stat->copyContents(this);
return stat;
}
@@ -2250,23 +2255,29 @@
return this;
}
-const char *ExHdfsScanStats::getNumValTxt(Int32 i) const
+ExHbaseAccessStats
+*ExHdfsScanStats::castToExHbaseAccessStats()
+{
+ return this;
+}
+
+const char *ExStorageEngineStats::getNumValTxt(Int32 i) const
{
switch (i)
{
case 1:
return "OperCpuTime";
case 2:
- return "BytesRead";
+ return "SE_IO_KBytes";
case 3:
- return "TimeWaitingOnHdfs";
+ return "SE_IO_SumTime";
case 4:
- return "AccessedRows";
+ return "ActRowsAccessed";
}
return NULL;
}
-Int64 ExHdfsScanStats::getNumVal(Int32 i) const
+Int64 ExStorageEngineStats::getNumVal(Int32 i) const
{
switch (i)
{
@@ -2282,7 +2293,7 @@
return 0;
}
-NABoolean ExHdfsScanStats::filterForSEstats(struct timespec currTimespec, Lng32 filter)
+NABoolean ExStorageEngineStats::filterForSEstats(struct timespec currTimespec, Lng32 filter)
{
Int64 sumIOTime;
@@ -2299,7 +2310,7 @@
return FALSE;
}
-void ExHdfsScanStats::getVariableStatsInfo(char * dataBuffer,
+void ExStorageEngineStats::getVariableStatsInfo(char * dataBuffer,
char * dataLen,
Lng32 maxLen)
{
@@ -2315,26 +2326,28 @@
{
ExOperStats::getVariableStatsInfo(dataBuffer, dataLen, maxLen);
buf += *((short *) dataLen);
-
- lobStats()->getVariableStatsInfo(buf, dataLen, maxLen);
- buf += *((short *) dataLen);
}
sprintf (buf,
- "AnsiName: %s MessagesBytes: %ld AccessedRows: %ld UsedRows: %ld HiveIOCalls: %ld HiveSumIOTime: %ld HdfsMaxIOTime: %ld",
+ "AnsiName: %s MessagesBytes: %ld AccessedRows: %ld UsedRows: %ld HiveIOCalls: %ld HiveSumIOTime: %ld HdfsMaxIOTime: %ld "
+ "HbaseSumIOCalls: %ld HbaseSumIOTime: %ld HbaseMaxIOTime: %ld ",
+
(char*)tableName_,
numBytesRead(),
rowsAccessed(),
rowsUsed(),
- numHdfsCalls_,
+ numIOCalls_,
timer_.getTime(),
- maxHdfsIOTime_
+ maxIOTime_,
+ hbaseCalls(),
+ timer_.getTime(),
+ maxHbaseIOTime()
);
buf += str_len(buf);
*(short*)dataLen = (short) (buf - dataBuffer);
}
-Lng32 ExHdfsScanStats::getStatsItem(SQLSTATS_ITEM* sqlStats_item)
+Lng32 ExStorageEngineStats::getStatsItem(SQLSTATS_ITEM* sqlStats_item)
{
sqlStats_item->error_code = 0;
Int32 len;
@@ -2374,409 +2387,20 @@
sqlStats_item->int64_value = usedRows_;
break;
case SQLSTATS_HIVE_IOS:
- sqlStats_item->int64_value = numHdfsCalls_;
+ case SQLSTATS_HBASE_IOS:
+ sqlStats_item->int64_value = numIOCalls_;
break;
case SQLSTATS_HIVE_IO_BYTES:
- sqlStats_item->int64_value = numBytesRead_;
- break;
- case SQLSTATS_HIVE_IO_ELAPSED_TIME:
- sqlStats_item->int64_value = timer_.getTime();
- break;
- case SQLSTATS_HIVE_IO_MAX_TIME:
- sqlStats_item->int64_value = maxHdfsIOTime();
- break;
- case SQLSTATS_DETAIL:
- if (sqlStats_item->str_value != NULL)
- {
- if (tableName_ != NULL)
- {
- len = str_len(tableName_);
- if (len > sqlStats_item->str_max_len)
- {
- sqlStats_item->error_code = EXE_ERROR_IN_STAT_ITEM;
- str_cpy_all(sqlStats_item->str_value, tableName_, sqlStats_item->str_max_len);
- }
- else
- str_cpy_all(sqlStats_item->str_value, tableName_, len);
- }
- else
- len = 0;
- sprintf(tmpBuf, "|%ld|%ld", accessedRows_,
- numBytesRead_);
- len1 = str_len(tmpBuf);
- if ((len+len1) > sqlStats_item->str_max_len)
- sqlStats_item->error_code = EXE_ERROR_IN_STAT_ITEM;
- else
- str_cpy(sqlStats_item->str_value+len, tmpBuf, len1);
- sqlStats_item->str_ret_len = len+len1;
- }
- break;
- default:
- ExOperStats::getStatsItem(sqlStats_item);
- break;
- }
- return 0;
-}
-
-
-//////////////////////////////////////////////////////////////////
-// class ExHbaseAccessStats
-//////////////////////////////////////////////////////////////////
-
-ExHbaseAccessStats::ExHbaseAccessStats(NAMemory * heap,
- ex_tcb *tcb,
- ComTdb * tdb)
- : ExOperStats(heap,
- HBASE_ACCESS_STATS,
- tcb,
- tdb)
- , timer_(CLOCK_MONOTONIC)
-{
- ComTdbHbaseAccess *hbaseTdb = (ComTdbHbaseAccess *) tdb;
-
- if (hbaseTdb->getTableName())
- {
- // allocate memory and copy the ansi name into the stats entry
- const char * name = hbaseTdb->getTableName();
- Lng32 len = (Lng32)str_len(name);
- tableName_ = (char *)heap_->allocateMemory(len + 1);
- sprintf(tableName_, "%s", name);
- }
- else
- {
- tableName_ = NULL;
- }
- queryId_ = NULL;
- queryIdLen_ = 0;
- init(FALSE);
-}
-
-ExHbaseAccessStats::ExHbaseAccessStats(NAMemory * heap)
- : ExOperStats(heap,
- HBASE_ACCESS_STATS)
- , tableName_(NULL)
- , timer_(CLOCK_MONOTONIC)
-{
- queryId_ = NULL;
- queryIdLen_ = 0;
- init(FALSE);
-}
-
-void ExHbaseAccessStats::init(NABoolean resetDop)
-{
- ExOperStats::init(resetDop);
- timer_.reset();
-
- lobStats_.init();
-
- numBytesRead_ = 0;
- accessedRows_ = 0;
- usedRows_ = 0;
- numHbaseCalls_ = 0;
- maxHbaseIOTime_ = 0;
- blockTime_ = 0;
-}
-
-ExHbaseAccessStats::~ExHbaseAccessStats()
-{
- if (tableName_ != NULL)
- {
- NADELETEBASIC(tableName_,getHeap());
- tableName_ = NULL;
- }
- if ((Int32)getCollectStatsType() == SQLCLI_SE_OFFENDER_STATS && queryId_ != NULL)
- {
- NADELETEBASIC(queryId_, getHeap());
- queryId_ = NULL;
- }
-}
-
-UInt32 ExHbaseAccessStats::packedLength()
-{
- UInt32 size = ExOperStats::packedLength();
- size += sizeof(timer_);
- size += sizeof(lobStats_);
-
- advanceSize2(size, tableName_);
-
- size += sizeof(numBytesRead_);
- size += sizeof(accessedRows_);
- size += sizeof(usedRows_);
- size += sizeof(numHbaseCalls_);
- size += sizeof(maxHbaseIOTime_);
- if ((Int32)getCollectStatsType() == SQLCLI_SE_OFFENDER_STATS)
- {
- size += sizeof(blockTime_);
- size += sizeof(queryIdLen_);
- size += queryIdLen_;
- }
- return size;
-}
-
-UInt32 ExHbaseAccessStats::pack(char *buffer)
-{
- UInt32 size = ExOperStats::pack(buffer);
- buffer += size;
- size += packIntoBuffer(buffer, timer_);
- size += packIntoBuffer(buffer, lobStats_);
-
- size += packCharStarIntoBuffer(buffer, tableName_);
-
- size += packIntoBuffer(buffer, numBytesRead_);
- size += packIntoBuffer(buffer, accessedRows_);
- size += packIntoBuffer(buffer, usedRows_);
- size += packIntoBuffer(buffer, numHbaseCalls_);
- size += packIntoBuffer(buffer, maxHbaseIOTime_);
- if ((Int32)getCollectStatsType() == SQLCLI_SE_OFFENDER_STATS)
- {
- size += packIntoBuffer(buffer, blockTime_);
- size += packIntoBuffer(buffer, queryIdLen_);
- if (queryIdLen_ != 0 && queryId_ != NULL)
- size += packStrIntoBuffer(buffer, queryId_, queryIdLen_);
- }
-
- return size;
-}
-
-void ExHbaseAccessStats::unpack(const char* &buffer)
-{
- ExOperStats::unpack(buffer);
-
- unpackBuffer(buffer, timer_);
- unpackBuffer(buffer, lobStats_);
-
- unpackBuffer(buffer, tableName_, heap_);
-
- unpackBuffer(buffer, numBytesRead_);
- unpackBuffer(buffer, accessedRows_);
- unpackBuffer(buffer, usedRows_);
- unpackBuffer(buffer, numHbaseCalls_);
- unpackBuffer(buffer, maxHbaseIOTime_);
- if ((Int32)getCollectStatsType() == SQLCLI_SE_OFFENDER_STATS)
- {
- unpackBuffer(buffer, blockTime_);
- unpackBuffer(buffer, queryIdLen_);
- if (queryIdLen_ != 0)
- {
- queryId_ = new ((NAHeap *)(getHeap())) char[queryIdLen_+1];
- unpackStrFromBuffer(buffer, queryId_, queryIdLen_);
- queryId_[queryIdLen_] = '\0';
- }
- }
-}
-
-void ExHbaseAccessStats::merge(ExHbaseAccessStats *other)
-{
- ExOperStats::merge(other);
- timer_ = timer_ + other->timer_;
- lobStats_ = lobStats_ + other->lobStats_;
- numBytesRead_ += other->numBytesRead_;
- accessedRows_ += other->accessedRows_;
- usedRows_ += other->usedRows_;
- numHbaseCalls_ += other->numHbaseCalls_;
- if (maxHbaseIOTime_ < other->maxHbaseIOTime_) // take the larger value
- maxHbaseIOTime_ = other->maxHbaseIOTime_;
-}
-
-void ExHbaseAccessStats::copyContents(ExHbaseAccessStats *other)
-{
- ExOperStats::copyContents(other);
-
- // copy names only if we don't have one
- if (tableName_ == NULL && other->tableName_)
- {
- Lng32 len = (Lng32)str_len(other->tableName_);
- tableName_ = (char *)heap_->allocateMemory(len + 1);
- str_cpy_all(tableName_, other->tableName_, len);
- tableName_[len] = 0;
- }
-
- timer_ = other->timer_;
- lobStats_ = other->lobStats_;
- numBytesRead_ = other->numBytesRead_;
- accessedRows_ = other->accessedRows_;
- usedRows_ = other->usedRows_;
- numHbaseCalls_ = other->numHbaseCalls_;
- maxHbaseIOTime_ = other->maxHbaseIOTime_;
- if ((Int32)getCollectStatsType() == SQLCLI_SE_OFFENDER_STATS)
- {
- blockTime_ = other->blockTime_;
- queryIdLen_ = other->queryIdLen_;
- if (queryIdLen_ != 0)
- {
- queryId_ = new ((NAHeap *)(getHeap())) char[queryIdLen_+1];
- str_cpy_all(queryId_, other->queryId_, queryIdLen_);
- queryId_[queryIdLen_] = '\0';
- }
- else
- queryId_ = NULL;
- }
- else
- {
- queryId_ = other->queryId_;
- queryIdLen_ = other->queryIdLen_;
- }
-}
-
-ExOperStats * ExHbaseAccessStats::copyOper(NAMemory * heap)
-{
- ExHbaseAccessStats *stat = new(heap) ExHbaseAccessStats(heap);
- stat->copyContents(this);
- return stat;
-}
-
-ExHbaseAccessStats
-*ExHbaseAccessStats::castToExHbaseAccessStats()
-{
- return this;
-}
-
-const char *ExHbaseAccessStats::getNumValTxt(Int32 i) const
-{
- switch (i)
- {
- case 1:
- return "OperCpuTime";
- case 2:
- return "BytesRead";
- case 3:
- return "TimeWaitingOnHbase";
- case 4:
- return "AccessedRows";
- case 5:
- return "UsedRows";
- case 6:
- return "NumHbaseCalls";
- case 7:
- return "MaxHbaseIOTime";
- }
- return NULL;
-}
-
-Int64 ExHbaseAccessStats::getNumVal(Int32 i) const
-{
- switch (i)
- {
- case 1:
- return ExOperStats::getNumVal(i);
- case 2:
- return numBytesRead_;
- case 3:
- return timer_.getTime();
- case 4:
- return accessedRows_;
- case 5:
- return usedRows_;
- case 6:
- return numHbaseCalls_;
- case 7:
- return maxHbaseIOTime_;
- }
- return 0;
-}
-
-NABoolean ExHbaseAccessStats::filterForSEstats(struct timespec currTimespec, Lng32 filter)
-{
- Int64 sumIOTime;
- if (filter > 0) {
- blockTime_ = timer_.filterForSEstats(currTimespec);
- if (blockTime_ >= filter)
- return TRUE;
- }
- else
- if (queryId_ != NULL && (sumIOTime = timer_.getTime()) > 0 && (sumIOTime = sumIOTime /(1000000LL)) >= -filter) {
- blockTime_ = sumIOTime;
- return TRUE;
- }
- return FALSE;
-}
-
-
-void ExHbaseAccessStats::getVariableStatsInfo(char * dataBuffer,
- char * dataLen,
- Lng32 maxLen)
-{
- char *buf = dataBuffer;
- if ((Int32)getCollectStatsType() == SQLCLI_SE_OFFENDER_STATS)
- {
- sprintf(buf, "statsRowType: %d Qid: %s blockedFor: %d ",
- statType(),
- ((queryId_ != NULL) ? queryId_ : "NULL"), blockTime_);
- buf += str_len(buf);
- }
- else
- {
- ExOperStats::getVariableStatsInfo(dataBuffer, dataLen, maxLen);
- buf += *((short *) dataLen);
-
- lobStats()->getVariableStatsInfo(buf, dataLen, maxLen);
- buf += *((short *) dataLen);
- }
- sprintf (buf,
- "AnsiName: %s MessagesBytes: %ld AccessedRows: %ld UsedRows: %ld HbaseSumIOCalls: %ld HbaseSumIOTime: %ld HbaseMaxIOTime: %ld",
- (char*)tableName_,
- numBytesRead(),
- rowsAccessed(),
- rowsUsed(),
- hbaseCalls(),
- timer_.getTime(),
- maxHbaseIOTime()
- );
- buf += str_len(buf);
-
- *(short*)dataLen = (short) (buf - dataBuffer);
-}
-
-Lng32 ExHbaseAccessStats::getStatsItem(SQLSTATS_ITEM* sqlStats_item)
-{
- sqlStats_item->error_code = 0;
- Int32 len;
- Int32 len1;
- const char *tableName;
- char tmpBuf[100];
-
- switch (sqlStats_item->statsItem_id)
- {
- case SQLSTATS_TABLE_ANSI_NAME:
- if (sqlStats_item->str_value != NULL)
- {
- if (tableName_ != NULL)
- tableName = tableName_;
- else
- tableName = "NO_NAME_YET";
- len = str_len(tableName);
- if (len > sqlStats_item->str_max_len)
- {
- len = sqlStats_item->str_max_len;
- sqlStats_item->error_code = EXE_ERROR_IN_STAT_ITEM;
- }
- str_cpy(sqlStats_item->str_value, tableName, len);
- sqlStats_item->str_ret_len = len;
- }
- break;
- case SQLSTATS_EST_ROWS_ACCESSED:
- sqlStats_item->double_value = getEstRowsAccessed();
- break;
- case SQLSTATS_EST_ROWS_USED:
- sqlStats_item->double_value = getEstRowsUsed();
- break;
- case SQLSTATS_ACT_ROWS_ACCESSED:
- sqlStats_item->int64_value = accessedRows_;
- break;
- case SQLSTATS_ACT_ROWS_USED:
- sqlStats_item->int64_value = usedRows_;
- break;
- case SQLSTATS_HBASE_IOS:
- sqlStats_item->int64_value = numHbaseCalls_;
- break;
case SQLSTATS_HBASE_IO_BYTES:
sqlStats_item->int64_value = numBytesRead_;
break;
+ case SQLSTATS_HIVE_IO_ELAPSED_TIME:
case SQLSTATS_HBASE_IO_ELAPSED_TIME:
sqlStats_item->int64_value = timer_.getTime();
break;
+ case SQLSTATS_HIVE_IO_MAX_TIME:
case SQLSTATS_HBASE_IO_MAX_TIME:
- sqlStats_item->int64_value = maxHbaseIOTime_;
+ sqlStats_item->int64_value = maxIOTime_;
break;
case SQLSTATS_DETAIL:
if (sqlStats_item->str_value != NULL)
@@ -2794,8 +2418,8 @@
}
else
len = 0;
- sprintf(tmpBuf, "|%ld|%ld", accessedRows_,
- numBytesRead_);
+
+ sprintf(tmpBuf, "|%ld|%ld|%ld", getNumVal(2), getNumVal(3), getNumVal(4));
len1 = str_len(tmpBuf);
if ((len+len1) > sqlStats_item->str_max_len)
sqlStats_item->error_code = EXE_ERROR_IN_STAT_ITEM;
@@ -2810,7 +2434,7 @@
}
return 0;
}
-
+
//////////////////////////////////////////////////////////////////
// class ExProbeCacheStats
//////////////////////////////////////////////////////////////////
@@ -4783,7 +4407,7 @@
topN_ = other->topN_;
}
-void ExMeasStats::merge(ExHdfsScanStats* other)
+void ExMeasStats::merge(ExStorageEngineStats* other)
{
exeSEStats()->incAccessedRows(other->rowsAccessed());
exeSEStats()->incUsedRows(other->rowsUsed());
@@ -4792,15 +4416,6 @@
exeSEStats()->incMaxIOTime(other->maxHdfsIOTime());
}
-void ExMeasStats::merge(ExHbaseAccessStats* other)
-{
- exeSEStats()->incAccessedRows(other->rowsAccessed());
- exeSEStats()->incUsedRows(other->rowsUsed());
- exeSEStats()->incNumIOCalls(other->hbaseCalls());
- exeSEStats()->incNumIOBytes(other->numBytesRead());
- exeSEStats()->incMaxIOTime(other->maxHbaseIOTime());
-}
-
void ExMeasStats::merge(ExMeasStats* other)
{
ExMeasBaseStats::merge(other);
@@ -4866,11 +4481,9 @@
case BMO_STATS:
merge((ExBMOStats *)other);
break;
- case HDFSSCAN_STATS:
- merge((ExHdfsScanStats *)other);
+ case SE_STATS:
+ merge((ExStorageEngineStats *)other);
break;
- case HBASE_ACCESS_STATS:
- merge((ExHbaseAccessStats *)other);
break;
default:
// do nothing - This type of stat has no merge data
@@ -5475,11 +5088,8 @@
case ExOperStats::UDR_BASE_STATS:
NADELETE((ExUDRBaseStats *)stat, ExUDRBaseStats, heap_);
break;
- case ExOperStats::HDFSSCAN_STATS:
- NADELETE((ExHdfsScanStats *)stat, ExHdfsScanStats, heap_);
- break;
- case ExOperStats::HBASE_ACCESS_STATS:
- NADELETE((ExHbaseAccessStats *)stat, ExHbaseAccessStats, heap_);
+ case ExOperStats::SE_STATS:
+ NADELETE((ExStorageEngineStats *)stat, ExStorageEngineStats, heap_);
break;
default:
NADELETE(stat, ExOperStats, heap_);
@@ -5588,19 +5198,11 @@
return TRUE;
}
break;
- case ExOperStats::HDFSSCAN_STATS:
- if (stat->statType() == ExOperStats::HDFSSCAN_STATS
+ case ExOperStats::SE_STATS:
+ if (stat->statType() == ExOperStats::SE_STATS
&& stat->getPertableStatsId() == other->getPertableStatsId())
{
- ((ExHdfsScanStats *)stat)->merge((ExHdfsScanStats *)other);
- return TRUE;
- }
- break;
- case ExOperStats::HBASE_ACCESS_STATS:
- if (stat->statType() == ExOperStats::HBASE_ACCESS_STATS
- && stat->getPertableStatsId() == other->getPertableStatsId())
- {
- ((ExHbaseAccessStats *)stat)->merge((ExHbaseAccessStats *)other);
+ ((ExStorageEngineStats *)stat)->merge((ExStorageEngineStats *)other);
return TRUE;
}
break;
@@ -5644,11 +5246,8 @@
case ExOperStats::UDR_BASE_STATS:
((ExUDRBaseStats *)stat)->merge((ExUDRBaseStats *)other);
break;
- case ExOperStats::HDFSSCAN_STATS:
- ((ExHdfsScanStats*)stat)->merge((ExHdfsScanStats*)other);
- break;
- case ExOperStats::HBASE_ACCESS_STATS:
- ((ExHbaseAccessStats*)stat)->merge((ExHbaseAccessStats*)other);
+ case ExOperStats::SE_STATS:
+ ((ExStorageEngineStats*)stat)->merge((ExStorageEngineStats*)other);
break;
default:
ex_assert(FALSE, "Merging unknown operator statistics type");
@@ -5764,22 +5363,11 @@
insert(newStat);
}
break;
-
- case ExOperStats::HDFSSCAN_STATS:
+ case ExOperStats::SE_STATS:
{
- newStat = new(heap_) ExHdfsScanStats(heap_);
+ newStat = new(heap_) ExStorageEngineStats(heap_);
newStat->setCollectStatsType(tempStatsMergeType);
- ((ExHdfsScanStats *)newStat)->copyContents((ExHdfsScanStats *)stat);
- newStat->setCollectStatsType(tempStatsMergeType);
- insert(newStat);
- }
- break;
-
- case ExOperStats::HBASE_ACCESS_STATS:
- {
- newStat = new(heap_) ExHbaseAccessStats(heap_);
- newStat->setCollectStatsType(tempStatsMergeType);
- ((ExHbaseAccessStats *)newStat)->copyContents((ExHbaseAccessStats *)stat);
+ ((ExStorageEngineStats *)newStat)->copyContents((ExStorageEngineStats *)stat);
newStat->setCollectStatsType(tempStatsMergeType);
insert(newStat);
}
@@ -5827,16 +5415,9 @@
insert(newStat);
break;
- case ExOperStats::HDFSSCAN_STATS:
- newStat = new(heap_) ExHdfsScanStats(heap_);
- ((ExHdfsScanStats *)newStat)->copyContents((ExHdfsScanStats *)stat);
- newStat->setCollectStatsType(tempStatsMergeType);
- insert(newStat);
- break;
-
- case ExOperStats::HBASE_ACCESS_STATS:
- newStat = new(heap_) ExHbaseAccessStats(heap_);
- ((ExHbaseAccessStats *)newStat)->copyContents((ExHbaseAccessStats *)stat);
+ case ExOperStats::SE_STATS:
+ newStat = new(heap_) ExStorageEngineStats(heap_);
+ ((ExStorageEngineStats *)newStat)->copyContents((ExStorageEngineStats *)stat);
newStat->setCollectStatsType(tempStatsMergeType);
insert(newStat);
break;
@@ -5950,18 +5531,10 @@
insert(newStat);
break;
- case ExOperStats::HDFSSCAN_STATS:
- newStat = new(heap_)ExHdfsScanStats(heap_);
- ((ExHdfsScanStats *)newStat)->
- copyContents((ExHdfsScanStats *)stat);
- newStat->setCollectStatsType(tempStatsMergeType);
- insert(newStat);
- break;
-
- case ExOperStats::HBASE_ACCESS_STATS:
- newStat = new(heap_)ExHbaseAccessStats(heap_);
- ((ExHbaseAccessStats *)newStat)->
- copyContents((ExHbaseAccessStats *)stat);
+ case ExOperStats::SE_STATS:
+ newStat = new(heap_)ExStorageEngineStats(heap_);
+ ((ExStorageEngineStats *)newStat)->
+ copyContents((ExStorageEngineStats *)stat);
newStat->setCollectStatsType(tempStatsMergeType);
insert(newStat);
break;
@@ -6398,12 +5971,9 @@
case ExOperStats::PROCESS_STATS:
stat = new(heap_) ExProcessStats((NAHeap *)heap_);
break;
- case ExOperStats::HDFSSCAN_STATS:
- stat = new(heap_) ExHdfsScanStats((NAHeap *)heap_);
+ case ExOperStats::SE_STATS:
+ stat = new(heap_) ExStorageEngineStats((NAHeap *)heap_);
break;
- case ExOperStats::HBASE_ACCESS_STATS:
- stat = new(heap_) ExHbaseAccessStats((NAHeap *)heap_);
- break;
default:
FAILURE ;
}
@@ -6536,6 +6106,7 @@
ExPartitionAccessStats* partitionAccessStats = NULL;
ExProbeCacheStats* probeCacheStats = NULL;
ExFastExtractStats* fastExtractStats = NULL;
+ ExStorageEngineStats *seStats = NULL;
ExHdfsScanStats* hdfsScanStats = NULL;
ExHbaseAccessStats* hbaseAccessStats = NULL;
ExSortStats* sortStats = NULL;
@@ -6669,19 +6240,11 @@
else
tempRetcode = -EXE_STAT_NOT_FOUND;
break;
- case ExOperStats::HDFSSCAN_STATS:
- if (hdfsScanStats == NULL)
- hdfsScanStats = (ExHdfsScanStats*)get(ExOperStats::HDFSSCAN_STATS, sqlStats_items[i].tdb_id);
- if (hdfsScanStats != NULL)
- tempRetcode = hdfsScanStats->getStatsItem(&sqlStats_items[i]);
- else
- tempRetcode = -EXE_STAT_NOT_FOUND;
- break;
- case ExOperStats::HBASE_ACCESS_STATS:
- if (hbaseAccessStats == NULL)
- hbaseAccessStats = (ExHbaseAccessStats*)get(ExOperStats::HBASE_ACCESS_STATS, sqlStats_items[i].tdb_id);
- if (hbaseAccessStats != NULL)
- tempRetcode = hbaseAccessStats->getStatsItem(&sqlStats_items[i]);
+ case ExOperStats::SE_STATS:
+ if (seStats == NULL)
+ seStats = (ExStorageEngineStats*)get(ExOperStats::HDFSSCAN_STATS, sqlStats_items[i].tdb_id);
+ if (seStats != NULL)
+ tempRetcode = seStats->getStatsItem(&sqlStats_items[i]);
else
tempRetcode = -EXE_STAT_NOT_FOUND;
break;
@@ -7026,8 +6589,9 @@
ExUDRBaseStats *udrBaseStats;
ExMasterStats *masterStats;
ExProcessStats *processStats;
- ExHbaseAccessStats *hbaseAccessStats;
+ ExStorageEngineStats *seStats;
ExHdfsScanStats *hdfsScanStats;
+ ExHbaseAccessStats *hbaseAccessStats;
NABoolean retcode = FALSE;
ExOperStats::StatType statType;
ExOperStats *stat1;
@@ -7172,26 +6736,16 @@
retcode = TRUE;
}
break;
- case ExOperStats::HDFSSCAN_STATS:
+ case ExOperStats::SE_STATS:
if (detailLevel_ == stat->getTdbId())
{
- hdfsScanStats = new (getHeap()) ExHdfsScanStats(getHeap());
- hdfsScanStats->setCollectStatsType(getCollectStatsType());
- hdfsScanStats->copyContents((ExHdfsScanStats *)stat);
- insert(hdfsScanStats);
+ seStats = new (getHeap()) ExStorageEngineStats(getHeap());
+ seStats->setCollectStatsType(getCollectStatsType());
+ seStats->copyContents((ExHdfsScanStats *)stat);
+ insert(seStats);
retcode = TRUE;
}
break;
- case ExOperStats::HBASE_ACCESS_STATS:
- if (detailLevel_ == stat->getTdbId())
- {
- hbaseAccessStats = new (getHeap()) ExHbaseAccessStats(getHeap());
- hbaseAccessStats->setCollectStatsType(getCollectStatsType());
- hbaseAccessStats->copyContents((ExHbaseAccessStats *)stat);
- insert(hbaseAccessStats);
- retcode = TRUE;
- }
- break;
default:
break;
} // StatType case
@@ -10529,9 +10083,9 @@
case 1:
return "OperCpuTime";
case 2:
- return "scrIORead";
+ return "scrIOCount";
case 3:
- return "scrIOWritten";
+ return "bmoHeapAllocated";
case 4:
return "scrFileCount";
}
@@ -10545,9 +10099,9 @@
case 1:
return ExOperStats::getNumVal(i);
case 2:
- return scratchReadCount_;
+ return scratchReadCount_+scratchWriteCount_;
case 3:
- return scratchWriteCount_;
+ return bmoHeapAlloc_;
case 4:
return scratchFileCount_;
}
@@ -10718,10 +10272,8 @@
case SQLSTATS_DETAIL:
if (sqlStats_item->str_value != NULL)
{
- sprintf(tmpBuf, "%d|%d|%d",
- scratchBufferBlockRead_,
- scratchBufferBlockWritten_,
- scratchFileCount_);
+ char* buf = tmpBuf;
+ sprintf(buf, "%ld|%ld|%ld|", getNumVal(2), getNumVal(3), getNumVal(4));
len = str_len(tmpBuf);
if (len > sqlStats_item->str_max_len)
sqlStats_item->error_code = EXE_ERROR_IN_STAT_ITEM;
diff --git a/core/sql/executor/ExStats.h b/core/sql/executor/ExStats.h
index e244b4d..6fd10e0 100644
--- a/core/sql/executor/ExStats.h
+++ b/core/sql/executor/ExStats.h
@@ -42,6 +42,7 @@
#include "Int64.h"
#include "ComTdb.h"
+#include "ex_stdh.h"
#include "ExScheduler.h"
#include "ComTdbStats.h"
#include "ComTdbUdr.h"
@@ -85,8 +86,10 @@
class ExBMOStats;
class ExUDRBaseStats;
class ExFastExtractStats;
-class ExHdfsScanStats;
-class ExHbaseAccessStats;
+class ExStorageEngineStats;
+
+typedef ExStorageEngineStats ExHbaseAccessStats;
+typedef ExStorageEngineStats ExHdfsScanStats;
//////////////////////////////////////////////////////////////////
// forward classes
@@ -434,8 +437,7 @@
UInt32 pack(char * buffer);
void merge(ExeSEStats * other);
- void merge(ExHbaseAccessStats * other);
- void merge(ExHdfsScanStats * other);
+ void merge(ExStorageEngineStats * other);
void unpack(const char* &buffer);
@@ -566,8 +568,9 @@
REPLICATOR_STATS = SQLSTATS_DESC_REPLICATOR_STATS,
FAST_EXTRACT_STATS = SQLSTATS_DESC_FAST_EXTRACT_STATS,
REORG_STATS = SQLSTATS_DESC_REORG_STATS,
- HDFSSCAN_STATS = SQLSTATS_DESC_HDFSSCAN_STATS,
- HBASE_ACCESS_STATS = SQLSTATS_DESC_HBASE_ACCESS_STATS,
+ SE_STATS = SQLSTATS_DESC_SE_STATS,
+ HDFSSCAN_STATS = SQLSTATS_DESC_SE_STATS,
+ HBASE_ACCESS_STATS = SQLSTATS_DESC_SE_STATS,
PROCESS_STATS = SQLSTATS_DESC_PROCESS_STATS
};
@@ -1795,24 +1798,24 @@
};
/////////////////////////////////////////////////////////////////
-//// class ExHdfsScanStats
+//// class ExStorageEngineStats
///////////////////////////////////////////////////////////////////
-class ExHdfsScanStats : public ExOperStats {
+class ExStorageEngineStats : public ExOperStats {
public:
- ExHdfsScanStats(NAMemory * heap,
+ ExStorageEngineStats(NAMemory * heap,
ex_tcb *tcb,
ComTdb * tdb); // tbd - other, specific params?
- ExHdfsScanStats(NAMemory * heap);
+ ExStorageEngineStats(NAMemory * heap);
- ~ExHdfsScanStats();
+ ~ExStorageEngineStats();
void init(NABoolean resetDop);
- void merge(ExHdfsScanStats* other);
+ void merge(ExStorageEngineStats* other);
- void copyContents(ExHdfsScanStats* other);
+ void copyContents(ExStorageEngineStats* other);
ExOperStats * copyOper(NAMemory * heap);
@@ -1831,24 +1834,32 @@
char * tableName() const {return tableName_;}
ExTimeStats &getHdfsTimer() { return timer_; }
+ ExTimeStats &getHbaseTimer() { return timer_; }
+
inline void incBytesRead(Int64 bytesRead) {numBytesRead_ += bytesRead;}
inline void incAccessedRows() {++accessedRows_;}
+ inline void incAccessedRows(Int64 v) {accessedRows_ += v;}
inline void incUsedRows() {++usedRows_;}
+ inline void incUsedRows(Int64 v) {usedRows_ += v;}
- inline void incMaxHdfsIOTime(Int64 v) {maxHdfsIOTime_ += v;}
+ inline void incMaxHdfsIOTime(Int64 v) {maxIOTime_ += v;}
+ inline void incMaxHbaseIOTime(Int64 v) {maxIOTime_ += v;}
+
Int64 numBytesRead() const {return numBytesRead_;}
-
Int64 rowsAccessed() const {return accessedRows_;}
-
Int64 rowsUsed() const {return usedRows_;}
NABoolean filterForSEstats(struct timespec currTimespec, Lng32 filter);
- Int64 maxHdfsIOTime() const {return maxHdfsIOTime_;}
+
+ Int64 maxHdfsIOTime() const {return maxIOTime_;}
+ Int64 maxHbaseIOTime() const {return maxIOTime_;}
ExHdfsScanStats * castToExHdfsScanStats();
+ ExHbaseAccessStats * castToExHbaseAccessStats();
+
virtual const char * getNumValTxt(Int32 i) const;
virtual Int64 getNumVal(Int32 i) const;
@@ -1859,125 +1870,27 @@
Lng32 getStatsItem(SQLSTATS_ITEM* sqlStats_item);
- ExLobStats * lobStats() { return &lobStats_;}
void setQueryId(char *queryId, Lng32 queryIdLen)
{queryId_ = queryId;
queryIdLen_ = queryIdLen;}
char *getQueryId() { return queryId_; }
Lng32 getQueryIdLen() { return queryIdLen_; }
- inline void incHdfsCalls() {++numHdfsCalls_;}
- Int64 hdfsCalls() const {return numHdfsCalls_;}
+
+ inline void incHdfsCalls() {++numIOCalls_;}
+ inline void incHbaseCalls() {++numIOCalls_;}
+
+ Int64 hdfsCalls() const {return numIOCalls_;}
+ Int64 hbaseCalls() const {return numIOCalls_;}
private:
ExTimeStats timer_;
- ExLobStats lobStats_;
-
char * tableName_;
-
Int64 numBytesRead_;
Int64 accessedRows_;
Int64 usedRows_;
- Int64 numHdfsCalls_;
- Int64 maxHdfsIOTime_;
- char *queryId_;
- Lng32 queryIdLen_;
- Lng32 blockTime_;
-};
-
-/////////////////////////////////////////////////////////////////
-//// class ExHbaseAccessStats
-///////////////////////////////////////////////////////////////////
-
-class ExHbaseAccessStats : public ExOperStats {
- public:
- ExHbaseAccessStats(NAMemory * heap,
- ex_tcb *tcb,
- ComTdb * tdb); // tbd - other, specific params?
-
- ExHbaseAccessStats(NAMemory * heap);
-
- ~ExHbaseAccessStats();
-
- void init(NABoolean resetDop);
-
- void merge(ExHbaseAccessStats* other);
-
- void copyContents(ExHbaseAccessStats* other);
-
- ExOperStats * copyOper(NAMemory * heap);
-
- UInt32 packedLength();
-
- //////////////////////////////////////////////////////////////////
- //// packs 'this' into a message. Converts pointers to offsets.
- ////////////////////////////////////////////////////////////////////
- UInt32 pack(char * buffer);
-
- void unpack(const char* &buffer);
-
- /////////////////////////////////////////////////////////////////
- //// accessors, mutators
- ///////////////////////////////////////////////////////////////////
- char * tableName() const {return tableName_;}
-
- ExTimeStats &getHbaseTimer() { return timer_; }
- inline void incBytesRead(Int64 bytesRead) {numBytesRead_ += bytesRead;}
-
- inline void incAccessedRows() {++accessedRows_;}
- inline void incAccessedRows(Int64 v) {accessedRows_ += v;}
-
- inline void incUsedRows() {++usedRows_;}
- inline void incUsedRows(Int64 v) {usedRows_ += v;}
-
- inline void incHbaseCalls() {++numHbaseCalls_;}
-
- inline void incMaxHbaseIOTime(Int64 v) {maxHbaseIOTime_ += v;}
-
- Int64 numBytesRead() const {return numBytesRead_;}
-
- Int64 rowsAccessed() const {return accessedRows_;}
-
- Int64 rowsUsed() const {return usedRows_;}
-
- Int64 hbaseCalls() const {return numHbaseCalls_;}
-
- Int64 maxHbaseIOTime() const {return maxHbaseIOTime_;}
-
- NABoolean filterForSEstats(struct timespec currTimespec, Lng32 filter);
-
- ExHbaseAccessStats * castToExHbaseAccessStats();
-
- virtual const char * getNumValTxt(Int32 i) const;
-
- virtual Int64 getNumVal(Int32 i) const;
-
- virtual void getVariableStatsInfo(char * dataBuffer,
- char * datalen,
- Lng32 maxLen);
- Lng32 getStatsItem(SQLSTATS_ITEM* sqlStats_item);
-
- ExLobStats * lobStats() { return &lobStats_;}
-
- // ExHbaseStats * hbaseStats() { return &hbaseStats_;}
- void setQueryId(char *queryId, Lng32 queryIdLen)
- {queryId_ = queryId;
- queryIdLen_ = queryIdLen;}
- char *getQueryId() { return queryId_; }
- Lng32 getQueryIdLen() { return queryIdLen_; }
-
- private:
-
- ExTimeStats timer_;
- ExLobStats lobStats_;
-
- char * tableName_;
-
- Int64 numBytesRead_;
- Int64 accessedRows_;
- Int64 usedRows_;
- Int64 numHbaseCalls_;
- Int64 maxHbaseIOTime_;
+ Int64 numIOCalls_;
+ Int64 maxIOTime_;
char *queryId_;
Lng32 queryIdLen_;
Lng32 blockTime_;
@@ -2087,8 +2000,7 @@
void merge(ExFragRootOperStats* other);
void merge(ExUDRBaseStats * other);
void merge(ExBMOStats * other);
- void merge(ExHdfsScanStats * other);
- void merge(ExHbaseAccessStats * other);
+ void merge(ExStorageEngineStats * other);
ExOperStats * copyOper(NAMemory * heap);
diff --git a/core/sql/executor/HBaseClient_JNI.h b/core/sql/executor/HBaseClient_JNI.h
index c89146a..eb339aa 100644
--- a/core/sql/executor/HBaseClient_JNI.h
+++ b/core/sql/executor/HBaseClient_JNI.h
@@ -29,23 +29,19 @@
#include "Platform.h"
#include "Collections.h"
#include "NABasicObject.h"
-
+#include "ExStats.h"
#include "JavaObjectInterface.h"
#include "Hbase_types.h"
#include "ExpHbaseDefs.h"
#include "NAMemory.h"
#include "org_trafodion_sql_HTableClient.h"
-// forward declare
-class ExHbaseAccessStats;
-
using namespace apache::hadoop::hbase::thrift;
namespace {
typedef std::vector<Text> TextVec;
}
-
class ContextCli;
class HBulkLoadClient_JNI;
diff --git a/core/sql/executor/HdfsClient_JNI.cpp b/core/sql/executor/HdfsClient_JNI.cpp
index d5b5043..65c83cd 100644
--- a/core/sql/executor/HdfsClient_JNI.cpp
+++ b/core/sql/executor/HdfsClient_JNI.cpp
@@ -288,6 +288,8 @@
short retArrayLen = jenv_->GetArrayLength(j_retArray);
ex_assert(retArrayLen == arrayLen, "HdfsScan::trafHdfsRead() InternalError: retArrayLen != arrayLen");
jenv_->GetIntArrayRegion(j_retArray, 0, 4, retArray);
+ if (hdfsStats_ != NULL)
+ hdfsStats_->incBytesRead(retArray[ExHdfsScanTcb::BYTES_COMPLETED]);
return HDFS_SCAN_OK;
}
@@ -666,6 +668,7 @@
if (hdfsStats_ != NULL) {
hdfsStats_->incMaxHdfsIOTime(hdfsStats_->getHdfsTimer().stop());
hdfsStats_->incHdfsCalls();
+ hdfsStats_->incBytesRead(writeLen);
}
if (jenv_->ExceptionCheck())
{
@@ -724,6 +727,7 @@
if (hdfsStats_ != NULL) {
hdfsStats_->incMaxHdfsIOTime(hdfsStats_->getHdfsTimer().stop());
hdfsStats_->incHdfsCalls();
+ hdfsStats_->incBytesRead(writeLen);
}
if (jenv_->ExceptionCheck())
{
@@ -765,6 +769,7 @@
if (hdfsStats_ != NULL) {
hdfsStats_->incMaxHdfsIOTime(hdfsStats_->getHdfsTimer().stop());
hdfsStats_->incHdfsCalls();
+ hdfsStats_->incBytesRead(bytesRead);
}
if (jenv_->ExceptionCheck())
{
diff --git a/core/sql/executor/OrcFileReader.h b/core/sql/executor/OrcFileReader.h
index 536235a..2c7d7b8 100644
--- a/core/sql/executor/OrcFileReader.h
+++ b/core/sql/executor/OrcFileReader.h
@@ -24,6 +24,7 @@
#define ORC_FILE_READER_H
#include "JavaObjectInterface.h"
+#include "ExStats.h"
// ===========================================================================
// ===== The OrcFileReader class implements access to th Java
diff --git a/core/sql/executor/log4cpp.hdfs.config b/core/sql/executor/log4cpp.hdfs.config
deleted file mode 100644
index d27650b..0000000
--- a/core/sql/executor/log4cpp.hdfs.config
+++ /dev/null
@@ -1,37 +0,0 @@
-# log4cxx configuration for HDFS access via JNI
-
-# @@@ START COPYRIGHT @@@
-#
-# Licensed to the Apache Software Foundation (ASF) under one
-# or more contributor license agreements. See the NOTICE file
-# distributed with this work for additional information
-# regarding copyright ownership. The ASF licenses this file
-# to you under the Apache License, Version 2.0 (the
-# "License"); you may not use this file except in compliance
-# with the License. You may obtain a copy of the License at
-#
-# http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing,
-# software distributed under the License is distributed on an
-# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
-# KIND, either express or implied. See the License for the
-# specific language governing permissions and limitations
-# under the License.
-#
-# @@@ END COPYRIGHT @@@
-
-log4j.rootLogger=INFO, rootAppender
-
-log4j.appender.rootAppender=org.apache.log4j.RollingFileAppender
-log4j.appender.rootAppender.fileName=hdfs.log
-log4j.appender.rootAppender.maxFileSize=100000000
-log4j.appender.rootAppender.maxBackupIndex=1
-log4j.appender.rootAppender.addPid=false
-log4j.appender.rootAppender.layout=org.apache.log4j.PatternLayout
-log4j.appender.rootAppender.layout.ConversionPattern=%d, %p, %c, %m%n
-
-log4j.logger.JniTop=ERROR
-log4j.logger.SeqFileReader=ERROR
-log4j.logger.SeqFileWriter=ERROR
-log4j.logger.HBase=ERROR
diff --git a/core/sql/executor/log4j.hdfs.config b/core/sql/executor/log4j.hdfs.config
deleted file mode 100644
index 6b8f9fe..0000000
--- a/core/sql/executor/log4j.hdfs.config
+++ /dev/null
@@ -1,50 +0,0 @@
-# Define some default values that can be overridden by system properties
-
-# @@@ START COPYRIGHT @@@
-#
-# Licensed to the Apache Software Foundation (ASF) under one
-# or more contributor license agreements. See the NOTICE file
-# distributed with this work for additional information
-# regarding copyright ownership. The ASF licenses this file
-# to you under the Apache License, Version 2.0 (the
-# "License"); you may not use this file except in compliance
-# with the License. You may obtain a copy of the License at
-#
-# http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing,
-# software distributed under the License is distributed on an
-# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
-# KIND, either express or implied. See the License for the
-# specific language governing permissions and limitations
-# under the License.
-#
-# @@@ END COPYRIGHT @@@
-
-hbase.root.logger=INFO,hbaseclient
-hbase.log.dir=.
-hbase.log.file=hdfs.java.log
-
-# Define the root logger to the system property "hbase.root.logger".
-log4j.rootLogger=${hbase.root.logger}
-
-# Logging Threshold
-log4j.threshhold=ALL
-
-#
-# Daily Rolling File Appender
-#
-log4j.appender.DRFA=org.apache.log4j.DailyRollingFileAppender
-log4j.appender.hbaseclient=org.apache.log4j.RollingFileAppender
-log4j.appender.hbaseclient.file=hdfs.java.log
-log4j.appender.hbaseclient.layout=org.apache.log4j.PatternLayout
-log4j.appender.hbaseclient.layout.ConversionPattern=%d{yy/MM/dd HH:mm:ss} %p %c{2}: %m%n
-log4j.appender.hbaseclient.immediateFlush=true
-
-# Custom Logging levels
-
-log4j.logger.org.apache.zookeeper=ERROR
-log4j.logger.org.apache.hadoop.hbase=ERROR
-log4j.logger.com.tandem.sqlmx=ERROR
-
-#log4j.logger.org.apache.hadoop.hbase=DEBUG
diff --git a/core/sql/exp/ExpHbaseInterface.h b/core/sql/exp/ExpHbaseInterface.h
index c9583e5..a7eee97 100644
--- a/core/sql/exp/ExpHbaseInterface.h
+++ b/core/sql/exp/ExpHbaseInterface.h
@@ -60,7 +60,6 @@
class ex_globals;
class CliGlobals;
-class ExHbaseAccessStats;
Int64 getTransactionIDFromContext();
diff --git a/core/sql/exp/ExpLOB.cpp b/core/sql/exp/ExpLOB.cpp
index 5fb0fc2..914861b 100644
--- a/core/sql/exp/ExpLOB.cpp
+++ b/core/sql/exp/ExpLOB.cpp
@@ -833,6 +833,7 @@
rc = ExpLOBInterfaceInsertSelect
(getExeGlobals()->getExLobGlobal(),
+ (getTcb()->getStatsEntry() != NULL ? getTcb()->getStatsEntry()->castToExHdfsScanStats() : NULL),
getLobHdfsServer(), getLobHdfsPort(),
tgtLobName,
so,
@@ -845,6 +846,7 @@
else
rc = ExpLOBInterfaceInsert
(getExeGlobals()->getExLobGlobal(),
+ (getTcb()->getStatsEntry() != NULL ? getTcb()->getStatsEntry()->castToExHdfsScanStats() : NULL),
tgtLobName,
lobStorageLocation(),
lobStorageType(),
@@ -992,6 +994,7 @@
rc = ExpLOBInterfaceInsert(getExeGlobals()->getExLobGlobal(),
+ (getTcb()->getStatsEntry() != NULL ? getTcb()->getStatsEntry()->castToExHdfsScanStats() : NULL),
tgtLobName,
lobStorageLocation(),
lobType,
@@ -1160,6 +1163,7 @@
rc = ExpLOBInterfaceDelete
(
getExeGlobals()->getExLobGlobal(),
+ (getTcb()->getStatsEntry() != NULL ? getTcb()->getStatsEntry()->castToExHdfsScanStats() : NULL),
getLobHdfsServer(),
getLobHdfsPort(),
lobName,
@@ -1439,6 +1443,7 @@
{
rc = ExpLOBInterfaceUpdateAppend
(getExeGlobals()->getExLobGlobal(),
+ (getTcb()->getStatsEntry() != NULL ? getTcb()->getStatsEntry()->castToExHdfsScanStats() : NULL),
getLobHdfsServer(),
getLobHdfsPort(),
tgtLobName,
@@ -1462,6 +1467,7 @@
{
rc = ExpLOBInterfaceUpdate
(getExeGlobals()->getExLobGlobal(),
+ (getTcb()->getStatsEntry() != NULL ? getTcb()->getStatsEntry()->castToExHdfsScanStats() : NULL),
getLobHdfsServer(),
getLobHdfsPort(),
tgtLobName,
@@ -1636,6 +1642,7 @@
so = Lob_File;
tgtFileName = tgtFileName_;
rc = ExpLOBInterfaceSelect(getExeGlobals()->getExLobGlobal(),
+ (getTcb()->getStatsEntry() != NULL ? getTcb()->getStatsEntry()->castToExHdfsScanStats() : NULL),
lobName,
lobStorageLocation(),
lobType,
@@ -1661,6 +1668,7 @@
lobLen = getConvertSize();
lobData = new(h) char[(Lng32)lobLen];
rc = ExpLOBInterfaceSelect(getExeGlobals()->getExLobGlobal(),
+ (getTcb()->getStatsEntry() != NULL ? getTcb()->getStatsEntry()->castToExHdfsScanStats() : NULL),
lobName,
lobStorageLocation(),
lobType,
diff --git a/core/sql/exp/ExpLOBaccess.cpp b/core/sql/exp/ExpLOBaccess.cpp
index a24018a..bb9b580 100644
--- a/core/sql/exp/ExpLOBaccess.cpp
+++ b/core/sql/exp/ExpLOBaccess.cpp
@@ -77,7 +77,7 @@
// short LobServerFNum;
SB_Phandle_Type serverPhandle;
-ExLob::ExLob(NAHeap * heap) :
+ExLob::ExLob(NAHeap * heap, ExHdfsScanStats *hdfsAccessStats) :
lobDataFile_(heap),
storage_(Lob_Invalid_Storage),
lobStorageLocation_(string()),
@@ -85,6 +85,7 @@
fs_(NULL),
fdData_(NULL),
openFlags_(0),
+ stats_(hdfsAccessStats),
lobTrace_(FALSE),
useLibHdfs_(FALSE),
hdfsClient_(NULL)
@@ -149,8 +150,6 @@
storage_ = storage;
}
- stats_.init();
-
hdfsServer_ = hdfsServer;
hdfsPort_ = hdfsPort;
// lobLocation_ = lobLocation;
@@ -165,7 +164,7 @@
hdfsClient_ = NULL;
}
else {
- hdfsClient_ = HdfsClient::newInstance(lobGlobalHeap_, NULL, hdfsClientRetcode);
+ hdfsClient_ = HdfsClient::newInstance(lobGlobalHeap_, stats_, hdfsClientRetcode);
fs_ = NULL;
if (hdfsClient_ == NULL)
return LOB_HDFS_CONNECT_ERROR;
@@ -181,7 +180,6 @@
nsecs += NUM_NSECS_IN_SEC;
}
totalnsecs = (secs * NUM_NSECS_IN_SEC) + nsecs;
- stats_.hdfsConnectionTime += totalnsecs;
if (! useLibHdfs_) {
if (mode == EX_LOB_CREATE) {
@@ -2192,7 +2190,6 @@
nsecs += NUM_NSECS_IN_SEC;
}
Int64 totalnsecs = (secs * NUM_NSECS_IN_SEC) + nsecs;
- stats_.CumulativeReadTime += totalnsecs;
} // useLibHdfs
if (bytesRead == -1) {
return LOB_DATA_READ_ERROR;
@@ -2603,20 +2600,19 @@
Ex_Lob_Error ExLob::readStats(char *statsBuffer)
{
- memcpy(statsBuffer, (char *)&stats_, sizeof(stats_));
+ stats_ = (ExHdfsScanStats *)statsBuffer;
return LOB_OPER_OK;
}
Ex_Lob_Error ExLob::initStats()
{
- stats_.init();
return LOB_OPER_OK;
}
//Main driver of any LOB related operation
Ex_Lob_Error ExLobsOper (
char *lobName, // lob name
-
+ ExHdfsScanStats *hdfsAccessStats,
char *handleIn, // input handle (for cli calls)
Int32 handleInLen, // input handle len
@@ -2709,7 +2705,7 @@
if (it == lobMap->end())
{
- lobPtr = new (lobGlobals->getHeap())ExLob(lobGlobals->getHeap());
+ lobPtr = new (lobGlobals->getHeap())ExLob(lobGlobals->getHeap(), hdfsAccessStats);
if (lobPtr == NULL)
return LOB_ALLOC_ERROR;
@@ -2802,7 +2798,7 @@
if (it2 == lobMap->end())
{
- srcLobPtr = new (lobGlobals->getHeap())ExLob(lobGlobals->getHeap());
+ srcLobPtr = new (lobGlobals->getHeap())ExLob(lobGlobals->getHeap(), hdfsAccessStats);
if (srcLobPtr == NULL)
return LOB_ALLOC_ERROR;
@@ -3019,11 +3015,6 @@
lobDebugInfo("purgeLob failed ",err,__LINE__,lobGlobals->lobTrace_);
break;
- case Lob_Stats:
- err = lobPtr->readStats(source);
- lobPtr->initStats(); // because file may remain open across cursors
- break;
-
case Lob_Empty_Directory:
err = lobPtr->emptyDirectory(lobStorageLocation, lobGlobals);
@@ -3090,7 +3081,6 @@
*/
clock_gettime(CLOCK_MONOTONIC, &endTime);
-
secs = endTime.tv_sec - startTime.tv_sec;
nsecs = endTime.tv_nsec - startTime.tv_nsec;
if (nsecs < 0) {
@@ -3098,9 +3088,10 @@
nsecs += NUM_NSECS_IN_SEC;
}
totalnsecs = (secs * NUM_NSECS_IN_SEC) + nsecs;
+/*
if (lobPtr && lobPtr->getStats())
lobPtr->getStats()->hdfsAccessLayerTime += totalnsecs;
-
+*/
return err;
}
@@ -3209,15 +3200,15 @@
buf->bytesUsed_ += bytesToCopy;
buf->bytesRemaining_ -= bytesToCopy;
}
- stats_.bytesPrefetched += bytesToCopy;
+ //stats_.bytesPrefetched += bytesToCopy;
operLen += bytesToCopy;
}
-
+/*
// update stats
stats_.bytesRead += operLen;
stats_.bytesToRead += tgtSize;
stats_.numReadReqs++;
-
+*/
return LOB_OPER_OK;
}
@@ -3262,7 +3253,7 @@
nsecs += NUM_NSECS_IN_SEC;
}
Int64 totalnsecs = (secs * NUM_NSECS_IN_SEC) + nsecs;
- stats_.cursorElapsedTime += totalnsecs;
+ //stats_.cursorElapsedTime += totalnsecs;
return LOB_OPER_OK;
}
@@ -3317,7 +3308,7 @@
cursor->lock_.unlock();
buf = new (getHeap()) ExLobCursorBuffer();
buf->data_ = (char *) (getHeap())->allocateMemory( cursor->bufMaxSize_);
- lobPtr->stats_.buffersUsed++;
+ //lobPtr->stats_.buffersUsed++;
}
size = min(cursor->bufMaxSize_, (cursor->maxBytes_ - cursor->bytesRead_));
if (buf->data_) {
@@ -3418,7 +3409,7 @@
// bytesRead = hdfsPread(fs_, fdData_, offset, tgt, bytesToCopy);
bytesRead = hdfsRead(fs_, fdData_, tgt, bytesToCopy);
- stats_.numHdfsReqs++;
+ //stats_.numHdfsReqs++;
if (bytesRead == -1) {
return LOB_DATA_READ_ERROR;
@@ -3441,10 +3432,11 @@
}
Int64 totalnsecs = (secs * NUM_NSECS_IN_SEC) + nsecs;
- stats_.CumulativeReadTime += totalnsecs;
+ //stats_.CumulativeReadTime += totalnsecs;
return LOB_OPER_OK;
}
+
void ExLobCursor::emptyPrefetchList(ExLobGlobals *lobGlobals)
{
ExLobCursor::bufferList_t::iterator c_it;
diff --git a/core/sql/exp/ExpLOBaccess.h b/core/sql/exp/ExpLOBaccess.h
index 416c3cc..4097d62 100644
--- a/core/sql/exp/ExpLOBaccess.h
+++ b/core/sql/exp/ExpLOBaccess.h
@@ -49,6 +49,8 @@
#include "Globals.h"
#include <seabed/ms.h>
#include <seabed/fs.h>
+#include "ex_stdh.h"
+#include "ExStats.h"
#ifdef LOB_DEBUG_STANDALONE
#define Int64 long long
#define Lng32 long
@@ -56,18 +58,10 @@
#endif
#define SQ_USE_HDFS 1
-
-
-
#include "hdfs.h"
-
-
-
-
using namespace std;
-
class ExLobGlobals;
// This class defines the request used to construct the message to send over
// to the mxlobsrvr process. It's currently not used. All lob functionailty is
@@ -149,6 +143,7 @@
Ex_Lob_Error ExLobsOper (
char *lobName, // lob name
+ ExHdfsScanStats *hdfsAccessStats, // Statistics for Lob access
char *handleIn, // input handle (for cli calls)
Int32 handleInLen, // input handle len
char *hdfsServer, // server where hdfs fs resides
@@ -394,7 +389,7 @@
{
public:
- ExLob(NAHeap * heap); // default constructor
+ ExLob(NAHeap * heap, ExHdfsScanStats *hdfsAccessStats); // default constructor
virtual ~ExLob(); // default desctructor
void setUseLibHdfs(NABoolean useLibHdfs)
@@ -490,7 +485,7 @@
Ex_Lob_Error emptyDirectory(char* dirPath, ExLobGlobals* lobGlobals);
- ExLobStats *getStats() { return &stats_; }
+ ExHdfsScanStats *getStats() { return stats_; }
NAHeap *getLobGlobalHeap() { return lobGlobalHeap_;}
Ex_Lob_Error getLength(char *handleIn, Int32 handleInLen,Int64 &outLobLen,LobsSubOper so, Int64 transId);
Ex_Lob_Error getOffset(char *handleIn, Int32 handleInLen,Int64 &outOffset,LobsSubOper so, Int64 transId);
@@ -515,7 +510,7 @@
hdfsFS fs_;
hdfsFile fdData_;
int openFlags_;
- ExLobStats stats_;
+ ExHdfsScanStats *stats_;
bool prefetchQueued_;
NAHeap *lobGlobalHeap_;
NABoolean lobTrace_;
diff --git a/core/sql/exp/ExpLOBenums.h b/core/sql/exp/ExpLOBenums.h
index 9729cbc..4d140a2 100644
--- a/core/sql/exp/ExpLOBenums.h
+++ b/core/sql/exp/ExpLOBenums.h
@@ -249,8 +249,6 @@
Lob_Drop,
Lob_Check_Status,
- Lob_Stats,
-
Lob_Print, // debugging purposes
Lob_Empty_Directory,
diff --git a/core/sql/exp/ExpLOBinterface.cpp b/core/sql/exp/ExpLOBinterface.cpp
index 93035ed..3320a83 100644
--- a/core/sql/exp/ExpLOBinterface.cpp
+++ b/core/sql/exp/ExpLOBinterface.cpp
@@ -47,6 +47,7 @@
Int32 dummyParam2 = 0;
err = ExLobsOper((char*)"dummy",
+ NULL,
NULL, 0,
NULL, 0,
NULL, dummyParam2, 0, dummyParam,
@@ -104,6 +105,7 @@
Int64 cliError = -1;
Int32 dummyParam2 = 0;
err = ExLobsOper(lobName,
+ NULL, // ExHdfsScanStats *
NULL, 0,
hdfsServer, hdfsPort,
NULL, dummyParam2, 0, dummyParam,
@@ -132,6 +134,7 @@
Int64 cliError = -1;
Int32 dummyParam2 = 0;
err = ExLobsOper(lobName,
+ NULL, // ExHdfsScanStats *
NULL, 0,
hdfsServer, hdfsPort,
NULL, dummyParam2, 0, dummyParam,
@@ -159,6 +162,7 @@
Int64 cliError = -1;
Int32 dummyParam2 = 0;
err = ExLobsOper(lobName,
+ NULL, // ExHdfsScanStats *
NULL, 0,
hdfsServer, hdfsPort,
NULL, dummyParam2, 0, dummyParam,
@@ -186,6 +190,7 @@
Int64 cliError = -1;
Int32 dummyParam2 = 0;
err = ExLobsOper((char *)"dummy",
+ NULL, // ExHdfsScanStats *
NULL, 0,
NULL, 0,
NULL, dummyParam2, 0, dummyParam,
@@ -224,6 +229,7 @@
Int64 cliError = -1;
err = ExLobsOper(lobName,
+ NULL, // ExHdfsScanStats *
NULL, 0,
lobHdfsServer, lobHdfsPort,
NULL, dummyParam2, 0, dummyParam,
@@ -279,6 +285,7 @@
*(Lng32*)&blackBox[sizeof(modTS)+sizeof(numOfPartLevels)] = failedLocBufLen;
failedModTS = -1;
err = ExLobsOper((char*)"",
+ NULL, // ExHdfsScanStats *
NULL, 0,
lobHdfsServer, lobHdfsPort,
NULL, dummyParam2,
@@ -338,6 +345,7 @@
Int64 cliError = -1;
err = ExLobsOper(lobName,
+ NULL, // ExHdfsScanStats *
NULL, 0,
lobHdfsServer, lobHdfsPort,
NULL, dummyParam2, 0, dummyParam,
@@ -371,6 +379,7 @@
Int64 cliError = -1;
err = ExLobsOper(lobName,
+ NULL, // ExHdfsScanStats *
NULL, 0,
lobHdfsServer, lobHdfsPort,
NULL, dummyParam2, 0, dummyParam,
@@ -403,6 +412,7 @@
err = ExLobsOper(lobName,
+ NULL, // ExHdfsScanStats *
NULL,0,
NULL, 0,
NULL, dummyParam2, 0, dummyParam,
@@ -424,6 +434,7 @@
}
Lng32 ExpLOBinterfaceCloseFile(ExLobGlobals * exLobGlob,
+ ExHdfsScanStats *hdfsAccessStats,
char * lobName,
char * lobLoc,
Lng32 lobType,
@@ -440,6 +451,7 @@
LobsStorage ls = (LobsStorage)lobType;
err = ExLobsOper(lobName,
+ hdfsAccessStats,
NULL, 0,
lobHdfsServer, lobHdfsPort,
NULL, dummyParam2, 0, dummyParam,
@@ -463,6 +475,7 @@
Lng32 ExpLOBInterfaceInsert(ExLobGlobals * exLobGlob,
+ ExHdfsScanStats *hdfsAccessStats,
char * tgtLobName,
char * lobStorageLocation,
Lng32 lobType,
@@ -518,6 +531,7 @@
// Int64 lobLen = (tgtLobLen ? *tgtLobLen : 0);
err = ExLobsOper(tgtLobName,
+ hdfsAccessStats,
lobHandle, handleLen,
lobHdfsServer, lobHdfsPort,
outLobHandle, *outHandleLen,
@@ -560,6 +574,7 @@
}
Lng32 ExpLOBInterfaceInsertSelect(ExLobGlobals * exLobGlob,
+ ExHdfsScanStats *hdfsAccessStats,
char * lobHdfsServer ,
Lng32 lobHdfsPort ,
char * tgtLobName,
@@ -594,6 +609,7 @@
LobsStorage ls = (LobsStorage)lobType;
err = ExLobsOper(tgtLobName,
+ hdfsAccessStats,
lobHandle, handleLen,
lobHdfsServer, lobHdfsPort,
outLobHandle, *outHandleLen,
@@ -627,6 +643,7 @@
}
Lng32 ExpLOBInterfaceUpdateAppend(ExLobGlobals * exLobGlob,
+ ExHdfsScanStats *hdfsAccessStats,
char * lobHdfsServer ,
Lng32 lobHdfsPort ,
char * tgtLobName,
@@ -640,7 +657,6 @@
Lng32 checkStatus,
Lng32 waitedOp,
LobsSubOper so,
-
Int64 &tgtDescSyskey,
Int64 tgtLobLen,
char * srcLobData,
@@ -667,6 +683,7 @@
else if ((so == Lob_Buffer) || (so == Lob_Memory))
srcLen = tgtLobLen;
err = ExLobsOper(tgtLobName,
+ hdfsAccessStats,
lobHandle, handleLen,
lobHdfsServer, lobHdfsPort, // hdfs server/port
outLobHandle, *outHandleLen,
@@ -697,9 +714,9 @@
}
Lng32 ExpLOBInterfaceUpdate(ExLobGlobals * exLobGlob,
+ ExHdfsScanStats *hdfsAccessStats,
char * lobHdfsServer ,
Lng32 lobHdfsPort,
-
char * tgtLobName,
char * lobStorageLocation,
Lng32 handleLen,
@@ -711,7 +728,6 @@
Lng32 checkStatus,
Lng32 waitedOp,
LobsSubOper so,
-
Int64 &tgtDescSyskey,
Int64 tgtLobLen,
char * srcLobData,
@@ -738,6 +754,7 @@
sourceLen = tgtLobLen;
err = ExLobsOper(tgtLobName,
+ hdfsAccessStats,
lobHandle, handleLen,
lobHdfsServer, lobHdfsPort, // hdfs server/port
outLobHandle, *outHandleLen,
@@ -770,10 +787,11 @@
}
Lng32 ExpLOBInterfaceDelete(ExLobGlobals * exLobGlob,
+ ExHdfsScanStats *hdfsAccessStats,
char * lobHdfsServer ,
Lng32 lobHdfsPort ,
char * lobName,
- char * lobLoc,
+ char * lobLoc,
Lng32 handleLen,
char * lobHandle,
Int64 &requestTag,
@@ -799,6 +817,7 @@
}
err = ExLobsOper(lobName,
+ hdfsAccessStats,
lobHandle, handleLen,
lobHdfsServer, lobHdfsPort, // hdfs server/port
NULL, dummyParam2,
@@ -829,12 +848,12 @@
}
Lng32 ExpLOBInterfaceSelect(ExLobGlobals * exLobGlob,
+ ExHdfsScanStats *hdfsAccessStats,
char * lobName,
char * lobLoc,
Lng32 lobType,
char * lobHdfsServer,
Lng32 lobHdfsPort,
-
Lng32 handleLen,
char * lobHandle,
Int64 &requestTag,
@@ -871,6 +890,7 @@
LobsStorage ls = (LobsStorage)lobType;
err = ExLobsOper(lobName,
+ hdfsAccessStats,
lobHandle, handleLen,
lobHdfsServer, lobHdfsPort,
NULL, dummyParam2,
@@ -906,6 +926,7 @@
}
Lng32 ExpLOBInterfaceSelectCursor(ExLobGlobals * exLobGlob,
+ ExHdfsScanStats *hdfsAccessStats,
char * lobName,
char * lobLoc,
Lng32 lobType,
@@ -971,6 +992,7 @@
LobsStorage ls = (LobsStorage)lobType;
err = ExLobsOper(lobName,
+ hdfsAccessStats,
lobHandle, handleLen,
lobHdfsServer, lobHdfsPort,
NULL, dummyParam2,
@@ -1026,6 +1048,7 @@
else
so = Lob_Buffer;
err = ExLobsOper(lobName,
+ NULL, // ExHdfsScanStats *
lobHandle, handleLen,
lobHdfsServer, lobHdfsPort,
NULL, dummyParam2,
@@ -1084,6 +1107,7 @@
else
so = Lob_Buffer;
err = ExLobsOper(lobName,
+ NULL, // ExHdfsScanStats *
lobHandle, handleLen,
lobHdfsServer, lobHdfsPort,
NULL, dummyParam2,
@@ -1139,6 +1163,7 @@
else
so = Lob_Buffer;
err = ExLobsOper(lobName,
+ NULL, // ExHdfsScanStats *
lobHandle, handleLen,
lobHdfsServer, lobHdfsPort,
NULL, dummyParam2,
@@ -1166,41 +1191,6 @@
return LOB_ACCESS_SUCCESS;
}
-Lng32 ExpLOBinterfaceStats(
- ExLobGlobals * exLobGlob,
- ExLobStats * lobStats,
- char * lobName, char * lobLoc,
- Lng32 lobType,
- char * lobHdfsServer,
- Lng32 lobHdfsPort)
-{
- Ex_Lob_Error err;
-
- Int64 dummyParam= 0;
- Int32 dummyParam2 = 0;
- Ex_Lob_Error status;
- Int64 cliError = -1;
-
- err = ExLobsOper(lobName,
- NULL, 0,
- lobHdfsServer, lobHdfsPort,
- NULL, dummyParam2, 0, dummyParam,
- dummyParam, 0, dummyParam, status, cliError,
- lobLoc, (LobsStorage)lobType,
- (char*)lobStats, 0,
- 0,NULL,
- Lob_Stats,
- Lob_None,
- 1, // waited op
- exLobGlob,
- 0, NULL, 0
- );
-
- if (err != LOB_OPER_OK)
- return -err;
- else
- return 0;
-}
char * getLobErrStr(Lng32 errEnum)
{
diff --git a/core/sql/exp/ExpLOBinterface.h b/core/sql/exp/ExpLOBinterface.h
index 54435a3..32ae777 100644
--- a/core/sql/exp/ExpLOBinterface.h
+++ b/core/sql/exp/ExpLOBinterface.h
@@ -26,6 +26,8 @@
#include "NAVersionedObject.h"
#include "ComQueue.h"
#include "ex_globals.h"
+#include "ExStats.h"
+
class HdfsFileInfo
{
public:
@@ -116,12 +118,15 @@
char * lobLoc);
Lng32 ExpLOBinterfaceCloseFile(ExLobGlobals * lobGlob,
+ ExHdfsScanStats *hdfsAccessStats,
char * lobName,
char * lobLoc,
Lng32 lobType,
char * lobHdfsServer ,
Lng32 lobHdfsPort );
+
Lng32 ExpLOBInterfaceInsertSelect(ExLobGlobals * exLobGlob,
+ ExHdfsScanStats *hdfsAccessStats,
char * lobHdfsServer ,
Lng32 lobHdfsPort ,
char * tgtLobName,
@@ -146,6 +151,7 @@
);
Lng32 ExpLOBInterfaceInsert(ExLobGlobals * lobGlob,
+ ExHdfsScanStats *hdfsAccessStats,
char * tgtLobName,
char * lobLocation,
Lng32 lobType,
@@ -182,6 +188,7 @@
);
Lng32 ExpLOBInterfaceUpdate(ExLobGlobals * lobGlob,
+ ExHdfsScanStats *hdfsAccessStats,
char * lobHdfsServer ,
Lng32 lobHdfsPort,
char * tgtLobName,
@@ -212,6 +219,7 @@
Int64 lobGCLimit = 0);
Lng32 ExpLOBInterfaceUpdateAppend(ExLobGlobals * lobGlob,
+ ExHdfsScanStats *hdfsAccessStats,
char * lobHdfsServer ,
Lng32 lobHdfsPort ,
char * tgtLobName,
@@ -243,6 +251,7 @@
);
Lng32 ExpLOBInterfaceDelete(ExLobGlobals * lobGlob,
+ ExHdfsScanStats *hdfsAccessStats,
char * lobHdfsServer ,
Lng32 lobHdfsPort ,
char * lobName,
@@ -256,6 +265,7 @@
Lng32 waitedOp);
Lng32 ExpLOBInterfaceSelect(ExLobGlobals * lobGlob,
+ ExHdfsScanStats *hdfsAccessStats,
char * lobName,
char * lobLoc,
Lng32 lobType,
@@ -276,6 +286,7 @@
Int32 inputFlags=0);
Lng32 ExpLOBInterfaceSelectCursor(ExLobGlobals * lobGlob,
+ ExHdfsScanStats *hdfsAccessStats,
char * lobName,
char * lobLoc,
Lng32 lobType,
@@ -299,14 +310,6 @@
Int32 *hdfsDetailError = NULL
);
-Lng32 ExpLOBinterfaceStats(ExLobGlobals * lobGlob,
- ExLobStats * lobStats,
- char * lobName,
- char * lobLoc,
- Lng32 lobType = (Lng32)Lob_HDFS_File,
- char * lobHdfsServer = (char *)"default",
- Lng32 lobHdfsPort = 0);
-
char * getLobErrStr(Lng32 errEnum);
Lng32 ExpLOBinterfacePerformGC(ExLobGlobals *& lobGlob, char *lobName,void *descChunksArray, Int32 numEntries, char *hdfsServer, Int32 hdfsPort,char *LOBlOC,Int64 lobMaxChunkMemSize);
diff --git a/core/sql/exp/ExpLOBprocess.cpp b/core/sql/exp/ExpLOBprocess.cpp
index e117160..190be7e 100644
--- a/core/sql/exp/ExpLOBprocess.cpp
+++ b/core/sql/exp/ExpLOBprocess.cpp
@@ -485,10 +485,6 @@
return LOB_OPER_OK;
}
-
-
-
-
Ex_Lob_Error ExLobGlobals::getLobPtr(char *lobName, ExLob *& lobPtr)
{
Ex_Lob_Error err;
@@ -500,7 +496,7 @@
if (it == lobMap->end())
{
- lobPtr = new (lobGlobals->getHeap())ExLob(lobGlobals->getHeap());
+ lobPtr = new (lobGlobals->getHeap())ExLob(lobGlobals->getHeap(),NULL);
if (lobPtr == NULL)
return LOB_ALLOC_ERROR;
diff --git a/core/sql/exp/exp_clause.h b/core/sql/exp/exp_clause.h
index ad51e4f..3f785ef 100644
--- a/core/sql/exp/exp_clause.h
+++ b/core/sql/exp/exp_clause.h
@@ -542,6 +542,11 @@
globals_ = glob;
}
+ void setTcb(const ex_tcb *tcb)
+ {
+ tcb_ = (ex_tcb *)tcb;
+ }
+
Int16 getInstrArrayIndex() { return instrArrayIndex_; }
void setInstrArrayIndex(Int16 index) { instrArrayIndex_ = index; }
@@ -550,6 +555,11 @@
{
return globals_;
}
+
+ ex_tcb *getTcb()
+ {
+ return tcb_;
+ }
private:
ExClausePtr nextClause_; // 00-07
@@ -585,13 +595,14 @@
// Not valid for EID expressions.
// Only used for SQ.
ExGlobalsPtr globals_; // 40-47
-
+
+ ex_tcb *tcb_; // 48-55
// ---------------------------------------------------------------------
// Fillers for potential future extensions without changing class size.
// When a new member is added, size of this filler should be reduced so
// that the size of the object remains the same (and is modulo 8).
// ---------------------------------------------------------------------
- char fillers_[16]; // 52-63
+ char fillers_[8]; // 56-63
};
diff --git a/core/sql/exp/exp_fixup.cpp b/core/sql/exp/exp_fixup.cpp
index 479ff44..c2cb36c 100644
--- a/core/sql/exp/exp_fixup.cpp
+++ b/core/sql/exp/exp_fixup.cpp
@@ -228,7 +228,7 @@
return retcode;
clause->setExeGlobals(glob);
-
+ clause->setTcb(tcb);
clause = clause->getNextClause();
}
diff --git a/core/sql/generator/GenExplain.cpp b/core/sql/generator/GenExplain.cpp
index f766873..da9e873 100644
--- a/core/sql/generator/GenExplain.cpp
+++ b/core/sql/generator/GenExplain.cpp
@@ -958,60 +958,60 @@
description += "small_scanner: " ;
description += "ON " ;
}
- size_t BUFFER_SIZE=512;
- char buf[BUFFER_SIZE];
+ size_t TMP_BUFFER_SIZE=512;
+ char buf[TMP_BUFFER_SIZE];
if ((((ComTdbHbaseAccess *)tdb)->getHbasePerfAttributes()->dopParallelScanner())>0.0) {
description += "parallel_scanner: " ;
- snprintf(buf, BUFFER_SIZE, "%g ", ((ComTdbHbaseAccess *)tdb)->getHbasePerfAttributes()->dopParallelScanner());
+ snprintf(buf, TMP_BUFFER_SIZE, "%g ", ((ComTdbHbaseAccess *)tdb)->getHbasePerfAttributes()->dopParallelScanner());
description += buf;
}
if ( getProbes().getValue() > 0.0 ) {
description += "probes: "; // total number of probes
- snprintf(buf, BUFFER_SIZE, "%g ", getProbes().getValue());
+ snprintf(buf, TMP_BUFFER_SIZE, "%g ", getProbes().getValue());
description += buf;
}
if ( getSuccessfulProbes().getValue() > 0.0 ) {
description += "successful_probes: "; // # of probes returning data
- snprintf(buf, BUFFER_SIZE, "%g ", getSuccessfulProbes().getValue());
+ snprintf(buf, TMP_BUFFER_SIZE, "%g ", getSuccessfulProbes().getValue());
description += buf;
}
if ( getUniqueProbes().getValue() > 0.0 ) {
description += "unique_probes: "; // # of probes returning 1 row
- snprintf(buf, BUFFER_SIZE, "%g ", getUniqueProbes().getValue());
+ snprintf(buf, TMP_BUFFER_SIZE, "%g ", getUniqueProbes().getValue());
description += buf;
}
if ( getDuplicatedSuccProbes().getValue() > 0.0 ) {
description += "duplicated_succ_probes: "; // # of succ probes returning
- snprintf(buf, BUFFER_SIZE, "%g ", getDuplicatedSuccProbes().getValue()); // more than 1 row
+ snprintf(buf, TMP_BUFFER_SIZE, "%g ", getDuplicatedSuccProbes().getValue()); // more than 1 row
description += buf;
}
if ( getEstRowsAccessed().getValue() ) {
description += "rows_accessed: "; // # rows accessed
- snprintf(buf, BUFFER_SIZE, "%g ", getEstRowsAccessed().getValue());
+ snprintf(buf, TMP_BUFFER_SIZE, "%g ", getEstRowsAccessed().getValue());
description += buf;
}
if (((ComTdbHbaseAccess *)tdb)->getHbaseSnapshotScanAttributes()->getUseSnapshotScan())
{
description += "use_snapshot_scan: ";
- snprintf(buf, BUFFER_SIZE, "%s ", "TRUE" );
+ snprintf(buf, TMP_BUFFER_SIZE, "%s ", "TRUE" );
description += buf;
description += "full_table_name: ";
- snprintf(buf, BUFFER_SIZE, "%s ", ((ComTdbHbaseAccess *)tdb)->getTableName());
+ snprintf(buf, TMP_BUFFER_SIZE, "%s ", ((ComTdbHbaseAccess *)tdb)->getTableName());
description += buf;
description += "snapshot_name: ";
- snprintf(buf, BUFFER_SIZE, "%s ", ((ComTdbHbaseAccess *)tdb)->getHbaseSnapshotScanAttributes()->getSnapshotName());
+ snprintf(buf, TMP_BUFFER_SIZE, "%s ", ((ComTdbHbaseAccess *)tdb)->getHbaseSnapshotScanAttributes()->getSnapshotName());
description += buf;
description += "snapshot_temp_location: ";
- snprintf(buf, BUFFER_SIZE, "%s ", ((ComTdbHbaseAccess *)tdb)->getHbaseSnapshotScanAttributes()->getSnapScanTmpLocation());
+ snprintf(buf, TMP_BUFFER_SIZE, "%s ", ((ComTdbHbaseAccess *)tdb)->getHbaseSnapshotScanAttributes()->getSnapScanTmpLocation());
description += buf;
}
@@ -1036,7 +1036,7 @@
// now get columns_retrieved
description += "columns_retrieved: ";
//sprintf(buf, "%d ", retrievedCols().entries());
- snprintf(buf, BUFFER_SIZE, "%d ", getIndexDesc()->getIndexColumns().entries());
+ snprintf(buf, TMP_BUFFER_SIZE, "%d ", getIndexDesc()->getIndexColumns().entries());
description += buf;
*/
diff --git a/core/sql/generator/GenPreCode.cpp b/core/sql/generator/GenPreCode.cpp
index 6968b96..88edc4b 100644
--- a/core/sql/generator/GenPreCode.cpp
+++ b/core/sql/generator/GenPreCode.cpp
@@ -12370,3 +12370,39 @@
// Done.
return this;
}
+
+ItemExpr * SplitPart::preCodeGen(Generator *generator)
+{
+ if (nodeIsPreCodeGenned())
+ return this;
+
+ child(0) = child(0)->preCodeGen(generator);
+ if (! child(0).getPtr())
+ return NULL;
+
+ child(1) = child(1)->preCodeGen(generator);
+ if (! child(1).getPtr())
+ return NULL;
+
+ for (Int32 i = 2; i < getArity(); i++)
+ {
+ if (child(i))
+ {
+ const NAType &typ1 = child(i)->getValueId().getType();
+
+ //Insert a cast node to convert child to an INT.
+ child(i) = new (generator->wHeap())
+ Cast(child(i), new (generator->wHeap()) SQLInt(generator->wHeap(), TRUE,
+ typ1.supportsSQLnullLogical()));
+
+ child(i)->bindNode(generator->getBindWA());
+ child(i) = child(i)->preCodeGen(generator);
+ if (! child(i).getPtr())
+ return NULL;
+
+ }
+ }
+
+ markAsPreCodeGenned();
+ return this;
+}
diff --git a/core/sql/optimizer/EncodedValue.cpp b/core/sql/optimizer/EncodedValue.cpp
index f05297a..f8c6b7b 100644
--- a/core/sql/optimizer/EncodedValue.cpp
+++ b/core/sql/optimizer/EncodedValue.cpp
@@ -648,8 +648,62 @@
void
EncodedValue::constructorFunction (const NAWchar * theValue,
const NAColumnArray &columns,
+ NABoolean okToReportErrors,
ConstValue* cvPtrs[])
{
+ // Some notes about error reporting for this function:
+ //
+ // The error reporting for this function is a little strange
+ // and should be re-engineered when we can imagine a better
+ // design for it.
+ //
+ // This function is called from two very different contexts.
+ //
+ // One is from the constructors of global objects, to provide
+ // convenient encoded constants. Being global objects, this
+ // call is made as a result of global constructor calls before
+ // the C++ main for the process is invoked. As such, we cannot
+ // depend on other global objects being constructed. So, for
+ // example, we cannot depend on CmpCommon::diags() being
+ // initialized, as C++ makes no guarantees about the order in
+ // which global objects are created. Too, it does no good to
+ // throw a C++ exception as there would be nothing to catch it
+ // and process it. So, if an error happens in this code path,
+ // we'll simply assert.
+ //
+ // The other is in the course of histogram processing. Histograms
+ // have been read in, and now we want to encode the boundary
+ // values in the histogram. These might be stale or corrupted
+ // so that condition has to be detected. When detected, this
+ // routine raises a warning in CmpCommon::diags(), and then
+ // throws a C++ exception.
+ //
+ // This warning processing has to be done carefully. The way
+ // it works is that lower level routines report errors into
+ // CmpCommon::diags(). This routine checks for such errors and
+ // if it sees any, it throws them away, replacing them with
+ // a warning in CmpCommon::diags(). It then throws a C++
+ // exception which is typically caught by HSHistogrmCursor::fetch
+ // (ustat/hs_read.cpp). We use default histograms in that case.
+ //
+ // Why do we throw away the errors? We do this because of the
+ // way the Normalizer handles CmpCommon::diags(). During
+ // synthesise logical properties processing, histograms may
+ // be read and processed. (Note: They can be read and processed
+ // from other phases as well, such as table analysis.) The
+ // Normalizer checks for errors in CmpCommon::diags(), and if
+ // found, retries compilation. On the retry, CmpCommon::diags()
+ // will be cleared, and the histograms code will simply use
+ // a default histogram. So, if there is any error in
+ // CmpCommon::diags(), we will lose the histogram warnings
+ // generated in this method.
+ //
+ // Note that if there is already an error in CmpCommon::diags()
+ // when this method is called, we'll lose the histogram warnings
+ // anyway. Sigh.
+
+ Lng32 mark = okToReportErrors ? CmpCommon::diags()->mark() : -1;
+
// Find the first non-blank char.
const NAWchar *item = theValue;
while (*item == L' ')
@@ -657,10 +711,17 @@
if ( *item != L'(' ) // must be '('
{
- *CmpCommon::diags() << DgSqlCode(CATALOG_HISTOGRM_HISTINTS_TABLES_CONTAIN_BAD_VALUE)
+ if (okToReportErrors)
+ {
+ *CmpCommon::diags() << DgSqlCode(CATALOG_HISTOGRM_HISTINTS_TABLES_CONTAIN_BAD_VALUE)
<< DgWString0(theValue)
<< DgString1(columns[0]->getFullColRefNameAsAnsiString());
- CmpInternalException("Bad Interval Boundary", __FILE__ , __LINE__).throwException();
+ CmpInternalException("Bad Interval Boundary", __FILE__ , __LINE__).throwException();
+ }
+ else
+ {
+ CMPASSERT(FALSE); // developer needs to fix the bug
+ }
}
item++;
@@ -766,11 +827,19 @@
if ( next == NULL ) // should never happen!
{
- *CmpCommon::diags()
+ if (okToReportErrors)
+ {
+ CmpCommon::diags()->rewind(mark,TRUE); // get rid of any diags we may have added
+ *CmpCommon::diags()
<< DgSqlCode(CATALOG_HISTOGRM_HISTINTS_TABLES_CONTAIN_BAD_VALUE)
<< DgWString0(theValue)
<< DgString1(columns[i]->getFullColRefNameAsAnsiString());
- CmpInternalException("Bad Interval Boundary", __FILE__ , __LINE__).throwException();
+ CmpInternalException("Bad Interval Boundary", __FILE__ , __LINE__).throwException();
+ }
+ else
+ {
+ CMPASSERT(FALSE); // developer needs to fix the bug
+ }
}
Lng32 len = BOUNDARY_LEN;
@@ -803,6 +872,10 @@
break;
}
+ // Parser assumes CmpCommon::diags() is initialized and available
+ // so okToReportErrors better be true in this code path.
+ CMPASSERT(okToReportErrors);
+
// invoke parser to parse the char string and generate a ConstValue
Parser parser(CmpCommon::context());
@@ -863,9 +936,7 @@
(entries == 1 &&
constVal->getType()->getTypeQualifier() != colType->getTypeQualifier()))
{
- if (CmpCommon::diags()->getNumber(DgSqlCode::ERROR_))
- CmpCommon::diags()->deleteError(0);
-
+ CmpCommon::diags()->rewind(mark,TRUE); // get rid of any diags parser may have added
*CmpCommon::diags()
<< DgSqlCode(CATALOG_HISTOGRM_HISTINTS_TABLES_CONTAIN_BAD_VALUE)
<< DgWString0(theValue)
diff --git a/core/sql/optimizer/EncodedValue.h b/core/sql/optimizer/EncodedValue.h
index 961adeb..4bc5e84 100644
--- a/core/sql/optimizer/EncodedValue.h
+++ b/core/sql/optimizer/EncodedValue.h
@@ -165,24 +165,27 @@
// construct a multi-attribute value given a string representation
// of the multi-attribute value, and a description of the columns
+
+ // Note: This constructor is used to construct global objects, so
+ // it cannot report errors.
EncodedValue (const NAWchar *theValue)
: valueList_(NULL), heap_(HISTHEAP)
{
const NAColumnArray empty ((CollHeap*) 0 /* NULL CollHeap* */) ;
- constructorFunction (theValue, empty) ;
+ constructorFunction (theValue, empty, FALSE) ;
}
EncodedValue (const wchar_t *theValue, const NAColumnArray &columns,
ConstValue* cvPtrs[] = NULL)
: valueList_(NULL), heap_(HISTHEAP)
- { constructorFunction (theValue, columns, cvPtrs) ; }
+ { constructorFunction (theValue, columns, TRUE, cvPtrs) ; }
EncodedValue (const NAWchar *theValue, const NAColumn * column)
: valueList_(NULL), heap_(HISTHEAP)
{
NAColumnArray columns ;
columns.insertAt (0,(NAColumn*)(column)) ;
- constructorFunction (theValue, columns) ;
+ constructorFunction (theValue, columns, TRUE) ;
}
EncodedValue (const EncodedValue & other, NAMemory * h = 0);
@@ -192,7 +195,7 @@
// thing, I've created a non-ctor function that both of them
// call. Sooner or later we can stop using the ctor that takes
// a NAColumnArray as its parameter ...
- void constructorFunction (const wchar_t * theValue, const NAColumnArray & columns, ConstValue** cvPtr = NULL) ;
+ void constructorFunction (const wchar_t * theValue, const NAColumnArray & columns, NABoolean okToReportErrors, ConstValue** cvPtr = NULL) ;
public:
// construct a single-attribute value from a constant or list of constants
diff --git a/core/sql/optimizer/ItemFunc.h b/core/sql/optimizer/ItemFunc.h
index 0dd901e..249c09b 100644
--- a/core/sql/optimizer/ItemFunc.h
+++ b/core/sql/optimizer/ItemFunc.h
@@ -5859,6 +5859,7 @@
virtual ItemExpr * copyTopNode(ItemExpr *derivedNode = NULL,
CollHeap *outheap = 0);
+ virtual ItemExpr * preCodeGen(Generator*);
}; //class SplitPart
#endif /* ITEMFUNC_H */
diff --git a/core/sql/pom.xml b/core/sql/pom.xml
index 7b143d9..6059d81 100644
--- a/core/sql/pom.xml
+++ b/core/sql/pom.xml
@@ -24,6 +24,10 @@
<id>cloudera</id>
<url>https://repository.cloudera.com/artifactory/cloudera-repos/</url>
</repository>
+ <repository>
+ <id>central</id>
+ <url>http://central.maven.org/maven2/</url>
+ </repository>
</repositories>
<properties>
diff --git a/core/sql/regress/core/EXPECTED038.LINUX b/core/sql/regress/core/EXPECTED038.LINUX
index aceb087..6fcb4e6 100644
--- a/core/sql/regress/core/EXPECTED038.LINUX
+++ b/core/sql/regress/core/EXPECTED038.LINUX
@@ -4723,6 +4723,11 @@
--- 4 row(s) selected.
+>>select split_part('sa:sbl:sc', ':', -4) from t038sf;
+
+*** ERROR[8691] Field position must be greater than zero, currently is -4.
+
+--- 0 row(s) selected.
>>
>>insert into T038sf values(110, 'a/b/c', 'sa/dsd/s');
diff --git a/core/sql/regress/core/FILTERRTS b/core/sql/regress/core/FILTERRTS
index 3832ed8..336b16a 100755
--- a/core/sql/regress/core/FILTERRTS
+++ b/core/sql/regress/core/FILTERRTS
@@ -113,4 +113,5 @@
/pertableStats/{N
s/pertableStats\n[0-9 ,]*/@pertableStats@/
}
+s/pertableStats[0-9 ,()|a-z]*/@pertableStats@/
" $fil
diff --git a/core/sql/regress/core/TEST038 b/core/sql/regress/core/TEST038
index 593822e..cad203e 100755
--- a/core/sql/regress/core/TEST038
+++ b/core/sql/regress/core/TEST038
@@ -1148,6 +1148,7 @@
-- **EMPTY RESULT**
select split_part('sa:sbl:sc', ':', 0) from t038sf;
select split_part('sa:sbl:sc', ':', 4) from t038sf;
+select split_part('sa:sbl:sc', ':', -4) from t038sf;
insert into T038sf values(110, 'a/b/c', 'sa/dsd/s');
insert into T038sf values(111, 'sasd', 'dsa:/~sd');
diff --git a/core/sql/regress/executor/EXPECTED130 b/core/sql/regress/executor/EXPECTED130
index 8f97dad..7ad8bbf 100644
--- a/core/sql/regress/executor/EXPECTED130
+++ b/core/sql/regress/executor/EXPECTED130
@@ -1596,8 +1596,7 @@
TLOB130TS2
=======================
-Summary info of get:
-Get 7 rows.
+ 7 row(s) returned
--- SQL operation complete.
>>drop schema trafodion.lobsch cascade;
diff --git a/core/sql/regress/privs2/EXPECTED144 b/core/sql/regress/privs2/EXPECTED144
index f9e0d8e..f3127e0 100644
--- a/core/sql/regress/privs2/EXPECTED144
+++ b/core/sql/regress/privs2/EXPECTED144
Binary files differ
diff --git a/core/sql/regress/privs2/EXPECTED146 b/core/sql/regress/privs2/EXPECTED146
index 66c4fd3..0752634 100644
--- a/core/sql/regress/privs2/EXPECTED146
+++ b/core/sql/regress/privs2/EXPECTED146
@@ -1611,7 +1611,7 @@
SIDU-R- TRAFODION._HB_MAP_.T146T2
=======================
- 6 row(s) returned
+ 8 row(s) returned
--- SQL operation complete.
>>
@@ -1753,7 +1753,7 @@
SIDU-R- TRAFODION._HB_MAP_.T146T2
=======================
- 6 row(s) returned
+ 8 row(s) returned
--- SQL operation complete.
>>
@@ -1772,7 +1772,7 @@
SIDU-R- TRAFODION._HB_MAP_.T146T1
=======================
- 4 row(s) returned
+ 5 row(s) returned
--- SQL operation complete.
>>
diff --git a/core/sql/regress/seabase/EXPECTED012 b/core/sql/regress/seabase/EXPECTED012
index 66c882b..c6acec1 100644
--- a/core/sql/regress/seabase/EXPECTED012
+++ b/core/sql/regress/seabase/EXPECTED012
@@ -290,8 +290,7 @@
T012T12
=======================
-Summary info of get:
-Get 5 rows.
+ 5 row(s) returned
--- SQL operation complete.
>>get indexes in schema trafodion.zschema;
@@ -305,8 +304,7 @@
T012T11I2
=======================
-Summary info of get:
-Get 4 rows.
+ 4 row(s) returned
--- SQL operation complete.
>>get views in schema trafodion.zschema;
@@ -317,8 +315,7 @@
T012T11V1
=======================
-Summary info of get:
-Get 1 rows.
+ 1 row(s) returned
--- SQL operation complete.
>>
@@ -328,27 +325,12 @@
>>
>>get tables in schema trafodion.zschema;
-
-=======================
-Summary info of get:
-Get 0 rows.
-
--- SQL operation complete.
>>get indexes in schema trafodion.zschema;
-
-=======================
-Summary info of get:
-Get 0 rows.
-
--- SQL operation complete.
>>get views in schema trafodion.zschema;
-
-=======================
-Summary info of get:
-Get 0 rows.
-
--- SQL operation complete.
>>
>>obey TEST012(getStmts);
@@ -392,8 +374,7 @@
TRAFODION.ZSCHEMA2.T
=======================
-Summary info of get:
-Get 2 rows.
+ 2 row(s) returned
--- SQL operation complete.
>>get views on table zschema1.t;
@@ -405,8 +386,7 @@
TRAFODION.ZSCHEMA2.V
=======================
-Summary info of get:
-Get 2 rows.
+ 2 row(s) returned
--- SQL operation complete.
>>
@@ -418,8 +398,7 @@
TRAFODION.ZSCHEMA2.T
=======================
-Summary info of get:
-Get 1 rows.
+ 1 row(s) returned
--- SQL operation complete.
>>get all tables in view zschema2.v2;
@@ -431,8 +410,7 @@
TRAFODION.ZSCHEMA2.T
=======================
-Summary info of get:
-Get 2 rows.
+ 2 row(s) returned
--- SQL operation complete.
>>get views in view zschema2.v2;
@@ -443,8 +421,7 @@
TRAFODION.ZSCHEMA1.V
=======================
-Summary info of get:
-Get 1 rows.
+ 1 row(s) returned
--- SQL operation complete.
>>get all objects in view zschema2.v2;
@@ -456,10 +433,8 @@
TRAFODION.ZSCHEMA1.V
TRAFODION.ZSCHEMA2.T
-
=======================
-Summary info of get:
-Get 3 rows.
+ 3 row(s) returned
--- SQL operation complete.
>>
diff --git a/core/sql/regress/seabase/EXPECTED024 b/core/sql/regress/seabase/EXPECTED024
index 82212b8..25556ae 100644
--- a/core/sql/regress/seabase/EXPECTED024
+++ b/core/sql/regress/seabase/EXPECTED024
@@ -181,6 +181,9 @@
TEST024SEQ6
TEST024SEQ7
+=======================
+ 7 row(s) returned
+
--- SQL operation complete.
>>set schema seqsch;
diff --git a/core/sql/regress/seabase/EXPECTED027 b/core/sql/regress/seabase/EXPECTED027
index 67bcfd9..0972679 100644
--- a/core/sql/regress/seabase/EXPECTED027
+++ b/core/sql/regress/seabase/EXPECTED027
@@ -1176,6 +1176,9 @@
TRAFODION.SCH027.T027V1
+=======================
+ 1 row(s) returned
+
--- SQL operation complete.
>>invoke t027v1;
@@ -1249,6 +1252,9 @@
TRAFODION.SCH027.T027V1
+=======================
+ 1 row(s) returned
+
--- SQL operation complete.
>>
>>-- tests for alter column rename
@@ -1434,6 +1440,9 @@
TRAFODION.SCH027.T027V12
TRAFODION.SCH027.T027V122
+=======================
+ 5 row(s) returned
+
--- SQL operation complete.
>>alter table t027t7 alter column a varchar(20);
@@ -1449,6 +1458,9 @@
TRAFODION.SCH027.T027V12
TRAFODION.SCH027.T027V122
+=======================
+ 5 row(s) returned
+
--- SQL operation complete.
>>
>>-- some alter operations cannot be performed within a user xn
diff --git a/core/sql/ustat/hs_globals.cpp b/core/sql/ustat/hs_globals.cpp
index b033e65..d6069e8 100644
--- a/core/sql/ustat/hs_globals.cpp
+++ b/core/sql/ustat/hs_globals.cpp
@@ -3186,38 +3186,13 @@
DeleteHSContext(contID_);
}
+
// -----------------------------------------------------------------------
-//
+// Initialize stats schema for Hive or native HBase tables if needed
// -----------------------------------------------------------------------
-Lng32 HSGlobalsClass::Initialize()
+Lng32 HSGlobalsClass::InitializeStatsSchema()
{
Lng32 retcode = 0;
- NAString query;
- HSCursor cursor;
- Int64 xSampleSet = 0;
- char intStr[30], intStr2[30];
- Int64 inserts, deletes, updates;
- HSLogMan *LM = HSLogMan::Instance();
- HSGlobalsClass *hs_globals = GetHSContext();
-
- // Seed the random number generator used in quicksort().
- srand(time(NULL));
- // Set the default catalog names for Hive and HBase.
- if (defaultHiveCatName == NULL)
- defaultHiveCatName = new (GetCliGlobals()->exCollHeap()) NAString("");
- else
- (*defaultHiveCatName) = "";
-
- CmpCommon::getDefault(HIVE_CATALOG, (*defaultHiveCatName), FALSE);
- (*defaultHiveCatName).toUpper();
-
- if (defaultHbaseCatName == NULL)
- defaultHbaseCatName = new (GetCliGlobals()->exCollHeap()) NAString("");
- else
- (*defaultHbaseCatName) = "";
-
- CmpCommon::getDefault(HBASE_CATALOG, (*defaultHbaseCatName), FALSE);
- (*defaultHbaseCatName).toUpper();
/*==============================*/
/* CREATE HIVE STATS SCHEMA */
@@ -3260,6 +3235,47 @@
retcode = CreateHistTables(this);
HSHandleError(retcode);
+ return retcode;
+ }
+
+
+
+// -----------------------------------------------------------------------
+//
+// -----------------------------------------------------------------------
+Lng32 HSGlobalsClass::Initialize()
+ {
+ Lng32 retcode = 0;
+ NAString query;
+ HSCursor cursor;
+ Int64 xSampleSet = 0;
+ char intStr[30], intStr2[30];
+ Int64 inserts, deletes, updates;
+ HSLogMan *LM = HSLogMan::Instance();
+ HSGlobalsClass *hs_globals = GetHSContext();
+
+ // Seed the random number generator used in quicksort().
+ srand(time(NULL));
+ // Set the default catalog names for Hive and HBase.
+ if (defaultHiveCatName == NULL)
+ defaultHiveCatName = new (GetCliGlobals()->exCollHeap()) NAString("");
+ else
+ (*defaultHiveCatName) = "";
+
+ CmpCommon::getDefault(HIVE_CATALOG, (*defaultHiveCatName), FALSE);
+ (*defaultHiveCatName).toUpper();
+
+ if (defaultHbaseCatName == NULL)
+ defaultHbaseCatName = new (GetCliGlobals()->exCollHeap()) NAString("");
+ else
+ (*defaultHbaseCatName) = "";
+
+ CmpCommon::getDefault(HBASE_CATALOG, (*defaultHbaseCatName), FALSE);
+ (*defaultHbaseCatName).toUpper();
+
+ // initialize stats schema if this is a Hive or native HBase table
+ retcode = InitializeStatsSchema();
+ HSHandleError(retcode);
/*==============================*/
/* CREATE UNDOCUMENTED VIEW */
@@ -15973,6 +15989,10 @@
if (!hs_globals) retcode = -1;
else
{
+ // initialize stats schema if our object is a Hive or native HBase table
+ retcode = hs_globals->InitializeStatsSchema();
+ HSHandleError(retcode);
+
NAString table;
Int64 sampleRows, tableRows;
NABoolean isEstimate = FALSE;
diff --git a/core/sql/ustat/hs_globals.h b/core/sql/ustat/hs_globals.h
index ac05497..2f8f4f9 100644
--- a/core/sql/ustat/hs_globals.h
+++ b/core/sql/ustat/hs_globals.h
@@ -1472,6 +1472,9 @@
HSGlobalsClass(ComDiagsArea &diags);
~HSGlobalsClass();
+ // Intialize stats schema on demand
+ Lng32 InitializeStatsSchema();
+
//Process USTAT options
Lng32 Initialize();
diff --git a/docs/sql_reference/src/asciidoc/_chapters/sql_functions_and_expressions.adoc b/docs/sql_reference/src/asciidoc/_chapters/sql_functions_and_expressions.adoc
index b1bed39..7a76d09 100644
--- a/docs/sql_reference/src/asciidoc/_chapters/sql_functions_and_expressions.adoc
+++ b/docs/sql_reference/src/asciidoc/_chapters/sql_functions_and_expressions.adoc
@@ -4437,35 +4437,670 @@
EXTRACT (datetime-field FROM extract-source)
```
-* `_datetime-field_` is:
+[[extract_function_syntax]]
+=== Syntax Descriptions of Extract Function
+
+* `_datetime-field_` and `_extract-source_` are:
+
-YEAR \| MONTH \| DAY \| HOUR \| MINUTE \| SECOND
+.Details of `_datetime-field_` and `_extract-source_`
+[cols="20%,40%,40%"]
+|===
+^| `_datetime-filed_`
+^| *Description*
+^| *Supported* `_extract-source_`
+
+a| CENTURY
+| Century.
+a| * `_datetime-expression_`
+** DATE
+** TIMESTAMP
+
+| DAY
+a| * `_datetime-expression_` +
+Day.
+* `_interval-expression_` +
+Number of day(s) in the `_interval-expression_`. +
+a| * `_datetime-expression_`
+** DATE
+** TIMESTAMP
+
+| DECADE
+a| * `_datetime-expression_` +
+Year field divided by 10.
+* `_interval-expression_` +
+Number of decade(s) in the `_interval-expression_`. +
+a| * `_datetime-expression_`
+** DATE
+** TIMESTAMP
+* `_interval-expression_`
+
+| DOW
+| Day of week (1-7), where 1 is Sunday, 6 is Saturday. +
+This is not configurable.
+a| * `_datetime-expression_`
+** DATE
+** TIMESTAMP
+| DOY
+| Day of year (1-366).
+a| * `_datetime-expression_`
+** DATE
+** TIMESTAMP
+
+| EPOCH
+a| * `_datetime-expression_` +
+Second(s) since 1970-01-01 00:00:00. +
+The value is negative if `_datetime-expression_` precedes 1970-01-01 00:00:00.
+* `_interval-expression_` +
+Number of second(s) in the `_interval-expression_`. +
+a| * `_datetime-expression_`
+** DATE
+** TIMESTAMP
+* `_interval-expression_`
+
+| HOUR
+a| * `_datetime-expression_` +
+Hour (0-23).
+* `_interval-expression_` +
+Number of hour(s) in the `_interval-expression_`. +
+a| * `_datetime-expression_` +
+** TIME
+** TIMESTAMP
+* `_interval-expression_`
+
+| MINUTE
+a| * `_datetime-expression_` +
+Minute (0-59).
+* `_interval-expression_` +
+Number of minute(s) in the `_interval-expression_`. +
+a| * `_datetime-expression_`
+** TIME
+** TIMESTAMP
+* `_interval-expression_`
+
+| MONTH
+a| * `_datetime-expression_` +
+Month (1-12).
+* `_interval-expression_` +
+Number of month(s) in the `_interval-expression_`. +
+a| * `_datetime-expression_`
+** DATE
+** TIMESTAMP
+* `_interval-expression_`
+
+| QUARTER
+a| * `_datetime-expression_` +
+Quarter of year (1-4).
+* `_interval-expression_` +
+Number of quarter(s) in the `_interval-expression_`.
+a| * `_datetime-expression_`
+** DATE
+** TIMESTAMP
+* `_interval-expression_`
+
+| SECOND
+a| * `_datetime-expression_` +
+Second (0-59).
+* `_interval-expression_` +
+Number of second(s) in the `_interval-expression_`. +
+a| * `_datetime-expression_` +
+** TIME
+** TIMESTAMP
+* `_interval-expression_` +
+
+| WEEK
+a| * `_datetime-expression_` +
+Week of year. +
+
+** The value 1 is returned for a datetime that occurs in the first 7 days of the year if the year begins on Sunday. +
+Otherwise, the value 1 is returned for a datetime that occurs in the partial week before the start of the first Sunday.
+
+** The value *53* is returned for a datetime that occurs in the last full or partial week of the year.
+
+** The value *54* is returned for a datetime that occurs in the last full or partial week of the leap year if the leap year begins on Saturday.
+
+a| * `_datetime-expression_`
+** DATE
+** TIMESTAMP
+
+| WOM
+a| * `_datetime-expression_` +
+Week of month.
+a| * `_datetime-expression_` +
+** DATE
+** TIMESTAMP
+
+| YEAR
+a| * `_datetime-expression_` +
+Year (0001-9999).
+* `_interval-expression_` +
+Number of year(s) in the `_interval-expression_`. +
+a| * `_datetime-expression_`
+** DATE
+** TIMESTAMP
+* `_interval-expression_`
+|===
* `_extract-source_` is:
+
-datetime-expression \| interval-expression
+ datetime-expression
+| interval-expression
-See <<datetime_value_expressions,Datetime Value Expressions>> and
++
+For more information, see <<datetime_value_expressions,Datetime Value Expressions>> and
<<interval_value_expressions,Interval Value Expressions>>.
[[examples_of_extract]]
=== Examples of EXTRACT
-* Extract the year from a DATE value:
-+
-```
-EXTRACT (YEAR FROM DATE '2007-09-28')
-```
-+
-The result is 2007.
+[[examples_of_extract_century]]
+==== Examples of EXTRACT (CENTURY)
-* Extract the year from an INTERVAL value:
+* This example extracts the century from `_DATE_`.
+
```
-EXTRACT (YEAR FROM INTERVAL '01-09' YEAR TO MONTH)
+SQL>SELECT EXTRACT (CENTURY FROM DATE '0001-02-03') FROM DUAL;
+
+(EXPR)
+------
+ 1
+
+--- 1 row(s) selected.
```
+
+* This example extracts the century from `_TIMESTAMP_`.
+
-The result is 1.
+```
+SQL>SELECT EXTRACT (CENTURY FROM TIMESTAMP '9899-12-31 23:59:59') FROM DUAL;
+
+(EXPR)
+------
+ 99
+
+--- 1 row(s) selected.
+```
+
+[[examples_of_extract_day]]
+==== Examples of EXTRACT (DAY)
+
+* This example extracts the day from `_DATE_`.
++
+```
+SQL>SELECT EXTRACT (DAY FROM DATE '2019-02-01') FROM DUAL;
+
+(EXPR)
+------
+ 1
+
+--- 1 row(s) selected.
+```
+
+* This example extracts the day from `_TIMESTAMP_`.
++
+```
+SELECT EXTRACT (DAY FROM TIMESTAMP '2019-12-31 11:43:00') FROM DUAL;
+
+(EXPR)
+------
+ 31
+
+--- 1 row(s) selected.
+```
+
+* This example extracts the number of days from `_interval-expression_`.
++
+```
+SQL>SELECT EXTRACT (DAY FROM INTERVAL '1' DAY - INTERVAL '99' DAY) FROM DUAL;
+
+(EXPR)
+------
+ -98
+
+--- 1 row(s) selected.
+```
+
+[[examples_of_extract_decade]]
+==== Examples of EXTRACT (DECADE)
+
+* This example extracts the decade from `_DATE_`.
++
+```
+SQL>SELECT EXTRACT (DECADE FROM DATE '0010-02-03') FROM DUAL;
+
+(EXPR)
+------
+ 1
+
+--- 1 row(s) selected.
+```
+
+* This example extracts the decade from `_TIMESTAMP_`.
++
+```
+SQL>SELECT EXTRACT (DECADE FROM TIMESTAMP '9999-12-31 23:59:59') FROM DUAL;
+
+(EXPR)
+------
+ 999
+
+--- 1 row(s) selected.
+```
+
+* This example extracts the number of decades from `_interval-expression_`.
++
+```
+SQL>SELECT EXTRACT (DECADE FROM INTERVAL '1'YEAR - INTERVAL '99'YEAR) FROM DUAL;
+
+(EXPR)
+------
+ -9
+
+--- 1 row(s) selected.
+```
+
+[[examples_of_extract_dow]]
+==== Examples of EXTRACT (DOW)
+
+* This example extracts the DOW from `_DATE_`.
++
+```
+SQL>SELECT EXTRACT (DOW FROM DATE '2017-12-31') FROM DUAL;
+
+(EXPR)
+------
+ 1
+
+--- 1 row(s) selected.
+```
+
+* This example extracts the DOW from `_TIMESTAMP_`.
++
+```
+SQL>SELECT EXTRACT (DOW FROM TIMESTAMP '2018-01-01 23:59:59') FROM DUAL;
+
+(EXPR)
+------
+ 2
+
+--- 1 row(s) selected.
+```
+
+[[examples_of_extract_doy]]
+==== Examples of EXTRACT (DOY)
+
+* This example extracts the DOY from `_DATE_`.
++
+```
+SQL>SELECT EXTRACT (DOY FROM DATE '2019-01-01') FROM DUAL;
+
+(EXPR)
+------
+ 1
+
+--- 1 row(s) selected.
+```
+
+* This example extracts the DOY from `_TIMESTAMP_`.
++
+```
+SQL>SELECT EXTRACT (DOY FROM TIMESTAMP '2020-12-31 11:36:28') FROM DUAL;
+
+(EXPR)
+------
+ 366
+
+--- 1 row(s) selected.
+```
+
+[[examples_of_extract_epoch]]
+==== Examples of EXTRACT (EPOCH)
+
+* This example extracts the seconds from `_DATE_` since 1970-01-01 00:00:00.
++
+```
+SQL>SELECT EXTRACT (EPOCH FROM DATE '1970-01-02') FROM DUAL;
+
+(EXPR)
+------------
+ 86400
+
+--- 1 row(s) selected.
+```
+
+* This example extracts the seconds from `_TIMESTAMP_` since 1970-01-01 00:00:00.
++
+```
+SQL>SELECT EXTRACT (EPOCH FROM TIMESTAMP '1969-12-31 23:59:59') FROM DUAL;
+
+(EXPR)
+------------
+ -1
+
+--- 1 row(s) selected.
+```
+
+* This is the first example to extract the seconds from `_interval-expression_`.
++
+```
+SQL>SELECT EXTRACT (EPOCH FROM INTERVAL '3' HOUR) FROM DUAL;
+
+(EXPR)
+------------
+ 10800
+
+--- 1 row(s) selected.
+```
+
+* This is the second example to extract the seconds from `_interval-expression_`.
++
+```
+SQL>SELECT EXTRACT (EPOCH FROM INTERVAL '1' MONTH - INTERVAL '2' YEAR) FROM DUAL;
+
+(EXPR)
+------------
+ -60069600
+
+--- 1 row(s) selected.
+```
+
+[[examples_of_extract_hour]]
+==== Examples of EXTRACT (HOUR)
+
+* This example extracts the hour from `_TIME_`.
++
+```
+SQL>SELECT EXTRACT (HOUR FROM TIME '00:01:02') FROM DUAL;
+
+(EXPR)
+------
+ 0
+
+--- 1 row(s) selected.
+```
+
+* This example extracts the hour from `_TIMESTAMP_`.
++
+```
+SQL>SELECT EXTRACT (HOUR FROM TIMESTAMP '1990-11-02 23:16:26') FROM DUAL;
+
+(EXPR)
+------
+ 23
+
+--- 1 row(s) selected.
+```
+
+* This example extracts the number of hours from `_interval-expression_`.
++
+```
+SQL>SELECT EXTRACT (HOUR FROM INTERVAL '1' HOUR - INTERVAL '99' HOUR) FROM DUAL;
+
+(EXPR)
+------
+ -98
+
+--- 1 row(s) selected.
+```
+
+[[examples_of_extract_minute]]
+==== Examples of EXTRACT (MINUTE)
+
+* This example extracts the minute from `_TIME_`.
++
+```
+SQL>SELECT EXTRACT (MINUTE FROM TIME '01:00:02') FROM DUAL;
+
+(EXPR)
+------
+ 0
+
+--- 1 row(s) selected.
+```
+
+* This example extracts the minute from `_TIMESTAMP_`.
++
+```
+SQL>SELECT EXTRACT (MINUTE FROM TIMESTAMP '1990-11-02 23:59:16') FROM DUAL;
+
+(EXPR)
+------
+ 59
+
+--- 1 row(s) selected.
+```
+
+* This example extracts the number of minutes from `_interval-expression_`.
++
+```
+SQL>SELECT EXTRACT(MINUTE FROM INTERVAL '1' MINUTE - INTERVAL '99' MINUTE) FROM DUAL;
+
+(EXPR)
+------
+ -98
+
+--- 1 row(s) selected.
+```
+
+[[examples_of_extract_month]]
+==== Examples of EXTRACT (MONTH)
+
+* This example extracts the month from `_DATE_`.
++
+```
+SQL>SELECT EXTRACT (MONTH FROM DATE '2019-01-02') FROM DUAL;
+
+(EXPR)
+------
+ 1
+
+--- 1 row(s) selected.
+```
+
+* This example extracts the month from `_TIME_`.
++
+```
+SQL>SELECT EXTRACT (MONTH FROM TIMESTAMP '2019-12-31 23:59:59') FROM DUAL;
+
+(EXPR)
+------
+ 12
+
+--- 1 row(s) selected.
+```
+
+* This example extracts the number of months from `_TIMESTAMP_`.
++
+```
+SQL>SELECT EXTRACT(MONTH FROM INTERVAL '1' MONTH - INTERVAL '99' MONTH) FROM DUAL;
+
+(EXPR)
+------
+ -98
+
+--- 1 row(s) selected.
+```
+
+[[examples_of_extract_quarter]]
+==== Examples of EXTRACT (QUARTER)
+
+* This example extracts the quarter from `_DATE_`.
++
+```
+SQL>SELECT EXTRACT (QUARTER FROM DATE '2019-01-01') FROM DUAL;
+
+(EXPR)
+------
+ 1
+
+--- 1 row(s) selected.
+```
+
+* This example extracts the quarter from `_TIMESTAMP_`.
++
+```
+SQL>SELECT EXTRACT (QUARTER FROM TIMESTAMP '1990-11-02 08:16:26') FROM DUAL;
+
+(EXPR)
+------
+ 4
+
+--- 1 row(s) selected.
+```
+
+* This example extracts the number of quarters from `_interval-expression_`.
++
+```
+SQL>SELECT EXTRACT (QUARTER FROM INTERVAL '97' MONTH) FROM DUAL;
+
+(EXPR)
+------
+ 33
+
+--- 1 row(s) selected.
+```
+
+[[examples_of_extract_second]]
+==== Examples of EXTRACT (SECOND)
+
+* This example extracts the second from `_TIME_`.
++
+```
+SQL>SELECT EXTRACT (SECOND FROM TIME '01:02:00') FROM DUAL;
+
+(EXPR)
+------
+ 0
+
+--- 1 row(s) selected.
+```
+
+* This example extracts the second from `_TIMESTAMP_`.
++
+```
+SQL>SELECT EXTRACT (SECOND FROM TIMESTAMP '1990-11-02 23:16:59') FROM DUAL;
+
+(EXPR)
+------
+ 59
+
+--- 1 row(s) selected.
+```
+
+* This example extracts the number of seconds from `_interval-expression_`.
++
+```
+SQL>SELECT EXTRACT(SECOND FROM INTERVAL '1' SECOND - INTERVAL '99' SECOND) FROM DUAL;
+
+(EXPR)
+-----------
+ -98.000000
+
+--- 1 row(s) selected.
+```
+
+[[examples_of_extract_week]]
+==== Examples of EXTRACT (WEEK)
+
+* This example extracts the week from `_DATE_`.
++
+```
+SQL>SELECT EXTRACT (WEEK FROM DATE '2019-01-01') FROM DUAL;
+
+(EXPR)
+------
+ 1
+
+--- 1 row(s) selected.
+```
+
+* This example extracts the week from `_TIMESTAMP_`.
++
+```
+SQL>SELECT EXTRACT (WEEK FROM TIMESTAMP '2000-12-31 23:59:59') FROM DUAL;
+
+(EXPR)
+------
+ 54
+
+--- 1 row(s) selected.
+```
+
+[[examples_of_extract_wom]]
+==== Examples of EXTRACT (WOM)
+
+* This example extracts the WOM from `_DATE_`.
++
+```
+SQL>SELECT EXTRACT (WOM FROM DATE '2019-01-01') FROM DUAL;
+
+(EXPR)
+------
+ 1
+
+--- 1 row(s) selected.
+```
+
+* This example extracts the WOM from `_TIMESTAMP_`.
++
+```
+SQL>SELECT EXTRACT (WOM FROM TIMESTAMP '2020-02-29 01:02:30') FROM DUAL;
+
+(EXPR)
+------
+ 5
+
+--- 1 row(s) selected.
+```
+
+[[examples_of_extract_year]]
+==== Examples of EXTRACT (YEAR)
+
+* This example extracts the year from `_DATE_`.
++
+```
+SQL>SELECT EXTRACT (YEAR FROM DATE '0001-02-03') FROM DUAL;
+
+(EXPR)
+------
+ 1
+
+--- 1 row(s) selected.
+```
+
+* This example extracts the year from `_TIMESTAMP_`.
++
+```
+SQL>SELECT EXTRACT (YEAR FROM TIMESTAMP '9999-12-31 23:59:59') FROM DUAL;
+
+(EXPR)
+------
+ 9999
+
+--- 1 row(s) selected.
+```
+
+* This example extracts the year from `_interval-expression_`.
++
+```
+SQL>SELECT EXTRACT (YEAR FROM INTERVAL '01-09' YEAR TO MONTH) FROM DUAL;
+
+(EXPR)
+------
+ 1
+
+--- 1 row(s) selected.
+```
+
+* This example extracts the number of years from `_interval-expression_`.
++
+```
+SQL>SELECT EXTRACT(YEAR FROM INTERVAL '1' YEAR - INTERVAL '99' YEAR) FROM DUAL;
+
+(EXPR)
+------
+ -98
+
+--- 1 row(s) selected.
+```
<<<
[[filetolob_function]]
@@ -7069,7 +7704,7 @@
image::grouping-by-three-rollup-columns.jpg[700,700]
+
-** First-level: the rows marked in *blue* are the total revenue for each year (_2016_ and _2017_), each region (_A_ and _B_) and each product (_Dress_ and _Pullover_), they are caculated by GROUP BY instead of ROLLUP.
+** First-level: the rows marked in *blue* are the total revenue for each year (_2016_ and _2017_), each region (_A_ and _B_) and each product (_Dress_ and _Pullover_), they are calculated by GROUP BY instead of ROLLUP.
+
** Second-level: the rows marked in *red* provide the total revenue for the given _delivery_year_ and _region_ by _product_.
@@ -9066,6 +9701,9 @@
TO_CHAR(character-expression [,format-string])
```
+[[to_char_syntax]]
+=== Syntax Description of TO_CHAR
+
* `_character-expression_`
+
is an expression that gives a datetime value.
@@ -9073,6 +9711,212 @@
* `_format-string_`
+
is one of the following character string literals:
++
+.Details of `_format-string_` and `_character-expression_`
+[cols="3*.^"]
+|===
+^| *Supported* `_character-expression_`
+^| *`_format-string_`*
+^| *Description*
+
+a| * `_datetime-expression_`
+** DATE
+** TIMESTAMP
+| 'CC'
+| Two-digit century.
+
+a| * `_datetime-expression_`
+** DATE
+** TIMESTAMP
+| 'D'
+| Day of week (1-7), where 1 is Sunday, 6 is Saturday. +
+This is not configurable.
+
+a| * `_datetime-expression_`
+** DATE
+** TIMESTAMP
+| 'DD'
+| Day of month (01-31).
+
+a| * `_datetime-expression_`
+** DATE
+** TIMESTAMP
+| 'DDD'
+| Day of year (001-366).
+
+a| * `_datetime-expression_`
+** DATE
+** TIMESTAMP
+| 'DY'
+a| Name of day, which is a three-letter abbreviation for the day in uppercase. +
+
+The following values are returned: +
+
+* MON +
+
+* TUE +
+
+* WED +
+
+* THU +
+
+* FRI +
+
+* SAT +
+
+* SUN
+
+a| * `_datetime-expression_`
+** DATE
+** TIMESTAMP
+| 'DAY'
+a| Name of day, which is full uppercase day name padded with blanks to the length of 9 characters. +
+
+The following values are returned: +
+
+* MONDAY +
+
+* TUESDAY +
+
+* WEDSDAY +
+
+* THURSDAY +
+
+* FRIDAY +
+
+* SATURDAY +
+
+* SUNDAY
+
+a| * `_datetime-expression_`
+** TIME
+** TIMESTAMP
+| 'HH'
+| Hour of day in 24-hour format (00-23). +
+'HH' behaves the same as 'HH24'.
+
+a| * `_datetime-expression_`
+** TIME
+** TIMESTAMP
+| 'HH12'
+| Hour of day in 12-hour format (01-12).
+
+a| * `_datetime-expression_`
+** TIME
+** TIMESTAMP
+| 'HH24'
+| Hour of day in 24-hour format (00-23). +
+'HH24' behaves the same as 'HH'.
+
+a| * `_datetime-expression_`
+** DATE
+** TIMESTAMP
+| 'J'
+| Julian date (that is, number of days since January 1, 4713 BC).
+
+a| * `_datetime-expression_`
+** TIME
+** TIMESTAMP
+| 'MI'
+| Minute (00-59).
+
+a| * `_datetime-expression_`
+** DATE
+** TIMESTAMP
+| 'MM'
+| Month (01-12).
+
+
+a| * `_datetime-expression_`
+** DATE
+** TIMESTAMP
+| 'MON'
+a| Month, which is a three-letter abbreviation for the month in uppercase. +
+
+The following values are returned: +
+
+* JAN +
+
+* FEB +
+
+* MAR +
+
+* APR +
+
+* MAY +
+
+* JUN +
+
+* JUL +
+
+* AUG +
+
+* SEP +
+
+* OCT +
+
+* NOV +
+
+* DEC
+
+a| * `_datetime-expression_`
+** DATE
+** TIMESTAMP
+| 'Q'
+| Quarter (1-4).
+
+a| * `_datetime-expression_`
+** TIME
+** TIMESTAMP
+| 'SS'
+| Second (00-59).
+
+a| * `_datetime-expression_`
+** DATE
+** TIMESTAMP
+| 'W'
+| Week of month.
+
+a| * `_datetime-expression_`
+** DATE
+** TIMESTAMP
+| 'WW'
+a| Week of year. +
+
+* The value 1 is returned for a datetime that occurs in the first 7 days of the year if the year begins on Sunday. +
+Otherwise, the value 1 is returned for a datetime that occurs in the partial week before the start of the first Sunday.
+
+* The value *53* is returned for a datetime that occurs in the last full or partial week of the year.
+
+* The value *54* is returned for a datetime that occurs in the last full or partial week of the leap year where begins on Saturday.
+
+a| * `_datetime-expression_`
+** DATE
+** TIMESTAMP
+| 'Y'
+| Last digit of year (0-9).
+
+a| * `_datetime-expression_`
+** DATE
+** TIMESTAMP
+| 'YY'
+| Last two digits of year (00-99).
+
+a| * `_datetime-expression_`
+** DATE
+** TIMESTAMP
+| 'YYY'
+| Last three digits of year (000-999).
+
+a| * `_datetime-expression_`
+** DATE
+** TIMESTAMP
+| 'YYYY'
+| Four-digit year (0001-9999).
+|===
+
++
+Besides the `_format-string_` listed above, the following character string literals are also valid:
** 'YYYY-MM-DD'
** 'MM/DD/YYYY'
@@ -9098,30 +9942,606 @@
** 'MM/DD/YYYY HH24:MI:SS'
** 'DD-MON-YYYY HH:MI:SS'
** 'MONTH DD, YYYY, HH:MI'
-** 'DD.MM.YYYY HH24.MI.SS'
+** 'DD.MM.YYYY HH24.MI.SS'
-Here, YYYY refers to a 4-digit year. YY refers to a two-digit year. MM refers to a two-digit month. MON refers to
-a three-letter abbreviation for month ('JAN', 'FEB', 'MAR', 'APR', 'MAY', 'JUN', 'JUL', 'AUG', 'SEP',
-'OCT', 'NOV' or 'DEC'). MONTH refers to the month spelled out. In the output value, the month abbreviation or month
++
+Here:
+
+*** YYYY refers to a four-digit year.
+*** YY refers to a two-digit year.
+*** MM refers to a two-digit month.
+*** MON refers to a three-letter abbreviation for month ('JAN', 'FEB', 'MAR', 'APR', 'MAY', 'JUN', 'JUL', 'AUG', 'SEP',
+'OCT', 'NOV' or 'DEC').
+*** MONTH refers to the month spelled out. In the output value, the month abbreviation or month
will appear in upper case.
-
-HH and HH24 refer to a 2-digit hour field. MI refers to a two-digit minutes field. SS refers to a 2-digit seconds field.
-
-If the _format-string_ argument is omitted, 'YYYY-MM-DD' is used as the
+*** HH and HH24 refer to a two-digit hour field.
+*** MI refers to a two-digit minutes field.
+*** SS refers to a two-digit seconds field.
+*** If the `_format-string_` argument is omitted, 'YYYY-MM-DD' is used as the
default for date and timestamp values, and 'HH:MI:SS' is used for time values.
[[considerations_for_to_char]]
=== Considerations for TO_CHAR
-If the _format-string_ contains only hour, minute or seconds fields, the input data type must be time or timestamp.
+If the `_format-string_` contains only hour, minute or seconds fields, the input data type must be time or timestamp.
-If the _format-string_ contains only year, month or day fields, the input data type must be date or timestamp.
+If the `_format-string_` contains only year, month or day fields, the input data type must be date or timestamp.
-If the _format-string_ contains all fields, and the input data type is date, the hour, minute and second fields in the result will be filled with zeroes.
+If the `_format-string_` contains all fields, and the input data type is date, the hour, minute and second fields in the result will be filled with zeroes.
[[examples_of_to_char]]
=== Examples of TO_CHAR
+[[examples_of_to_char_cc]]
+==== Examples of TO_CHAR (CC)
+
+* This example converts the `_DATE_` value to the character value of century.
++
+```
+SQL>SELECT TO_CHAR (DATE '0001-11-02','CC') FROM DUAL;
+
+(EXPR)
+------
+01
+
+--- 1 row(s) selected.
+```
+
+* This example converts the `_TIMESTAMP_` value to the character value of century.
++
+```
+SQL>SELECT TO_CHAR (TIMESTAMP '9899-12-31 23:59:59','CC') FROM DUAL;
+
+(EXPR)
+------
+99
+
+--- 1 row(s) selected.
+```
+
+[[examples_of_to_char_d]]
+==== Examples of TO_CHAR (D)
+
+* This example converts the `_DATE_` value to the character value of day of week.
++
+```
+SQL>SELECT TO_CHAR (DATE '2018-01-01','D') FROM DUAL;
+
+(EXPR)
+------
+2
+
+--- 1 row(s) selected.
+```
+
+* This example converts the `_TIMESTAMP_` value to the character value of day of week.
++
+```
+SQL>SELECT TO_CHAR (TIMESTAMP '2018-04-01 23:59:59','D') FROM DUAL;
+
+(EXPR)
+------
+1
+
+--- 1 row(s) selected.
+```
+
+[[examples_of_to_char_dd]]
+==== Examples of TO_CHAR (DD)
+
+* This example converts the `_DATE_` value to the character value of day of month.
++
+```
+SQL>SELECT TO_CHAR (DATE '2018-01-01','DD') FROM DUAL;
+
+(EXPR)
+------
+01
+
+--- 1 row(s) selected.
+```
+
+* This example converts the `_TIMESTAMP_` value to the character value of day of month.
++
+```
+SQL>SELECT TO_CHAR (TIMESTAMP '2018-12-31 23:59:59','DD') FROM DUAL;
+
+(EXPR)
+------
+31
+
+--- 1 row(s) selected.
+```
+
+[[examples_of_to_char_ddd]]
+==== Examples of TO_CHAR (DDD)
+
+* This example converts the `_DATE_` value to the character value of day of year.
++
+```
+SQL>SELECT TO_CHAR (DATE '2018-01-01','DDD') FROM DUAL;
+
+(EXPR)
+------
+001
+
+--- 1 row(s) selected.
+```
+
+* This example converts the `_TIMESTAMP_` value to the character value of day of year.
++
+```
+SQL>SELECT TO_CHAR (TIMESTAMP '2020-12-31 23:59:59','DDD') FROM DUAL;
+
+(EXPR)
+------
+366
+
+--- 1 row(s) selected.
+```
+
+[[examples_of_to_char_dy]]
+==== Examples of TO_CHAR (DY)
+
+* This example converts the `_DATE_` value to the character value of name of day (abbreviation).
++
+```
+SQL>SELECT TO_CHAR (DATE '2018-12-31','DY') FROM DUAL;
+
+(EXPR)
+------
+MON
+
+--- 1 row(s) selected.
+```
+
+* This example converts the `_TIMESTAMP_` value to the character value of name of day (abbreviation).
++
+```
+SQL>SELECT TO_CHAR (TIMESTAMP '2019-02-14 23:59:59','DY') FROM DUAL;
+
+(EXPR)
+------
+THU
+
+--- 1 row(s) selected.
+```
+
+[[examples_of_to_char_day]]
+==== Examples of TO_CHAR (DAY)
+
+* This example converts the `_DATE_` value to the character value of name of day.
++
+```
+SQL>SELECT TO_CHAR (DATE '2019-05-12','DAY') FROM DUAL;
+
+(EXPR)
+---------
+SUNDAY
+
+--- 1 row(s) selected.
+```
+
+* This example converts the `_TIMESTAMP_` value to the character value of name of day.
++
+```
+SQL>SELECT TO_CHAR (TIMESTAMP '2019-12-24 23:59:59','DAY') FROM DUAL;
+
+(EXPR)
+---------
+TUESDAY
+
+--- 1 row(s) selected.
+```
+
+[[examples_of_to_char_hh]]
+==== Examples of TO_CHAR (HH)
+
+* This example converts the `_TIME_` value to the character value of hour (24-hour format).
++
+```
+SQL>SELECT TO_CHAR (TIME '00:00:01','HH') FROM DUAL;
+
+(EXPR)
+------
+00
+
+--- 1 row(s) selected.
+```
+
+* This example converts the `_TIMESTAMP_` value to the character value of hour (24-hour format).
++
+```
+SQL>SELECT TO_CHAR (TIMESTAMP '2019-01-01 23:59:59','HH') FROM DUAL;
+
+(EXPR)
+------
+23
+
+--- 1 row(s) selected.
+```
+
+[[examples_of_to_char_hh12]]
+==== Examples of TO_CHAR (HH12)
+
+* This example converts the `_TIME_` value to the character value of hour (12-hour format).
++
+```
+SQL>SELECT TO_CHAR (TIME '01:00:00','HH12') FROM DUAL;
+
+(EXPR)
+------
+01
+
+--- 1 row(s) selected.
+```
+
+* This example converts the `_TIMESTAMP_` value to the character value of hour (12-hour format).
++
+```
+SQL>SELECT TO_CHAR (TIMESTAMP '2019-01-01 12:59:59','HH12') FROM DUAL;
+
+(EXPR)
+------
+12
+
+--- 1 row(s) selected.
+```
+
+[[examples_of_to_char_hh24]]
+==== Examples of TO_CHAR (HH24)
+
+* This example converts the `_TIME_` value to the character value of hour (24-hour format).
++
+```
+SQL>SELECT TO_CHAR (TIME '00:00:01','HH24') FROM DUAL;
+
+(EXPR)
+------
+00
+
+--- 1 row(s) selected.
+```
+
+* This example converts the `_TIMESTAMP_` value to the character value of hour (24-hour format).
++
+```
+SQL>SELECT TO_CHAR (TIMESTAMP '2019-01-01 23:59:59','HH24') FROM DUAL;
+
+(EXPR)
+------
+23
+
+--- 1 row(s) selected.
+```
+
+[[examples_of_to_char_j]]
+==== Examples of TO_CHAR (J)
+
+* This example calculates the number of days since the beginning of the Julian epoch and converts the `_DATE_` value to the character value.
++
+```
+SQL>SELECT TO_CHAR (DATE '0001-01-01','J') FROM DUAL;
+
+(EXPR)
+-------
+1721426
+
+--- 1 row(s) selected.
+```
+
+* This example calculates the number of days since the beginning of the Julian epoch and converts the `_TIMESTAMP_` value to the character value.
++
+```
+SQL>SELECT TO_CHAR (TIMESTAMP '2018-11-02 23:59:59','J') FROM DUAL;;
+
+(EXPR)
+-------
+2458425
+
+--- 1 row(s) selected.
+```
+
+[[examples_of_to_char_mi]]
+==== Examples of TO_CHAR (MI)
+
+* This example converts the `_TIME_` value to the character value of minute.
++
+```
+SQL>SELECT TO_CHAR (TIME '01:00:02','MI') FROM DUAL;
+
+(EXPR)
+------
+00
+
+--- 1 row(s) selected.
+```
+
+* This example converts the `_TIMESTAMP_` value to the character value of minute.
++
+```
+SQL>SELECT TO_CHAR (TIMESTAMP '2019-01-01 23:59:01','MI') FROM DUAL;
+
+(EXPR)
+------
+59
+
+--- 1 row(s) selected.
+```
+
+[[examples_of_to_char_mm]]
+==== Examples of TO_CHAR (MM)
+
+* This example converts the `_DATE_` value to the character value of month.
++
+```
+SQL>SELECT TO_CHAR (DATE '0001-01-01','MM') FROM DUAL;
+
+(EXPR)
+------
+01
+
+--- 1 row(s) selected.
+```
+
+* This example converts the `_TIMESTAMP_` value to the character value of month.
++
+```
+SQL>SELECT TO_CHAR (TIMESTAMP '2019-01-01 23:59:59','MM') FROM DUAL;
+
+(EXPR)
+------
+12
+
+--- 1 row(s) selected.
+```
+
+[[examples_of_to_char_mon]]
+==== Examples of TO_CHAR (MON)
+
+* This example converts the `_DATE_` value to the character value of month.
++
+```
+SQL>SELECT TO_CHAR (DATE '0001-01-01','MON') FROM DUAL;
+
+(EXPR)
+------
+JAN
+
+--- 1 row(s) selected.
+```
+
+* This example converts the `_TIMESTAMP_` value to the character value of month.
++
+```
+SQL>SELECT TO_CHAR (TIMESTAMP '2018-11-02 23:59:59','MON') FROM DUAL;
+
+(EXPR)
+------
+NOV
+
+--- 1 row(s) selected.
+```
+
+[[examples_of_to_char_quarter]]
+==== Examples of TO_CHAR (QUARTER)
+
+* This example converts the `_DATE_` value to the character value of quarter.
++
+```
+SQL>SELECT TO_CHAR (DATE '0001-01-01','Q') FROM DUAL;
+
+(EXPR)
+------
+1
+
+--- 1 row(s) selected.
+```
+
+* This example converts the `_TIMESTAMP_` value to the character value of quarter.
++
+```
+SQL>SELECT TO_CHAR (TIMESTAMP '2018-11-02 23:59:59','Q') FROM DUAL;
+
+(EXPR)
+------
+4
+
+--- 1 row(s) selected.
+```
+
+[[examples_of_to_char_ss]]
+==== Examples of TO_CHAR (SS)
+
+* This example converts the `_TIME_` value to the character value of second.
++
+```
+SQL>SELECT TO_CHAR (TIME '01:02:00','SS') FROM DUAL;
+
+(EXPR)
+------
+00
+
+--- 1 row(s) selected.
+```
+
+* This example converts the `_TIMESTAMP_` value to the character value of second.
++
+```
+SQL>SELECT TO_CHAR (TIMESTAMP '2019-01-01 23:01:59','SS') FROM DUAL;
+
+(EXPR)
+------
+59
+
+--- 1 row(s) selected.
+```
+
+[[examples_of_to_char_w]]
+==== Examples of TO_CHAR (W)
+
+* This example converts the `_DATE_` value to the character value of week of month.
++
+```
+SQL>SELECT TO_CHAR (DATE '2019-01-01','W') FROM DUAL;
+
+(EXPR)
+------
+1
+
+--- 1 row(s) selected.
+```
+
+* This example converts the `_TIMESTAMP_` value to the character value of week of month.
++
+```
+SQL>SELECT TO_CHAR (TIMESTAMP '2018-04-30 23:59:59','W') FROM DUAL;
+
+(EXPR)
+------
+5
+
+--- 1 row(s) selected.
+```
+
+[[examples_of_to_char_ww]]
+==== Examples of TO_CHAR (WW)
+
+* This example converts the `_DATE_` value to the character value of week of year.
++
+```
+SQL>SELECT TO_CHAR (DATE '2016-01-03','WW') FROM DUAL;
+
+(EXPR)
+------
+02
+
+--- 1 row(s) selected.
+```
+
+* This example converts the `_TIMESTAMP_` value to the character value of week of year.
++
+```
+SQL>SELECT TO_CHAR (TIMESTAMP '2000-12-31 23:59:59','WW') FROM DUAL;
+
+(EXPR)
+------
+54
+
+--- 1 row(s) selected.
+```
+
+[[examples_of_to_char_y]]
+==== Examples of TO_CHAR (Y)
+
+* This example converts the `_DATE_` value to the character value of week of year (last digit).
++
+```
+SQL>SELECT TO_CHAR (DATE '1000-01-01','Y') FROM DUAL;
+
+(EXPR)
+------
+0
+
+--- 1 row(s) selected.
+```
+
+* This example converts the `_TIMESTAMP_` value to the character value of week of year (last digit).
++
+```
+SQL>SELECT TO_CHAR (TIMESTAMP '9999-12-31 23:59:59','Y') FROM DUAL;
+
+(EXPR)
+------
+9
+
+--- 1 row(s) selected.
+```
+
+[[examples_of_to_char_yy]]
+==== Examples of TO_CHAR (YY)
+
+* This example converts the `_DATE_` value to the character value of week of year (last two digits).
++
+```
+SQL>SELECT TO_CHAR (DATE '1000-01-01','YY') FROM DUAL;
+
+(EXPR)
+------
+00
+
+--- 1 row(s) selected.
+```
+
+* This example converts the `_TIMESTAMP_` value to the character value of week of year (last two digits).
++
+```
+SQL>SELECT TO_CHAR (TIMESTAMP '9999-12-31 23:59:59','YY') FROM DUAL;
+
+(EXPR)
+------
+99
+
+--- 1 row(s) selected.
+```
+
+[[examples_of_to_char_yyy]]
+==== Examples of TO_CHAR (YYY)
+
+* This example converts the `_DATE_` value to the character value of week of year (last three digits).
++
+```
+SQL>SELECT TO_CHAR (DATE '1000-01-01','YYY') FROM DUAL;
+
+(EXPR)
+------
+000
+
+--- 1 row(s) selected.
+```
+
+* This example converts the `_TIMESTAMP_` value to the character value of week of year (last three digits).
++
+```
+SQL>SELECT TO_CHAR (TIMESTAMP '9999-12-31 23:59:59','YYY') FROM DUAL;
+
+(EXPR)
+------
+999
+
+--- 1 row(s) selected.
+```
+
+[[examples_of_to_char_yyyy]]
+==== Examples of TO_CHAR (YYYY)
+
+* This example converts the `_DATE_` value to the character value of week of year.
++
+```
+SQL>SELECT TO_CHAR (DATE '0001-01-01','YYYY') FROM DUAL;
+
+(EXPR)
+------
+0001
+
+--- 1 row(s) selected.
+```
+
+* This example converts the `_TIMESTAMP_` value to the character value of week of year.
++
+```
+SQL>SELECT TO_CHAR (TIMESTAMP '9999-12-31 23:59:59','YYYY') FROM DUAL;
+
+(EXPR)
+------
+9999
+
+--- 1 row(s) selected.
+```
+
+[[examples_of_to_char_other]]
+==== Examples of TO_CHAR (Other)
+
* This function returns the character value '01MAR2016':
+
```
diff --git a/win-odbc64/odbcclient/drvr35/ctosqlconv.cpp b/win-odbc64/odbcclient/drvr35/ctosqlconv.cpp
index 1d338b6..e603708 100644
--- a/win-odbc64/odbcclient/drvr35/ctosqlconv.cpp
+++ b/win-odbc64/odbcclient/drvr35/ctosqlconv.cpp
@@ -288,10 +288,6 @@
return SQL_SUCCESS;
}
- //if (targetPrecision < 19)
- if (((SQLDataType == SQLTYPECODE_NUMERIC) && (targetPrecision <= 18)) ||
- ((SQLDataType == SQLTYPECODE_NUMERIC_UNSIGNED) && (targetPrecision <= 9)))
- getMaxNum(targetPrecision, targetScale, integralMax, decimalMax);
switch (ODBCDataType)
{
@@ -756,6 +752,7 @@
}
if(negative && targetUnsigned)
return IDS_22_003_02;
+ getMaxNum(targetPrecision, targetScale, integralMax, decimalMax);
if ((integralPart < 0) || (integralPart > integralMax))
return IDS_22_003;
decimalDigits = 0;
@@ -848,6 +845,7 @@
}
if(negative && targetUnsigned)
return IDS_22_003_02;
+ getMaxNum(targetPrecision, targetScale, integralMax, decimalMax);
if ((integralPart < 0) || (integralPart > integralMax))
return IDS_22_003;
decimalDigits = 0;
@@ -1435,6 +1433,7 @@
}
if(negative && targetUnsigned)
return IDS_22_003_02;
+ getMaxNum(targetPrecision, targetScale, integralMax, decimalMax);
if ((integralPart < 0) || (integralPart > integralMax))
return IDS_22_003;
decimalDigits = 0;
@@ -1490,6 +1489,7 @@
}
if(negative && targetUnsigned)
return IDS_22_003_02;
+ getMaxNum(targetPrecision, targetScale, integralMax, decimalMax);
if ((integralPart < 0) || (integralPart > integralMax))
return IDS_22_003;
decimalDigits = 0;
@@ -1598,6 +1598,7 @@
integralPart = (integralPart < 0)? -integralPart: integralPart;
decimalPart = 0;
leadZeros = 0;
+ getMaxNum(targetPrecision, targetScale, integralMax, decimalMax);
if ( integralPart > integralMax )
return IDS_22_003;