Skip to content

Commit

Permalink
Merge pull request #1460 from nichtsfrei/gvmd-21.04
Browse files Browse the repository at this point in the history
Add retry if a deadlock occurs on postgres within sql#sql
  • Loading branch information
nichtsfrei authored Mar 23, 2021
2 parents 31b5ced + af9dee9 commit 1fa443a
Show file tree
Hide file tree
Showing 3 changed files with 31 additions and 1 deletion.
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/).
- Limit "whole-only" config families to "growing" and "every nvt" [#1386](https://github.com/greenbone/gvmd/pull/1386)
- Access current user with an SQL function [#1399](https://github.com/greenbone/gvmd/pull/1399)
- Refactor modify_config, allowing multiple simultaneous changes [#1404](https://github.com/greenbone/gvmd/pull/1404)
- Add retry on a deadlock within sql#sql [#1460](https://github.com/greenbone/gvmd/pull/1460)

### Fixed
- Use GMP version with leading zero for feed dirs [#1287](https://github.com/greenbone/gvmd/pull/1287)
Expand Down
21 changes: 21 additions & 0 deletions src/sql.c
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,15 @@
* @brief GLib log domain.
*/
#define G_LOG_DOMAIN "md manage"
/**
* @brief amount of ms sql should wait before retrying when a deadlock occured
*/
#define DEADLOCK_SLEEP 1000

/**
* @brief defines the amount of retries after a deadlock is considered a warning
*/
#define DEADLOCK_THRESHOLD 25


/* Headers of internal symbols defined in backend files. */
Expand Down Expand Up @@ -206,6 +215,8 @@ sqlv (int retry, char* sql, va_list args)
return -1;
if (ret == -4)
return 3;
if (ret == -5)
return 4;
assert (ret == -1 || ret == 0);
return ret;
}
Expand All @@ -220,6 +231,7 @@ sqlv (int retry, char* sql, va_list args)
void
sql (char* sql, ...)
{
unsigned int deadlock_amount = 0;
while (1)
{
va_list args;
Expand All @@ -231,6 +243,15 @@ sql (char* sql, ...)
if (ret == 1)
/* Gave up with statement reset. */
continue;
else if (ret == 4)
{
if (deadlock_amount++ > DEADLOCK_THRESHOLD)
{
g_warning("%s: %d deadlocks detected, wating and retrying %s", __func__, deadlock_amount, sql);
}
gvm_usleep (DEADLOCK_SLEEP);
continue;
}
else if (ret)
abort();
break;
Expand Down
10 changes: 9 additions & 1 deletion src/sql_pg.c
Original file line number Diff line number Diff line change
Expand Up @@ -523,7 +523,15 @@ sql_exec_internal (int retry, sql_stmt_t *stmt)
g_warning ("%s: SQL: %s", __func__, stmt->sql);
return -4;
}

else if (sqlstate && (strcmp (sqlstate, "40P01") == 0))
{
/* deadlock_detected */
g_debug ("%s: deadlock: %s",
__func__,
PQresultErrorMessage (result));
g_debug ("%s: SQL: %s", __func__, stmt->sql);
return -5;
}
if (log_errors)
{
g_warning ("%s: PQexec failed: %s (%i)",
Expand Down

0 comments on commit 1fa443a

Please sign in to comment.