{"id":2791,"date":"2024-01-08T11:26:23","date_gmt":"2024-01-08T05:56:23","guid":{"rendered":"https:\/\/bentocase.tanshcreative.com\/?p=2791"},"modified":"2026-08-28T10:02:59","modified_gmt":"2026-08-28T10:02:59","slug":"jangan-pernah-jalankan-create-index-di-production-saat-jam-sibuk","status":"publish","type":"post","link":"https:\/\/agussyarif.my.id\/index.php\/2024\/01\/08\/jangan-pernah-jalankan-create-index-di-production-saat-jam-sibuk\/","title":{"rendered":"Jangan Pernah Jalankan CREATE INDEX di Production Saat Jam Sibuk! (Kecuali Tahu Rahasia Ini)"},"content":{"rendered":"\t\t<div data-elementor-type=\"wp-post\" data-elementor-id=\"2791\" class=\"elementor elementor-2791\">\n\t\t\t\t<div class=\"elementor-element elementor-element-491a42c3 e-flex e-con-boxed e-con e-parent\" data-id=\"491a42c3\" data-element_type=\"container\" data-e-type=\"container\">\n\t\t\t\t\t<div class=\"e-con-inner\">\n\t\t\t\t<div class=\"elementor-element elementor-element-4f724190 elementor-widget elementor-widget-text-editor\" data-id=\"4f724190\" data-element_type=\"widget\" data-e-type=\"widget\" data-widget_type=\"text-editor.default\">\n\t\t\t\t\t\t\t\t\t<p>Lebih dari dua tahun saya berkecimpung mengelola <i data-path-to-node=\"4\" data-index-in-node=\"50\">database<\/i> skala <i data-path-to-node=\"4\" data-index-in-node=\"65\">enterprise<\/i> dan PostgreSQL, jika ditanya apa salah satu penyebab <i data-path-to-node=\"4\" data-index-in-node=\"129\">downtime<\/i> konyol yang paling sering saya temui, jawabannya selalu sama: <b data-path-to-node=\"4\" data-index-in-node=\"200\">Mengeksekusi manipulasi Index di tabel raksasa (VLDB) pada jam operasional<\/b><\/p>\t\t\t\t\t\t\t\t<\/div>\n\t\t\t\t<div class=\"elementor-element elementor-element-526410c4 elementor-widget elementor-widget-spacer\" data-id=\"526410c4\" data-element_type=\"widget\" data-e-type=\"widget\" data-widget_type=\"spacer.default\">\n\t\t\t\t\t\t\t<div class=\"elementor-spacer\">\n\t\t\t<div class=\"elementor-spacer-inner\"><\/div>\n\t\t<\/div>\n\t\t\t\t\t\t<\/div>\n\t\t\t\t<div class=\"elementor-element elementor-element-3b9abaf6 elementor-widget elementor-widget-text-editor\" data-id=\"3b9abaf6\" data-element_type=\"widget\" data-e-type=\"widget\" data-widget_type=\"text-editor.default\">\n\t\t\t\t\t\t\t\t\t<p>Niatnya baik: Aplikasi mulai melambat, lalu <i data-path-to-node=\"5\" data-index-in-node=\"44\">Backend Engineer<\/i> atau <i data-path-to-node=\"5\" data-index-in-node=\"66\">DBA<\/i> memutuskan untuk membuat indeks baru agar <i data-path-to-node=\"5\" data-index-in-node=\"112\">query<\/i> kembali ngebut. Mereka mengetik <code data-path-to-node=\"5\" data-index-in-node=\"150\">CREATE INDEX idx_baru ON tabel_transaksi(kolom_a);<\/code>, menekan <i data-path-to-node=\"5\" data-index-in-node=\"210\">Enter<\/i>, dan tiba-tiba&#8230; <b data-path-to-node=\"5\" data-index-in-node=\"234\">BAM!<\/b> Seluruh aplikasi berhenti merespons. <i data-path-to-node=\"5\" data-index-in-node=\"276\">Timeout<\/i> di mana-mana. Layanan pelanggan berteriak.<\/p>\t\t\t\t\t\t\t\t<\/div>\n\t\t\t\t<div class=\"elementor-element elementor-element-5949c4f6 elementor-widget elementor-widget-text-editor\" data-id=\"5949c4f6\" data-element_type=\"widget\" data-e-type=\"widget\" data-widget_type=\"text-editor.default\">\n\t\t\t\t\t\t\t\t\t<p>Apa yang sebenarnya terjadi di balik layar PostgreSQL (Internal Engine)? Mari kita bedah apa yang dilakukan <i data-path-to-node=\"6\" data-index-in-node=\"108\">Lock Manager<\/i>, dan bagaimana cara profesional menangani ini dengan status <b data-path-to-node=\"6\" data-index-in-node=\"181\">Zero Downtime<\/b>.<\/p>\t\t\t\t\t\t\t\t<\/div>\n\t\t\t\t<div class=\"elementor-element elementor-element-6c826142 elementor-widget elementor-widget-text-editor\" data-id=\"6c826142\" data-element_type=\"widget\" data-e-type=\"widget\" data-widget_type=\"text-editor.default\">\n\t\t\t\t\t\t\t\t\t<p>Jebakan Batman: Standard Indexing Operations<\/p>\t\t\t\t\t\t\t\t<\/div>\n\t\t\t\t<div class=\"elementor-element elementor-element-222cd02a elementor-widget elementor-widget-spacer\" data-id=\"222cd02a\" data-element_type=\"widget\" data-e-type=\"widget\" data-widget_type=\"spacer.default\">\n\t\t\t\t\t\t\t<div class=\"elementor-spacer\">\n\t\t\t<div class=\"elementor-spacer-inner\"><\/div>\n\t\t<\/div>\n\t\t\t\t\t\t<\/div>\n\t\t\t\t<div class=\"elementor-element elementor-element-700646c0 elementor-widget elementor-widget-dtr-quote\" data-id=\"700646c0\" data-element_type=\"widget\" data-e-type=\"widget\" data-widget_type=\"dtr-quote.default\">\n\t\t\t\t<div class=\"elementor-widget-container\">\n\t\t\t\t\t<div class=\"dtr-quote dtr-quote__left-align clearfix\"><blockquote>\u201cDi dalam memori PostgreSQL, terdapat komponen krusial bernama Lock Manager. Komponen ini bertugas mengevaluasi Conflict Matrix untuk memastikan konsistensi data.\u201d<\/blockquote><p class=\"dtr-quote__author\">Agus Syarif<\/p><span class=\"dtr-quote__source\">Senior Database Engineer<\/span><\/div>\t\t\t\t<\/div>\n\t\t\t\t<\/div>\n\t\t\t\t<div class=\"elementor-element elementor-element-1e4aa64d elementor-widget elementor-widget-spacer\" data-id=\"1e4aa64d\" data-element_type=\"widget\" data-e-type=\"widget\" data-widget_type=\"spacer.default\">\n\t\t\t\t\t\t\t<div class=\"elementor-spacer\">\n\t\t\t<div class=\"elementor-spacer-inner\"><\/div>\n\t\t<\/div>\n\t\t\t\t\t\t<\/div>\n\t\t\t\t<div class=\"elementor-element elementor-element-7d0b231e elementor-widget elementor-widget-image\" data-id=\"7d0b231e\" data-element_type=\"widget\" data-e-type=\"widget\" data-widget_type=\"image.default\">\n\t\t\t\t\t\t\t\t\t\t\t\t<figure class=\"wp-caption\">\n\t\t\t\t\t\t\t\t\t\t<img decoding=\"async\" src=\"https:\/\/agussyarif.my.id\/wp-content\/uploads\/elementor\/thumbs\/Gemini_Generated_Image_yvybw8yvybw8yvyb-scaled-rsk9dxrcbwshil425npwvkvf3y5kiqmeywmic3tsns.jpg\" title=\"Postgres Index Operation\" alt=\"Postgres Index Operation\" loading=\"lazy\" \/>\t\t\t\t\t\t\t\t\t\t\t<figcaption class=\"widget-image-caption wp-caption-text\">Gambar 2: Postgres Index Operation<\/figcaption>\n\t\t\t\t\t\t\t\t\t\t<\/figure>\n\t\t\t\t\t\t\t\t\t<\/div>\n\t\t\t\t<div class=\"elementor-element elementor-element-42306043 elementor-widget elementor-widget-text-editor\" data-id=\"42306043\" data-element_type=\"widget\" data-e-type=\"widget\" data-widget_type=\"text-editor.default\">\n\t\t\t\t\t\t\t\t\t<ol><li><b data-path-to-node=\"11\" data-index-in-node=\"0\">Tragedi <code data-path-to-node=\"11\" data-index-in-node=\"11\">CREATE INDEX<\/code> &amp; <code data-path-to-node=\"11\" data-index-in-node=\"26\">REINDEX<\/code> (SHARE Lock)<\/b> Saat kita menjalankan perintah standar <code data-path-to-node=\"11\" data-index-in-node=\"86\">CREATE INDEX<\/code> atau <code data-path-to-node=\"11\" data-index-in-node=\"104\">REINDEX<\/code>, PostgreSQL akan mengambil <b data-path-to-node=\"11\" data-index-in-node=\"139\">SHARE Lock<\/b> pada tabel tersebut.<ul><li><b data-path-to-node=\"12,0,0\" data-index-in-node=\"0\">Apa yang lolos?<\/b> Aplikasi <i data-path-to-node=\"12,0,0\" data-index-in-node=\"25\">Reporting<\/i> yang melakukan <code data-path-to-node=\"12,0,0\" data-index-in-node=\"50\">SELECT<\/code> masih bisa membaca data.<\/li><li><b data-path-to-node=\"12,1,0\" data-index-in-node=\"0\">Apa yang tersumbat?<\/b> Aplikasi <i data-path-to-node=\"12,1,0\" data-index-in-node=\"29\">Transactional<\/i> yang melakukan <code data-path-to-node=\"12,1,0\" data-index-in-node=\"58\">UPDATE<\/code>, <code data-path-to-node=\"12,1,0\" data-index-in-node=\"66\">INSERT<\/code>, atau <code data-path-to-node=\"12,1,0\" data-index-in-node=\"79\">DELETE<\/code> akan diblokir total! Jika tabel tersebut berukuran ratusan Gigabyte dan proses indeks memakan waktu 30 menit, artinya aplikasi kita tidak bisa menerima transaksi baru selama setengah jam.<\/li><\/ul><\/li><li><b data-path-to-node=\"13\" data-index-in-node=\"0\">Bencana <code data-path-to-node=\"13\" data-index-in-node=\"11\">DROP INDEX<\/code> (ACCESS EXCLUSIVE Lock)<\/b> Banyak yang berpikir, <i data-path-to-node=\"13\" data-index-in-node=\"68\">&#8220;Ah, menghapus indeks kan cepat, hapus saja.&#8221;<\/i> Ini adalah jebakan paling mematikan. Perintah standar <code data-path-to-node=\"13\" data-index-in-node=\"168\">DROP INDEX<\/code> akan meminta <b data-path-to-node=\"13\" data-index-in-node=\"192\">ACCESS EXCLUSIVE Lock<\/b>.<ul><li><b data-path-to-node=\"14,0,0\" data-index-in-node=\"0\">Dampaknya?<\/b> <i data-path-to-node=\"14,0,0\" data-index-in-node=\"11\">Total Traffic Jam!<\/i> Lock ini memblokir <b data-path-to-node=\"14,0,0\" data-index-in-node=\"49\">SEMUANYA<\/b>. Baik aplikasi transaksional (<code data-path-to-node=\"14,0,0\" data-index-in-node=\"88\">UPDATE<\/code>\/<code data-path-to-node=\"14,0,0\" data-index-in-node=\"95\">INSERT<\/code>) maupun aplikasi pelaporan (<code data-path-to-node=\"14,0,0\" data-index-in-node=\"130\">SELECT<\/code>) akan dipaksa mengantre sampai indeks selesai dihapus.<\/li><\/ul><\/li><\/ol>\t\t\t\t\t\t\t\t<\/div>\n\t\t\t\t<div class=\"elementor-element elementor-element-2ddbdf88 elementor-widget elementor-widget-text-editor\" data-id=\"2ddbdf88\" data-element_type=\"widget\" data-e-type=\"widget\" data-widget_type=\"text-editor.default\">\n\t\t\t\t\t\t\t\t\t<h5 data-path-to-node=\"15\">Solusi : Kekuatan Sakti <code data-path-to-node=\"15\" data-index-in-node=\"31\">CONCURRENTLY<\/code><\/h5><p data-path-to-node=\"16\">Lalu, bagaimana cara <i data-path-to-node=\"16\" data-index-in-node=\"21\">Tech Giants<\/i> dan perusahaan <i data-path-to-node=\"16\" data-index-in-node=\"48\">Enterprise<\/i> melakukan pemeliharaan indeks tanpa mematikan layanan? Jawabannya ada pada satu kata ajaib: <b data-path-to-node=\"16\" data-index-in-node=\"151\"><code data-path-to-node=\"16\" data-index-in-node=\"151\">CONCURRENTLY<\/code><\/b>.<\/p>\t\t\t\t\t\t\t\t<\/div>\n\t\t\t\t<div class=\"elementor-element elementor-element-700af75 elementor-widget elementor-widget-text-editor\" data-id=\"700af75\" data-element_type=\"widget\" data-e-type=\"widget\" data-widget_type=\"text-editor.default\">\n\t\t\t\t\t\t\t\t\t<p data-path-to-node=\"17\">Dengan menambahkan <i data-path-to-node=\"17\" data-index-in-node=\"19\">keyword<\/i> ini (<code data-path-to-node=\"17\" data-index-in-node=\"32\">CREATE INDEX CONCURRENTLY<\/code> atau <code data-path-to-node=\"17\" data-index-in-node=\"63\">DROP INDEX CONCURRENTLY<\/code>), kita mengubah cara PostgreSQL meminta izin pada <i data-path-to-node=\"17\" data-index-in-node=\"137\">Lock Manager<\/i>. Alih-alih meminta lock yang agresif, PostgreSQL hanya akan meminta <b data-path-to-node=\"17\" data-index-in-node=\"218\">SHARE UPDATE EXCLUSIVE Lock<\/b>.<\/p>\t\t\t\t\t\t\t\t<\/div>\n\t\t\t\t<div class=\"elementor-element elementor-element-3758d6f elementor-widget elementor-widget-text-editor\" data-id=\"3758d6f\" data-element_type=\"widget\" data-e-type=\"widget\" data-widget_type=\"text-editor.default\">\n\t\t\t\t\t\t\t\t\t<p data-path-to-node=\"15\">Mengapa ini sangat aman? Karena lock jenis ini sangat ramah. Ia mengizinkan <code data-path-to-node=\"18\" data-index-in-node=\"76\">ACCESS SHARE<\/code> (untuk <code data-path-to-node=\"18\" data-index-in-node=\"96\">SELECT<\/code>) dan <code data-path-to-node=\"18\" data-index-in-node=\"108\">ROW EXCLUSIVE<\/code> (untuk <code data-path-to-node=\"18\" data-index-in-node=\"129\">UPDATE<\/code>\/<code data-path-to-node=\"18\" data-index-in-node=\"136\">INSERT<\/code>) berjalan berdampingan tanpa saling memblokir. Aplikasi kita tetap hidup, transaksi tetap masuk, laporan tetap berjalan, sementara PostgreSQL diam-diam membangun indeks di latar belakang.<\/p><p data-path-to-node=\"15\">\u00a0<\/p>\t\t\t\t\t\t\t\t<\/div>\n\t\t\t\t<div class=\"elementor-element elementor-element-b97d755 elementor-widget elementor-widget-text-editor\" data-id=\"b97d755\" data-element_type=\"widget\" data-e-type=\"widget\" data-widget_type=\"text-editor.default\">\n\t\t\t\t\t\t\t\t\t<h5 data-path-to-node=\"15\">Berikut adalah <i data-path-to-node=\"20\" data-index-in-node=\"66\">Best Practices<\/i> yang wajib diterapkan pada <i data-path-to-node=\"20\" data-index-in-node=\"108\">Very Large Databases<\/i> (VLDB)<\/h5>\t\t\t\t\t\t\t\t<\/div>\n\t\t\t\t<div class=\"elementor-element elementor-element-657572d elementor-widget elementor-widget-dtr-icon-list\" data-id=\"657572d\" data-element_type=\"widget\" data-e-type=\"widget\" data-widget_type=\"dtr-icon-list.default\">\n\t\t\t\t<div class=\"elementor-widget-container\">\n\t\t\t\t\t        <ul class=\"dtr-icon-list\">\r\n                            <li class=\"dtr-icon-list__list-item\">\r\n                                        <span class=\"dtr-icon dtr-icon-list__icon\">\r\n                                        \t<i class=\"icon-circle-half\"><\/i>\r\n                                        <\/span>\r\n                     <span class=\"dtr-icon-list__list-text\">Haramkan Standard Indexing di Production: Jangan pernah menjalankan CREATE INDEX atau REINDEX biasa di tabel yang aktif menerima operasi tulis (Writes).<\/span>\r\n                                    <\/li>\r\n                            <li class=\"dtr-icon-list__list-item\">\r\n                                        <span class=\"dtr-icon dtr-icon-list__icon\">\r\n                                        \t<i class=\"icon-circle-half\"><\/i>\r\n                                        <\/span>\r\n                     <span class=\"dtr-icon-list__list-text\">Gunakan CONCURRENTLY: Selalu biasakan menulis CREATE INDEX CONCURRENTLY atau REINDEX INDEX CONCURRENTLY. Proses ini memang memakan waktu lebih lama (karena PostgreSQL harus melakukan scanning tabel beberapa kali), tetapi ini adalah harga yang sangat murah untuk menjamin Zero Downtime. Biar lambat asal selamat!<\/span>\r\n                                    <\/li>\r\n                            <li class=\"dtr-icon-list__list-item\">\r\n                                        <span class=\"dtr-icon dtr-icon-list__icon\">\r\n                                        \t<i class=\"icon-circle-half\"><\/i>\r\n                                        <\/span>\r\n                     <span class=\"dtr-icon-list__list-text\">Hati-hati dengan DROP INDEX: Menghapus indeks yang tidak terpakai itu bagus, tetapi ingat bahwa DROP INDEX biasa mengunci semuanya. Selalu gunakan DROP INDEX CONCURRENTLY di lingkungan live.<\/span>\r\n                                    <\/li>\r\n                            <li class=\"dtr-icon-list__list-item\">\r\n                                        <span class=\"dtr-icon dtr-icon-list__icon\">\r\n                                        \t<i class=\"icon-circle-half\"><\/i>\r\n                                        <\/span>\r\n                     <span class=\"dtr-icon-list__list-text\">Waspada Index INVALID: Pembangunan indeks secara concurrent bisa saja gagal (misalnya karena deadlock ringan atau unique constraint violation). Jika gagal, PostgreSQL akan meninggalkan indeks berstatus 'INVALID'. Indeks ini tidak akan digunakan oleh query planner, tetapi tetap membebani proses INSERT\/UPDATE. Kita harus segera melakukan DROP INDEX CONCURRENTLY pada indeks yang invalid tersebut sebelum mencoba membuatnya lagi.<\/span>\r\n                                    <\/li>\r\n                    <\/ul>\r\n\t\t\t\t<\/div>\n\t\t\t\t<\/div>\n\t\t\t\t<div class=\"elementor-element elementor-element-56e88d3 elementor-widget elementor-widget-text-editor\" data-id=\"56e88d3\" data-element_type=\"widget\" data-e-type=\"widget\" data-widget_type=\"text-editor.default\">\n\t\t\t\t\t\t\t\t\t<h5 data-path-to-node=\"22\">Kesimpulan<\/h5><p data-path-to-node=\"23\">Mengelola database bukan hanya soal membuat <i data-path-to-node=\"23\" data-index-in-node=\"44\">query<\/i> berjalan cepat, tapi juga tentang memahami bagaimana <i data-path-to-node=\"23\" data-index-in-node=\"103\">internal engine<\/i> bekerja (khususnya mekanisme antrean <i data-path-to-node=\"23\" data-index-in-node=\"156\">Locking<\/i>). Memahami matriks konflik pada PostgreSQL adalah garis batas yang membedakan antara Engineer amatir dan Profesional Sejati.<\/p><p data-path-to-node=\"24\">Punya pengalaman horor terkait <i data-path-to-node=\"24\" data-index-in-node=\"31\">locking<\/i> atau <i data-path-to-node=\"24\" data-index-in-node=\"44\">indexing<\/i> di PostgreSQL? Mari berdiskusi di kolom komentar! \ud83d\udc47<\/p>\t\t\t\t\t\t\t\t<\/div>\n\t\t\t\t\t<\/div>\n\t\t\t\t<\/div>\n\t\t<div class=\"elementor-element elementor-element-5e718b7 e-flex e-con-boxed e-con e-parent\" data-id=\"5e718b7\" data-element_type=\"container\" data-e-type=\"container\">\n\t\t\t\t\t<div class=\"e-con-inner\">\n\t\t\t\t\t<\/div>\n\t\t\t\t<\/div>\n\t\t\t\t<\/div>\n\t\t","protected":false},"excerpt":{"rendered":"<p>Lebih dari dua tahun saya berkecimpung mengelola database skala enterprise dan PostgreSQL, jika ditanya apa salah satu penyebab downtime konyol yang paling sering saya temui, jawabannya selalu sama: Mengeksekusi manipulasi Index di tabel raksasa (VLDB) pada jam operasional Niatnya baik: Aplikasi mulai melambat, lalu Backend Engineer atau DBA memutuskan untuk membuat indeks baru agar query [&hellip;]<\/p>\n","protected":false},"author":1,"featured_media":4321,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"_monsterinsights_skip_tracking":false,"footnotes":""},"categories":[45],"tags":[52,50,46,49,51,43,48,53,54,47],"class_list":["post-2791","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-database-index","tag-agussyarif","tag-backenddeveloper","tag-databaseadministration","tag-dba","tag-highavailability","tag-postgresql","tag-softwareengineering","tag-sql","tag-systemarchitecture","tag-techtips"],"aioseo_notices":[],"_links":{"self":[{"href":"https:\/\/agussyarif.my.id\/index.php\/wp-json\/wp\/v2\/posts\/2791","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/agussyarif.my.id\/index.php\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/agussyarif.my.id\/index.php\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/agussyarif.my.id\/index.php\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/agussyarif.my.id\/index.php\/wp-json\/wp\/v2\/comments?post=2791"}],"version-history":[{"count":30,"href":"https:\/\/agussyarif.my.id\/index.php\/wp-json\/wp\/v2\/posts\/2791\/revisions"}],"predecessor-version":[{"id":4392,"href":"https:\/\/agussyarif.my.id\/index.php\/wp-json\/wp\/v2\/posts\/2791\/revisions\/4392"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/agussyarif.my.id\/index.php\/wp-json\/wp\/v2\/media\/4321"}],"wp:attachment":[{"href":"https:\/\/agussyarif.my.id\/index.php\/wp-json\/wp\/v2\/media?parent=2791"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/agussyarif.my.id\/index.php\/wp-json\/wp\/v2\/categories?post=2791"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/agussyarif.my.id\/index.php\/wp-json\/wp\/v2\/tags?post=2791"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}