-
Type: Bug Report
-
Status: Needs Changes
-
Priority: Minor
-
Resolution: Unresolved
-
Affects Version/s: None
-
Fix Version/s: 5.2.2
-
Component/s: Database
-
Labels:None
-
Change Log Group:Fixed
-
Change Log Message:The queries causing lock/deadlock are retried automatically now.
-
Story Points:2
-
Copy Issue Key:
-
Patch Instructions:
Part 1 - fixing error retry for iterators
- add the '$iterator_class = ''' parameter for the "\kDBConnection::showError" method
- when when doing a retry and "$iterator_class" parameter isn't empty, then execute "$this->GetIterator($sql, $key_field, $no_debug, $iterator_class)" code instead of "$this->Query($sql, $key_field, $no_debug)" code
Part 2 - improving retry code
- add these settings to the "Database" sub-section of the "/system/config.php" file (specify them in the "Database Configuration" and "Update Database Configuration" steps of the installation wizard):
- DBErrorBackoffMaxRetryAttempts:
- title: Database Error Backoff Max Retry Attempts
- default: 3
- form control: textbox
- DBErrorBackoffLogicBaseTime:
- title: Database Error Backoff Logic Base Time (in milliseconds)
- default: 100
- form control: textbox
- DBEnableLockRetryDebugging:
- title: Database Lock Retry Debugging Enabled
- default: 0
- form control: radio buttons
- DBErrorBackoffMaxRetryAttempts:
- the default values of the above settings should be set via the "\kSystemConfig::getDefaults" method
- store values of the above settings as the protected properties of the "kDBConnection" class via the "kDBConnection::setup" method
- for all the places where kDBConnection/kDBConnectionDebug/kDBLoadBalancer classes are instantiated ensure, that their "setup" method called instead of the "Connect" method and values of above added settings are also passed to it
- for each of the database error handlers (specified during kDBConnection/kDBConnectionDebug/kDBLoadBalancer classes construction or via their "setErrorHandler" method) do this:
- add the "$throw_exception = null" parameter
- when "$throw_exception" is exactly "true", then throw the "RuntimeException"
- change the "kDBConnection::callErrorHandler" method like this:
- add the "$throw_exception = null" parameter
- pass on this parameter to the called error handler
- change the "\kDBConnection::showError" method like this:
- consider 1205 (lock) and 1213 (deadlock) errors are ones, that require retrying
- when a retriable error is encountered, then:
- call the "$this->callErrorHandler($sql, true)" instead of "$this->callErrorHandler($sql)" and catch the exception (we'll use it later)
- if no exception was caught, then rebuild it from error information as the "kLogger::handleSQLError" method does
- use the exponential formula for detecting a wait time (1st attempt: "DBErrorBackoffLogicBaseTime" time; 2nd+ attempt: 2^$attempt_number * "DBErrorBackoffLogicBaseTime"
- if it's a lock and "DBEnableLockRetryDebugging" setting is enabled, then add the caught exception to the System Log + additional info about the retry (retry number, total retries possible, wait time)
- if it's a disconnect issue, then reconnect
- execute Query/GetIterator method accordingly