diff --git a/src/Storages/StorageReplicatedMergeTree.cpp b/src/Storages/StorageReplicatedMergeTree.cpp index 6119541ff52..8e1598a1eef 100644 --- a/src/Storages/StorageReplicatedMergeTree.cpp +++ b/src/Storages/StorageReplicatedMergeTree.cpp @@ -513,8 +513,15 @@ StorageReplicatedMergeTree::StorageReplicatedMergeTree( if (same_structure) { Coordination::Stat metadata_stat; - current_zookeeper->get(zookeeper_path + "/metadata", &metadata_stat); + current_zookeeper->get(fs::path(zookeeper_path) / "metadata", &metadata_stat); + + /** We change metadata_snapshot so that `createReplica` method will create `metadata_version` node in ZooKeeper + * with version of table '/metadata' node in Zookeeper. + * + * Otherwise `metadata_version` for not first replica will be initialized with 0 by default. + */ setInMemoryMetadata(metadata_snapshot->withMetadataVersion(metadata_stat.version)); + metadata_snapshot = getInMemoryMetadataPtr(); } } catch (Coordination::Exception & e) @@ -5817,6 +5824,7 @@ bool StorageReplicatedMergeTree::executeMetadataAlter(const StorageReplicatedMer Coordination::Requests requests; requests.emplace_back(zkutil::makeSetRequest(fs::path(replica_path) / "columns", entry.columns_str, -1)); requests.emplace_back(zkutil::makeSetRequest(fs::path(replica_path) / "metadata", entry.metadata_str, -1)); + requests.emplace_back(zkutil::makeSetRequest(fs::path(replica_path) / "metadata_version", std::to_string(entry.alter_version), -1)); auto table_id = getStorageID(); auto alter_context = getContext(); @@ -5863,10 +5871,6 @@ bool StorageReplicatedMergeTree::executeMetadataAlter(const StorageReplicatedMer resetObjectColumnsFromActiveParts(parts_lock); } - /// This transaction may not happen, but it's OK, because on the next retry we will eventually create/update this node - /// TODO Maybe do in in one transaction for Replicated database? - zookeeper->createOrUpdate(fs::path(replica_path) / "metadata_version", std::to_string(current_metadata->getMetadataVersion()), zkutil::CreateMode::Persistent); - return true; } diff --git a/tests/queries/0_stateless/02989_replicated_merge_tree_invalid_metadata_version.reference b/tests/queries/0_stateless/02989_replicated_merge_tree_invalid_metadata_version.reference new file mode 100644 index 00000000000..128e3adcc0a --- /dev/null +++ b/tests/queries/0_stateless/02989_replicated_merge_tree_invalid_metadata_version.reference @@ -0,0 +1,14 @@ +Row 1: +────── +name: metadata +version: 1 +-- +Row 1: +────── +name: metadata_version +value: 1 +-- +id UInt64 +value String +insert_time DateTime +insert_time_updated DateTime diff --git a/tests/queries/0_stateless/02989_replicated_merge_tree_invalid_metadata_version.sql b/tests/queries/0_stateless/02989_replicated_merge_tree_invalid_metadata_version.sql new file mode 100644 index 00000000000..3e37f368fd8 --- /dev/null +++ b/tests/queries/0_stateless/02989_replicated_merge_tree_invalid_metadata_version.sql @@ -0,0 +1,40 @@ +-- Tags: zookeeper + +DROP TABLE IF EXISTS test_table_replicated; +CREATE TABLE test_table_replicated +( + id UInt64, + value String +) ENGINE=ReplicatedMergeTree('/clickhouse/tables/{database}/test_table_replicated', '1_replica') ORDER BY id; + +ALTER TABLE test_table_replicated ADD COLUMN insert_time DateTime; + +SELECT name, version FROM system.zookeeper +WHERE path = '/clickhouse/tables/' || currentDatabase() ||'/test_table_replicated/' +AND name = 'metadata' FORMAT Vertical; + +DROP TABLE IF EXISTS test_table_replicated_second; +CREATE TABLE test_table_replicated_second +( + id UInt64, + value String, + insert_time DateTime +) ENGINE=ReplicatedMergeTree('/clickhouse/tables/{database}/test_table_replicated', '2_replica') ORDER BY id; + +DROP TABLE test_table_replicated; + +SELECT '--'; + +SELECT name, value FROM system.zookeeper +WHERE path = '/clickhouse/tables/' || currentDatabase() ||'/test_table_replicated/replicas/2_replica' +AND name = 'metadata_version' FORMAT Vertical; + +SYSTEM RESTART REPLICA test_table_replicated_second; + +ALTER TABLE test_table_replicated_second ADD COLUMN insert_time_updated DateTime; + +SELECT '--'; + +DESCRIBE test_table_replicated_second; + +DROP TABLE test_table_replicated_second;