Құрметті DELETE. Николай Самохвалов (Postgres.ai)

Құрметті DELETE. Николай Самохвалов (Postgres.ai)

Бірде алыс болашақта қажетсіз деректерді автоматты түрде жою ДҚБЖ маңызды міндеттерінің бірі болады [1]. Осы уақытта біз қажет емес деректерді жою немесе арзанырақ сақтау жүйелеріне көшіру туралы қамқорлық жасауымыз керек. Сіз бірнеше миллион жолды жоюды шештіңіз делік. Өте қарапайым тапсырма, әсіресе жағдай белгілі болса және сәйкес көрсеткіш болса. "DELETE FROM table1 WHERE col1 = :value" - қарапайымырақ не болуы мүмкін, солай емес пе?

Бейне:

Құрметті DELETE. Николай Самохвалов (Postgres.ai)

  • Мен бірінші курстан бастап, яғни 2007 жылдан бастап Highload бағдарламасы комитетінде болдым.

  • Мен Postgres-те 2005 жылдан бері жұмыс істеймін. Оны көптеген жобаларда қолданды.

  • RuPostges-пен 2007 жылдан бері топ.

  • Meetup-те біз 2100+ қатысушыға жеттік. Сан-Франциско ұзақ уақыт бойы басып озған Нью-Йорктен кейін әлемде екінші орында.

  • Мен Калифорнияда бірнеше жыл тұрдым. Мен американдық компаниялармен, соның ішінде ірі компаниялармен көбірек айналысамын. Олар Postgres-тің белсенді пайдаланушылары. Және қызықты нәрселердің бәрі бар.

Құрметті DELETE. Николай Самохвалов (Postgres.ai)

https://postgres.ai/ менің компаниям. Біз дамудың баяулауын болдырмайтын тапсырмаларды автоматтандырумен айналысамыз.

Егер сіз бірдеңе істеп жатсаңыз, кейде Postgres айналасында қандай да бір штепсельдер бар. Әкімші сіз үшін сынақ стенді орнатқанша күтуіңіз керек немесе DBA сізге жауап беруін күтуіңіз керек делік. Біз әзірлеу, тестілеу және басқару процесінде мұндай кедергілерді тауып, оларды автоматтандыру мен жаңа тәсілдер арқылы жоюға тырысамыз.

Құрметті DELETE. Николай Самохвалов (Postgres.ai)

https://www.seagate.com/files/www-content/our-story/trends/files/idc-seagate-dataage-whitepaper.pdf

Мен жақында Лос-Анджелестегі VLDB-де болдым. Бұл дерекқорларға арналған ең үлкен конференция. Ал болашақта ДҚБЖ деректерді сақтап қана қоймай, автоматты түрде жояды деген есеп болды. Бұл жаңа тақырып.

Зеттабайттар әлемінде көбірек деректер бар - бұл 1 000 000 петабайт. Ал қазірдің өзінде бізде әлемде сақталған 100 зеттабайттан астам деректер бар деп есептеледі. Ал олардың саны артып келеді.

Құрметті DELETE. Николай Самохвалов (Postgres.ai)

https://vldb2019.github.io/files/VLDB19-keynote-2-slides.pdf

Ал онымен не істеу керек? Оны алып тастау керек екені анық. Міне, осы қызықты есептің сілтемесі. Бірақ осы уақытқа дейін бұл ДҚБЖ-да жүзеге асырылған жоқ.

Ақша санауды білетіндер екі нәрсені қалайды. Олар біздің жоюды қалайды, сондықтан техникалық тұрғыдан біз мұны істей алуымыз керек.

Құрметті DELETE. Николай Самохвалов (Postgres.ai)

Бұдан әрі айтатыным - нақты жағдайлардың жиынтығын қамтитын кейбір дерексіз жағдай, яғни менімен және айналасындағы дерекқорлармен бірнеше рет, көптеген жылдар бойы болған оқиғаның бір түрі. Тырмалар барлық жерде және барлығы оларға үнемі басады.

Құрметті DELETE. Николай Самохвалов (Postgres.ai)

Бізде өсуде база немесе бірнеше база бар делік. Ал кейбір жазбалар қоқыс екені анық. Мысалы, пайдаланушы сол жерде бірдеңе істей бастады, бірақ оны аяқтамады. Біраз уақыттан кейін біз бұл аяқталмағанды ​​бұдан былай сақтауға болмайтынын білеміз. Яғни, орынды үнемдеу, өнімділікті жақсарту және т.б. үшін кейбір қоқыс заттарды тазалағымыз келеді.

Құрметті DELETE. Николай Самохвалов (Postgres.ai)

Тұтастай алғанда, тапсырма белгілі бір нәрселерді, кейбір кестедегі нақты сызықтарды жоюды автоматтандыру болып табылады.

Құрметті DELETE. Николай Самохвалов (Postgres.ai)

Ал бізде осындай өтініш бар, ол туралы бүгін айтамыз, яғни қоқыс шығару туралы.

Құрметті DELETE. Николай Самохвалов (Postgres.ai)

Біз мұны тәжірибелі әзірлеушіден сұрадық. Ол бұл өтінішті қабылдады, оны өзі тексерді - бәрі жұмыс істейді. Сахналауда сыналған - бәрі жақсы. Шығарылды - бәрі жұмыс істейді. Біз оны күніне бір рет іске қосамыз - бәрі жақсы.

Құрметті DELETE. Николай Самохвалов (Postgres.ai)

Деректер базасы өседі және өседі. Күнделікті DELETE сәл баяу жұмыс істей бастайды.

Құрметті DELETE. Николай Самохвалов (Postgres.ai)

Содан кейін бізде қазір маркетингтік компания бар екенін түсінеміз және трафик бірнеше есе көп болады, сондықтан біз қажет емес нәрселерді уақытша тоқтатуды шешеміз. Және қайтаруды ұмыт.

Құрметті DELETE. Николай Самохвалов (Postgres.ai)

Бірнеше айдан кейін олар есіне алды. Және бұл әзірлеуші ​​жұмысын тоқтатты немесе басқа нәрсемен айналысады, басқасына оны қайтаруды тапсырды.

Ол әзірлеуді, қойылымды тексерді - бәрі жақсы. Әрине, сіз әлі де жинақталған нәрсені тазалауыңыз керек. Ол барлығын тексерді.

Құрметті DELETE. Николай Самохвалов (Postgres.ai)

Әрі қарай не болады? Содан кейін біз үшін бәрі бұзылады. Ол бір сәтте бәрі құлайтындай етіп төмендейді. Барлығы шошып кетті, не болып жатқанын ешкім түсінбейді. Сосын іс осы DELETE-де болған екен.

Құрметті DELETE. Николай Самохвалов (Postgres.ai)

Бірдеңе дұрыс болмады ма? Міне, қате болуы мүмкін тізім. Бұлардың қайсысы ең маңызды?

  • Мысалы, шолу болған жоқ, яғни DBA сарапшысы оған қараған жоқ. Ол тәжірибелі көзбен мәселені бірден табады, сонымен қатар бірнеше миллион жолдар жиналған өнімге қол жеткізе алады.

  • Мүмкін олар дұрыс емес нәрсені тексерді.

  • Мүмкін аппараттық құрал ескірген және сізге бұл базаны жаңарту қажет.

  • Немесе дерекқордың өзінде бірдеңе дұрыс емес және біз Postgres-тен MySQL-ге көшуіміз керек.

  • Немесе операцияда ақау бар шығар.

  • Мүмкін жұмысты ұйымдастыруда қателіктер бар және біреуді жұмыстан шығарып, ең жақсы адамдарды жұмысқа алу керек пе?

Құрметті DELETE. Николай Самохвалов (Postgres.ai)

DBA тексеруі болған жоқ. Егер DBA болса, ол осы бірнеше миллион жолдарды көреді және тіпті ешқандай экспериментсіз: «Олар мұны істемейді» деп айтар еді. Айталық, егер бұл код GitLab, GitHub-та болса және кодты тексеру процесі болса және DBA рұқсатынсыз бұл операция өнімде орындалатын нәрсе болмаса, DBA: «Мұны істеу мүмкін емес. .”

Құрметті DELETE. Николай Самохвалов (Postgres.ai)

Ол сізде дискідегі IO-мен проблемалар туындайды және барлық процестер ақылсыз болады, құлыптар болуы мүмкін, сонымен қатар сіз бірнеше минутқа автовакуумды блоктайсыз, сондықтан бұл жақсы емес.

Құрметті DELETE. Николай Самохвалов (Postgres.ai)

http://bit.ly/nancy-hl2018-2

Екінші қате - олар дұрыс емес жерде тексерді. Біз өнімде көптеген қажетсіз деректердің жинақталғанын көрдік, бірақ әзірлеушіде бұл дерекқорда деректер жинақталмаған және сахналау кезінде ешкім бұл қоқыстарды жасамаған. Тиісінше, тез өңделген 1 жол болды.

Біздің сынақтарымыз әлсіз екенін түсінеміз, яғни құрастырылған процесс қиындық тудырмайды. Адекватты МҚ тәжірибесі орындалмады.

Идеал эксперимент дәл сол жабдықта орындалады. Мұны бір жабдықта жасау әрқашан мүмкін емес, бірақ оның дерекқордың толық өлшемді көшірмесі болуы өте маңызды. Міне, мен бірнеше жылдан бері уағыздап келемін. Ал бір жыл бұрын мен бұл туралы айтқан болатынмын, мұның бәрін YouTube-тен көре аласыз.

Құрметті DELETE. Николай Самохвалов (Postgres.ai)

Мүмкін техникамыз нашар шығар? Қарасаңыз, кідіріс секірді. Қолдану 100 пайыз екенін көрдік. Әрине, егер бұл заманауи NVMe дискілері болса, біз үшін бұл әлдеқайда оңай болар еді. Бәлкім, біз одан бас тартпас едік.

Егер сізде бұлттар болса, онда жаңарту оңай орындалады. Жаңа жабдықта жаңа көшірмелер көтерілді. ауысу. Және бәрі жақсы. Өте оңай.

Құрметті DELETE. Николай Самохвалов (Postgres.ai)

Кішірек дискілерге қандай да бір түрде қол тигізу мүмкін бе? Міне, тек DBA көмегімен біз бақылау нүктесін баптау деп аталатын белгілі бір тақырыпқа енеміз. Бізде бақылау пунктінің баптауы болмаған екен.

Бақылау пункті дегеніміз не? Ол кез келген ДҚБЖ-да болады. Жадта өзгеретін деректер болған кезде ол бірден дискіге жазылмайды. Деректердің өзгергені туралы ақпарат алдымен алдын ала жазу журналына жазылады. Және бір сәтте ДҚБЖ нақты беттерді дискіге шығару уақыты келді деп шешеді, осылайша бізде сәтсіздік болса, біз аз REDO жасай аламыз. Бұл ойыншық сияқты. Егер біз өлтірілсек, ойынды соңғы бақылау нүктесінен бастаймыз. Және барлық ДҚБЖ оны жүзеге асырады.

Құрметті DELETE. Николай Самохвалов (Postgres.ai)

Postgres-тегі параметрлер артта қалды. Олар деректер мен транзакциялардың 10-15 жылдық көлеміне арналған. Ал бақылау-өткізу пункті де ерекшелік емес.

Міне, біздің Postgres тексеру есебіміздегі ақпарат, яғни автоматты денсаулықты тексеру. Міне, бірнеше терабайттан тұратын мәліметтер базасы. Ал 90% дерлік жағдайда мәжбүрлі бақылау бекеттері екенін жақсы көруге болады.

Бұл не мағына береді? Онда екі параметр бар. Бақылау нүктесі күту уақытында, мысалы, 10 минуттан кейін келуі мүмкін. Немесе бұл өте көп деректер толтырылған кезде келуі мүмкін.

Әдепкі бойынша max_wal_saze 1 гигабайтқа орнатылған. Шын мәнінде, бұл Postgres-те 300-400 мегабайттан кейін орын алады. Сіз көптеген деректерді өзгерттіңіз және сізде бақылау нүктесі бар.

Ал егер оны ешкім баптамаса, қызметі дамып, компания қомақты табыс тауып жатса, онда транзакциялар көп болса, онда бақылау пункті минутына бір рет, кейде 30 секунд сайын келеді, кейде тіпті бір-бірінен асып түседі. Бұл өте нашар.

Және оның жиі келетініне көз жеткізуіміз керек. Яғни, біз max_wal_size көбейте аламыз. Және ол сирек келеді.

Бірақ біз оны қалай дұрыс орындауға болатынын, яғни нақты деректерге негізделген параметрлерді таңдау туралы шешімді қалай қабылдауға болатынын толық әдістемесін әзірледік.

Құрметті DELETE. Николай Самохвалов (Postgres.ai)

Тиісінше, біз мәліметтер базасында екі тәжірибе сериясын жасап жатырмыз.

Бірінші серия - біз max_wal_size өзгертеміз. Ал біз жаппай операция жасап жатырмыз. Біріншіден, біз оны 1 гигабайт әдепкі параметрінде жасаймыз. Біз миллиондаған жолдарды жаппай ЖОЮ жасаймыз.

Бізге қаншалықты қиын екенін көріп тұрсыздар. Біз дискінің IO өте нашар екенін көреміз. Біз қанша WAL жасағанымызды қарастырамыз, себебі бұл өте маңызды. Бақылау бекетінің неше рет болғанын көрейік. Ал оның жақсы емес екенін көріп отырмыз.

Әрі қарай біз max_wal_size ұлғайтамыз. Қайталаймыз. Біз көбейтеміз, қайталаймыз. Және көп рет. Негізінде 10 ұпай жақсы, мұнда 1, 2, 4, 8 гигабайт. Ал біз белгілі бір жүйенің мінез-құлқын қарастырамыз. Бұл жерде жабдық өндірістегідей болуы керек екені анық. Сізде бірдей дискілер, бірдей жад көлемі және бірдей Postgres параметрлері болуы керек.

Осылайша біз өз жүйемізді ауыстырамыз және біз ДҚБЖ нашар жаппай DELETE жағдайында қалай әрекет ететінін, оның бақылау нүктесін қалай жасайтынын білеміз.

Орыс тілінде бақылау пункті - бұл өткізу пункттері.

Мысал: Индекс бойынша бірнеше миллион жолды ЖОЮ, жолдар беттер бойынша «шашырауда».

Құрметті DELETE. Николай Самохвалов (Postgres.ai)

Міне, мысал. Бұл кейбір база. Ал max_wal_size үшін 1 гигабайт әдепкі параметрімен жазуға арналған дискілеріміз сөреге түсетіні анық. Бұл сурет өте науқас науқастың типтік симптомы, яғни ол өзін шынымен нашар сезінді. Бір ғана операция болды, мұнда бірнеше миллион жолды DELETE ғана болды.

Егер мұндай операцияға өндірісте рұқсат етілсе, онда біз жай ғана жатамыз, өйткені полкте бізді бір DELETE өлтіретіні анық.

Құрметті DELETE. Николай Самохвалов (Postgres.ai)

Әрі қарай, онда 16 гигабайт, ол тіс қазірдің өзінде кеткені анық. Тістер қазірдің өзінде жақсырақ, яғни біз төбені қағып жатырмыз, бірақ соншалықты жаман емес. Ол жерде біраз еркіндік болды. Оң жақта жазба. Ал операциялар саны – екінші график. Ал 16 гигабайт болғанда, біз қазірдің өзінде біраз жеңілірек дем алатынымыз анық.

Құрметті DELETE. Николай Самохвалов (Postgres.ai)

Ал 64 гигабайттан оның мүлдем жақсырақ болғанын көруге болады. Қазірдің өзінде тістер айтылады, басқа операциялардан аман қалуға және дискімен бірдеңе істеуге көбірек мүмкіндіктер бар.

Неге бұлай?

Құрметті DELETE. Николай Самохвалов (Postgres.ai)

Мен егжей-тегжейлерге аздап енетін боламын, бірақ бақылау нүктесін баптауды қалай жүргізу керектігі туралы бұл тақырып толық есеп беруге әкелуі мүмкін, сондықтан мен көп жүктемеймін, бірақ мен қандай қиындықтар бар екенін аздап сипаттаймын.

Егер бақылау нүктесі тым жиі орын алса және біз жолдарымызды дәйекті түрде жаңартпаймыз, бірақ оларды индекс бойынша табамыз, бұл жақсы, өйткені біз бүкіл кестені жоймаймыз, онда алдымен бірінші бетті, содан кейін мыңыншы бетті ұстағанымыз мүмкін. содан кейін біріншісіне оралды. Егер бірінші бетке осы кірулер арасында бақылау нүктесі оны дискіге сақтап қойған болса, оны қайтадан сақтайды, өйткені біз оны екінші рет ластадық.

Ал біз бақылау-өткізу пунктін бірнеше рет сақтауға мәжбүрлейміз. Ол үшін артық операциялар бар сияқты.

Құрметті DELETE. Николай Самохвалов (Postgres.ai)

Бірақ бұл бәрі емес. Postgres жүйесінде беттер 8 килобайтты және Linux жүйесінде 4 килобайтты құрайды. Және толық_бет_жазу параметрі бар. Ол әдепкі бойынша қосылады. Және бұл дұрыс, өйткені оны өшіріп тастасақ, егер ол бұзылса, беттің жартысы ғана сақталады деген қауіп бар.

Алға жіберу журналының WAL-ге жазу әрекеті бізде бақылау нүктесі болған кезде және бетті бірінші рет өзгерткенде, біз тек өзгерткенімізге қарамастан, бүкіл бет, яғни, барлық 8 килобайт, алға жіберу журналына енетіндей. салмағы 100 байт болатын жол. Және біз бүкіл бетті жазуымыз керек.

Кейінгі өзгерістерде тек белгілі бір кортеж болады, бірақ біз бірінші рет бәрін жазамыз.

Тиісінше, егер бақылау нүктесі қайтадан орын алса, біз бәрін нөлден бастап, бүкіл бетті итеруіміз керек. Жиі бақылау нүктелерімен бірдей беттерді аралағанда full_page_writes = қосулы болуы мүмкін болатыннан көп болады, яғни біз көбірек WAL жасаймыз. Көбірек көшірмелерге, мұрағатқа, дискіге жіберіледі.

Және, тиісінше, бізде екі бос орын бар.

Құрметті DELETE. Николай Самохвалов (Postgres.ai)

Егер біз max_wal_size өлшемін ұлғайтсақ, біз бақылау нүктесіне де, wal жазушысына да жеңілдетеміз. Және бұл тамаша.

Терабайтты салып, онымен өмір сүрейік. Оның несі жаман? Бұл жаман, өйткені сәтсіздікке ұшыраған жағдайда біз сағаттап көтерілеміз, өйткені бақылау бекеті бұрыннан болды және көп нәрсе өзгерді. Және осының бәрін REDO жасауымыз керек. Осылайша біз эксперименттердің екінші сериясын жасаймыз.

Біз операция жасаймыз және бақылау пунктінің қашан аяқталатынын көреміз, біз -9 Postgres-ті әдейі өлтіреміз.

Осыдан кейін біз оны қайтадан бастаймыз және оның осы жабдықта қанша уақыт көтерілетінін, яғни бұл нашар жағдайда қаншалықты ҚАЙТА болатынын көреміз.

Жағдайдың нашар екенін екі рет айтамын. Біріншіден, біз бақылау-өткізу пункті аяқталмай тұрып апатқа ұшырадық, сондықтан жоғалтатынымыз көп. Екіншіден, бізге жаппай операция жасалды. Ал егер бақылау нүктелері күту уақытында болса, соңғы өткізу пунктінен бері WAL азырақ жасалуы мүмкін. Яғни, бұл екі есе жеңіліске ұшырайды.

Біз мұндай жағдайды әртүрлі max_wal_size өлшемдері үшін өлшейміз және егер max_wal_size 64 гигабайт болса, онда екі есе нашар жағдайда біз 10 минутқа көтерілетінімізді түсінеміз. Ал өзімізге жараса ма, жарамай ма деп ойлаймыз. Бұл іскерлік сұрақ. Біз бұл суретті іскерлік шешімдерге жауапты адамдарға көрсетіп, «Мәселе туындаған жағдайда біз қанша уақыт жатуға болады? Ең қиын жағдайда 3-5 минут жатып аламыз ба? Ал сіз шешім қабылдайсыз.

Және бұл жерде бір қызық жайт бар. Конференцияда Патрони туралы бір-екі баяндамамыз бар. Мүмкін сіз оны пайдаланып жатқан шығарсыз. Бұл Postgres үшін автоматты ауыстыру. Бұл туралы GitLab және Data Egret айтты.

Ал егер сізде 30 секундтан кейін келетін автофайл бар болса, онда біз 10 минут жатып аламыз ба? Өйткені біз осы уақытқа дейін көшірмеге ауысамыз және бәрі жақсы болады. Бұл даулы мәселе. Мен нақты жауапты білмеймін. Менің ойымша, бұл тақырып тек апатты қалпына келтіруге қатысты емес.

Егер сәтсіздіктен кейін ұзақ уақыт бойы қалпына келсек, онда біз көптеген басқа жағдайларда ыңғайсыз боламыз. Мысалы, сол эксперименттерде, біз бірдеңе жасағанда және кейде 10 минут күтуге тура келеді.

Мен әлі де тым алысқа бармас едім, тіпті бізде автоматты ауыстыру болса да. Әдетте, 64, 100 гигабайт сияқты мәндер жақсы мәндер болып табылады. Кейде тіпті азырақ таңдауға тұрарлық. Жалпы, бұл нәзік ғылым.

Құрметті DELETE. Николай Самохвалов (Postgres.ai)

Итерацияларды орындау үшін, мысалы, max_wal_size =1, 8, массалық операцияны бірнеше рет қайталау керек. Сіз үлгердіңіз. Сол негізде сіз мұны қайтадан жасағыңыз келеді, бірақ сіз бәрін жойдыңыз. Не істеу?

Мен шешіміміз туралы, мұндай жағдайларда қайталану үшін не істейтініміз туралы кейінірек айтатын боламын. Және бұл ең дұрыс тәсіл.

Бірақ бұл жағдайда біздің жолымыз болды. Егер мұнда айтылғандай «БАСТАУ, ЖОЮ, КЕРІ АЛУ» болса, біз ЖОЮ әрекетін қайталай аламыз. Яғни, егер біз оны өзіміз жойған болсақ, онда біз оны қайталай аламыз. Және физикалық деректеріңіз сонда болады. Сіз тіпті ісінуді де алмайсыз. Осындай DELETE бойынша қайталауға болады.

Бұл ROLLBACK бар DELETE, тіпті дұрыс орналастырылған дерекқор зертханалары болмаса да, бақылау нүктесін баптау үшін өте қолайлы.

Құрметті DELETE. Николай Самохвалов (Postgres.ai)

Біз бір баған «i» белгісін жасадық. Postgres-те қызмет көрсету бағандары бар. Арнайы сұралмаған жағдайда олар көрінбейді. Олар: ctid, xmid, xmax.

Ctid - физикалық мекенжай. Нөлдік бет, беттегі бірінші кортеж.

ROOLBACK кейін кортеж бұрынғы орнында қалғанын көруге болады. Яғни, біз қайтадан әрекет жасай аламыз, ол дәл солай әрекет етеді. Бұл бастысы.

Құрметті DELETE. Николай Самохвалов (Postgres.ai)

Xmax - кортеждің өлу уақыты. Оған мөр басылды, бірақ Postgres транзакцияның кері қайтарылғанын біледі, сондықтан оның 0 немесе кері қайтарылған транзакция екендігі маңызды емес. Бұл DELETE арқылы қайталауға және жүйе әрекетінің жаппай әрекеттерін тексеруге болатынын көрсетеді. Сіз кедейлер үшін дерекқор зертханаларын жасай аласыз.

Құрметті DELETE. Николай Самохвалов (Postgres.ai)

Бұл бағдарламашылар туралы. DBA туралы да олар әрқашан бағдарламашыларды бұл үшін ұрсады: «Неге сонша ұзақ және қиын операцияларды жасайсыз?». Бұл мүлдем басқа перпендикуляр тақырып. Бұрын әкімшілік болған, енді даму болады.

Әлбетте, біз бөлшектенген жоқпыз. Бұл түсінікті. Миллиондаған жолдардың үйіндісі үшін мұндай DELETE-ді бөліктерге бөлмеу мүмкін емес. Бұл 20 минутта жасалады, және бәрі жатып қалады. Бірақ, өкінішке орай, тіпті тәжірибелі әзірлеушілер тіпті өте ірі компанияларда қателіктер жібереді.

Неліктен бұзу маңызды?

  • Егер диск қатты екенін көрсек, оны баяулатайық. Ал егер біз бұзылған болсақ, онда үзілістерді қосуға болады, дроссельді баяулатуға болады.

  • Ал біз басқаларды көпке дейін бөгетпейміз. Кейбір жағдайларда маңызды емес, егер сіз ешкім жұмыс істемейтін қоқысты жойсаңыз, автовакуум жұмысынан басқа ешкімді блоктамайсыз, себебі ол транзакцияның аяқталуын күтеді. Бірақ егер сіз басқа біреу сұрай алатын нәрсені алып тастасаңыз, олар бұғатталады, қандай да бір тізбекті реакция болады. Веб-сайттар мен мобильді қосымшаларда ұзақ транзакциялардан аулақ болу керек.

Құрметті DELETE. Николай Самохвалов (Postgres.ai)

https://postgres.ai/products/joe/

Бұл қызық. Мен әзірлеушілер: «Қандай пакет өлшемін таңдауым керек?» Дейтінін жиі көремін.

Топтаманың мөлшері неғұрлым үлкен болса, транзакцияның үстеме шығысы соғұрлым аз болатыны анық, яғни транзакциялардан түсетін қосымша шығындар. Бірақ сонымен бірге бұл транзакцияның уақыты артады.

Менде өте қарапайым ереже бар: мүмкіндігінше көп алыңыз, бірақ секундына орындалатын файлдарды асырмаңыз.

Неліктен секунд? Түсіндіру өте қарапайым және барлығына, тіпті техникалық емес адамдарға түсінікті. Біз реакцияны көреміз. 50 миллисекунд алайық. Егер бірдеңе өзгерсе, онда біздің көзіміз жауап береді. Егер аз болса, қиынырақ. Егер бірдеңе 100 миллисекундтан кейін жауап берсе, мысалы, сіз тінтуірді бассаңыз және ол сізге 100 миллисекундтан кейін жауап берсе, сіз бұл аздаған кідірісті сезесіз. Секунд қазірдің өзінде тежегіш ретінде қабылданады.

Тиісінше, егер біз жаппай операцияларымызды 10 секундтық жарылыстарға бөлетін болсақ, онда біз біреуді бұғаттау қаупі бар. Ол бірнеше секунд жұмыс істейді және адамдар оны байқайды. Сондықтан мен бір секундтан артық жасамағанды ​​жөн көремін. Бірақ сонымен бірге оны өте ұсақтауға болмайды, өйткені транзакцияның үстеме шығындары байқалады. База қиынырақ болады және басқа да әртүрлі мәселелер туындауы мүмкін.

Біз пакеттің өлшемін таңдаймыз. Әр жағдайда біз мұны басқаша жасай аламыз. Автоматтандыруға болады. Ал біз бір буманы өңдеудің тиімділігіне сенімдіміз. Яғни, біз бір буманы ЖОЮ немесе ЖАҢАРТУ жасаймыз.

Айтпақшы, менің айтып отырғанымның бәрі ЖОЮ туралы ғана емес. Өзіңіз ойлағандай, бұл деректер бойынша кез келген көлемді операциялар.

Ал жоспардың тамаша екенін көріп отырмыз. Сіз индексті сканерлеуді көре аласыз, тек индексті сканерлеу одан да жақсырақ. Ал бізде аздаған деректер бар. Және бір секундтан азырақ орындалады. Тамаша.

Ал біз әлі де деградацияның жоқтығына көз жеткізуіміз керек. Алғашқы пакеттер тез жұмыс істейді, содан кейін ол нашарлайды, нашарлайды және нашарлайды. Процесс өте көп сынақтан өту керек. Дерекқор зертханалары дәл осыған арналған.

Біз әлі де бірдеңе дайындауымыз керек, бұл өндірісте мұны дұрыс ұстануға мүмкіндік береді. Мысалы, біз журналға уақытты жаза аламыз, біз қазір қайда екенімізді және қазір кімді жойғанымызды жаза аламыз. Және бұл кейінірек не болып жатқанын түсінуге мүмкіндік береді. Бірдеңе дұрыс болмаса, мәселені тез табыңыз.

Егер сұраулардың тиімділігін тексеру қажет болса және бізге бірнеше рет қайталау қажет болса, онда басқа бот сияқты нәрсе бар. Ол қазірдің өзінде дайын. Оны күн сайын ондаған әзірлеушілер пайдаланады. Ол 30 секундта сұраныс бойынша үлкен терабайт деректер базасын, өз көшірмесін беруді біледі. Ал сол жерде бірдеңені өшіріп, RESET деп айтуыңызға болады және оны қайтадан жоюға болады. Сіз онымен осылай тәжірибе жасай аласыз. Мен бұл нәрсенің болашағын көремін. Ал біз қазірдің өзінде жасап жатырмыз.

Құрметті DELETE. Николай Самохвалов (Postgres.ai)

https://docs.gitlab.com/ee/development/background_migrations.html

Бөлу стратегиялары дегеніміз не? Мен бумадағы әзірлеушілер қолданатын 3 түрлі бөлу стратегиясын көремін.

Біріншісі өте қарапайым. Бізде сандық идентификатор бар. Және оны әртүрлі интервалдарға бөліп, онымен жұмыс жасайық. Кемшілігі анық. Бірінші сегментте бізде 100 жол нақты қоқыс болуы мүмкін, екінші 5 жолда немесе мүлде болмауы мүмкін немесе 1 жолдың барлығы қоқыс болып шығады. Өте біркелкі емес жұмыс, бірақ оны бұзу оңай. Олар максималды куәлікті алып, оны сындырды. Бұл аңғал көзқарас.

Екінші стратегия – теңгерімді тәсіл. Ол Gitlab жүйесінде қолданылады. Олар үстелді алып, сканерледі. Біз идентификаторлар бумаларының шекараларын таптық, сонда әрбір бумада дәл 10 000 жазба болады. Және оларды кезекке қойыңыз. Содан кейін өңдейміз. Мұны бірнеше ағындарда жасауға болады.

Бірінші стратегияда да, айтпақшы, сіз мұны бірнеше ағындарда жасай аласыз. Бұл қиын емес.

Құрметті DELETE. Николай Самохвалов (Postgres.ai)

https://medium.com/@samokhvalov/how-partial-indexes-affect-update-performance-in-postgres-d05e0052abc

Бірақ салқын және жақсы тәсіл бар. Бұл үшінші стратегия. Ал мүмкіндігінше оны таңдаған дұрыс. Біз мұны арнайы көрсеткіш негізінде жасаймыз. Бұл жағдайда бұл біздің қоқыс жағдайымыз бен идентификаторымызға сәйкес индекс болуы мүмкін. Біз идентификаторды үймеге өтпеу үшін тек индексті сканерлеу үшін қосамыз.

Әдетте, тек индексті сканерлеу индексті сканерлеуге қарағанда жылдамырақ.

Құрметті DELETE. Николай Самохвалов (Postgres.ai)

Біз жойғымыз келетін идентификаторларымызды тез табамыз. BATCH_SIZE біз алдын ала таңдаймыз. Және біз оларды алып қана қоймай, оларды ерекше жолмен аламыз және дереу бұзып аламыз. Бірақ біз құлыптап жатырмыз, егер олар әлдеқашан құлыпталған болса, біз оларды құлыптамаймыз, бірақ алға жылжып, келесілерді аламыз. Бұл жаңартуды өткізіп жіберуді құлыптауға арналған. Postgres-тің бұл керемет мүмкіндігі, егер қаласақ, бірнеше ағындарда жұмыс істеуге мүмкіндік береді. Бұл бір ағында мүмкін. Міне, CTE бар - бұл бір өтініш. Бізде осы CTE екінші қабатында нақты жою жүріп жатыр - returning *. Сіз идентификаторды қайтара аласыз, бірақ бұл жақсы *егер сізде әр жолда көп деректер болмаса.

Құрметті DELETE. Николай Самохвалов (Postgres.ai)

Ол бізге не үшін керек? Бұл бізге есеп беруіміз керек. Біз қазір шын мәнінде көптеген жолдарды жойдық. Бізде идентификатор немесе created_at арқылы шекаралар бар. Мин, макс. Тағы бірдеңе жасауға болады. Мұнда сіз көп нәрсені толтыра аласыз. Және бұл бақылауға өте ыңғайлы.

Индекс туралы тағы бір ескертпе бар. Егер біз осы нақты тапсырма үшін арнайы индекс қажет деп шешсек, онда ол тек кортеждердің жаңартуларын бұзбайтынына көз жеткізуіміз керек. Яғни, Постгрестің осындай статистикасы бар. Мұны кестеңіз үшін pg_stat_user_tables ішінде көруге болады. Ыстық жаңартулардың пайдаланылғанын немесе пайдаланылмайтынын көре аласыз.

Сіздің жаңа индексіңіз оларды жай ғана кесіп тастауы мүмкін жағдайлар бар. Сізде қазірдің өзінде жұмыс істеп тұрған барлық басқа жаңартулар бар, баяулатыңыз. Индекс пайда болғандықтан ғана емес (әрбір индекс жаңартуларды аздап баяулатады, бірақ аздап), бірақ бұл жерде ол әлі де оны бұзады. Және бұл кестеге арнайы оңтайландыру жасау мүмкін емес. Бұл кейде болады. Бұл аз ғана адамның есінде болатын нәзіктік. Және бұл тырмаға оңай басуға болады. Кейде басқа жақтан тәсіл табу керек және әлі де бұл жаңа индекссіз істеу керек немесе басқа индексті жасау керек немесе басқа жолмен, мысалы, екінші әдісті қолдануға болады.

Бірақ бұл ең оңтайлы стратегия, партияларға бөлу және бір сұраныспен партияларға түсіру, аздап жою және т.б.

Құрметті DELETE. Николай Самохвалов (Postgres.ai)

Ұзақ транзакциялар https://gitlab.com/snippets/1890447

Блокталған автовакуум - https://gitlab.com/snippets/1889668

блоктау мәселесі - https://gitlab.com/snippets/1890428

№5 қате - үлкен қате. Окметрден келген Николай Postgres мониторингі туралы айтты. Өкінішке орай, тамаша Postgres мониторингі жоқ. Кейбіреулер жақынырақ, кейбіреулері одан әрі. Окметр мінсіз болу үшін жеткілікті жақын, бірақ көп нәрсе жетіспейді және оны қосу керек. Сіз бұған дайын болуыңыз керек.

Мысалы, өлі кортеждер жақсы бақыланады. Егер кестеде өлі заттар көп болса, онда бірдеңе дұрыс емес. Қазір әрекет еткен дұрыс, әйтпесе деградация болуы мүмкін, біз жатамыз. Болады.

Егер үлкен IO болса, онда бұл жақсы емес екені анық.

Ұзақ транзакциялар да. OLTP-де ұзақ транзакцияларға рұқсат етілмеуі керек. Міне, осы үзіндіні алуға және ұзақ транзакцияларды бақылауға мүмкіндік беретін үзіндіге сілтеме.

Неліктен ұзақ транзакциялар нашар? Өйткені барлық құлыптар соңында ғана босатылады. Ал біз барлығын жағамыз. Сонымен қатар, біз барлық кестелер үшін автовакуумды блоктаймыз. Бұл мүлдем жақсы емес. Репликада ыстық күту режимі қосылған болса да, ол әлі де нашар. Жалпы, еш жерде ұзақ транзакциялардан аулақ болу жақсы емес.

Егер бізде вакуумдалмаған көптеген үстелдер болса, бізде ескерту болуы керек. Мұнда мұндай жағдай болуы мүмкін. Біз автовакуумның жұмысына жанама әсер ете аламыз. Бұл Avito үзіндісі, мен оны сәл жақсарттым. Және бұл автовакууммен бізде не бар екенін көру үшін қызықты құрал болып шықты. Мысалы, кейбір үстелдер сонда күтіп тұр және өз кезегін күтпейді. Сондай-ақ, оны бақылауға қойып, ескерту керек.

Және блоктар шығарады. Блок ағаштарының орманы. Мен біреуден бірдеңені алып, оны жақсартуды ұнатамын. Мұнда мен Data Egret-тен керемет рекурсивті CTE алдым, ол ағаштар орманын көрсетеді. Бұл жақсы диагностикалық құрал. Оның негізінде мониторингті де құруға болады. Бірақ бұл мұқият жасалуы керек. Сіз өзіңіз үшін шағын мәлімдеме жасауыңыз керек. Және lock_timeout қажет.

Құрметті DELETE. Николай Самохвалов (Postgres.ai)

Кейде бұл қателердің барлығы жиынтықта болады.

Меніңше, бұл жерде басты қателік – ұйымдастырушылық. Бұл ұйымдастырушылық, өйткені техника тартпайды. Бұл нөмір 2 - олар дұрыс емес жерде тексерді.

Біз дұрыс емес жерде тексердік, өйткені бізде өндіріс клоны жоқ, оны тексеру оңай. Әзірлеушіде өндіріске мүлде рұқсат болмауы мүмкін.

Біз ол жерде емес тексердік. Сол жерде тексерсек, өзіміз де көретін едік. Әзірлеуші ​​мұны DBA болмаса да көрді, егер ол оны бірдей деректер көлемі және бірдей орын бар жақсы ортада тексерсе. Бұл азғындықтың бәрін көріп, ұятқа қалар еді.

Автовакуум туралы толығырақ. Біз бірнеше миллион жолды жаппай сыпырып алғаннан кейін, бізге әлі де REPACK жасау керек. Бұл әсіресе индекстер үшін маңызды. Біз ол жерде бәрін тазалаған соң олар өздерін жаман сезінеді.

Күнделікті тазалау жұмыстарын қайтарғыңыз келсе, мен оны жиірек, бірақ азырақ жасауды ұсынар едім. Ол минутына бір рет немесе одан да жиі болуы мүмкін. Және екі нәрсені қадағалау керек: бұл нәрседе қателер жоқ және ол артта қалмауы керек. Мен көрсеткен трюк мұны шешеді.

Құрметті DELETE. Николай Самохвалов (Postgres.ai)

Біздің істеп жатқанымыз ашық бастапқы код. Ол GitLab сайтында жарияланған. Біз оны адамдар DBA болмаса да тексере алатындай етіп жасаймыз. Біз дерекқор зертханасын жасап жатырмыз, яғни Джо жұмыс істеп тұрған негізгі компонентті шақырамыз. Сіз өнімнің көшірмесін ала аласыз. Енді Joe for slack-тің іске асырылуы бар, сіз сол жерде айта аласыз: «осындай сұрауды түсіндіріңіз» және дерекқордың көшірмесі үшін нәтижені дереу алыңыз. Онда сіз тіпті ЖОЮға болады, оны ешкім байқамайды.

Құрметті DELETE. Николай Самохвалов (Postgres.ai)

Сізде 10 терабайт бар делік, дерекқор зертханасын да 10 терабайт жасаймыз. Ал бір мезгілде 10 терабайт деректер қорымен 10 әзірлеуші ​​бір уақытта жұмыс істей алады. Әркім өз қалағанын істей алады. Жоюға, тастауға және т.б. Бұл фантазия. Бұл туралы ертең сөйлесеміз.

Құрметті DELETE. Николай Самохвалов (Postgres.ai)

Бұл жұқа қамтамасыз ету деп аталады. Бұл нәзік қамтамасыз ету. Бұл дамудағы, тестілеудегі кідірістерді айтарлықтай жоятын және әлемді осыған байланысты жақсы орынға айналдыратын қиялдың бір түрі. Яғни, бұл жай ғана көлемді операциялармен проблемаларды болдырмауға мүмкіндік береді.

Мысал: 5 терабайт дерекқор, көшірмесін 30 секундтан аз уақыт ішінде алу. Және бұл тіпті өлшеміне де байланысты емес, яғни қанша терабайт маңызды емес.

Бүгін баруға болады postgres.ai және біздің құралдарымызды қазып алыңыз. Онда не бар екенін көру үшін тіркелуге болады. Бұл ботты орнатуға болады. Бұл тегін. Жазыңыз.

Сіздің сұрақтарыңыз

Көбінесе нақты жағдайларда кестеде қалуы керек деректер жойылуы керек деректерден әлдеқайда аз болады. Яғни, мұндай жағдайда жаңа нысанды жасау, сол жерде тек қажетті деректерді көшіру және ескі кестені транкингтеу оңайырақ болғанда, мұндай тәсілді жүзеге асыру жиі оңайырақ. Сіз ауысу кезінде осы сәтте бағдарламалық тәсіл қажет екені анық. Бұл тәсіл қалай?

Бұл өте жақсы тәсіл және өте жақсы тапсырма. Бұл pg_repack әрекетіне өте ұқсас, идентификаторларды 4 байт жасағанда істеу керек нәрсеге өте ұқсас. Көптеген фреймворктар мұны бірнеше жыл бұрын жасады, және жай ғана пластиналар өсті және оларды 8 байтқа түрлендіру қажет.

Бұл тапсырма өте қиын. Біз мұны жасадық. Және өте сақ болу керек. Құлыптар бар және т.б. Бірақ бұл орындалып жатыр. Яғни, стандартты тәсіл pg_repack бағдарламасымен жүру болып табылады. Сіз осындай белгіні жариялайсыз. Оған сурет деректерін жүктеп салуды бастамас бұрын, сіз барлық өзгерістерді қадағалайтын бір тақтаны жариялайсыз. Кейбір өзгерістерді қадағаламауыңыз мүмкін трюк бар. Жіңішке тұстары бар. Содан кейін өзгертулерді жылжыту арқылы ауысасыз. Барлығын өшірген кезде қысқа үзіліс болады, бірақ жалпы бұл орындалуда.

Егер сіз GitHub сайтында pg_repack қарасаңыз, онда идентификаторды int 4-тен int 8-ге түрлендіру тапсырмасы болған кезде, pg_repack-тің өзін пайдалану идеясы болды. Бұл да мүмкін, бірақ бұл аздап бұзу, бірақ бұл үшін де жұмыс істейді. Сіз pg_repack пайдаланатын триггерге араласып, сол жерде айта аласыз: «Бізге бұл деректер қажет емес», яғни біз тек қажет нәрсені ғана тасымалдаймыз. Содан кейін ол жай ғана ауысады және болды.

Бұл тәсілмен біз әлі де кестенің екінші көшірмесін аламыз, онда деректер қазірдің өзінде индекстелген және әдемі индекстермен өте біркелкі жинақталған.

Bloat жоқ, бұл жақсы тәсіл. Бірақ мен бұл үшін автоматтандыруды әзірлеу, яғни әмбебап шешім қабылдау әрекеттері бар екенін білемін. Мен сізді осы автоматтандырумен байланыстыра аламын. Бұл Python тілінде жазылған, бұл жақсы нәрсе.

Мен MySQL әлемінен сәл ғана емеспін, сондықтан мен тыңдауға келдім. Және біз бұл әдісті қолданамыз.

Бірақ бұл бізде 90% болған жағдайда ғана. Егер бізде 5% болса, онда оны пайдалану өте жақсы емес.

Есеп үшін рахмет! Өнімнің толық көшірмесін жасау үшін ресурстар болмаса, жүктемені немесе өлшемді есептеу үшін қандай да бір алгоритм немесе формула бар ма?

Жақсы сұрақ. Әзірге біз көп терабайттық деректер қорын таба аламыз. Аппараттық құрал бірдей болмаса да, мысалы, жады аз, процессор мен дискілер бірдей емес, бірақ бәрібір біз мұны істейміз. Егер мүлдем еш жерде жоқ болса, онда сіз ойлануыңыз керек. Ертеңге дейін ойланып көрейін, келдің, сөйлесеміз, жақсы сұрақ екен.

Есеп үшін рахмет! Сіз алдымен осындай шектеулері бар керемет Postgres бар екенін бастадыңыз, бірақ ол дамып келеді. Ал мұның бәрі жалпы алғанда балдақ. Мұның бәрі Postgres-тің дамуына қайшы емес пе, онда кейбір DELETE deferent пайда болады немесе біз мұнда кейбір оғаш құралдарымызбен ластауға тырысатын нәрсені төмен деңгейде ұстауы керек басқа нәрсе бар ма?

Егер SQL-де біз бір транзакцияда көптеген жазбаларды жою немесе жаңарту керек десек, Postgres мұны қалай тарата алады? Біз физикалық тұрғыдан операцияларда шектелеміз. Біз мұны әлі ұзақ уақыт бойы жасаймыз. Ал біз осы уақытта құлыптаймыз, т.б.

Индекстермен аяқталды.

Мен дәл сол бақылау нүктесін баптауды автоматтандыруға болады деп болжауға болады. Бір күні болуы мүмкін. Бірақ содан кейін мен сұрақты шынымен түсінбеймін.

Мәселе мынада, мұнда және мұнда жүретін даму векторы бар ма, ал сіздікі параллельді? Анау. Олар бұл туралы әлі ойланбады ма?

Мен қазір қолдануға болатын принциптер туралы айттым. Басқа бот бар Нэнси, мұнымен сіз бақылау пунктін автоматты түрде баптауға болады. Ол бір күні Postgres-те болады ма? Білмеймін, әлі талқыланған жоқ. Біз одан әлі алыспыз. Бірақ жаңа жүйелерді жасайтын ғалымдар бар. Және олар бізді автоматты индекстерге итермелейді. Дамулар бар. Мысалы, сіз автоматты баптауды көре аласыз. Ол параметрлерді автоматты түрде таңдайды. Бірақ ол әлі сіз үшін бақылау пунктін баптамайды. Яғни, ол өнімділікке, қабық буферіне және т.б.

Ал бақылау нүктесін баптау үшін сіз мұны істей аласыз: егер сізде мың кластер және әртүрлі аппараттық құралдар, бұлтта әртүрлі виртуалды машиналар болса, сіз біздің ботты пайдалана аласыз. Нэнси автоматтандыруды жүзеге асыру. Ал max_wal_size сіздің мақсатты параметрлеріңізге сәйкес автоматты түрде таңдалады. Бірақ әзірге бұл, өкінішке орай, өзегіне жақын емес.

Қайырлы күн! Сіз ұзақ транзакциялардың қауіптілігі туралы айттыңыз. Автовакуум жойылған жағдайда бұғатталғанын айттыңыз. Бұл бізге тағы қалай зиян тигізеді? Өйткені біз кеңістікті босату және оны пайдалана алу туралы көбірек айтып отырмыз. Бізге тағы не жетіспейді?

Автовакуум бұл жерде ең үлкен мәселе емес шығар. Ал ұзақ транзакцияның басқа транзакцияларды құлыптауы мүмкін екендігі, бұл мүмкіндік қауіптірек. Ол кездесуі де мүмкін. Егер ол кездессе, бұл өте нашар болуы мүмкін. Ал автовакууммен - бұл да проблема. OLTP-де ұзақ транзакцияларда екі мәселе бар: құлыптар және автовакуум. Егер сізде репликада ыстық күту режимінде кері байланыс қосылған болса, онда сіз әлі де мастерде автовакуумды құлыпты аласыз, ол репликадан келеді. Бірақ кем дегенде құлыптар болмайды. Және локтар болады. Біз деректерді өзгерту туралы айтып отырмыз, сондықтан құлыптар мұнда маңызды сәт болып табылады. Егер мұның бәрі ұзақ, ұзақ уақытқа болса, онда көбірек транзакциялар құлыпталады. Олар басқаларды ұрлай алады. Ал лок ағаштары пайда болады. Мен үзіндіге сілтеме бердім. Және бұл мәселе тек жинақталуы мүмкін автовакуум мәселесіне қарағанда тезірек байқалады.

Есеп үшін рахмет! Есепті қате тексердім деп бастадыңыз. Біз сол құрал-жабдықты, базаны бірдей алуымыз керек деген ойымызды жалғастырдық. Әзірлеушіге негіз бердік делік. Және ол өтінішті орындады. Және ол жақсы сияқты. Бірақ ол тікелей емес, тірі үшін тексереді, мысалы, бізде 60-70% жүктеме бар. Және бұл баптауды қолдансақ та, ол өте жақсы жұмыс істемейді.

Командада сарапшы болуы және нақты фондық жүктемемен не болатынын болжай алатын DBA сарапшыларын пайдалану маңызды. Біз таза өзгерістерді жүргізген кезде біз суретті көреміз. Бірақ анағұрлым жетілдірілген тәсіл, біз сол нәрсені қайтадан жасаған кезде, бірақ өндіріске имитацияланған жүктемемен. Бұл өте керемет. Оған дейін сен есейесің. Бұл ересек адам сияқты. Біз жай ғана бізде бар нәрселерді қарастырдық, сонымен қатар бізде ресурстар жеткілікті ме, жоқ па деп қарадық. Бұл жақсы сұрақ.

Біз қазірдің өзінде қоқыс таңдауын жасап жатқанда, бізде, мысалы, жойылған жалауша бар

Бұл Postgres-те автовакуум автоматты түрде жасайды.

О, ол мұны істей ме?

Автовакуум - қоқыс жинағыш.

рахмет!

Есеп үшін рахмет! Барлық қоқыс негізгі кестенің бір жерінен бүйіріне қарай ластанатындай етіп бөлумен дерекқорды дереу жобалау мүмкіндігі бар ма?

Әрине бар.

Егер біз қолдануға болмайтын үстелді құлыптап қойсақ, өзімізді қорғауға болады ма?

Әрине бар. Бірақ бұл тауық пен жұмыртқа мәселесі сияқты. Болашақта не болатынын бәріміз білсек, әрине, біз бәрін жақсы жасаймыз. Бірақ бизнес өзгеріп жатыр, жаңа бағандар, жаңа сұраныстар бар. Содан кейін – ой, біз оны жойғымыз келеді. Бірақ бұл идеалды жағдай өмірде болады, бірақ әрқашан емес. Бірақ жалпы алғанда бұл жақсы идея. Жай ғана қысқартыңыз және солай.

Ақпарат көзі: www.habr.com

пікір қалдыру