What happens?
When trying to set partitioning on a newly created empty table the transaction fails with conflict when there are concurrent writers into other tables.
CREATE TABLE lake.test (...);
ALTER TABLE lake.test SET PARTITIONED BY (...);
TransactionContext Error: Failed to commit: Failed to commit DuckLake transaction.
Exceeded the maximum retry count of 10 set by the ducklake_max_retry_count setting.
. Consider increasing the value with: e.g., "SET ducklake_max_retry_count = 100;"
Failed to write new snapshot to DuckLake: Duplicate key "snapshot_id: 1122" violates primary key constraint.
See the provided test code for reproducing using Python threads.
To Reproduce
(edit: updated example to both create and alter table at the same time)
import duckdb
import pandas as pd
import threading
import time
import os
import shutil
import random
import string
NUM_WRITER_THREADS = 100
WRITE_DURATION_SECONDS = 5
stop_event = threading.Event()
def setup_environment():
if os.path.exists("./ducklake_generic_test"):
shutil.rmtree("./ducklake_generic_test")
os.makedirs("./ducklake_generic_test")
con = duckdb.connect()
con.sql("INSTALL ducklake;")
con.sql("LOAD ducklake;")
con.sql(f"ATTACH 'ducklake:./ducklake_generic_test/metadata.ducklake' AS generic_lake (DATA_PATH './ducklake_generic_test');")
con.sql(f"USE generic_lake;")
print("Creating separate writer table")
con.sql("""
CREATE TABLE writer_table (
ts BIGINT,
payload VARCHAR
);
""")
con.close()
def writer_task(lake_connection: duckdb.DuckDBPyConnection, thread_id: int):
cursor = lake_connection.cursor()
print(f"[Writer {thread_id}] Started for table 'generic_lake.writer_table")
while not stop_event.is_set():
try:
df = pd.DataFrame({
'ts': [int(time.time() * 1000)],
'payload': [''.join(random.choices(string.ascii_letters, k=10))]
})
cursor.execute("INSERT INTO generic_lake.writer_table SELECT * FROM df")
time.sleep(random.uniform(0.001, 0.005))
except duckdb.TransactionException:
# Not interested in this right now
pass
def set_partition_task(lake_connection: duckdb.DuckDBPyConnection):
cursor = lake_connection.cursor()
print("[Partitioner] Attempting to execute 'CREATE TABLE ...; ALTER TABLE ... SET PARTITIONED BY'...")
try:
cursor.execute("""
CREATE TABLE generic_lake.main_table (
col1 INTEGER,
col2 DECIMAL(10, 2),
partition_key DATE
);
ALTER TABLE generic_lake.main_table SET PARTITIONED BY (partition_key);
""")
print("[Partitioner] SUCCESS: ALTER TABLE command completed.")
except Exception as e:
print(f">>> [Partitioner] FAILED to set partition: {e}")
if __name__ == "__main__":
setup_environment()
shared_connection = duckdb.connect()
shared_connection.sql("INSTALL ducklake;")
shared_connection.sql("LOAD ducklake;")
shared_connection.sql(f"ATTACH 'ducklake:./ducklake_generic_test/metadata.ducklake' AS generic_lake (DATA_PATH './ducklake_generic_test');")
shared_connection.sql(f"USE generic_lake;")
threads = []
for i in range(NUM_WRITER_THREADS):
thread = threading.Thread(target=writer_task, args=(shared_connection, i))
threads.append(thread)
thread.start()
time.sleep(0.5)
partitioner_thread = threading.Thread(target=set_partition_task, args=(shared_connection,))
threads.append(partitioner_thread)
partitioner_thread.start()
time.sleep(WRITE_DURATION_SECONDS)
stop_event.set()
for thread in threads:
thread.join()
shared_connection.close()
OS:
aarch64 OS X
DuckDB Version:
1.4.1
DuckLake Version:
45788f0
DuckDB Client:
CLI & Python
Hardware:
No response
Full Name:
Hampus Linander
Affiliation:
Hampus Linander
What is the latest build you tested with? If possible, we recommend testing with the latest nightly build.
I have tested with a stable release
Did you include all relevant data sets for reproducing the issue?
Yes
Did you include all code required to reproduce the issue?
Did you include all relevant configuration (e.g., CPU architecture, Python version, Linux distribution) to reproduce the issue?
What happens?
When trying to set partitioning on a newly created empty table the transaction fails with conflict when there are concurrent writers into other tables.
See the provided test code for reproducing using Python threads.
To Reproduce
(edit: updated example to both create and alter table at the same time)
OS:
aarch64 OS X
DuckDB Version:
1.4.1
DuckLake Version:
45788f0
DuckDB Client:
CLI & Python
Hardware:
No response
Full Name:
Hampus Linander
Affiliation:
Hampus Linander
What is the latest build you tested with? If possible, we recommend testing with the latest nightly build.
I have tested with a stable release
Did you include all relevant data sets for reproducing the issue?
Yes
Did you include all code required to reproduce the issue?
Did you include all relevant configuration (e.g., CPU architecture, Python version, Linux distribution) to reproduce the issue?