61.4. ÐамеÑÐ°Ð½Ð¸Ñ Ð¾ блокиÑовке Ñ Ð¸Ð½Ð´ÐµÐºÑами #
ÐндекÑнÑе меÑÐ¾Ð´Ñ Ð´Ð¾ÑÑÑпа Ð´Ð¾Ð»Ð¶Ð½Ñ ÑпÑавлÑÑÑÑÑ Ñ Ð¿Ð°ÑаллелÑнÑми опеÑаÑиÑми Ð¾Ð±Ð½Ð¾Ð²Ð»ÐµÐ½Ð¸Ñ Ð¸Ð½Ð´ÐµÐºÑа, пÑоизводимÑми неÑколÑкими пÑоÑеÑÑами. ЯдÑо ÑиÑÑÐµÐ¼Ñ Postgres Pro полÑÑÐ°ÐµÑ Ð±Ð»Ð¾ÐºÐ¸ÑÐ¾Ð²ÐºÑ AccessShareLock Ð´Ð»Ñ Ð¸Ð½Ð´ÐµÐºÑа в пÑоÑеÑÑе ÑканиÑÐ¾Ð²Ð°Ð½Ð¸Ñ Ð¸ RowExclusiveLock пÑи модиÑикаÑии индекÑа (вклÑÑÐ°Ñ Ð¸ обÑÑнÑÑ Ð¾ÑиÑÑÐºÑ ÐºÐ¾Ð¼Ð°Ð½Ð´Ð¾Ð¹ VACUUM). Так как ÑÑи ÑÐ¸Ð¿Ñ Ð±Ð»Ð¾ÐºÐ¸Ñовок не конÑликÑÑÑÑ, меÑод доÑÑÑпа должен Ñам ÑÑÑанавливаÑÑ Ð±Ð¾Ð»ÐµÐµ ÑоÑеÑнÑе блокиÑовки, коÑоÑÑе ÐµÐ¼Ñ Ð¼Ð¾Ð³ÑÑ Ð¿Ð¾ÑÑебоваÑÑÑÑ. ÐлокиÑовка индекÑа в Ñелом в Ñежиме ACCESS EXCLUSIVE ÑÑÑанавливаеÑÑÑ ÑолÑко пÑи Ñоздании и ÑниÑÑожении индекÑа или опеÑаÑии REINDEX (вмеÑÑо ÑÑого иÑполÑзÑеÑÑÑ SHARE UPDATE EXCLUSIVE вмеÑÑе Ñ CONCURRENTLY).
РеализаÑÐ¸Ñ Ñипа индекÑа, поддеÑживаÑÑего паÑаллелÑнÑе изменениÑ, обÑÑно ÑÑебÑÐµÑ Ð³Ð»Ñбокого и вÑеÑÑоÑоннего анализа ÑÑебÑемого поведениÑ.
Ðомимо ÑобÑÑвеннÑÑ Ð²Ð½ÑÑÑÐµÐ½Ð½Ð¸Ñ ÑÑебований индекÑов к ÑелоÑÑноÑÑи, пÑи паÑаллелÑном обновлении даннÑÑ Ð²Ð¾Ð·Ð½Ð¸ÐºÐ°ÑÑ Ð²Ð¾Ð¿ÑоÑÑ ÑоглаÑованноÑÑи ÑодиÑелÑÑкой ÑаблиÑÑ (оÑновнÑÑ Ð´Ð°Ð½Ð½ÑÑ ) и индекÑа. ÐÑледÑÑвие Ñого, ÑÑо Postgres Pro оÑделÑÐµÑ ÑÑение и изменение оÑновнÑÑ Ð´Ð°Ð½Ð½ÑÑ Ð¾Ñ ÑÑÐµÐ½Ð¸Ñ Ð¸ Ð¸Ð·Ð¼ÐµÐ½ÐµÐ½Ð¸Ñ Ð¸Ð½Ð´ÐµÐºÑа, обÑазÑÑÑÑÑ Ð²ÑеменнÑе инÑеÑвалÑ, в коÑоÑÑÑ Ð¸Ð½Ð´ÐµÐºÑ Ð¼Ð¾Ð¶ÐµÑ Ð±ÑÑÑ Ð½ÐµÑоглаÑованнÑм Ñ Ð´Ð°Ð½Ð½Ñми. ÐÑ ÑеÑаем ÑÑÑ Ð¿ÑоблемÑ, пÑименÑÑ ÑледÑÑÑие пÑавила:
ÐÐ¾Ð²Ð°Ñ Ð·Ð°Ð¿Ð¸ÑÑ Ð² облаÑÑи даннÑÑ Ð´Ð¾Ð±Ð°Ð²Ð»ÑеÑÑÑ Ð´Ð¾ Ñого, как Ð´Ð»Ñ Ð½ÐµÑ Ð±ÑдÑÑ ÑÐ¾Ð·Ð´Ð°Ð½Ñ Ð·Ð°Ð¿Ð¸Ñи в индекÑÐ°Ñ . (Таким обÑазом, пÑи паÑаллелÑном ÑканиÑовании индекÑа ÑÑа запиÑÑ Ð² даннÑÑ ÑкоÑее вÑего не бÑÐ´ÐµÑ Ð·Ð°Ð¼ÐµÑена. ÐÑо не пÑоблема, Ñак как ÑиÑаÑÐµÐ»Ñ Ð¸Ð½Ð´ÐµÐºÑа вÑÑ Ñавно не нÑÐ¶Ð½Ñ Ð½ÐµÐ·Ð°ÑикÑиÑованнÑе ÑÑÑоки. Ðо ÑÑÑиÑе напиÑанное в Разделе 61.5.)
Ðогда запиÑÑ Ð´Ð°Ð½Ð½ÑÑ ÑдалÑеÑÑÑ (командой
VACUUM), ÑнаÑала Ð´Ð¾Ð»Ð¶Ð½Ñ ÑдалиÑÑÑÑ Ð²Ñе ÑозданнÑе Ð´Ð»Ñ Ð½ÐµÑ Ð·Ð°Ð¿Ð¸Ñи в индекÑÐ°Ñ .СканиÑование индекÑа должно закÑепиÑÑ ÑÑÑаниÑÑ Ð¸Ð½Ð´ÐµÐºÑа, на коÑоÑой Ð½Ð°Ñ Ð¾Ð´Ð¸ÑÑÑ ÑлеменÑ, возвÑаÑÑннÑй поÑледним вÑзовом
amgettuple, аambulkdeleteне должна ÑдалÑÑÑ Ð·Ð°Ð¿Ð¸Ñи Ñо ÑÑÑаниÑ, закÑеплÑннÑÑ Ð´ÑÑгими пÑоÑеÑÑами. Чем обоÑновано ÑÑо пÑавило, опиÑÑваеÑÑÑ Ð½Ð¸Ð¶Ðµ.
Ðез ÑÑеÑÑего пÑавила ÑиÑаÑÐµÐ»Ñ Ð¸Ð½Ð´ÐµÐºÑа мог Ð±Ñ ÑвидеÑÑ Ð·Ð°Ð¿Ð¸ÑÑ Ð¸Ð½Ð´ÐµÐºÑа за мгновение до Ñого, как она бÑла Ñдалена пÑоÑедÑÑой VACUUM, а заÑем обÑаÑиÑÑÑÑ Ðº ÑооÑвеÑÑÑвÑÑÑей запиÑи даннÑÑ
поÑле Ñого, как VACUUM ÑÐ´Ð°Ð»Ð¸Ñ Ð¸ еÑ. ÐÑо не пÑиведÑÑ Ðº ÑеÑÑÑзнÑм пÑоблемам, еÑли даннÑй ÑÐ»ÐµÐ¼ÐµÐ½Ñ Ð¾ÑÑаÑÑÑÑ Ð½ÐµÐ·Ð°Ð´ÐµÐ¹ÑÑвованнÑм, когда к Ð½ÐµÐ¼Ñ Ð¾Ð±ÑаÑаеÑÑÑ ÑиÑаÑелÑ, Ñак как пÑÑÑой ÑÐ»Ð¾Ñ Ð±ÑÐ´ÐµÑ Ð¸Ð³Ð½Ð¾ÑиÑоваÑÑÑÑ ÑÑнкÑией heap_fetch(). Ðо как бÑÑÑ, еÑли ÑÑеÑий пÑоÑеÑÑ Ñже занÑл ÑÑÐ¾Ñ ÑÐ»Ð¾Ñ ÐºÐ°ÐºÐ¸Ð¼Ð¸-Ñо Ñвоими даннÑми? Ðогда пÑименÑеÑÑÑ Ñнимок, ÑовмеÑÑимÑй Ñ MVCC, и ÑÑо не пÑоблема, Ñак как ÑÑи даннÑе опÑеделÑнно окажÑÑÑÑ ÑлиÑком новÑми пÑи пÑовеÑке видимоÑÑи Ð´Ð»Ñ Ð´Ð°Ð½Ð½Ð¾Ð³Ð¾ Ñнимка. Ðднако Ð´Ð»Ñ Ñнимка неÑовмеÑÑимого Ñ MVCC (напÑимеÑ, Ñнимка SnapshotAny), Ð¼Ð¾Ð¶ÐµÑ Ñак полÑÑиÑÑÑÑ, ÑÑо бÑÐ´ÐµÑ Ð²Ð¾Ð·Ð²ÑаÑена ÑÑÑока, на Ñамом деле не ÑооÑвеÑÑÑвÑÑÑÐ°Ñ ÐºÐ»ÑÑам ÑканиÑованиÑ. ÐÑ Ð¼Ð¾Ð¶ÐµÐ¼ заÑиÑиÑÑÑÑ Ð¾Ñ Ñакого иÑÑ
ода, поÑÑебовав, ÑÑÐ¾Ð±Ñ ÐºÐ»ÑÑи ÑканиÑÐ¾Ð²Ð°Ð½Ð¸Ñ Ð²Ñегда пеÑепÑовеÑÑлиÑÑ Ð´Ð»Ñ ÑÑÑоки даннÑÑ
, но ÑÑо ÑлиÑком доÑогоÑÑоÑÑее ÑеÑение. ÐмеÑÑо ÑÑого, Ð¼Ñ Ð·Ð°ÐºÑеплÑем ÑÑÑаниÑÑ Ð¸Ð½Ð´ÐµÐºÑа как пÑомежÑÑоÑнÑй обÑекÑ, показÑваÑÑий, ÑÑо ÑиÑаÑÐµÐ»Ñ Ð¼Ð¾Ð¶ÐµÑ Ð²ÑÑ ÐµÑÑ Ð±ÑÑÑ Â«Ð² пÑÑи» Ð¾Ñ Ð·Ð°Ð¿Ð¸Ñи индекÑа к ÑооÑвеÑÑÑвÑÑÑей ÑÑÑоке даннÑÑ
. ÐлагодаÑÑ ÑомÑ, ÑÑо ambulkdelete блокиÑÑеÑÑÑ Ð¿Ñи обÑаÑении к ÑÑой закÑеплÑнной ÑÑÑаниÑе, пÑоÑедÑÑа VACUUM не ÑÐ¼Ð¾Ð¶ÐµÑ ÑдалиÑÑ ÑÑÑÐ¾ÐºÑ Ð´Ð°Ð½Ð½ÑÑ
, пока ÐµÑ Ð¸Ð·Ð²Ð»ÐµÑение не законÑÐ¸Ñ ÑиÑаÑелÑ. ÐÑо ÑеÑение оказÑваеÑÑÑ Ð¾ÑÐµÐ½Ñ Ð½ÐµÐ´Ð¾Ñогим по вÑемени вÑполнениÑ, а издеÑжки блокиÑÐ¾Ð²Ð°Ð½Ð¸Ñ Ð¿ÑивноÑÑÑÑÑ ÑолÑко в ÑедкиÑ
ÑлÑÑаÑÑ
, когда дейÑÑвиÑелÑно Ð²Ð¾Ð·Ð½Ð¸ÐºÐ°ÐµÑ ÐºÐ¾Ð½ÑликÑ.
Такое ÑеÑение ÑÑебÑеÑ, ÑÑÐ¾Ð±Ñ ÑканиÑÐ¾Ð²Ð°Ð½Ð¸Ñ Ð¸Ð½Ð´ÐµÐºÑов вÑполнÑлиÑÑ Â«ÑÐ¸Ð½Ñ Ñонно»: Ð¼Ñ Ð´Ð¾Ð»Ð¶Ð½Ñ Ð²ÑбиÑаÑÑ ÐºÐ°Ð¶Ð´Ñй ÑледÑÑÑий коÑÑеж даннÑÑ ÑÑÐ°Ð·Ñ Ð¿Ð¾Ñле Ñого полÑÑили ÑооÑвеÑÑÑвÑÑÑÑ Ð·Ð°Ð¿Ð¸ÑÑ Ð¸Ð½Ð´ÐµÐºÑа. ÐÑо оказÑваеÑÑÑ Ð½ÐµÐ²Ñгодно по ÑÑÐ´Ñ Ð¿ÑиÑин. «ÐÑÐ¸Ð½Ñ Ñонное» ÑканиÑование, пÑи коÑоÑом Ð¼Ñ ÑобиÑаем множеÑÑво TID из индекÑа, и обÑаÑаемÑÑ Ð·Ð° коÑÑежами даннÑÑ ÑолÑко поÑле ÑÑого, влеÑÑÑ Ð³Ð¾Ñаздо менÑÑе издеÑжек Ñ Ð±Ð»Ð¾ÐºÐ¸Ñовками и позволÑÐµÑ Ð¾Ð±ÑаÑаÑÑÑÑ Ðº даннÑм более ÑÑÑекÑивнÑм обÑазом. СоглаÑно пÑоведÑÐ½Ð½Ð¾Ð¼Ñ Ð²ÑÑе анализÑ, Ð¼Ñ Ð´Ð¾Ð»Ð¶Ð½Ñ Ð¸ÑполÑзоваÑÑ ÑÐ¸Ð½Ñ ÑоннÑй Ð¿Ð¾Ð´Ñ Ð¾Ð´ Ð´Ð»Ñ Ñнимков, неÑовмеÑÑимÑÑ Ñ MVCC, но Ð´Ð»Ñ Ð·Ð°Ð¿ÑоÑов Ñо Ñнимками MVCC бÑÐ´ÐµÑ ÑабоÑаÑÑ Ð¸ аÑÐ¸Ð½Ñ Ñонное ÑканиÑование.
ÐÑи ÑканиÑовании индекÑа Ñ amgetbitmap, меÑод доÑÑÑпа не закÑеплÑÐµÑ ÑÑÑаниÑÑ Ð¸Ð½Ð´ÐµÐºÑа ни Ð´Ð»Ñ ÐºÐ°ÐºÐ¸Ñ
из возвÑаÑаемÑÑ
коÑÑежей. ÐоÑÑÐ¾Ð¼Ñ Ñакое ÑканиÑование можно безопаÑно пÑименÑÑÑ ÑолÑко Ñо Ñнимками MVCC.
Ðогда Ñлаг ampredlocks не ÑÑÑановлен, лÑбое ÑканиÑование Ñ Ð´Ð°Ð½Ð½Ñм меÑодом доÑÑÑпа в ÑеÑиализÑемой ÑÑанзакÑии бÑÐ´ÐµÑ Ð¿Ð¾Ð»ÑÑаÑÑ Ð½ÐµÐ±Ð»Ð¾ÐºÐ¸ÑÑÑÑÑÑ Ð¿ÑедикаÑнÑÑ Ð±Ð»Ð¾ÐºÐ¸ÑÐ¾Ð²ÐºÑ Ð´Ð»Ñ Ð²Ñего индекÑа. ÐÑо бÑÐ´ÐµÑ Ð¿ÑиводиÑÑ Ðº конÑликÑÑ ÑÑениÑ-запиÑи пÑи добавлении лÑбого коÑÑежа в ÑÑÐ¾Ñ Ð¸Ð½Ð´ÐµÐºÑ Ð¿Ð°ÑаллелÑной ÑеÑиализÑемой ÑÑанзакÑией. ÐÑли ÑÑеди набоÑа паÑаллелÑнÑÑ
ÑеÑиализÑемÑÑ
ÑÑанзакÑий вÑÑвлÑÑÑÑÑ Ð¾Ð¿ÑеделÑннÑе ваÑианÑÑ ÐºÐ¾Ð½ÑликÑов ÑÑениÑ-запиÑи, одна из ÑÑиÑ
ÑÑанзакÑий Ð¼Ð¾Ð¶ÐµÑ Ð±ÑÑÑ Ð¾Ñменена Ð´Ð»Ñ ÑоÑ
ÑÐ°Ð½ÐµÐ½Ð¸Ñ ÑелоÑÑноÑÑи даннÑÑ
. Ðогда даннÑй Ñлаг ÑÑÑановлен, ÑÑо ознаÑаеÑ, ÑÑо меÑод доÑÑÑпа ÑеализÑÐµÑ Ð±Ð¾Ð»ÐµÐµ ÑоÑнÑÑ Ð¿ÑедикаÑнÑÑ Ð±Ð»Ð¾ÐºÐ¸ÑовкÑ, ÑÑо ÑпоÑобÑÑвÑÐµÑ ÑокÑаÑÐµÐ½Ð¸Ñ ÑаÑÑоÑÑ Ð¾ÑÐ¼ÐµÐ½Ñ ÑÑанзакÑий по ÑÑой пÑиÑине.