DELETE yang dihormati. Nikolay Samokhvalov (Postgres.ai)

DELETE yang dihormati. Nikolay Samokhvalov (Postgres.ai)

Pada masa hadapan yang jauh, penyingkiran automatik data yang tidak diperlukan akan menjadi salah satu tugas penting DBMS [1]. Sementara itu, kita sendiri perlu menjaga pemadaman atau pemindahan data yang tidak diperlukan ke sistem storan yang lebih murah. Katakan anda memutuskan untuk memadamkan beberapa juta baris. Tugas yang agak mudah, terutamanya jika keadaan diketahui dan terdapat indeks yang sesuai. "DELETE FROM table1 WHERE col1 = :value" - apa yang lebih mudah, bukan?

Video:

DELETE yang dihormati. Nikolay Samokhvalov (Postgres.ai)

  • Saya telah menganggotai jawatankuasa program Highload sejak tahun pertama, iaitu sejak 2007.

  • Dan saya telah bersama Postgres sejak 2005. Digunakan dalam banyak projek.

  • Kumpulan dengan RuPostges juga sejak 2007.

  • Kami telah berkembang kepada 2100+ peserta di Meetup. Ia adalah kedua di dunia selepas New York, diatasi oleh San Francisco untuk masa yang lama.

  • Saya telah tinggal di California selama beberapa tahun. Saya lebih banyak berurusan dengan syarikat Amerika, termasuk yang besar. Mereka adalah pengguna aktif Postgres. Dan terdapat pelbagai perkara yang menarik.

DELETE yang dihormati. Nikolay Samokhvalov (Postgres.ai)

https://postgres.ai/ adalah syarikat saya. Kami berada dalam perniagaan mengautomasikan tugas yang menghapuskan kelembapan pembangunan.

Jika anda melakukan sesuatu, kadangkala terdapat beberapa jenis palam di sekitar Postgres. Katakan anda perlu menunggu pentadbir menyediakan tempat ujian untuk anda, atau anda perlu menunggu DBA membalas kepada anda. Dan kami mendapati kesesakan sedemikian dalam proses pembangunan, ujian dan pentadbiran dan cuba menghapuskannya dengan bantuan automasi dan pendekatan baharu.

DELETE yang dihormati. Nikolay Samokhvalov (Postgres.ai)

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

Saya baru-baru ini berada di VLDB di Los Angeles. Ini adalah persidangan terbesar mengenai pangkalan data. Dan terdapat laporan bahawa pada masa akan datang DBMS bukan sahaja akan menyimpan, tetapi juga secara automatik memadam data. Ini topik baru.

Terdapat lebih banyak data dalam dunia zettabait - iaitu 1 petabait. Dan kini dianggarkan bahawa kami mempunyai lebih daripada 000 zettabait data yang disimpan di dunia. Dan terdapat lebih banyak daripada mereka.

DELETE yang dihormati. Nikolay Samokhvalov (Postgres.ai)

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

Dan apa yang perlu dilakukan dengannya? Jelas sekali ia perlu dikeluarkan. Berikut adalah pautan kepada laporan menarik ini. Tetapi setakat ini ini belum dilaksanakan dalam DBMS.

Mereka yang boleh mengira wang mahu dua perkara. Mereka mahu kami memadamkan, jadi secara teknikal kami sepatutnya dapat melakukannya.

DELETE yang dihormati. Nikolay Samokhvalov (Postgres.ai)

Apa yang akan saya ceritakan seterusnya ialah beberapa situasi abstrak yang merangkumi sekumpulan situasi sebenar, iaitu sejenis kompilasi apa yang sebenarnya berlaku kepada saya dan pangkalan data di sekelilingnya berkali-kali, bertahun-tahun. Rake ada di mana-mana dan semua orang memijaknya sepanjang masa.

DELETE yang dihormati. Nikolay Samokhvalov (Postgres.ai)

Katakan kita mempunyai pangkalan atau beberapa pangkalan yang sedang berkembang. Dan beberapa rekod jelas adalah sampah. Sebagai contoh, pengguna mula melakukan sesuatu di sana, tetapi tidak menyelesaikannya. Dan selepas beberapa lama kita tahu bahawa yang belum selesai ini tidak boleh disimpan lagi. Iaitu, kami ingin membersihkan beberapa perkara sampah untuk menjimatkan ruang, meningkatkan prestasi, dsb.

DELETE yang dihormati. Nikolay Samokhvalov (Postgres.ai)

Secara umum, tugasnya adalah untuk mengautomasikan pemadaman perkara tertentu, baris tertentu dalam beberapa jadual.

DELETE yang dihormati. Nikolay Samokhvalov (Postgres.ai)

Dan kami mempunyai permintaan sedemikian, yang akan kami bincangkan hari ini, iaitu, mengenai penyingkiran sampah.

DELETE yang dihormati. Nikolay Samokhvalov (Postgres.ai)

Kami meminta pembangun berpengalaman untuk melakukannya. Dia menerima permintaan ini, menyemaknya sendiri - semuanya berfungsi. Diuji pada pementasan - semuanya baik-baik saja. Dilancarkan - semuanya berfungsi. Sekali sehari kami menjalankannya - semuanya baik-baik saja.

DELETE yang dihormati. Nikolay Samokhvalov (Postgres.ai)

Pangkalan data berkembang dan berkembang. DELETE harian mula berfungsi dengan lebih perlahan.

DELETE yang dihormati. Nikolay Samokhvalov (Postgres.ai)

Kemudian kami faham bahawa kami kini mempunyai syarikat pemasaran dan trafik akan menjadi beberapa kali lebih besar, jadi kami memutuskan untuk menjeda perkara yang tidak perlu buat sementara waktu. Dan lupa untuk kembali.

DELETE yang dihormati. Nikolay Samokhvalov (Postgres.ai)

Beberapa bulan kemudian mereka teringat. Dan pembangun itu berhenti atau sibuk dengan perkara lain, mengarahkan orang lain untuk mengembalikannya.

Dia menyemak pada dev, pada pementasan - semuanya OK. Sememangnya, anda masih perlu membersihkan apa yang terkumpul. Dia memeriksa semuanya berfungsi.

DELETE yang dihormati. Nikolay Samokhvalov (Postgres.ai)

Apa yang berlaku seterusnya? Kemudian semuanya runtuh untuk kita. Ia jatuh sehingga pada satu ketika semuanya jatuh ke bawah. Semua orang terkejut, tiada siapa yang memahami apa yang berlaku. Dan kemudian ternyata perkara itu adalah dalam DELETE ini.

DELETE yang dihormati. Nikolay Samokhvalov (Postgres.ai)

Ada masalah? Berikut ialah senarai perkara yang mungkin salah. Manakah antara ini yang paling penting?

  • Sebagai contoh, tiada semakan, iaitu pakar DBA tidak melihatnya. Dia akan segera mencari masalah dengan mata yang berpengalaman, dan selain itu, dia mempunyai akses kepada prod, di mana beberapa juta baris telah terkumpul.

  • Mungkin mereka menyemak sesuatu yang salah.

  • Mungkin perkakasan sudah lapuk dan anda perlu menaik taraf pangkalan ini.

  • Atau ada yang tidak kena dengan pangkalan data itu sendiri, dan kita perlu beralih dari Postgres ke MySQL.

  • Atau mungkin ada yang tidak kena dengan operasi.

  • Mungkin terdapat beberapa kesilapan dalam organisasi kerja dan anda perlu memecat seseorang dan mengupah orang yang terbaik?

DELETE yang dihormati. Nikolay Samokhvalov (Postgres.ai)

Tiada semakan DBA. Jika ada DBA, dia akan melihat beberapa juta baris ini dan walaupun tanpa sebarang eksperimen akan berkata: "Mereka tidak berbuat demikian." Katakan jika kod ini berada dalam GitLab, GitHub dan akan ada proses semakan kod dan tidak ada perkara sedemikian yang tanpa kelulusan DBA operasi ini akan berlaku pada prod, maka jelas DBA akan berkata: "Ini tidak boleh dilakukan .”

DELETE yang dihormati. Nikolay Samokhvalov (Postgres.ai)

Dan dia akan mengatakan bahawa anda akan menghadapi masalah dengan cakera IO dan semua proses akan menjadi gila, mungkin terdapat kunci, dan juga anda akan menyekat autovakum selama beberapa minit, jadi ini tidak baik.

DELETE yang dihormati. Nikolay Samokhvalov (Postgres.ai)

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

Kesilapan kedua - mereka menyemak di tempat yang salah. Kami melihat selepas fakta bahawa banyak data sampah terkumpul pada prod, tetapi pembangun tidak mempunyai data terkumpul dalam pangkalan data ini, dan tiada siapa yang mencipta sampah ini semasa pementasan. Sehubungan itu, terdapat 1 baris yang berjaya dengan cepat.

Kami faham bahawa ujian kami lemah, iaitu proses yang dibina tidak menghadapi masalah. Percubaan DB yang mencukupi tidak dilakukan.

Eksperimen yang ideal sebaiknya dijalankan pada peralatan yang sama. Ia tidak selalu mungkin untuk melakukan ini pada peralatan yang sama, tetapi adalah sangat penting bahawa ia adalah salinan pangkalan data bersaiz penuh. Inilah yang saya telah dakwahkan selama beberapa tahun sekarang. Dan setahun yang lalu saya bercakap tentang ini, anda boleh menonton semuanya di YouTube.

DELETE yang dihormati. Nikolay Samokhvalov (Postgres.ai)

Mungkin peralatan kita teruk? Jika anda melihat, maka kependaman melonjak. Kami telah melihat bahawa penggunaan adalah 100%. Sudah tentu, jika ini adalah pemacu NVMe moden, maka ia mungkin lebih mudah untuk kita. Dan mungkin kita tidak akan berputus asa daripadanya.

Jika anda mempunyai awan, maka naik taraf mudah dilakukan di sana. Menimbulkan replika baharu pada perkakasan baharu. beralih. Dan semuanya baik-baik saja. Agak mudah.

DELETE yang dihormati. Nikolay Samokhvalov (Postgres.ai)

Adakah mungkin untuk menyentuh cakera yang lebih kecil? Dan di sini, hanya dengan bantuan DBA, kita menyelami topik tertentu yang dipanggil penalaan pusat pemeriksaan. Ternyata kami tidak mempunyai penalaan pusat pemeriksaan.

Apakah pusat pemeriksaan? Ia ada dalam mana-mana DBMS. Apabila anda mempunyai data dalam memori yang berubah, ia tidak segera ditulis ke cakera. Maklumat yang data telah diubah terlebih dahulu ditulis pada log tulis ke hadapan. Dan pada satu ketika, DBMS memutuskan bahawa sudah tiba masanya untuk membuang halaman sebenar ke cakera, supaya jika kita mengalami kegagalan, kita boleh melakukan kurang REDO. Ia seperti mainan. Jika kami terbunuh, kami akan memulakan permainan dari checkpoint terakhir. Dan semua DBMS melaksanakannya.

DELETE yang dihormati. Nikolay Samokhvalov (Postgres.ai)

Tetapan dalam Postgres ketinggalan. Ia direka untuk volum data dan transaksi berusia 10-15 tahun. Dan pusat pemeriksaan tidak terkecuali.

Berikut adalah maklumat daripada laporan pemeriksaan Postgres kami, iaitu pemeriksaan kesihatan automatik. Dan berikut adalah beberapa pangkalan data beberapa terabait. Dan dapat dilihat dengan baik bahawa pusat pemeriksaan paksa dalam hampir 90% kes.

Apakah maksudnya? Terdapat dua tetapan di sana. Pusat pemeriksaan boleh datang dengan tamat masa, contohnya, pada 10 minit. Atau ia mungkin datang apabila cukup banyak data telah diisi.

Dan secara lalai max_wal_saze ditetapkan kepada 1 gigabait. Malah, ini benar-benar berlaku dalam Postgres selepas 300-400 megabait. Anda telah menukar begitu banyak data dan pusat pemeriksaan anda berlaku.

Dan jika tiada siapa yang menalanya, dan perkhidmatan itu berkembang, dan syarikat memperoleh banyak wang, ia mempunyai banyak transaksi, maka pusat pemeriksaan datang sekali seminit, kadang-kadang setiap 30 saat, dan kadang-kadang bertindih. Ini agak teruk.

Dan kita perlu memastikan bahawa ia datang kurang kerap. Iaitu, kita boleh meningkatkan max_wal_size. Dan ia akan datang kurang kerap.

Tetapi kami telah membangunkan keseluruhan metodologi untuk cara melakukannya dengan lebih betul, iaitu cara membuat keputusan tentang memilih tetapan, dengan jelas berdasarkan data tertentu.

DELETE yang dihormati. Nikolay Samokhvalov (Postgres.ai)

Sehubungan itu, kami sedang melakukan dua siri eksperimen pada pangkalan data.

Siri pertama - kami menukar max_wal_size. Dan kami sedang melakukan operasi besar-besaran. Pertama, kami melakukannya pada tetapan lalai 1 gigabait. Dan kami melakukan PADAM besar-besaran berjuta-juta baris.

Anda boleh melihat betapa sukarnya untuk kami. Kami melihat bahawa cakera IO adalah sangat buruk. Kami melihat berapa banyak WAL yang telah kami hasilkan, kerana ini sangat penting. Mari kita lihat berapa kali pusat pemeriksaan berlaku. Dan kita melihat bahawa ia tidak baik.

Seterusnya kami meningkatkan max_wal_size. Kami ulangi. Kita tambah, kita ulang. Dan begitu banyak kali. Pada dasarnya, 10 mata adalah baik, di mana 1, 2, 4, 8 gigabait. Dan kita melihat tingkah laku sistem tertentu. Adalah jelas bahawa di sini peralatan harus seperti pada prod. Anda mesti mempunyai cakera yang sama, jumlah memori yang sama, dan tetapan Postgres yang sama.

Dan dengan cara ini kami akan menukar sistem kami, dan kami tahu bagaimana DBMS akan berkelakuan sekiranya DELETE massa yang teruk, bagaimana ia akan menjadi pusat pemeriksaan.

Pusat pemeriksaan dalam bahasa Rusia adalah pusat pemeriksaan.

Contoh: PADAM beberapa juta baris mengikut indeks, baris "tersebar" merentasi halaman.

DELETE yang dihormati. Nikolay Samokhvalov (Postgres.ai)

Berikut adalah contoh. Ini adalah beberapa asas. Dan dengan tetapan lalai 1 gigabait untuk max_wal_size, adalah sangat jelas bahawa cakera kami pergi ke rak untuk rakaman. Gambar ini adalah simptom tipikal pesakit yang sangat sakit, iaitu, dia berasa sangat teruk. Dan terdapat satu operasi tunggal, terdapat hanya PADAM beberapa juta baris.

Jika operasi sedemikian dibenarkan secara prod, maka kita akan baring sahaja, kerana jelas satu DELETE membunuh kita dalam rejimen.

DELETE yang dihormati. Nikolay Samokhvalov (Postgres.ai)

Selanjutnya, di mana 16 gigabait, adalah jelas bahawa gigi telah hilang. Gigi sudah lebih baik, iaitu, kita mengetuk siling, tetapi tidak begitu teruk. Terdapat sedikit kebebasan di sana. Di sebelah kanan ialah rekod. Dan bilangan operasi - graf kedua. Dan jelas bahawa kita sudah bernafas lebih lega apabila 16 gigabait.

DELETE yang dihormati. Nikolay Samokhvalov (Postgres.ai)

Dan di mana 64 gigabait boleh dilihat bahawa ia telah menjadi lebih baik sepenuhnya. Sudah gigi diucapkan, terdapat lebih banyak peluang untuk bertahan dalam operasi lain dan melakukan sesuatu dengan cakera.

Mengapa begitu?

DELETE yang dihormati. Nikolay Samokhvalov (Postgres.ai)

Saya akan menyelami butiran sedikit, tetapi topik ini, bagaimana untuk menjalankan penalaan pusat pemeriksaan, boleh menghasilkan laporan keseluruhan, jadi saya tidak akan memuatkan banyak, tetapi saya akan menggariskan sedikit kesulitan yang ada.

Jika pusat pemeriksaan berlaku terlalu kerap, dan kami mengemas kini baris kami tidak secara berurutan, tetapi mencari mengikut indeks, yang bagus, kerana kami tidak memadamkan keseluruhan jadual, maka mungkin pada mulanya kami menyentuh halaman pertama, kemudian yang ke seribu, dan kemudian kembali ke yang pertama. Dan jika di antara lawatan ini ke halaman pertama, pusat pemeriksaan telah menyimpannya ke cakera, maka ia akan menyimpannya semula, kerana kami membuatnya kotor untuk kali kedua.

Dan kami akan memaksa pusat pemeriksaan untuk menyelamatkannya berkali-kali. Bagaimana mungkin ada operasi berlebihan untuknya.

DELETE yang dihormati. Nikolay Samokhvalov (Postgres.ai)

Tetapi bukan itu sahaja. Halaman ialah 8 kilobait dalam Postgres dan 4 kilobait dalam Linux. Dan terdapat tetapan full_page_writes. Ia didayakan secara lalai. Dan ini betul, kerana jika kita mematikannya, maka terdapat bahaya bahawa hanya separuh daripada halaman akan disimpan jika ia ranap.

Tingkah laku menulis kepada WAL log ke hadapan adalah sedemikian rupa sehingga apabila kita mempunyai pusat pemeriksaan dan kita menukar halaman untuk kali pertama, keseluruhan halaman, iaitu, kesemua 8 kilobait, masuk ke dalam log ke hadapan, walaupun kita hanya menukar baris, yang mempunyai berat 100 bait . Dan kita perlu menulis keseluruhan halaman.

Dalam perubahan seterusnya, hanya akan ada tupel tertentu, tetapi buat pertama kalinya kami menulis segala-galanya.

Dan, sewajarnya, jika pusat pemeriksaan berlaku lagi, maka kita perlu memulakan segala-galanya dari awal sekali lagi dan menolak seluruh halaman. Dengan pusat pemeriksaan yang kerap, apabila kami berjalan melalui halaman yang sama, full_page_writes = on akan menjadi lebih daripada yang mungkin, iaitu kami menjana lebih banyak WAL. Lebih banyak dihantar ke replika, ke arkib, ke cakera.

Dan, sewajarnya, kami mempunyai dua redundansi.

DELETE yang dihormati. Nikolay Samokhvalov (Postgres.ai)

Jika kita menambah max_wal_size, ternyata kita memudahkan kedua-dua checkpoint dan wal writer. Dan itu bagus.

Mari kita masukkan terabait dan hidup dengannya. Apa yang buruk tentangnya? Ini teruk, kerana jika gagal, kami akan mendaki berjam-jam, kerana pusat pemeriksaan itu sudah lama dan banyak yang telah berubah. Dan kita perlu melakukan semua REDO ini. Jadi kami melakukan siri kedua eksperimen.

Kami melakukan operasi dan melihat apabila pusat pemeriksaan hampir selesai, kami membunuh -9 Postgres dengan sengaja.

Dan selepas itu kita mulakannya semula, dan lihat berapa lama ia akan meningkat pada peralatan ini, iaitu berapa banyak ia akan REDO dalam keadaan buruk ini.

Dua kali saya akan perhatikan bahawa keadaannya teruk. Pertama, kami terhempas sejurus sebelum pusat pemeriksaan tamat, jadi kami mempunyai banyak kerugian. Dan kedua, kami melakukan operasi besar-besaran. Dan jika pusat pemeriksaan telah tamat masa, kemungkinan besar, kurang WAL akan dijana sejak pusat pemeriksaan terakhir. Iaitu, ia adalah kalah berganda.

Kami mengukur situasi sedemikian untuk saiz max_wal_size yang berbeza dan memahami bahawa jika max_wal_size ialah 64 gigabait, maka dalam kes terburuk berganda kami akan naik selama 10 minit. Dan kita fikir sama ada ia sesuai dengan kita atau tidak. Ini soalan perniagaan. Kita perlu menunjukkan gambar ini kepada mereka yang bertanggungjawab untuk keputusan perniagaan dan bertanya, β€œBerapa lama kita boleh berbaring paling lama sekiranya berlaku masalah? Bolehkah kita berbaring dalam keadaan yang paling teruk selama 3-5 minit? Dan anda membuat keputusan.

Dan inilah satu perkara yang menarik. Kami mempunyai beberapa laporan tentang Patroni pada persidangan itu. Dan mungkin anda menggunakannya. Ini adalah autofailover untuk Postgres. GitLab dan Data Egret bercakap tentang perkara ini.

Dan jika anda mempunyai autofailover yang datang dalam 30 saat, maka mungkin kita boleh berbaring selama 10 minit? Kerana kita akan beralih kepada replika pada ketika ini, dan semuanya akan baik-baik saja. Ini adalah satu perkara yang boleh dipertikaikan. Saya tidak tahu jawapan yang jelas. Saya hanya merasakan bahawa topik ini bukan sahaja mengenai pemulihan ranap.

Jika kita mengalami pemulihan yang lama selepas kegagalan, maka kita akan berasa tidak selesa dalam banyak situasi lain. Sebagai contoh, dalam eksperimen yang sama, apabila kita melakukan sesuatu dan kadang-kadang perlu menunggu selama 10 minit.

Saya masih tidak akan pergi terlalu jauh, walaupun kita mempunyai autofailover. Sebagai peraturan, nilai seperti 64, 100 gigabait adalah nilai yang baik. Kadang-kadang ia berbaloi untuk memilih kurang. Secara umum, ini adalah sains yang halus.

DELETE yang dihormati. Nikolay Samokhvalov (Postgres.ai)

Untuk melakukan lelaran, sebagai contoh, max_wal_size =1, 8, anda perlu mengulang operasi jisim berkali-kali. Anda berjaya. Dan pada asas yang sama anda mahu melakukannya sekali lagi, tetapi anda telah memadamkan semuanya. Apa nak buat?

Saya akan bercakap kemudian tentang penyelesaian kami, perkara yang kami lakukan untuk mengulangi dalam situasi sedemikian. Dan ini adalah pendekatan yang paling tepat.

Tetapi dalam kes ini, kami bernasib baik. Jika, seperti yang dinyatakan di sini "MULAI, PADAM, GULUNG", maka kita boleh ulangi PADAM. Maksudnya, jika kita sendiri yang membatalkannya, maka kita boleh mengulanginya. Dan secara fizikal pada anda data akan terletak di tempat yang sama. Anda tidak mendapat sebarang kembung. Anda boleh mengulangi DELETE tersebut.

DELETE dengan ROLLBACK ini sesuai untuk penalaan pusat pemeriksaan, walaupun anda tidak mempunyai makmal pangkalan data yang digunakan dengan betul.

DELETE yang dihormati. Nikolay Samokhvalov (Postgres.ai)

Kami membuat plat dengan satu lajur "i". Postgres mempunyai lajur utiliti. Mereka tidak kelihatan melainkan diminta secara khusus. Ini ialah: ctid, xmid, xmax.

Ctid ialah alamat fizikal. Halaman sifar, tuple pertama dalam halaman.

Ia boleh dilihat bahawa selepas ROOLBACK tuple kekal di tempat yang sama. Iaitu, kita boleh mencuba lagi, ia akan berkelakuan dengan cara yang sama. Ini adalah perkara utama.

DELETE yang dihormati. Nikolay Samokhvalov (Postgres.ai)

Xmax ialah masa kematian tupel. Ia telah dicop, tetapi Postgres tahu bahawa urus niaga ini telah ditarik balik, jadi tidak kira sama ada 0 atau urus niaga ditarik balik. Ini menunjukkan bahawa anda boleh melelakan pada DELETE dan menyemak operasi pukal tingkah laku sistem. Anda boleh membuat makmal pangkalan data untuk golongan miskin.

DELETE yang dihormati. Nikolay Samokhvalov (Postgres.ai)

Ini mengenai pengaturcara. Mengenai DBA juga, mereka sentiasa memarahi pengaturcara kerana ini: "Mengapa anda melakukan operasi yang panjang dan sukar?". Ini adalah topik serenjang yang sama sekali berbeza. Dulu ada pentadbiran, sekarang akan ada pembangunan.

Jelas sekali, kami tidak berpecah belah. Ia jelas. Adalah mustahil untuk tidak memecahkan DELETE sedemikian untuk timbunan berjuta-juta baris menjadi beberapa bahagian. Ia akan dilakukan selama 20 minit, dan semuanya akan berbaring. Tetapi, malangnya, walaupun pemaju berpengalaman membuat kesilapan, walaupun dalam syarikat yang sangat besar.

Mengapa penting untuk berbuka?

  • Jika kita melihat bahawa cakera keras, maka mari kita perlahankannya. Dan jika kita rosak, maka kita boleh menambah jeda, kita boleh memperlahankan pendikit.

  • Dan kami tidak akan menyekat orang lain untuk masa yang lama. Dalam sesetengah kes, tidak mengapa, jika anda memadamkan sampah sebenar yang tidak diusahakan oleh sesiapa, kemungkinan besar anda tidak akan menyekat sesiapa kecuali kerja autovakum, kerana ia akan menunggu sehingga transaksi selesai. Tetapi jika anda mengalih keluar sesuatu yang orang lain boleh minta, maka mereka akan disekat, akan ada beberapa jenis tindak balas berantai. Urus niaga yang lama harus dielakkan di laman web dan aplikasi mudah alih.

DELETE yang dihormati. Nikolay Samokhvalov (Postgres.ai)

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

Ini menarik. Saya sering melihat bahawa pembangun bertanya: "Apakah saiz pek yang harus saya pilih?".

Adalah jelas bahawa lebih besar saiz berkas, lebih kecil overhed urus niaga, iaitu, overhed tambahan daripada urus niaga. Tetapi pada masa yang sama, masa meningkat untuk transaksi ini.

Saya mempunyai peraturan yang sangat mudah: ambil seberapa banyak yang anda boleh, tetapi jangan pergi ke atas boleh laku sesaat.

Kenapa sekejap? Penerangannya sangat mudah dan boleh difahami oleh semua orang, walaupun orang bukan teknikal. Kita lihat reaksi. Mari ambil masa 50 milisaat. Jika sesuatu telah berubah, maka mata kita akan bertindak balas. Jika kurang, maka lebih sukar. Jika sesuatu bertindak balas selepas 100 milisaat, contohnya, anda mengklik tetikus dan ia menjawab anda selepas 100 milisaat, anda sudah merasakan kelewatan sedikit ini. Satu saat sudah dianggap sebagai brek.

Oleh itu, jika kita memecahkan operasi besar-besaran kita kepada pecahan 10 saat, maka kita mempunyai risiko bahawa kita akan menyekat seseorang. Dan ia akan berfungsi selama beberapa saat, dan orang ramai akan menyedarinya. Oleh itu, saya lebih suka untuk tidak melakukan lebih daripada satu saat. Tetapi pada masa yang sama, jangan pecahkannya dengan sangat halus, kerana overhed transaksi akan ketara. Pangkalan akan menjadi lebih keras, dan masalah lain yang berbeza mungkin timbul.

Kami memilih saiz pek. Dalam setiap kes, kita boleh melakukannya secara berbeza. Boleh automatik. Dan kami yakin dengan kecekapan pemprosesan satu pek. Iaitu, kami melakukan DELETE satu pek atau KEMASKINI.

By the way, semua yang saya cakapkan bukan sahaja tentang DELETE. Seperti yang anda sangka, ini adalah sebarang operasi pukal pada data.

Dan kami melihat bahawa rancangan itu sangat baik. Anda boleh melihat imbasan indeks, imbasan indeks sahaja adalah lebih baik. Dan kami mempunyai sejumlah kecil data yang terlibat. Dan kurang daripada satu saat memenuhi. Super.

Dan kita masih perlu memastikan bahawa tiada kemerosotan. Ia berlaku bahawa pek pertama dengan cepat bersenam, dan kemudian ia menjadi lebih teruk, lebih teruk dan lebih teruk. Prosesnya sedemikian rupa sehingga anda perlu banyak menguji. Inilah sebenarnya tujuan makmal pangkalan data.

Dan kami masih perlu menyediakan sesuatu supaya ia membolehkan kami mengikuti ini dengan betul dalam pengeluaran. Sebagai contoh, kita boleh menulis masa dalam log, kita boleh menulis di mana kita berada sekarang dan siapa yang kita telah padamkan sekarang. Dan ini akan membolehkan kita memahami apa yang berlaku kemudian. Dan sekiranya berlaku masalah, cepat cari masalahnya.

Jika kita perlu menyemak kecekapan permintaan dan kita perlu mengulangi berkali-kali, maka ada perkara seperti rakan bot. Dia sudah bersedia. Ia digunakan oleh berpuluh-puluh pembangun setiap hari. Dan dia tahu bagaimana untuk memberikan pangkalan data terabait yang besar atas permintaan dalam 30 saat, salinan anda sendiri. Dan anda boleh memadamkan sesuatu di sana dan sebut RESET, dan padamkannya semula. Anda boleh mencubanya dengan cara ini. Saya melihat masa depan untuk perkara ini. Dan kami sudah melakukannya.

DELETE yang dihormati. Nikolay Samokhvalov (Postgres.ai)

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

Apakah strategi pembahagian? Saya melihat 3 strategi pembahagian berbeza yang digunakan oleh pembangun pada pek.

Yang pertama sangat mudah. Kami mempunyai ID berangka. Dan mari kita memecahkannya kepada selang yang berbeza dan bekerja dengan itu. Kelemahannya adalah jelas. Dalam segmen pertama, kita mungkin mempunyai 100 baris sampah sebenar, dalam 5 baris kedua atau tidak sama sekali, atau semua 1 baris akan menjadi sampah. Kerja yang sangat tidak rata, tetapi ia mudah pecah. Mereka mengambil ID maksimum dan menghancurkannya. Ini adalah pendekatan yang naif.

Strategi kedua ialah pendekatan seimbang. Ia digunakan dalam Gitlab. Mereka mengambil dan mengimbas meja. Kami menemui sempadan pek ID supaya setiap pek mempunyai tepat 10 rekod. Dan letakkan mereka dalam barisan. Dan kemudian kami proses. Anda boleh melakukan ini dalam berbilang benang.

Dalam strategi pertama, juga, dengan cara ini, anda boleh melakukan ini dalam beberapa utas. Ia tidak sukar.

DELETE yang dihormati. Nikolay Samokhvalov (Postgres.ai)

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

Tetapi ada pendekatan yang lebih sejuk dan lebih baik. Ini adalah strategi ketiga. Dan apabila boleh, lebih baik memilihnya. Kami melakukan ini berdasarkan indeks khas. Dalam kes ini, kemungkinan besar ia akan menjadi indeks mengikut keadaan sampah dan ID kami. Kami akan memasukkan ID supaya ia hanya imbasan indeks supaya kami tidak pergi ke timbunan.

Secara amnya, imbasan indeks sahaja lebih pantas daripada imbasan indeks.

DELETE yang dihormati. Nikolay Samokhvalov (Postgres.ai)

Dan kami segera mencari ID kami yang ingin kami padamkan. BATCH_SIZE kami pilih lebih awal. Dan kami bukan sahaja mendapatkannya, kami mendapatkannya dengan cara yang istimewa dan segera menggodamnya. Tetapi kami mengunci supaya jika mereka sudah terkunci, kami tidak mengunci mereka, tetapi teruskan dan ambil yang seterusnya. Ini untuk kemas kini langkau dikunci. Ciri hebat Postgres ini membolehkan kami bekerja dalam beberapa utas jika kami mahu. Ia boleh dilakukan dalam satu aliran. Dan di sini terdapat CTE - ini adalah satu permintaan. Dan kami mempunyai pemadaman sebenar yang berlaku di tingkat dua CTE ini - returning *. Anda boleh memulangkan id, tetapi lebih baik *jika anda tidak mempunyai banyak data pada setiap baris.

DELETE yang dihormati. Nikolay Samokhvalov (Postgres.ai)

Mengapa kita memerlukannya? Inilah yang perlu kita laporkan semula. Kami kini telah memadamkan begitu banyak baris sebenarnya. Dan kami mempunyai sempadan mengikut ID atau dengan created_at seperti ini. Anda boleh melakukan min, maks. Sesuatu yang lain boleh dilakukan. Anda boleh mengisi banyak di sini. Dan ia sangat mudah untuk pemantauan.

Terdapat satu lagi nota mengenai indeks. Jika kami memutuskan bahawa kami memerlukan indeks khas untuk tugas ini, maka kami perlu memastikan bahawa ia tidak merosakkan kemas kini tuple sahaja. Iaitu, Postgres mempunyai statistik sedemikian. Ini boleh dilihat dalam pg_stat_user_tables untuk jadual anda. Anda boleh melihat sama ada kemas kini hangat sedang digunakan atau tidak.

Terdapat situasi apabila indeks baharu anda boleh memotongnya. Dan anda mempunyai semua kemas kini lain yang sudah berfungsi, perlahankan. Bukan hanya kerana indeks muncul (setiap indeks memperlahankan sedikit kemas kini, tetapi sedikit), tetapi di sini ia masih merosakkannya. Dan adalah mustahil untuk membuat pengoptimuman khas untuk jadual ini. Ini berlaku kadang-kadang. Ini adalah kehalusan yang tidak ramai orang ingat. Dan garu ini mudah untuk dipijak. Kadang-kadang ia berlaku bahawa anda perlu mencari pendekatan dari sisi lain dan masih melakukannya tanpa indeks baru ini, atau membuat indeks lain, atau dengan cara lain, sebagai contoh, anda boleh menggunakan kaedah kedua.

Tetapi ini adalah strategi yang paling optimum, bagaimana untuk berpecah kepada kelompok dan menembak pada kelompok dengan satu permintaan, padam sedikit, dll.

DELETE yang dihormati. Nikolay Samokhvalov (Postgres.ai)

Transaksi yang panjang https://gitlab.com/snippets/1890447

Autovakum disekat - https://gitlab.com/snippets/1889668

isu menyekat - https://gitlab.com/snippets/1890428

Kesilapan #5 adalah besar. Nikolai dari Okmeter bercakap tentang pemantauan Postgres. Pemantauan Postgres Ideal, malangnya, tidak wujud. Ada yang lebih dekat, ada yang lebih jauh. Okmeter cukup dekat untuk menjadi sempurna, tetapi banyak yang hilang dan perlu ditambah. Anda perlu bersedia untuk ini.

Sebagai contoh, tupel mati paling baik dipantau. Jika anda mempunyai banyak benda mati di dalam meja, maka ada sesuatu yang tidak kena. Adalah lebih baik untuk bertindak balas sekarang, jika tidak mungkin terdapat kemerosotan, dan kita boleh berbaring. Ia berlaku.

Sekiranya terdapat IO yang besar, maka jelas bahawa ini tidak baik.

Transaksi lama juga. Urus niaga lama tidak boleh dibenarkan pada OLTP. Dan berikut ialah pautan ke coretan yang membolehkan anda mengambil coretan ini dan sudah melakukan beberapa penjejakan urus niaga yang lama.

Mengapa urus niaga yang lama tidak baik? Kerana semua kunci akan dilepaskan hanya pada akhirnya. Dan kita kacau semua orang. Selain itu, kami menyekat autovakum untuk semua jadual. Ia tidak baik sama sekali. Walaupun anda telah mendayakan siap sedia panas pada replika, ia masih buruk. Secara umum, tidak ada tempat yang lebih baik untuk mengelakkan transaksi yang panjang.

Jika kita mempunyai banyak jadual yang tidak dikosongkan, maka kita perlu mempunyai makluman. Di sini keadaan sedemikian mungkin. Kita secara tidak langsung boleh menjejaskan operasi autovakum. Ini adalah coretan daripada Avito, yang saya perbaiki sedikit. Dan ternyata ia menjadi alat yang menarik untuk melihat apa yang kita ada dengan autovakum. Sebagai contoh, beberapa meja sedang menunggu di sana dan tidak akan menunggu giliran mereka. Anda juga perlu memasukkannya ke dalam pemantauan dan mempunyai makluman.

Dan mengeluarkan sekatan. Hutan pokok blok. Saya suka mengambil sesuatu daripada seseorang dan memperbaikinya. Di sini saya mengambil CTE rekursif yang keren daripada Data Egret yang menunjukkan hutan pokok kunci. Ini adalah alat diagnostik yang baik. Dan berdasarkannya, anda juga boleh membina pemantauan. Tetapi ini mesti dilakukan dengan berhati-hati. Anda perlu membuat kenyataan_masa tamat untuk diri sendiri. Dan lock_timeout adalah wajar.

DELETE yang dihormati. Nikolay Samokhvalov (Postgres.ai)

Kadang-kadang semua ralat ini berlaku dalam jumlah.

Pada pendapat saya, kesilapan utama di sini adalah organisasi. Ia adalah organisasi, kerana teknik itu tidak menarik. Ini nombor 2 - mereka menyemak di tempat yang salah.

Kami menyemak di tempat yang salah, kerana kami tidak mempunyai klon pengeluaran, yang mudah untuk diperiksa. Pembangun mungkin tidak mempunyai akses kepada pengeluaran sama sekali.

Dan kami menyemak tidak di sana. Jika kami telah menyemak di sana, kami akan melihatnya sendiri. Pembangun melihat semua ini walaupun tanpa DBA jika dia menyemaknya dalam persekitaran yang baik, di mana terdapat jumlah data yang sama dan lokasi yang sama. Dia akan melihat semua kemerosotan ini dan dia akan malu.

Lebih lanjut mengenai autovakum. Selepas kami telah melakukan sapuan besar-besaran beberapa juta baris, kami masih perlu melakukan REPACK. Ini amat penting untuk indeks. Mereka akan berasa teruk selepas kami membersihkan segala-galanya di sana.

Dan jika anda ingin mengembalikan kerja pembersihan harian, maka saya cadangkan melakukannya dengan lebih kerap, tetapi lebih kecil. Ia boleh sekali seminit atau lebih kerap sedikit. Dan anda perlu memantau dua perkara: bahawa perkara ini tidak mempunyai ralat dan ia tidak ketinggalan. Helah yang saya tunjukkan hanya akan menyelesaikan ini.

DELETE yang dihormati. Nikolay Samokhvalov (Postgres.ai)

Apa yang kami lakukan ialah sumber terbuka. Ia disiarkan di GitLab. Dan kami membuatnya supaya orang ramai boleh menyemak walaupun tanpa DBA. Kami sedang melakukan makmal pangkalan data, iaitu, kami memanggil komponen asas yang Joe sedang bekerja. Dan anda boleh mengambil salinan pengeluaran. Sekarang terdapat pelaksanaan Joe untuk slack, anda boleh mengatakan di sana: "terangkan permintaan itu dan itu" dan segera dapatkan hasilnya untuk salinan pangkalan data anda. Anda juga boleh PADAM di sana, dan tiada siapa yang akan menyedarinya.

DELETE yang dihormati. Nikolay Samokhvalov (Postgres.ai)

Katakan anda mempunyai 10 terabait, kami membuat makmal pangkalan data juga 10 terabait. Dan dengan pangkalan data 10 terabait serentak, 10 pembangun boleh berfungsi serentak. Semua orang boleh melakukan apa yang mereka mahu. Boleh padam, jatuhkan, dll. Itu fantasi. Kita akan bercakap tentang ini esok.

DELETE yang dihormati. Nikolay Samokhvalov (Postgres.ai)

Ini dipanggil peruntukan nipis. Ini adalah peruntukan yang halus. Ini adalah sejenis fantasi yang sangat menghapuskan kelewatan dalam pembangunan, dalam ujian dan menjadikan dunia tempat yang lebih baik dalam hal ini. Iaitu, ia hanya membolehkan anda mengelakkan masalah dengan operasi pukal.

Contoh: pangkalan data 5 terabait, mendapat salinan dalam masa kurang daripada 30 saat. Dan ia tidak bergantung pada saiz, iaitu, tidak kira berapa terabait.

Hari ini anda boleh pergi ke postgres.ai dan gali alat kami. Anda boleh mendaftar untuk melihat apa yang ada. Anda boleh memasang bot ini. Ianya percuma. tulis.

soalan

Selalunya dalam situasi sebenar ternyata data yang sepatutnya kekal dalam jadual adalah lebih sedikit daripada yang perlu dipadamkan. Iaitu, dalam keadaan sedemikian, selalunya lebih mudah untuk melaksanakan pendekatan sedemikian, apabila lebih mudah untuk mencipta objek baru, salin hanya data yang diperlukan di sana, dan letakkan jadual lama. Adalah jelas bahawa pendekatan terprogram diperlukan untuk masa ini, semasa anda akan beralih. Bagaimanakah pendekatan ini?

Ini adalah pendekatan yang sangat baik dan tugas yang sangat baik. Ia sangat serupa dengan apa yang pg_repack lakukan, ia sangat serupa dengan apa yang anda perlu lakukan apabila anda membuat ID 4 bait. Banyak rangka kerja melakukan ini beberapa tahun yang lalu, dan hanya plat telah membesar, dan ia perlu ditukar kepada 8 bait.

Tugasan ini agak sukar. Kita berjaya. Dan anda perlu berhati-hati. Terdapat kunci, dsb. Tetapi ia sedang dilakukan. Iaitu, pendekatan standard adalah untuk pergi dengan pg_repack. Anda mengisytiharkan label sedemikian. Dan sebelum anda mula memuat naik data syot kilat ke dalamnya, anda juga mengisytiharkan satu plat yang menjejaki semua perubahan. Terdapat helah yang anda mungkin tidak menjejaki beberapa perubahan. Terdapat kehalusan. Dan kemudian anda bertukar dengan melancarkan perubahan. Akan ada jeda singkat apabila kami menutup semua orang, tetapi secara umum ini sedang dilakukan.

Jika anda melihat pg_repack pada GitHub, kemudian di sana, apabila terdapat tugas untuk menukar ID daripada int 4 kepada int 8, maka terdapat idea untuk menggunakan pg_repack itu sendiri. Ini juga mungkin, tetapi ia agak meretas, tetapi ia juga akan berfungsi untuk ini. Anda boleh campur tangan dalam pencetus yang pg_repack gunakan dan katakan di sana: "Kami tidak memerlukan data ini", iaitu kami hanya memindahkan apa yang kami perlukan. Dan kemudian dia hanya bertukar dan itu sahaja.

Dengan pendekatan ini, kami masih mendapat salinan kedua jadual, di mana data telah diindeks dan disusun dengan sangat sekata dengan indeks yang cantik.

Kembung tidak hadir, ia adalah pendekatan yang baik. Tetapi saya tahu bahawa terdapat percubaan untuk membangunkan automasi untuk ini, iaitu untuk membuat penyelesaian universal. Saya boleh menghubungi anda dengan automasi ini. Ia ditulis dalam Python, yang merupakan perkara yang baik.

Saya hanya sedikit dari dunia MySQL, jadi saya datang untuk mendengar. Dan kami menggunakan pendekatan ini.

Tetapi ia hanya jika kita mempunyai 90%. Jika kita mempunyai 5%, maka ia tidak begitu baik untuk menggunakannya.

Terima kasih atas laporan itu! Jika tiada sumber untuk membuat salinan lengkap prod, adakah terdapat sebarang algoritma atau formula untuk mengira beban atau saiz?

Soalan yang baik. Setakat ini, kami dapat mencari pangkalan data berbilang terabait. Walaupun perkakasan di sana tidak sama, contohnya, kurang memori, kurang pemproses dan cakera tidak betul-betul sama, tetapi kami tetap melakukannya. Sekiranya tiada tempat, maka anda perlu berfikir. Biar saya fikir sehingga esok, awak datang, kita akan bercakap, ini soalan yang bagus.

Terima kasih atas laporan itu! Anda mula-mula bermula tentang fakta bahawa terdapat Postgres yang hebat, yang mempunyai batasan ini dan itu, tetapi ia sedang berkembang. Dan ini semua adalah tongkat pada umumnya. Bukankah ini semua bercanggah dengan pembangunan Postgres itu sendiri, di mana beberapa DELETE deferent akan muncul atau sesuatu yang lain yang sepatutnya mengekalkan pada tahap yang rendah apa yang kita cuba calitkan dengan beberapa cara aneh kita di sini?

Jika kami berkata dalam SQL untuk memadam atau mengemas kini banyak rekod dalam satu transaksi, maka bagaimanakah Postgres boleh mengedarkannya di sana? Kami secara fizikal terhad dalam operasi. Kami masih akan melakukannya untuk masa yang lama. Dan kami akan mengunci pada masa ini, dsb.

Selesai dengan indeks.

Saya boleh menganggap bahawa penalaan pusat pemeriksaan yang sama boleh diautomasikan. Suatu hari nanti mungkin. Tetapi kemudian saya tidak begitu memahami soalan itu.

Persoalannya, adakah terdapat vektor pembangunan yang pergi ke sana sini, dan di sini anda berjalan selari? Itu. Tidakkah mereka memikirkannya lagi?

Saya bercakap tentang prinsip yang boleh digunakan sekarang. Terdapat bot lain Nancy, dengan ini anda boleh melakukan penalaan pusat pemeriksaan automatik. Adakah ia suatu hari nanti akan berada di Postgres? Entahlah, belum lagi dibincangkan. Kita masih jauh dari itu. Tetapi ada saintis yang membuat sistem baru. Dan mereka mendorong kami ke dalam indeks automatik. Ada perkembangan. Sebagai contoh, anda boleh melihat penalaan automatik. Ia memilih parameter secara automatik. Tetapi dia tidak akan melakukan penalaan pusat pemeriksaan untuk anda lagi. Iaitu, ia akan mengambil untuk prestasi, penimbal shell, dll.

Dan untuk penalaan pusat pemeriksaan, anda boleh melakukan ini: jika anda mempunyai seribu kluster dan perkakasan yang berbeza, mesin maya yang berbeza dalam awan, anda boleh menggunakan bot kami Nancy melakukan automasi. Dan max_wal_size akan dipilih mengikut tetapan sasaran anda secara automatik. Tetapi setakat ini ini tidak terlalu dekat dalam inti, malangnya.

Selamat petang Anda bercakap tentang bahaya urus niaga yang lama. Anda mengatakan bahawa autovakum disekat sekiranya berlaku pemadaman. Bagaimana lagi ia memudaratkan kita? Kerana kita lebih banyak bercakap tentang mengosongkan ruang dan dapat menggunakannya. Apa lagi yang kita kurang?

Autovacuum mungkin bukan masalah terbesar di sini. Dan hakikat bahawa transaksi yang lama boleh mengunci transaksi lain, kemungkinan ini lebih berbahaya. Dia mungkin bertemu atau tidak. Jika dia bertemu, maka ia boleh menjadi sangat teruk. Dan dengan autovakum - ini juga menjadi masalah. Terdapat dua masalah dengan transaksi lama dalam OLTP: kunci dan autovakum. Dan jika anda mempunyai maklum balas siap sedia panas didayakan pada replika, maka anda masih akan menerima kunci autovakum pada induk, ia akan tiba dari replika. Tetapi sekurang-kurangnya tidak akan ada kunci. Dan akan ada loks. Kita bercakap tentang perubahan data, jadi kunci adalah perkara penting di sini. Dan jika ini semua untuk masa yang lama, maka semakin banyak transaksi dikunci. Mereka boleh mencuri orang lain. Dan pokok lok muncul. Saya menyediakan pautan ke coretan. Dan masalah ini menjadi lebih ketara lebih cepat daripada masalah dengan autovakum, yang hanya boleh terkumpul.

Terima kasih atas laporan itu! Anda memulakan laporan anda dengan mengatakan bahawa anda telah menguji secara salah. Kami meneruskan idea kami bahawa kami perlu mengambil peralatan yang sama, dengan pangkalan dengan cara yang sama. Katakan kami memberi pemaju asas. Dan dia menuruti permintaan itu. Dan dia nampaknya baik-baik saja. Tetapi dia tidak menyemak secara langsung, tetapi secara langsung, sebagai contoh, kami mempunyai beban 60-70%. Dan walaupun kita menggunakan penalaan ini, ia tidak berfungsi dengan baik.

Mempunyai pakar dalam pasukan dan menggunakan pakar DBA yang boleh meramalkan perkara yang akan berlaku dengan beban latar belakang sebenar adalah penting. Apabila kami hanya melakukan perubahan bersih kami, kami melihat gambar itu. Tetapi pendekatan yang lebih maju, apabila kami melakukan perkara yang sama sekali lagi, tetapi dengan beban yang disimulasikan dengan pengeluaran. Ia agak sejuk. Sehingga itu, anda perlu membesar. Dah macam orang dewasa. Kami hanya melihat apa yang kami ada dan juga melihat sama ada kami mempunyai sumber yang mencukupi. Itu soalan yang bagus.

Apabila kita sudah melakukan pilihan sampah dan kita mempunyai, sebagai contoh, bendera yang dipadamkan

Inilah yang autovacuum lakukan secara automatik dalam Postgres.

Oh, adakah dia melakukannya?

Autovacuum ialah pengumpul sampah.

Thank you!

Terima kasih atas laporan itu! Adakah terdapat pilihan untuk segera mereka bentuk pangkalan data dengan pembahagian sedemikian rupa sehingga semua sampah menjadi kotor dari meja utama di suatu tempat ke tepi?

Sudah tentu ada.

Adakah mungkin untuk melindungi diri kita jika kita telah mengunci meja yang tidak boleh digunakan?

Sudah tentu ada. Tapi macam soalan ayam dan telur. Jika kita semua tahu apa yang akan berlaku pada masa hadapan, maka, sudah tentu, kita akan melakukan segala-galanya dengan baik. Tetapi perniagaan berubah, terdapat lajur baru, permintaan baru. Dan kemudian – oops, kami mahu mengalih keluarnya. Tetapi keadaan ideal ini, dalam kehidupan ia berlaku, tetapi tidak selalu. Tetapi secara keseluruhan ia adalah idea yang baik. Hanya potong dan itu sahaja.

Sumber: www.habr.com

Tambah komen