[ https://issues.apache.org/jira/browse/ZOOKEEPER-4681?page=com.atlassian.jira.plugin.system.issuetabpanels:all-tabpanel ]
krystal he updated ZOOKEEPER-4681: ---------------------------------- Description: Using a [tool|https://github.com/kry4tall/CC-ZOO358] that I modifyed from [Filip Niksic's zootester|https://github.com/fniksic/zootester] for testing ZooKeeper, I discovered the following scenario which causes uncommitted requests to be executed. Zab protocol has three rounds: PROPOSE, ACK, and COMMIT. My tool can isolate the PROPOSAL, ACK and COMMIT messages and collect the values of some variables of each server at the end of each round. Setup: The code for isolating messages and collecting variable values is written in the zookeeper-server, so you need to replace the code in version 3.5.8 with the zookeeper-server in my github repo. Initially, start an ensemble with 3 servers called A, B, and C, and initialize 2 znodes called /key0 and /key1, and set them to 0 and 1 respectively. # Request to set /key0 to 1000 on 3 servers. # Isolate the ack messages of 2 servers. # Request to set /key0 to 1001 on 3 servers. # Stop all servers and restart them. # Check the contents of /key0 and /key1. Surprisingly, both requests worked,reading /key0 == 1000, /key1 == 1001 from all servers or several of them. If we skip step 4, we may read "/key0 == null, /key1 == null" from A and B, and read "/key0 == 0, /key1 == 1001" from C. Value null is because the "ConnectionLoss" with znodes. Repeat the scenario above may get different results. However, value 1000 and 1001 should not appear in any znode, because the proposal of the first request cannot obtain enough ack, it cannot be committed. And servers will also not commit the proposal of the second request, because there is a pending proposal that has not been committed before, according to the source code of Zookeeper. was: Using a [tool|https://github.com/kry4tall/CC-ZOO358] that I modifyed from [Filip Niksic's zootester|https://github.com/fniksic/zootester] for testing ZooKeeper, I discovered the following scenario which causes uncommitted requests to be executed. Zab protocol has three rounds: PROPOSE, ACK, and COMMIT. My tool can isolate the PROPOSAL, ACK and COMMIT messages and collect the values of some variables of each server at the end of each round. Setup: unbuntu Initially, start an ensemble with 3 servers called A, B, and C, and initialize 2 znodes called /key0 and /key1, and set them to 0 and 1 respectively. # Request to set /key0 to 1000 on 3 servers. # Isolate the ack messages of 2 servers. # Request to set /key0 to 1001 on 3 servers. # Stop all servers and restart them. # Check the contents of /key0 and /key1. Surprisingly, both requests worked,reading /key0 == 1000, /key1 == 1001 from all servers or several of them. If we skip step 4, we may read "/key0 == null, /key1 == null" from A and B, and read "/key0 == 0, /key1 == 1001" from C. Value null is because the "ConnectionLoss" with znodes. Repeat the scenario above may get different results. However, value 1000 and 1001 should not appear in any znode, because the proposal of the first request cannot obtain enough ack, it cannot be committed. And servers will also not commit the proposal of the second request, because there is a pending proposal that has not been committed before, according to the source code of Zookeeper. > Uncommitted requests have been executed > ---------------------------------------- > > Key: ZOOKEEPER-4681 > URL: https://issues.apache.org/jira/browse/ZOOKEEPER-4681 > Project: ZooKeeper > Issue Type: Bug > Components: quorum > Affects Versions: 3.5.8 > Reporter: krystal he > Priority: Critical > Attachments: no-restart.patch, restart-all-server.patch > > > Using a [tool|https://github.com/kry4tall/CC-ZOO358] that I modifyed from > [Filip Niksic's zootester|https://github.com/fniksic/zootester] for testing > ZooKeeper, I discovered the following scenario which causes uncommitted > requests to be executed. > Zab protocol has three rounds: PROPOSE, ACK, and COMMIT. My tool can isolate > the PROPOSAL, ACK and COMMIT messages and collect the values of some > variables of each server at the end of each round. > Setup: > The code for isolating messages and collecting variable values is written in > the zookeeper-server, so you need to replace the code in version 3.5.8 with > the zookeeper-server in my github repo. > > Initially, start an ensemble with 3 servers called A, B, and C, and > initialize 2 znodes called /key0 and /key1, and set them to 0 and 1 > respectively. > # Request to set /key0 to 1000 on 3 servers. > # Isolate the ack messages of 2 servers. > # Request to set /key0 to 1001 on 3 servers. > # Stop all servers and restart them. > # Check the contents of /key0 and /key1. Surprisingly, both requests > worked,reading /key0 == 1000, /key1 == 1001 from all servers or several of > them. > If we skip step 4, we may read "/key0 == null, /key1 == null" from A and B, > and read "/key0 == 0, /key1 == 1001" from C. Value null is because the > "ConnectionLoss" with znodes. > Repeat the scenario above may get different results. > However, value 1000 and 1001 should not appear in any znode, because the > proposal of the first request cannot obtain enough ack, it cannot be > committed. And servers will also not commit the proposal of the second > request, because there is a pending proposal that has not been committed > before, according to the source code of Zookeeper. -- This message was sent by Atlassian Jira (v8.20.10#820010)