|
@@ -2714,7 +2714,7 @@ CJobBase::CJobBase(ILoadedDllEntry *_querySo, const char *_graphName) : querySo(
|
|
maxDiskUsage = diskUsage = 0;
|
|
maxDiskUsage = diskUsage = 0;
|
|
dirty = true;
|
|
dirty = true;
|
|
aborted = false;
|
|
aborted = false;
|
|
- globalMemoryMB = globals->getPropInt("@globalMemorySize"); // in MB
|
|
|
|
|
|
+ queryMemoryMB = 0;
|
|
channelsPerSlave = globals->getPropInt("@channelsPerSlave", 1);
|
|
channelsPerSlave = globals->getPropInt("@channelsPerSlave", 1);
|
|
numChannels = channelsPerSlave;
|
|
numChannels = channelsPerSlave;
|
|
pluginMap = new SafePluginMap(&pluginCtx, true);
|
|
pluginMap = new SafePluginMap(&pluginCtx, true);
|
|
@@ -2740,6 +2740,66 @@ CJobBase::CJobBase(ILoadedDllEntry *_querySo, const char *_graphName) : querySo(
|
|
throwUnexpected();
|
|
throwUnexpected();
|
|
}
|
|
}
|
|
|
|
|
|
|
|
+void CJobBase::applyMemorySettings(float recommendReservePercentage, const char *context)
|
|
|
|
+{
|
|
|
|
+ VStringBuffer totalMemorySetting("%sMemory/@total", context);
|
|
|
|
+ unsigned totalMemoryMB = globals->getPropInt(totalMemorySetting);
|
|
|
|
+
|
|
|
|
+ unsigned recommendReservedMemoryMB = totalMemoryMB * recommendReservePercentage / 100;
|
|
|
|
+#ifdef _CONTAINERIZED
|
|
|
|
+ /* only "query" memory is actually used (if set configures Thor roxiemem limit)
|
|
|
|
+ * others are only advisory, but totalled and checked if within the total limit.
|
|
|
|
+ */
|
|
|
|
+ std::vector<std::string> memorySettings = { "query", "thirdParty" };
|
|
|
|
+ offset_t totalRequirements = 0;
|
|
|
|
+ for (const auto &setting : memorySettings)
|
|
|
|
+ {
|
|
|
|
+ VStringBuffer workunitSettingName("%smemory.%s", context, setting.c_str()); // NB: workunit options are case insensitive
|
|
|
|
+ StringBuffer memString;
|
|
|
|
+ getWorkUnitValue(workunitSettingName, memString);
|
|
|
|
+ if (0 == memString.length())
|
|
|
|
+ {
|
|
|
|
+ VStringBuffer globalSettingName("%sMemory/@%s", context, setting.c_str());
|
|
|
|
+ globals->getProp(globalSettingName, memString);
|
|
|
|
+ }
|
|
|
|
+ if (memString.length())
|
|
|
|
+ {
|
|
|
|
+ offset_t memBytes = friendlyStringToSize(memString);
|
|
|
|
+ if (streq("query", setting.c_str()))
|
|
|
|
+ queryMemoryMB = (unsigned)(memBytes / 0x100000);
|
|
|
|
+ totalRequirements += memBytes;
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+ unsigned totalRequirementsMB = (unsigned)(totalRequirements / 0x100000);
|
|
|
|
+ if (totalRequirementsMB > totalMemoryMB)
|
|
|
|
+ throw makeStringExceptionV(0, "The total memory requirements of the query (%u MB) exceeds the %s memory limit (%u MB)", totalRequirementsMB, context, totalMemoryMB);
|
|
|
|
+
|
|
|
|
+ unsigned remainingMB = totalMemoryMB - totalRequirementsMB;
|
|
|
|
+ if (remainingMB < recommendReservedMemoryMB)
|
|
|
|
+ {
|
|
|
|
+ WARNLOG("The total memory requirements of the query (%u MB) exceed the recommended reserve limits for %s (total memory: %u MB, reserve recommendation: %.2f%%)", totalRequirementsMB, context, totalMemoryMB, recommendReservePercentage);
|
|
|
|
+ if (0 == queryMemoryMB)
|
|
|
|
+ queryMemoryMB = remainingMB; // probably not recommended - use all of remaining in this case for query memory.
|
|
|
|
+ }
|
|
|
|
+ else if (0 == queryMemoryMB)
|
|
|
|
+ queryMemoryMB = remainingMB - recommendReservedMemoryMB;
|
|
|
|
+#else
|
|
|
|
+ if (totalMemoryMB < recommendReservedMemoryMB)
|
|
|
|
+ throw makeStringExceptionV(0, "The total memory (%u MB) is less than recommendReservedMemoryMB (%u MB), recommendReservePercentage (%.2f%%)", totalMemoryMB, recommendReservedMemoryMB, recommendReservePercentage);
|
|
|
|
+
|
|
|
|
+ unsigned remainingMB = totalMemoryMB;
|
|
|
|
+ queryMemoryMB = totalMemoryMB - recommendReservedMemoryMB;
|
|
|
|
+#endif
|
|
|
|
+
|
|
|
|
+ bool gmemAllowHugePages = globals->getPropBool("@heapUseHugePages", false);
|
|
|
|
+ gmemAllowHugePages = globals->getPropBool("@heapMasterUseHugePages", gmemAllowHugePages);
|
|
|
|
+ bool gmemAllowTransparentHugePages = globals->getPropBool("@heapUseTransparentHugePages", true);
|
|
|
|
+ bool gmemRetainMemory = globals->getPropBool("@heapRetainMemory", false);
|
|
|
|
+ roxiemem::setTotalMemoryLimit(gmemAllowHugePages, gmemAllowTransparentHugePages, gmemRetainMemory, ((memsize_t)queryMemoryMB) * 0x100000, 0, thorAllocSizes, NULL);
|
|
|
|
+
|
|
|
|
+ PROGLOG("Total memory = %u MB, query memory = %u MB, memory spill at = %u (reserve = %.2f%%, reserveMB = %u, remainingMB = %u)", totalMemoryMB, queryMemoryMB, memorySpillAtPercentage, recommendReservePercentage, recommendReservedMemoryMB, remainingMB);
|
|
|
|
+}
|
|
|
|
+
|
|
void CJobBase::init()
|
|
void CJobBase::init()
|
|
{
|
|
{
|
|
StringBuffer tmp;
|
|
StringBuffer tmp;
|
|
@@ -2768,13 +2828,10 @@ void CJobBase::init()
|
|
crcChecking = 0 != getWorkUnitValueInt("THOR_ROWCRC", globals->getPropBool("@THOR_ROWCRC", false));
|
|
crcChecking = 0 != getWorkUnitValueInt("THOR_ROWCRC", globals->getPropBool("@THOR_ROWCRC", false));
|
|
usePackedAllocator = 0 != getWorkUnitValueInt("THOR_PACKEDALLOCATOR", globals->getPropBool("@THOR_PACKEDALLOCATOR", true));
|
|
usePackedAllocator = 0 != getWorkUnitValueInt("THOR_PACKEDALLOCATOR", globals->getPropBool("@THOR_PACKEDALLOCATOR", true));
|
|
memorySpillAtPercentage = (unsigned)getWorkUnitValueInt("memorySpillAt", globals->getPropInt("@memorySpillAt", 80));
|
|
memorySpillAtPercentage = (unsigned)getWorkUnitValueInt("memorySpillAt", globals->getPropInt("@memorySpillAt", 80));
|
|
- sharedMemoryLimitPercentage = (unsigned)getWorkUnitValueInt("globalMemoryLimitPC", globals->getPropInt("@sharedMemoryLimit", 90));
|
|
|
|
- sharedMemoryMB = globalMemoryMB*sharedMemoryLimitPercentage/100;
|
|
|
|
failOnLeaks = getOptBool("failOnLeaks");
|
|
failOnLeaks = getOptBool("failOnLeaks");
|
|
maxLfnBlockTimeMins = getOptInt(THOROPT_MAXLFN_BLOCKTIME_MINS, DEFAULT_MAXLFN_BLOCKTIME_MINS);
|
|
maxLfnBlockTimeMins = getOptInt(THOROPT_MAXLFN_BLOCKTIME_MINS, DEFAULT_MAXLFN_BLOCKTIME_MINS);
|
|
soapTraceLevel = getOptInt("soapTraceLevel", 1);
|
|
soapTraceLevel = getOptInt("soapTraceLevel", 1);
|
|
|
|
|
|
- PROGLOG("Global memory size = %d MB, shared memory = %d%%, memory spill at = %d%%", globalMemoryMB, sharedMemoryLimitPercentage, memorySpillAtPercentage);
|
|
|
|
StringBuffer tracing("maxActivityCores = ");
|
|
StringBuffer tracing("maxActivityCores = ");
|
|
if (maxActivityCores)
|
|
if (maxActivityCores)
|
|
tracing.append(maxActivityCores);
|
|
tracing.append(maxActivityCores);
|