import uuid import pytest from helpers.cluster import ClickHouseCluster cluster = ClickHouseCluster(__file__) node1 = cluster.add_instance( 'node1', main_configs=['configs/remote_servers.xml', 'configs/merge_tree_uuids.xml'], with_zookeeper=True) node2 = cluster.add_instance( 'node2', main_configs=['configs/remote_servers.xml', 'configs/merge_tree_uuids.xml', 'configs/merge_tree_in_memory.xml'], with_zookeeper=True) @pytest.fixture(scope="module") def started_cluster(): try: cluster.start() yield cluster finally: cluster.shutdown() def test_part_uuid(started_cluster): uuid_zero = uuid.UUID(bytes=b"\x00" * 16) for ix, n in enumerate([node1, node2]): n.query(""" CREATE TABLE t(key UInt64, value UInt64) ENGINE ReplicatedMergeTree('/clickhouse/tables/t', '{}') ORDER BY tuple() """.format(ix)) # Test insert assigns uuid to part. node1.query("INSERT INTO t VALUES (1, 1)") uuids = set() for node in [node1, node2]: node.query("SYSTEM SYNC REPLICA t") part_initial_uuid = uuid.UUID(node.query("SELECT uuid FROM system.parts WHERE table = 't' AND active ORDER BY name").strip()) uuids.add(part_initial_uuid) assert uuid_zero != part_initial_uuid assert len(uuids) == 1, "expect the same uuid on all the replicas" # Test detach / attach. node1.query("ALTER TABLE t DETACH PARTITION tuple(); ALTER TABLE t ATTACH PARTITION tuple()") for node in [node1, node2]: node.query("SYSTEM SYNC REPLICA t") part_reattach_uuid = uuid.UUID(node.query( "SELECT uuid FROM system.parts WHERE table = 't' AND active ORDER BY name").strip()) assert part_initial_uuid == part_reattach_uuid # Test mutation assigns new non-zero uuids. node1.query("ALTER TABLE t UPDATE value = 1 WHERE key = 1 SETTINGS mutations_sync = 2") part_mutate_uuid = uuid.UUID(node1.query("SELECT uuid FROM system.parts WHERE table = 't' AND active ORDER BY name").strip()) assert part_mutate_uuid not in [uuid_zero, part_initial_uuid] node2.query("SYSTEM SYNC REPLICA t") assert part_mutate_uuid == uuid.UUID(node2.query( "SELECT uuid FROM system.parts WHERE table = 't' AND active ORDER BY name").strip()) # Test merge assigns new non-zero uuids. node2.query("INSERT INTO t VALUES (1, 1)") node2.query("OPTIMIZE TABLE t FINAL") uuids = set() for node in [node1, node2]: node.query("SYSTEM SYNC REPLICA t") part_merge_uuid = uuid.UUID(node.query( "SELECT uuid FROM system.parts WHERE table = 't' AND active ORDER BY name").strip()) uuids.add(part_merge_uuid) assert part_mutate_uuid not in [uuid_zero, part_merge_uuid] assert len(uuids) == 1, "expect the same uuid on all the replicas" def test_part_uuid_wal(started_cluster): uuid_zero = uuid.UUID(bytes=b"\x00" * 16) for ix, n in enumerate([node1, node2]): n.query(""" CREATE TABLE t_wal(key UInt64, value UInt64) ENGINE ReplicatedMergeTree('/clickhouse/tables/t_wal', '{}') ORDER BY tuple() """.format(ix)) node2.query("INSERT INTO t_wal VALUES (1, 1)") uuids = set() for node in [node1, node2]: node.query("SYSTEM SYNC REPLICA t_wal") part_initial_uuid = uuid.UUID(node.query("SELECT uuid FROM system.parts WHERE table = 't_wal' AND active ORDER BY name").strip()) assert "InMemory" == node.query("SELECT part_type FROM system.parts WHERE table = 't_wal' AND active ORDER BY name").strip() uuids.add(part_initial_uuid) assert uuid_zero != part_initial_uuid assert len(uuids) == 1, "expect the same uuid on all the replicas" # Test detach / attach table to trigger WAL processing. for node in [node1, node2]: node.query("DETACH TABLE t_wal; ATTACH TABLE t_wal") part_reattach_uuid = uuid.UUID(node.query( "SELECT uuid FROM system.parts WHERE table = 't_wal' AND active ORDER BY name").strip()) assert part_initial_uuid == part_reattach_uuid