[ 
https://issues.apache.org/jira/browse/GEODE-10171?page=com.atlassian.jira.plugin.system.issuetabpanels:all-tabpanel
 ]

Donal Evans updated GEODE-10171:
--------------------------------
    Description: 
For SADD, which may or may not modify the data in the region depending on 
whether the member being added is already present in the set, the version in 
AbstractRedisData is updated regardless of whether a Delta is sent to the 
secondary. This can lead to the version on the primary wrapping around to be 
equal to the version on the secondary, which means that if a delta is sent, it 
will not be applied on the secondary, leading to potential data loss.

Below is a test to show this behaviour:
{code:java}
@Test
public void deltaVersionOnPrimary_shouldNotUpdate_ifNoDeltaSent() {
  String originalMember = "fixedMemberName";
  String key = clusterStartUp.getKeyOnServer("tag", 1);
  
  // Version of primary = 0
  // Version of secondary = 0
  jedis.sadd(key, originalMember);

  // No changes are made to the set, since adding an already existing member 
doesn't modify it
  // Version of primary wraps around back to -1
  // Version of secondary doesn't change because we don't send a delta
  for (int i = 0; i < 255; ++i) {
    jedis.sadd(key, originalMember);
  }

  String newMember = "aNewMemberName";
  // Version of primary = 0
  // Version of secondary = 0, delta is not applied
  jedis.sadd(key, newMember);

  assertThat(jedis.smembers(key)).containsExactlyInAnyOrder(originalMember, 
newMember);

  clusterStartUp.crashVM(1); // kill primary server

  assertThat(jedis.smembers(key)).containsExactlyInAnyOrder(originalMember, 
newMember);
} {code}
The example here uses SADD, but potentially, any command that can be a no-op 
and uses a versioned Delta is at risk of hitting this. All commands should be 
checked to ensure they're not vulnerable to this bug.

  was:
For SADD, which may or may not modify the data in the region depending on 
whether the member being added is already present in the set, the version in 
AbstractRedisData is updated regardless of whether a Delta is sent to the 
secondary. This can lead to the version on the primary wrapping around to be 
equal to the version on the secondary, which means that if a delta is sent, it 
will not be applied on the secondary, leading to potential data loss.

Below is a test to show this behaviour:
{code:java}
@Test
public void deltaVersionOnPrimary_shouldNotUpdate_ifNoDeltaSent() {
  String originalMember = "fixedMemberName";
  String key = clusterStartUp.getKeyOnServer("lrem", 1);
  
  // Version of primary = 0
  // Version of secondary = 0
  jedis.sadd(key, originalMember);

  // No changes are made to the set, since adding an already existing member 
doesn't modify it
  // Version of primary wraps around back to -1
  // Version of secondary doesn't change because we don't send a delta
  for (int i = 0; i < 255; ++i) {
    jedis.sadd(key, originalMember);
  }

  String newMember = "aNewMemberName";
  // Version of primary = 0
  // Version of secondary = 0, delta is not applied
  jedis.sadd(key, newMember);

  assertThat(jedis.smembers(key)).containsExactlyInAnyOrder(originalMember, 
newMember);

  clusterStartUp.crashVM(1); // kill primary server

  assertThat(jedis.smembers(key)).containsExactlyInAnyOrder(originalMember, 
newMember);
} {code}


> AbstractRedisData version being incremented for no-op operations can lead to 
> delta not being applied on secondary
> -----------------------------------------------------------------------------------------------------------------
>
>                 Key: GEODE-10171
>                 URL: https://issues.apache.org/jira/browse/GEODE-10171
>             Project: Geode
>          Issue Type: Bug
>          Components: redis
>    Affects Versions: 1.15.0
>            Reporter: Donal Evans
>            Priority: Major
>              Labels: blocks-1.15.0​
>
> For SADD, which may or may not modify the data in the region depending on 
> whether the member being added is already present in the set, the version in 
> AbstractRedisData is updated regardless of whether a Delta is sent to the 
> secondary. This can lead to the version on the primary wrapping around to be 
> equal to the version on the secondary, which means that if a delta is sent, 
> it will not be applied on the secondary, leading to potential data loss.
> Below is a test to show this behaviour:
> {code:java}
> @Test
> public void deltaVersionOnPrimary_shouldNotUpdate_ifNoDeltaSent() {
>   String originalMember = "fixedMemberName";
>   String key = clusterStartUp.getKeyOnServer("tag", 1);
>   
>   // Version of primary = 0
>   // Version of secondary = 0
>   jedis.sadd(key, originalMember);
>   // No changes are made to the set, since adding an already existing member 
> doesn't modify it
>   // Version of primary wraps around back to -1
>   // Version of secondary doesn't change because we don't send a delta
>   for (int i = 0; i < 255; ++i) {
>     jedis.sadd(key, originalMember);
>   }
>   String newMember = "aNewMemberName";
>   // Version of primary = 0
>   // Version of secondary = 0, delta is not applied
>   jedis.sadd(key, newMember);
>   assertThat(jedis.smembers(key)).containsExactlyInAnyOrder(originalMember, 
> newMember);
>   clusterStartUp.crashVM(1); // kill primary server
>   assertThat(jedis.smembers(key)).containsExactlyInAnyOrder(originalMember, 
> newMember);
> } {code}
> The example here uses SADD, but potentially, any command that can be a no-op 
> and uses a versioned Delta is at risk of hitting this. All commands should be 
> checked to ensure they're not vulnerable to this bug.



--
This message was sent by Atlassian Jira
(v8.20.1#820001)

Reply via email to