MySQL ನಲ್ಲಿ 300 ಮಿಲಿಯನ್ ದಾಖಲೆಗಳನ್ನು ಭೌತಿಕವಾಗಿ ಅಳಿಸುವ ಕಥೆ

ಪರಿಚಯ

ನಮಸ್ಕಾರ. ನಾನು ningenMe, ವೆಬ್ ಡೆವಲಪರ್.

ಶೀರ್ಷಿಕೆ ಹೇಳುವಂತೆ, ನನ್ನ ಕಥೆಯು MySQL ನಲ್ಲಿ 300 ಮಿಲಿಯನ್ ದಾಖಲೆಗಳನ್ನು ಭೌತಿಕವಾಗಿ ಅಳಿಸುವ ಕಥೆಯಾಗಿದೆ.

ನಾನು ಇದರಲ್ಲಿ ಆಸಕ್ತಿ ಹೊಂದಿದ್ದೇನೆ, ಆದ್ದರಿಂದ ನಾನು ಜ್ಞಾಪನೆ (ಸೂಚನೆಗಳು) ಮಾಡಲು ನಿರ್ಧರಿಸಿದೆ.

ಮನೆ - ಎಚ್ಚರಿಕೆ

ನಾನು ಬಳಸುವ ಮತ್ತು ನಿರ್ವಹಿಸುವ ಬ್ಯಾಚ್ ಸರ್ವರ್ ದಿನಕ್ಕೆ ಒಮ್ಮೆ MySQL ನಿಂದ ಕಳೆದ ತಿಂಗಳ ಡೇಟಾವನ್ನು ಸಂಗ್ರಹಿಸುವ ನಿಯಮಿತ ಪ್ರಕ್ರಿಯೆಯನ್ನು ಹೊಂದಿದೆ.

ಸಾಮಾನ್ಯವಾಗಿ ಈ ಪ್ರಕ್ರಿಯೆಯು ಸುಮಾರು 1 ಗಂಟೆಯೊಳಗೆ ಪೂರ್ಣಗೊಳ್ಳುತ್ತದೆ, ಆದರೆ ಈ ಬಾರಿ ಅದು 7 ಅಥವಾ 8 ಗಂಟೆಗಳವರೆಗೆ ಪೂರ್ಣಗೊಳ್ಳಲಿಲ್ಲ ಮತ್ತು ಎಚ್ಚರಿಕೆಯು ಪಾಪ್ ಅಪ್ ಆಗುವುದನ್ನು ನಿಲ್ಲಿಸಲಿಲ್ಲ...

ಕಾರಣ ಹುಡುಕುತ್ತಿದ್ದೇನೆ

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

hoge_table | 350'000'000 |

350 ಮಿಲಿಯನ್ ದಾಖಲೆಗಳು. ಇಂಡೆಕ್ಸಿಂಗ್ ಸರಿಯಾಗಿ ಕೆಲಸ ಮಾಡುತ್ತಿರುವಂತೆ ತೋರುತ್ತಿದೆ, ತುಂಬಾ ನಿಧಾನವಾಗಿದೆ.

ತಿಂಗಳಿಗೆ ಅಗತ್ಯವಿರುವ ಡೇಟಾ ಸಂಗ್ರಹಣೆಯು ಸರಿಸುಮಾರು 12 ದಾಖಲೆಗಳು. ಆಯ್ಕೆಮಾಡಿದ ಆಜ್ಞೆಯು ಬಹಳ ಸಮಯ ತೆಗೆದುಕೊಂಡಂತೆ ತೋರುತ್ತಿದೆ ಮತ್ತು ವಹಿವಾಟನ್ನು ದೀರ್ಘಕಾಲದವರೆಗೆ ಕಾರ್ಯಗತಗೊಳಿಸಲಾಗಿಲ್ಲ.

DB

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

ಈ ಡೇಟಾಬೇಸ್ ಅನ್ನು ನಾನು ಅಭಿವೃದ್ಧಿಪಡಿಸಿಲ್ಲ. ನಾನು ಅದನ್ನು ಇನ್ನೊಬ್ಬ ಡೆವಲಪರ್‌ನಿಂದ ತೆಗೆದುಕೊಂಡಿದ್ದೇನೆ, ಹಾಗಾಗಿ ಅದು ಇನ್ನೂ ತಾಂತ್ರಿಕ ಸಾಲದಂತೆ ಭಾಸವಾಯಿತು.

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

ತದನಂತರ ನಾನು ಕಾರ್ಯರೂಪಕ್ಕೆ ಬಂದೆ.

ತಿದ್ದುಪಡಿ

ಡೇಟಾಬೇಸ್‌ನ ಗಾತ್ರವನ್ನು ಕಡಿಮೆ ಮಾಡುವುದು ಮತ್ತು ತರ್ಕವನ್ನು ಬದಲಾಯಿಸುವುದಕ್ಕಿಂತ ಅದನ್ನು ಪ್ರಕ್ರಿಯೆಗೊಳಿಸಲು ಸಮಯವನ್ನು ಕಡಿಮೆ ಮಾಡುವುದು ಹೆಚ್ಚು ತರ್ಕಬದ್ಧವಾಗಿದೆ.

ನೀವು 300 ಮಿಲಿಯನ್ ದಾಖಲೆಗಳನ್ನು ಅಳಿಸಿದರೆ ಪರಿಸ್ಥಿತಿಯು ಗಮನಾರ್ಹವಾಗಿ ಬದಲಾಗಬೇಕು, ಹಾಗಾಗಿ ನಾನು ಹಾಗೆ ಮಾಡಲು ನಿರ್ಧರಿಸಿದೆ ... ಓಹ್, ಇದು ಖಂಡಿತವಾಗಿಯೂ ಕೆಲಸ ಮಾಡುತ್ತದೆ ಎಂದು ನಾನು ಭಾವಿಸಿದೆ.

ಕ್ರಿಯೆ 1

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

"ವಿನಂತಿಯನ್ನು ಕಳುಹಿಸಲಾಗುತ್ತಿದೆ"

DELETE FROM hoge_table WHERE create_time <= 'YYYY-MM-DD HH:MM:SS';

"..."

"..."

“ಹೂಂ... ಉತ್ತರವಿಲ್ಲ. ಬಹುಶಃ ಪ್ರಕ್ರಿಯೆಯು ಬಹಳ ಸಮಯ ತೆಗೆದುಕೊಳ್ಳುತ್ತದೆಯೇ?" - ನಾನು ಯೋಚಿಸಿದೆ, ಆದರೆ ಒಂದು ವೇಳೆ, ನಾನು ಗ್ರಾಫಾನಾವನ್ನು ನೋಡಿದೆ ಮತ್ತು ಡಿಸ್ಕ್ ಲೋಡ್ ವೇಗವಾಗಿ ಬೆಳೆಯುತ್ತಿದೆ ಎಂದು ನೋಡಿದೆ.
"ಅಪಾಯಕಾರಿ," ನಾನು ಮತ್ತೊಮ್ಮೆ ಯೋಚಿಸಿದೆ ಮತ್ತು ತಕ್ಷಣವೇ ವಿನಂತಿಯನ್ನು ನಿಲ್ಲಿಸಿದೆ.

ಕ್ರಿಯೆ 2

ಎಲ್ಲವನ್ನೂ ವಿಶ್ಲೇಷಿಸಿದ ನಂತರ, ಡೇಟಾದ ಪರಿಮಾಣವು ಎಲ್ಲವನ್ನೂ ಒಂದೇ ಬಾರಿಗೆ ಅಳಿಸಲು ತುಂಬಾ ದೊಡ್ಡದಾಗಿದೆ ಎಂದು ನಾನು ಅರಿತುಕೊಂಡೆ.

ನಾನು ಸುಮಾರು 1 ದಾಖಲೆಗಳನ್ನು ಅಳಿಸಬಹುದಾದ ಸ್ಕ್ರಿಪ್ಟ್ ಬರೆಯಲು ನಿರ್ಧರಿಸಿದೆ ಮತ್ತು ಅದನ್ನು ಪ್ರಾರಂಭಿಸಿದೆ.

"ನಾನು ಸ್ಕ್ರಿಪ್ಟ್ ಅನ್ನು ಕಾರ್ಯಗತಗೊಳಿಸುತ್ತೇನೆ"

"ಈಗ ಇದು ಖಂಡಿತವಾಗಿಯೂ ಕೆಲಸ ಮಾಡುತ್ತದೆ," ನಾನು ಯೋಚಿಸಿದೆ.

ಕ್ರಿಯೆ 3

ಎರಡನೆಯ ವಿಧಾನವು ಕೆಲಸ ಮಾಡಿದೆ, ಆದರೆ ಬಹಳ ಕಾರ್ಮಿಕ-ತೀವ್ರವಾಗಿದೆ.
ಎಲ್ಲವನ್ನೂ ಎಚ್ಚರಿಕೆಯಿಂದ ಮಾಡಲು, ಅನಗತ್ಯ ನರಗಳಿಲ್ಲದೆ, ಸುಮಾರು ಎರಡು ವಾರಗಳನ್ನು ತೆಗೆದುಕೊಳ್ಳುತ್ತದೆ. ಆದರೆ ಇನ್ನೂ, ಈ ಸನ್ನಿವೇಶವು ಸೇವಾ ಅವಶ್ಯಕತೆಗಳನ್ನು ಪೂರೈಸಲಿಲ್ಲ, ಆದ್ದರಿಂದ ನಾವು ಅದರಿಂದ ದೂರ ಹೋಗಬೇಕಾಯಿತು.

ಹಾಗಾಗಿ ನಾನು ಮಾಡಲು ನಿರ್ಧರಿಸಿದ್ದು ಇಲ್ಲಿದೆ:

ಟೇಬಲ್ ಅನ್ನು ನಕಲಿಸಿ ಮತ್ತು ಅದನ್ನು ಮರುಹೆಸರಿಸಿ

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

| hoge_table     | 350'000'000|
| tmp_hoge_table |  50'000'000|

ನೀವು ಹೊಸ ಕೋಷ್ಟಕವನ್ನು ಮೇಲಿನ ಗಾತ್ರದಂತೆಯೇ ಮಾಡಿದರೆ, ಡೇಟಾ ಪ್ರಕ್ರಿಯೆಯ ವೇಗವು 1/7 ವೇಗವಾಗಿರುತ್ತದೆ.

ಟೇಬಲ್ ಅನ್ನು ರಚಿಸಿದ ನಂತರ ಮತ್ತು ಅದನ್ನು ಮರುಹೆಸರಿಸಿದ ನಂತರ, ನಾನು ಅದನ್ನು ಮಾಸ್ಟರ್ ಟೇಬಲ್ ಆಗಿ ಬಳಸಲು ಪ್ರಾರಂಭಿಸಿದೆ. ಈಗ ನಾನು 300 ಮಿಲಿಯನ್ ದಾಖಲೆಗಳೊಂದಿಗೆ ಟೇಬಲ್ ಅನ್ನು ಬಿಟ್ಟರೆ ಎಲ್ಲವೂ ಸರಿಯಾಗಿರಬೇಕು.
ಮೊಟಕುಗೊಳಿಸುವಿಕೆ ಅಥವಾ ಡ್ರಾಪ್ ಅಳಿಸುವುದಕ್ಕಿಂತ ಕಡಿಮೆ ಓವರ್ಹೆಡ್ ಅನ್ನು ರಚಿಸುತ್ತದೆ ಎಂದು ನಾನು ಕಂಡುಕೊಂಡಿದ್ದೇನೆ ಮತ್ತು ಈ ವಿಧಾನವನ್ನು ಬಳಸಲು ನಿರ್ಧರಿಸಿದೆ.

ಪ್ರದರ್ಶನ

"ವಿನಂತಿಯನ್ನು ಕಳುಹಿಸಲಾಗುತ್ತಿದೆ"

INSERT INTO tmp_hoge_table SELECT FROM hoge_table create_time > 'YYYY-MM-DD HH:MM:SS';

"..."
"..."
"ಎಂ...?"

ಕ್ರಿಯೆ 4

ಹಿಂದಿನ ಕಲ್ಪನೆಯು ಕೆಲಸ ಮಾಡುತ್ತದೆ ಎಂದು ನಾನು ಭಾವಿಸಿದೆವು, ಆದರೆ ಇನ್ಸರ್ಟ್ ವಿನಂತಿಯನ್ನು ಕಳುಹಿಸಿದ ನಂತರ, ಬಹು ದೋಷಗಳು ಕಾಣಿಸಿಕೊಂಡವು. MySQL ಕ್ಷಮಿಸುವುದಿಲ್ಲ.

ನಾನು ಈಗಾಗಲೇ ತುಂಬಾ ದಣಿದಿದ್ದೆ, ನಾನು ಇನ್ನು ಮುಂದೆ ಇದನ್ನು ಮಾಡಲು ಬಯಸುವುದಿಲ್ಲ ಎಂದು ಯೋಚಿಸಲು ಪ್ರಾರಂಭಿಸಿದೆ.

ನಾನು ಕುಳಿತು ಯೋಚಿಸಿದೆ ಮತ್ತು ಒಂದು ಬಾರಿಗೆ ಹಲವಾರು ಇನ್ಸರ್ಟ್ ಪ್ರಶ್ನೆಗಳು ಇರಬಹುದು ಎಂದು ಅರಿತುಕೊಂಡೆ...
ಡೇಟಾಬೇಸ್ 1 ದಿನದಲ್ಲಿ ಪ್ರಕ್ರಿಯೆಗೊಳಿಸಬೇಕಾದ ಡೇಟಾದ ಮೊತ್ತಕ್ಕೆ ಇನ್ಸರ್ಟ್ ವಿನಂತಿಯನ್ನು ಕಳುಹಿಸಲು ನಾನು ಪ್ರಯತ್ನಿಸಿದೆ. ಸಂಭವಿಸಿದ!

ಸರಿ, ಅದರ ನಂತರ ನಾವು ಅದೇ ಪ್ರಮಾಣದ ಡೇಟಾಕ್ಕಾಗಿ ವಿನಂತಿಗಳನ್ನು ಕಳುಹಿಸುವುದನ್ನು ಮುಂದುವರಿಸುತ್ತೇವೆ. ನಾವು ಒಂದು ತಿಂಗಳ ಮೌಲ್ಯದ ಡೇಟಾವನ್ನು ತೆಗೆದುಹಾಕಬೇಕಾಗಿರುವುದರಿಂದ, ನಾವು ಈ ಕಾರ್ಯಾಚರಣೆಯನ್ನು ಸರಿಸುಮಾರು 35 ಬಾರಿ ಪುನರಾವರ್ತಿಸುತ್ತೇವೆ.

ಟೇಬಲ್ ಅನ್ನು ಮರುಹೆಸರಿಸುವುದು

ಇಲ್ಲಿ ಅದೃಷ್ಟ ನನ್ನ ಕಡೆ ಇತ್ತು: ಎಲ್ಲವೂ ಸುಗಮವಾಗಿ ನಡೆಯಿತು.

ಎಚ್ಚರಿಕೆಯು ಕಾಣೆಯಾಗಿದೆ

ಬ್ಯಾಚ್ ಪ್ರಕ್ರಿಯೆಯ ವೇಗ ಹೆಚ್ಚಾಗಿದೆ.

ಹಿಂದೆ ಈ ಪ್ರಕ್ರಿಯೆಯು ಸುಮಾರು ಒಂದು ಗಂಟೆ ತೆಗೆದುಕೊಳ್ಳುತ್ತದೆ, ಈಗ ಇದು ಸುಮಾರು 2 ನಿಮಿಷಗಳನ್ನು ತೆಗೆದುಕೊಳ್ಳುತ್ತದೆ.

ಎಲ್ಲಾ ಸಮಸ್ಯೆಗಳನ್ನು ಪರಿಹರಿಸಲಾಗಿದೆ ಎಂದು ನನಗೆ ಖಚಿತವಾದ ನಂತರ, ನಾನು 300 ಮಿಲಿಯನ್ ದಾಖಲೆಗಳನ್ನು ಕೈಬಿಟ್ಟೆ. ನಾನು ಟೇಬಲ್ ಅನ್ನು ಅಳಿಸಿದೆ ಮತ್ತು ಮರುಜನ್ಮವನ್ನು ಅನುಭವಿಸಿದೆ.

ಸಾರಾಂಶ

ಬ್ಯಾಚ್ ಪ್ರಕ್ರಿಯೆಯಲ್ಲಿ ತಿರುಗುವಿಕೆಯ ಪ್ರಕ್ರಿಯೆಯು ಕಾಣೆಯಾಗಿದೆ ಎಂದು ನಾನು ಅರಿತುಕೊಂಡೆ ಮತ್ತು ಅದು ಮುಖ್ಯ ಸಮಸ್ಯೆಯಾಗಿದೆ. ಈ ರೀತಿಯ ವಾಸ್ತು ದೋಷವು ಸಮಯ ವ್ಯರ್ಥಕ್ಕೆ ಕಾರಣವಾಗುತ್ತದೆ.

ಡೇಟಾಬೇಸ್‌ನಿಂದ ದಾಖಲೆಗಳನ್ನು ಅಳಿಸುವಾಗ ಡೇಟಾ ಪುನರಾವರ್ತನೆಯ ಸಮಯದಲ್ಲಿ ಲೋಡ್ ಬಗ್ಗೆ ನೀವು ಯೋಚಿಸುತ್ತೀರಾ? MySQL ಅನ್ನು ಓವರ್‌ಲೋಡ್ ಮಾಡಬೇಡಿ.

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

ಓದಿದ್ದಕ್ಕಾಗಿ ಧನ್ಯವಾದಗಳು!

ನೀವು ಈ ಲೇಖನವನ್ನು ಇಷ್ಟಪಟ್ಟಿದ್ದೀರಾ, ಅನುವಾದವು ಸ್ಪಷ್ಟವಾಗಿದೆಯೇ, ಅದು ನಿಮಗೆ ಉಪಯುಕ್ತವಾಗಿದೆಯೇ ಎಂದು ನೀವು ನಮಗೆ ಹೇಳಿದರೆ ನಮಗೆ ತುಂಬಾ ಸಂತೋಷವಾಗುತ್ತದೆ.

ಮೂಲ: www.habr.com

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