Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion src/Databases/DatabaseReplicatedWorker.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -257,7 +257,7 @@ void DatabaseReplicatedDDLWorker::initializeReplication()
active_node_holder = zkutil::EphemeralNodeHolder::existing(active_path, *active_node_holder_zookeeper);
}

void DatabaseReplicatedDDLWorker::markReplicasActive(bool reinitialized)
void DatabaseReplicatedDDLWorker::markReplicasActive(bool reinitialized, bool /*should_create_dirs*/)
{
if (reinitialized || !active_node_holder_zookeeper || active_node_holder_zookeeper->expired())
{
Expand Down
2 changes: 1 addition & 1 deletion src/Databases/DatabaseReplicatedWorker.h
Original file line number Diff line number Diff line change
Expand Up @@ -49,7 +49,7 @@ class DatabaseReplicatedDDLWorker : public DDLWorker
void initializeReplication() override;

void createReplicaDirs(const ZooKeeperPtr &, const NameSet &) override { }
void markReplicasActive(bool reinitialized) override;
void markReplicasActive(bool reinitialized, bool should_create_dirs) override;

void initializeLogPointer(const String & processed_entry_name);

Expand Down
16 changes: 12 additions & 4 deletions src/Interpreters/DDLWorker.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1234,12 +1234,14 @@ void DDLWorker::runMainThread()
}

if (host_ids_updated.exchange(false))
markReplicasActive(/*reinitialized=*/false);
markReplicasActive(/*reinitialized=*/false, /*should_create_dirs=*/true);

cleanup_event->set();
try
{
markReplicasActive(reinitialized);
/// On per-tick invocations (i.e. not reinitialized), do NOT recreate
/// the host_id dirs - that races with external recursive cleanup.
markReplicasActive(reinitialized, /*should_create_dirs=*/reinitialized);
}
catch (...)
{
Expand Down Expand Up @@ -1314,7 +1316,7 @@ void DDLWorker::createReplicaDirs(const ZooKeeperPtr & zookeeper, const NameSet
}
}

void DDLWorker::markReplicasActive(bool reinitialized)
void DDLWorker::markReplicasActive(bool reinitialized, bool should_create_dirs)
{
auto zookeeper = getZooKeeper();

Expand Down Expand Up @@ -1356,7 +1358,13 @@ void DDLWorker::markReplicasActive(bool reinitialized)
LOG_INFO(log, "Unable to get interserver IO address, error {}", e.what());
}

createReplicaDirs(zookeeper, all_host_ids);
/// Only (re)create the host_id dirs on real events (initialization, reconnect,
/// or a freshly-observed host ID). Doing it on every main-loop tick races
/// against external recursive cleanup of /clickhouse and breaks
/// test_replication_without_zookeeper::test_startup_without_zookeeper.
/// See Altinity/ClickHouse#1711.
if (should_create_dirs)
createReplicaDirs(zookeeper, all_host_ids);

if (reinitialized)
{
Expand Down
6 changes: 5 additions & 1 deletion src/Interpreters/DDLWorker.h
Original file line number Diff line number Diff line change
Expand Up @@ -173,7 +173,11 @@ class DDLWorker
virtual void initializeReplication();

virtual void createReplicaDirs(const ZooKeeperPtr & zookeeper, const NameSet & host_ids);
virtual void markReplicasActive(bool reinitialized);
/// `should_create_dirs` controls whether `createReplicaDirs` is called.
/// We only create dirs on (re)initialization or when host IDs were just updated -
/// not on every main-loop tick, otherwise it races with external recursive deletion
/// of the DDL queue path (see Altinity/ClickHouse#1711).
virtual void markReplicasActive(bool reinitialized, bool should_create_dirs);

void runMainThread();
void runCleanupThread();
Expand Down
Loading