2
0

README.statement_timeouts 6.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159
  1. Timeouts for running SQL statements.
  2. Author:
  3. Vlad Khorsun <[email protected]>
  4. Description:
  5. The feature allows to set timeout for SQL statement, i.e. it allows to automatically
  6. stop execution of SQL statement when it running longer than given timeout value.
  7. The feature could be useful for:
  8. - database administrators get instrument to limit heavy queries from consuming too
  9. much resources
  10. - application developers could use statement timeout when creating\debugging complex
  11. queries with unknown in advance execution time
  12. - testers could use statement timeout to detect long running queries and ensure finite
  13. run time of the test suites
  14. - and so on
  15. From the end user point of view feature have following details:
  16. - when statement starts execution (or cursor is opened), engine starts special timer
  17. - fetch doesn't reset timer
  18. - timer is stopped when statement execution finished (or last record is fetched)
  19. - when timer is fired
  20. - if statement execution is active, it stops at closest possible moment
  21. - if statement is not active currently (between fetches, for example), it is marked
  22. as cancelled and next fetch will actually break execution and returns with error
  23. - timeout value could be set:
  24. - at database level, by setting value in firebird.conf (or databases.conf) by database
  25. administrator
  26. scope - all statements in all connections
  27. units - seconds
  28. - at connection level, using API and\or new SQL statement (see below)
  29. scope - all statements at given connection
  30. units - up to milliseconds
  31. - at statement level, using API
  32. scope - given statement
  33. units - milliseconds
  34. - effective value of timeout is evaluated every time statement starts execution
  35. (or cursor is opened) as:
  36. - if not set at statement level, look at connection level
  37. - if not set at connection level, look at database level
  38. - in any case can't be greater than value set at database level
  39. i.e. value of statement timeout could be overridden by application developer at lower
  40. scope but it can't relax limit set by DBA (in config)
  41. - zero timeout means no timeout, i.e. timer will not start
  42. - while statement timeout is set in milliseconds at API level, we can't promise
  43. absolute precision. With big load it could be less precise. The only guarantee
  44. is that timeout will not fire before specified moment.
  45. - if statement execution is cancelled due to timeout, then API call returns error
  46. isc_cancelled with secondary error code specifying exact reason:
  47. - isc_cfg_stmt_timeout: Config level timeout expired
  48. - isc_att_stmt_timeout: Attachment level timeout expired
  49. - isc_req_stmt_timeout: Statement level timeout expired
  50. - statement timeout is ignored for all internal queries issued by engine itself
  51. - statement timeout is ignored for DDL statements
  52. - client application could wait more time than set by timeout value if engine
  53. need to undo many actions due to statement cancellation
  54. - when engine run EXECUTE STATEMENT statement, it pass rest of currently active timeout
  55. to the new statement. If external (remote) engine doesn't support statement timeouts,
  56. local engine silently ignores corresponding error
  57. - when engine acquires some lock of lock manager, it could lower value of lock timeout
  58. using rest of the currently active statement timeout, if possible. Due to lock manager
  59. internals rest of statement timeout will be rounded up to the whole seconds.
  60. Support at configuration level (firebird.conf and\or databases.conf)
  61. New setting "StatementTimeout": set number of seconds after which statement execution
  62. will be automatically cancelled by the engine. Zero means no timeout is set.
  63. Per-database configurable. Type: integer. Default value is 0.
  64. Support at API level
  65. - get\set statement execution timeout at connection level, milliseconds:
  66. interface Attachment
  67. uint getStatementTimeout(Status status);
  68. void setStatementTimeout(Status status, uint timeOut);
  69. - get\set statement execution timeout at statement level, milliseconds:
  70. interface Statement
  71. uint getTimeout(Status status);
  72. void setTimeout(Status status, uint timeOut);
  73. - set statement execution timeout at statement level using ISC API, milliseconds:
  74. ISC_STATUS ISC_EXPORT fb_dsql_set_timeout(ISC_STATUS*, isc_stmt_handle*, ISC_ULONG);
  75. - get statement execution timeout at config and\or connection level is possible
  76. using isc_database_info() API with new info tags:
  77. - fb_info_statement_timeout_db
  78. - fb_info_statement_timeout_att
  79. - get statement execution timeout at statement level is possible using isc_dsql_info()
  80. API with new info tags:
  81. - isc_info_sql_stmt_timeout_user timeout value of given statement
  82. - isc_info_sql_stmt_timeout_run actual timeout value of given statement
  83. evaluated considering values set at config, connection and statement levels, see
  84. "effective value of timeout" above. Valid only when timeout timer is running, i.e.
  85. for currently executed statements.
  86. Remote client implementation notes:
  87. - Attachment::setStatementTimeout() issued "SET STATEMENT TIMEOUT" SQL statement
  88. - Attachment::getStatementTimeout() calls isc_database_info() with
  89. fb_info_statement_timeout_att tag
  90. - Statement::setTimeout() save timeout value given and pass it with op_execute
  91. and op_execute2 packets
  92. - Statement::getTimeout() returns saved timeout value
  93. - fb_dsql_set_timeout() is a wrapper over Statement::setTimeout()
  94. If remote server doesn't support statement timeouts (protocol version less than 16):
  95. - "set" functions will return isc_wish_list error
  96. - "get" functions will return zero and set isc_wish_list error
  97. - "info" functions will return isc_info_error tag in info buffer (as usual).
  98. Support in SQL
  99. - New SQL statement allows to set set statement execution timeout at connection level:
  100. SET STATEMENT TIMEOUT <value> [HOUR | MINUTE | SECOND | MILLISECOND]
  101. if timepart is not set, default is SECOND.
  102. This statement could run outside of transaction control and immediately effective.
  103. - Context variables
  104. Context 'SYSTEM' have new variable: 'STATEMENT_TIMEOUT'. It contains current value of
  105. statement execution timeout that was set at connection level, or zero, if timeout was
  106. not set.
  107. - Monitoring tables
  108. MON$ATTACHMENTS
  109. MON$STATEMENT_TIMEOUT Connection level statement timeout
  110. MON$STATEMENTS
  111. MON$STATEMENT_TIMEOUT Statement level statement timeout
  112. MON$STATEMENT_TIMER Timeout timer expiration time
  113. MON$STATEMENT_TIMEOUT contains timeout values set at connection\statement level,
  114. in milliseconds. Zero, if timeout is not set.
  115. MON$STATEMENT_TIMER contains NULL value if timeout was not set or if timer is not
  116. running.
  117. Support in ISQL tool
  118. New ISQL command is introduced:
  119. SET LOCAL_TIMEOUT <int>
  120. It allows to set statement execution timeout (in milliseconds) for the next statement.
  121. After statement execution it automatically reset to zero.