Skip to content

Commit 73c3d18

Browse files
authored
Merge pull request ClickHouse#79439 from jkartseva/fix-plain-rw-loading
Fix loading of plain_rewritable disks with data
2 parents f787426 + 8a748d4 commit 73c3d18

File tree

4 files changed

+161
-2
lines changed

4 files changed

+161
-2
lines changed

src/Disks/ObjectStorages/MetadataStorageFromPlainRewritableObjectStorage.cpp

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -163,7 +163,7 @@ void MetadataStorageFromPlainRewritableObjectStorage::load(bool is_initial_load)
163163

164164
/// Load the list of files inside the directory.
165165
fs::path full_remote_path = object_storage->getCommonKeyPrefix() / remote_path;
166-
size_t prefix_length = remote_path.string().size() + 1; /// randomlygenerated/
166+
size_t full_prefix_length = full_remote_path.string().size() + 1; /// common/key/prefix/randomlygenerated/
167167
for (auto dir_iterator = object_storage->iterate(full_remote_path, 0); dir_iterator->isValid(); dir_iterator->next())
168168
{
169169
auto remote_file = dir_iterator->current();
@@ -178,7 +178,8 @@ void MetadataStorageFromPlainRewritableObjectStorage::load(bool is_initial_load)
178178
}
179179

180180
/// Check that the file is a direct child.
181-
if (remote_file_path.substr(prefix_length) == filename)
181+
chassert(full_prefix_length < remote_file_path.size());
182+
if (std::string_view(remote_file_path.data() + full_prefix_length) == filename)
182183
files.insert(std::move(filename));
183184
}
184185

tests/integration/test_s3_plain_rewritable_rotate_tables/__init__.py

Whitespace-only changes.
Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
<clickhouse>
2+
<storage_configuration>
3+
<disks>
4+
<disk_s3_plain_rewritable>
5+
<type>object_storage</type>
6+
<object_storage_type>s3</object_storage_type>
7+
<metadata_type>plain_rewritable</metadata_type>
8+
<endpoint>http://minio1:9001/root/data/</endpoint>
9+
<endpoint_subpath from_env="ENDPOINT_SUBPATH"></endpoint_subpath>
10+
<access_key_id>minio</access_key_id>
11+
<secret_access_key>ClickHouse_Minio_P@ssw0rd</secret_access_key>
12+
</disk_s3_plain_rewritable>
13+
</disks>
14+
<policies>
15+
<s3_plain_rewritable>
16+
<volumes>
17+
<main>
18+
<disk>disk_s3_plain_rewritable</disk>
19+
</main>
20+
</volumes>
21+
</s3_plain_rewritable>
22+
</policies>
23+
</storage_configuration>
24+
</clickhouse>
Lines changed: 134 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,134 @@
1+
import logging
2+
import random
3+
import string
4+
import uuid
5+
6+
import pytest
7+
8+
from helpers.cluster import ClickHouseCluster
9+
from helpers.config_cluster import minio_secret_key
10+
11+
cluster = ClickHouseCluster(__file__)
12+
13+
14+
def gen_insert_values(size):
15+
return ",".join(
16+
f"({i},'{''.join(random.choices(string.ascii_lowercase, k=5))}')"
17+
for i in range(size)
18+
)
19+
20+
21+
def randomize_name(table_name, random_suffix_length=8):
22+
letters = string.ascii_letters
23+
return f"{table_name}_{''.join(random.choice(letters) for _ in range(random_suffix_length))}"
24+
25+
26+
@pytest.fixture(scope="module", autouse=True)
27+
def start_cluster():
28+
cluster.add_instance(
29+
"node1",
30+
main_configs=["configs/storage_conf.xml"],
31+
with_minio=True,
32+
env_variables={"ENDPOINT_SUBPATH": "node1"},
33+
stay_alive=True,
34+
)
35+
cluster.add_instance(
36+
"node2",
37+
main_configs=["configs/storage_conf.xml"],
38+
with_minio=True,
39+
env_variables={
40+
"ENDPOINT_SUBPATH": "node2",
41+
"ROTATED_REPLICA_ENDPOINT_SUBPATH": "node1",
42+
},
43+
stay_alive=True,
44+
instance_env_variables=True,
45+
)
46+
47+
try:
48+
cluster.start()
49+
yield cluster
50+
finally:
51+
cluster.shutdown()
52+
53+
54+
def test_alter_partition_after_table_rotation():
55+
node1 = cluster.instances["node1"]
56+
57+
def create_insert(node, table_name, insert_values):
58+
node1.query(f"DROP TABLE IF EXISTS {table_name} SYNC")
59+
node.query(
60+
f"""CREATE TABLE {table_name} (
61+
id Int64,
62+
data String
63+
) ENGINE=MergeTree()
64+
ORDER BY id
65+
PARTITION BY id%10
66+
SETTINGS storage_policy='s3_plain_rewritable'
67+
"""
68+
)
69+
70+
node.query("INSERT INTO {} VALUES {}".format(table_name, insert_values))
71+
72+
table1 = randomize_name("t1")
73+
create_insert(node1, table1, gen_insert_values(1000))
74+
75+
assert int(node1.query(f"SELECT count(*) FROM {table1}")) == 1000
76+
77+
uuid1 = node1.query(
78+
f"SELECT uuid FROM system.tables WHERE table='{table1}'"
79+
).strip()
80+
81+
node1.query(f"DETACH TABLE {table1} PERMANENTLY SYNC")
82+
83+
disk_name = randomize_name("disk")
84+
node2 = cluster.instances["node2"]
85+
table2 = randomize_name("table2")
86+
node2.query(f"DROP TABLE IF EXISTS {table2} SYNC")
87+
node2.query(
88+
f"""CREATE TABLE {table2} (id Int64, data String)
89+
ENGINE=MergeTree()
90+
ORDER BY id
91+
PARTITION BY id%10
92+
SETTINGS disk=disk(
93+
name={disk_name},
94+
type='s3_plain_rewritable',
95+
endpoint='http://minio1:9001/root/data/node1',
96+
access_key_id='minio',
97+
secret_access_key='ClickHouse_Minio_P@ssw0rd')
98+
"""
99+
)
100+
101+
rotated_table = f"{table1}_rotated"
102+
node2.query(f"""DROP TABLE IF EXISTS {rotated_table} SYNC""")
103+
node2.query(
104+
f"""ATTACH TABLE {rotated_table} UUID '{uuid1}' (id Int64, data String)
105+
ENGINE=MergeTree()
106+
ORDER BY id
107+
PARTITION BY id%10
108+
SETTINGS disk=disk(
109+
name={disk_name},
110+
type='s3_plain_rewritable',
111+
endpoint='http://minio1:9001/root/data/node1',
112+
access_key_id='minio',
113+
secret_access_key='ClickHouse_Minio_P@ssw0rd')
114+
"""
115+
)
116+
117+
assert (
118+
int(
119+
node2.query(
120+
f"SELECT count(*) FROM {rotated_table} WHERE _partition_id = '0'"
121+
)
122+
)
123+
== 100
124+
)
125+
126+
assert int(node2.query(f"SELECT count(*) FROM {rotated_table}")) == 1000
127+
128+
node2.query(f"""ALTER TABLE {rotated_table} MOVE PARTITION '0' TO TABLE {table2}""")
129+
130+
assert int(node2.query(f"SELECT count(*) FROM {rotated_table}")) == 900
131+
assert int(node2.query(f"SELECT count(*) FROM {table2}")) == 100
132+
133+
node2.query(f"DROP TABLE {rotated_table} SYNC")
134+
node2.query(f"DROP TABLE {table2} SYNC")

0 commit comments

Comments
 (0)