Skip to content

Conversation

@jeffswenson
Copy link
Collaborator

This reworks the LDR crud writer to use the isql.Session, prepared statements, and generic query plans. When replicating TPC-C, this PR is more than 2x more efficient than the version of the crud writer that was using the internal executor.

Release note: none
Fixes: #148310

@jeffswenson jeffswenson requested a review from msbutler October 29, 2025 20:58
@jeffswenson jeffswenson requested a review from a team as a code owner October 29, 2025 20:58
@cockroach-teamcity
Copy link
Member

This change is Reviewable

@jeffswenson jeffswenson force-pushed the jeffswenson-ldr-use-isession branch from 3228cb3 to d962bc3 Compare October 29, 2025 22:13
show-select table=products
----
SELECT key_list.index, replication_target.crdb_internal_origin_timestamp, replication_target.crdb_internal_mvcc_timestamp, replication_target.id, replication_target.name, replication_target.unit_price, replication_target.quantity, replication_target.total_value, replication_target.last_updated FROM ROWS FROM (unnest($1::INT8[], $2::DECIMAL(10,2)[])) WITH ORDINALITY AS key_list (key1, key2, index) INNER LOOKUP JOIN [108 AS replication_target] ON (replication_target.id = key_list.key1) AND (replication_target.total_value = key_list.key2)
SELECT key_list.index, replication_target.crdb_internal_origin_timestamp, replication_target.crdb_internal_mvcc_timestamp, replication_target.id, replication_target.name, replication_target.unit_price, replication_target.quantity, replication_target.total_value, replication_target.last_updated FROM ROWS FROM (unnest($1::INT8[], $2::DECIMAL[])) WITH ORDINALITY AS key_list (key1, key2, index) INNER LOOKUP JOIN [108 AS replication_target] ON (replication_target.id = key_list.key1) AND (replication_target.total_value = key_list.key2)
Copy link
Collaborator Author

Choose a reason for hiding this comment

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

NOTE: the change in this query is a side effect of switching to consistently use the canonical type within LDR. The canonical type of a decimal with fixed with is a decimal with variable width.

@stevendanna
Copy link
Collaborator

When replicating TPC-C, this PR is more than 2x more efficient than the version of the crud writer that was using the internal executor.

Nice. Out of curiosity, does that make it faster than the KV writer now?

@jeffswenson
Copy link
Collaborator Author

Nice. Out of curiosity, does that make it faster than the KV writer now?

It's faster than the KV writer in cases where the KV writer performs 2-PC and ~20% less efficient in cases where the KV writer hits the 1-PC fast path.

@stevendanna
Copy link
Collaborator

It's faster than the KV writer in cases where the KV writer performs 2-PC and ~20% less efficient in cases where the KV writer hits the 1-PC fast path.

Awesome. Huge win here.

Copy link
Collaborator

@msbutler msbutler left a comment

Choose a reason for hiding this comment

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

Amazing! left a couple nits


sd = sd.Clone()
sd.PlanCacheMode = sessiondatapb.PlanCacheModeForceGeneric
sd.VectorizeMode = sessiondatapb.VectorizeOff
Copy link
Collaborator

Choose a reason for hiding this comment

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

just curious: why no vectorized execution or buffered writes?

Copy link
Collaborator

Choose a reason for hiding this comment

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

Buffered writes doesn't support batches with any WriteOptions set. That should be relatively straightforward if needed. However, I kinda wonder if buffered writes really helps y'all that much.

ctx context.Context, originTimestamp hlc.Timestamp,
) error {
return s.session.ModifySession(ctx, func(m sessionmutator.SessionDataMutator) {
m.Data.OriginIDForLogicalDataReplication = 1
Copy link
Collaborator

Choose a reason for hiding this comment

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

nit: no need to set originID everytime, yeah?

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

Good point. I moved this to the static session initialization.

@jeffswenson jeffswenson force-pushed the jeffswenson-ldr-use-isession branch from d962bc3 to dd779c0 Compare October 30, 2025 21:11
This reworks the LDR crud writer to use the isql.Session, prepared
statements, and generic query plans. When replicating TPC-C, this PR is
more than 2x more efficient than the version of the crud writer that was
using the internal executor.

Release note: none
Fixes: cockroachdb#148310
@jeffswenson jeffswenson force-pushed the jeffswenson-ldr-use-isession branch from dd779c0 to 436c452 Compare October 30, 2025 22:06
@jeffswenson
Copy link
Collaborator Author

Thanks for the reviews!

bors r+

@craig
Copy link
Contributor

craig bot commented Oct 31, 2025

@craig craig bot merged commit c1b788a into cockroachdb:master Oct 31, 2025
24 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

ldr: create sessionfull internal executor

4 participants