gooderp18绿色标准版
No puede seleccionar más de 25 temas Los temas deben comenzar con una letra o número, pueden incluir guiones ('-') y pueden tener hasta 35 caracteres de largo.

93 líneas
9.1KB

  1. <?xml version="1.0" encoding="UTF-8" standalone="no"?>
  2. <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"><html xmlns="http://www.w3.org/1999/xhtml"><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /><title>56.5. Row Locking in Foreign Data Wrappers</title><link rel="stylesheet" type="text/css" href="stylesheet.css" /><link rev="made" href="pgsql-docs@lists.postgresql.org" /><meta name="generator" content="DocBook XSL Stylesheets V1.79.1" /><link rel="prev" href="fdw-planning.html" title="56.4. Foreign Data Wrapper Query Planning" /><link rel="next" href="tablesample-method.html" title="Chapter 57. Writing a Table Sampling Method" /></head><body><div xmlns="http://www.w3.org/TR/xhtml1/transitional" class="navheader"><table width="100%" summary="Navigation header"><tr><th colspan="5" align="center">56.5. Row Locking in Foreign Data Wrappers</th></tr><tr><td width="10%" align="left"><a accesskey="p" href="fdw-planning.html" title="56.4. Foreign Data Wrapper Query Planning">Prev</a> </td><td width="10%" align="left"><a accesskey="u" href="fdwhandler.html" title="Chapter 56. Writing a Foreign Data Wrapper">Up</a></td><th width="60%" align="center">Chapter 56. Writing a Foreign Data Wrapper</th><td width="10%" align="right"><a accesskey="h" href="index.html" title="PostgreSQL 12.4 Documentation">Home</a></td><td width="10%" align="right"> <a accesskey="n" href="tablesample-method.html" title="Chapter 57. Writing a Table Sampling Method">Next</a></td></tr></table><hr></hr></div><div class="sect1" id="FDW-ROW-LOCKING"><div class="titlepage"><div><div><h2 class="title" style="clear: both">56.5. Row Locking in Foreign Data Wrappers</h2></div></div></div><p>
  3. If an FDW's underlying storage mechanism has a concept of locking
  4. individual rows to prevent concurrent updates of those rows, it is
  5. usually worthwhile for the FDW to perform row-level locking with as
  6. close an approximation as practical to the semantics used in
  7. ordinary <span class="productname">PostgreSQL</span> tables. There are multiple
  8. considerations involved in this.
  9. </p><p>
  10. One key decision to be made is whether to perform <em class="firstterm">early
  11. locking</em> or <em class="firstterm">late locking</em>. In early locking, a row is
  12. locked when it is first retrieved from the underlying store, while in
  13. late locking, the row is locked only when it is known that it needs to
  14. be locked. (The difference arises because some rows may be discarded by
  15. locally-checked restriction or join conditions.) Early locking is much
  16. simpler and avoids extra round trips to a remote store, but it can cause
  17. locking of rows that need not have been locked, resulting in reduced
  18. concurrency or even unexpected deadlocks. Also, late locking is only
  19. possible if the row to be locked can be uniquely re-identified later.
  20. Preferably the row identifier should identify a specific version of the
  21. row, as <span class="productname">PostgreSQL</span> TIDs do.
  22. </p><p>
  23. By default, <span class="productname">PostgreSQL</span> ignores locking considerations
  24. when interfacing to FDWs, but an FDW can perform early locking without
  25. any explicit support from the core code. The API functions described
  26. in <a class="xref" href="fdw-callbacks.html#FDW-CALLBACKS-ROW-LOCKING" title="56.2.5. FDW Routines for Row Locking">Section 56.2.5</a>, which were added
  27. in <span class="productname">PostgreSQL</span> 9.5, allow an FDW to use late locking if
  28. it wishes.
  29. </p><p>
  30. An additional consideration is that in <code class="literal">READ COMMITTED</code>
  31. isolation mode, <span class="productname">PostgreSQL</span> may need to re-check
  32. restriction and join conditions against an updated version of some
  33. target tuple. Rechecking join conditions requires re-obtaining copies
  34. of the non-target rows that were previously joined to the target tuple.
  35. When working with standard <span class="productname">PostgreSQL</span> tables, this is
  36. done by including the TIDs of the non-target tables in the column list
  37. projected through the join, and then re-fetching non-target rows when
  38. required. This approach keeps the join data set compact, but it
  39. requires inexpensive re-fetch capability, as well as a TID that can
  40. uniquely identify the row version to be re-fetched. By default,
  41. therefore, the approach used with foreign tables is to include a copy of
  42. the entire row fetched from a foreign table in the column list projected
  43. through the join. This puts no special demands on the FDW but can
  44. result in reduced performance of merge and hash joins. An FDW that is
  45. capable of meeting the re-fetch requirements can choose to do it the
  46. first way.
  47. </p><p>
  48. For an <code class="command">UPDATE</code> or <code class="command">DELETE</code> on a foreign table, it
  49. is recommended that the <code class="literal">ForeignScan</code> operation on the target
  50. table perform early locking on the rows that it fetches, perhaps via the
  51. equivalent of <code class="command">SELECT FOR UPDATE</code>. An FDW can detect whether
  52. a table is an <code class="command">UPDATE</code>/<code class="command">DELETE</code> target at plan time
  53. by comparing its relid to <code class="literal">root-&gt;parse-&gt;resultRelation</code>,
  54. or at execution time by using <code class="function">ExecRelationIsTargetRelation()</code>.
  55. An alternative possibility is to perform late locking within the
  56. <code class="function">ExecForeignUpdate</code> or <code class="function">ExecForeignDelete</code>
  57. callback, but no special support is provided for this.
  58. </p><p>
  59. For foreign tables that are specified to be locked by a <code class="command">SELECT
  60. FOR UPDATE/SHARE</code> command, the <code class="literal">ForeignScan</code> operation can
  61. again perform early locking by fetching tuples with the equivalent
  62. of <code class="command">SELECT FOR UPDATE/SHARE</code>. To perform late locking
  63. instead, provide the callback functions defined
  64. in <a class="xref" href="fdw-callbacks.html#FDW-CALLBACKS-ROW-LOCKING" title="56.2.5. FDW Routines for Row Locking">Section 56.2.5</a>.
  65. In <code class="function">GetForeignRowMarkType</code>, select rowmark option
  66. <code class="literal">ROW_MARK_EXCLUSIVE</code>, <code class="literal">ROW_MARK_NOKEYEXCLUSIVE</code>,
  67. <code class="literal">ROW_MARK_SHARE</code>, or <code class="literal">ROW_MARK_KEYSHARE</code> depending
  68. on the requested lock strength. (The core code will act the same
  69. regardless of which of these four options you choose.)
  70. Elsewhere, you can detect whether a foreign table was specified to be
  71. locked by this type of command by using <code class="function">get_plan_rowmark</code> at
  72. plan time, or <code class="function">ExecFindRowMark</code> at execution time; you must
  73. check not only whether a non-null rowmark struct is returned, but that
  74. its <code class="structfield">strength</code> field is not <code class="literal">LCS_NONE</code>.
  75. </p><p>
  76. Lastly, for foreign tables that are used in an <code class="command">UPDATE</code>,
  77. <code class="command">DELETE</code> or <code class="command">SELECT FOR UPDATE/SHARE</code> command but
  78. are not specified to be row-locked, you can override the default choice
  79. to copy entire rows by having <code class="function">GetForeignRowMarkType</code> select
  80. option <code class="literal">ROW_MARK_REFERENCE</code> when it sees lock strength
  81. <code class="literal">LCS_NONE</code>. This will cause <code class="function">RefetchForeignRow</code> to
  82. be called with that value for <code class="structfield">markType</code>; it should then
  83. re-fetch the row without acquiring any new lock. (If you have
  84. a <code class="function">GetForeignRowMarkType</code> function but don't wish to re-fetch
  85. unlocked rows, select option <code class="literal">ROW_MARK_COPY</code>
  86. for <code class="literal">LCS_NONE</code>.)
  87. </p><p>
  88. See <code class="filename">src/include/nodes/lockoptions.h</code>, the comments
  89. for <code class="type">RowMarkType</code> and <code class="type">PlanRowMark</code>
  90. in <code class="filename">src/include/nodes/plannodes.h</code>, and the comments for
  91. <code class="type">ExecRowMark</code> in <code class="filename">src/include/nodes/execnodes.h</code> for
  92. additional information.
  93. </p></div><div class="navfooter"><hr /><table width="100%" summary="Navigation footer"><tr><td width="40%" align="left"><a accesskey="p" href="fdw-planning.html">Prev</a> </td><td width="20%" align="center"><a accesskey="u" href="fdwhandler.html">Up</a></td><td width="40%" align="right"> <a accesskey="n" href="tablesample-method.html">Next</a></td></tr><tr><td width="40%" align="left" valign="top">56.4. Foreign Data Wrapper Query Planning </td><td width="20%" align="center"><a accesskey="h" href="index.html">Home</a></td><td width="40%" align="right" valign="top"> Chapter 57. Writing a Table Sampling Method</td></tr></table></div></body></html>
上海开阖软件有限公司 沪ICP备12045867号-1