54.5. ÐлокиÑовка ÑÑÑок в обÑÑÑÐºÐ°Ñ ÑÑоÑÐ¾Ð½Ð½Ð¸Ñ Ð´Ð°Ð½Ð½ÑÑ
ÐÑли нижележаÑий Ð¼ÐµÑ Ð°Ð½Ð¸Ð·Ð¼ Ñ ÑÐ°Ð½ÐµÐ½Ð¸Ñ FDW поддеÑÐ¶Ð¸Ð²Ð°ÐµÑ ÐºÐ¾Ð½ÑепÑÐ¸Ñ Ð±Ð»Ð¾ÐºÐ¸Ñовки оÑделÑнÑÑ ÑÑÑок, пÑедоÑвÑаÑаÑÑÑÑ Ð¾Ð´Ð½Ð¾Ð²Ñеменное изменение ÑÑÐ¸Ñ ÑÑÑок, обÑÑно Ð¸Ð¼ÐµÐµÑ ÑмÑÑл ÑеализоваÑÑ Ð² FDW ÑÑÑановление блокиÑовок на ÑÑовне ÑÑÑок в пÑиближении, наÑÑолÑко близком к обÑÑнÑм ÑаблиÑам Postgres Pro, наÑколÑко ÑÑо возможно и пÑакÑиÑно. ÐÑи ÑÑом нÑжно ÑÑиÑÑваÑÑ ÑÑд замеÑаний.
ÐеÑвое важное ÑеÑение, коÑоÑое нÑжно пÑинÑÑÑ â бÑÐ´ÐµÑ Ð»Ð¸ Ñеализована ÑаннÑÑ Ð±Ð»Ð¾ÐºÐ¸Ñовка или позднÑÑ Ð±Ð»Ð¾ÐºÐ¸Ñовка. С Ñанней блокиÑовкой ÑÑÑока блокиÑÑеÑÑÑ, когда впеÑвÑе ÑÑиÑÑваеÑÑÑ Ð¸Ð· нижележаÑего Ñ ÑанилиÑа, Ñогда как Ñ Ð¿Ð¾Ð·Ð´Ð½ÐµÐ¹ блокиÑовкой ÑÑÑока блокиÑÑеÑÑÑ, ÑолÑко когда извеÑÑно, ÑÑо ÐµÑ Ð½Ñжно заблокиÑоваÑÑ. (РазлиÑие Ð²Ð¾Ð·Ð½Ð¸ÐºÐ°ÐµÑ Ð¸Ð·-за Ñого, ÑÑо некоÑоÑÑе ÑÑÑоки могÑÑ Ð±ÑÑÑ Ð¾ÑбÑоÑÐµÐ½Ñ Ð»Ð¾ÐºÐ°Ð»Ñно пÑовеÑÑемÑми ÑÑловиÑми огÑаниÑений или Ñоединений.) РаннÑÑ Ð±Ð»Ð¾ÐºÐ¸Ñовка гоÑаздо пÑоÑе и не ÑÑебÑÐµÑ Ð´Ð¾Ð¿Ð¾Ð»Ð½Ð¸ÑелÑнÑÑ Ð¾Ð±ÑаÑений к ÑдалÑÐ½Ð½Ð¾Ð¼Ñ Ñ ÑанилиÑÑ, но Ð¼Ð¾Ð¶ÐµÑ Ð²ÑзÑваÑÑ Ð±Ð»Ð¾ÐºÐ¸ÑÐ¾Ð²ÐºÑ ÑÑÑок, коÑоÑÑе можно бÑло Ð±Ñ Ð½Ðµ блокиÑоваÑÑ, ÑÑо Ð¼Ð¾Ð¶ÐµÑ Ð¿Ð¾Ð²Ð»ÐµÑÑ ÑÑаÑение конÑликÑов и даже неожиданнÑе взаимоблокиÑовки. ÐÑоме Ñого, позднÑÑ Ð±Ð»Ð¾ÐºÐ¸Ñовка возможна, ÑолÑко еÑли блокиÑÑÐµÐ¼Ð°Ñ ÑÑÑока Ð¼Ð¾Ð¶ÐµÑ Ð±ÑÑÑ Ð¾Ð´Ð½Ð¾Ð·Ð½Ð°Ñно иденÑиÑиÑиÑована позже. ÐоÑÑÐ¾Ð¼Ñ Ð² иденÑиÑикаÑоÑе ÑÑÑоки ÑледÑÐµÑ Ð¸Ð´ÐµÐ½ÑиÑиÑиÑоваÑÑ Ð¾Ð¿ÑеделÑннÑÑ Ð²ÐµÑÑÐ¸Ñ ÑÑÑоки, как ÑÑо Ð´ÐµÐ»Ð°ÐµÑ TID в Postgres Pro.
Ðо ÑмолÑÐ°Ð½Ð¸Ñ Postgres Pro игноÑиÑÑÐµÑ Ð²Ð¾Ð·Ð¼Ð¾Ð¶Ð½Ð¾ÑÑи блокиÑовки, обÑаÑаÑÑÑ Ðº FDW, но FDW Ð¼Ð¾Ð¶ÐµÑ ÑÑÑановиÑÑ Ñанние блокиÑовки и без Ñвной поддеÑжки Ñо ÑÑоÑÐ¾Ð½Ñ ÑдÑа. ФÑнкÑии, опиÑаннÑе в ÐодÑазделе 54.2.6, коÑоÑÑе бÑли Ð´Ð¾Ð±Ð°Ð²Ð»ÐµÐ½Ñ Ð² API в Postgres Pro 9.5, позволÑÑÑ FDW пÑименÑÑÑ Ð¿Ð¾Ð·Ð´Ð½Ð¸Ðµ блокиÑовки, еÑли она ÑÑого пожелаеÑ.
Также ÑледÑÐµÑ ÑÑеÑÑÑ, ÑÑо в Ñежиме изолÑÑии READ COMMITTED ÑеÑвеÑÑ Postgres Pro Ð¼Ð¾Ð¶ÐµÑ Ð¿Ð¾ÑÑебоваÑÑÑÑ Ð¿ÐµÑепÑовеÑиÑÑ ÑÑÐ»Ð¾Ð²Ð¸Ñ Ð¾Ð³ÑаниÑений и ÑÐ¾ÐµÐ´Ð¸Ð½ÐµÐ½Ð¸Ñ Ñ Ð¸Ð·Ð¼ÐµÐ½Ñнной веÑÑией некоÑоÑого Ñелевого коÑÑежа. ÐÐ»Ñ Ð¿ÐµÑепÑовеÑки ÑÑловий ÑÐ¾ÐµÐ´Ð¸Ð½ÐµÐ½Ð¸Ñ ÑÑебÑеÑÑÑ Ð¿Ð¾Ð²ÑоÑно полÑÑиÑÑ ÐºÐ¾Ð¿Ð¸Ð¸ иÑÑ
однÑÑ
ÑÑÑок, коÑоÑÑе Ñанее бÑли ÑÐ¾ÐµÐ´Ð¸Ð½ÐµÐ½Ñ Ð² Ñелевой коÑÑеж. Ð ÑлÑÑае Ñо ÑÑандаÑÑнÑми ÑаблиÑами Postgres Pro Ð´Ð»Ñ ÑÑого в ÑпиÑок ÑÑолбÑов, пÑоÑ
одÑÑиÑ
ÑеÑез Ñоединение, вклÑÑаÑÑÑÑ TID из иÑÑ
однÑÑ
ÑаблиÑ, а заÑем иÑÑ
однÑе ÑÑÑоки извлекаÑÑÑÑ Ð·Ð°Ð½Ð¾Ð²Ð¾ пÑи необÑ
одимоÑÑи. ÐÑи Ñаком подÑ
оде Ð½Ð°Ð±Ð¾Ñ Ð´Ð°Ð½Ð½ÑÑ
ÑÐ¾ÐµÐ´Ð¸Ð½ÐµÐ½Ð¸Ñ Ð¾ÑÑаÑÑÑÑ ÐºÐ¾Ð¼Ð¿Ð°ÐºÑнÑм, но ÑÑебÑеÑÑÑ Ð½ÐµÐ´Ð¾ÑÐ¾Ð³Ð°Ñ Ð¾Ð¿ÐµÑаÑÐ¸Ñ Ð¿Ð¾Ð²ÑоÑного ÑÑÐµÐ½Ð¸Ñ ÑÑÑок, а Ñакже возможноÑÑÑ Ð¾Ð´Ð½Ð¾Ð·Ð½Ð°Ñно иденÑиÑиÑиÑоваÑÑ Ð¿Ð¾Ð²ÑоÑно ÑÑиÑÑваемÑÑ Ð²ÐµÑÑÐ¸Ñ ÑÑÑоки по TID. ÐоÑÑÐ¾Ð¼Ñ Ð¿Ð¾ ÑмолÑÐ°Ð½Ð¸Ñ Ð¿Ñи ÑабоÑе Ñо ÑÑоÑонними ÑаблиÑами в ÑпиÑок ÑÑолбÑов, пÑоÑ
одÑÑиÑ
ÑеÑез Ñоединение, вклÑÑаеÑÑÑ ÐºÐ¾Ð¿Ð¸Ñ Ð²Ñей ÑÑÑоки, извлекаемой из ÑÑоÑонней ÑаблиÑÑ. ÐÑо не накладÑÐ²Ð°ÐµÑ ÑпеÑиалÑнÑÑ
ÑÑебований на FDW, но Ð¼Ð¾Ð¶ÐµÑ Ð¿ÑивеÑÑи к ÑÐ½Ð¸Ð¶ÐµÐ½Ð¸Ñ Ð¿ÑоизводиÑелÑноÑÑи пÑи Ñоединении ÑлиÑнием или по Ñ
еÑÑ. FDW, коÑоÑÐ°Ñ Ð¼Ð¾Ð¶ÐµÑ ÑдовлеÑвоÑиÑÑ ÑÑебованиÑм повÑоÑного ÑÑениÑ, Ð¼Ð¾Ð¶ÐµÑ ÑеализоваÑÑ Ð¿ÐµÑвÑй ваÑианÑ.
ÐÐ»Ñ ÐºÐ¾Ð¼Ð°Ð½Ð´ UPDATE или DELETE Ñо ÑÑоÑонней ÑаблиÑей ÑекомендÑеÑÑÑ, ÑÑÐ¾Ð±Ñ Ð¾Ð¿ÐµÑаÑÐ¸Ñ ForeignScan в Ñелевой ÑаблиÑе вÑполнÑла ÑаннÑÑ Ð±Ð»Ð¾ÐºÐ¸ÑÐ¾Ð²ÐºÑ ÑÑÑок, коÑоÑÑе она вÑбиÑаеÑ, возможно, иÑполÑзÑÑ Ð°Ð½Ð°Ð»Ð¾Ð³ SELECT FOR UPDATE. FDW Ð¼Ð¾Ð¶ÐµÑ Ð¾Ð¿ÑеделиÑÑ, ÑвлÑеÑÑÑ Ð»Ð¸ ÑаблиÑа Ñелевой ÑаблиÑей команд UPDATE/DELETE, во вÑÐµÐ¼Ñ Ð¿Ð»Ð°Ð½Ð¸ÑованиÑ, ÑÑавнив ÐµÑ relid Ñ root->parse->resultRelation, или во вÑÐµÐ¼Ñ Ð¿Ð»Ð°Ð½Ð¸ÑованиÑ, вÑзвав ExecRelationIsTargetRelation(). Также возможно вÑполнÑÑÑ Ð¿Ð¾Ð·Ð´Ð½ÑÑ Ð±Ð»Ð¾ÐºÐ¸ÑÐ¾Ð²ÐºÑ Ð² обÑабоÑÑике ExecForeignUpdate или ExecForeignDelete, но ÑпеÑиалÑной поддеÑжки Ð´Ð»Ñ ÑÑого неÑ.
ÐÐ»Ñ ÑÑоÑонниÑ
ÑаблиÑ, блокиÑовка коÑоÑÑÑ
запÑаÑиваеÑÑÑ ÐºÐ¾Ð¼Ð°Ð½Ð´Ð¾Ð¹ SELECT FOR UPDATE/SHARE, опеÑаÑÐ¸Ñ ForeignScan Ñак же Ð¼Ð¾Ð¶ÐµÑ Ð¿ÑоизвеÑÑи ÑаннÑÑ Ð±Ð»Ð¾ÐºÐ¸ÑовкÑ, вÑбÑав коÑÑежи, иÑполÑзÑÑ Ð°Ð½Ð°Ð»Ð¾Ð³ SELECT FOR UPDATE/SHARE. ЧÑÐ¾Ð±Ñ Ð²Ð¼ÐµÑÑо ÑÑого пÑоизвеÑÑи позднÑÑ Ð±Ð»Ð¾ÐºÐ¸ÑовкÑ, пÑедоÑÑавÑÑе подпÑогÑаммÑ-обÑабоÑÑики, опиÑаннÑе в ÐодÑазделе 54.2.6. Ð GetForeignRowMarkType вÑбеÑиÑе ваÑÐ¸Ð°Ð½Ñ Ð¾ÑмеÑки ÑÑÑок ROW_MARK_EXCLUSIVE, ROW_MARK_NOKEYEXCLUSIVE, ROW_MARK_SHARE или ROW_MARK_KEYSHARE, в завиÑимоÑÑи Ð¾Ñ Ð·Ð°Ð¿ÑоÑенной ÑÐ¸Ð»Ñ Ð±Ð»Ð¾ÐºÐ¸Ñовки. (Ðод ÑдÑа бÑÐ´ÐµÑ ÑабоÑаÑÑ Ð¾Ð´Ð¸Ð½Ð°ÐºÐ¾Ð²Ð¾ пÑи лÑбом из ÑÑиÑ
ÑеÑÑÑÑÑ
ваÑианÑов.) ÐаÑем Ð²Ñ ÑможеÑе опÑеделиÑÑ, должна ли ÑÑоÑоннÑÑ ÑаблиÑа блокиÑоваÑÑÑÑ ÐºÐ¾Ð¼Ð°Ð½Ð´Ð¾Ð¹ ÑÑого Ñипа, вÑзвав ÑÑнкÑÐ¸Ñ get_plan_rowmark во вÑÐµÐ¼Ñ Ð¿Ð»Ð°Ð½Ð¸ÑÐ¾Ð²Ð°Ð½Ð¸Ñ Ð»Ð¸Ð±Ð¾ ExecFindRowMark во вÑÐµÐ¼Ñ Ð²ÑполнениÑ; нÑжно пÑовеÑиÑÑ Ð½Ðµ ÑолÑко, ÑÑо возвÑаÑÑÐ½Ð½Ð°Ñ ÑÑÑÑкÑÑÑа rowmark оÑлиÑна Ð¾Ñ NULL, но и ÑÑо ÐµÑ Ð¿Ð¾Ð»Ðµ strength не Ñавно LCS_NONE.
ÐаконеÑ, Ð´Ð»Ñ ÑÑоÑонниÑ
ÑаблиÑ, задейÑÑвованнÑÑ
в командаÑ
UPDATE, DELETE или SELECT FOR UPDATE/SHARE, но не ÑÑебÑÑÑиÑ
блокиÑовки ÑÑÑок, можно пеÑеопÑеделиÑÑ Ð¿Ð¾Ð²ÐµÐ´ÐµÐ½Ð¸Ðµ по ÑмолÑаниÑ, заклÑÑаÑÑееÑÑ Ð² копиÑовании ÑÑÑок Ñеликом, вÑбÑав в GetForeignRowMarkType ваÑÐ¸Ð°Ð½Ñ ROW_MARK_REFERENCE, полÑÑив знаÑение ÑÐ¸Ð»Ñ Ð±Ð»Ð¾ÐºÐ¸Ñовки LCS_NONE. Ð ÑезÑлÑÑаÑе RefetchForeignRow бÑÐ´ÐµÑ Ð²ÑзÑваÑÑÑÑ Ñ Ñаким знаÑением markType; она должна бÑÐ´ÐµÑ Ð·Ð°Ð½Ð¾Ð²Ð¾ ÑÑиÑÑваÑÑ ÑÑÑокÑ, не запÑаÑÐ¸Ð²Ð°Ñ Ð½Ð¾Ð²ÑÑ Ð±Ð»Ð¾ÐºÐ¸ÑовкÑ. (ÐÑли Ð²Ñ ÑеализÑеÑе ÑÑнкÑÐ¸Ñ GetForeignRowMarkType, но не Ñ
оÑиÑе повÑоÑно ÑÑиÑÑваÑÑ Ð½ÐµÐ·Ð°Ð±Ð»Ð¾ÐºÐ¸ÑованнÑе ÑÑÑоки, вÑбеÑиÑе Ð´Ð»Ñ LCS_NONE ваÑÐ¸Ð°Ð½Ñ ROW_MARK_COPY.)