Skip to content

Commit 6cc3a2d

Browse files
committed
store: Work around mysterious write errors
1 parent 3f3c4ef commit 6cc3a2d

File tree

5 files changed

+48
-9
lines changed

5 files changed

+48
-9
lines changed

graph/src/components/store/write.rs

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -933,6 +933,18 @@ impl<'a> WriteChunk<'a> {
933933
count: 0,
934934
}
935935
}
936+
937+
/// Return a vector of `WriteChunk`s each containing a single write
938+
pub fn as_single_writes(&self) -> Vec<Self> {
939+
(0..self.len())
940+
.into_iter()
941+
.map(|position| WriteChunk {
942+
group: self.group,
943+
chunk_size: 1,
944+
position: self.position + position,
945+
})
946+
.collect()
947+
}
936948
}
937949

938950
impl<'a> IntoIterator for &WriteChunk<'a> {

store/postgres/src/deployment_store.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -379,7 +379,7 @@ impl DeploymentStore {
379379
section.end();
380380

381381
let section = stopwatch.start_section("apply_entity_modifications_insert");
382-
layout.insert(conn, group, stopwatch).await?;
382+
layout.insert(&self.logger, conn, group, stopwatch).await?;
383383
section.end();
384384
}
385385

store/postgres/src/relational.rs

Lines changed: 33 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -736,6 +736,7 @@ impl Layout {
736736

737737
pub async fn insert<'a>(
738738
&'a self,
739+
logger: &Logger,
739740
conn: &mut AsyncPgConnection,
740741
group: &'a RowGroup,
741742
stopwatch: &StopwatchMetrics,
@@ -769,13 +770,39 @@ impl Layout {
769770
for chunk in group.write_chunks(chunk_size) {
770771
// Empty chunks would lead to invalid SQL
771772
if !chunk.is_empty() {
772-
InsertQuery::new(table, &chunk)?
773-
.execute(conn)
774-
.await
775-
.map_err(|e| {
773+
if let Err(e) = InsertQuery::new(table, &chunk)?.execute(conn).await {
774+
// We occasionally get these errors but it's entirely
775+
// unclear what causes them. We work around that by
776+
// switching to row-by-row inserts until we can figure
777+
// out what the underlying cause is
778+
let err_msg = e.to_string();
779+
if !err_msg.contains("value too large to transmit") {
776780
let (block, msg) = chunk_details(&chunk);
777-
StoreError::write_failure(e, table.object.as_str(), block, msg)
778-
})?;
781+
return Err(StoreError::write_failure(
782+
e,
783+
table.object.as_str(),
784+
block,
785+
msg,
786+
));
787+
}
788+
let (block, msg) = chunk_details(&chunk);
789+
warn!(logger, "Insert of entire chunk failed. Trying row by row insert.";
790+
"table" => table.object.as_str(),
791+
"block" => block,
792+
"error" => err_msg,
793+
"details" => msg
794+
);
795+
for single_chunk in chunk.as_single_writes() {
796+
InsertQuery::new(table, &single_chunk)?
797+
.execute(conn)
798+
.await
799+
.map_err(|e| {
800+
let (block, msg) = chunk_details(&single_chunk);
801+
let msg = format!("{}: offending row {:?}", msg, single_chunk);
802+
StoreError::write_failure(e, table.object.as_str(), block, msg)
803+
})?;
804+
}
805+
}
779806
}
780807
}
781808
Ok(())

store/test-store/tests/postgres/relational.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -271,7 +271,7 @@ async fn insert_entity_at(
271271
);
272272
let group = row_group_insert(&entity_type, block, entities_with_keys_owned.clone());
273273
layout
274-
.insert(conn, &group, &MOCK_STOPWATCH)
274+
.insert(&LOGGER, conn, &group, &MOCK_STOPWATCH)
275275
.await
276276
.expect(&errmsg);
277277
assert_eq!(

store/test-store/tests/postgres/relational_bytes.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -134,7 +134,7 @@ async fn insert_entity(
134134
let group = row_group_insert(&entity_type, 0, entities);
135135
let errmsg = format!("Failed to insert entity {}[{}]", entity_type, key.entity_id);
136136
layout
137-
.insert(conn, &group, &MOCK_STOPWATCH)
137+
.insert(&LOGGER, conn, &group, &MOCK_STOPWATCH)
138138
.await
139139
.expect(&errmsg);
140140
}

0 commit comments

Comments
 (0)