@@ -119,8 +119,17 @@ public class PartitionInfo implements SnapshotProcessor {
119119
120120 private static final Logger LOGGER = LoggerFactory .getLogger (PartitionInfo .class );
121121
122- // Allocate 8MB buffer for load snapshot of PartitionInfo
123- private static final int PARTITION_TABLE_BUFFER_SIZE = 32 * 1024 * 1024 ;
122+ /** Upper bound of a snapshot stream buffer, preserving the previous 32MB cap for large tables. */
123+ private static final int PARTITION_TABLE_BUFFER_SIZE_MAX = 32 * 1024 * 1024 ;
124+
125+ /** Fallback buffer size used when no snapshot size estimate is available yet. */
126+ private static final int DEFAULT_SNAPSHOT_BUFFER_SIZE = 8 * 1024 ;
127+
128+ /**
129+ * Size of the last written or loaded snapshot file, used to size the buffer of the next snapshot
130+ * adaptively instead of always allocating a fixed 32MB buffer.
131+ */
132+ private volatile long lastSnapshotSize = -1L ;
124133
125134 /** For Cluster Partition. */
126135 // For allocating Regions
@@ -978,6 +987,19 @@ public Map<TSeriesPartitionSlot, TConsensusGroupId> getLastDataAllotTable(String
978987 return Collections .emptyMap ();
979988 }
980989
990+ /**
991+ * Compute the buffer size for a snapshot file of {@code fileSize} bytes: the actual file size
992+ * when known, bounded by {@link #PARTITION_TABLE_BUFFER_SIZE_MAX} so that snapshot I/O never
993+ * allocates more than 32MB, falling back to {@link #DEFAULT_SNAPSHOT_BUFFER_SIZE} when no size
994+ * estimate is available.
995+ */
996+ static int getSnapshotBufferSize (final long fileSize ) {
997+ if (fileSize <= 0 ) {
998+ return DEFAULT_SNAPSHOT_BUFFER_SIZE ;
999+ }
1000+ return (int ) Math .min (fileSize , PARTITION_TABLE_BUFFER_SIZE_MAX );
1001+ }
1002+
9811003 @ Override
9821004 public boolean processTakeSnapshot (File snapshotDir ) throws TException , IOException {
9831005
@@ -993,9 +1015,11 @@ public boolean processTakeSnapshot(File snapshotDir) throws TException, IOExcept
9931015 // snapshot operation.
9941016 File tmpFile = new File (snapshotFile .getAbsolutePath () + "-" + UUID .randomUUID ());
9951017
1018+ // Size the write buffer from the last snapshot size, so a small partition table no longer
1019+ // allocates a fixed 32MB buffer per snapshot.
9961020 try (FileOutputStream fileOutputStream = new FileOutputStream (tmpFile );
9971021 BufferedOutputStream bufferedOutputStream =
998- new BufferedOutputStream (fileOutputStream , PARTITION_TABLE_BUFFER_SIZE );
1022+ new BufferedOutputStream (fileOutputStream , getSnapshotBufferSize ( lastSnapshotSize ) );
9991023 TIOStreamTransport tioStreamTransport = new TIOStreamTransport (bufferedOutputStream )) {
10001024 TProtocol protocol = new TBinaryProtocol (tioStreamTransport );
10011025
@@ -1024,7 +1048,12 @@ public boolean processTakeSnapshot(File snapshotDir) throws TException, IOExcept
10241048 tioStreamTransport .close ();
10251049
10261050 // rename file
1027- return tmpFile .renameTo (snapshotFile );
1051+ final boolean renamed = tmpFile .renameTo (snapshotFile );
1052+ if (renamed ) {
1053+ // Remember the file size to size the buffer of the next snapshot.
1054+ lastSnapshotSize = snapshotFile .length ();
1055+ }
1056+ return renamed ;
10281057 } finally {
10291058 // with or without success, delete temporary files anyway
10301059 for (int retry = 0 ; retry < 5 ; retry ++) {
@@ -1050,9 +1079,12 @@ public void processLoadSnapshot(final File snapshotDir) throws TException, IOExc
10501079 return ;
10511080 }
10521081
1082+ // Size the read buffer from the file size, so loading a small snapshot no longer allocates a
1083+ // fixed 32MB buffer.
10531084 try (final BufferedInputStream fileInputStream =
10541085 new BufferedInputStream (
1055- Files .newInputStream (snapshotFile .toPath ()), PARTITION_TABLE_BUFFER_SIZE );
1086+ Files .newInputStream (snapshotFile .toPath ()),
1087+ getSnapshotBufferSize (snapshotFile .length ()));
10561088 final TIOStreamTransport tioStreamTransport = new TIOStreamTransport (fileInputStream )) {
10571089 final TProtocol protocol = new TBinaryProtocol (tioStreamTransport );
10581090 // before restoring a snapshot, clear all old data
@@ -1082,6 +1114,9 @@ public void processLoadSnapshot(final File snapshotDir) throws TException, IOExc
10821114 regionMaintainTaskList .add (task );
10831115 }
10841116 }
1117+
1118+ // Remember the loaded file size to size the buffer of the next snapshot.
1119+ lastSnapshotSize = snapshotFile .length ();
10851120 }
10861121
10871122 /**
0 commit comments