Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

sql: RETAIN HISTORY for materialized views #23788

Merged
merged 1 commit into from
Dec 17, 2023

Conversation

maddyblue
Copy link
Contributor

@maddyblue maddyblue commented Dec 9, 2023

Add RETAIN HISTORY to materialized views.

See https://github.com/MaterializeInc/database-issues/issues/4840

Motivation

  • This PR adds a known-desirable feature.

Checklist

  • This PR has adequate test coverage / QA involvement has been duly considered.
  • This PR has an associated up-to-date design doc, is a design doc (template), or is sufficiently small to not require a design.
  • If this PR evolves an existing $T ⇔ Proto$T mapping (possibly in a backwards-incompatible way), then it is tagged with a T-proto label.
  • If this PR will require changes to cloud orchestration or tests, there is a companion cloud PR to account for those changes that is tagged with the release-blocker label (example).
  • This PR includes the following user-facing behavior changes:
    • Add COMPACTION WINDOW to MATERIALIZED VIEWS.

@maddyblue maddyblue requested a review from a team as a code owner December 9, 2023 21:53
@maddyblue maddyblue requested review from a team and jkosh44 December 9, 2023 21:53
@frankmcsherry
Copy link
Contributor

Is this a good place to bikeshed the name? I think users may not understand "compaction" but might understand e.g. "history" or "historical" windows instead?

Copy link
Contributor

@jkosh44 jkosh44 left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Code LGTM, I don't really have a strong opinion on the naming.

EDIT: I forgot I'm on the SQL council this month. I will form an opinion next week.

let source = ts.sources.into_element();
let upper = source.write_frontier.into_element();
let since = source.read_frontier.into_element();
if upper.saturating_sub(since) > Timestamp::from(2000u64) {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Should this be >=?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't know! During testing the diff was usually just a bit above 2000. I'm not sure what the guarantees are for read and write frontiers in the storage controller though. I changed it?

Copy link
Member

@benesch benesch left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Requesting changes since there's a pending discussion on the naming of the option in Slack.

@maddyblue
Copy link
Contributor Author

Changed to RETAIN HISTORY = FOR <interval>.

@maddyblue maddyblue changed the title sql: COMPACTION WINDOW for materialized views sql: RETAIN HISTORY for materialized views Dec 11, 2023
Copy link
Member

@benesch benesch left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Syntax looks good modulo the point about the equals sign being optional.

Just to confirm: it's not possible with this change to alter the compaction window for a materialized view, yeah? Seems fine, since this is plenty to unblock testing with rETL tools.

src/sql-parser/src/parser.rs Outdated Show resolved Hide resolved
Comment on lines 1558 to 1559
/// Disable logical compaction entirely.
Disabled,
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is this meant to be constructible at the moment? It doesn't seem to be! Is the idea that we'll introduce RETAIN HISTORY = FOREVER in the future?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It is written this way to have compatibility with index options which allow for this:

/// Configures the logical compaction window for an index. `None` disables

In a later PR I would like to refactor the index planning and controller read policy code to use this new enum instead of passing around Option<milliseconds or Timestamp or Duration>.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The principal motivation for this struct is to describe exactly what a None Option means. There are some places it means "I want NO user compaction performed" and others it means "no one specified anything, use the default". With the current scheme we'd have some Option<Option<Duration>> in a few places. I thought this would improve that greatly, although the refactor is getting annoying.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

That plan sounds good to me! I just couldn't tell in the current code where the Disabled variant was getting used.

@maddyblue
Copy link
Contributor Author

it's not possible with this change to alter the compaction window for a materialized view, yeah?

Correct. ALTER is a bit harder because it has to muck with the SQL. I'd like to ship retain history for CREATE tables, sources and mvs. Then do ALTER afterward.

@maddyblue
Copy link
Contributor Author

Hold off on any more reviews, this doesn't work on restart.

@maddyblue
Copy link
Contributor Author

RFAL. First commit is #23854. This now works on restart and has a test for that.

Copy link
Member

@benesch benesch left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Syntax LGTM. Not going to have time to look through the rest.

@ggevay
Copy link
Contributor

ggevay commented Dec 13, 2023

Oh, great! I'm happy about this, because I'm planning to also increase the compaction window of REFRESH EVERY materialized views to the refresh interval, and I guess that should be easy after this PR.

I have a question: What happens with indexes on a materialized view that has a custom compaction window? Does the compaction window of the index inherit the MV's window? If not, then this might be surprising to users: they might expect that creating an index can only speed up querying from the MV but never alter the semantics.

@@ -448,7 +446,7 @@ pub struct Source {
pub desc: RelationDesc,
pub timeline: Timeline,
pub resolved_ids: ResolvedIds,
pub custom_logical_compaction_window: Option<Duration>,
pub custom_logical_compaction_window: Option<CustomCompactionWindow>,
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

For these objects, what's the difference between None and Some(CustomCompactionWindow::Default)?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

none means the user did not specify a custom window in the syntax. maybe customcompactionwindow::default should not exist then since it's implied by none!

@maddyblue maddyblue requested a review from a team December 14, 2023 02:15
@maddyblue maddyblue requested a review from a team as a code owner December 14, 2023 02:15
@maddyblue maddyblue force-pushed the mv-lcw branch 4 times, most recently from d14d5bf to 86ee2ca Compare December 14, 2023 04:45
@@ -29,6 +32,44 @@
]


def workflow_retain_history(c: Composition) -> None:
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Putting this test in restart doesn't feel quite right. Is there a better place to put it?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

restart seems right to me, actually! In the future #team-testing will get you a very fast answer to these sorts of questions. They'd probably recommend adding a platform check for this, since platform checks get interspersed with all sorts of disruptions, like restarts. Can do that as a followup though. cc @MaterializeInc/testing for thoughts.

@maddyblue
Copy link
Contributor Author

The restart test is failing in another test in the file because

$ docker volume rm --force restart_mzdata
--
  | Error response from daemon: remove restart_mzdata: volume is in use - [76a26dde16d3d6561f4829e78674f07de904cbc6a5c330e8cbb2c643b076f28d]

Retrying didn't fix it and I'm unable to reproduce locally. Any ideas?

@nrainer-materialize
Copy link
Contributor

The restart test is failing in another test in the file because

$ docker volume rm --force restart_mzdata
--
  | Error response from daemon: remove restart_mzdata: volume is in use - [76a26dde16d3d6561f4829e78674f07de904cbc6a5c330e8cbb2c643b076f28d]

Retrying didn't fix it and I'm unable to reproduce locally. Any ideas?

The full stack trace is:

Error response from daemon: remove restart_mzdata: volume is in use - [76a26dde16d3d6561f4829e78674f07de904cbc6a5c330e8cbb2c643b076f28d]
--- mzcompose: test case stash failed: <class 'subprocess.CalledProcessError'>: Command '['docker', 'volume', 'rm', '--force', 'restart_mzdata']' returned non-zero exit status 1.
Traceback (most recent call last):
  File "/var/lib/buildkite-agent/builds/buildkite-15f2293-i-01becf557c126887b-1/materialize/tests/misc/python/materialize/mzcompose/composition.py", line 475, in test_case
    yield
  File "/var/lib/buildkite-agent/builds/buildkite-15f2293-i-01becf557c126887b-1/materialize/tests/test/restart/mzcompose.py", line 433, in workflow_default
    c.workflow(name)
  File "/var/lib/buildkite-agent/builds/buildkite-15f2293-i-01becf557c126887b-1/materialize/tests/misc/python/materialize/mzcompose/composition.py", line 371, in workflow
    func(self)
  File "/var/lib/buildkite-agent/builds/buildkite-15f2293-i-01becf557c126887b-1/materialize/tests/test/restart/mzcompose.py", line 185, in workflow_stash
    c.rm_volumes("mzdata", force=True)
  File "/var/lib/buildkite-agent/builds/buildkite-15f2293-i-01becf557c126887b-1/materialize/tests/misc/python/materialize/mzcompose/composition.py", line 939, in rm_volumes
    spawn.runv(
  File "/var/lib/buildkite-agent/builds/buildkite-15f2293-i-01becf557c126887b-1/materialize/tests/misc/python/materialize/spawn.py", line 72, in runv
    return subprocess.run(

test/restart/mzcompose.py:433 just triggers the workflow.
test/restart/mzcompose.py:185 is c.rm_volumes("mzdata", force=True) in workflow_stash.

@philip-stoev, have you seen this before? Any ideas?

@maddyblue
Copy link
Contributor Author

What happens with indexes on a materialized view that has a custom compaction window? Does the compaction window of the index inherit the MV's window?

Good point! This is a thing we decided on in the read holds design

An `AS OF` query will restrict the indexes or object it considers to those that are valid for the requested time.

And it needs to be tested and probably implemented here.

@maddyblue
Copy link
Contributor Author

The docker ps -a log shows restart-testdrive_no_reset-1 is still running. Could that be related?

@maddyblue
Copy link
Contributor Author

What happens with indexes on a materialized view that has a custom compaction window?

Did some testing and adding an index seems to disable the compaction. Working on a fix.

@maddyblue
Copy link
Contributor Author

maddyblue commented Dec 16, 2023

We decided that indexes breaking this is in spec for now. Tests were added to assert that behavior. I'm going to merge this once I figure out the test failure.

Adding indexes currently breaks this, but we've decided that's in spec for now.
@maddyblue
Copy link
Contributor Author

@benesch Merging is blocked until your change request is resolved.

@benesch
Copy link
Member

benesch commented Dec 17, 2023

FYI you can dismiss stale reviews here!
image

@benesch benesch dismissed their stale review December 17, 2023 02:14

SQL council has approved syntax

@maddyblue maddyblue merged commit fb26da5 into MaterializeInc:main Dec 17, 2023
63 checks passed
@maddyblue maddyblue deleted the mv-lcw branch December 17, 2023 02:14
@maddyblue
Copy link
Contributor Author

TIL! Thanks.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

6 participants