You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
Repository navigation
Incorrect table definition after executing rollback_to_snapshot procedure #5591
Spark returns the latest table definition even after executing rollback_to_snapshot procedure.
Steps to reproduce
> CREATE TABLE test USING iceberg AS SELECT 1 c1;
> ALTER TABLE test ADD COLUMN c2 int;
> INSERT INTO test VALUES (1, 1);
> SELECT * FROM iceberg_test.default.test.snapshots;
2022-08-19 07:32:29.499 2770581293596517273 ...
2022-08-19 07:32:50.006 6893045681966948046 ...
> DESC iceberg_test.default.test.snapshot_id_2770581293596517273;
c1 int
# Partitioning
Not partitioned
> CALL iceberg_test.system.rollback_to_snapshot('default.test', 2770581293596517273);
> DESC iceberg_test.default.test;
c1 int
c2 int
The result is same even after I executed REFRESH TABLE iceberg_test.default.test after rollback_to_snapshot.
I'm able to reproduce it and it looks like the data is rolebacked, but the schema isn't.
%%sql
CREATETABLEtest.test USING iceberg ASSELECT1 c1;
SLF4J: Failed to load class "org.slf4j.impl.StaticLoggerBinder".
SLF4J: Defaulting to no-operation (NOP) logger implementation
SLF4J: See http://www.slf4j.org/codes.html#StaticLoggerBinder for further details.
This isn't a bug. Metadata and data updates are intended to be separate, although I can see why there are cases where you'd assume that they are not.
If you update the schema and commit data in a single job, then it isn't unreasonable to assume the schema change would be rolled back. But if I concurrently add a column while someone else commits, then a rollback should be independent. Expectations can go both ways.
While expectations differ, Iceberg never rolls back to a previous schema because that operation is unsafe. For example, if someone deletes a required column and then tries to roll that back, there may have been data written without that column. You can recover the column, but you need to make it optional (or in the future, set a read default).
@rdblue thanks for the background information. I see the point.
One question, are there situations where it is possible to do a rollback, but still have additional data being written? I would expect that the rollback would cause a conflict on a concurrent write. And then it would fail because of a schema mismatch.
Schema evolution rules allow always being able to write with an older schema, so that there is no need to check whether the schema a writer is using is allowed. That cuts down on commit conflicts, but it also means that schemas should always be rolled forward and never backward. I don't think that we want to start adding extra validation to support a case where we roll back a schema.
Could you please document the behavior or is it mentioned in somewhere? I believe the current behavior isn't intuitive and I saw some other people in Iceberg community said "it's a bug".
Reacted by Perfect Stranger, Andrew Sherman, wood, yotahk, Mihir Gadgil and Tom Ebergen
From end-user perspective, there is a difference between
querying table state at given snapshot -- at least in Trino, this uses the "schema current at that time", so includes columns that have been dropped since then
query table state after rollback_to_snapshot -- if this uses current schema, this doesn't include columns that have been dropped since the snapshot
Now consider example
-- add new column
ALTER TABLE orders ADD COLUMN order_timestamp timestamp(6) with time zone;
-- feel in data for new column
UPDATE orders SET order_timestamp = CAST(json_value(order_data, '$.timestamp') AS timestamp(6) with time zone);
-- drop the now-redundant column
ALTER TABLE orders DROP COLUMN order_data;
-- imagine now that comparing this uncovered that `order_data` was encoded in a bad way, so we need to roll this all back
CALL rollback_to_snapshot(.....)
As a user, i would expect to see order_data column back in my table.
Per this issue, i understand this wouldn't be the case. As a user I would call it a data loss (and so a bug).
This issue has been automatically marked as stale because it has been open for 180 days with no activity. It will be closed in next 14 days if no further activity occurs. To permanently prevent this issue from being considered stale, add the label 'not-stale', but commenting on the issue is preferred when possible.
Activity
Fokko commentedon Aug 22, 2022
I'm able to reproduce it and it looks like the data is rolebacked, but the schema isn't.
Waiting one minute
Fokko commentedon Aug 22, 2022
It looks like the
current_schema_idis not being updated when rolling back to an earlier snapshot:Spark: Set the current schema id when rolling back a snapshot
Fokko commentedon Aug 22, 2022
@ebyhr Thanks for reporting this, this looks like a bug 🐛 I've created a PR to fix this, but I would love to get some input from other maintainers.
rdblue commentedon Aug 22, 2022
This isn't a bug. Metadata and data updates are intended to be separate, although I can see why there are cases where you'd assume that they are not.
If you update the schema and commit data in a single job, then it isn't unreasonable to assume the schema change would be rolled back. But if I concurrently add a column while someone else commits, then a rollback should be independent. Expectations can go both ways.
While expectations differ, Iceberg never rolls back to a previous schema because that operation is unsafe. For example, if someone deletes a required column and then tries to roll that back, there may have been data written without that column. You can recover the column, but you need to make it optional (or in the future, set a read default).
Fokko commentedon Aug 22, 2022
@rdblue thanks for the background information. I see the point.
One question, are there situations where it is possible to do a rollback, but still have additional data being written? I would expect that the rollback would cause a conflict on a concurrent write. And then it would fail because of a schema mismatch.
rdblue commentedon Aug 22, 2022
Schema evolution rules allow always being able to write with an older schema, so that there is no need to check whether the schema a writer is using is allowed. That cuts down on commit conflicts, but it also means that schemas should always be rolled forward and never backward. I don't think that we want to start adding extra validation to support a case where we roll back a schema.
ebyhr commentedon Sep 2, 2022
Could you please document the behavior or is it mentioned in somewhere? I believe the current behavior isn't intuitive and I saw some other people in Iceberg community said "it's a bug".
findepi commentedon Sep 5, 2022
From end-user perspective, there is a difference between
querying table state at given snapshot -- at least in Trino, this uses the "schema current at that time", so includes columns that have been dropped since then
query table state after rollback_to_snapshot -- if this uses current schema, this doesn't include columns that have been dropped since the snapshot
Now consider example
As a user, i would expect to see
order_datacolumn back in my table.Per this issue, i understand this wouldn't be the case. As a user I would call it a data loss (and so a bug).
cc @alexjo2144 @electrum
github-actions commentedon Mar 8, 2023
This issue has been automatically marked as stale because it has been open for 180 days with no activity. It will be closed in next 14 days if no further activity occurs. To permanently prevent this issue from being considered stale, add the label 'not-stale', but commenting on the issue is preferred when possible.
github-actions commentedon Mar 23, 2023
This issue has been closed because it has not received any activity in the last 14 days since being marked as 'stale'
Keep current schema when rolling back to a snapshot.