අසාර්ථක වීමෙන් පසු Postgres දත්ත සමුදායක් ප්‍රතිසාධනය කිරීමේ මගේ පළමු අත්දැකීම (relatton base/4123007 බ්ලොක් 16490 හි අවලංගු පිටුව)

Postgres දත්ත සමුදායක් සම්පූර්ණ ක්‍රියාකාරීත්වයට ප්‍රතිස්ථාපනය කිරීමේ මගේ පළමු සාර්ථක අත්දැකීම ඔබ සමඟ බෙදා ගැනීමට මම කැමැත්තෙමි. මම මීට වසරකට භාගයකට පෙර Postgres DBMS සමඟ දැන හඳුනා ගත්තෙමි; ඊට පෙර මට දත්ත සමුදා පරිපාලනය පිළිබඳ කිසිදු අත්දැකීමක් නොතිබුණි.

අසාර්ථක වීමෙන් පසු Postgres දත්ත සමුදායක් ප්‍රතිසාධනය කිරීමේ මගේ පළමු අත්දැකීම (relatton base/4123007 බ්ලොක් 16490 හි අවලංගු පිටුව)

මම විශාල තොරතුරු තාක්ෂණ සමාගමක අර්ධ DevOps ඉංජිනේරුවෙකු ලෙස සේවය කරමි. අපගේ සමාගම අධි බර සේවා සඳහා මෘදුකාංග සංවර්ධනය කරන අතර, කාර්ය සාධනය, නඩත්තු කිරීම සහ යෙදවීම සඳහා මම වගකිව යුතුය. මට සම්මත කාර්යයක් ලබා දී ඇත: එක් සේවාදායකයක යෙදුමක් යාවත්කාලීන කිරීමට. යෙදුම ලියා ඇත්තේ ජැන්ගෝ භාෂාවෙන්, යාවත්කාලීන කිරීමේදී සංක්‍රමණයන් සිදු කරනු ලැබේ (දත්ත සමුදා ව්‍යුහයේ වෙනස්කම්), සහ මෙම ක්‍රියාවලියට පෙර අපි සම්මත pg_dump වැඩසටහන හරහා සම්පූර්ණ දත්ත සමුදා ඩම්ප් එකක් ගනිමු.

ඩම්ප් එකක් ගන්නා අතරතුර අනපේක්ෂිත දෝෂයක් සිදු විය (Postgres අනුවාදය 9.5):

pg_dump: Oumping the contents of table “ws_log_smevlog” failed: PQgetResult() failed.
pg_dump: Error message from server: ERROR: invalid page in block 4123007 of relatton base/16490/21396989
pg_dump: The command was: COPY public.ws_log_smevlog [...]
pg_dunp: [parallel archtver] a worker process dled unexpectedly

දෝෂයක් "බ්ලොක් එකේ වලංගු නොවන පිටුවක්" ගොනු පද්ධති මට්ටමේ ගැටළු ගැන කතා කරයි, එය ඉතා නරක ය. විවිධ සංසදවලදී එය කිරීමට යෝජනා කරන ලදී සම්පූර්ණ රික්තකය විකල්පය සමඟ zero_damaged_pages මෙම ගැටලුව විසඳීමට. හොඳයි, අපි උත්සාහ කරමු ...

ප්රකෘතිමත් වීම සඳහා සූදානම් වීම

අවධානය! ඔබගේ දත්ත සමුදාය ප්‍රතිසාධන කිරීමට උත්සාහ කිරීමට පෙර Postgres උපස්ථයක් ගැනීමට වග බලා ගන්න. ඔබට අතථ්‍ය යන්ත්‍රයක් තිබේ නම්, දත්ත සමුදාය නවතා ස්නැප්ෂොට් එකක් ගන්න. ස්නැප්ෂොට් එකක් ගැනීමට නොහැකි නම්, දත්ත සමුදාය නවතා Postgres බහලුමේ අන්තර්ගතය (wal files ඇතුළුව) ආරක්ෂිත ස්ථානයකට පිටපත් කරන්න. අපගේ ව්‍යාපාරයේ ප්‍රධානතම දෙය වන්නේ දේවල් නරක අතට හැරීම නොවේ. කියවන්න එය.

දත්ත සමුදාය සාමාන්‍යයෙන් මා වෙනුවෙන් ක්‍රියා කළ බැවින්, මම සාමාන්‍ය දත්ත සමුදා ඩම්ප් එකකට සීමා වූ නමුත් හානියට පත් දත්ත සහිත වගුව බැහැර කළෙමි (විකල්පය -T, --exclude-table=TABLE pg_dump තුළ).

සේවාදායකය භෞතික විය, එය ස්නැප්ෂොට් එකක් ගැනීමට නොහැකි විය. උපස්ථය ඉවත් කර ඇත, අපි ඉදිරියට යමු.

ගොනු පද්ධතිය පරීක්ෂා කිරීම

දත්ත සමුදාය ප්‍රතිස්ථාපනය කිරීමට උත්සාහ කිරීමට පෙර, ගොනු පද්ධතිය සමඟම සියල්ල පිළිවෙලට ඇති බවට අපි සහතික විය යුතුය. වැරදි වලදී, ඒවා නිවැරදි කරන්න, එසේ නොමැතිනම් ඔබට කළ හැක්කේ දේවල් නරක අතට හැරීම පමණි.

මගේ නඩුවේදී, දත්ත සමුදාය සමඟ ගොනු පද්ධතිය සවි කර ඇත "/srv" සහ වර්ගය ext4 විය.

දත්ත සමුදාය නතර කිරීම: systemctl නැවතුම [විද්‍යුත් ආරක්‍ෂිත] සහ ගොනු පද්ධතිය කිසිවකු විසින් භාවිතා නොකරන බව සහ විධානය භාවිතයෙන් ඉවත් කළ හැකිදැයි පරීක්ෂා කරන්න lsof:
lsof +D / srv

රෙඩිස් දත්ත සමුදාය ද භාවිතා කරන බැවින් මට එය නතර කිරීමට සිදු විය "/srv". ඊළඟට මම සවි කළා / srv (උමවුන්ට්).

ගොනු පද්ධතිය උපයෝගීතාව භාවිතයෙන් පරීක්ෂා කරන ලදී e2fsck ස්විචය සමඟ -f (ගොනු පද්ධතිය පිරිසිදු ලෙස සලකුණු කර තිබුණත් බලහත්කාරයෙන් පරීක්ෂා කරන්න):

අසාර්ථක වීමෙන් පසු Postgres දත්ත සමුදායක් ප්‍රතිසාධනය කිරීමේ මගේ පළමු අත්දැකීම (relatton base/4123007 බ්ලොක් 16490 හි අවලංගු පිටුව)

ඊළඟට, උපයෝගීතාව භාවිතා කිරීම dumpe2fs (sudo dumpe2fs /dev/mapper/gu2—sys-srv | grep පරීක්ෂා කර ඇත) චෙක්පත ඇත්ත වශයෙන්ම සිදු කර ඇති බව ඔබට තහවුරු කර ගත හැක:

අසාර්ථක වීමෙන් පසු Postgres දත්ත සමුදායක් ප්‍රතිසාධනය කිරීමේ මගේ පළමු අත්දැකීම (relatton base/4123007 බ්ලොක් 16490 හි අවලංගු පිටුව)

e2fsck ext4 ගොනු පද්ධති මට්ටමේ කිසිදු ගැටළුවක් හමු නොවූ බව පවසයි, එයින් අදහස් කරන්නේ ඔබට දත්ත සමුදාය ප්‍රතිසාධනය කිරීමට දිගටම උත්සාහ කළ හැකි බවයි, නැතහොත් ඒ වෙනුවට ආපසු රික්තය පිරී ඇත (ඇත්ත වශයෙන්ම, ඔබ ගොනු පද්ධතිය නැවත සවි කර දත්ත සමුදාය ආරම්භ කළ යුතුය).

ඔබට භෞතික සේවාදායකයක් තිබේ නම්, තැටිවල තත්ත්වය පරීක්ෂා කිරීමට වග බලා ගන්න ( හරහා smartctl -a /dev/XXX) හෝ RAID පාලකය ගැටළුව දෘඪාංග මට්ටමේ නොමැති බව තහවුරු කර ගන්න. මගේ නඩුවේදී, RAID "දෘඪාංග" බවට පත් විය, එබැවින් මම RAID හි තත්ත්වය පරීක්ෂා කරන ලෙස ප්රාදේශීය පරිපාලකගෙන් ඉල්ලා සිටියෙමි (සේවාදායකය මගෙන් කිලෝමීටර සිය ගණනක් දුරින්). ඔහු පැවසුවේ කිසිදු දෝෂයක් නොමැති බවත්, එයින් අදහස් කරන්නේ අපට අනිවාර්යයෙන්ම ප්‍රතිසංස්කරණය ආරම්භ කළ හැකි බවයි.

උත්සාහය 1: zero_damaged_pages

අපි සුපිරි පරිශීලක අයිතිවාසිකම් ඇති ගිණුමක් සමඟ psql හරහා දත්ත සමුදායට සම්බන්ධ කරමු. අපට සුපිරි පරිශීලකයෙකු අවශ්‍යයි, මන්ද ... විකල්පය zero_damaged_pages වෙනස් කළ හැක්කේ ඔහුට පමණි. මගේ නඩුවේ එය postgres වේ:

psql -h 127.0.0.1 -U postgres -s [database_name]

විකල්පය zero_damaged_pages කියවීමේ දෝෂ නොසලකා හැරීම සඳහා අවශ්‍ය වේ (postgrespro වෙබ් අඩවියෙන්):

PostgreSQL විසින් දූෂිත පිටු ශීර්ෂයක් අනාවරණය කරගත් විට, එය සාමාන්‍යයෙන් දෝෂයක් වාර්තා කර වත්මන් ගනුදෙනුව නවත්වයි. zero_damaged_pages සක්‍රීය කර ඇත්නම්, පද්ධතිය ඒ වෙනුවට අනතුරු ඇඟවීමක් නිකුත් කරයි, මතකයේ ඇති හානියට පත් පිටුව ශුන්‍ය කරයි, සහ සැකසීම දිගටම කරගෙන යයි. මෙම හැසිරීම දත්ත විනාශ කරයි, එනම් හානියට පත් පිටුවේ ඇති සියලුම පේළි.

අපි විකල්පය සක්රිය කර වගු වල සම්පූර්ණ රික්තයක් කිරීමට උත්සාහ කරමු:

VACUUM FULL VERBOSE

අසාර්ථක වීමෙන් පසු Postgres දත්ත සමුදායක් ප්‍රතිසාධනය කිරීමේ මගේ පළමු අත්දැකීම (relatton base/4123007 බ්ලොක් 16490 හි අවලංගු පිටුව)
අවාසනාවකට, අවාසනාව.

අපට සමාන දෝෂයක් හමු විය:

INFO: vacuuming "“public.ws_log_smevlog”
WARNING: invalid page in block 4123007 of relation base/16400/21396989; zeroing out page
ERROR: unexpected chunk number 573 (expected 565) for toast value 21648541 in pg_toast_106070

pg_toast - එය එක් පිටුවකට නොගැලපේ නම් (පෙරනිමියෙන් 8kb) Poetgres හි "දිගු දත්ත" ගබඩා කිරීම සඳහා යාන්ත්රණයක්.

උත්සාහය 2: reindex

ගූගල් වෙතින් පළමු උපදෙස් උදව් කළේ නැත. මිනිත්තු කිහිපයක් සෙවීමෙන් පසු, මට දෙවන ඉඟිය හමු විය - සෑදීමට reindex හානියට පත් මේසය. මම මෙම උපදෙස බොහෝ ස්ථානවල දුටුවෙමි, නමුත් එය විශ්වාසයක් ඇති කළේ නැත. අපි නැවත සුචිගත කරමු:

reindex table ws_log_smevlog

අසාර්ථක වීමෙන් පසු Postgres දත්ත සමුදායක් ප්‍රතිසාධනය කිරීමේ මගේ පළමු අත්දැකීම (relatton base/4123007 බ්ලොක් 16490 හි අවලංගු පිටුව)

reindex ගැටළු නොමැතිව සම්පූර්ණ කර ඇත.

කෙසේ වෙතත්, මෙය උදව් කළේ නැත, රික්තකය සම්පූර්ණයි සමාන දෝෂයක් සමඟ කඩා වැටුණි. මම අසාර්ථකත්වයට පුරුදු වී සිටින බැවින්, මම අන්තර්ජාලයේ උපදෙස් සඳහා තවදුරටත් බැලීමට පටන් ගත් අතර තරමක් සිත්ගන්නාසුලු දෙයක් හමු විය ලිපිය.

උත්සාහය 3: SELECT, LIMIT, OFFSET

ඉහත ලිපියෙන් යෝජනා කළේ වගු පේළිය පේළියෙන් පේළිය දෙස බලා ගැටලුකාරී දත්ත ඉවත් කරන ලෙසයි. මුලින්ම අපි සියලු රේඛා දෙස බැලිය යුතුය:

for ((i=0; i<"Number_of_rows_in_nodes"; i++ )); do psql -U "Username" "Database Name" -c "SELECT * FROM nodes LIMIT 1 offset $i" >/dev/null || echo $i; done

මගේ නඩුවේදී, මේසයේ අඩංගු විය 1 628 991 රේඛා! එය හොඳින් රැකබලා ගැනීමට අවශ්ය විය දත්ත කොටස් කිරීම, නමුත් මෙය වෙනම සාකච්ඡාවක් සඳහා මාතෘකාවකි. එය සෙනසුරාදා විය, මම මෙම විධානය tmux හි ක්‍රියාත්මක කර නින්දට ගියෙමි:

for ((i=0; i<1628991; i++ )); do psql -U my_user -d my_database -c "SELECT * FROM ws_log_smevlog LIMIT 1 offset $i" >/dev/null || echo $i; done

උදේ වෙනකොට මම තීරණය කළා වැඩේ කොහොමද කියලා බලන්න. මා පුදුමයට පත් කරමින්, පැය 20 කට පසු, දත්ත වලින් 2% ක් පමණක් පරිලෝකනය කර ඇති බව මම සොයා ගතිමි! මට දින 50ක් ඉන්න ඕන වුණේ නැහැ. තවත් සම්පූර්ණ අසාර්ථකත්වය.

නමුත් මම අත්හැරියේ නැහැ. ස්කෑන් කිරීම මෙතරම් කාලයක් ගත වූයේ මන්දැයි මම කල්පනා කළෙමි. ලේඛනයෙන් (නැවතත් postgrespro මත) මම සොයා ගත්තේ:

OFFSET මඟින් පේළි ප්‍රතිදානය කිරීම ආරම්භ කිරීමට පෙර නියමිත පේළි ගණන මඟ හැරීමට නියම කරයි.
OFFSET සහ LIMIT යන දෙකම සඳහන් කර ඇත්නම්, පද්ධතිය මුලින්ම OFFSET පේළි මඟහරින අතර පසුව LIMIT සීමාව සඳහා පේළි ගණන් කිරීම ආරම්භ කරයි.

LIMIT භාවිතා කරන විට, ප්‍රතිඵල පේළි නිශ්චිත අනුපිළිවෙලකට ආපසු ලැබෙන පරිදි වගන්තියෙන් නියෝගයක් භාවිතා කිරීම ද වැදගත් වේ. එසේ නොමැති නම්, පේළිවල අනපේක්ෂිත උප කුලක ආපසු ලබා දෙනු ඇත.

පැහැදිලිවම, ඉහත විධානය වැරදියි: පළමුව, නැත විසින් ඇණවුම් කරන්න, ප්රතිඵලය වැරදි විය හැක. දෙවනුව, Postgres හට ප්‍රථමයෙන් OFFSET පේළි පරිලෝකනය කර මග හැරීමට සිදු විය OFFSET ඵලදායිතාව තවත් පහත වැටෙනු ඇත.

උත්සාහය 4: පෙළ ආකාරයෙන් ඩම්ප් එකක් ගන්න

එවිට මගේ මනසට දීප්තිමත් අදහසක් ඇති විය: පෙළ ආකාරයෙන් ඩම්ප් එකක් ගෙන අවසන් පටිගත කළ පේළිය විශ්ලේෂණය කරන්න.

නමුත් පළමුව, අපි මේසයේ ව්යුහය දෙස බලමු. ws_log_smevlog:

අසාර්ථක වීමෙන් පසු Postgres දත්ත සමුදායක් ප්‍රතිසාධනය කිරීමේ මගේ පළමු අත්දැකීම (relatton base/4123007 බ්ලොක් 16490 හි අවලංගු පිටුව)

අපගේ නඩුවේදී අපට තීරුවක් තිබේ "අයිඩී", පේළියේ අනන්‍ය හඳුනාගැනීම් (කවුන්ටරය) අඩංගු විය. සැලැස්ම මේ වගේ විය:

  1. අපි පෙළ ආකාරයෙන් ඩම්ප් එකක් ගැනීමට පටන් ගනිමු (sql විධාන ආකාරයෙන්)
  2. යම් අවස්ථාවක දී, දෝෂයක් හේතුවෙන් ඩම්ප් බාධා කරනු ඇත, නමුත් පෙළ ගොනුව තවමත් තැටියේ සුරැකෙනු ඇත.
  3. අපි පෙළ ගොනුවේ අවසානය දෙස බලමු, එමඟින් සාර්ථකව ඉවත් කරන ලද අවසාන පේළියේ හඳුනාගැනීම (id) සොයා ගන්නෙමු.

මම පෙළ ආකාරයෙන් ඩම්ප් එකක් ගැනීමට පටන් ගතිමි:

pg_dump -U my_user -d my_database -F p -t ws_log_smevlog -f ./my_dump.dump

බලාපොරොත්තු වූ පරිදි ඩම්ප් එකම දෝෂයකින් බාධා විය:

pg_dump: Error message from server: ERROR: invalid page in block 4123007 of relatton base/16490/21396989

තවදුරටත් හරහා වලිගය මම කුණු කන්දේ කෙළවර බැලුවා (වලිගය -5 ./my_dump.dump) හැඳුනුම්පත සහිත රේඛාව මත ඩම්ප් බාධා ඇති බව සොයා ගන්නා ලදී 186 525. "එබැවින් ගැටළුව ඇත්තේ 186 526 හැඳුනුම්පතේ පේළියේය, එය කැඩී ඇති අතර මකා දැමිය යුතුය!" - මම හිතුවා. නමුත්, දත්ත සමුදාය වෙත විමසීමක් කරමින්:
«id=186529 යන තැන ws_log_smevlog වෙතින් * තෝරන්න"මෙම රේඛාව සමඟ සියල්ල හොඳින් ඇති බව පෙනී ගියේය ... දර්ශක 186 - 530 සමඟ පේළි ද ගැටළු නොමැතිව වැඩ කළේය. තවත් "දීප්තිමත් අදහසක්" අසාර්ථක විය. මෙය සිදු වූයේ මන්දැයි පසුව මට වැටහුණි: වගුවකින් දත්ත මකා දැමීමේදී සහ වෙනස් කිරීමේදී, ඒවා භෞතිකව මකා නොදමනු ඇත, නමුත් “මළ ටියුපල්” ලෙස සලකුණු කර ඇත, පසුව පැමිණේ autovacuum සහ මෙම රේඛා මකා දැමූ ලෙස සලකුණු කර මෙම රේඛා නැවත භාවිතා කිරීමට ඉඩ සලසයි. තේරුම් ගැනීම සඳහා, වගුවේ දත්ත වෙනස් වී ස්වයංක්‍රීයව සක්‍රීය කර ඇත්නම්, එය අනුපිළිවෙලින් ගබඩා නොවේ.

උත්සාහය 5: SELECT, FROM, HHERE id=

අසාර්ථකත්වය අපව ශක්තිමත් කරයි. ඔබ කිසි විටෙකත් අත් නොහැරිය යුතුය, ඔබ අවසානය දක්වා ගොස් ඔබ සහ ඔබේ හැකියාවන් විශ්වාස කළ යුතුය. එබැවින් මම වෙනත් විකල්පයක් උත්සාහ කිරීමට තීරණය කළෙමි: දත්ත සමුදායේ ඇති සියලුම වාර්තා එකින් එක බලන්න. මගේ වගුවේ ව්‍යුහය දැන ගැනීම (ඉහත බලන්න), අපට අනන්‍ය වූ (ප්‍රාථමික යතුර) හැඳුනුම්පතක් ඇත. අපි වගුවේ පේළි 1 ක් සහ id ඒවා පිළිවෙලට තිබේ, එයින් අදහස් කරන්නේ අපට ඒවා එකින් එක යා හැකි බවයි:

for ((i=1; i<1628991; i=$((i+1)) )); do psql -U my_user -d my_database  -c "SELECT * FROM ws_log_smevlog where id=$i" >/dev/null || echo $i; done

යමෙකුට නොතේරෙන්නේ නම්, විධානය පහත පරිදි ක්‍රියා කරයි: එය පේළියෙන් පේළිය ස්කෑන් කර stdout වෙත යවයි. / dev / null, නමුත් SELECT විධානය අසමත් වුවහොත්, දෝෂ පෙළ මුද්‍රණය කරනු ලැබේ (stderr කොන්සෝලය වෙත යවනු ලැබේ) සහ දෝෂය අඩංගු රේඛාවක් මුද්‍රණය කරනු ලැබේ (ස්තුතියි ||, එයින් අදහස් වන්නේ තේරීමට ගැටළු ඇති බවයි (විධානයේ ආපසු කේතය 0)) නොවේ.

මම වාසනාවන්තයි, මම ක්ෂේත්රයේ නිර්මාණය කරන ලද දර්ශක තිබුණා id:

අසාර්ථක වීමෙන් පසු Postgres දත්ත සමුදායක් ප්‍රතිසාධනය කිරීමේ මගේ පළමු අත්දැකීම (relatton base/4123007 බ්ලොක් 16490 හි අවලංගු පිටුව)

මෙයින් අදහස් කරන්නේ අපේක්ෂිත හැඳුනුම්පත සමඟ රේඛාවක් සොයා ගැනීමට වැඩි කාලයක් ගත නොවිය යුතු බවයි. න්යායාත්මකව එය ක්රියා කළ යුතුය. හොඳයි, අපි විධානය ක්‍රියාත්මක කරමු tmux හා අපි නිදාගමු.

උදෑසන වන විට, ඇතුළත් කිරීම් 90 ක් පමණ නරඹා ඇති බව මට පෙනී ගියේය, එය 000% කට වඩා වැඩි ය. පෙර ක්‍රමය (5%) හා සසඳන විට විශිෂ්ට ප්‍රතිඵලයක්! ඒත් මට දවස් 2ක් ඉන්න ඕන උනේ නෑ...

උත්සාහය 6: SELECT, FROM, HHERE id >= සහ id <

පාරිභෝගිකයාට දත්ත සමුදාය සඳහා කැප වූ විශිෂ්ට සේවාදායකයක් තිබුණි: ද්විත්ව සකසනය Intel Xeon E5-2697 v2, අපේ ස්ථානයේ නූල් 48ක් තරම් තිබුණා! සේවාදායකයේ පැටවීම සාමාන්‍ය විය; අපට කිසිදු ගැටළුවක් නොමැතිව නූල් 20 ක් පමණ බාගත කළ හැකිය. ප්‍රමාණවත් RAM ද තිබුණි: ගිගාබයිට් 384ක් තරම්!

එබැවින්, විධානය සමාන්තරගත කිරීම අවශ්ය වේ:

for ((i=1; i<1628991; i=$((i+1)) )); do psql -U my_user -d my_database  -c "SELECT * FROM ws_log_smevlog where id=$i" >/dev/null || echo $i; done

මෙහි ලස්සන හා අලංකාර පිටපතක් ලිවීමට හැකි විය, නමුත් මම වේගවත්ම සමාන්තරකරණ ක්‍රමය තෝරා ගත්තෙමි: 0-1628991 පරාසය වාර්තා 100 ක පරතරයකට අතින් බෙදා පෝරමයේ විධාන 000 ක් වෙන වෙනම ක්‍රියාත්මක කරන්න:

for ((i=N; i<M; i=$((i+1)) )); do psql -U my_user -d my_database  -c "SELECT * FROM ws_log_smevlog where id=$i" >/dev/null || echo $i; done

නමුත් එය පමණක් නොවේ. න්‍යායාත්මකව, දත්ත සමුදායකට සම්බන්ධ වීමට යම් කාලයක් සහ පද්ධති සම්පත් ද ගත වේ. 1 සම්බන්ධ කිරීම එතරම් දක්ෂ නොවීය, ඔබ එකඟ වනු ඇත. එබැවින්, එක් සම්බන්ධතාවයක් වෙනුවට පේළි 628 ක් ලබා ගනිමු. එහි ප්රතිඵලයක් වශයෙන්, කණ්ඩායම මෙසේ පරිවර්තනය විය:

for ((i=N; i<M; i=$((i+1000)) )); do psql -U my_user -d my_database  -c "SELECT * FROM ws_log_smevlog where id>=$i and id<$((i+1000))" >/dev/null || echo $i; done

tmux සැසියකදී කවුළු 16 ක් විවෘත කර විධාන ක්‍රියාත්මක කරන්න:

1) for ((i=0; i<100000; i=$((i+1000)) )); do psql -U my_user -d my_database  -c "SELECT * FROM ws_log_smevlog where id>=$i and id<$((i+1000))" >/dev/null || echo $i; done
2) for ((i=100000; i<200000; i=$((i+1000)) )); do psql -U my_user -d my_database  -c "SELECT * FROM ws_log_smevlog where id>=$i and id<$((i+1000))" >/dev/null || echo $i; done
…
15) for ((i=1400000; i<1500000; i=$((i+1000)) )); do psql -U my_user -d my_database -c "SELECT * FROM ws_log_smevlog where id>=$i and id<$((i+1000))" >/dev/null || echo $i; done
16) for ((i=1500000; i<1628991; i=$((i+1000)) )); do psql -U my_user -d my_database  -c "SELECT * FROM ws_log_smevlog where id>=$i and id<$((i+1000))" >/dev/null || echo $i; done

දිනකට පසු මට පළමු ප්රතිඵල ලැබුණි! එනම් (XXX සහ ZZZ අගයන් තවදුරටත් සුරැකෙන්නේ නැත):

ERROR:  missing chunk number 0 for toast value 37837571 in pg_toast_106070
829000
ERROR:  missing chunk number 0 for toast value XXX in pg_toast_106070
829000
ERROR:  missing chunk number 0 for toast value ZZZ in pg_toast_106070
146000

මෙයින් අදහස් කරන්නේ පේළි තුනක දෝෂයක් ඇති බවයි. පළමු හා දෙවන ගැටළු වාර්තා වල id 829 සහ 000 අතර විය, තුන්වන id 830 ත් 000 ත් අතර විය.ඊළඟට, ගැටළු වාර්තා වල නිවැරදි id අගය සොයා ගැනීමට අපට සිදු විය. මෙය සිදු කිරීම සඳහා, අපි 146 පියවරක් සමඟ ගැටළු සහගත වාර්තා සමඟ අපගේ පරාසය දෙස බලා හැඳුනුම්පත හඳුනා ගනිමු:

for ((i=829000; i<830000; i=$((i+1)) )); do psql -U my_user -d my_database -c "SELECT * FROM ws_log_smevlog where id=$i" >/dev/null || echo $i; done
829417
ERROR:  unexpected chunk number 2 (expected 0) for toast value 37837843 in pg_toast_106070
829449
for ((i=146000; i<147000; i=$((i+1)) )); do psql -U my_user -d my_database -c "SELECT * FROM ws_log_smevlog where id=$i" >/dev/null || echo $i; done
829417
ERROR:  unexpected chunk number ZZZ (expected 0) for toast value XXX in pg_toast_106070
146911

සතුටුදායක අවසානය

ගැටළු සහගත රේඛා අපට හමු විය. අපි psql හරහා දත්ත සමුදායට ගොස් ඒවා මකා දැමීමට උත්සාහ කරමු:

my_database=# delete from ws_log_smevlog where id=829417;
DELETE 1
my_database=# delete from ws_log_smevlog where id=829449;
DELETE 1
my_database=# delete from ws_log_smevlog where id=146911;
DELETE 1

මා පුදුමයට පත් කරමින්, විකල්පය නොමැතිව පවා කිසිදු ගැටළුවක් නොමැතිව ඇතුළත් කිරීම් මකා දමන ලදී zero_damaged_pages.

ඊට පස්සේ මම දත්ත සමුදායට සම්බන්ධ කළා, කළා රික්තකය සම්පූර්ණයි (මෙය කිරීම අවශ්‍ය නොවන බව මම සිතමි), අවසානයේ මම උපස්ථය භාවිතයෙන් සාර්ථකව ඉවත් කළෙමි pg_dump. කිසිදු දෝෂයකින් තොරව ඩම්ප් එක ගෙන ඇත! ප්‍රශ්නය විසඳුවේ ඒ තරම් මෝඩ විදියට. ප්‍රීතියට සීමාවක් නැත, බොහෝ අසාර්ථකත්වයන්ගෙන් පසුව අපට විසඳුමක් සොයා ගැනීමට හැකි විය!

පිළිගැනීම් සහ නිගමනය

සැබෑ Postgres දත්ත සමුදායක් ප්‍රතිසාධනය කිරීමේ මගේ පළමු අත්දැකීම සිදුවූයේ එලෙසය. මේ අත්දැකීම මට බොහෝ කලකට මතකයි.

අවසාන වශයෙන්, ලිපි ලේඛන රුසියානු භාෂාවට පරිවර්තනය කිරීම සහ ඒ සඳහා PostgresPro වෙත ස්තුති කිරීමට මම කැමතියි සම්පූර්ණයෙන්ම නොමිලේ මාර්ගගත පාඨමාලා, එය ගැටලුව විශ්ලේෂණය කිරීමේදී බොහෝ සෙයින් උපකාරී විය.

මූලාශ්රය: www.habr.com

අදහස් එක් කරන්න