Fix Parquet writer data race - #956
Merged
Merged
Conversation
On top of LadybugDB#956 (which fixed the TSan data race by serializing the whole flush): move the null counter from the shared ColumnWriter into the thread-local ColumnWriterState, so prepareRowGroup() only reads shared immutable state (writer layout, schema, codec) and writes to the per-flush PreparedRowGroup. flush() now prepares lock-free in parallel and serializes just the commit (fileOffset / file bytes / fileMetaData) in flushRowGroup(). ft.clear() stays outside the lock since the FactorizedTable is thread-local. Side benefit: null_count statistics are now per row group instead of accumulating across row groups. Verified: 8-thread COPY round-trips (200k scalar rows with NULLs, 50k struct rows with NULLs) match ground-truth counts/sums.
Contributor
|
The fix looks correct. Trying to see if we can keep it correct while restoring the write parallelism that existed before. |
adsharma
added a commit
that referenced
this pull request
Sep 10, 2026
On top of #956 (which fixed the TSan data race by serializing the whole flush): move the null counter from the shared ColumnWriter into the thread-local ColumnWriterState, so prepareRowGroup() only reads shared immutable state (writer layout, schema, codec) and writes to the per-flush PreparedRowGroup. flush() now prepares lock-free in parallel and serializes just the commit (fileOffset / file bytes / fileMetaData) in flushRowGroup(). ft.clear() stays outside the lock since the FactorizedTable is thread-local. Side benefit: null_count statistics are now per row group instead of accumulating across row groups. Verified: 8-thread COPY round-trips (200k scalar rows with NULLs, 50k struct rows with NULLs) match ground-truth counts/sums.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
This fixes a TSan data race in Parquet export.
Multiple worker threads could call
ParquetWriter::flush()concurrently. The existing mutex only protectedflushRowGroup(), whileprepareRowGroup()also modifies shared writer state.Moved the existing lock to cover the full flush operation.
ApiTest.PrepareExportpreviously reported 3 TSan warnings and now passes cleanly across repeated runs. A full TSan suite run also dropped from 10 race reports to 2, with no remaining Parquet-related races.Part of #879.