Ðлава 62. УниÑиÑиÑованнÑе запиÑи WAL
ХоÑÑ Ñ Ð²ÑÐµÑ Ð²Ð½ÑÑÑÐµÐ½Ð½Ð¸Ñ Ð¼Ð¾Ð´Ñлей, взаимодейÑÑвÑÑÑÐ¸Ñ Ñ WAL, имеÑÑÑÑ ÑобÑÑвеннÑе ÑÐ¸Ð¿Ñ Ð·Ð°Ð¿Ð¸Ñей WAL, ÑÑÑеÑÑвÑÐµÑ Ñакже ÑниÑиÑиÑованнÑй Ñип запиÑей WAL, опиÑÑваÑÑий Ð¸Ð·Ð¼ÐµÐ½ÐµÐ½Ð¸Ñ Ð² ÑÑÑаниÑÐ°Ñ ÑниÑиÑиÑованнÑм обÑазом. ÐÑо полезно Ð´Ð»Ñ ÑаÑÑиÑений, ÑеализÑÑÑÐ¸Ñ ÑобÑÑвеннÑе меÑÐ¾Ð´Ñ Ð´Ð¾ÑÑÑпа.
Ðо ÑÑÐ°Ð²Ð½ÐµÐ½Ð¸Ñ Ñ ÐолÑзоваÑелÑÑкими менеджеÑами ÑеÑÑÑÑов WAL ÑниÑиÑиÑованнÑе запиÑи WAL пÑоÑе ÑеализоваÑÑ Ð² ÑаÑÑиÑениÑÑ , к ÑÐ¾Ð¼Ñ Ð¶Ðµ Ð´Ð»Ñ Ð¿ÑÐ¸Ð¼ÐµÐ½ÐµÐ½Ð¸Ñ ÑÑÐ¸Ñ Ð·Ð°Ð¿Ð¸Ñей не ÑÑебÑеÑÑÑ Ð·Ð°Ð³ÑÑжаÑÑ Ð±Ð¸Ð±Ð»Ð¸Ð¾ÑÐµÐºÑ ÑаÑÑиÑениÑ.
ÐÑимеÑание
УниÑиÑиÑованнÑе запиÑи WAL игноÑиÑÑÑÑÑÑ Ð²Ð¾ вÑÐµÐ¼Ñ Ð»Ð¾Ð³Ð¸ÑеÑкого декодиÑованиÑ. ÐÑли Ð´Ð»Ñ Ð²Ð°Ñего ÑаÑÑиÑÐµÐ½Ð¸Ñ ÑÑебÑеÑÑÑ Ð»Ð¾Ð³Ð¸ÑеÑкое декодиÑование, ÑаÑÑмоÑÑиÑе возможноÑÑÑ Ð¸ÑполÑÐ·Ð¾Ð²Ð°Ð½Ð¸Ñ Ð¿Ð¾Ð»ÑзоваÑелÑÑкого менеджеÑа ÑеÑÑÑÑов WAL.
API Ð´Ð»Ñ ÐºÐ¾Ð½ÑÑÑÑиÑÐ¾Ð²Ð°Ð½Ð¸Ñ ÑниÑиÑиÑованнÑÑ
запиÑей WAL опÑеделÑн в access/generic_xlog.h и Ñеализован в access/transam/generic_xlog.c.
ЧÑÐ¾Ð±Ñ ÑÑоÑмиÑоваÑÑ Ð·Ð°Ð¿Ð¸ÑÑ Ð¸Ð·Ð¼ÐµÐ½ÐµÐ½Ð¸Ñ Ð´Ð°Ð½Ð½ÑÑ Ð´Ð»Ñ WAL, пÑименÑÑ Ð¼ÐµÑ Ð°Ð½Ð¸Ð·Ð¼ ÑниÑиÑиÑованнÑÑ Ð·Ð°Ð¿Ð¸Ñей WAL, вÑполниÑе ÑледÑÑÑие дейÑÑвиÑ:
state = GenericXLogStart(relation)â наÑниÑе ÑоÑмиÑование ÑниÑиÑиÑованной запиÑи WAL Ð´Ð»Ñ Ð·Ð°Ð´Ð°Ð½Ð½Ð¾Ð³Ð¾ оÑноÑениÑ.page = GenericXLogRegisterBuffer(state, buffer, flags)â заÑегиÑÑÑиÑÑйÑе бÑÑеÑ, коÑоÑÑй бÑÐ´ÐµÑ Ð¸Ð·Ð¼ÐµÐ½Ñн ÑекÑÑей ÑниÑиÑиÑованной запиÑÑÑ WAL. ÐÑа ÑÑнкÑÐ¸Ñ Ð²Ð¾Ð·Ð²ÑаÑÐ°ÐµÑ ÑказаÑÐµÐ»Ñ Ð½Ð° вÑеменнÑÑ ÐºÐ¾Ð¿Ð¸Ñ ÑÑÑаниÑÑ Ð±ÑÑеÑа, в коÑоÑой Ð´Ð¾Ð»Ð¶Ð½Ñ Ð¿ÑоизводиÑÑÑÑ Ð¸Ð·Ð¼ÐµÐ½ÐµÐ½Ð¸Ñ. (ÐодиÑиÑиÑоваÑÑ Ð½ÐµÐ¿Ð¾ÑÑедÑÑвенно ÑодеÑжимое бÑÑеÑа нелÑзÑ.) Ð ÑÑеÑÑем аÑгÑменÑе пеÑедаÑÑÑÑ Ð±Ð¸ÑÐ¾Ð²Ð°Ñ Ð¼Ð°Ñка Ñлагов, пÑименимÑÑ Ðº ÑÑой опеÑаÑии. РнаÑÑоÑÑее вÑÐµÐ¼Ñ Ñлаг ÑолÑко один âGENERIC_XLOG_FULL_IMAGE, коÑоÑÑй показÑваеÑ, ÑÑо в запиÑÑ WAL нÑжно вклÑÑиÑÑ Ð¾Ð±Ñаз вÑей ÑÑÑаниÑÑ, а не ÑолÑко изменениÑ. ÐбÑÑно ÑÑÐ¾Ñ Ñлаг должен ÑÑÑанавливаÑÑÑÑ, когда ÑÑÑаниÑа Ð½Ð¾Ð²Ð°Ñ Ð¸Ð»Ð¸ полноÑÑÑÑ Ð¿ÐµÑезапиÑана. ÐÑзовGenericXLogRegisterBufferможно повÑоÑÑÑÑ, еÑли ÑикÑиÑÑемое в WAL дейÑÑвие изменÑÐµÑ Ð½ÐµÑколÑко ÑÑÑаниÑ.ÐÑимениÑе Ð¸Ð·Ð¼ÐµÐ½ÐµÐ½Ð¸Ñ Ðº обÑазам ÑÑÑаниÑ, полÑÑеннÑм на пÑедÑдÑÑем Ñаге.
GenericXLogFinish(state)â завеÑÑиÑе Ð¸Ð·Ð¼ÐµÐ½ÐµÐ½Ð¸Ñ Ð² бÑÑеÑÐ°Ñ Ð¸ вÑдайÑе ÑниÑиÑиÑованнÑÑ Ð·Ð°Ð¿Ð¸ÑÑ WAL.
ФоÑмиÑование запиÑи WAL можно пÑеÑваÑÑ Ð½Ð° лÑбом Ñаге, вÑзвав GenericXLogAbort(state). ÐÑи ÑÑом бÑдÑÑ Ð¾ÑÐ¼ÐµÐ½ÐµÐ½Ñ Ð²Ñе изменениÑ, внеÑÑннÑе в копии обÑазов ÑÑÑаниÑ.
ÐÑполÑзÑÑ Ð¼ÐµÑ Ð°Ð½Ð¸Ð·Ð¼ ÑниÑиÑиÑованнÑÑ Ð·Ð°Ð¿Ð¸Ñей WAL, Ð½ÐµÐ¾Ð±Ñ Ð¾Ð´Ð¸Ð¼Ð¾ ÑÑиÑÑваÑÑ ÑледÑÑÑее:
ÐодиÑиÑиÑоваÑÑ Ð±ÑÑеÑÑ Ð½Ð°Ð¿ÑÑмÑÑ Ð½ÐµÐ»ÑзÑ! ÐÑе Ð¸Ð·Ð¼ÐµÐ½ÐµÐ½Ð¸Ñ Ð´Ð¾Ð»Ð¶Ð½Ñ Ð¿ÑоизводиÑÑÑÑ Ð² копиÑÑ , полÑÑеннÑÑ Ð¾Ñ ÑÑнкÑии
GenericXLogRegisterBuffer(). ÐÑÑгими Ñловами, код, ÑоÑмиÑÑÑÑий ÑниÑиÑиÑованнÑе запиÑи WAL, никогда не должен Ñам вÑзÑваÑÑBufferGetPage(). Ðднако вÑзÑваÑÑий код оÑвеÑÐ°ÐµÑ Ð·Ð° закÑепление/оÑкÑепление и блокиÑовкÑ/ÑазблокиÑÐ¾Ð²ÐºÑ Ð±ÑÑеÑов в Ð¿Ð¾Ð´Ñ Ð¾Ð´ÑÑие моменÑÑ Ð²Ñемени. ÐÑклÑÑиÑелÑÐ½Ð°Ñ Ð±Ð»Ð¾ÐºÐ¸Ñовка каждого Ñелевого бÑÑеÑа должна ÑдеÑживаÑÑÑÑ Ð¾Ñ Ð²ÑзоваGenericXLogRegisterBuffer()доGenericXLogFinish().РегиÑÑÑаÑÐ¸Ñ Ð±ÑÑеÑов (Ñаг 2) и модиÑикаÑÐ¸Ñ Ð¾Ð±Ñазов ÑÑÑÐ°Ð½Ð¸Ñ (Ñаг 3) можно Ñвободно ÑмеÑиваÑÑ, оба ÑÑÐ¸Ñ Ñага можно повÑоÑÑÑÑ Ð² лÑбой поÑледоваÑелÑноÑÑи. Ðо помниÑе, ÑÑо бÑÑеÑÑ Ð´Ð¾Ð»Ð¶Ð½Ñ ÑегиÑÑÑиÑоваÑÑÑÑ Ð² Ñом же поÑÑдке, в каком Ð´Ð»Ñ Ð½Ð¸Ñ Ð´Ð¾Ð»Ð¶Ð½Ñ Ð¿Ð¾Ð»ÑÑаÑÑÑÑ Ð±Ð»Ð¾ÐºÐ¸Ñовки пÑи воÑпÑоизведении.
ÐакÑималÑное ÑиÑло бÑÑеÑов, коÑоÑÑе можно заÑегиÑÑÑиÑоваÑÑ Ð´Ð»Ñ ÑниÑиÑиÑованной запиÑи WAL, ÑоÑÑавлÑеÑ
MAX_GENERIC_XLOG_PAGES. ÐÑи иÑÑеÑпании ÑÑого лимиÑа бÑÐ´ÐµÑ Ð²Ñдана оÑибка.УниÑиÑиÑованнÑй Ñип WAL подÑазÑмеваеÑ, ÑÑо ÑÑÑаниÑÑ, подлежаÑие изменениÑ, имеÑÑ ÑÑандаÑÑнÑÑ ÑÑÑÑкÑÑÑÑ, в ÑаÑÑноÑÑи междÑ
pd_lowerиpd_upperÐ½ÐµÑ Ð¿Ð¾Ð»ÐµÐ·Ð½ÑÑ Ð´Ð°Ð½Ð½ÑÑ .Так как изменÑÑÑÑÑ ÐºÐ¾Ð¿Ð¸Ð¸ ÑÑÑÐ°Ð½Ð¸Ñ Ð±ÑÑеÑа,
GenericXLogStart()не наÑÐ¸Ð½Ð°ÐµÑ ÐºÑиÑиÑеÑкÑÑ ÑекÑиÑ. Таким обÑазом Ð²Ñ Ð¼Ð¾Ð¶ÐµÑе безопаÑно вÑделÑÑÑ Ð¿Ð°Ð¼ÑÑÑ, вÑдаÑÑ Ð¾ÑÐ¸Ð±ÐºÑ Ð¸ Ñ. п. междÑGenericXLogStart()иGenericXLogFinish(). ÐдинÑÑÐ²ÐµÐ½Ð½Ð°Ñ ÑакÑиÑеÑÐºÐ°Ñ ÐºÑиÑиÑеÑÐºÐ°Ñ ÑекÑÐ¸Ñ Ð¿ÑиÑÑÑÑÑвÑÐµÑ Ð²Ð½ÑÑÑиGenericXLogFinish(). ÐÑи вÑÑ Ð¾Ð´Ðµ по оÑибке Ñак же не нÑжно забоÑиÑÑÑÑ Ð¾ вÑзовеGenericXLogAbort().GenericXLogFinish()помеÑÐ°ÐµÑ Ð±ÑÑеÑÑ ÐºÐ°Ðº гÑÑзнÑе и ÑÑÑÐ°Ð½Ð°Ð²Ð»Ð¸Ð²Ð°ÐµÑ Ð´Ð»Ñ Ð½Ð¸Ñ LSN. Ðам делаÑÑ Ñвно ÑÑо не нÑжно.ÐÐ»Ñ Ð½ÐµÐ¶ÑÑналиÑÑемÑÑ Ð¾ÑноÑений вÑÑ ÑабоÑÐ°ÐµÑ Ñак же, за иÑклÑÑением Ñого, ÑÑо ÑакÑиÑеÑки запиÑÑ Ð² WAL не вÑдаÑÑÑÑ. Таким обÑазом, Ñвно пÑовеÑÑÑÑ, ÑвлÑеÑÑÑ Ð»Ð¸ оÑноÑение нежÑÑналиÑÑемÑм, не ÑÑебÑеÑÑÑ.
ФÑнкÑÐ¸Ñ Ð²Ð¾ÑпÑÐ¾Ð¸Ð·Ð²ÐµÐ´ÐµÐ½Ð¸Ñ ÑниÑиÑиÑованнÑÑ Ð¸Ð·Ð¼ÐµÐ½ÐµÐ½Ð¸Ð¹ WAL полÑÑÐ¸Ñ Ð¸ÑклÑÑиÑелÑнÑе блокиÑовки бÑÑеÑов в Ñом же поÑÑдке, в каком они бÑли заÑегиÑÑÑиÑованÑ. ÐоÑле воÑпÑÐ¾Ð¸Ð·Ð²ÐµÐ´ÐµÐ½Ð¸Ñ Ð²ÑÐµÑ Ð¸Ð·Ð¼ÐµÐ½ÐµÐ½Ð¸Ð¹ блокиÑовки в Ñом же поÑÑдке и оÑвобождаÑÑÑÑ.
ÐÑли Ð´Ð»Ñ ÑегиÑÑÑиÑÑемого бÑÑеÑа не задаÑÑÑÑ
GENERIC_XLOG_FULL_IMAGE, ÑниÑиÑиÑÐ¾Ð²Ð°Ð½Ð½Ð°Ñ Ð·Ð°Ð¿Ð¸ÑÑ WAL ÑодеÑÐ¶Ð¸Ñ ÑазлиÑие Ð¼ÐµÐ¶Ð´Ñ ÑÑаÑÑм и новÑм обÑазом ÑÑÑаниÑÑ, коÑоÑое вÑÑиÑлÑеÑÑÑ Ð¿Ñи побайÑовом ÑÑавнении. РезÑлÑÑÐ°Ñ Ð¾ÐºÐ°Ð·ÑваеÑÑÑ Ð½Ðµ оÑÐµÐ½Ñ ÐºÐ¾Ð¼Ð¿Ð°ÐºÑнÑм пÑи пеÑемеÑении даннÑÑ Ð² ÑÑÑаниÑе, но ÑÑо Ð¼Ð¾Ð¶ÐµÑ Ð±ÑÑÑ Ð´Ð¾ÑабоÑано в бÑдÑÑем.