The "DB::Exception: Unexpected table engine" error is raised when you perform an operation on a table whose engine does not support that operation. The error code UNEXPECTED_TABLE_ENGINE signals that the command you issued is only valid for certain engine types, and the target table uses a different one. For example, trying to run replication commands on a non-replicated table, or attempting MergeTree-specific mutations on a Log table.
Impact
The operation fails, and the table is unaffected. This is not a data corruption risk -- ClickHouse is simply telling you that the requested operation is incompatible with the table's engine. You need to either use a different approach or change the table's engine.
Common Causes
- Running SYSTEM RESTART REPLICA on a non-replicated table -- this command only works on ReplicatedMergeTree tables.
- Attempting ALTER TABLE ... UPDATE or DELETE on a non-MergeTree table -- mutations are a MergeTree-family feature.
- Using OPTIMIZE TABLE on an engine that does not support it -- not all engines support merge operations.
- Trying to ATTACH PARTITION on a table that does not support partitioning -- Log and Memory engines do not have partitions.
- Issuing replication-specific commands on non-replicated engines -- commands like
SYSTEM SYNC REPLICArequire ReplicatedMergeTree. - DDL operations that assume a specific engine -- scripts written for one engine type being run against tables with different engines.
Troubleshooting and Resolution Steps
Check the table's engine:
SELECT database, name, engine FROM system.tables WHERE name = 'my_table';Verify which operations your engine supports. Here is a quick reference:
- MergeTree family -- supports mutations (UPDATE/DELETE), OPTIMIZE, partitions, projections
- ReplicatedMergeTree family -- all of the above plus replication commands (SYNC REPLICA, RESTART REPLICA)
- Log / TinyLog -- basic insert and select only; no mutations, no partitions
- Memory -- insert, select, and truncate; no persistence across restarts
- Distributed -- query routing only; no direct data storage
If you need the operation, consider converting to a compatible engine. Create a new table with the right engine and migrate data:
CREATE TABLE my_table_new (...) ENGINE = MergeTree() ORDER BY id; INSERT INTO my_table_new SELECT * FROM my_table; EXCHANGE TABLES my_table AND my_table_new; DROP TABLE my_table_new;Use the correct command for your engine type. For example, to delete data from a Log table, you cannot use mutations -- you need to recreate the table:
-- For MergeTree: use mutations ALTER TABLE my_mergetree_table DELETE WHERE id = 5; -- For Log: recreate without the unwanted rows CREATE TABLE my_log_table_tmp AS my_log_table; INSERT INTO my_log_table_tmp SELECT * FROM my_log_table WHERE id != 5; EXCHANGE TABLES my_log_table AND my_log_table_tmp; DROP TABLE my_log_table_tmp;For replicated operations, confirm the table uses a Replicated engine variant:
SELECT name, engine FROM system.tables WHERE engine LIKE 'Replicated%' AND name = 'my_table';Review your automation scripts to ensure they do not assume a specific engine for all tables. Add engine checks before running engine-specific operations.
Best Practices
- Check a table's engine before running engine-specific operations, especially in automated scripts.
- Standardize on MergeTree-family engines for analytical tables to get the broadest feature support.
- Document which engine each table uses and why, so team members know what operations are available.
- When writing generic maintenance scripts, query
system.tablesto filter by engine before issuing engine-specific commands. - Use
EXCHANGE TABLESfor engine migrations to minimize downtime.
Frequently Asked Questions
Q: Can I change a table's engine without recreating it?
A: No. ClickHouse does not support ALTER TABLE ... ENGINE = .... You must create a new table with the desired engine, migrate the data, and swap them.
Q: Which operations are specific to ReplicatedMergeTree and will not work on plain MergeTree?
A: Commands like SYSTEM SYNC REPLICA, SYSTEM RESTART REPLICA, SYSTEM RESTORE REPLICA, and SYSTEM DROP REPLICA are all replication-specific and only work on ReplicatedMergeTree tables.
Q: I tried OPTIMIZE TABLE on a Distributed table and got this error. What should I do?
A: OPTIMIZE does not apply to Distributed tables. Run OPTIMIZE on the underlying local tables (the MergeTree tables that the Distributed table routes to) on each shard individually.
Q: Can I use ALTER TABLE ... UPDATE on a Memory table?
A: No. Mutations (UPDATE and DELETE via ALTER) are only supported by MergeTree-family engines. For Memory tables, you would need to recreate the table with the desired data.