This is an automated email from the ASF dual-hosted git repository.

lta pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/incubator-iotdb.git


The following commit(s) were added to refs/heads/master by this push:
     new 7492966  Fix OOM (#1074)
7492966 is described below

commit 7492966cdcf6bd7df0b238f51a7b9a509f87761b
Author: Tianan Li <[email protected]>
AuthorDate: Wed Apr 22 20:27:17 2020 +0800

    Fix OOM (#1074)
    
    * modify new memtable size estimation and limit the total memoty size of 
write log to up to allocate for write size / 10
    
    * update dynamic adapter equation
    
    * modify text size eatimation considering efficiency
    
    * remove useless import
---
 .../java/org/apache/iotdb/db/conf/IoTDBConfig.java |  2 +-
 .../db/conf/adapter/IoTDBConfigDynamicAdapter.java | 24 ++++++-----
 .../iotdb/db/engine/memtable/AbstractMemTable.java |  4 +-
 .../db/engine/storagegroup/TsFileProcessor.java    |  2 +
 .../java/org/apache/iotdb/db/utils/MemUtils.java   | 48 +++++++++++-----------
 .../db/writelog/node/ExclusiveWriteLogNode.java    |  8 ++--
 6 files changed, 49 insertions(+), 39 deletions(-)

diff --git a/server/src/main/java/org/apache/iotdb/db/conf/IoTDBConfig.java 
b/server/src/main/java/org/apache/iotdb/db/conf/IoTDBConfig.java
index d9a406e..c1b3350 100644
--- a/server/src/main/java/org/apache/iotdb/db/conf/IoTDBConfig.java
+++ b/server/src/main/java/org/apache/iotdb/db/conf/IoTDBConfig.java
@@ -959,7 +959,7 @@ public class IoTDBConfig {
     return walBufferSize;
   }
 
-  void setWalBufferSize(int walBufferSize) {
+  public void setWalBufferSize(int walBufferSize) {
     this.walBufferSize = walBufferSize;
   }
 
diff --git 
a/server/src/main/java/org/apache/iotdb/db/conf/adapter/IoTDBConfigDynamicAdapter.java
 
b/server/src/main/java/org/apache/iotdb/db/conf/adapter/IoTDBConfigDynamicAdapter.java
index a6a5bb8..ac7d4be 100644
--- 
a/server/src/main/java/org/apache/iotdb/db/conf/adapter/IoTDBConfigDynamicAdapter.java
+++ 
b/server/src/main/java/org/apache/iotdb/db/conf/adapter/IoTDBConfigDynamicAdapter.java
@@ -94,6 +94,8 @@ public class IoTDBConfigDynamicAdapter implements 
IDynamicAdapter {
    */
   private static long CHUNK_METADATA_SIZE_IN_BYTE = 1536L;
 
+  private static final double WAL_MEMORY_RATIO = 0.1;
+
   /**
    * Average queue length in memtable pool
    */
@@ -153,6 +155,8 @@ public class IoTDBConfigDynamicAdapter implements 
IDynamicAdapter {
 
     if (canAdjust) {
       CONFIG.setMaxMemtableNumber(maxMemTableNum);
+      CONFIG.setWalBufferSize(
+          (int) Math.min(Integer.MAX_VALUE, allocateMemoryForWrite * 
WAL_MEMORY_RATIO / maxMemTableNum));
       CONFIG.setTsFileSizeThreshold(tsFileSizeThreshold);
       CONFIG.setMemtableSizeThreshold(memtableSizeInByte);
       if (LOGGER.isDebugEnabled() && initialized) {
@@ -181,7 +185,7 @@ public class IoTDBConfigDynamicAdapter implements 
IDynamicAdapter {
     // when unit is byte, it's likely to cause Long type overflow.
     // so when b is larger than Integer.MAC_VALUE use the unit KB.
     double a = maxMemTableNum;
-    double b = allocateMemoryForWrite - staticMemory;
+    double b = allocateMemoryForWrite * (1 - WAL_MEMORY_RATIO) - staticMemory;
     int magnification = b > Integer.MAX_VALUE ? 1024 : 1;
     b /= magnification;
     double c =
@@ -201,10 +205,9 @@ public class IoTDBConfigDynamicAdapter implements 
IDynamicAdapter {
    * @return Tsfile byte threshold
    */
   private long calcTsFileSizeThreshold(long memTableSize, double ratio) {
-    return (long) (
-        (allocateMemoryForWrite - maxMemTableNum * memTableSize - 
staticMemory) * memTableSize / (
-            ratio * maxMemTableNum * CHUNK_METADATA_SIZE_IN_BYTE * 
MManager.getInstance()
-                .getMaximalSeriesNumberAmongStorageGroups()));
+    return (long) ((allocateMemoryForWrite * (1 - WAL_MEMORY_RATIO) - 
maxMemTableNum * memTableSize
+        - staticMemory) * memTableSize / (ratio * maxMemTableNum * 
CHUNK_METADATA_SIZE_IN_BYTE
+        * MManager.getInstance().getMaximalSeriesNumberAmongStorageGroups()));
   }
 
   /**
@@ -220,17 +223,17 @@ public class IoTDBConfigDynamicAdapter implements 
IDynamicAdapter {
   @Override
   public void addOrDeleteStorageGroup(int diff) throws ConfigAdjusterException 
{
     totalStorageGroup += diff;
-    maxMemTableNum += 
IoTDBDescriptor.getInstance().getConfig().getMemtableNumInEachStorageGroup() * 
diff;
-
-    if(!CONFIG.isEnableParameterAdapter()){
-      // the maxMemTableNum will also be set in tryToAdaptParameters, this 
should not move out
+    maxMemTableNum +=
+        
IoTDBDescriptor.getInstance().getConfig().getMemtableNumInEachStorageGroup() * 
diff;
+    if (!CONFIG.isEnableParameterAdapter()) {
       CONFIG.setMaxMemtableNumber(maxMemTableNum);
       return;
     }
 
     if (!tryToAdaptParameters()) {
       totalStorageGroup -= diff;
-      maxMemTableNum -= 
IoTDBDescriptor.getInstance().getConfig().getMemtableNumInEachStorageGroup() * 
diff;
+      maxMemTableNum -=
+          
IoTDBDescriptor.getInstance().getConfig().getMemtableNumInEachStorageGroup() * 
diff;
       throw new ConfigAdjusterException(CREATE_STORAGE_GROUP);
     }
   }
@@ -297,4 +300,5 @@ public class IoTDBConfigDynamicAdapter implements 
IDynamicAdapter {
     }
 
   }
+
 }
diff --git 
a/server/src/main/java/org/apache/iotdb/db/engine/memtable/AbstractMemTable.java
 
b/server/src/main/java/org/apache/iotdb/db/engine/memtable/AbstractMemTable.java
index f9de3c7..7297c61 100644
--- 
a/server/src/main/java/org/apache/iotdb/db/engine/memtable/AbstractMemTable.java
+++ 
b/server/src/main/java/org/apache/iotdb/db/engine/memtable/AbstractMemTable.java
@@ -93,11 +93,11 @@ public abstract class AbstractMemTable implements IMemTable 
{
         Object value = 
CommonUtils.parseValue(insertPlan.getSchemas()[i].getType(),
             insertPlan.getValues()[i]);
 
+        memSize += 
MemUtils.getRecordSize(insertPlan.getSchemas()[i].getType(), value);
+
         write(insertPlan.getDeviceId(), insertPlan.getMeasurements()[i],
             insertPlan.getSchemas()[i], insertPlan.getTime(), value);
       }
-      long recordSizeInByte = MemUtils.getRecordSize(insertPlan);
-      memSize += recordSizeInByte;
     } catch (QueryProcessException e) {
       throw new WriteProcessException(e.getMessage());
     }
diff --git 
a/server/src/main/java/org/apache/iotdb/db/engine/storagegroup/TsFileProcessor.java
 
b/server/src/main/java/org/apache/iotdb/db/engine/storagegroup/TsFileProcessor.java
index 2ee5c9f..ae81a7d 100644
--- 
a/server/src/main/java/org/apache/iotdb/db/engine/storagegroup/TsFileProcessor.java
+++ 
b/server/src/main/java/org/apache/iotdb/db/engine/storagegroup/TsFileProcessor.java
@@ -33,6 +33,7 @@ import org.apache.iotdb.db.conf.IoTDBDescriptor;
 import org.apache.iotdb.db.conf.adapter.ActiveTimeSeriesCounter;
 import org.apache.iotdb.db.conf.adapter.CompressionRatio;
 import org.apache.iotdb.db.conf.adapter.IoTDBConfigDynamicAdapter;
+import org.apache.iotdb.db.engine.cache.RamUsageEstimator;
 import org.apache.iotdb.db.engine.flush.FlushManager;
 import org.apache.iotdb.db.engine.flush.MemTableFlushTask;
 import org.apache.iotdb.db.engine.flush.NotifyFlushMemTable;
@@ -87,6 +88,7 @@ public class TsFileProcessor {
    */
   private volatile boolean shouldClose;
   private IMemTable workMemTable;
+
   private VersionController versionController;
   /**
    * this callback is called after the corresponding TsFile is called 
endFile().
diff --git a/server/src/main/java/org/apache/iotdb/db/utils/MemUtils.java 
b/server/src/main/java/org/apache/iotdb/db/utils/MemUtils.java
index 5229c48..7946ba6 100644
--- a/server/src/main/java/org/apache/iotdb/db/utils/MemUtils.java
+++ b/server/src/main/java/org/apache/iotdb/db/utils/MemUtils.java
@@ -19,8 +19,9 @@
 package org.apache.iotdb.db.utils;
 
 import org.apache.iotdb.db.conf.IoTDBConstant;
+import org.apache.iotdb.db.engine.cache.RamUsageEstimator;
 import org.apache.iotdb.db.qp.physical.crud.BatchInsertPlan;
-import org.apache.iotdb.db.qp.physical.crud.InsertPlan;
+import org.apache.iotdb.tsfile.file.metadata.enums.TSDataType;
 import org.apache.iotdb.tsfile.utils.Binary;
 import org.apache.iotdb.tsfile.write.record.TSRecord;
 import org.apache.iotdb.tsfile.write.record.datapoint.BooleanDataPoint;
@@ -43,29 +44,30 @@ public class MemUtils {
   }
 
   /**
-   * function for getting the record size.
+   * function for getting the value size.
    */
-  public static long getRecordSize(InsertPlan insertPlan) {
-    long memSize = 0;
-    for (int i = 0; i < insertPlan.getValues().length; i++) {
-      switch (insertPlan.getSchemas()[i].getType()) {
-        case INT32:
-          memSize += 8L + 4L; break;
-        case INT64:
-          memSize += 8L + 8L; break;
-        case FLOAT:
-          memSize += 8L + 4L; break;
-        case DOUBLE:
-          memSize += 8L + 8L; break;
-        case BOOLEAN:
-          memSize += 8L + 1L; break;
-        case TEXT:
-          memSize += 8L + insertPlan.getValues()[i].length(); break;
-        default:
-          memSize += 8L + 8L;
-      }
+  public static long getRecordSize(TSDataType dataType, Object value) {
+    switch (dataType) {
+      case INT32:
+        return 8L + 4L;
+      case INT64:
+        return 8L + 8L;
+      case FLOAT:
+        return 8L + 4L;
+      case DOUBLE:
+        return 8L + 8L;
+      case BOOLEAN:
+        return 8L + 1L;
+      case TEXT:
+        return 8L + getBinarySize((Binary) value);
+      default:
+        return 8L + 8L;
     }
-    return memSize;
+  }
+
+  public static long getBinarySize(Binary value) {
+    return RamUsageEstimator.NUM_BYTES_OBJECT_HEADER + RamUsageEstimator
+        .sizeOf(value.getValues());
   }
 
   public static long getRecordSize(BatchInsertPlan batchInsertPlan, int start, 
int end) {
@@ -88,7 +90,7 @@ public class MemUtils {
         case TEXT:
           memSize += (end - start) * 8L;
           for (int j = start; j < end; j++) {
-            memSize += ((Binary[]) 
batchInsertPlan.getColumns()[i])[j].getLength();
+            memSize += getBinarySize(((Binary[]) 
batchInsertPlan.getColumns()[i])[j]);
           }
           break;
         default:
diff --git 
a/server/src/main/java/org/apache/iotdb/db/writelog/node/ExclusiveWriteLogNode.java
 
b/server/src/main/java/org/apache/iotdb/db/writelog/node/ExclusiveWriteLogNode.java
index b9b5e0a..dda1a7e 100644
--- 
a/server/src/main/java/org/apache/iotdb/db/writelog/node/ExclusiveWriteLogNode.java
+++ 
b/server/src/main/java/org/apache/iotdb/db/writelog/node/ExclusiveWriteLogNode.java
@@ -46,7 +46,6 @@ public class ExclusiveWriteLogNode implements WriteLogNode, 
Comparable<Exclusive
 
   public static final String WAL_FILE_NAME = "wal";
   private static final Logger logger = 
LoggerFactory.getLogger(ExclusiveWriteLogNode.class);
-  private static int logBufferSize = 
IoTDBDescriptor.getInstance().getConfig().getWalBufferSize();
 
   private String identifier;
 
@@ -56,7 +55,8 @@ public class ExclusiveWriteLogNode implements WriteLogNode, 
Comparable<Exclusive
 
   private IoTDBConfig config = IoTDBDescriptor.getInstance().getConfig();
 
-  private ByteBuffer logBuffer = ByteBuffer.allocate(logBufferSize);
+  private ByteBuffer logBuffer = ByteBuffer
+      .allocate(IoTDBDescriptor.getInstance().getConfig().getWalBufferSize());
 
   private ReadWriteLock lock = new ReentrantReadWriteLock();
 
@@ -88,7 +88,9 @@ public class ExclusiveWriteLogNode implements WriteLogNode, 
Comparable<Exclusive
         sync();
       }
     } catch (BufferOverflowException e) {
-      throw new IOException("Log cannot fit into buffer, please increase 
wal_buffer_size", e);
+      throw new IOException(
+          "Log cannot fit into buffer, if you don't enable Dynamic Parameter 
Adapter, please increase wal_buffer_size;"
+              + "otherwise, please increase the JVM memory", e);
     } finally {
       lock.writeLock().unlock();
     }

Reply via email to