PostgreSQL Antipatterns፡ የ"ሙታን" ጭፍሮችን መዋጋት

የ PostgreSQL ውስጣዊ አሠራሮች ልዩነቶች በአንዳንድ ሁኔታዎች በጣም ፈጣን እና በሌሎች ውስጥ "በጣም ፈጣን" እንዲሆኑ ያስችላቸዋል. ዛሬ በዲቢኤምኤስ እንዴት እንደሚሰራ እና ገንቢው በእሱ ምን እንደሚሰራ መካከል ያለውን ግጭት በሚታወቅ ምሳሌ ላይ እናተኩራለን - አዘምን ከ MVCC መርሆዎች ጋር.

አጭር ታሪክ ከ ታላቅ ጽሑፍ:

አንድ ረድፍ በUPDATE ትዕዛዝ ሲቀየር፣ ሁለት ክዋኔዎች በትክክል ይከናወናሉ፡ ሰርዝ እና አስገባ። ውስጥ የሕብረቁምፊው የአሁኑ ስሪት xmax ዝማኔውን ካከናወነው የግብይቱ ቁጥር ጋር እኩል ተዘጋጅቷል። ከዚያም ይፈጠራል አዲስ ስሪት ተመሳሳይ መስመር; የእሱ xmin ዋጋ ከቀዳሚው ስሪት xmax ዋጋ ጋር ይዛመዳል።

ይህ ግብይት ከተጠናቀቀ ከተወሰነ ጊዜ በኋላ, አሮጌው ወይም አዲሱ ስሪት, በእሱ ላይ የተመሰረተ ነው COMMIT/ROOLBACK, እውቅና ይደረጋል "ሙታን" (የሞቱ ጡቦች) ሲያልፍ VACUUM በጠረጴዛው መሰረት እና ተጠርጓል.

PostgreSQL Antipatterns፡ የ"ሙታን" ጭፍሮችን መዋጋት

ግን ይህ ወዲያውኑ አይሆንም ፣ ግን “ከሙታን” ጋር ያሉ ችግሮች በፍጥነት ሊገኙ ይችላሉ - በተደጋጋሚ ወይም መዝገቦች የጅምላ ማሻሻያ በትልቅ ጠረጴዛ ውስጥ, እና ትንሽ ቆይተው ተመሳሳይ ሁኔታ ያጋጥሙዎታል 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ዎቹ ከእርስዎ በኋላ በ [auto]VACUM ማጽዳት አለባቸው።

በዚህ መንገድ አታድርጉ! ተጠቀም ሁሉንም መስኮች በአንድ ጥያቄ ማዘመን - ሁልጊዜ ማለት ይቻላል የአሠራሩ ሎጂክ እንደዚህ ሊለወጥ ይችላል-

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 እና ሌሎች ሎጂካዊ ኦፕሬተሮችን ለመርዳት፡-
PostgreSQL Antipatterns፡ የ"ሙታን" ጭፍሮችን መዋጋት
... እና ስለ ውስብስብ ስራዎች ትንሽ ROW()- መግለጫዎች;
PostgreSQL Antipatterns፡ የ"ሙታን" ጭፍሮችን መዋጋት

#3፡ ውዷን የማውቀው በ... በማገድ ነው።

እየተጀመሩ ነው። ሁለት ተመሳሳይ ትይዩ ሂደቶችእያንዳንዱ መግቢያው “በሂደት ላይ ነው” የሚል ምልክት ለማድረግ ይሞክራል።

UPDATE tbl SET processing = TRUE WHERE pk = $1;

ምንም እንኳን እነዚህ ሂደቶች እርስ በእርሳቸው እራሳቸውን የቻሉ ነገሮችን ቢያደርጉም, ነገር ግን በተመሳሳይ መታወቂያ ውስጥ, ሁለተኛው ደንበኛ የመጀመሪያው ግብይት እስኪጠናቀቅ ድረስ በዚህ ጥያቄ ላይ "ይቆለፋል".

መፍትሄ ቁጥር 1: ተግባሩ ወደ ቀዳሚው ቀንሷል

እስቲ እንደገና እንጨምር IS DISTINCT FROM:

UPDATE tbl SET processing = TRUE WHERE pk = $1 AND processing IS DISTINCT FROM TRUE;

በዚህ ቅጽ ውስጥ, ሁለተኛው ጥያቄ በቀላሉ በመረጃ ቋቱ ውስጥ ምንም ነገር አይለውጥም, ሁሉም ነገር ቀድሞውኑ እንደነበረው ነው - ስለዚህ ማገድ አይከሰትም. በመቀጠል, በተተገበረው ስልተ-ቀመር ውስጥ መዝገቡን "አላገኘንም" የሚለውን እውነታ እንሰራለን.

መፍትሄ ቁጥር 2: የምክር መቆለፊያዎች

ማንበብ ለሚችሉበት የተለየ ጽሑፍ ትልቅ ርዕስ የአተገባበር ዘዴዎች እና "መሰቅሰቂያ" የምክር እገዳ.

መፍትሄ ቁጥር 3: ደደብ ጥሪዎች

ግን በአንተ ላይ መሆን ያለበት ይህ ነው። ከተመሳሳይ መዝገብ ጋር በአንድ ጊዜ ሥራ? ወይስ በደንበኛው በኩል ለምሳሌ የንግድ ሥራ አመክንዮ ለመጥራት ስልተ ቀመሮችን አበላሽተሃል? እና ቢያስቡበት? ..

ምንጭ: hab.com

አስተያየት ያክሉ