PostgreSQL యొక్క అంతర్గత మెకానిజమ్స్ యొక్క ప్రత్యేకతలు కొన్ని పరిస్థితులలో చాలా వేగంగా మరియు ఇతరులలో "చాలా వేగంగా కాదు" అని అనుమతిస్తాయి. ఈ రోజు మనం DBMS ఎలా పని చేస్తుంది మరియు డెవలపర్ దానితో ఏమి చేస్తుంది అనే దాని మధ్య వైరుధ్యానికి సంబంధించిన ఒక క్లాసిక్ ఉదాహరణపై దృష్టి పెడతాము - నవీకరణ vs MVCC సూత్రాలు.
నుండి సంక్షిప్త కథ
UPDATE కమాండ్ ద్వారా అడ్డు వరుస సవరించబడినప్పుడు, వాస్తవానికి రెండు కార్యకలాపాలు నిర్వహించబడతాయి: DELETE మరియు INSERT. IN స్ట్రింగ్ యొక్క ప్రస్తుత వెర్షన్ xmax అనేది UPDATE చేసిన లావాదేవీల సంఖ్యకు సమానంగా సెట్ చేయబడింది. అప్పుడు అది సృష్టించబడుతుంది కొత్త వెర్సియ అదే లైన్; దాని xmin విలువ మునుపటి సంస్కరణ యొక్క xmax విలువతో సమానంగా ఉంటుంది.
ఈ లావాదేవీ పూర్తయిన కొంత సమయం తర్వాత, పాత లేదా కొత్త వెర్షన్, ఆధారపడి ఉంటుంది COMMIT/ROOLBACK
, గుర్తింపు ఉంటుంది "చనిపోయిన" (చనిపోయిన టుపుల్స్) ప్రయాణిస్తున్నప్పుడు VACUUM
పట్టిక ప్రకారం మరియు క్లియర్ చేయబడింది.
కానీ ఇది వెంటనే జరగదు, కానీ "చనిపోయిన" సమస్యలను చాలా త్వరగా పొందవచ్చు - పునరావృతం లేదా
#1: నేను దానిని తరలించడానికి ఇష్టపడతాను
మీ పద్ధతి వ్యాపార తర్కంపై పని చేస్తోందని అనుకుందాం మరియు ఏదో ఒక రికార్డ్లో X ఫీల్డ్ను అప్డేట్ చేయడం అవసరం అని అకస్మాత్తుగా అది గ్రహించింది:
UPDATE tbl SET X = <newX> WHERE pk = $1;
అప్పుడు, అమలు జరుగుతున్నప్పుడు, Y ఫీల్డ్ కూడా నవీకరించబడాలి:
UPDATE tbl SET Y = <newY> WHERE pk = $1;
... ఆపై కూడా Z - ఎందుకు ట్రిఫ్లెస్ సమయం వృధా?
UPDATE tbl SET Z = <newZ> WHERE pk = $1;
డేటాబేస్లో ఇప్పుడు ఈ రికార్డ్ యొక్క ఎన్ని వెర్షన్లు ఉన్నాయి? అవును, 4 ముక్కలు! వీటిలో, ఒకటి సంబంధితమైనది మరియు 3 మీ తర్వాత [ఆటో]VACUUM ద్వారా శుభ్రపరచబడాలి.
ఈ విధంగా చేయవద్దు! వా డు ఒక అభ్యర్థనలో అన్ని ఫీల్డ్లను నవీకరిస్తోంది — దాదాపు ఎల్లప్పుడూ పద్ధతి యొక్క తర్కాన్ని ఇలా మార్చవచ్చు:
UPDATE tbl SET X = <newX>, Y = <newY>, Z = <newZ> WHERE pk = $1;
#2: ఉపయోగం వేరు, ల్యూక్!
కాబట్టి, మీరు ఇంకా కోరుకున్నారు
UPDATE tbl SET X = <newX> WHERE pk BETWEEN $1 AND $2;
దాదాపుగా ఈ ఫారమ్లోని అభ్యర్థన చాలా తరచుగా జరుగుతుంది మరియు దాదాపు ఎల్లప్పుడూ ఖాళీ కొత్త ఫీల్డ్ని పూరించడానికి కాదు, కానీ డేటాలోని కొన్ని లోపాలను సరిచేయడానికి. అదే సమయంలో, ఆమె స్వయంగా ఇప్పటికే ఉన్న డేటా యొక్క ఖచ్చితత్వం పరిగణనలోకి తీసుకోబడదు - కానీ ఫలించలేదు! అంటే, రికార్డు తిరగరాస్తుంది, అందులో సరిగ్గా కోరుకున్నది ఉన్నప్పటికీ - ఎందుకు? దాన్ని సరిచేద్దాం:
UPDATE tbl SET X = <newX> WHERE pk BETWEEN $1 AND $2 AND X IS DISTINCT FROM <newX>;
అటువంటి అద్భుతమైన ఆపరేటర్ ఉనికి గురించి చాలా మందికి తెలియదు, కాబట్టి ఇక్కడ ఒక చీట్ షీట్ ఉంది IS DISTINCT FROM
మరియు సహాయం చేయడానికి ఇతర లాజికల్ ఆపరేటర్లు:
... మరియు కాంప్లెక్స్పై కార్యకలాపాల గురించి కొంచెం ROW()
- వ్యక్తీకరణలు:
#3: నేను నా ప్రియురాలిని... నిరోధించడం ద్వారా గుర్తించాను
ప్రయోగిస్తున్నారు రెండు ఒకేలా సమాంతర ప్రక్రియలు, ప్రతి ఒక్కటి ఎంట్రీని "ప్రోగ్రెస్లో ఉంది" అని గుర్తు పెట్టడానికి ప్రయత్నిస్తుంది:
UPDATE tbl SET processing = TRUE WHERE pk = $1;
ఈ ప్రక్రియలు వాస్తవానికి ఒకదానికొకటి స్వతంత్రంగా పనులు చేసినప్పటికీ, అదే IDలో, మొదటి లావాదేవీ పూర్తయ్యే వరకు రెండవ క్లయింట్ ఈ అభ్యర్థనపై "లాక్ చేయబడతారు".
పరిష్కారం #1: పని మునుపటిదానికి తగ్గించబడింది
దాన్ని మళ్లీ జోడిద్దాం IS DISTINCT FROM
:
UPDATE tbl SET processing = TRUE WHERE pk = $1 AND processing IS DISTINCT FROM TRUE;
ఈ రూపంలో, రెండవ అభ్యర్థన డేటాబేస్లో దేనినీ మార్చదు, ప్రతిదీ ఇప్పటికే ఉండాలి - కాబట్టి, నిరోధించడం జరగదు. తరువాత, అనువర్తిత అల్గోరిథంలో రికార్డును "కనుగొనలేదు" అనే వాస్తవాన్ని మేము ప్రాసెస్ చేస్తాము.
పరిష్కారం #2: సలహా తాళాలు
ప్రత్యేక కథనం కోసం ఒక పెద్ద అంశం, దాని గురించి మీరు చదువుకోవచ్చు
పరిష్కారం #3: తెలివితక్కువ కాల్స్
అయితే ఇది మీకు సరిగ్గా జరగాలి అదే రికార్డుతో ఏకకాల పని? లేదా క్లయింట్ వైపు వ్యాపార లాజిక్ని కాల్ చేయడం కోసం మీరు అల్గారిథమ్లతో గందరగోళానికి గురయ్యారా, ఉదాహరణకు? మరియు మీరు దాని గురించి ఆలోచిస్తే? ..
మూలం: www.habr.com