Added another test; fixup

This commit is contained in:
Alexey Milovidov 2020-08-28 03:28:37 +03:00
parent c4e8aaac16
commit ed1d120de0
3 changed files with 54 additions and 6 deletions

View File

@ -28,6 +28,7 @@ namespace ErrorCodes
extern const int TIMEOUT_EXCEEDED;
extern const int NO_ACTIVE_REPLICAS;
extern const int DUPLICATE_DATA_PART;
extern const int PART_IS_TEMPORARILY_LOCKED;
extern const int LOGICAL_ERROR;
}
@ -98,7 +99,8 @@ void ReplicatedMergeTreeBlockOutputStream::checkQuorumPrecondition(zkutil::ZooKe
auto quorum_status = quorum_status_future.get();
if (quorum_status.error != Coordination::Error::ZNONODE)
throw Exception("Quorum for previous write has not been satisfied yet. Status: " + quorum_status.data, ErrorCodes::UNSATISFIED_QUORUM_FOR_PREVIOUS_WRITE);
throw Exception("Quorum for previous write has not been satisfied yet. Status: " + quorum_status.data,
ErrorCodes::UNSATISFIED_QUORUM_FOR_PREVIOUS_WRITE);
/// Both checks are implicitly made also later (otherwise there would be a race condition).
@ -305,7 +307,8 @@ void ReplicatedMergeTreeBlockOutputStream::commitPart(
storage.replica_path + "/is_active",
quorum_info.is_active_node_version));
/// Unfortunately, just checking the above is not enough, because `is_active` node can be deleted and reappear with the same version.
/// Unfortunately, just checking the above is not enough, because `is_active`
/// node can be deleted and reappear with the same version.
/// But then the `host` value will change. We will check this.
/// It's great that these two nodes change in the same transaction (see MergeTreeRestartingThread).
ops.emplace_back(
@ -360,18 +363,22 @@ void ReplicatedMergeTreeBlockOutputStream::commitPart(
}
catch (const Exception & e)
{
if (e.code() != ErrorCodes::DUPLICATE_DATA_PART)
if (e.code() != ErrorCodes::DUPLICATE_DATA_PART
&& e.code() != ErrorCodes::PART_IS_TEMPORARILY_LOCKED)
throw;
}
if (!renamed)
{
if (is_already_existing_part)
{
LOG_INFO(log, "Part {} is duplicate and it is already written by concurrent request; ignoring it.", block_id, existing_part_name);
LOG_INFO(log, "Part {} is duplicate and it is already written by concurrent request or fetched; ignoring it.",
block_id, existing_part_name);
return;
}
else
throw Exception("Part with name {} is already written by concurrent request. It should not happen for non-duplicate data parts because unique names are assigned for them. It's a bug", ErrorCodes::LOGICAL_ERROR);
throw Exception("Part with name {} is already written by concurrent request."
" It should not happen for non-duplicate data parts because unique names are assigned for them. It's a bug",
ErrorCodes::LOGICAL_ERROR);
}
Coordination::Responses responses;
@ -485,7 +492,8 @@ void ReplicatedMergeTreeBlockOutputStream::commitPart(
throw Exception("Timeout while waiting for quorum", ErrorCodes::TIMEOUT_EXCEEDED);
}
/// And what if it is possible that the current replica at this time has ceased to be active and the quorum is marked as failed and deleted?
/// And what if it is possible that the current replica at this time has ceased to be active
/// and the quorum is marked as failed and deleted?
String value;
if (!zookeeper->tryGet(storage.replica_path + "/is_active", value, nullptr)
|| value != quorum_info.is_active_node_value)

View File

@ -0,0 +1,2 @@
100 0 99 4950
100 0 99 4950

View File

@ -0,0 +1,38 @@
#!/usr/bin/env bash
set -e
CURDIR=$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)
. "$CURDIR"/../shell_config.sh
$CLICKHOUSE_CLIENT -n -q "
DROP TABLE IF EXISTS r1;
DROP TABLE IF EXISTS r2;
CREATE TABLE r1 (x UInt64) ENGINE = ReplicatedMergeTree('/clickhouse/tables/r', 'r1') ORDER BY x;
CREATE TABLE r2 (x UInt64) ENGINE = ReplicatedMergeTree('/clickhouse/tables/r', 'r2') ORDER BY x;
"
function thread {
for x in {0..99}; do
$CLICKHOUSE_CLIENT --query "INSERT INTO r$1 SELECT $x"
done
}
thread 1 &
thread 2 &
wait
$CLICKHOUSE_CLIENT -n -q "
SYSTEM SYNC REPLICA r1;
SYSTEM SYNC REPLICA r2;
"
$CLICKHOUSE_CLIENT -q "SELECT count(), min(x), max(x), sum(x) FROM r1";
$CLICKHOUSE_CLIENT -q "SELECT count(), min(x), max(x), sum(x) FROM r2";
$CLICKHOUSE_CLIENT -n -q "
DROP TABLE IF EXISTS r1;
DROP TABLE IF EXISTS r2;
"