You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@iotdb.apache.org by xi...@apache.org on 2021/07/20 08:08:45 UTC

[iotdb] 01/01: Add overlapped page rate in tracing

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

xiangweiwei pushed a commit to branch optTracing
in repository https://gitbox.apache.org/repos/asf/iotdb.git

commit d3ee8dc6190575b7096b8b37fc2c68de1d128b68
Author: Alima777 <wx...@gmail.com>
AuthorDate: Tue Jul 20 16:08:02 2021 +0800

    Add overlapped page rate in tracing
---
 .../java/org/apache/iotdb/db/conf/IoTDBConfig.java |  2 +-
 .../db/query/control/QueryResourceManager.java     | 52 +++---------
 .../apache/iotdb/db/query/control/TracingInfo.java | 84 +++++++++++++++++++
 .../iotdb/db/query/control/TracingManager.java     | 80 ++++++++++---------
 .../iotdb/db/query/reader/series/SeriesReader.java | 93 ++++++++++++----------
 .../reader/universal/DescPriorityMergeReader.java  |  5 +-
 .../reader/universal/PriorityMergeReader.java      | 17 +++-
 .../iotdb/db/query/control/TracingManagerTest.java |  7 +-
 8 files changed, 212 insertions(+), 128 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 4b8d6b8..eb14e0f 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
@@ -313,7 +313,7 @@ public class IoTDBConfig {
   private int mergePagePointNumberThreshold = 100;
 
   /** LEVEL_COMPACTION, NO_COMPACTION */
-  private CompactionStrategy compactionStrategy = CompactionStrategy.LEVEL_COMPACTION;
+  private CompactionStrategy compactionStrategy = CompactionStrategy.NO_COMPACTION;
 
   /**
    * Works when the compaction_strategy is LEVEL_COMPACTION. Whether to merge unseq files into seq
diff --git a/server/src/main/java/org/apache/iotdb/db/query/control/QueryResourceManager.java b/server/src/main/java/org/apache/iotdb/db/query/control/QueryResourceManager.java
index d0042a1..773d467 100644
--- a/server/src/main/java/org/apache/iotdb/db/query/control/QueryResourceManager.java
+++ b/server/src/main/java/org/apache/iotdb/db/query/control/QueryResourceManager.java
@@ -23,7 +23,6 @@ import org.apache.iotdb.db.conf.IoTDBConstant;
 import org.apache.iotdb.db.conf.IoTDBDescriptor;
 import org.apache.iotdb.db.engine.StorageEngine;
 import org.apache.iotdb.db.engine.querycontext.QueryDataSource;
-import org.apache.iotdb.db.engine.storagegroup.TsFileResource;
 import org.apache.iotdb.db.exception.StorageEngineException;
 import org.apache.iotdb.db.exception.query.PathNumOverLimitException;
 import org.apache.iotdb.db.exception.query.QueryProcessException;
@@ -40,10 +39,8 @@ import org.slf4j.LoggerFactory;
 import java.io.File;
 import java.io.IOException;
 import java.util.ArrayList;
-import java.util.HashSet;
 import java.util.List;
 import java.util.Map;
-import java.util.Set;
 import java.util.concurrent.ConcurrentHashMap;
 import java.util.concurrent.atomic.AtomicLong;
 
@@ -58,14 +55,8 @@ public class QueryResourceManager {
   private final AtomicLong queryIdAtom = new AtomicLong();
   private final QueryFileManager filePathsManager;
   private static final Logger logger = LoggerFactory.getLogger(QueryResourceManager.class);
-  // record the total number and size of chunks for each query id
-  private Map<Long, Integer> chunkNumMap = new ConcurrentHashMap<>();
-  // chunk size represents the number of time-value points in the chunk
-  private Map<Long, Long> chunkSizeMap = new ConcurrentHashMap<>();
-  // record the distinct tsfiles for each query id
-  private Map<Long, Set<TsFileResource>> seqFileNumMap = new ConcurrentHashMap<>();
-  private Map<Long, Set<TsFileResource>> unseqFileNumMap = new ConcurrentHashMap<>();
-  private IoTDBConfig config = IoTDBDescriptor.getInstance().getConfig();
+
+  private Map<Long, TracingInfo> tracingInfoMap = new ConcurrentHashMap<>();
 
   /**
    * Record temporary files used for external sorting.
@@ -131,12 +122,8 @@ public class QueryResourceManager {
     return queryId;
   }
 
-  public Map<Long, Integer> getChunkNumMap() {
-    return chunkNumMap;
-  }
-
-  public Map<Long, Long> getChunkSizeMap() {
-    return chunkSizeMap;
+  public Map<Long, TracingInfo> getTracingInfoMap() {
+    return tracingInfoMap;
   }
 
   /**
@@ -159,13 +146,10 @@ public class QueryResourceManager {
     QueryDataSource queryDataSource =
         StorageEngine.getInstance().query(singleSeriesExpression, context, filePathsManager);
     // calculate the distinct number of seq and unseq tsfiles
-    if (config.isEnablePerformanceTracing()) {
-      seqFileNumMap
-          .computeIfAbsent(context.getQueryId(), k -> new HashSet<>())
-          .addAll((queryDataSource.getSeqResources()));
-      unseqFileNumMap
-          .computeIfAbsent(context.getQueryId(), k -> new HashSet<>())
-          .addAll((queryDataSource.getUnseqResources()));
+    if (CONFIG.isEnablePerformanceTracing()) {
+      tracingInfoMap
+          .computeIfAbsent(context.getQueryId(), k -> new TracingInfo())
+          .addTsFileSet(queryDataSource.getSeqResources(), queryDataSource.getUnseqResources());
     }
     return queryDataSource;
   }
@@ -177,26 +161,14 @@ public class QueryResourceManager {
   @SuppressWarnings("squid:S3776") // Suppress high Cognitive Complexity warning
   public void endQuery(long queryId) throws StorageEngineException {
     try {
-      if (config.isEnablePerformanceTracing()) {
-        boolean isprinted = false;
-        if (seqFileNumMap.get(queryId) != null && unseqFileNumMap.get(queryId) != null) {
-          TracingManager.getInstance()
-              .writeTsFileInfo(
-                  queryId, seqFileNumMap.remove(queryId), unseqFileNumMap.remove(queryId));
-          isprinted = true;
-        }
-        if (chunkNumMap.get(queryId) != null && chunkSizeMap.get(queryId) != null) {
-          TracingManager.getInstance()
-              .writeChunksInfo(queryId, chunkNumMap.remove(queryId), chunkSizeMap.remove(queryId));
-        }
-        if (isprinted) {
-          TracingManager.getInstance().writeEndTime(queryId);
-        }
+      if (CONFIG.isEnablePerformanceTracing() && tracingInfoMap.get(queryId) != null) {
+        TracingManager.getInstance().writeTracingInfo(queryId, tracingInfoMap.get(queryId));
+        TracingManager.getInstance().writeEndTime(queryId);
       }
     } catch (IOException e) {
       logger.error(
           "Error while writing performance info to {}, {}",
-          config.getTracingDir() + File.separator + IoTDBConstant.TRACING_LOG,
+          CONFIG.getTracingDir() + File.separator + IoTDBConstant.TRACING_LOG,
           e.getMessage());
     }
 
diff --git a/server/src/main/java/org/apache/iotdb/db/query/control/TracingInfo.java b/server/src/main/java/org/apache/iotdb/db/query/control/TracingInfo.java
new file mode 100644
index 0000000..2c9f73e
--- /dev/null
+++ b/server/src/main/java/org/apache/iotdb/db/query/control/TracingInfo.java
@@ -0,0 +1,84 @@
+/*
+ * 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.
+ */
+package org.apache.iotdb.db.query.control;
+
+import org.apache.iotdb.db.engine.storagegroup.TsFileResource;
+
+import java.util.HashSet;
+import java.util.List;
+import java.util.Set;
+
+/**
+ * A distinct TracingInfo is storaged for each query id, which includes the total number of chunks,
+ * the average points number of chunk, the information of sequence files and unSequence files this
+ * query involves.
+ */
+public class TracingInfo {
+
+  private int totalChunkNum = 0;
+  private long totalChunkPoints = 0;
+  private int totalPageNum = 0;
+  private int overlappedPageNum = 0;
+  private Set<TsFileResource> seqFileSet = new HashSet<>();
+  private Set<TsFileResource> unSeqFileSet = new HashSet<>();
+
+  public TracingInfo() {}
+
+  public int getTotalChunkNum() {
+    return totalChunkNum;
+  }
+
+  public long getTotalChunkPoints() {
+    return totalChunkPoints;
+  }
+
+  public void addChunkInfo(int totalChunkNum, long totalChunkPoints) {
+    this.totalChunkNum += totalChunkNum;
+    this.totalChunkPoints += totalChunkPoints;
+  }
+
+  public void addTotalPageNum(int totalPageNum) {
+    this.totalPageNum += totalPageNum;
+  }
+
+  public void addOverlappedPageNum() {
+    this.overlappedPageNum++;
+  }
+
+  public int getTotalPageNum() {
+    return totalPageNum;
+  }
+
+  public int getOverlappedPageNum() {
+    return overlappedPageNum;
+  }
+
+  public Set<TsFileResource> getSeqFileSet() {
+    return seqFileSet;
+  }
+
+  public Set<TsFileResource> getUnSeqFileSet() {
+    return unSeqFileSet;
+  }
+
+  public void addTsFileSet(List<TsFileResource> seqResources, List<TsFileResource> unSeqResources) {
+    this.seqFileSet.addAll(seqResources);
+    this.unSeqFileSet.addAll(unSeqResources);
+  }
+}
diff --git a/server/src/main/java/org/apache/iotdb/db/query/control/TracingManager.java b/server/src/main/java/org/apache/iotdb/db/query/control/TracingManager.java
index 450c4f4..5723656 100644
--- a/server/src/main/java/org/apache/iotdb/db/query/control/TracingManager.java
+++ b/server/src/main/java/org/apache/iotdb/db/query/control/TracingManager.java
@@ -119,6 +119,13 @@ public class TracingManager {
     writer.write(builder.toString());
   }
 
+  public void writeTracingInfo(long queryId, TracingInfo tracingInfo) throws IOException {
+    writeTsFileInfo(queryId, tracingInfo.getSeqFileSet(), tracingInfo.getUnSeqFileSet());
+    writeChunksInfo(queryId, tracingInfo.getTotalChunkNum(), tracingInfo.getTotalChunkPoints());
+    writeOverlappedPageInfo(
+        queryId, tracingInfo.getTotalPageNum(), tracingInfo.getOverlappedPageNum());
+  }
+
   public void writeTsFileInfo(
       long queryId, Set<TsFileResource> seqFileResources, Set<TsFileResource> unSeqFileResources)
       throws IOException {
@@ -129,13 +136,15 @@ public class TracingManager {
             .append(queryId)
             .append(" - Number of sequence files: ")
             .append(seqFileResources.size());
-    for (TsFileResource seqFileResource : seqFileResources) {
-      builder
-          .append("\n" + QUERY_ID)
-          .append(queryId)
-          .append(" - SeqFile_")
-          .append(seqFileResource.getTsFile().getName());
-      printTsFileStatistics(builder, seqFileResource);
+    if (!seqFileResources.isEmpty()) {
+      builder.append("\n" + QUERY_ID).append(queryId).append(" - SeqFiles: ");
+      Iterator<TsFileResource> seqFileIterator = seqFileResources.iterator();
+      while (seqFileIterator.hasNext()) {
+        builder.append(seqFileIterator.next().getTsFile().getName());
+        if (seqFileIterator.hasNext()) {
+          builder.append(", ");
+        }
+      }
     }
 
     builder
@@ -143,49 +152,42 @@ public class TracingManager {
         .append(queryId)
         .append(" - Number of unSequence files: ")
         .append(unSeqFileResources.size());
-    for (TsFileResource unSeqFileResource : unSeqFileResources) {
-      builder
-          .append("\n" + QUERY_ID)
-          .append(queryId)
-          .append(" - UnSeqFile_")
-          .append(unSeqFileResource.getTsFile().getName());
-      printTsFileStatistics(builder, unSeqFileResource);
+    if (!unSeqFileResources.isEmpty()) {
+      builder.append("\n" + QUERY_ID).append(queryId).append(" - UnSeqFiles: ");
+      Iterator<TsFileResource> unSeqFileIterator = unSeqFileResources.iterator();
+      while (unSeqFileIterator.hasNext()) {
+        builder.append(unSeqFileIterator.next().getTsFile().getName());
+        if (unSeqFileIterator.hasNext()) {
+          builder.append(", ");
+        }
+      }
     }
     builder.append("\n");
     writer.write(builder.toString());
   }
 
-  // print startTime and endTime of each device, format e.g.: device1[1, 10000]
-  private void printTsFileStatistics(StringBuilder builder, TsFileResource tsFileResource) {
-    Iterator<String> deviceIter = tsFileResource.getDevices().iterator();
-    while (deviceIter.hasNext()) {
-      String device = deviceIter.next();
-      builder
-          .append(" ")
-          .append(device)
-          .append("[")
-          .append(tsFileResource.getStartTime(device))
-          .append(", ")
-          .append(tsFileResource.getEndTime(device))
-          .append("]");
-      if (deviceIter.hasNext()) {
-        builder.append(",");
-      }
-    }
+  public void writeChunksInfo(long queryId, long totalChunkNum, long totalChunkPoints)
+      throws IOException {
+    StringBuilder builder =
+        new StringBuilder(QUERY_ID)
+            .append(queryId)
+            .append(String.format(" - Number of chunks: %d", totalChunkNum))
+            .append(", Average data points of chunks: ")
+            .append(totalChunkPoints / totalChunkNum)
+            .append("\n");
+    writer.write(builder.toString());
   }
 
-  public void writeChunksInfo(long queryId, long totalChunkNum, long totalChunkSize)
+  public void writeOverlappedPageInfo(long queryId, int totalPageNum, int overlappedPageNum)
       throws IOException {
     StringBuilder builder =
         new StringBuilder(QUERY_ID)
             .append(queryId)
-            .append(" - Number of chunks: ")
-            .append(totalChunkNum)
-            .append("\n" + QUERY_ID)
-            .append(queryId)
-            .append(" - Average size of chunks: ")
-            .append(totalChunkSize / totalChunkNum)
-            .append("\n");
+            .append(" - Rate of overlapped pages: ")
+            .append(String.format("%.1f%%, ", (double) overlappedPageNum / totalPageNum * 100))
+            .append(
+                String.format(
+                    "%d overlapped pages in total %d pages.\n", overlappedPageNum, totalPageNum));
     writer.write(builder.toString());
   }
 
diff --git a/server/src/main/java/org/apache/iotdb/db/query/reader/series/SeriesReader.java b/server/src/main/java/org/apache/iotdb/db/query/reader/series/SeriesReader.java
index b225a0f..481b45b 100644
--- a/server/src/main/java/org/apache/iotdb/db/query/reader/series/SeriesReader.java
+++ b/server/src/main/java/org/apache/iotdb/db/query/reader/series/SeriesReader.java
@@ -18,6 +18,7 @@
  */
 package org.apache.iotdb.db.query.reader.series;
 
+import org.apache.iotdb.db.conf.IoTDBConfig;
 import org.apache.iotdb.db.conf.IoTDBDescriptor;
 import org.apache.iotdb.db.engine.querycontext.QueryDataSource;
 import org.apache.iotdb.db.engine.storagegroup.TsFileResource;
@@ -25,6 +26,7 @@ import org.apache.iotdb.db.metadata.PartialPath;
 import org.apache.iotdb.db.query.context.QueryContext;
 import org.apache.iotdb.db.query.control.QueryResourceManager;
 import org.apache.iotdb.db.query.control.QueryTimeManager;
+import org.apache.iotdb.db.query.control.TracingInfo;
 import org.apache.iotdb.db.query.filter.TsFileFilter;
 import org.apache.iotdb.db.query.reader.universal.DescPriorityMergeReader;
 import org.apache.iotdb.db.query.reader.universal.PriorityMergeReader;
@@ -56,6 +58,7 @@ import java.util.stream.Collectors;
 
 public class SeriesReader {
 
+  private static final IoTDBConfig CONFIG = IoTDBDescriptor.getInstance().getConfig();
   // inner class of SeriesReader for order purpose
   protected TimeOrderUtils orderUtils;
 
@@ -367,19 +370,14 @@ public class SeriesReader {
     // try to calculate the total number of chunk and time-value points in chunk
     if (IoTDBDescriptor.getInstance().getConfig().isEnablePerformanceTracing()) {
       QueryResourceManager queryResourceManager = QueryResourceManager.getInstance();
-      queryResourceManager
-          .getChunkNumMap()
-          .compute(
-              context.getQueryId(),
-              (k, v) -> v == null ? chunkMetadataList.size() : v + chunkMetadataList.size());
-
-      long totalChunkSize =
+      long totalChunkPointsNum =
           chunkMetadataList.stream()
               .mapToLong(chunkMetadata -> chunkMetadata.getStatistics().getCount())
               .sum();
       queryResourceManager
-          .getChunkSizeMap()
-          .compute(context.getQueryId(), (k, v) -> v == null ? totalChunkSize : v + totalChunkSize);
+          .getTracingInfoMap()
+          .computeIfAbsent(context.getQueryId(), k -> new TracingInfo())
+          .addChunkInfo(chunkMetadataList.size(), totalChunkPointsNum);
     }
 
     cachedChunkMetadata.addAll(chunkMetadataList);
@@ -539,37 +537,43 @@ public class SeriesReader {
   }
 
   private void unpackOneChunkMetaData(IChunkMetadata chunkMetaData) throws IOException {
-    FileLoaderUtils.loadPageReaderList(chunkMetaData, timeFilter)
-        .forEach(
-            pageReader -> {
-              if (chunkMetaData.isSeq()) {
-                // addLast for asc; addFirst for desc
-                if (orderUtils.getAscending()) {
-                  seqPageReaders.add(
-                      new VersionPageReader(
-                          chunkMetaData.getVersion(),
-                          chunkMetaData.getOffsetOfChunkHeader(),
-                          pageReader,
-                          true));
-                } else {
-                  seqPageReaders.add(
-                      0,
-                      new VersionPageReader(
-                          chunkMetaData.getVersion(),
-                          chunkMetaData.getOffsetOfChunkHeader(),
-                          pageReader,
-                          true));
-                }
-
-              } else {
-                unSeqPageReaders.add(
-                    new VersionPageReader(
-                        chunkMetaData.getVersion(),
-                        chunkMetaData.getOffsetOfChunkHeader(),
-                        pageReader,
-                        false));
-              }
-            });
+    List<IPageReader> pageReaderList =
+        FileLoaderUtils.loadPageReaderList(chunkMetaData, timeFilter);
+    if (CONFIG.isEnablePerformanceTracing()) {
+      QueryResourceManager.getInstance()
+          .getTracingInfoMap()
+          .computeIfAbsent(context.getQueryId(), k -> new TracingInfo())
+          .addTotalPageNum(pageReaderList.size());
+    }
+    pageReaderList.forEach(
+        pageReader -> {
+          if (chunkMetaData.isSeq()) {
+            // addLast for asc; addFirst for desc
+            if (orderUtils.getAscending()) {
+              seqPageReaders.add(
+                  new VersionPageReader(
+                      chunkMetaData.getVersion(),
+                      chunkMetaData.getOffsetOfChunkHeader(),
+                      pageReader,
+                      true));
+            } else {
+              seqPageReaders.add(
+                  0,
+                  new VersionPageReader(
+                      chunkMetaData.getVersion(),
+                      chunkMetaData.getOffsetOfChunkHeader(),
+                      pageReader,
+                      true));
+            }
+          } else {
+            unSeqPageReaders.add(
+                new VersionPageReader(
+                    chunkMetaData.getVersion(),
+                    chunkMetaData.getOffsetOfChunkHeader(),
+                    pageReader,
+                    false));
+          }
+        });
   }
 
   /**
@@ -736,7 +740,8 @@ public class SeriesReader {
                       .getAllSatisfiedPageData(orderUtils.getAscending())
                       .getBatchDataIterator(),
                   firstPageReader.version,
-                  orderUtils.getOverlapCheckTime(firstPageReader.getStatistics()));
+                  orderUtils.getOverlapCheckTime(firstPageReader.getStatistics()),
+                  context);
               currentPageEndPointTime =
                   updateEndPointTime(currentPageEndPointTime, firstPageReader);
               firstPageReader = null;
@@ -760,7 +765,8 @@ public class SeriesReader {
                       .getAllSatisfiedPageData(orderUtils.getAscending())
                       .getBatchDataIterator(),
                   pageReader.version,
-                  orderUtils.getOverlapCheckTime(pageReader.getStatistics()));
+                  orderUtils.getOverlapCheckTime(pageReader.getStatistics()),
+                  context);
               currentPageEndPointTime = updateEndPointTime(currentPageEndPointTime, pageReader);
             }
           }
@@ -867,7 +873,8 @@ public class SeriesReader {
     mergeReader.addReader(
         pageReader.getAllSatisfiedPageData(orderUtils.getAscending()).getBatchDataIterator(),
         pageReader.version,
-        orderUtils.getOverlapCheckTime(pageReader.getStatistics()));
+        orderUtils.getOverlapCheckTime(pageReader.getStatistics()),
+        context);
   }
 
   private BatchData nextOverlappedPage() throws IOException {
diff --git a/server/src/main/java/org/apache/iotdb/db/query/reader/universal/DescPriorityMergeReader.java b/server/src/main/java/org/apache/iotdb/db/query/reader/universal/DescPriorityMergeReader.java
index d73fc14..06fd982 100644
--- a/server/src/main/java/org/apache/iotdb/db/query/reader/universal/DescPriorityMergeReader.java
+++ b/server/src/main/java/org/apache/iotdb/db/query/reader/universal/DescPriorityMergeReader.java
@@ -19,6 +19,7 @@
 
 package org.apache.iotdb.db.query.reader.universal;
 
+import org.apache.iotdb.db.query.context.QueryContext;
 import org.apache.iotdb.tsfile.read.reader.IPointReader;
 
 import java.io.IOException;
@@ -40,10 +41,12 @@ public class DescPriorityMergeReader extends PriorityMergeReader {
    * @param reader
    * @param priority
    * @param endTime
+   * @param queryContext
    * @throws IOException
    */
   @Override
-  public void addReader(IPointReader reader, MergeReaderPriority priority, long endTime)
+  public void addReader(
+      IPointReader reader, MergeReaderPriority priority, long endTime, QueryContext queryContext)
       throws IOException {
     if (reader.hasNextTimeValuePair()) {
       heap.add(new Element(reader, reader.nextTimeValuePair(), priority));
diff --git a/server/src/main/java/org/apache/iotdb/db/query/reader/universal/PriorityMergeReader.java b/server/src/main/java/org/apache/iotdb/db/query/reader/universal/PriorityMergeReader.java
index 2b7db36..b9fc4c5 100644
--- a/server/src/main/java/org/apache/iotdb/db/query/reader/universal/PriorityMergeReader.java
+++ b/server/src/main/java/org/apache/iotdb/db/query/reader/universal/PriorityMergeReader.java
@@ -18,6 +18,10 @@
  */
 package org.apache.iotdb.db.query.reader.universal;
 
+import org.apache.iotdb.db.conf.IoTDBDescriptor;
+import org.apache.iotdb.db.query.context.QueryContext;
+import org.apache.iotdb.db.query.control.QueryResourceManager;
+import org.apache.iotdb.db.query.control.TracingInfo;
 import org.apache.iotdb.tsfile.read.TimeValuePair;
 import org.apache.iotdb.tsfile.read.reader.IPointReader;
 
@@ -70,16 +74,27 @@ public class PriorityMergeReader implements IPointReader {
     }
   }
 
-  public void addReader(IPointReader reader, MergeReaderPriority priority, long endTime)
+  public void addReader(
+      IPointReader reader, MergeReaderPriority priority, long endTime, QueryContext context)
       throws IOException {
     if (reader.hasNextTimeValuePair()) {
       heap.add(new Element(reader, reader.nextTimeValuePair(), priority));
       currentReadStopTime = Math.max(currentReadStopTime, endTime);
+      if (IoTDBDescriptor.getInstance().getConfig().isEnablePerformanceTracing()) {
+        addOverlappedPageNum(context);
+      }
     } else {
       reader.close();
     }
   }
 
+  private void addOverlappedPageNum(QueryContext context) {
+    QueryResourceManager.getInstance()
+        .getTracingInfoMap()
+        .computeIfAbsent(context.getQueryId(), k -> new TracingInfo())
+        .addOverlappedPageNum();
+  }
+
   public long getCurrentReadStopTime() {
     return currentReadStopTime;
   }
diff --git a/server/src/test/java/org/apache/iotdb/db/query/control/TracingManagerTest.java b/server/src/test/java/org/apache/iotdb/db/query/control/TracingManagerTest.java
index 3f1f0a9..3dae0d9 100644
--- a/server/src/test/java/org/apache/iotdb/db/query/control/TracingManagerTest.java
+++ b/server/src/test/java/org/apache/iotdb/db/query/control/TracingManagerTest.java
@@ -75,10 +75,10 @@ public class TracingManagerTest {
       "Query Id: 10 - Start time: 2020-12-",
       "Query Id: 10 - Number of series paths: 3",
       "Query Id: 10 - Number of sequence files: 1",
-      "Query Id: 10 - SeqFile_1-1-0.tsfile root.sg.d1[1, 999], root.sg.d2[2, 998]",
+      "Query Id: 10 - SeqFiles: 1-1-0.tsfile",
       "Query Id: 10 - Number of unSequence files: 0",
-      "Query Id: 10 - Number of chunks: 3",
-      "Query Id: 10 - Average size of chunks: 1371",
+      "Query Id: 10 - Number of chunks: 3, Average data points of chunks: 1371",
+      "Query Id: 10 - Rate of overlapped pages: 50.0%, 10 overlapped pages in total 20 pages",
       "Query Id: 10 - Total cost time: "
     };
     tracingManager.writeQueryInfo(queryId, sql, 1607529600000L);
@@ -86,6 +86,7 @@ public class TracingManagerTest {
     tracingManager.writeQueryInfo(queryId, sql, 1607529600000L, 3);
     tracingManager.writeTsFileInfo(queryId, seqResources, Collections.EMPTY_SET);
     tracingManager.writeChunksInfo(queryId, 3, 4113L);
+    tracingManager.writeOverlappedPageInfo(queryId, 20, 10);
     tracingManager.writeEndTime(queryId);
     tracingManager.close();