Xiangdong Huang created IOTDB-735:
-------------------------------------

             Summary: Concurrent error for MNode when creating time series 
automatically
                 Key: IOTDB-735
                 URL: https://issues.apache.org/jira/browse/IOTDB-735
             Project: Apache IoTDB
          Issue Type: Bug
          Components: Core/Engine
    Affects Versions: 0.9.3, 0.10.0-SNAPSHOT
            Reporter: Xiangdong Huang


When multiply users write time series data concurrently and IoTDB enables 
auto_create_timeseries, sometimes NullpointException may be thrown from 
PlanExecutor.

 

The NullPointer exception is thrown from `LeafMNode measurementNode = 
(LeafMNode) node.getChild(measurement);`. 

 
{code:java}
// code placeholder
@Override
public void insert(InsertPlan insertPlan) throws QueryProcessException {
  MNode node = null;
  try {
    String[] measurementList = insertPlan.getMeasurements();
    String deviceId = insertPlan.getDeviceId();
    node = mManager.getDeviceNodeWithAutoCreateAndReadLock(deviceId);
    MeasurementSchema[] schemas = new MeasurementSchema[measurementList.length];

    for (int i = 0; i < measurementList.length; i++) {
      String measurement = measurementList[i];
      if (!node.hasChild(measurement)) {
        if 
(!IoTDBDescriptor.getInstance().getConfig().isAutoCreateSchemaEnabled()) {
          throw new PathNotExistException(deviceId + PATH_SEPARATOR + 
measurement);
        }
        TSDataType dataType = TypeInferenceUtils
            .getPredictedDataType(insertPlan.getValues()[i], 
insertPlan.isInferType());
        Path path = new Path(deviceId, measurement);
        internalCreateTimeseries(path.toString(), dataType);
      }
      LeafMNode measurementNode = (LeafMNode) node.getChild(measurement);
      schemas[i] = measurementNode.getSchema();
      // reset measurement to common name instead of alias
      measurementList[i] = measurementNode.getName();

      if(!insertPlan.isInferType()) {
        checkType(insertPlan, i, measurementNode.getSchema().getType());
      }
    }

    insertPlan.setMeasurements(measurementList);
    insertPlan.setSchemasAndTransferType(schemas);
    StorageEngine.getInstance().insert(insertPlan);
  } catch (StorageEngineException | MetadataException e) {
    throw new QueryProcessException(e);
  } finally {
    if (node != null) {
      ((InternalMNode) node).readUnlock();
    }
  }
}
{code}
The reason is, this method operates MNode instance directly without mtree.lock. 
Then, when `node.getChild()` is called, someone may call `node.addChild()` and 
the Concurrent error may lead the `node.getChild()` returns null.

 

So, be careful when you directly operate a MNode instance.

 

 

 

 

 



--
This message was sent by Atlassian Jira
(v8.3.4#803005)

Reply via email to