exwiw 0.9.13 → 0.9.14
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/CHANGELOG.md +6 -0
- data/README.md +1 -1
- data/docs/sql-dump-optimization-notes.md +2 -1
- data/lib/exwiw/adapter/sql_bulk_insert.rb +18 -5
- data/lib/exwiw/adapter.rb +10 -9
- data/lib/exwiw/version.rb +1 -1
- metadata +1 -1
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: 1e66762378ba8b4357a2d42fff5fbb1f0c12e96979d0e59f6fdcaae46bd7da4d
|
|
4
|
+
data.tar.gz: 1c1cd268f516ab60b34915f77fc1ab2ed7e6cdfb8d4cc1e508abf026bb5519fa
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: dd5dda5f6dcfa4fce06b3e9bd7ef5c8d9d45fb32a2606db0bc2dcf5aa047784036bec61d7a4efe49d92632fb4bdd9bb460445b72587503a05e1bd49f0fa1fd63
|
|
7
|
+
data.tar.gz: 267f0de9ca7fcca1ee19e4005031c5740493ea9d8550e13af6bc199f90f45377d5f9a840f4379a28fa8fe73ec7e26514a0fa0e2523df4df43143663dbed2dbf0
|
data/CHANGELOG.md
CHANGED
|
@@ -2,6 +2,12 @@
|
|
|
2
2
|
|
|
3
3
|
## [Unreleased]
|
|
4
4
|
|
|
5
|
+
## [0.9.14] - 2026-07-29
|
|
6
|
+
|
|
7
|
+
### Changed
|
|
8
|
+
|
|
9
|
+
- **SQL adapters now default `bulk_insert_chunk_size` to 10_000** (previously nil = one INSERT statement per table). A single statement covering a multi-million-row table exceeds the import target's `max_allowed_packet` and aborts the load with "MySQL server has gone away". Output for tables at or below 10,000 rows is byte-identical; larger tables now emit multiple bounded INSERT statements. Set `bulk_insert_chunk_size` in a table config to override.
|
|
10
|
+
|
|
5
11
|
## [0.9.13] - 2026-07-28
|
|
6
12
|
|
|
7
13
|
### Changed
|
data/README.md
CHANGED
|
@@ -753,7 +753,7 @@ Unlike rails-managed entries, `columns` and `belongs_tos` are retained so the en
|
|
|
753
753
|
|
|
754
754
|
`bulk_insert_chunk_size` splits the generated `INSERT` statement into multiple statements, each containing at most the specified number of rows. This is useful when the number of records per table is large enough to hit limits like MySQL's `max_allowed_packet`.
|
|
755
755
|
|
|
756
|
-
If omitted,
|
|
756
|
+
If omitted, the adapter default applies: 10,000 rows per statement for the SQL adapters (1,000 documents per chunk for MongoDB). Tables at or below the chunk size still produce a single `INSERT` statement. To force a single statement regardless of table size, set a value larger than the table's row count.
|
|
757
757
|
|
|
758
758
|
### Filter
|
|
759
759
|
|
|
@@ -34,7 +34,8 @@ The Runner drives, per table:
|
|
|
34
34
|
downstream.
|
|
35
35
|
|
|
36
36
|
2. **to_bulk_insert** — SQL adapters set **no** `default_bulk_insert_chunk_size`
|
|
37
|
-
(it
|
|
37
|
+
(it was `nil` at measurement time; since then the default is 10_000 —
|
|
38
|
+
large tables emit multiple bounded INSERT statements), so at measurement time the Runner treated the whole table as one chunk and
|
|
38
39
|
`to_bulk_insert` builds the **entire** `INSERT INTO ... VALUES (...),(...);`
|
|
39
40
|
as one giant String — first an `Array` of N per-row tuple strings, then the
|
|
40
41
|
joined result — held simultaneously with the result set from step 1.
|
|
@@ -18,8 +18,8 @@ module Exwiw
|
|
|
18
18
|
# Array#map + Array#join (the same C-level path #to_bulk_insert uses) so it
|
|
19
19
|
# stays close to whole-string speed — far faster than a naive row-at-a-time
|
|
20
20
|
# IO#print (see script/bench_sql_dump.rb / docs/sql-dump-optimization-notes.md).
|
|
21
|
-
#
|
|
22
|
-
#
|
|
21
|
+
# Bounded work per flush WITHIN a single statement: flush boundaries never
|
|
22
|
+
# split a statement — statement boundaries come from bulk_insert_chunk_size.
|
|
23
23
|
STREAM_FLUSH_ROWS = 2_000
|
|
24
24
|
|
|
25
25
|
# Build the whole INSERT statement as a single String. Kept for callers
|
|
@@ -37,15 +37,28 @@ module Exwiw
|
|
|
37
37
|
# resident at a time rather than the entire table's INSERT string. Returns
|
|
38
38
|
# [statement_count, record_count]; record_count is tallied during the single
|
|
39
39
|
# streaming drain so the Runner needs no separate SELECT COUNT(*) pass.
|
|
40
|
+
# Chunks are buffered off `#each` rather than `results.each_slice(...)`:
|
|
41
|
+
# each_slice consults the receiver's `#size` (verified on CRuby for both
|
|
42
|
+
# the block and enumerator forms), which on a streaming result issues a
|
|
43
|
+
# redundant `SELECT COUNT(*)` — a second full pass over the same filter.
|
|
44
|
+
# Manual buffering walks the cursor exactly once.
|
|
40
45
|
def write_inserts(io, results, table, chunk_size)
|
|
41
|
-
|
|
46
|
+
return [1, stream_single_insert(io, results, table)] unless chunk_size
|
|
47
|
+
|
|
42
48
|
statement_count = 0
|
|
43
49
|
record_count = 0
|
|
44
|
-
|
|
50
|
+
buffer = []
|
|
51
|
+
flush = lambda do
|
|
45
52
|
io.print("\n") if statement_count.positive?
|
|
46
|
-
record_count += stream_single_insert(io,
|
|
53
|
+
record_count += stream_single_insert(io, buffer, table)
|
|
47
54
|
statement_count += 1
|
|
55
|
+
buffer.clear
|
|
48
56
|
end
|
|
57
|
+
results.each do |row|
|
|
58
|
+
buffer << row
|
|
59
|
+
flush.call if buffer.size >= chunk_size
|
|
60
|
+
end
|
|
61
|
+
flush.call unless buffer.empty?
|
|
49
62
|
[statement_count, record_count]
|
|
50
63
|
end
|
|
51
64
|
|
data/lib/exwiw/adapter.rb
CHANGED
|
@@ -120,13 +120,14 @@ module Exwiw
|
|
|
120
120
|
end
|
|
121
121
|
|
|
122
122
|
# Default bulk-insert chunk size when a table config does not set one.
|
|
123
|
-
# The Runner streams each chunk straight to the output file, so
|
|
124
|
-
#
|
|
125
|
-
#
|
|
126
|
-
#
|
|
127
|
-
#
|
|
123
|
+
# The Runner streams each chunk straight to the output file, so this
|
|
124
|
+
# bounds how much serialized output lives in memory at once — and, for
|
|
125
|
+
# SQL adapters, bounds the size of each INSERT statement: a single
|
|
126
|
+
# statement covering a multi-million-row table exceeds the target
|
|
127
|
+
# server's max_allowed_packet at import time ("MySQL server has gone
|
|
128
|
+
# away"). Table configs can override per table.
|
|
128
129
|
def default_bulk_insert_chunk_size
|
|
129
|
-
|
|
130
|
+
10_000
|
|
130
131
|
end
|
|
131
132
|
|
|
132
133
|
# Write the bulk INSERT/JSONL output for `results` to the open `io`,
|
|
@@ -164,9 +165,9 @@ module Exwiw
|
|
|
164
165
|
# untouched, so the cursor is walked exactly once. The chunk boundaries and
|
|
165
166
|
# "\n" separators reproduce the each_slice output byte-for-byte.
|
|
166
167
|
#
|
|
167
|
-
# chunk_size is always positive for callers of this default (MongoDB
|
|
168
|
-
#
|
|
169
|
-
#
|
|
168
|
+
# chunk_size is always positive for callers of this default (MongoDB,
|
|
169
|
+
# whose adapter default is 1_000); the SQL adapters override
|
|
170
|
+
# #write_inserts (SqlBulkInsert) with their own chunked writer.
|
|
170
171
|
def write_inserts(io, results, table, chunk_size)
|
|
171
172
|
statement_count = 0
|
|
172
173
|
record_count = 0
|
data/lib/exwiw/version.rb
CHANGED