PostgreSQL ಆಂಟಿಪ್ಯಾಟರ್ನ್ಸ್: "ಸತ್ತವರ" ಹೋರಾಟದ ಗುಂಪುಗಳು

PostgreSQL ನ ಆಂತರಿಕ ಕಾರ್ಯವಿಧಾನಗಳು ಕಾರ್ಯನಿರ್ವಹಿಸುವ ವಿಧಾನವು ಕೆಲವು ಸಂದರ್ಭಗಳಲ್ಲಿ ತುಂಬಾ ವೇಗವಾಗಿರಲು ಮತ್ತು ಇತರರಲ್ಲಿ ಅಷ್ಟು ವೇಗವಾಗಿರಲು ಅನುವು ಮಾಡಿಕೊಡುತ್ತದೆ. ಇಂದು, DBMS ಹೇಗೆ ಕಾರ್ಯನಿರ್ವಹಿಸುತ್ತದೆ ಮತ್ತು ಡೆವಲಪರ್ ಅದನ್ನು ಬಳಸಿಕೊಂಡು ಏನು ಮಾಡುತ್ತಾರೆ ಎಂಬುದರ ನಡುವಿನ ಸಂಘರ್ಷದ ಒಂದು ಶ್ರೇಷ್ಠ ಉದಾಹರಣೆಯನ್ನು ನಾವು ನೋಡುತ್ತೇವೆ: ಅಪ್‌ಡೇಟ್ vs. MVCC ತತ್ವಗಳು.

ಸಂಕ್ಷಿಪ್ತ ಕಥಾವಸ್ತು ಅತ್ಯುತ್ತಮ ಲೇಖನ:

UPDATE ಆಜ್ಞೆಯಿಂದ ಸಾಲನ್ನು ಮಾರ್ಪಡಿಸಿದಾಗ, ಎರಡು ಕಾರ್ಯಾಚರಣೆಗಳನ್ನು ವಾಸ್ತವವಾಗಿ ನಿರ್ವಹಿಸಲಾಗುತ್ತದೆ: DELETE ಮತ್ತು INSERT. ಸಾಲಿನ ಪ್ರಸ್ತುತ ಆವೃತ್ತಿ xmax ಅನ್ನು UPDATE ನಿರ್ವಹಿಸಿದ ವಹಿವಾಟಿನ ಸಂಖ್ಯೆಗೆ ಹೊಂದಿಸಲಾಗಿದೆ. ನಂತರ ಅದನ್ನು ರಚಿಸಲಾಗುತ್ತದೆ. ಹೊಸ ಆವೃತ್ತಿ ಅದೇ ಸಾಲು; ಇದರ xmin ಮೌಲ್ಯವು ಹಿಂದಿನ ಆವೃತ್ತಿಯ xmax ಮೌಲ್ಯಕ್ಕೆ ಹೊಂದಿಕೆಯಾಗುತ್ತದೆ.

ಈ ವಹಿವಾಟು ಪೂರ್ಣಗೊಂಡ ಸ್ವಲ್ಪ ಸಮಯದ ನಂತರ, ಹಳೆಯ ಅಥವಾ ಹೊಸ ಆವೃತ್ತಿ, ಇದನ್ನು ಅವಲಂಬಿಸಿ COMMIT/ROOLBACK, ಗುರುತಿಸಲ್ಪಡುತ್ತದೆ ಸತ್ತ ಟುಪಲ್ಸ್ ಹಾದುಹೋಗುವಾಗ VACUUM ಟೇಬಲ್ ಪ್ರಕಾರ ಮತ್ತು ತೆರವುಗೊಳಿಸಲಾಗಿದೆ.

PostgreSQL ಆಂಟಿಪ್ಯಾಟರ್ನ್ಸ್: "ಸತ್ತವರ" ಹೋರಾಟದ ಗುಂಪುಗಳು

ಆದರೆ ಇದು ತಕ್ಷಣವೇ ಸಂಭವಿಸುವುದಿಲ್ಲ, ಆದರೆ "ಸತ್ತವರ" ಸಮಸ್ಯೆಗಳನ್ನು ಬಹಳ ಬೇಗನೆ ಪಡೆಯಬಹುದು - ಪುನರಾವರ್ತಿತ ಅಥವಾ ದಾಖಲೆಗಳ ಸಾಮೂಹಿಕ ನವೀಕರಣ ಒಂದು ದೊಡ್ಡ ಕೋಷ್ಟಕದಲ್ಲಿ, ಮತ್ತು ಸ್ವಲ್ಪ ಸಮಯದ ನಂತರ ಒಂದು ಪರಿಸ್ಥಿತಿಯನ್ನು ಎದುರಿಸಬೇಕಾಗುತ್ತದೆ 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;

ಡೇಟಾಬೇಸ್‌ನಲ್ಲಿ ಈ ನಮೂದಿನ ಎಷ್ಟು ಆವೃತ್ತಿಗಳು ಈಗ ನಮ್ಮ ಬಳಿ ಇವೆ? ಹೌದು, ನಾಲ್ಕು! ಅವುಗಳಲ್ಲಿ ಒಂದು ಪ್ರಸ್ತುತವಾಗಿದೆ, ಮತ್ತು ಮೂರನ್ನು [ಸ್ವಯಂ]ವ್ಯಾಕ್ಯೂಮ್ ಮೂಲಕ ಸ್ವಚ್ಛಗೊಳಿಸಬೇಕಾಗುತ್ತದೆ.

ಹಾಗೆ ಮಾಡಬೇಡಿ! ಅದನ್ನು ಬಳಸಿ! ಒಂದೇ ವಿನಂತಿಯಲ್ಲಿ ಎಲ್ಲಾ ಕ್ಷೇತ್ರಗಳನ್ನು ನವೀಕರಿಸಲಾಗುತ್ತಿದೆ — ಬಹುತೇಕ ಯಾವಾಗಲೂ ವಿಧಾನದ ತರ್ಕವನ್ನು ಈ ರೀತಿ ಬದಲಾಯಿಸಬಹುದು:

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 ಆಂಟಿಪ್ಯಾಟರ್ನ್ಸ್: "ಸತ್ತವರ" ಹೋರಾಟದ ಗುಂಪುಗಳು
…ಮತ್ತು ಸಂಕೀರ್ಣದಲ್ಲಿನ ಕಾರ್ಯಾಚರಣೆಗಳ ಬಗ್ಗೆ ಸ್ವಲ್ಪ ROW()-ಅಭಿವ್ಯಕ್ತಿಗಳು:
PostgreSQL ಆಂಟಿಪ್ಯಾಟರ್ನ್ಸ್: "ಸತ್ತವರ" ಹೋರಾಟದ ಗುಂಪುಗಳು

#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