Details
-
Bug
-
Status: Open
-
Major
-
Resolution: Unresolved
-
None
-
None
-
None
Description
Currently RegionSnapshotService save attempts to deserialize the value before writing it to the snapshot file.
org.apache.geode.SerializationException: An IOException was thrown while deserializing at org.apache.geode.internal.cache.EntryEventImpl.deserialize(EntryEventImpl.java:1915) at org.apache.geode.internal.cache.EntryEventImpl.deserialize(EntryEventImpl.java:1904) at org.apache.geode.internal.cache.VMCachedDeserializable.getDeserializedValue(VMCachedDeserializable.java:134) at org.apache.geode.internal.cache.EntrySnapshot.getRawValue(EntrySnapshot.java:113) at org.apache.geode.internal.cache.EntrySnapshot.getRawValue(EntrySnapshot.java:101) at org.apache.geode.internal.cache.EntrySnapshot.getValue(EntrySnapshot.java:130) at org.apache.geode.internal.cache.snapshot.SnapshotPacket$SnapshotRecord.<init>(SnapshotPacket.java:79) at org.apache.geode.internal.cache.snapshot.LocalExporter.export(LocalExporter.java:46) at org.apache.geode.internal.cache.snapshot.RegionSnapshotServiceImpl.exportOnMember(RegionSnapshotServiceImpl.java:322) at org.apache.geode.internal.cache.snapshot.RegionSnapshotServiceImpl.save(RegionSnapshotServiceImpl.java:150) at org.apache.geode.internal.cache.snapshot.RegionSnapshotServiceImpl.save(RegionSnapshotServiceImpl.java:133) Caused by: java.io.IOException: Unknown header byte: -3 at org.apache.geode.internal.InternalDataSerializer.basicReadObject(InternalDataSerializer.java:2876) at org.apache.geode.DataSerializer.readObject(DataSerializer.java:2961) at org.apache.geode.internal.util.BlobHelper.deserializeBlob(BlobHelper.java:99) at org.apache.geode.internal.cache.EntryEventImpl.deserialize(EntryEventImpl.java:1911)
Instead it should just take the serialized bytes and write them to the file.
The SnapshotRecord constructor calls entry.getValue() which deserializes the value here:
public <K, V> SnapshotRecord(LocalRegion region, Entry<K, V> entry) throws IOException { key = BlobHelper.serializeToBlob(entry.getKey()); if (entry instanceof NonTXEntry && region != null) { @Released Object v = ((NonTXEntry) entry).getRegionEntry().getValueOffHeapOrDiskWithoutFaultIn(region); try { value = convertToBytes(v); } finally { OffHeapHelper.release(v); } } else { -> value = convertToBytes(entry.getValue()); } }
Code like this gets the CachedDeserializable instead:
value = convertToBytes(((EntrySnapshot) entry).getRegionEntry().getValue(null));
which when passed to convertToBytes gets the bytes instead:
byte[] bytes = ((CachedDeserializable) val).getSerializedValue();
Currently, export can fail with serialization exceptions on corrupted records. Not deserializing the value would hide corrupted data and propagate it via import into the new system. Any access will cause the SerializationException.