Jika ada hal yang paling mengerikan dari manajemen database, maka saya nomer satukan corruption. Kalau saya kehilangan primary server, masih punya standby, atau backup server. Kalau misalnya yang bermasalah adalah hilangnya data, masih ada backup server juga yang bisa diambil. Tapi, tidak dengan corrupt.

Tapi, sebenarnya seperti apa sih data corrupt itu?

Beberapa hal yang terjadi dan merupakan bentuk dari database corruption dalam Postgres adalah sebagai berikut:

  • file yang tidak bisa dibaca, misalnya error seperti: could not read block N of relation X/Y/Z: read only 0 of 8192 bytes
  • hilangnya attribute, seperti error: catalog is missing N attribute(s) for relid M
  • rusaknya blok dari data semacam ERROR: invalid page in block %u of relation %s
  • data yang ada di tabel, tapi ketika query dengan membaca index tidak kelihatan
  • dll

Ketika ini terjadi, yang paling sedikit dampaknya adalah data tidak bisa diakses atau hilang. Sedangkan kasus terburuknya adalah, Postgres tidak lagi mau menyala. Dan mencari tahu bentuk corrupt saja bukan perkara mudah.

Penyebab database corruption bisa bermacam-macam, begitu pula mengatasinya:

  • Hardware, kalau memang hardware-nya cacat maka hasil baca bisa berbeda dari hasil ketika dituliskan. Dan ini tidak melalu soal hard drive, tetapi juga memory. Dan penyebab dari cacatnya hardware bisa saja dikarenakan oleh kernel, baik dalam hal locking maupun hal lain.

    Terus bagaimana dong? Beli hardware yang bagus untuk server database. Titik.

  • System reboot atau crash. Tahukah kamu bahwa Postgres itu percaya pada filesystem? Ya, Postgres selalu mengasumsikan bahwa filesystem adalah makhluk sempurna.

    Dalam konfigurasi bawaan, Postgres menyalakan parameter fsync untuk memastikan bahwa data yang tersimpan di memory dan perlu dituliskan ke disk dilakukan secara benar. Namun, kalau parameter ini dimatikan untuk mengurangi beban misalnya, maka proses penulisan ke disk tak lagi sesuai yang disarankan dan data hilang/corrupt sangat mungkin terjadi.

    Nah, pastikan bahwa konfigurasi filesystem juga benar dan mendukung fsync dengan baik. Jangan sampai pakai system yang tidak bagus pada pengaplikasian model fsync. Psstt… Postgres sebenarnya punya masalah dengan pengaplikasian fsync https://lwn.net/Articles/752063/

  • Kecerobohan manusia, yang biasanya disebabkan karena kesalahan saat restore. Ketika restore database, pastikan penulisan isi recovery.conf file sudah benar sesuai dengan yang diharapkan. Tanpa konfigurasi yang benar, maka WAL files yang mungkin dibutuhkan oleh server tidak di-apply dan akibatnya server menganggap dirinya dalam crash-recovery dan rusak.

  • Efek pg_resetxlog. Jika error parah terjadi, misalnya hapus manual file di pg_xlog (pg_wal), atau restore tidak mengikutkan isi folder tersebut, maka salah satu solusi yang bisa dicoba adalah menjalankan pg_resetxlog. Dengan begitu postgres bisa menyala kembali. Salah satu penyebab lain, ya karena datanya corrupt tadi.

Oke, misalnya database-nya corrupt. Terus, DIAPAIN?!

Jawabannya cuma satu:

PANIC MODE

  • pg_dump, karena pg_dump akan scan semua baris dan memastikan jika ada baris yang rusak.

    pg_dumpall -g > pgglobals
    for in `psql -t -c 'select datname from pg_database where datallowconn'`
      do pg_dump -Fc -f pgdb.$db $db
    done
    

    Nah, ketika menjalankan hal ini, mungkin juga pg_dump akan menampilkan error alih-alih sukses, misalnya: pg_dump: schema with OID X does not exist. Nah, kalau sudah begini berarti system catalog-nya rusak, yang berarti kita juga tak bisa mengakses banyak informasi yang penting sehubungan dengan detail database.

    Ada namanya pg_catcheck yang bisa digunakan untuk analisa apakah system catalog di postgres rusak atau tidak, dan yang mana. Jika sudah ketemu, tinggal dilewati saja yang itu dan dilanjut dengan yang lain.

  • Stop postgres. Lho? Kok malah distop?

    Iya, karena ini berguna karena kita butuh analisa lebih lanjut nantinya. Setelah mati, copy data directory dengan alat bawaan, seperti cp/scp atau rsync sehingga bisa kita gunakan nanti.

  • Kalau masalahnya lebih sepele, seperti corrupted index yang banyak terjadi? Kalau ini sih cukup hapus indexnya dan cek apakah masalahnya masih terjadi. Kalau sudah tidak terjadi, buat ulang indexnya. Kalau setelah dihapus masih terjadi, berarti masalahnya bukan index corruption.

  • Gunakan amcheck yang sudah ada sejak PostgreSQL versi 10. amcheck akan melakukan scanning dan memastikan bahwa relasi dalam B-TREE index benar.

    Tapi saya belum pakai PostgreSQL 10? Ya nasibmu! Enggak, bisa ko pakai amcheck yang versi ini

  • pg_verify_checksums buat yang sudah pakai PostgreSQL 11+. Dengan menggunakan alat ini kita bisa memastikan bahwa checksums yang ada di data directory benar dan valid. Untuk bisa menjalankan pg_verify_checksums, postgres harus dalam kondisi mati.

Kalau sudah melakukan itu semua, dan masih juga belum tahu kenapa error, ada baiknya cari tahu di forum. Atau, kalau punya duit, saya siap membantu.

Sebagai langkah antisipasi lain, pastikan punya backup. DAN pastikan hasil backup-nya dites untuk restore apakah sukses atau tidak.