ಪೋಸ್ಟ್‌ಗ್ರೆಸ್: ಉಬ್ಬುವುದು, pg_repack ಮತ್ತು ಮುಂದೂಡಲ್ಪಟ್ಟ ನಿರ್ಬಂಧಗಳು

ಪೋಸ್ಟ್‌ಗ್ರೆಸ್: ಉಬ್ಬುವುದು, pg_repack ಮತ್ತು ಮುಂದೂಡಲ್ಪಟ್ಟ ನಿರ್ಬಂಧಗಳು

ಕೋಷ್ಟಕಗಳು ಮತ್ತು ಸೂಚ್ಯಂಕಗಳ ಮೇಲೆ ಉಬ್ಬುವಿಕೆಯ ಪರಿಣಾಮವು ವ್ಯಾಪಕವಾಗಿ ತಿಳಿದಿದೆ ಮತ್ತು ಪೋಸ್ಟ್‌ಗ್ರೆಸ್‌ನಲ್ಲಿ ಮಾತ್ರವಲ್ಲ. VACUUM FULL ಅಥವಾ CLUSTER ನಂತಹ ಬಾಕ್ಸ್‌ನಿಂದ ಹೊರಗೆ ವ್ಯವಹರಿಸಲು ಮಾರ್ಗಗಳಿವೆ, ಆದರೆ ಅವು ಕಾರ್ಯಾಚರಣೆಯ ಸಮಯದಲ್ಲಿ ಕೋಷ್ಟಕಗಳನ್ನು ಲಾಕ್ ಮಾಡುತ್ತವೆ ಮತ್ತು ಆದ್ದರಿಂದ ಯಾವಾಗಲೂ ಬಳಸಲಾಗುವುದಿಲ್ಲ.

ಲೇಖನವು ಉಬ್ಬುವುದು ಹೇಗೆ ಸಂಭವಿಸುತ್ತದೆ, ನೀವು ಅದನ್ನು ಹೇಗೆ ಹೋರಾಡಬಹುದು, ಮುಂದೂಡಲ್ಪಟ್ಟ ನಿರ್ಬಂಧಗಳು ಮತ್ತು pg_repack ವಿಸ್ತರಣೆಯ ಬಳಕೆಗೆ ತರುವ ಸಮಸ್ಯೆಗಳ ಬಗ್ಗೆ ಸ್ವಲ್ಪ ಸಿದ್ಧಾಂತವನ್ನು ಒಳಗೊಂಡಿರುತ್ತದೆ.

ಈ ಲೇಖನವನ್ನು ಆಧರಿಸಿ ಬರೆಯಲಾಗಿದೆ ನನ್ನ ಮಾತು PgConf.Russia 2020 ನಲ್ಲಿ.

ಉಬ್ಬುವುದು ಏಕೆ ಸಂಭವಿಸುತ್ತದೆ?

ಪೋಸ್ಟ್‌ಗ್ರೆಸ್ ಬಹು-ಆವೃತ್ತಿಯ ಮಾದರಿಯನ್ನು ಆಧರಿಸಿದೆ (MVCC) ಇದರ ಸಾರಾಂಶವೆಂದರೆ ಟೇಬಲ್‌ನಲ್ಲಿನ ಪ್ರತಿಯೊಂದು ಸಾಲು ಹಲವಾರು ಆವೃತ್ತಿಗಳನ್ನು ಹೊಂದಬಹುದು, ಆದರೆ ವಹಿವಾಟುಗಳು ಈ ಆವೃತ್ತಿಗಳಲ್ಲಿ ಒಂದಕ್ಕಿಂತ ಹೆಚ್ಚಿನದನ್ನು ನೋಡುವುದಿಲ್ಲ, ಆದರೆ ಒಂದೇ ಒಂದು ಅಗತ್ಯವಿಲ್ಲ. ಇದು ಹಲವಾರು ವಹಿವಾಟುಗಳನ್ನು ಏಕಕಾಲದಲ್ಲಿ ಕೆಲಸ ಮಾಡಲು ಅನುಮತಿಸುತ್ತದೆ ಮತ್ತು ವಾಸ್ತವಿಕವಾಗಿ ಪರಸ್ಪರ ಪ್ರಭಾವ ಬೀರುವುದಿಲ್ಲ.

ನಿಸ್ಸಂಶಯವಾಗಿ, ಈ ಎಲ್ಲಾ ಆವೃತ್ತಿಗಳನ್ನು ಸಂಗ್ರಹಿಸಬೇಕಾಗಿದೆ. ಪೋಸ್ಟ್‌ಗ್ರೆಸ್ ಪುಟದ ಮೂಲಕ ಮೆಮೊರಿಯೊಂದಿಗೆ ಕಾರ್ಯನಿರ್ವಹಿಸುತ್ತದೆ ಮತ್ತು ಪುಟವು ಡಿಸ್ಕ್‌ನಿಂದ ಓದಬಹುದಾದ ಅಥವಾ ಬರೆಯಬಹುದಾದ ಕನಿಷ್ಠ ಪ್ರಮಾಣದ ಡೇಟಾವಾಗಿದೆ. ಇದು ಹೇಗೆ ಸಂಭವಿಸುತ್ತದೆ ಎಂಬುದನ್ನು ಅರ್ಥಮಾಡಿಕೊಳ್ಳಲು ಒಂದು ಸಣ್ಣ ಉದಾಹರಣೆಯನ್ನು ನೋಡೋಣ.

ನಾವು ಹಲವಾರು ದಾಖಲೆಗಳನ್ನು ಸೇರಿಸಿರುವ ಟೇಬಲ್ ಅನ್ನು ಹೊಂದಿದ್ದೇವೆ ಎಂದು ಹೇಳೋಣ. ಟೇಬಲ್ ಸಂಗ್ರಹವಾಗಿರುವ ಫೈಲ್‌ನ ಮೊದಲ ಪುಟದಲ್ಲಿ ಹೊಸ ಡೇಟಾ ಕಾಣಿಸಿಕೊಂಡಿದೆ. ಇವುಗಳು ಬದ್ಧತೆಯ ನಂತರ ಇತರ ವಹಿವಾಟುಗಳಿಗೆ ಲಭ್ಯವಿರುವ ಸಾಲುಗಳ ಲೈವ್ ಆವೃತ್ತಿಗಳಾಗಿವೆ (ಸರಳತೆಗಾಗಿ, ಪ್ರತ್ಯೇಕತೆಯ ಮಟ್ಟವು ಓದಲು ಬದ್ಧವಾಗಿದೆ ಎಂದು ನಾವು ಭಾವಿಸುತ್ತೇವೆ).

ಪೋಸ್ಟ್‌ಗ್ರೆಸ್: ಉಬ್ಬುವುದು, pg_repack ಮತ್ತು ಮುಂದೂಡಲ್ಪಟ್ಟ ನಿರ್ಬಂಧಗಳು

ನಾವು ನಂತರ ನಮೂದುಗಳಲ್ಲಿ ಒಂದನ್ನು ನವೀಕರಿಸಿದ್ದೇವೆ, ಆ ಮೂಲಕ ಹಳೆಯ ಆವೃತ್ತಿಯನ್ನು ಇನ್ನು ಮುಂದೆ ಪ್ರಸ್ತುತವಲ್ಲ ಎಂದು ಗುರುತಿಸುತ್ತೇವೆ.

ಪೋಸ್ಟ್‌ಗ್ರೆಸ್: ಉಬ್ಬುವುದು, pg_repack ಮತ್ತು ಮುಂದೂಡಲ್ಪಟ್ಟ ನಿರ್ಬಂಧಗಳು

ಹಂತ ಹಂತವಾಗಿ, ಸಾಲು ಆವೃತ್ತಿಗಳನ್ನು ನವೀಕರಿಸುವುದು ಮತ್ತು ಅಳಿಸುವುದು, ನಾವು ಸುಮಾರು ಅರ್ಧದಷ್ಟು ಡೇಟಾ "ಕಸ" ಆಗಿರುವ ಪುಟದೊಂದಿಗೆ ಕೊನೆಗೊಂಡಿದ್ದೇವೆ. ಈ ಡೇಟಾ ಯಾವುದೇ ವಹಿವಾಟಿಗೆ ಗೋಚರಿಸುವುದಿಲ್ಲ.

ಪೋಸ್ಟ್‌ಗ್ರೆಸ್: ಉಬ್ಬುವುದು, pg_repack ಮತ್ತು ಮುಂದೂಡಲ್ಪಟ್ಟ ನಿರ್ಬಂಧಗಳು

Postgres ಒಂದು ಯಾಂತ್ರಿಕ ವ್ಯವಸ್ಥೆಯನ್ನು ಹೊಂದಿದೆ ನಿರ್ವಾತ, ಇದು ಬಳಕೆಯಲ್ಲಿಲ್ಲದ ಆವೃತ್ತಿಗಳನ್ನು ತೆರವುಗೊಳಿಸುತ್ತದೆ ಮತ್ತು ಹೊಸ ಡೇಟಾಗೆ ಸ್ಥಳಾವಕಾಶವನ್ನು ನೀಡುತ್ತದೆ. ಆದರೆ ಇದು ಸಾಕಷ್ಟು ಆಕ್ರಮಣಕಾರಿಯಾಗಿ ಕಾನ್ಫಿಗರ್ ಮಾಡದಿದ್ದರೆ ಅಥವಾ ಇತರ ಕೋಷ್ಟಕಗಳಲ್ಲಿ ಕಾರ್ಯನಿರತವಾಗಿದ್ದರೆ, ನಂತರ "ಕಸ ಡೇಟಾ" ಉಳಿದಿದೆ, ಮತ್ತು ನಾವು ಹೊಸ ಡೇಟಾಕ್ಕಾಗಿ ಹೆಚ್ಚುವರಿ ಪುಟಗಳನ್ನು ಬಳಸಬೇಕಾಗುತ್ತದೆ.

ಆದ್ದರಿಂದ ನಮ್ಮ ಉದಾಹರಣೆಯಲ್ಲಿ, ಕೆಲವು ಸಮಯದಲ್ಲಿ ಟೇಬಲ್ ನಾಲ್ಕು ಪುಟಗಳನ್ನು ಒಳಗೊಂಡಿರುತ್ತದೆ, ಆದರೆ ಅದರಲ್ಲಿ ಅರ್ಧದಷ್ಟು ಮಾತ್ರ ಲೈವ್ ಡೇಟಾವನ್ನು ಹೊಂದಿರುತ್ತದೆ. ಪರಿಣಾಮವಾಗಿ, ಟೇಬಲ್ ಅನ್ನು ಪ್ರವೇಶಿಸುವಾಗ, ಅಗತ್ಯಕ್ಕಿಂತ ಹೆಚ್ಚಿನ ಡೇಟಾವನ್ನು ನಾವು ಓದುತ್ತೇವೆ.

ಪೋಸ್ಟ್‌ಗ್ರೆಸ್: ಉಬ್ಬುವುದು, pg_repack ಮತ್ತು ಮುಂದೂಡಲ್ಪಟ್ಟ ನಿರ್ಬಂಧಗಳು

VACUM ಈಗ ಎಲ್ಲಾ ಅಪ್ರಸ್ತುತ ಸಾಲು ಆವೃತ್ತಿಗಳನ್ನು ಅಳಿಸಿದರೂ, ಪರಿಸ್ಥಿತಿಯು ನಾಟಕೀಯವಾಗಿ ಸುಧಾರಿಸುವುದಿಲ್ಲ. ಹೊಸ ಸಾಲುಗಳಿಗಾಗಿ ನಾವು ಪುಟಗಳಲ್ಲಿ ಅಥವಾ ಸಂಪೂರ್ಣ ಪುಟಗಳಲ್ಲಿ ಮುಕ್ತ ಸ್ಥಳವನ್ನು ಹೊಂದಿರುತ್ತೇವೆ, ಆದರೆ ನಾವು ಇನ್ನೂ ಅಗತ್ಯಕ್ಕಿಂತ ಹೆಚ್ಚಿನ ಡೇಟಾವನ್ನು ಓದುತ್ತೇವೆ.
ಮೂಲಕ, ಸಂಪೂರ್ಣವಾಗಿ ಖಾಲಿ ಪುಟ (ನಮ್ಮ ಉದಾಹರಣೆಯಲ್ಲಿ ಎರಡನೆಯದು) ಫೈಲ್‌ನ ಕೊನೆಯಲ್ಲಿ ಇದ್ದರೆ, ನಂತರ VACUUM ಅದನ್ನು ಟ್ರಿಮ್ ಮಾಡಲು ಸಾಧ್ಯವಾಗುತ್ತದೆ. ಆದರೆ ಈಗ ಅವಳು ಮಧ್ಯದಲ್ಲಿದ್ದಾಳೆ, ಆದ್ದರಿಂದ ಅವಳೊಂದಿಗೆ ಏನೂ ಮಾಡಲು ಸಾಧ್ಯವಿಲ್ಲ.

ಪೋಸ್ಟ್‌ಗ್ರೆಸ್: ಉಬ್ಬುವುದು, pg_repack ಮತ್ತು ಮುಂದೂಡಲ್ಪಟ್ಟ ನಿರ್ಬಂಧಗಳು

ಅಂತಹ ಖಾಲಿ ಅಥವಾ ಹೆಚ್ಚು ವಿರಳವಾದ ಪುಟಗಳ ಸಂಖ್ಯೆಯು ದೊಡ್ಡದಾದಾಗ, ಅದನ್ನು ಉಬ್ಬುವುದು ಎಂದು ಕರೆಯಲಾಗುತ್ತದೆ, ಅದು ಕಾರ್ಯಕ್ಷಮತೆಯ ಮೇಲೆ ಪರಿಣಾಮ ಬೀರಲು ಪ್ರಾರಂಭಿಸುತ್ತದೆ.

ಮೇಲೆ ವಿವರಿಸಿದ ಎಲ್ಲವೂ ಕೋಷ್ಟಕಗಳಲ್ಲಿ ಉಬ್ಬುವುದು ಸಂಭವಿಸುವ ಯಂತ್ರಶಾಸ್ತ್ರವಾಗಿದೆ. ಸೂಚ್ಯಂಕಗಳಲ್ಲಿ ಇದು ಅದೇ ರೀತಿಯಲ್ಲಿ ಸಂಭವಿಸುತ್ತದೆ.

ನನಗೆ ಉಬ್ಬುವುದು ಇದೆಯೇ?

ನಿಮಗೆ ಉಬ್ಬುವುದು ಇದೆಯೇ ಎಂದು ನಿರ್ಧರಿಸಲು ಹಲವಾರು ಮಾರ್ಗಗಳಿವೆ. ಮೊದಲನೆಯ ಕಲ್ಪನೆಯು ಆಂತರಿಕ ಪೋಸ್ಟ್‌ಗ್ರೆಸ್ ಅಂಕಿಅಂಶಗಳನ್ನು ಬಳಸುವುದು, ಇದು ಕೋಷ್ಟಕಗಳಲ್ಲಿನ ಸಾಲುಗಳ ಸಂಖ್ಯೆ, "ಲೈವ್" ಸಾಲುಗಳ ಸಂಖ್ಯೆ, ಇತ್ಯಾದಿಗಳ ಬಗ್ಗೆ ಅಂದಾಜು ಮಾಹಿತಿಯನ್ನು ಒಳಗೊಂಡಿರುತ್ತದೆ. ನೀವು ಅಂತರ್ಜಾಲದಲ್ಲಿ ಸಿದ್ಧ-ಸಿದ್ಧ ಸ್ಕ್ರಿಪ್ಟ್‌ಗಳ ಅನೇಕ ಮಾರ್ಪಾಡುಗಳನ್ನು ಕಾಣಬಹುದು. ನಾವು ಆಧಾರವಾಗಿ ತೆಗೆದುಕೊಂಡಿದ್ದೇವೆ ಸ್ಕ್ರಿಪ್ಟ್ PostgreSQL ತಜ್ಞರಿಂದ, ಇದು ಟೋಸ್ಟ್ ಮತ್ತು ಬ್ಲೋಟ್ ಬಿಟ್ರೀ ಇಂಡೆಕ್ಸ್‌ಗಳ ಜೊತೆಗೆ ಬ್ಲೋಟ್ ಟೇಬಲ್‌ಗಳನ್ನು ಮೌಲ್ಯಮಾಪನ ಮಾಡಬಹುದು. ನಮ್ಮ ಅನುಭವದಲ್ಲಿ, ಅದರ ದೋಷವು 10-20% ಆಗಿದೆ.

ವಿಸ್ತರಣೆಯನ್ನು ಬಳಸುವುದು ಇನ್ನೊಂದು ಮಾರ್ಗವಾಗಿದೆ pgstattuple, ಇದು ಪುಟಗಳ ಒಳಗೆ ನೋಡಲು ಮತ್ತು ಅಂದಾಜು ಮತ್ತು ನಿಖರವಾದ ಬ್ಲೋಟ್ ಮೌಲ್ಯವನ್ನು ಪಡೆಯಲು ನಿಮಗೆ ಅನುಮತಿಸುತ್ತದೆ. ಆದರೆ ಎರಡನೆಯ ಸಂದರ್ಭದಲ್ಲಿ, ನೀವು ಸಂಪೂರ್ಣ ಟೇಬಲ್ ಅನ್ನು ಸ್ಕ್ಯಾನ್ ಮಾಡಬೇಕಾಗುತ್ತದೆ.

ನಾವು 20% ವರೆಗೆ, ಸ್ವೀಕಾರಾರ್ಹವಾದ ಸಣ್ಣ ಉಬ್ಬು ಮೌಲ್ಯವನ್ನು ಪರಿಗಣಿಸುತ್ತೇವೆ. ಇದನ್ನು ಫಿಲ್ಫ್ಯಾಕ್ಟರ್ನ ಅನಲಾಗ್ ಎಂದು ಪರಿಗಣಿಸಬಹುದು ಕೋಷ್ಟಕಗಳು и ಸೂಚ್ಯಂಕಗಳು. 50% ಮತ್ತು ಅದಕ್ಕಿಂತ ಹೆಚ್ಚಿನ ಪ್ರಮಾಣದಲ್ಲಿ, ಕಾರ್ಯಕ್ಷಮತೆಯ ಸಮಸ್ಯೆಗಳು ಪ್ರಾರಂಭವಾಗಬಹುದು.

ಉಬ್ಬುವಿಕೆಯನ್ನು ಎದುರಿಸುವ ಮಾರ್ಗಗಳು

ಪೋಸ್ಟ್‌ಗ್ರೆಸ್ ಬಾಕ್ಸ್‌ನಿಂದ ಉಬ್ಬುವಿಕೆಯನ್ನು ಎದುರಿಸಲು ಹಲವಾರು ಮಾರ್ಗಗಳನ್ನು ಹೊಂದಿದೆ, ಆದರೆ ಅವು ಯಾವಾಗಲೂ ಎಲ್ಲರಿಗೂ ಸೂಕ್ತವಲ್ಲ.

ಉಬ್ಬುವುದು ಸಂಭವಿಸದಂತೆ AUTOVACUUM ಅನ್ನು ಕಾನ್ಫಿಗರ್ ಮಾಡಿ. ಅಥವಾ ಹೆಚ್ಚು ನಿಖರವಾಗಿ, ಅದನ್ನು ನಿಮಗೆ ಸ್ವೀಕಾರಾರ್ಹ ಮಟ್ಟದಲ್ಲಿ ಇರಿಸಿಕೊಳ್ಳಲು. ಇದು "ಕ್ಯಾಪ್ಟನ್" ಸಲಹೆಯಂತೆ ತೋರುತ್ತದೆ, ಆದರೆ ವಾಸ್ತವದಲ್ಲಿ ಇದನ್ನು ಸಾಧಿಸುವುದು ಯಾವಾಗಲೂ ಸುಲಭವಲ್ಲ. ಉದಾಹರಣೆಗೆ, ಡೇಟಾ ಸ್ಕೀಮಾಗೆ ನಿಯಮಿತ ಬದಲಾವಣೆಗಳೊಂದಿಗೆ ನೀವು ಸಕ್ರಿಯ ಅಭಿವೃದ್ಧಿಯನ್ನು ಹೊಂದಿದ್ದೀರಿ ಅಥವಾ ಕೆಲವು ರೀತಿಯ ಡೇಟಾ ವಲಸೆ ನಡೆಯುತ್ತಿದೆ. ಪರಿಣಾಮವಾಗಿ, ನಿಮ್ಮ ಲೋಡ್ ಪ್ರೊಫೈಲ್ ಆಗಾಗ್ಗೆ ಬದಲಾಗಬಹುದು ಮತ್ತು ಸಾಮಾನ್ಯವಾಗಿ ಟೇಬಲ್‌ನಿಂದ ಟೇಬಲ್‌ಗೆ ಬದಲಾಗುತ್ತದೆ. ಇದರರ್ಥ ನೀವು ನಿರಂತರವಾಗಿ ಸ್ವಲ್ಪ ಮುಂದೆ ಕೆಲಸ ಮಾಡಬೇಕಾಗುತ್ತದೆ ಮತ್ತು ಪ್ರತಿ ಟೇಬಲ್‌ನ ಬದಲಾಗುತ್ತಿರುವ ಪ್ರೊಫೈಲ್‌ಗೆ AUTOVACUUM ಅನ್ನು ಹೊಂದಿಸಬೇಕು. ಆದರೆ ನಿಸ್ಸಂಶಯವಾಗಿ ಇದನ್ನು ಮಾಡಲು ಸುಲಭವಲ್ಲ.

AUTOVACUM ಟೇಬಲ್‌ಗಳೊಂದಿಗೆ ಮುಂದುವರಿಯಲು ಸಾಧ್ಯವಾಗದಿರಲು ಮತ್ತೊಂದು ಸಾಮಾನ್ಯ ಕಾರಣವೆಂದರೆ ಆ ವಹಿವಾಟುಗಳಿಗೆ ಲಭ್ಯವಿರುವ ಡೇಟಾವನ್ನು ಸ್ವಚ್ಛಗೊಳಿಸದಂತೆ ತಡೆಯುವ ದೀರ್ಘಾವಧಿಯ ವಹಿವಾಟುಗಳಿವೆ. ಇಲ್ಲಿ ಶಿಫಾರಸು ಸಹ ಸ್ಪಷ್ಟವಾಗಿದೆ - "ತೂಗಾಡುತ್ತಿರುವ" ವಹಿವಾಟುಗಳನ್ನು ತೊಡೆದುಹಾಕಲು ಮತ್ತು ಸಕ್ರಿಯ ವಹಿವಾಟುಗಳ ಸಮಯವನ್ನು ಕಡಿಮೆ ಮಾಡಿ. ಆದರೆ ನಿಮ್ಮ ಅಪ್ಲಿಕೇಶನ್‌ನಲ್ಲಿನ ಲೋಡ್ OLAP ಮತ್ತು OLTP ಯ ಹೈಬ್ರಿಡ್ ಆಗಿದ್ದರೆ, ನೀವು ಏಕಕಾಲದಲ್ಲಿ ಅನೇಕ ಪುನರಾವರ್ತಿತ ನವೀಕರಣಗಳು ಮತ್ತು ಸಣ್ಣ ಪ್ರಶ್ನೆಗಳನ್ನು ಮತ್ತು ದೀರ್ಘಾವಧಿಯ ಕಾರ್ಯಾಚರಣೆಗಳನ್ನು ಹೊಂದಬಹುದು - ಉದಾಹರಣೆಗೆ, ವರದಿಯನ್ನು ನಿರ್ಮಿಸುವುದು. ಅಂತಹ ಪರಿಸ್ಥಿತಿಯಲ್ಲಿ, ವಿಭಿನ್ನ ನೆಲೆಗಳಲ್ಲಿ ಲೋಡ್ ಅನ್ನು ಹರಡುವ ಬಗ್ಗೆ ಯೋಚಿಸುವುದು ಯೋಗ್ಯವಾಗಿದೆ, ಅದು ಅವುಗಳಲ್ಲಿ ಪ್ರತಿಯೊಂದಕ್ಕೂ ಹೆಚ್ಚು ಉತ್ತಮವಾದ ಶ್ರುತಿಯನ್ನು ಅನುಮತಿಸುತ್ತದೆ.

ಮತ್ತೊಂದು ಉದಾಹರಣೆ - ಪ್ರೊಫೈಲ್ ಏಕರೂಪವಾಗಿದ್ದರೂ, ಡೇಟಾಬೇಸ್ ಅತಿ ಹೆಚ್ಚು ಲೋಡ್ ಆಗಿದ್ದರೂ ಸಹ, ಅತ್ಯಂತ ಆಕ್ರಮಣಕಾರಿ AUTOVACUUM ಸಹ ನಿಭಾಯಿಸದಿರಬಹುದು ಮತ್ತು ಉಬ್ಬುವುದು ಸಂಭವಿಸುತ್ತದೆ. ಸ್ಕೇಲಿಂಗ್ (ಲಂಬ ಅಥವಾ ಅಡ್ಡ) ಮಾತ್ರ ಪರಿಹಾರವಾಗಿದೆ.

ನೀವು AUTOVACUM ಅನ್ನು ಸ್ಥಾಪಿಸಿದ ಪರಿಸ್ಥಿತಿಯಲ್ಲಿ ಏನು ಮಾಡಬೇಕು, ಆದರೆ ಉಬ್ಬುವುದು ಬೆಳೆಯುತ್ತಲೇ ಇರುತ್ತದೆ.

ತಂಡದ ನಿರ್ವಾತ ಪೂರ್ಣ ಕೋಷ್ಟಕಗಳು ಮತ್ತು ಸೂಚಿಕೆಗಳ ವಿಷಯಗಳನ್ನು ಪುನರ್ನಿರ್ಮಿಸುತ್ತದೆ ಮತ್ತು ಅವುಗಳಲ್ಲಿ ಕೇವಲ ಸಂಬಂಧಿತ ಡೇಟಾವನ್ನು ಬಿಡುತ್ತದೆ. ಉಬ್ಬುವಿಕೆಯನ್ನು ತೊಡೆದುಹಾಕಲು, ಇದು ಸಂಪೂರ್ಣವಾಗಿ ಕಾರ್ಯನಿರ್ವಹಿಸುತ್ತದೆ, ಆದರೆ ಅದರ ಕಾರ್ಯಗತಗೊಳಿಸುವಿಕೆಯ ಸಮಯದಲ್ಲಿ ಮೇಜಿನ ಮೇಲೆ ವಿಶೇಷ ಲಾಕ್ ಅನ್ನು ಸೆರೆಹಿಡಿಯಲಾಗುತ್ತದೆ (AccessExclusiveLock), ಇದು ಈ ಕೋಷ್ಟಕದಲ್ಲಿ ಪ್ರಶ್ನೆಗಳನ್ನು ಕಾರ್ಯಗತಗೊಳಿಸಲು ಅನುಮತಿಸುವುದಿಲ್ಲ, ಸಹ ಆಯ್ಕೆ ಮಾಡುತ್ತದೆ. ನಿಮ್ಮ ಸೇವೆಯನ್ನು ಅಥವಾ ಅದರ ಭಾಗವನ್ನು ಸ್ವಲ್ಪ ಸಮಯದವರೆಗೆ ನಿಲ್ಲಿಸಲು ನೀವು ಶಕ್ತರಾಗಿದ್ದರೆ (ಡೇಟಾಬೇಸ್ ಮತ್ತು ನಿಮ್ಮ ಹಾರ್ಡ್‌ವೇರ್‌ನ ಗಾತ್ರವನ್ನು ಅವಲಂಬಿಸಿ ಹತ್ತಾರು ನಿಮಿಷಗಳಿಂದ ಹಲವಾರು ಗಂಟೆಗಳವರೆಗೆ), ನಂತರ ಈ ಆಯ್ಕೆಯು ಉತ್ತಮವಾಗಿದೆ. ದುರದೃಷ್ಟವಶಾತ್, ನಿಗದಿತ ನಿರ್ವಹಣೆಯ ಸಮಯದಲ್ಲಿ VACUUM FULL ಅನ್ನು ಚಲಾಯಿಸಲು ನಮಗೆ ಸಮಯವಿಲ್ಲ, ಆದ್ದರಿಂದ ಈ ವಿಧಾನವು ನಮಗೆ ಸೂಕ್ತವಲ್ಲ.

ತಂಡದ ಕ್ಲಸ್ಟರ್ VACUUM FULL ರೀತಿಯಲ್ಲಿಯೇ ಕೋಷ್ಟಕಗಳ ವಿಷಯಗಳನ್ನು ಮರುನಿರ್ಮಾಣ ಮಾಡುತ್ತದೆ, ಆದರೆ ಡಿಸ್ಕ್‌ನಲ್ಲಿ ಡೇಟಾವನ್ನು ಭೌತಿಕವಾಗಿ ಆದೇಶಿಸುವ ಸೂಚ್ಯಂಕವನ್ನು ನಿರ್ದಿಷ್ಟಪಡಿಸಲು ನಿಮಗೆ ಅನುಮತಿಸುತ್ತದೆ (ಆದರೆ ಭವಿಷ್ಯದಲ್ಲಿ ಹೊಸ ಸಾಲುಗಳಿಗೆ ಆದೇಶವನ್ನು ಖಾತರಿಪಡಿಸಲಾಗುವುದಿಲ್ಲ). ಕೆಲವು ಸಂದರ್ಭಗಳಲ್ಲಿ, ಇದು ಹಲವಾರು ಪ್ರಶ್ನೆಗಳಿಗೆ ಉತ್ತಮ ಆಪ್ಟಿಮೈಸೇಶನ್ ಆಗಿದೆ - ಸೂಚ್ಯಂಕದ ಮೂಲಕ ಅನೇಕ ದಾಖಲೆಗಳನ್ನು ಓದುವುದರೊಂದಿಗೆ. ಆಜ್ಞೆಯ ಅನನುಕೂಲವೆಂದರೆ VACUUM FULL ನಂತೆಯೇ ಇರುತ್ತದೆ - ಇದು ಕಾರ್ಯಾಚರಣೆಯ ಸಮಯದಲ್ಲಿ ಟೇಬಲ್ ಅನ್ನು ಲಾಕ್ ಮಾಡುತ್ತದೆ.

ತಂಡದ REINDEX ಹಿಂದಿನ ಎರಡರಂತೆಯೇ, ಆದರೆ ನಿರ್ದಿಷ್ಟ ಸೂಚ್ಯಂಕ ಅಥವಾ ಟೇಬಲ್‌ನ ಎಲ್ಲಾ ಸೂಚಿಕೆಗಳನ್ನು ಮರುನಿರ್ಮಾಣ ಮಾಡುತ್ತದೆ. ಲಾಕ್‌ಗಳು ಸ್ವಲ್ಪ ದುರ್ಬಲವಾಗಿವೆ: ಟೇಬಲ್‌ನಲ್ಲಿನ ಶೇರ್‌ಲಾಕ್ (ಮಾರ್ಪಾಡುಗಳನ್ನು ತಡೆಯುತ್ತದೆ, ಆದರೆ ಆಯ್ಕೆ ಮಾಡಲು ಅನುಮತಿಸುತ್ತದೆ) ಮತ್ತು ಮರುನಿರ್ಮಾಣಗೊಳ್ಳುತ್ತಿರುವ ಸೂಚ್ಯಂಕದಲ್ಲಿನ ಆಕ್ಸೆಸ್ ಎಕ್ಸ್‌ಕ್ಲೂಸಿವ್‌ಲಾಕ್ (ಈ ಸೂಚಿಯನ್ನು ಬಳಸಿಕೊಂಡು ಪ್ರಶ್ನೆಗಳನ್ನು ನಿರ್ಬಂಧಿಸುತ್ತದೆ). ಆದಾಗ್ಯೂ, ಪೋಸ್ಟ್‌ಗ್ರೆಸ್‌ನ 12 ನೇ ಆವೃತ್ತಿಯಲ್ಲಿ ಒಂದು ಪ್ಯಾರಾಮೀಟರ್ ಕಾಣಿಸಿಕೊಂಡಿತು ಏಕಕಾಲದಲ್ಲಿ, ಇದು ಏಕಕಾಲೀನ ಸೇರ್ಪಡೆ, ಮಾರ್ಪಾಡು ಅಥವಾ ದಾಖಲೆಗಳ ಅಳಿಸುವಿಕೆಯನ್ನು ನಿರ್ಬಂಧಿಸದೆಯೇ ಸೂಚ್ಯಂಕವನ್ನು ಮರುನಿರ್ಮಾಣ ಮಾಡಲು ನಿಮಗೆ ಅನುಮತಿಸುತ್ತದೆ.

ಪೋಸ್ಟ್‌ಗ್ರೆಸ್‌ನ ಹಿಂದಿನ ಆವೃತ್ತಿಗಳಲ್ಲಿ, ನೀವು REINDEX ಅನ್ನು ಏಕಕಾಲದಲ್ಲಿ ಬಳಸುವಂತೆಯೇ ಫಲಿತಾಂಶವನ್ನು ಸಾಧಿಸಬಹುದು ಸೂಚ್ಯಂಕವನ್ನು ಏಕಕಾಲದಲ್ಲಿ ರಚಿಸಿ. ಕಟ್ಟುನಿಟ್ಟಾದ ಲಾಕ್ ಮಾಡದೆಯೇ ಸೂಚ್ಯಂಕವನ್ನು ರಚಿಸಲು ಇದು ನಿಮ್ಮನ್ನು ಅನುಮತಿಸುತ್ತದೆ (ShareUpdateExclusiveLock, ಇದು ಸಮಾನಾಂತರ ಪ್ರಶ್ನೆಗಳೊಂದಿಗೆ ಮಧ್ಯಪ್ರವೇಶಿಸುವುದಿಲ್ಲ), ನಂತರ ಹಳೆಯ ಸೂಚ್ಯಂಕವನ್ನು ಹೊಸದರೊಂದಿಗೆ ಬದಲಾಯಿಸಿ ಮತ್ತು ಹಳೆಯ ಸೂಚಿಯನ್ನು ಅಳಿಸಿ. ನಿಮ್ಮ ಅಪ್ಲಿಕೇಶನ್‌ನಲ್ಲಿ ಮಧ್ಯಪ್ರವೇಶಿಸದೆಯೇ ಸೂಚ್ಯಂಕ ಉಬ್ಬುವಿಕೆಯನ್ನು ತೊಡೆದುಹಾಕಲು ಇದು ನಿಮ್ಮನ್ನು ಅನುಮತಿಸುತ್ತದೆ. ಸೂಚಿಕೆಗಳನ್ನು ಮರುನಿರ್ಮಾಣ ಮಾಡುವಾಗ ಡಿಸ್ಕ್ ಉಪವ್ಯವಸ್ಥೆಯಲ್ಲಿ ಹೆಚ್ಚುವರಿ ಲೋಡ್ ಇರುತ್ತದೆ ಎಂದು ಪರಿಗಣಿಸುವುದು ಮುಖ್ಯ.

ಹೀಗಾಗಿ, ಸೂಚ್ಯಂಕಗಳಿಗೆ "ಫ್ಲೈನಲ್ಲಿ" ಉಬ್ಬುವಿಕೆಯನ್ನು ತೊಡೆದುಹಾಕಲು ಮಾರ್ಗಗಳಿದ್ದರೆ, ನಂತರ ಕೋಷ್ಟಕಗಳಿಗೆ ಯಾವುದೂ ಇಲ್ಲ. ಇಲ್ಲಿ ವಿವಿಧ ಬಾಹ್ಯ ವಿಸ್ತರಣೆಗಳು ಕಾರ್ಯರೂಪಕ್ಕೆ ಬರುತ್ತವೆ: pg_repack (ಹಿಂದೆ pg_reorg), pgcompact, pgcompactable ಮತ್ತು ಇತರರು. ಈ ಲೇಖನದಲ್ಲಿ, ನಾನು ಅವುಗಳನ್ನು ಹೋಲಿಸುವುದಿಲ್ಲ ಮತ್ತು pg_repack ಬಗ್ಗೆ ಮಾತ್ರ ಮಾತನಾಡುತ್ತೇನೆ, ಕೆಲವು ಮಾರ್ಪಾಡುಗಳ ನಂತರ ನಾವು ನಮ್ಮನ್ನು ಬಳಸುತ್ತೇವೆ.

pg_repack ಹೇಗೆ ಕೆಲಸ ಮಾಡುತ್ತದೆ

ಪೋಸ್ಟ್‌ಗ್ರೆಸ್: ಉಬ್ಬುವುದು, pg_repack ಮತ್ತು ಮುಂದೂಡಲ್ಪಟ್ಟ ನಿರ್ಬಂಧಗಳು
ನಾವು ಸಂಪೂರ್ಣವಾಗಿ ಸಾಮಾನ್ಯ ಕೋಷ್ಟಕವನ್ನು ಹೊಂದಿದ್ದೇವೆ ಎಂದು ಹೇಳೋಣ - ಸೂಚ್ಯಂಕಗಳು, ನಿರ್ಬಂಧಗಳು ಮತ್ತು ದುರದೃಷ್ಟವಶಾತ್, ಉಬ್ಬುವಿಕೆಯೊಂದಿಗೆ. ಚಾಲನೆಯಲ್ಲಿರುವಾಗ ಎಲ್ಲಾ ಬದಲಾವಣೆಗಳ ಬಗ್ಗೆ ಡೇಟಾವನ್ನು ಸಂಗ್ರಹಿಸಲು ಲಾಗ್ ಟೇಬಲ್ ಅನ್ನು ರಚಿಸುವುದು pg_repack ನ ಮೊದಲ ಹಂತವಾಗಿದೆ. ಪ್ರತಿ ಇನ್ಸರ್ಟ್, ಅಪ್‌ಡೇಟ್ ಮತ್ತು ಡಿಲೀಟ್‌ಗಳಿಗೆ ಟ್ರಿಗ್ಗರ್ ಈ ಬದಲಾವಣೆಗಳನ್ನು ಪುನರಾವರ್ತಿಸುತ್ತದೆ. ನಂತರ ಒಂದು ಟೇಬಲ್ ಅನ್ನು ರಚಿಸಲಾಗಿದೆ, ರಚನೆಯಲ್ಲಿ ಮೂಲವನ್ನು ಹೋಲುತ್ತದೆ, ಆದರೆ ಸೂಚಿಕೆಗಳು ಮತ್ತು ನಿರ್ಬಂಧಗಳಿಲ್ಲದೆ, ಡೇಟಾವನ್ನು ಸೇರಿಸುವ ಪ್ರಕ್ರಿಯೆಯನ್ನು ನಿಧಾನಗೊಳಿಸುವುದಿಲ್ಲ.

ಮುಂದೆ, pg_repack ಹಳೆಯ ಟೇಬಲ್‌ನಿಂದ ಹೊಸ ಟೇಬಲ್‌ಗೆ ಡೇಟಾವನ್ನು ವರ್ಗಾಯಿಸುತ್ತದೆ, ಎಲ್ಲಾ ಅಪ್ರಸ್ತುತ ಸಾಲುಗಳನ್ನು ಸ್ವಯಂಚಾಲಿತವಾಗಿ ಫಿಲ್ಟರ್ ಮಾಡುತ್ತದೆ ಮತ್ತು ನಂತರ ಹೊಸ ಟೇಬಲ್‌ಗಾಗಿ ಸೂಚಿಕೆಗಳನ್ನು ರಚಿಸುತ್ತದೆ. ಈ ಎಲ್ಲಾ ಕಾರ್ಯಾಚರಣೆಗಳ ಮರಣದಂಡನೆಯ ಸಮಯದಲ್ಲಿ, ಲಾಗ್ ಕೋಷ್ಟಕದಲ್ಲಿ ಬದಲಾವಣೆಗಳು ಸಂಗ್ರಹಗೊಳ್ಳುತ್ತವೆ.

ಬದಲಾವಣೆಗಳನ್ನು ಹೊಸ ಕೋಷ್ಟಕಕ್ಕೆ ವರ್ಗಾಯಿಸುವುದು ಮುಂದಿನ ಹಂತವಾಗಿದೆ. ಹಲವಾರು ಪುನರಾವರ್ತನೆಗಳ ಮೂಲಕ ವಲಸೆಯನ್ನು ನಿರ್ವಹಿಸಲಾಗುತ್ತದೆ ಮತ್ತು ಲಾಗ್ ಟೇಬಲ್‌ನಲ್ಲಿ 20 ಕ್ಕಿಂತ ಕಡಿಮೆ ನಮೂದುಗಳು ಉಳಿದಿರುವಾಗ, pg_repack ಬಲವಾದ ಲಾಕ್ ಅನ್ನು ಪಡೆದುಕೊಳ್ಳುತ್ತದೆ, ಇತ್ತೀಚಿನ ಡೇಟಾವನ್ನು ಸ್ಥಳಾಂತರಿಸುತ್ತದೆ ಮತ್ತು ಪೋಸ್ಟ್‌ಗ್ರೆಸ್ ಸಿಸ್ಟಮ್ ಟೇಬಲ್‌ಗಳಲ್ಲಿ ಹಳೆಯ ಟೇಬಲ್ ಅನ್ನು ಹೊಸದರೊಂದಿಗೆ ಬದಲಾಯಿಸುತ್ತದೆ. ನೀವು ಮೇಜಿನೊಂದಿಗೆ ಕೆಲಸ ಮಾಡಲು ಸಾಧ್ಯವಾಗದ ಏಕೈಕ ಮತ್ತು ಕಡಿಮೆ ಸಮಯ ಇದು. ಇದರ ನಂತರ, ಹಳೆಯ ಟೇಬಲ್ ಮತ್ತು ಲಾಗ್ಗಳೊಂದಿಗೆ ಟೇಬಲ್ ಅನ್ನು ಅಳಿಸಲಾಗುತ್ತದೆ ಮತ್ತು ಫೈಲ್ ಸಿಸ್ಟಮ್ನಲ್ಲಿ ಜಾಗವನ್ನು ಮುಕ್ತಗೊಳಿಸಲಾಗುತ್ತದೆ. ಪ್ರಕ್ರಿಯೆ ಪೂರ್ಣಗೊಂಡಿದೆ.

ಸಿದ್ಧಾಂತದಲ್ಲಿ ಎಲ್ಲವೂ ಉತ್ತಮವಾಗಿ ಕಾಣುತ್ತದೆ, ಆದರೆ ಆಚರಣೆಯಲ್ಲಿ ಏನಾಗುತ್ತದೆ? ನಾವು ಲೋಡ್ ಇಲ್ಲದೆ ಮತ್ತು ಲೋಡ್ ಅಡಿಯಲ್ಲಿ pg_repack ಅನ್ನು ಪರೀಕ್ಷಿಸಿದ್ದೇವೆ ಮತ್ತು ಅಕಾಲಿಕ ನಿಲುಗಡೆಯ ಸಂದರ್ಭದಲ್ಲಿ ಅದರ ಕಾರ್ಯಾಚರಣೆಯನ್ನು ಪರಿಶೀಲಿಸಿದ್ದೇವೆ (ಬೇರೆ ರೀತಿಯಲ್ಲಿ ಹೇಳುವುದಾದರೆ, Ctrl+C ಬಳಸಿ). ಎಲ್ಲಾ ಪರೀಕ್ಷೆಗಳು ಸಕಾರಾತ್ಮಕವಾಗಿವೆ.

ನಾವು ಆಹಾರ ಅಂಗಡಿಗೆ ಹೋದೆವು - ಮತ್ತು ನಂತರ ನಾವು ನಿರೀಕ್ಷಿಸಿದಂತೆ ಎಲ್ಲವೂ ನಡೆಯಲಿಲ್ಲ.

ಮೊದಲ ಪ್ಯಾನ್ಕೇಕ್ ಮಾರಾಟದಲ್ಲಿದೆ

ಮೊದಲ ಕ್ಲಸ್ಟರ್‌ನಲ್ಲಿ ನಾವು ಅನನ್ಯ ನಿರ್ಬಂಧದ ಉಲ್ಲಂಘನೆಯ ಬಗ್ಗೆ ದೋಷವನ್ನು ಸ್ವೀಕರಿಸಿದ್ದೇವೆ:

$ ./pg_repack -t tablename -o id
INFO: repacking table "tablename"
ERROR: query failed: 
    ERROR: duplicate key value violates unique constraint "index_16508"
DETAIL:  Key (id, index)=(100500, 42) already exists.

ಈ ಮಿತಿಯು ಸ್ವಯಂ-ರಚಿಸಿದ ಹೆಸರು index_16508 ಅನ್ನು ಹೊಂದಿದೆ - ಇದನ್ನು pg_repack ನಿಂದ ರಚಿಸಲಾಗಿದೆ. ಅದರ ಸಂಯೋಜನೆಯಲ್ಲಿ ಒಳಗೊಂಡಿರುವ ಗುಣಲಕ್ಷಣಗಳ ಆಧಾರದ ಮೇಲೆ, ಅದಕ್ಕೆ ಅನುಗುಣವಾದ "ನಮ್ಮ" ನಿರ್ಬಂಧವನ್ನು ನಾವು ನಿರ್ಧರಿಸಿದ್ದೇವೆ. ಸಮಸ್ಯೆಯೆಂದರೆ ಇದು ಸಂಪೂರ್ಣವಾಗಿ ಸಾಮಾನ್ಯ ಮಿತಿಯಲ್ಲ, ಆದರೆ ಮುಂದೂಡಲ್ಪಟ್ಟಿದೆ (ಮುಂದೂಡಲ್ಪಟ್ಟ ನಿರ್ಬಂಧ), ಅಂದರೆ. ಅದರ ಪರಿಶೀಲನೆಯನ್ನು sql ಆದೇಶಕ್ಕಿಂತ ನಂತರ ನಡೆಸಲಾಗುತ್ತದೆ, ಇದು ಅನಿರೀಕ್ಷಿತ ಪರಿಣಾಮಗಳಿಗೆ ಕಾರಣವಾಗುತ್ತದೆ.

ಮುಂದೂಡಲ್ಪಟ್ಟ ನಿರ್ಬಂಧಗಳು: ಅವು ಏಕೆ ಬೇಕು ಮತ್ತು ಅವು ಹೇಗೆ ಕಾರ್ಯನಿರ್ವಹಿಸುತ್ತವೆ

ಮುಂದೂಡಲ್ಪಟ್ಟ ನಿರ್ಬಂಧಗಳ ಬಗ್ಗೆ ಸ್ವಲ್ಪ ಸಿದ್ಧಾಂತ.
ಸರಳವಾದ ಉದಾಹರಣೆಯನ್ನು ಪರಿಗಣಿಸೋಣ: ನಾವು ಎರಡು ಗುಣಲಕ್ಷಣಗಳೊಂದಿಗೆ ಕಾರುಗಳ ಟೇಬಲ್-ಉಲ್ಲೇಖ ಪುಸ್ತಕವನ್ನು ಹೊಂದಿದ್ದೇವೆ - ಡೈರೆಕ್ಟರಿಯಲ್ಲಿ ಕಾರಿನ ಹೆಸರು ಮತ್ತು ಕ್ರಮ.
ಪೋಸ್ಟ್‌ಗ್ರೆಸ್: ಉಬ್ಬುವುದು, pg_repack ಮತ್ತು ಮುಂದೂಡಲ್ಪಟ್ಟ ನಿರ್ಬಂಧಗಳು

create table cars
(
  name text constraint pk_cars primary key,
  ord integer not null constraint uk_cars unique
);



ನಾವು ಮೊದಲ ಮತ್ತು ಎರಡನೆಯ ಕಾರುಗಳನ್ನು ವಿನಿಮಯ ಮಾಡಿಕೊಳ್ಳಬೇಕು ಎಂದು ಹೇಳೋಣ. ಮೊದಲ ಮೌಲ್ಯವನ್ನು ಎರಡನೆಯದಕ್ಕೆ ಮತ್ತು ಎರಡನೆಯದನ್ನು ಮೊದಲನೆಯದಕ್ಕೆ ನವೀಕರಿಸುವುದು ನೇರ ಪರಿಹಾರವಾಗಿದೆ:

begin;
  update cars set ord = 2 where name = 'audi';
  update cars set ord = 1 where name = 'bmw';
commit;

ಆದರೆ ನಾವು ಈ ಕೋಡ್ ಅನ್ನು ಚಲಾಯಿಸಿದಾಗ, ನಾವು ನಿರ್ಬಂಧದ ಉಲ್ಲಂಘನೆಯನ್ನು ನಿರೀಕ್ಷಿಸುತ್ತೇವೆ ಏಕೆಂದರೆ ಕೋಷ್ಟಕದಲ್ಲಿನ ಮೌಲ್ಯಗಳ ಕ್ರಮವು ವಿಶಿಷ್ಟವಾಗಿದೆ:

[23305] ERROR: duplicate key value violates unique constraint “uk_cars”
Detail: Key (ord)=(2) already exists.

ನಾನು ಅದನ್ನು ವಿಭಿನ್ನವಾಗಿ ಹೇಗೆ ಮಾಡಬಹುದು? ಆಯ್ಕೆ ಒಂದು: ಕೋಷ್ಟಕದಲ್ಲಿ ಅಸ್ತಿತ್ವದಲ್ಲಿಲ್ಲ ಎಂದು ಖಾತರಿಪಡಿಸುವ ಆದೇಶಕ್ಕೆ ಹೆಚ್ಚುವರಿ ಮೌಲ್ಯದ ಬದಲಿಯನ್ನು ಸೇರಿಸಿ, ಉದಾಹರಣೆಗೆ "-1". ಪ್ರೋಗ್ರಾಮಿಂಗ್‌ನಲ್ಲಿ, ಇದನ್ನು "ಎರಡು ಅಸ್ಥಿರಗಳ ಮೌಲ್ಯಗಳನ್ನು ಮೂರನೇ ಮೂಲಕ ವಿನಿಮಯ ಮಾಡಿಕೊಳ್ಳುವುದು" ಎಂದು ಕರೆಯಲಾಗುತ್ತದೆ. ಈ ವಿಧಾನದ ಏಕೈಕ ನ್ಯೂನತೆಯೆಂದರೆ ಹೆಚ್ಚುವರಿ ನವೀಕರಣ.

ಆಯ್ಕೆ ಎರಡು: ಪೂರ್ಣಾಂಕಗಳ ಬದಲಿಗೆ ಆರ್ಡರ್ ಮೌಲ್ಯಕ್ಕಾಗಿ ಫ್ಲೋಟಿಂಗ್ ಪಾಯಿಂಟ್ ಡೇಟಾ ಪ್ರಕಾರವನ್ನು ಬಳಸಲು ಟೇಬಲ್ ಅನ್ನು ಮರುವಿನ್ಯಾಸಗೊಳಿಸಿ. ನಂತರ, 1 ರಿಂದ ಮೌಲ್ಯವನ್ನು ನವೀಕರಿಸುವಾಗ, ಉದಾಹರಣೆಗೆ, 2.5 ಗೆ, ಮೊದಲ ನಮೂದು ಸ್ವಯಂಚಾಲಿತವಾಗಿ ಎರಡನೇ ಮತ್ತು ಮೂರನೇ ನಡುವೆ "ನಿಂತಿದೆ". ಈ ಪರಿಹಾರವು ಕಾರ್ಯನಿರ್ವಹಿಸುತ್ತದೆ, ಆದರೆ ಎರಡು ಮಿತಿಗಳಿವೆ. ಮೊದಲನೆಯದಾಗಿ, ಇಂಟರ್ಫೇಸ್‌ನಲ್ಲಿ ಎಲ್ಲೋ ಮೌಲ್ಯವನ್ನು ಬಳಸಿದರೆ ಅದು ನಿಮಗೆ ಕೆಲಸ ಮಾಡುವುದಿಲ್ಲ. ಎರಡನೆಯದಾಗಿ, ಡೇಟಾ ಪ್ರಕಾರದ ನಿಖರತೆಯನ್ನು ಅವಲಂಬಿಸಿ, ಎಲ್ಲಾ ದಾಖಲೆಗಳ ಮೌಲ್ಯಗಳನ್ನು ಮರು ಲೆಕ್ಕಾಚಾರ ಮಾಡುವ ಮೊದಲು ನೀವು ಸೀಮಿತ ಸಂಖ್ಯೆಯ ಸಂಭವನೀಯ ಒಳಸೇರಿಸುವಿಕೆಯನ್ನು ಹೊಂದಿರುತ್ತೀರಿ.

ಆಯ್ಕೆ ಮೂರು: ನಿರ್ಬಂಧವನ್ನು ಮುಂದೂಡುವಂತೆ ಮಾಡಿ ಇದರಿಂದ ಬದ್ಧತೆಯ ಸಮಯದಲ್ಲಿ ಮಾತ್ರ ಅದನ್ನು ಪರಿಶೀಲಿಸಲಾಗುತ್ತದೆ:

create table cars
(
  name text constraint pk_cars primary key,
  ord integer not null constraint uk_cars unique deferrable initially deferred
);

ನಮ್ಮ ಆರಂಭಿಕ ವಿನಂತಿಯ ತರ್ಕವು ಬದ್ಧತೆಯ ಸಮಯದಲ್ಲಿ ಎಲ್ಲಾ ಮೌಲ್ಯಗಳು ಅನನ್ಯವಾಗಿವೆ ಎಂದು ಖಚಿತಪಡಿಸುವುದರಿಂದ, ಅದು ಯಶಸ್ವಿಯಾಗುತ್ತದೆ.

ಮೇಲೆ ಚರ್ಚಿಸಿದ ಉದಾಹರಣೆಯು ಸಹಜವಾಗಿ, ಬಹಳ ಸಂಶ್ಲೇಷಿತವಾಗಿದೆ, ಆದರೆ ಇದು ಕಲ್ಪನೆಯನ್ನು ಬಹಿರಂಗಪಡಿಸುತ್ತದೆ. ನಮ್ಮ ಅಪ್ಲಿಕೇಶನ್‌ನಲ್ಲಿ, ಬಳಕೆದಾರರು ಏಕಕಾಲದಲ್ಲಿ ಬೋರ್ಡ್‌ನಲ್ಲಿ ಹಂಚಿಕೊಂಡ ವಿಜೆಟ್ ಆಬ್ಜೆಕ್ಟ್‌ಗಳೊಂದಿಗೆ ಕೆಲಸ ಮಾಡುವಾಗ ಸಂಘರ್ಷಗಳನ್ನು ಪರಿಹರಿಸಲು ಜವಾಬ್ದಾರರಾಗಿರುವ ತರ್ಕವನ್ನು ಕಾರ್ಯಗತಗೊಳಿಸಲು ನಾವು ಮುಂದೂಡಲ್ಪಟ್ಟ ನಿರ್ಬಂಧಗಳನ್ನು ಬಳಸುತ್ತೇವೆ. ಅಂತಹ ನಿರ್ಬಂಧಗಳನ್ನು ಬಳಸುವುದರಿಂದ ಅಪ್ಲಿಕೇಶನ್ ಕೋಡ್ ಅನ್ನು ಸ್ವಲ್ಪ ಸರಳಗೊಳಿಸಲು ನಮಗೆ ಅನುಮತಿಸುತ್ತದೆ.

ಸಾಮಾನ್ಯವಾಗಿ, ನಿರ್ಬಂಧದ ಪ್ರಕಾರವನ್ನು ಅವಲಂಬಿಸಿ, ಪೋಸ್ಟ್‌ಗ್ರೆಸ್ ಅವುಗಳನ್ನು ಪರಿಶೀಲಿಸಲು ಮೂರು ಹಂತದ ಗ್ರ್ಯಾನ್ಯುಲಾರಿಟಿಯನ್ನು ಹೊಂದಿದೆ: ಸಾಲು, ವಹಿವಾಟು ಮತ್ತು ಅಭಿವ್ಯಕ್ತಿ ಮಟ್ಟಗಳು.
ಪೋಸ್ಟ್‌ಗ್ರೆಸ್: ಉಬ್ಬುವುದು, pg_repack ಮತ್ತು ಮುಂದೂಡಲ್ಪಟ್ಟ ನಿರ್ಬಂಧಗಳು
ಮೂಲ: ಬಿಗ್ರಿಫ್ಸ್

ಚೆಕ್ ಮತ್ತು NULL ಅನ್ನು ಯಾವಾಗಲೂ ಸಾಲು ಮಟ್ಟದಲ್ಲಿ ಪರಿಶೀಲಿಸಲಾಗುತ್ತದೆ; ಇತರ ನಿರ್ಬಂಧಗಳಿಗಾಗಿ, ಟೇಬಲ್‌ನಿಂದ ನೋಡಬಹುದಾದಂತೆ, ವಿಭಿನ್ನ ಆಯ್ಕೆಗಳಿವೆ. ನೀವು ಹೆಚ್ಚು ಓದಬಹುದು ಇಲ್ಲಿ.

ಸಂಕ್ಷಿಪ್ತವಾಗಿ ಸಂಕ್ಷಿಪ್ತವಾಗಿ ಹೇಳುವುದಾದರೆ, ಹಲವಾರು ಸಂದರ್ಭಗಳಲ್ಲಿ ಮುಂದೂಡಲ್ಪಟ್ಟ ನಿರ್ಬಂಧಗಳು ಹೆಚ್ಚು ಓದಬಹುದಾದ ಕೋಡ್ ಮತ್ತು ಕಡಿಮೆ ಆಜ್ಞೆಗಳನ್ನು ಒದಗಿಸುತ್ತವೆ. ಆದಾಗ್ಯೂ, ಡೀಬಗ್ ಮಾಡುವ ಪ್ರಕ್ರಿಯೆಯನ್ನು ಸಂಕೀರ್ಣಗೊಳಿಸುವ ಮೂಲಕ ನೀವು ಇದಕ್ಕಾಗಿ ಪಾವತಿಸಬೇಕಾಗುತ್ತದೆ, ಏಕೆಂದರೆ ದೋಷ ಸಂಭವಿಸುವ ಕ್ಷಣ ಮತ್ತು ಅದರ ಬಗ್ಗೆ ನೀವು ಕಂಡುಹಿಡಿಯುವ ಕ್ಷಣವನ್ನು ಸಮಯಕ್ಕೆ ಬೇರ್ಪಡಿಸಲಾಗುತ್ತದೆ. ಮತ್ತೊಂದು ಸಂಭವನೀಯ ಸಮಸ್ಯೆಯೆಂದರೆ, ವಿನಂತಿಯು ಮುಂದೂಡಲ್ಪಟ್ಟ ನಿರ್ಬಂಧವನ್ನು ಒಳಗೊಂಡಿದ್ದರೆ ಶೆಡ್ಯೂಲರ್ ಯಾವಾಗಲೂ ಸೂಕ್ತ ಯೋಜನೆಯನ್ನು ನಿರ್ಮಿಸಲು ಸಾಧ್ಯವಾಗುವುದಿಲ್ಲ.

pg_repack ನ ಸುಧಾರಣೆ

ಮುಂದೂಡಲ್ಪಟ್ಟ ನಿರ್ಬಂಧಗಳು ಯಾವುವು ಎಂಬುದನ್ನು ನಾವು ಕವರ್ ಮಾಡಿದ್ದೇವೆ, ಆದರೆ ಅವು ನಮ್ಮ ಸಮಸ್ಯೆಗೆ ಹೇಗೆ ಸಂಬಂಧಿಸಿವೆ? ನಾವು ಹಿಂದೆ ಸ್ವೀಕರಿಸಿದ ದೋಷವನ್ನು ನೆನಪಿಸಿಕೊಳ್ಳೋಣ:

$ ./pg_repack -t tablename -o id
INFO: repacking table "tablename"
ERROR: query failed: 
    ERROR: duplicate key value violates unique constraint "index_16508"
DETAIL:  Key (id, index)=(100500, 42) already exists.

ಲಾಗ್ ಟೇಬಲ್‌ನಿಂದ ಹೊಸ ಟೇಬಲ್‌ಗೆ ಡೇಟಾವನ್ನು ನಕಲಿಸಿದಾಗ ಇದು ಸಂಭವಿಸುತ್ತದೆ. ಇದು ವಿಚಿತ್ರವಾಗಿ ಕಾಣುತ್ತದೆ ಏಕೆಂದರೆ ... ಲಾಗ್ ಕೋಷ್ಟಕದಲ್ಲಿನ ಡೇಟಾವು ಮೂಲ ಕೋಷ್ಟಕದಲ್ಲಿನ ಡೇಟಾದೊಂದಿಗೆ ಬದ್ಧವಾಗಿದೆ. ಅವರು ಮೂಲ ಕೋಷ್ಟಕದ ನಿರ್ಬಂಧಗಳನ್ನು ಪೂರೈಸಿದರೆ, ಹೊಸದರಲ್ಲಿ ಅದೇ ನಿರ್ಬಂಧಗಳನ್ನು ಹೇಗೆ ಉಲ್ಲಂಘಿಸಬಹುದು?

ಅದು ಬದಲಾದಂತೆ, ಸಮಸ್ಯೆಯ ಮೂಲವು pg_repack ನ ಹಿಂದಿನ ಹಂತದಲ್ಲಿದೆ, ಇದು ಸೂಚ್ಯಂಕಗಳನ್ನು ಮಾತ್ರ ರಚಿಸುತ್ತದೆ, ಆದರೆ ನಿರ್ಬಂಧಗಳಲ್ಲ: ಹಳೆಯ ಕೋಷ್ಟಕವು ವಿಶಿಷ್ಟವಾದ ನಿರ್ಬಂಧವನ್ನು ಹೊಂದಿತ್ತು ಮತ್ತು ಹೊಸದು ಬದಲಿಗೆ ಅನನ್ಯ ಸೂಚ್ಯಂಕವನ್ನು ರಚಿಸಿತು.

ಪೋಸ್ಟ್‌ಗ್ರೆಸ್: ಉಬ್ಬುವುದು, pg_repack ಮತ್ತು ಮುಂದೂಡಲ್ಪಟ್ಟ ನಿರ್ಬಂಧಗಳು

ನಿರ್ಬಂಧವು ಸಾಮಾನ್ಯವಾಗಿದ್ದರೆ ಮತ್ತು ಮುಂದೂಡದಿದ್ದರೆ, ಬದಲಿಗೆ ರಚಿಸಲಾದ ಅನನ್ಯ ಸೂಚ್ಯಂಕವು ಈ ನಿರ್ಬಂಧಕ್ಕೆ ಸಮನಾಗಿರುತ್ತದೆ ಎಂಬುದನ್ನು ಇಲ್ಲಿ ಗಮನಿಸುವುದು ಮುಖ್ಯವಾಗಿದೆ, ಏಕೆಂದರೆ ವಿಶಿಷ್ಟವಾದ ಸೂಚಿಯನ್ನು ರಚಿಸುವ ಮೂಲಕ ಪೋಸ್ಟ್‌ಗ್ರೆಸ್‌ನಲ್ಲಿ ವಿಶಿಷ್ಟ ನಿರ್ಬಂಧಗಳನ್ನು ಅಳವಡಿಸಲಾಗಿದೆ. ಆದರೆ ಮುಂದೂಡಲ್ಪಟ್ಟ ನಿರ್ಬಂಧದ ಸಂದರ್ಭದಲ್ಲಿ, ನಡವಳಿಕೆಯು ಒಂದೇ ಆಗಿರುವುದಿಲ್ಲ, ಏಕೆಂದರೆ ಸೂಚ್ಯಂಕವನ್ನು ಮುಂದೂಡಲಾಗುವುದಿಲ್ಲ ಮತ್ತು sql ಆಜ್ಞೆಯನ್ನು ಕಾರ್ಯಗತಗೊಳಿಸಿದ ಸಮಯದಲ್ಲಿ ಯಾವಾಗಲೂ ಪರಿಶೀಲಿಸಲಾಗುತ್ತದೆ.

ಹೀಗಾಗಿ, ಸಮಸ್ಯೆಯ ಮೂಲತತ್ವವು ಚೆಕ್‌ನ "ವಿಳಂಬ" ದಲ್ಲಿದೆ: ಮೂಲ ಕೋಷ್ಟಕದಲ್ಲಿ ಇದು ಬದ್ಧತೆಯ ಸಮಯದಲ್ಲಿ ಸಂಭವಿಸುತ್ತದೆ ಮತ್ತು ಹೊಸ ಕೋಷ್ಟಕದಲ್ಲಿ sql ಆಜ್ಞೆಯನ್ನು ಕಾರ್ಯಗತಗೊಳಿಸುವ ಸಮಯದಲ್ಲಿ. ಇದರರ್ಥ ನಾವು ಎರಡೂ ಸಂದರ್ಭಗಳಲ್ಲಿ ತಪಾಸಣೆಗಳನ್ನು ಒಂದೇ ರೀತಿಯಲ್ಲಿ ನಿರ್ವಹಿಸುತ್ತೇವೆ ಎಂದು ಖಚಿತಪಡಿಸಿಕೊಳ್ಳಬೇಕು: ಯಾವಾಗಲೂ ವಿಳಂಬವಾಗುತ್ತದೆ ಅಥವಾ ಯಾವಾಗಲೂ ತಕ್ಷಣವೇ.

ಹಾಗಾದರೆ ನಾವು ಯಾವ ಆಲೋಚನೆಗಳನ್ನು ಹೊಂದಿದ್ದೇವೆ?

ಮುಂದೂಡಲ್ಪಟ್ಟಿರುವಂತೆಯೇ ಸೂಚ್ಯಂಕವನ್ನು ರಚಿಸಿ

ತಕ್ಷಣದ ಕ್ರಮದಲ್ಲಿ ಎರಡೂ ತಪಾಸಣೆಗಳನ್ನು ನಿರ್ವಹಿಸುವುದು ಮೊದಲ ಉಪಾಯವಾಗಿದೆ. ಇದು ಹಲವಾರು ತಪ್ಪು ಧನಾತ್ಮಕ ನಿರ್ಬಂಧಗಳನ್ನು ಉಂಟುಮಾಡಬಹುದು, ಆದರೆ ಅವುಗಳಲ್ಲಿ ಕೆಲವು ಇದ್ದರೆ, ಇದು ಬಳಕೆದಾರರ ಕೆಲಸದ ಮೇಲೆ ಪರಿಣಾಮ ಬೀರಬಾರದು, ಏಕೆಂದರೆ ಅಂತಹ ಸಂಘರ್ಷಗಳು ಅವರಿಗೆ ಸಾಮಾನ್ಯ ಪರಿಸ್ಥಿತಿಯಾಗಿದೆ. ಉದಾಹರಣೆಗೆ, ಇಬ್ಬರು ಬಳಕೆದಾರರು ಒಂದೇ ಸಮಯದಲ್ಲಿ ಒಂದೇ ವಿಜೆಟ್ ಅನ್ನು ಸಂಪಾದಿಸಲು ಪ್ರಾರಂಭಿಸಿದಾಗ ಮತ್ತು ಎರಡನೇ ಬಳಕೆದಾರರ ಕ್ಲೈಂಟ್‌ಗೆ ಮೊದಲ ಬಳಕೆದಾರರಿಂದ ಸಂಪಾದನೆಗಾಗಿ ವಿಜೆಟ್ ಅನ್ನು ಈಗಾಗಲೇ ನಿರ್ಬಂಧಿಸಲಾಗಿದೆ ಎಂಬ ಮಾಹಿತಿಯನ್ನು ಸ್ವೀಕರಿಸಲು ಸಮಯವಿಲ್ಲ ಎಂದು ಅವು ಸಂಭವಿಸುತ್ತವೆ. ಅಂತಹ ಪರಿಸ್ಥಿತಿಯಲ್ಲಿ, ಸರ್ವರ್ ಎರಡನೇ ಬಳಕೆದಾರರನ್ನು ನಿರಾಕರಿಸುತ್ತದೆ ಮತ್ತು ಅದರ ಕ್ಲೈಂಟ್ ಬದಲಾವಣೆಗಳನ್ನು ಹಿಂತಿರುಗಿಸುತ್ತದೆ ಮತ್ತು ವಿಜೆಟ್ ಅನ್ನು ನಿರ್ಬಂಧಿಸುತ್ತದೆ. ಸ್ವಲ್ಪ ಸಮಯದ ನಂತರ, ಮೊದಲ ಬಳಕೆದಾರರು ಸಂಪಾದನೆಯನ್ನು ಪೂರ್ಣಗೊಳಿಸಿದಾಗ, ಎರಡನೆಯವರು ವಿಜೆಟ್ ಅನ್ನು ಇನ್ನು ಮುಂದೆ ನಿರ್ಬಂಧಿಸಲಾಗಿಲ್ಲ ಮತ್ತು ಅವರ ಕ್ರಿಯೆಯನ್ನು ಪುನರಾವರ್ತಿಸಲು ಸಾಧ್ಯವಾಗುತ್ತದೆ ಎಂಬ ಮಾಹಿತಿಯನ್ನು ಸ್ವೀಕರಿಸುತ್ತಾರೆ.

ಪೋಸ್ಟ್‌ಗ್ರೆಸ್: ಉಬ್ಬುವುದು, pg_repack ಮತ್ತು ಮುಂದೂಡಲ್ಪಟ್ಟ ನಿರ್ಬಂಧಗಳು

ಪರಿಶೀಲನೆಗಳು ಯಾವಾಗಲೂ ಮುಂದೂಡದ ಮೋಡ್‌ನಲ್ಲಿವೆ ಎಂದು ಖಚಿತಪಡಿಸಿಕೊಳ್ಳಲು, ನಾವು ಮೂಲ ಮುಂದೂಡಲ್ಪಟ್ಟ ನಿರ್ಬಂಧದಂತೆಯೇ ಹೊಸ ಸೂಚಿಯನ್ನು ರಚಿಸಿದ್ದೇವೆ:

CREATE UNIQUE INDEX CONCURRENTLY uk_tablename__immediate ON tablename (id, index);
-- run pg_repack
DROP INDEX CONCURRENTLY uk_tablename__immediate;

ಪರೀಕ್ಷಾ ಪರಿಸರದಲ್ಲಿ, ನಾವು ಕೆಲವು ನಿರೀಕ್ಷಿತ ದೋಷಗಳನ್ನು ಮಾತ್ರ ಸ್ವೀಕರಿಸಿದ್ದೇವೆ. ಯಶಸ್ಸು! ನಾವು ಉತ್ಪಾದನೆಯಲ್ಲಿ ಮತ್ತೊಮ್ಮೆ pg_repack ಅನ್ನು ನಡೆಸಿದ್ದೇವೆ ಮತ್ತು ಒಂದು ಗಂಟೆಯ ಕೆಲಸದಲ್ಲಿ ಮೊದಲ ಕ್ಲಸ್ಟರ್‌ನಲ್ಲಿ 5 ದೋಷಗಳನ್ನು ಪಡೆದುಕೊಂಡಿದ್ದೇವೆ. ಇದು ಸ್ವೀಕಾರಾರ್ಹ ಫಲಿತಾಂಶವಾಗಿದೆ. ಆದಾಗ್ಯೂ, ಈಗಾಗಲೇ ಎರಡನೇ ಕ್ಲಸ್ಟರ್‌ನಲ್ಲಿ ದೋಷಗಳ ಸಂಖ್ಯೆಯು ಗಮನಾರ್ಹವಾಗಿ ಹೆಚ್ಚಾಗಿದೆ ಮತ್ತು ನಾವು pg_repack ಅನ್ನು ನಿಲ್ಲಿಸಬೇಕಾಗಿತ್ತು.

ಯಾಕೆ ಹೀಗಾಯಿತು? ಒಂದೇ ಸಮಯದಲ್ಲಿ ಒಂದೇ ವಿಜೆಟ್‌ಗಳೊಂದಿಗೆ ಎಷ್ಟು ಬಳಕೆದಾರರು ಕಾರ್ಯನಿರ್ವಹಿಸುತ್ತಿದ್ದಾರೆ ಎಂಬುದರ ಮೇಲೆ ದೋಷ ಸಂಭವಿಸುವ ಸಾಧ್ಯತೆಯು ಅವಲಂಬಿತವಾಗಿರುತ್ತದೆ. ಸ್ಪಷ್ಟವಾಗಿ, ಆ ಕ್ಷಣದಲ್ಲಿ ಇತರರಿಗಿಂತ ಮೊದಲ ಕ್ಲಸ್ಟರ್‌ನಲ್ಲಿ ಸಂಗ್ರಹಿಸಲಾದ ಡೇಟಾದೊಂದಿಗೆ ಕಡಿಮೆ ಸ್ಪರ್ಧಾತ್ಮಕ ಬದಲಾವಣೆಗಳಿವೆ, ಅಂದರೆ. ನಾವು ಕೇವಲ "ಅದೃಷ್ಟವಂತರು".

ಉಪಾಯ ಫಲಿಸಲಿಲ್ಲ. ಆ ಸಮಯದಲ್ಲಿ, ನಾವು ಎರಡು ಇತರ ಪರಿಹಾರಗಳನ್ನು ನೋಡಿದ್ದೇವೆ: ಮುಂದೂಡಲ್ಪಟ್ಟ ನಿರ್ಬಂಧಗಳನ್ನು ತೊಡೆದುಹಾಕಲು ನಮ್ಮ ಅಪ್ಲಿಕೇಶನ್ ಕೋಡ್ ಅನ್ನು ಪುನಃ ಬರೆಯಿರಿ ಅಥವಾ ಅವರೊಂದಿಗೆ ಕೆಲಸ ಮಾಡಲು pg_repack ಅನ್ನು "ಕಲಿಸಿ". ನಾವು ಎರಡನೆಯದನ್ನು ಆರಿಸಿದ್ದೇವೆ.

ಹೊಸ ಕೋಷ್ಟಕದಲ್ಲಿನ ಸೂಚಿಕೆಗಳನ್ನು ಮೂಲ ಕೋಷ್ಟಕದಿಂದ ಮುಂದೂಡಲ್ಪಟ್ಟ ನಿರ್ಬಂಧಗಳೊಂದಿಗೆ ಬದಲಾಯಿಸಿ

ಪರಿಷ್ಕರಣೆಯ ಉದ್ದೇಶವು ಸ್ಪಷ್ಟವಾಗಿತ್ತು - ಮೂಲ ಕೋಷ್ಟಕವು ಮುಂದೂಡಲ್ಪಟ್ಟ ನಿರ್ಬಂಧವನ್ನು ಹೊಂದಿದ್ದರೆ, ಹೊಸದಕ್ಕಾಗಿ ನೀವು ಅಂತಹ ನಿರ್ಬಂಧವನ್ನು ರಚಿಸಬೇಕಾಗಿದೆ, ಮತ್ತು ಸೂಚ್ಯಂಕವಲ್ಲ.

ನಮ್ಮ ಬದಲಾವಣೆಗಳನ್ನು ಪರೀಕ್ಷಿಸಲು, ನಾವು ಸರಳ ಪರೀಕ್ಷೆಯನ್ನು ಬರೆದಿದ್ದೇವೆ:

  • ಮುಂದೂಡಲ್ಪಟ್ಟ ನಿರ್ಬಂಧ ಮತ್ತು ಒಂದು ದಾಖಲೆಯೊಂದಿಗೆ ಟೇಬಲ್;
  • ಅಸ್ತಿತ್ವದಲ್ಲಿರುವ ದಾಖಲೆಯೊಂದಿಗೆ ಸಂಘರ್ಷಗೊಳ್ಳುವ ಲೂಪ್‌ನಲ್ಲಿ ಡೇಟಾವನ್ನು ಸೇರಿಸಿ;
  • ನವೀಕರಣವನ್ನು ಮಾಡಿ - ಡೇಟಾವು ಇನ್ನು ಮುಂದೆ ಸಂಘರ್ಷಗೊಳ್ಳುವುದಿಲ್ಲ;
  • ಬದಲಾವಣೆಗಳನ್ನು ಮಾಡಿ.

create table test_table
(
  id serial,
  val int,
  constraint uk_test_table__val unique (val) deferrable initially deferred 
);

INSERT INTO test_table (val) VALUES (0);
FOR i IN 1..10000 LOOP
  BEGIN
    INSERT INTO test_table VALUES (0) RETURNING id INTO v_id;
    UPDATE test_table set val = i where id = v_id;
    COMMIT;
  END;
END LOOP;

pg_repack ನ ಮೂಲ ಆವೃತ್ತಿಯು ಯಾವಾಗಲೂ ಮೊದಲ ಇನ್ಸರ್ಟ್‌ನಲ್ಲಿ ಕ್ರ್ಯಾಶ್ ಆಗುತ್ತದೆ, ಮಾರ್ಪಡಿಸಿದ ಆವೃತ್ತಿಯು ದೋಷಗಳಿಲ್ಲದೆ ಕಾರ್ಯನಿರ್ವಹಿಸುತ್ತದೆ. ಕುವೆಂಪು.

ನಾವು ಉತ್ಪಾದನೆಗೆ ಹೋಗುತ್ತೇವೆ ಮತ್ತು ಲಾಗ್ ಟೇಬಲ್‌ನಿಂದ ಹೊಸದಕ್ಕೆ ಡೇಟಾವನ್ನು ನಕಲಿಸುವ ಅದೇ ಹಂತದಲ್ಲಿ ಮತ್ತೊಮ್ಮೆ ದೋಷವನ್ನು ಪಡೆಯುತ್ತೇವೆ:

$ ./pg_repack -t tablename -o id
INFO: repacking table "tablename"
ERROR: query failed: 
    ERROR: duplicate key value violates unique constraint "index_16508"
DETAIL:  Key (id, index)=(100500, 42) already exists.

ಕ್ಲಾಸಿಕ್ ಪರಿಸ್ಥಿತಿ: ಎಲ್ಲವೂ ಪರೀಕ್ಷಾ ಪರಿಸರದಲ್ಲಿ ಕಾರ್ಯನಿರ್ವಹಿಸುತ್ತದೆ, ಆದರೆ ಉತ್ಪಾದನೆಯಲ್ಲಿ ಅಲ್ಲವೇ?!

APPLY_COUNT ಮತ್ತು ಎರಡು ಬ್ಯಾಚ್‌ಗಳ ಜಂಕ್ಷನ್

ನಾವು ಕೋಡ್ ಅನ್ನು ಅಕ್ಷರಶಃ ಸಾಲಿನ ಮೂಲಕ ವಿಶ್ಲೇಷಿಸಲು ಪ್ರಾರಂಭಿಸಿದ್ದೇವೆ ಮತ್ತು ಪ್ರಮುಖ ಅಂಶವನ್ನು ಕಂಡುಹಿಡಿದಿದ್ದೇವೆ: ಡೇಟಾವನ್ನು ಲಾಗ್ ಟೇಬಲ್‌ನಿಂದ ಬ್ಯಾಚ್‌ಗಳಲ್ಲಿ ಹೊಸದಕ್ಕೆ ವರ್ಗಾಯಿಸಲಾಗುತ್ತದೆ, APPLY_COUNT ಸ್ಥಿರಾಂಕವು ಬ್ಯಾಚ್‌ನ ಗಾತ್ರವನ್ನು ಸೂಚಿಸುತ್ತದೆ:

for (;;)
{
num = apply_log(connection, table, APPLY_COUNT);

if (num > MIN_TUPLES_BEFORE_SWITCH)
     continue;  /* there might be still some tuples, repeat. */
...
}

ಸಮಸ್ಯೆಯೆಂದರೆ ಮೂಲ ವಹಿವಾಟಿನ ಡೇಟಾ, ಇದರಲ್ಲಿ ಹಲವಾರು ಕಾರ್ಯಾಚರಣೆಗಳು ನಿರ್ಬಂಧವನ್ನು ಉಲ್ಲಂಘಿಸಬಹುದು, ವರ್ಗಾಯಿಸಿದಾಗ, ಎರಡು ಬ್ಯಾಚ್‌ಗಳ ಜಂಕ್ಷನ್‌ನಲ್ಲಿ ಕೊನೆಗೊಳ್ಳಬಹುದು - ಅರ್ಧದಷ್ಟು ಆಜ್ಞೆಗಳು ಮೊದಲ ಬ್ಯಾಚ್‌ನಲ್ಲಿ ಬದ್ಧವಾಗಿರುತ್ತವೆ ಮತ್ತು ಉಳಿದ ಅರ್ಧ ಎರಡನೆಯದರಲ್ಲಿ. ಮತ್ತು ಇಲ್ಲಿ, ನಿಮ್ಮ ಅದೃಷ್ಟವನ್ನು ಅವಲಂಬಿಸಿ: ತಂಡಗಳು ಮೊದಲ ಬ್ಯಾಚ್‌ನಲ್ಲಿ ಏನನ್ನೂ ಉಲ್ಲಂಘಿಸದಿದ್ದರೆ, ಎಲ್ಲವೂ ಉತ್ತಮವಾಗಿದೆ, ಆದರೆ ಅವರು ಮಾಡಿದರೆ, ದೋಷ ಸಂಭವಿಸುತ್ತದೆ.

APPLY_COUNT 1000 ದಾಖಲೆಗಳಿಗೆ ಸಮಾನವಾಗಿದೆ, ಇದು ನಮ್ಮ ಪರೀಕ್ಷೆಗಳು ಏಕೆ ಯಶಸ್ವಿಯಾಗಿದೆ ಎಂಬುದನ್ನು ವಿವರಿಸುತ್ತದೆ - ಅವುಗಳು "ಬ್ಯಾಚ್ ಜಂಕ್ಷನ್" ಪ್ರಕರಣವನ್ನು ಒಳಗೊಂಡಿಲ್ಲ. ನಾವು ಎರಡು ಆಜ್ಞೆಗಳನ್ನು ಬಳಸಿದ್ದೇವೆ - ಸೇರಿಸು ಮತ್ತು ನವೀಕರಿಸಿ, ಆದ್ದರಿಂದ ಎರಡು ಆಜ್ಞೆಗಳ ನಿಖರವಾಗಿ 500 ವಹಿವಾಟುಗಳನ್ನು ಯಾವಾಗಲೂ ಬ್ಯಾಚ್‌ನಲ್ಲಿ ಇರಿಸಲಾಗುತ್ತದೆ ಮತ್ತು ನಾವು ಯಾವುದೇ ಸಮಸ್ಯೆಗಳನ್ನು ಅನುಭವಿಸಲಿಲ್ಲ. ಎರಡನೇ ನವೀಕರಣವನ್ನು ಸೇರಿಸಿದ ನಂತರ, ನಮ್ಮ ಸಂಪಾದನೆಯು ಕಾರ್ಯನಿರ್ವಹಿಸುವುದನ್ನು ನಿಲ್ಲಿಸಿದೆ:

FOR i IN 1..10000 LOOP
  BEGIN
    INSERT INTO test_table VALUES (1) RETURNING id INTO v_id;
    UPDATE test_table set val = i where id = v_id;
    UPDATE test_table set val = i where id = v_id; -- one more update
    COMMIT;
  END;
END LOOP;

ಆದ್ದರಿಂದ, ಒಂದು ವಹಿವಾಟಿನಲ್ಲಿ ಬದಲಾಯಿಸಲಾದ ಮೂಲ ಕೋಷ್ಟಕದ ಡೇಟಾವು ಹೊಸ ಕೋಷ್ಟಕದಲ್ಲಿ ಒಂದು ವಹಿವಾಟಿನೊಳಗೆ ಕೊನೆಗೊಳ್ಳುತ್ತದೆ ಎಂದು ಖಚಿತಪಡಿಸಿಕೊಳ್ಳುವುದು ಮುಂದಿನ ಕಾರ್ಯವಾಗಿದೆ.

ಬ್ಯಾಚಿಂಗ್ ನಿಂದ ನಿರಾಕರಣೆ

ಮತ್ತು ಮತ್ತೆ ನಮಗೆ ಎರಡು ಪರಿಹಾರಗಳಿವೆ. ಮೊದಲನೆಯದು: ಬ್ಯಾಚ್‌ಗಳಾಗಿ ವಿಭಜನೆಯನ್ನು ಸಂಪೂರ್ಣವಾಗಿ ತ್ಯಜಿಸೋಣ ಮತ್ತು ಒಂದು ವಹಿವಾಟಿನಲ್ಲಿ ಡೇಟಾವನ್ನು ವರ್ಗಾಯಿಸೋಣ. ಈ ಪರಿಹಾರದ ಪ್ರಯೋಜನವೆಂದರೆ ಅದರ ಸರಳತೆ - ಅಗತ್ಯವಿರುವ ಕೋಡ್ ಬದಲಾವಣೆಗಳು ಕಡಿಮೆ (ಮೂಲಕ, ಹಳೆಯ ಆವೃತ್ತಿಗಳಲ್ಲಿ pg_reorg ನಿಖರವಾಗಿ ಕೆಲಸ ಮಾಡಿದೆ). ಆದರೆ ಒಂದು ಸಮಸ್ಯೆ ಇದೆ - ನಾವು ದೀರ್ಘಾವಧಿಯ ವಹಿವಾಟನ್ನು ರಚಿಸುತ್ತಿದ್ದೇವೆ ಮತ್ತು ಇದು ಹಿಂದೆ ಹೇಳಿದಂತೆ, ಹೊಸ ಉಬ್ಬುವಿಕೆಯ ಹೊರಹೊಮ್ಮುವಿಕೆಗೆ ಬೆದರಿಕೆಯಾಗಿದೆ.

ಎರಡನೆಯ ಪರಿಹಾರವು ಹೆಚ್ಚು ಸಂಕೀರ್ಣವಾಗಿದೆ, ಆದರೆ ಬಹುಶಃ ಹೆಚ್ಚು ಸರಿಯಾಗಿದೆ: ಟೇಬಲ್‌ಗೆ ಡೇಟಾವನ್ನು ಸೇರಿಸಿದ ವಹಿವಾಟಿನ ಗುರುತಿಸುವಿಕೆಯೊಂದಿಗೆ ಲಾಗ್ ಟೇಬಲ್‌ನಲ್ಲಿ ಕಾಲಮ್ ಅನ್ನು ರಚಿಸಿ. ನಂತರ, ನಾವು ಡೇಟಾವನ್ನು ನಕಲಿಸಿದಾಗ, ನಾವು ಅದನ್ನು ಈ ಗುಣಲಕ್ಷಣದ ಮೂಲಕ ಗುಂಪು ಮಾಡಬಹುದು ಮತ್ತು ಸಂಬಂಧಿತ ಬದಲಾವಣೆಗಳನ್ನು ಒಟ್ಟಿಗೆ ವರ್ಗಾಯಿಸಲಾಗುತ್ತದೆ ಎಂದು ಖಚಿತಪಡಿಸಿಕೊಳ್ಳಬಹುದು. ಬ್ಯಾಚ್ ಹಲವಾರು ವಹಿವಾಟುಗಳಿಂದ (ಅಥವಾ ಒಂದು ದೊಡ್ಡದು) ರಚನೆಯಾಗುತ್ತದೆ ಮತ್ತು ಈ ವಹಿವಾಟುಗಳಲ್ಲಿ ಎಷ್ಟು ಡೇಟಾವನ್ನು ಬದಲಾಯಿಸಲಾಗಿದೆ ಎಂಬುದರ ಆಧಾರದ ಮೇಲೆ ಅದರ ಗಾತ್ರವು ಬದಲಾಗುತ್ತದೆ. ವಿಭಿನ್ನ ವಹಿವಾಟುಗಳ ಡೇಟಾವು ಯಾದೃಚ್ಛಿಕ ಕ್ರಮದಲ್ಲಿ ಲಾಗ್ ಟೇಬಲ್‌ಗೆ ಪ್ರವೇಶಿಸುವುದರಿಂದ, ಅದನ್ನು ಮೊದಲಿನಂತೆ ಅನುಕ್ರಮವಾಗಿ ಓದಲು ಇನ್ನು ಮುಂದೆ ಸಾಧ್ಯವಾಗುವುದಿಲ್ಲ ಎಂಬುದನ್ನು ಗಮನಿಸುವುದು ಮುಖ್ಯವಾಗಿದೆ. tx_id ಮೂಲಕ ಫಿಲ್ಟರಿಂಗ್‌ನೊಂದಿಗೆ ಪ್ರತಿ ವಿನಂತಿಗೆ seqscan ತುಂಬಾ ದುಬಾರಿಯಾಗಿದೆ, ಸೂಚ್ಯಂಕ ಅಗತ್ಯವಿದೆ, ಆದರೆ ಅದನ್ನು ನವೀಕರಿಸುವ ಓವರ್‌ಹೆಡ್‌ನಿಂದಾಗಿ ಇದು ವಿಧಾನವನ್ನು ನಿಧಾನಗೊಳಿಸುತ್ತದೆ. ಸಾಮಾನ್ಯವಾಗಿ, ಯಾವಾಗಲೂ, ನೀವು ಏನನ್ನಾದರೂ ತ್ಯಾಗ ಮಾಡಬೇಕಾಗಿದೆ.

ಆದ್ದರಿಂದ, ನಾವು ಮೊದಲ ಆಯ್ಕೆಯೊಂದಿಗೆ ಪ್ರಾರಂಭಿಸಲು ನಿರ್ಧರಿಸಿದ್ದೇವೆ, ಏಕೆಂದರೆ ಅದು ಸರಳವಾಗಿದೆ. ಮೊದಲನೆಯದಾಗಿ, ಸುದೀರ್ಘ ವಹಿವಾಟು ನಿಜವಾದ ಸಮಸ್ಯೆಯಾಗಿದೆಯೇ ಎಂಬುದನ್ನು ಅರ್ಥಮಾಡಿಕೊಳ್ಳುವುದು ಅಗತ್ಯವಾಗಿತ್ತು. ಹಳೆಯ ಕೋಷ್ಟಕದಿಂದ ಹೊಸದಕ್ಕೆ ಡೇಟಾದ ಮುಖ್ಯ ವರ್ಗಾವಣೆಯು ಒಂದು ಸುದೀರ್ಘ ವಹಿವಾಟಿನಲ್ಲಿ ಸಂಭವಿಸುವುದರಿಂದ, ಪ್ರಶ್ನೆಯು "ಈ ವಹಿವಾಟನ್ನು ನಾವು ಎಷ್ಟು ಹೆಚ್ಚಿಸುತ್ತೇವೆ?" ಮೊದಲ ವಹಿವಾಟಿನ ಅವಧಿಯು ಮುಖ್ಯವಾಗಿ ಮೇಜಿನ ಗಾತ್ರವನ್ನು ಅವಲಂಬಿಸಿರುತ್ತದೆ. ಡೇಟಾ ವರ್ಗಾವಣೆಯ ಸಮಯದಲ್ಲಿ ಟೇಬಲ್‌ನಲ್ಲಿ ಎಷ್ಟು ಬದಲಾವಣೆಗಳು ಸಂಗ್ರಹಗೊಳ್ಳುತ್ತವೆ ಎಂಬುದರ ಮೇಲೆ ಹೊಸದೊಂದರ ಅವಧಿಯು ಅವಲಂಬಿತವಾಗಿರುತ್ತದೆ, ಅಂದರೆ. ಹೊರೆಯ ತೀವ್ರತೆಯ ಮೇಲೆ. ಕನಿಷ್ಠ ಸೇವಾ ಲೋಡ್ ಸಮಯದಲ್ಲಿ pg_repack ರನ್ ಸಂಭವಿಸಿದೆ ಮತ್ತು ಟೇಬಲ್‌ನ ಮೂಲ ಗಾತ್ರಕ್ಕೆ ಹೋಲಿಸಿದರೆ ಬದಲಾವಣೆಗಳ ಪ್ರಮಾಣವು ಅಸಮಾನವಾಗಿ ಚಿಕ್ಕದಾಗಿದೆ. ಹೊಸ ವಹಿವಾಟಿನ ಸಮಯವನ್ನು ನಾವು ನಿರ್ಲಕ್ಷಿಸಬಹುದೆಂದು ನಾವು ನಿರ್ಧರಿಸಿದ್ದೇವೆ (ಹೋಲಿಕೆಗಾಗಿ, ಸರಾಸರಿ ಇದು 1 ಗಂಟೆ ಮತ್ತು 2-3 ನಿಮಿಷಗಳು).

ಪ್ರಯೋಗಗಳು ಸಕಾರಾತ್ಮಕವಾಗಿವೆ. ಉತ್ಪಾದನೆಯಲ್ಲೂ ಪ್ರಾರಂಭಿಸಿ. ಸ್ಪಷ್ಟತೆಗಾಗಿ, ಚಾಲನೆಯ ನಂತರ ಡೇಟಾಬೇಸ್‌ಗಳಲ್ಲಿ ಒಂದರ ಗಾತ್ರವನ್ನು ಹೊಂದಿರುವ ಚಿತ್ರ ಇಲ್ಲಿದೆ:

ಪೋಸ್ಟ್‌ಗ್ರೆಸ್: ಉಬ್ಬುವುದು, pg_repack ಮತ್ತು ಮುಂದೂಡಲ್ಪಟ್ಟ ನಿರ್ಬಂಧಗಳು

ಈ ಪರಿಹಾರದೊಂದಿಗೆ ನಾವು ಸಂಪೂರ್ಣವಾಗಿ ತೃಪ್ತರಾಗಿರುವುದರಿಂದ, ನಾವು ಎರಡನೆಯದನ್ನು ಕಾರ್ಯಗತಗೊಳಿಸಲು ಪ್ರಯತ್ನಿಸಲಿಲ್ಲ, ಆದರೆ ವಿಸ್ತರಣೆಯ ಡೆವಲಪರ್‌ಗಳೊಂದಿಗೆ ಚರ್ಚಿಸುವ ಸಾಧ್ಯತೆಯನ್ನು ನಾವು ಪರಿಗಣಿಸುತ್ತಿದ್ದೇವೆ. ನಮ್ಮ ಪ್ರಸ್ತುತ ಪರಿಷ್ಕರಣೆ, ದುರದೃಷ್ಟವಶಾತ್, ಪ್ರಕಟಣೆಗೆ ಇನ್ನೂ ಸಿದ್ಧವಾಗಿಲ್ಲ, ಏಕೆಂದರೆ ನಾವು ಅನನ್ಯ ಮುಂದೂಡಲ್ಪಟ್ಟ ನಿರ್ಬಂಧಗಳೊಂದಿಗೆ ಮಾತ್ರ ಸಮಸ್ಯೆಯನ್ನು ಪರಿಹರಿಸಿದ್ದೇವೆ ಮತ್ತು ಪೂರ್ಣ ಪ್ರಮಾಣದ ಪ್ಯಾಚ್‌ಗಾಗಿ ಇತರ ಪ್ರಕಾರಗಳಿಗೆ ಬೆಂಬಲವನ್ನು ಒದಗಿಸುವುದು ಅವಶ್ಯಕ. ಭವಿಷ್ಯದಲ್ಲಿ ಇದನ್ನು ಮಾಡಲು ಸಾಧ್ಯವಾಗುತ್ತದೆ ಎಂದು ನಾವು ಭಾವಿಸುತ್ತೇವೆ.

ಬಹುಶಃ ನಿಮಗೆ ಒಂದು ಪ್ರಶ್ನೆ ಇದೆ, ನಾವು pg_repack ನ ಮಾರ್ಪಾಡಿನೊಂದಿಗೆ ಈ ಕಥೆಯಲ್ಲಿ ಏಕೆ ತೊಡಗಿಸಿಕೊಂಡಿದ್ದೇವೆ ಮತ್ತು ಉದಾಹರಣೆಗೆ, ಅದರ ಸಾದೃಶ್ಯಗಳನ್ನು ಬಳಸಲಿಲ್ಲವೇ? ಕೆಲವು ಹಂತದಲ್ಲಿ ನಾವು ಸಹ ಈ ಬಗ್ಗೆ ಯೋಚಿಸಿದ್ದೇವೆ, ಆದರೆ ಮುಂದೂಡಲ್ಪಟ್ಟ ನಿರ್ಬಂಧಗಳಿಲ್ಲದ ಕೋಷ್ಟಕಗಳಲ್ಲಿ ಅದನ್ನು ಮೊದಲು ಬಳಸಿದ ಸಕಾರಾತ್ಮಕ ಅನುಭವವು ಸಮಸ್ಯೆಯ ಸಾರವನ್ನು ಅರ್ಥಮಾಡಿಕೊಳ್ಳಲು ಮತ್ತು ಅದನ್ನು ಸರಿಪಡಿಸಲು ಪ್ರಯತ್ನಿಸಲು ನಮ್ಮನ್ನು ಪ್ರೇರೇಪಿಸಿತು. ಹೆಚ್ಚುವರಿಯಾಗಿ, ಇತರ ಪರಿಹಾರಗಳನ್ನು ಬಳಸುವುದರಿಂದ ಪರೀಕ್ಷೆಗಳನ್ನು ನಡೆಸಲು ಸಮಯ ಬೇಕಾಗುತ್ತದೆ, ಆದ್ದರಿಂದ ನಾವು ಮೊದಲು ಅದರಲ್ಲಿ ಸಮಸ್ಯೆಯನ್ನು ಪರಿಹರಿಸಲು ಪ್ರಯತ್ನಿಸುತ್ತೇವೆ ಎಂದು ನಾವು ನಿರ್ಧರಿಸಿದ್ದೇವೆ ಮತ್ತು ನಾವು ಇದನ್ನು ಸಮಂಜಸವಾದ ಸಮಯದಲ್ಲಿ ಮಾಡಲು ಸಾಧ್ಯವಿಲ್ಲ ಎಂದು ನಾವು ಅರಿತುಕೊಂಡರೆ, ನಾವು ಅನಲಾಗ್‌ಗಳನ್ನು ನೋಡಲು ಪ್ರಾರಂಭಿಸುತ್ತೇವೆ .

ಸಂಶೋಧನೆಗಳು

ನಮ್ಮ ಸ್ವಂತ ಅನುಭವದ ಆಧಾರದ ಮೇಲೆ ನಾವು ಏನು ಶಿಫಾರಸು ಮಾಡಬಹುದು:

  1. ನಿಮ್ಮ ಉಬ್ಬುವಿಕೆಯನ್ನು ಮೇಲ್ವಿಚಾರಣೆ ಮಾಡಿ. ಮಾನಿಟರಿಂಗ್ ಡೇಟಾವನ್ನು ಆಧರಿಸಿ, ಆಟೋವಾಕ್ಯೂಮ್ ಅನ್ನು ಎಷ್ಟು ಚೆನ್ನಾಗಿ ಕಾನ್ಫಿಗರ್ ಮಾಡಲಾಗಿದೆ ಎಂಬುದನ್ನು ನೀವು ಅರ್ಥಮಾಡಿಕೊಳ್ಳಬಹುದು.
  2. ಉಬ್ಬುವಿಕೆಯನ್ನು ಸ್ವೀಕಾರಾರ್ಹ ಮಟ್ಟದಲ್ಲಿ ಇರಿಸಿಕೊಳ್ಳಲು AUTOVACUM ಅನ್ನು ಹೊಂದಿಸಿ.
  3. ಉಬ್ಬುವುದು ಇನ್ನೂ ಬೆಳೆಯುತ್ತಿದ್ದರೆ ಮತ್ತು ಪೆಟ್ಟಿಗೆಯ ಹೊರಗಿನ ಉಪಕರಣಗಳನ್ನು ಬಳಸಿಕೊಂಡು ನೀವು ಅದನ್ನು ಜಯಿಸಲು ಸಾಧ್ಯವಾಗದಿದ್ದರೆ, ಬಾಹ್ಯ ವಿಸ್ತರಣೆಗಳನ್ನು ಬಳಸಲು ಹಿಂಜರಿಯದಿರಿ. ಎಲ್ಲವನ್ನೂ ಚೆನ್ನಾಗಿ ಪರೀಕ್ಷಿಸುವುದು ಮುಖ್ಯ ವಿಷಯ.
  4. ನಿಮ್ಮ ಅಗತ್ಯಗಳಿಗೆ ಸರಿಹೊಂದುವಂತೆ ಬಾಹ್ಯ ಪರಿಹಾರಗಳನ್ನು ಮಾರ್ಪಡಿಸಲು ಹಿಂಜರಿಯದಿರಿ - ಕೆಲವೊಮ್ಮೆ ಇದು ನಿಮ್ಮ ಸ್ವಂತ ಕೋಡ್ ಅನ್ನು ಬದಲಾಯಿಸುವುದಕ್ಕಿಂತ ಹೆಚ್ಚು ಪರಿಣಾಮಕಾರಿ ಮತ್ತು ಸುಲಭವಾಗಿರುತ್ತದೆ.

ಮೂಲ: www.habr.com

ಕಾಮೆಂಟ್ ಅನ್ನು ಸೇರಿಸಿ