Search in sources :

Example 6 with Proposal

use of org.apache.zookeeper.server.quorum.Leader.Proposal in project zookeeper by apache.

the class QuorumPeerMainTest method testFailedTxnAsPartOfQuorumLoss.

@Test
public void testFailedTxnAsPartOfQuorumLoss() throws Exception {
    final int LEADER_TIMEOUT_MS = 10_000;
    // 1. start up server and wait for leader election to finish
    ClientBase.setupTestEnv();
    final int SERVER_COUNT = 3;
    servers = LaunchServers(SERVER_COUNT);
    waitForAll(servers, States.CONNECTED);
    // we need to shutdown and start back up to make sure that the create session isn't the first transaction since
    // that is rather innocuous.
    servers.shutDownAllServers();
    waitForAll(servers, States.CONNECTING);
    servers.restartAllServersAndClients(this);
    waitForAll(servers, States.CONNECTED);
    // 2. kill all followers
    int leader = servers.findLeader();
    Map<Long, Proposal> outstanding = servers.mt[leader].main.quorumPeer.leader.outstandingProposals;
    // increase the tick time to delay the leader going to looking
    int previousTick = servers.mt[leader].main.quorumPeer.tickTime;
    servers.mt[leader].main.quorumPeer.tickTime = LEADER_TIMEOUT_MS;
    // let the previous tick on the leader exhaust itself so the new tick time takes effect
    Thread.sleep(previousTick);
    LOG.warn("LEADER {}", leader);
    for (int i = 0; i < SERVER_COUNT; i++) {
        if (i != leader) {
            servers.mt[i].shutdown();
        }
    }
    // 3. start up the followers to form a new quorum
    for (int i = 0; i < SERVER_COUNT; i++) {
        if (i != leader) {
            servers.mt[i].start();
        }
    }
    // 4. wait one of the follower to be the new leader
    for (int i = 0; i < SERVER_COUNT; i++) {
        if (i != leader) {
            // Recreate a client session since the previous session was not persisted.
            servers.restartClient(i, this);
            waitForOne(servers.zk[i], States.CONNECTED);
        }
    }
    // which means it acked from itself
    try {
        servers.zk[leader].create("/zk" + leader, "zk".getBytes(), Ids.OPEN_ACL_UNSAFE, CreateMode.PERSISTENT);
        fail("create /zk" + leader + " should have failed");
    } catch (KeeperException e) {
    }
    // just make sure that we actually did get it in process at the
    // leader
    // there can be extra sessionClose proposals
    assertTrue(outstanding.size() > 0);
    Proposal p = findProposalOfType(outstanding, OpCode.create);
    LOG.info("Old leader id: {}. All proposals: {}", leader, outstanding);
    assertNotNull(p, "Old leader doesn't have 'create' proposal");
    // make sure it has a chance to write it to disk
    int sleepTime = 0;
    Long longLeader = (long) leader;
    while (!p.qvAcksetPairs.get(0).getAckset().contains(longLeader)) {
        if (sleepTime > 2000) {
            fail("Transaction not synced to disk within 1 second " + p.qvAcksetPairs.get(0).getAckset() + " expected " + leader);
        }
        Thread.sleep(100);
        sleepTime += 100;
    }
    // 6. wait for the leader to quit due to not enough followers and come back up as a part of the new quorum
    LOG.info("Waiting for leader {} to timeout followers", leader);
    sleepTime = 0;
    Follower f = servers.mt[leader].main.quorumPeer.follower;
    while (f == null || !f.isRunning()) {
        if (sleepTime > LEADER_TIMEOUT_MS * 2) {
            fail("Took too long for old leader to time out " + servers.mt[leader].main.quorumPeer.getPeerState());
        }
        Thread.sleep(100);
        sleepTime += 100;
        f = servers.mt[leader].main.quorumPeer.follower;
    }
    int newLeader = servers.findLeader();
    // make sure a different leader was elected
    assertNotEquals(leader, newLeader);
    // 7. restart the previous leader to force it to replay the edits and possibly come up in a bad state
    servers.mt[leader].shutdown();
    servers.mt[leader].start();
    // old client session can expire, restart it
    servers.restartClient(leader, this);
    waitForAll(servers, States.CONNECTED);
    // make sure everything is consistent
    for (int i = 0; i < SERVER_COUNT; i++) {
        assertNull(servers.zk[i].exists("/zk" + leader, false), "server " + i + " should not have /zk" + leader);
    }
}
Also used : Proposal(org.apache.zookeeper.server.quorum.Leader.Proposal) KeeperException(org.apache.zookeeper.KeeperException) Test(org.junit.jupiter.api.Test)

Example 7 with Proposal

use of org.apache.zookeeper.server.quorum.Leader.Proposal in project zookeeper by apache.

the class LocalSessionRequestTest method validateRequestLog.

/**
 * Walk through the target peer commmittedLog.
 * @param sessionId
 * @param peerId
 */
private void validateRequestLog(long sessionId, int peerId) {
    String session = Long.toHexString(sessionId);
    LOG.info("Searching for txn of session 0x " + session + " on peer " + peerId);
    String peerType = peerId == qb.getLeaderIndex() ? "leader" : "follower";
    QuorumPeer peer = qb.getPeerList().get(peerId);
    ZKDatabase db = peer.getActiveServer().getZKDatabase();
    for (Proposal p : db.getCommittedLog()) {
        assertFalse(p.request.sessionId == sessionId, "Should not see " + Request.op2String(p.request.type) + " request from local session 0x" + session + " on the " + peerType);
    }
}
Also used : QuorumPeer(org.apache.zookeeper.server.quorum.QuorumPeer) ZKDatabase(org.apache.zookeeper.server.ZKDatabase) Proposal(org.apache.zookeeper.server.quorum.Leader.Proposal)

Example 8 with Proposal

use of org.apache.zookeeper.server.quorum.Leader.Proposal in project zookeeper by apache.

the class RestoreCommittedLogTest method testRestoreCommittedLog.

/**
 * test the purge
 * @throws Exception an exception might be thrown here
 */
@Test
public void testRestoreCommittedLog() throws Exception {
    File tmpDir = ClientBase.createTmpDir();
    ClientBase.setupTestEnv();
    ZooKeeperServer zks = new ZooKeeperServer(tmpDir, tmpDir, 3000);
    SyncRequestProcessor.setSnapCount(100);
    final int PORT = Integer.parseInt(HOSTPORT.split(":")[1]);
    ServerCnxnFactory f = ServerCnxnFactory.createFactory(PORT, -1);
    f.startup(zks);
    Assert.assertTrue("waiting for server being up ", ClientBase.waitForServerUp(HOSTPORT, CONNECTION_TIMEOUT));
    ZooKeeper zk = ClientBase.createZKClient(HOSTPORT);
    try {
        for (int i = 0; i < 2000; i++) {
            zk.create("/invalidsnap-" + i, new byte[0], Ids.OPEN_ACL_UNSAFE, CreateMode.PERSISTENT);
        }
    } finally {
        zk.close();
    }
    f.shutdown();
    zks.shutdown();
    Assert.assertTrue("waiting for server to shutdown", ClientBase.waitForServerDown(HOSTPORT, CONNECTION_TIMEOUT));
    // start server again
    zks = new ZooKeeperServer(tmpDir, tmpDir, 3000);
    zks.startdata();
    List<Proposal> committedLog = zks.getZKDatabase().getCommittedLog();
    int logsize = committedLog.size();
    LOG.info("committedLog size = {}", logsize);
    Assert.assertTrue("log size != 0", (logsize != 0));
    zks.shutdown();
}
Also used : ZooKeeper(org.apache.zookeeper.ZooKeeper) ServerCnxnFactory(org.apache.zookeeper.server.ServerCnxnFactory) File(java.io.File) ZooKeeperServer(org.apache.zookeeper.server.ZooKeeperServer) Proposal(org.apache.zookeeper.server.quorum.Leader.Proposal) Test(org.junit.Test)

Example 9 with Proposal

use of org.apache.zookeeper.server.quorum.Leader.Proposal in project zookeeper by apache.

the class ZKDatabase method getCommittedLog.

public synchronized Collection<Proposal> getCommittedLog() {
    final Collection<Proposal> result;
    ReadLock rl = logLock.readLock();
    // make a copy if this thread is not already holding a lock
    if (logLock.getReadHoldCount() > 0) {
        result = this.committedLog;
    } else {
        rl.lock();
        try {
            result = new ArrayList<>(this.committedLog);
        } finally {
            rl.unlock();
        }
    }
    return Collections.unmodifiableCollection(result);
}
Also used : ReadLock(java.util.concurrent.locks.ReentrantReadWriteLock.ReadLock) Proposal(org.apache.zookeeper.server.quorum.Leader.Proposal)

Example 10 with Proposal

use of org.apache.zookeeper.server.quorum.Leader.Proposal in project zookeeper by apache.

the class TxnLogProposalIterator method next.

/**
 * Proposal returned by this iterator has request part set to null, since
 * it is not used for follower sync-up.
 */
@Override
public Proposal next() {
    Proposal p = new Proposal();
    try {
        byte[] serializedData = Util.marshallTxnEntry(itr.getHeader(), itr.getTxn(), itr.getDigest());
        QuorumPacket pp = new QuorumPacket(Leader.PROPOSAL, itr.getHeader().getZxid(), serializedData, null);
        p.packet = pp;
        p.request = null;
        // This is the only place that can throw IO exception
        hasNext = itr.next();
    } catch (IOException e) {
        LOG.error("Unable to read txnlog from disk", e);
        hasNext = false;
    }
    return p;
}
Also used : QuorumPacket(org.apache.zookeeper.server.quorum.QuorumPacket) IOException(java.io.IOException) Proposal(org.apache.zookeeper.server.quorum.Leader.Proposal)

Aggregations

Proposal (org.apache.zookeeper.server.quorum.Leader.Proposal)16 ZooKeeper (org.apache.zookeeper.ZooKeeper)6 Test (org.junit.jupiter.api.Test)6 File (java.io.File)4 KeeperException (org.apache.zookeeper.KeeperException)4 ReentrantReadWriteLock (java.util.concurrent.locks.ReentrantReadWriteLock)3 ReadLock (java.util.concurrent.locks.ReentrantReadWriteLock.ReadLock)3 ServerCnxnFactory (org.apache.zookeeper.server.ServerCnxnFactory)3 ZKDatabase (org.apache.zookeeper.server.ZKDatabase)3 ZooKeeperServer (org.apache.zookeeper.server.ZooKeeperServer)3 IOException (java.io.IOException)2 Iterator (java.util.Iterator)2 Stat (org.apache.zookeeper.data.Stat)2 QuorumPeer (org.apache.zookeeper.server.quorum.QuorumPeer)2 ByteArrayOutputStream (java.io.ByteArrayOutputStream)1 LineNumberReader (java.io.LineNumberReader)1 StringReader (java.io.StringReader)1 InetSocketAddress (java.net.InetSocketAddress)1 ByteBuffer (java.nio.ByteBuffer)1 SocketChannel (java.nio.channels.SocketChannel)1