Belajar Menyetel Database MySQL Server

Akhir tahun adalah saat yang paling tepat untuk beres-beres setelah setahun menulis kode program. Salah satu contoh bentuk upaya beres-beres tersebut misalnya adalah memeriksa apakah kinerja database yang dipakai oleh aplikasi sudah maksimal. Sama seperti kendaraan bermotor, database juga perlu dirawat secara berkala. Bila yang merawat sepeda motor adalah mekanik di bengkel, maka profesi yang bertugas merawat database dinamakan sebagai database administrator.

Untuk mengukur kinerja program, saya akan mencoba mensimulasikan operasi pengisian sejumlah data penjualan. Operasi ini tidak hanya terdiri atas operasi INSERT, tetapi juga operasi SELECT untuk mencari nama konsumen dan nama produk. Hasil yang saya peroleh adalah dibutuhkan waktu 30.053 ms untuk menyelesaikan query yang ada. Ini adalah perkiraan kasar karena masih belum memperhitungkan jeda waktu yang ditimbulkan oleh jaringan dan kesibukan server saat diakses secara bersamaan. Walaupun demikian, tanpa memperhitungkan hal lain tersebut, apakah nilai ‘dasar’ ini bisa ditingkatkan?

Konfiguras MySQL Server bisa dilakukan dengan mengubah file my.ini. Saya dapat menemukan file ini di lokasi C:\Program Files\MySQL\MySQL Server 5.6 atau di C:\ProgramData\MySQL\MySQL Server 5.6. Untuk lokasi yang lebih akurat, saya dapat menjalankan MySQL dari Command Prompt dan memberikan perintah mysqld --help --verbose | more. Disini akan ada daftar lokasi pada bagian Default options are read from the following files in the given order:. Saya juga dapat melakukan pengaturan secara sementara tanpa mengubah file my.ini dengan memberikan perintah SET GLOBAL. Akan tetapi, karena ingin melakukan perbandingan, saya memilih mengubah file my.ini dan me-restart database setiap kali pengujian dilakukan.

Salah satu pengaturan yang paling klasik adalah mengubah nilai innodb_buffer_pool_size. Ini adalah besarnya wilayah di memori yang dialokasikan khusus untuk menampung cache yang berisi informasi tabel dan index. Semakin besar ukuran buffer pool, maka semakin sedikit operasi disk yang dibutuhkan. Nilai default-nya yang berupa 128 MB merupakan sesuatu yang cukup kecil bila dipakai pada server dengan jumlah memori mencapai gigabyte. Dokumentasi MySQL Server merekomendasikan nilai 80% dari jumlah memori untuk database yang sibuk. Jangan lupa bahwa nilai innodb_buffer_pool_size yang terlalu besar malah bisa mengakibatkan perlambatan akibat paging.

Sebagai percobaan, saya mengubah konfigurasi menjadi seperti berikut ini:

innodb_buffer_pool_size=512M
innodb_log_file_size=512M

Saya juga meningkatkan ukuran innodb_log_file_size untuk mengurangi aktifitas flush. Hasil akhir percobaan setelah perubahan konfigurasi menunjukkan bahwa terdapat peningkatan waktu eksekusi sebesar 7%. Ini adalah peningkatan yang cukup besar. Sayangnya, saya tidak bisa menaikkan innodb_buffer_pool_size menjadi 1GB karena walaupun memiliki free memori lebih dari jumlah tersebut, Windows mensyaratkan lokasi memori bebas harus berlanjut dan tidak boleh tersebar! Batasan ini hanya terasa pada Windows 32-bit dan hampir tidak terjadi di Windows 64-bit (akibat ruang alokasi memori yang masih luas 🙂 ).

Sejak versi 5.6.8, nilai query_cache_type secara default adalah 0 sehingga query cache tidak aktif. Query cache adalah fitur untuk menampung hasil query secara sementara di memori sehingga hasil yang sama bisa dikembalikan dengan cepat untuk SQL yang sama. Tentu saja query cache harus dihapus bila isi tabel yang dibaca sudah berubah sejak terakhir kali dibaca. Bila query cache terlalu sering kadaluarsa, ini bukannya mempercepat malah bisa memperlambat. Dengan demikian, query cache bisa bermanfaat dan juga bisa merugikan tergantung dari seberapa sering aplikasi mengubah isi tabelnya.

Sebagai contoh, saya akan menggunakan mysqlslap bawaan MySQL Server untuk mensimulasikan query SELECT yang dilakukan oleh beberapa klien secara bersamaan dengan memberikan perintah berikut ini:

C:\> mysqlslap --user=root --password --create-schema=inventory 
--concurrency=20 --iterations=10 --no-drop --query=select.sql

Benchmark
        Average number of seconds to run all queries: 25.033 seconds
        Minimum number of seconds to run all queries: 22.435 seconds
        Maximum number of seconds to run all queries: 32.380 seconds
        Number of clients running queries: 20
        Average number of queries per client: 7513

Perintah di atas akan mensimulasikan akses dari 20 client secara bersamaan yang mengerjakan isi query di file select.sql selama 10 kali.

Sebagai perbandingan, saya kemudian mengaktifkan query cache dengan menambahkan baris berikut ini di my.ini:

query_cache_type=1
query_cache_size=5MB

Kali ini, bila saya memberikan perintah yang sama, saya akan memperoleh hasil seperti berikut ini:

C:\> mysqlslap --user=root --password --create-schema=inventory
--concurrency=20 --iterations=10 --no-drop --query=select.sql

Benchmark
        Average number of seconds to run all queries: 36.043 seconds
        Minimum number of seconds to run all queries: 31.943 seconds
        Maximum number of seconds to run all queries: 41.467 seconds
        Number of clients running queries: 20
        Average number of queries per client: 7513

Terlihat bahwa mengaktifkan query cache hanya membuat query menjadi lambat. Mengapa bisa demikian? Untuk melihat status query cache, saya dapat memberikan perintah SQL berikut ini:

mysql> SHOW STATUS LIKE 'Qcache%';
+-------------------------+---------+
| Variable_name           | Value   |
+-------------------------+---------+
| Qcache_free_blocks      | 327     |
| Qcache_free_memory      | 988680  |
| Qcache_hits             | 1196351 |
| Qcache_inserts          | 65103   |
| Qcache_lowmem_prunes    | 64153   |
| Qcache_not_cached       | 240682  |
| Qcache_queries_in_cache | 950     |
| Qcache_total_blocks     | 2351    |
+-------------------------+---------+

Nilai Qcache_lowmem_prunes menunjukkan jumlah query yang terpaksa dihapus karena ukuran query cache sudah tidak cukup lagi. Pada hasil di atas, nilainya cukup tinggi. Walaupun demikian, nilai Qcache_hits yang tinggi menunjukkan bahwa query cache seharusnya bisa membantu. Oleh sebab itu, saya akan mencoba meningkatkan ukuran query cache dengan mengubah konfigurasi menjadi seperti berikut ini:

query_cache_type=1
query_cache_size=10MB

Hasil ketika menjalankan mysqlslap adalah:

C:\> mysqlslap --user=root --password --create-schema=inventory
--concurrency=20 --iterations=10 --no-drop --query=select.sql

Benchmark
        Average number of seconds to run all queries: 24.233 seconds
        Minimum number of seconds to run all queries: 22.326 seconds
        Maximum number of seconds to run all queries: 31.803 seconds
        Number of clients running queries: 20
        Average number of queries per client: 7513

Walaupun sudah tidak lambat lagi, saya tidak menjumpai peningkatkan kinerja yang cukup berarti saat mengaktifkan query cache. Hal ini cukup masuk akal karena saat ini belum ada tabel raksasa yang membutuhkan waktu pencarian lama sehingga query cache belum dapat menunjukkan taringnya.

Bicara soal jaringan, MySQL Server memiliki kebiasaan melakukan request DNS untuk melakukan validasi host pada saat pengguna login. Bila DNS server yang dipakai lambat (misalnya bawaan ISP), maka hal ini bisa menimbulkan kesan bahwa koneksi database sangat lambat pada aplikasi pertama kali dijalankan. Untuk mengatasinya, saya bisa mematikan request DNS dan hanya melakukan validasi berdasarkan IP dengan menambahkan konfigurasi berikut ini:

skip_name_resolve=ON

Fitur lainnya yang berguna untuk tabel berukuran besar adalah kompresi tabel. MySQL Server mendukung 2 jenis file format untuk InnoDB: Antelope (versi original) dan Barracuda (versi terbaru). File format yang dipakai secara default adalah Antelope untuk memaksimalkan kompatibilitas dengan fitur lama. Karena suka ber-eksperimen, saya akan beralih ke Barracuda dengan menambahkan baris berikut ini di file konfigurasi:

innodb_file_format=Barracuda

Salah satu fitur baru yang ditawarkan oleh format Barracuda adalah kompresi tabel. Kompresi dapat diakses dengan menambahkan ROW_FORMAT=COMPRESSED pada saat memberikan perintah CREATE TABLE atau ALTER TABLE seperti pada:

ALTER TABLE `produk`
ROW_FORMAT = COMPRESSED ;

Untuk bisa memakai kompresi, saya perlu memastikan bahwa nilai innodb_file_per_table adalah ON (nilai default sejak versi 5.6.6). Lagi-lagi saya tidak memiliki tabel yang berukuran sangat besar sehingga saya tidak menjumpai peningkatan kinerja yang cukup berarti dengan mengaktifkan kompresi tabel.

Memakai Index Advisor Di TimesTen

Pada query SQL yang mengandung klausa WHERE, database perlu menyaring data yang harus dikembalikan.   Pencarian isi tabel yang dilakukan berdasarkan seluruh data yang ada, baris per baris, disebut sebagai full table scan.   Pada full table scan, semakin banyak baris pada tabel maka semakin lambat eksekusi query tersebut.

Full table scan dapat dihindari bila kolom dalam klausa WHERE sudah di-index sebelumnya.   Index adalah struktur data yang mewakili kolom di tabel yang dirancang untuk mempercepat pencarian.   Sebagai contoh, bila saya mendefinisikan sebuah range index pada kolom NILAI, maka database dapat menentukan dengan cepat baris mana yang memenuhi kondisi SQL WHERE NILAI > 60,  tanpa harus menelusuri seluruh baris yang ada (full table scan).   Walaupun penggunaan index meningkatkan kinerja query,  ia akan mempengaruhi proses seperti INSERT dan UPDATE karena pada saat isi tabel berubah, maka index juga perlu diperbaharui.   Oleh sebab itu, penggunaan index perlu dipertimbangkan secara seksama 🙂

Oracle TimesTen memiliki fasilitas index advisor yang dapat memberikan saran kolom mana yang perlu di-index bagi database administrator (atau developer, terutama yang ingat merawat database!).   Index advisor hanya memberikan rekomendasi saja;  database administrator perlu mempertimbangkan lagi apakah index perlu dibuat atau tidak.

Saya akan mencoba memakai index advisor untuk melihat rekomendasi index untuk sebuah aplikasi yang memproses faktur.   Langkah pertama yang saya lakukan adalah memperbaharui statistics untuk tabel.   Di SQL Developer, saya men-klik kanan Tables, lalu memilih Statistics, Update.   Setelah itu, saya men-klik tombol Apply.

Memperbaharui statistik

Memperbaharui statistik

Pada langkah berikutnya, saya memanggil procedure ttIndexAdviceCaptureStart() untuk menjalankan index advisor seperti yang diperlihatkan pada gambar berikut ini:

Memulai proses capture

Memulai proses capture

Agar dapat bekerja dengan baik, index advisor perlu mengamati SQL yang diberikan selama proses capture sebagai bahan pertimbangan dalam merekomendasikan index.

Saya memberikan nilai 1 sebagai nilai parameter pertama, captureLevel, karena SQL sebagai akan dikerjakan oleh aplikasi melalui koneksi yang berbeda.   Bila SQL akan diberikan oleh koneksi yang sama, saya dapat menggunakan nilai 0.

Setelah memulai proses capture, saya kemudian menjalankan aplikasi dan melakukan operasi dari aplikasi seperti layaknya saat dipakai oleh pengguna.   Saya mencoba mensimulasi beberapa aktifitas yang paling sering dilakukan oleh pengguna.   Saya juga mencoba menampilkan laporan, terutama yang membutuhkan waktu lama.

Setelah selesai dengan aplikasi, saya perlu mematikan proses capture dengan memanggil procedure ttIndexAdviceCaptureEnd()seperti yang terlihat pada gambar berikut ini:

Menyelesaikan proses capture

Menyelesaikan proses capture

Untuk melihat apa saja SQL yang berhasil diperoleh oleh index advisor, saya memanggil procedure ttIndexAdviceCaptureInfoGet()seperti pada gambar berikut ini:

Melihat informasi yang di-capture

Melihat informasi yang di-capture

Hasil dari procedure ttIndexAdviceCaptureInfoGet() memperlihatkan bahwa sebuah proses capture secara global (CAPTURELEVEL=1) telah selesai dilakukan (CAPTURESTATE=0).   Proses capture tersebut menampung 25.196 prepared statement dan telah mengerjakan 25.200 perintah SQL.

Sekarang, saya akan melihat apa rekomendasi dari index advisor berdasarkan hasil capture yang diperolehnya dengan memanggil procedure ttIndexAdviceCaptureOutput() seperti yang terlihat pada gambar berikut ini:

Menampilkan hasil capture

Menampilkan hasil capture

Pada hasil di atas, kolom createStmt berisi perintah SQL untuk membuat index, sementara kolom stmtCount menunjukkan jumlah perintah SQL berbeda yang akan diuntungkan oleh index tersebut.   Sebagai contoh, bila saya memberikan index yang berisi kombinasi kolom (DTYPE,TANGGAL) pada tabel FAKTUR,  maka akan ada 33 perintah SQL berbeda (di aplikasi) yang diuntungkan oleh index tersebut.

Saya tidak akan mengerjakan seluruh saran yang diberikan di createStmt karena operasi insert, update, dan delete akan menjadi lambat.  Semakin banyak index yang perlu diperbaharui, maka semakin lambat operasi perubahan data pada sebuah tabel.  Walaupun demikian, index advisor setidaknya sudah memberikan titik terang berupa kandidat kolom yang perlu di-index.

Mengakses TimesTen Dengan Oracle SQL Developer

Selama ini saya mengakses database TimesTen melalui tool bawaan yang berbasis command line, yaitu ttIsql.   Namun proses administrasi database akan lebih mudah bila seandainya terdapat tool berbasis GUI.   Sebagai contoh, di MySQL Server ada MySQL Workbench dan di Oracle Database ada SQL Developer, juga ada aplikasi komersial seperti Toad.   Lalu bagaimana dengan Oracle TimesTen?   Saya dapat menggunakan SQL Developer untuk mengakses database TimesTen.

Tapi saat pertama kali mencoba menghubungi TimesTen di SQL Developer, saya mengalami kendala.  Saat saya mengakses TimesTen melalui metode direct connection, SQL Developer menampilkan pesan kesalahan seperti berikut ini:

[TimesTen][TimesTen 11.2.2.5.0 ODBC Driver][TimesTen]TT0837:
Cannot attach data store shared-memory segment, error 8 -- file
"db.c", lineno 9934, procedure "sbDbConnect"

Error 8 adalah pesan kesalahan bahwa memori tidak cukup.   Dokumentasi TimesTen menyebutkan bahwa manajemen shared memory di Windows berbeda dengan sistem operasi Unix atau Linux.   Keterbatasan di Windows menyebabkan sulitnya memetakan seluruh isi database ke lokasi memori secara berlanjut (tanpa fragmentasi).   Dokumentasi juga menyarankan agar memakai Windows 64-bit untuk menghindari kesalahan ini.

Tapi bagaimana bila saya tidak akan beralih ke Windows 64-bit?  Saya tetap ingin mengakses TimesTen melalui SQL Developer di Windows 32-bit.   Salah satu solusinya adalah dengan menggunakan koneksi client server di komputer yang sama.   Btw, hanya DSN yang didefinisikan pada System DSN saja yang dapat diakses sebagai server.   Sebagai contoh, gambar berikut ini DSN di ODBC Data Source Administrator yang akan dijadikan sebagai server:

Server DSN

Server DSN

Saya akan membuat sebuah client DSN baru dengan men-klik tombol Add…, memilih TimesTen Client 11.2.2 lalu men-klik tombol Finish.

Pada kotak dialog yang muncul, saya men-klik tombol Servers….   Lalu, pada kotak dialog Oracle TimesTen Logical Server List, saya men-klik tombol Add… untuk mendefinisikan server baru, yang isinya seperti berikut ini:

Mendefinisikan server baru

Mendefinisikan lokasi server baru

Setelah itu, saya men-klik tombol OK. Saya memilih server yang barusan saya buat, lalu men-klik tombol Close.   Kemudian saya mengisi kotak dialog yang ada menjadi seperti pada tampilan berikut ini:

Atribut untuk client DSN

Atribut untuk client DSN

Saya men-klik tombol Test Oracle TimesTen Server Connection dan Test Data Source Connection untuk memastikan koneksi dapat dilakukan dengan baik.   Setelah itu, saya men-klik tombol OK dua kali untuk menyelesaikan proses pembuatan client DSN ini.

Sekarang, saya akan menjalankan SQL Developer.   Tapi sebelumnya, saya perlu memastikan terlebih dahulu bahwa library TimesTen yang dibutuhkan sudah terdaftar di environment variable CLASSPATH.   Agar lebih pasti, saya menjalankan SQL Developer dari command prompt dengan memberikan perintah seperti berikut ini:

C:\>c:\TimesTen\tt1122_32\bin\ttenv.bat
Setting environment variables for TimesTen

set PATH to "..."

set CLASSPATH to "..."

C:\>c:\sqldeveloper\sqldeveloper

Tidak lama kemudian SQL Developer akan muncul di layar.  Saya hanya perlu sekali saja untuk mengerjakan SQL Developer seperti di atas, setelah itu saya dapat menjalankan SQL Developer melalui shortcut.

Langkah pertama yang saya lakukan di SQL Developer adalah men-klik tombol new connection pada SQL Developer untuk membuat koneksi baru ke database TimesTen, seperti yang diperlihatkan oleh gambar berikut ini:

Membuat koneksi baru

Membuat koneksi baru

Saya kemudian mengisi kotak dialog New / Select Database Connection menjadi seperti pada gambar berikut ini:

Mengisi informasi koneksi ke TimesTen

Mengisi informasi koneksi ke TimesTen

Bila tab TimesTen tidak muncul seperti di gambar di atas, pastikan bahwa JDBC driver untuk TimesTen sudah didefinisikan di environment variable CLASSPATH.

Saya kemudian men-klik tombol Test dan memastikan bahwa terdapat indikator Status: Success.   Setelah yakin, saya men-klik tombol Save, lalu diikuti dengan men-klik tombol Connect.

Setelah ini, saya dapat melihat isi schema untuk LATIHAN_CLIENT melalui SQL Developer, seperti yang terlihat pada gambar berikut ini:

Melihat isi schema database

Melihat isi schema database

Pada bagian Reports, saya juga dapat mengerjakan beberapa query ‘siap jadi‘ yang berkaitan dengan administrasi database TimesTen, seperti yang diperlihatkan oleh gambar berikut ini:

Query siap jadi untuk administrasi TimesTen

Query siap jadi untuk administrasi TimesTen

Untuk melakukan operasi pada sebuah tabel, saya dapat men-klik kanan sebuah tabel dan memilih salah satu akses yang diinginkan, seperti yang diperlihatkan pada gambar berikut ini:

Aksi pada tabel

Aksi pada tabel

Pada SQL Worksheet, saya dapat memberikan query SQL ataupun mengerjakan PL/SQL, seperti yang diperlihatkan oleh gambar berikut ini:

Mengerjakan PL/SQL dari worksheet

Mengerjakan PL/SQL dari worksheet

Memakai ttIsql di Oracle TimesTen

ttIsql adalah sebuah tool bawaan Oracle TimesTen yang dapat dipakai untuk berinteraksi dengan database.   Tool ini bekerja mirip seperti SQL*Plus untuk Oracle Database.   Bagi pengguna MySQL Server, tool ini mirip seperti client CLI mysql.

Pada saat menjalankan ttIsql, saya dapat menyertakan DSN untuk database yang akan dipakai, seperti:

C:\>ttIsql LATIHAN

Pada perintah di atas, saya akan melakukan koneksi ke DSN bernama LATIHAN (tidak case-sensitive di Windows).   Bila ini adalah koneksi pertama kalinya, maka TimesTen akan me-load database dari file ke memori.

Bila ingin menyertakan atribut koneksi, maka pada saat menjalankan ttIsql, saya dapat memberikan parameter -connStr seperti berikut ini:

C:\>ttIsql -connStr "DSN=LATIHAN;UID=SolidSnake"

Pada contoh di atas, saya melakukan koneksi ke DSN LATIHAN dengan menyertakan atribut UID (nama user) berupa seorang external user bernama SolidSnake.   Bila connection attribute sudah didefinisikan saat membuat DSN, maka connection attribute yang saya atur saat membuat DSN yang akan dipakai.

Setelah itu akan muncul prompt Command> dimana saya dapat mengetikkan perintah khusus ttIsql dan juga perintah SQL.   Sebagai contoh, bila ingin membuat sebuah tabel baru, saya dapat memberitan perintah SQL berupa CREATE TABLE seperti berikut ini:

Command> CREATE TABLE sensus (
       >   age NUMBER,
       >   workclass VARCHAR(20),
       >   fnlwgt NUMBER,
       >   education VARCHAR(20),
       >   education_num NUMBER,
       >   marital_status VARCHAR(20),
       >   occupation VARCHAR(20),
       >   relationship VARCHAR(20),
       >   race VARCHAR(20),
       >   sex CHAR(6),
       >   capital_gain NUMBER,
       >   capital_loss NUMBER,
       >   hours_per_week NUMBER,
       >   native_country VARCHAR(20)
       > );

Selain mengetik perintah secara satu per satu, saya juga dapat menyuruh ttIsql untuk mengerjakan seluruh perintah dalam file yang telah saya siapkan sebelumnya.   Sebagai contoh, perintah SQL untuk mengisi tabel di atas terletak pada sebuah file bernama data.sql.   Untuk mengerjakan file tersebut, saya memberikan perintah seperti berikut ini:

Command> run E:\data.sql

Untuk melihat daftar tabel yang dimiliki oleh user, saya dapat memberikan perintah berikut ini:

Command> tables;
  SOLIDSNAKE.SENSUS
1 table found.

Untuk melihat seluruh tabel yang ada, saya menggunakan perintah berikut ini:

Command> alltables;
  SOLIDSNAKE.SENSUS
  SYS.ACCESS$
  SYS.ARGUMENT$
  SYS.CACHE_GROUP
  SYS.COLUMNS
  SYS.COLUMN_HISTORY
  SYS.COL_STATS
  SYS.DEPENDENCY$
  SYS.DIR$
  SYS.DUAL
  SYS.ERROR$
  SYS.IDL_CHAR$
  SYS.IDL_SB4$
  SYS.IDL_UB1$
  SYS.IDL_UB2$
  SYS.INDEXES
  SYS.MONITOR
  SYS.NCOMP_DLL$
  SYS.OBJ$
  SYS.OBJAUTH$
  SYS.OBJERROR$
  SYS.PLAN
  SYS.PLSCOPE_ACTION$
  SYS.PLSCOPE_IDENTIFIER$
  SYS.PROCEDURE$
  SYS.PROCEDUREINFO$
  SYS.PROCEDUREPLSQL$
  SYS.REPSTATS
  SYS.SEQUENCES
  SYS.SETTINGS$
  SYS.SNAPSHOT_DESCRIPTION
  SYS.SNAPSHOT_INFO
  SYS.SNAPSHOT_LATCH_INFO
  SYS.SNAPSHOT_REPL_PEER
  SYS.SNAPSHOT_VALUE_CGGROUP
  SYS.SNAPSHOT_VALUE_CKPTHIST
  SYS.SNAPSHOT_VALUE_CONFIG
  SYS.SNAPSHOT_VALUE_GENERIC
  SYS.SNAPSHOT_VALUE_GRIDMEMBER
  SYS.SNAPSHOT_VALUE_GRIDNODE
  SYS.SNAPSHOT_VALUE_LATCH
  SYS.SNAPSHOT_VALUE_LOGHOLD
  SYS.SNAPSHOT_VALUE_PARAWT
  SYS.SNAPSHOT_VALUE_PLSQL
  SYS.SNAPSHOT_VALUE_REPL
  SYS.SNAPSHOT_VALUE_SQL
  SYS.SNAPSHOT_VALUE_XLA
  SYS.SOURCE$
  SYS.STATNAMES
  SYS.SYN$
  SYS.SYSAUTH$
  SYS.SYSTEMSTATS
  SYS.SYSTEM_PRIVILEGE_MAP
  SYS.TABLES
  SYS.TABLE_HISTORY
  SYS.TABLE_PRIVILEGE_MAP
  SYS.TAB_SIZES$
  SYS.TBL_STATS
  SYS.TCOL_STATS
  SYS.TINDEXES
  SYS.TRANSACTION_LOG_API
  SYS.TTABLES
  SYS.TTBL_STATS
  SYS.TT_STATS_PARAM
  SYS.USER$
  SYS.USER_ASTATUS_MAP
  SYS.UTL_RECOMP_COMPILED
  SYS.UTL_RECOMP_ERRORS
  SYS.UTL_RECOMP_SORTED
  SYS.VIEWS
  SYS.WARNING_SETTINGS$
  SYS.XLASUBSCRIPTIONS
  TTREP.CLIENTFAILOVER
  TTREP.REPELEMENTS
  TTREP.REPLICATIONS
  TTREP.REPNETWORK
  TTREP.REPPEERS
  TTREP.REPSTORES
  TTREP.REPSUBSCRIPTIONS
  TTREP.REPTABLES
  TTREP.TTSTORES
81 tables found.

Tabel yang ada di schema SYS dan TTREP dipakai untuk keperluan internal TimesTen.   Satu-satunya tabel yang dibuat oleh user hanya tabel Sensus.

Untuk melihat struktur sebuah tabel, saya dapat menggunakan perintah describe atau sering kali disingkat menjadi desc seperti pada contoh berikut ini:

Command> desc SYS.USER$;

System table SYS.USER$:
  Columns:
    USER#                           TT_INTEGER NOT NULL
    NAME                            TT_CHAR (30) NOT NULL
    TYPE#                           TT_TINYINT NOT NULL
    DEFROLE                         TT_TINYINT NOT NULL
    PASSWORD                        TT_CHAR (60)
    CTIME                           TT_TIMESTAMP NOT NULL
    PTIME                           TT_TIMESTAMP
    LTIME                           TT_TIMESTAMP
    USER$ID                         TT_INTEGER NOT NULL
    IDENTIFICATION                  TT_TINYINT NOT NULL
    ASTATUS                         TT_TINYINT NOT NULL
    SYS1                            BINARY (2) NOT NULL
    SYS2                            BINARY (16) NOT NULL

1 table found.
(primary key columns are indicated with *)

Saya dapat menggunakan perintah history untuk melihat daftar perintah yang pernah diberikan.   Dengan menggunakan tanda seru (!) yang diikuti nomor history,  saya bisa mengerjakan kembali perintah tersebut.   Tanda seru dua kali (!!) akan mengerjakan perintah terakhir.

History di ttIsql

History di ttIsql

Gunakan perintah dssize untuk melihat status memori, seperti contoh berikut ini (satuan dalam MB):

Command> dssize;

  PERM_ALLOCATED_SIZE:      262144
  PERM_IN_USE_SIZE:         17767
  PERM_IN_USE_HIGH_WATER:   17767
  TEMP_ALLOCATED_SIZE:      131072
  TEMP_IN_USE_SIZE:         7931
  TEMP_IN_USE_HIGH_WATER:   7994

Untuk melihat ukuran sebuah tabel,  saya dapat memanggil procedure ttComputeTabSizes() diikuti dengan perintah tablesize seperti yang diperlihatkan oleh contoh berikut ini (satuan dalam bytes):

Command> call ttComputeTabSizes('sensus');
Command> tablesize sensus;

Sizes of SOLID.SENSUS:

  INLINE_ALLOC_BYTES:   10565856
  NUM_USED_ROWS:        32129
  NUM_FREE_ROWS:        127
  AVG_ROW_LEN:          327
  OUT_OF_LINE_BYTES:    0
  METADATA_BYTES:       5328
  TOTAL_BYTES:          10571184
  LAST_UPDATED:         2013-09-14 10:17:37.000000

1 table found.

Untuk melihat nilai dari seluruh connection attribute yang ada, gunakan perintah show all. Untuk mengubah nilai sebuah connection attribute, gunakan perintah set, seperti yang diperlihatkan pada contoh berikut ini:

Command> show autocommit
autocommit = 1 (ON)
Command> set autocommit 0

Command> show autocommit
autocommit = 0 (OFF)

ttIsql mendukung definisi variabel dan dapat mengerjakan PL/SQL anonymous block, seperti yang ditunjukkan pada gambar berikut ini:

Variabel dan PL/SQL di ttIsql

Variabel dan PL/SQL di ttIsql

Untuk mengukur waktu eksekusi sebuah query (berdasarkan pemanggilan ODBC),  saya dapat menggunakan perintah timing.   Hal ini sebaiknya diikuti dengan perintah verbosity 0 sehingga waktu selama mencetak ke layar tidak akan ikut dihitung.   Berikut ini adalah contoh tampilan waktu eksekusi untuk data sensus yang terdiri atas 32.129 baris atau sekitar 4.6 MB bila berdasarkan ukuran file backup SQL INSERT-nya:

Command> timing 1;

Command> verbosity 0;

Command> SELECT * FROM sensus;
Execution time (SQLExecute + Fetch Loop) = 0.120389 seconds.

Command> SELECT COUNT(sex) FROM sensus WHERE sex = 'Female';
Execution time (SQLExecute + Fetch Loop) = 0.003853 seconds.

Command> SELECT COUNT(age) FROM sensus WHERE age < 20; 
Execution time (SQLExecute + Fetch Loop) = 0.003528 seconds. 

Command> SELECT SUM(fnlwgt) FROM sensus;
Execution time (SQLExecute + Fetch Loop) = 0.027481 seconds.

Mengelola User Di Oracle TimesTen

Hari ini saya mendapatkan sebuah trophy yang mengingatkan bahwa usia blog ini sudah mencapai lima tahun:

Happy anniversary!

Happy anniversary!

Lima tahun yang lalu, saya berhenti menulis blog subjektif yang penuh lelucon, komentar dan opini pribadi 🙂  Saya kemudian mendaftar di WordPress.com dan membuat blog TheSolidSnake ini.  Saya mulai belajar menulis secara serius dan objektif.   Apalagi, seorang sosok eksentrik di Indonesia, R*y S*ryo, pernah meremehkan blogger dengan menyatakan bahwa: “Blog tidak bertanggung jawab, bahkan blogger itu tukang tipu”.  Oleh sebab itu, saya tidak ingin menjadi blogger penerjemah yang hanya menerjemahkan dokumentasi dari bahasa Inggris menjadi bahasa Indonesia.   Visi saya saat itu adalah menuliskan informasi yang sulit diperoleh dalam bahasa Indonesia atau sesuatu yang menarik bagi saya.   Kini, hasilnya setelah lima tahun, adalah sebuah blog yang membosankan dan terkadang sulit dicerna.  Tulisan pertama saya di blog ini adalah mengenai salah satu produk Oracle yang sangat populer di lingkungan kerja, Oracle Database.  Hari ini saya kembali lagi bereksperimen dengan produk database lainnya dari Oracle yang bernama Oracle TimesTen.

Oracle TimesTen mengenali dua jenis user, yaitu internal user dan external user.   Seorang external user yang men-install TimesTen boleh melakukan apa saja terhadap database tersebut sehingga ia disebut juga sebagai instance administrator.   Untuk melihat seluruh user yang ada, saya dapat menggunakan perintah SQL berikut:

C:\>ttIsql LATIHAN

Command> SELECT * FROM SYS.ALL_USERS;
< SYS, 0, 2013-09-13 22:36:07.442000 >
< TTREP, 2, 2013-09-13 22:36:07.442000 >
< SYSTEM, 3, 2013-09-13 22:36:07.442000 >
< GRID, 4, 2013-09-13 22:36:07.442000 >
< SOLIDSNAKE, 10, 2013-09-13 22:36:07.442000 >
5 rows found.

Internal user adalah user yang dibuat dan disimpan di dalam database TimesTen itu sendiri melalui perintah SQL CREATE USER.   Pada hasil query di atas, terlihat bahwa Oracle TimesTen secara otomatis membuat 4 internal user, yaitu SYS, TTREP, SYSTEM dan GRID.   Mereka adalah user yang dipakai oleh TimesTen itu sendiri.

External user adalah user yang disimpan di sistem operasi.   Pada hasil query di atas, user SOLIDSNAKE adalah external user.   TimesTen tidak menyimpan password untuk external user karena mereka dikelola oleh sistem operasi.   TimesTen juga tidak meminta password untuk external user karena sebelum menjalankan TimesTen pastinya mereka sudah login terlebih dahulu di sistem operasi.

Bila saya melakukan koneksi tanpa memberikan atribut UID (nama user), maka user yang dipakai adalah external user dengan nama yang sama sesuai dengan user di sistem operasi.   Hanya external user selaku instance administrator yang boleh melakukan koneksi ke database untuk pertama kalinya (ingat bahwa koneksi pertama kali akan memindahkan file database ke memori).    Sebagai contoh, pada perintah di atas, saya melakukan koneksi ke database sebagai instance administrator karena saya sedang login di Windows 7 sebagai user yang men-install Oracle TimesTen.

Untuk membuat sebuah internal user baru, saya dapat menggunakan perintah SQL seperti berikut ini:

C:\>ttIsql LATIHAN

Command> CREATE USER solid IDENTIFIED BY "snake";

User created.

Command> GRANT CREATE SESSION TO solid;

Untuk mendaftarkan sebuah external user baru, saya dapat menggunakan perintah SQL seperti berikut ini:

C:\>ttIsql LATIHAN

Command> CREATE USER solid IDENTIFIED EXTERNALLy;

User created.

Untuk login sebagai user solid, saya dapat memberikan atribut UID yang mewakili nama user dan PWD yang mewakili password, seperti berikut ini:

C:\>ttIsql -connStr "DSN=LATIHAN;UID=solid;PWD=snake"

Sama seperti di Oracle Database, user memiliki schema masing-masing.   User solid tidak dapat mengakses tabel milik user liquid dan sebaliknya.   Pengguna yang berlatar belakang MySQL mungkin dapat membayangkan bahwa sebuah user di TimesTen sebagai sebuah user plus sebuah database dengan nama yang sama bila di MySQL.

Setiap user dibatasi oleh privilege yang dimilikinya.   Privilege ADMIN adalah sebuah system privilege yang merupakan hak akses paling tinggi.   User yang memiliki privilege ini boleh melakukan apa saja!   Secara default, hanya instance administrator dan user internal dari TimesTen yang memiliki privilege ini.   Nantinya, instance administrator boleh memberikan hak ADMIN ke user lain bila dirasa perlu.

Untuk melihat privilege yang dimiliki oleh user, saya memberikan query SQL berikut ini:

C:\>ttIsql LATIHAN

Command> SELECT * FROM SYS.DBA_SYS_PRIVS;
< SYS, ADMIN, YES >
< SYSTEM, ADMIN, YES >
< SOLIDSNAKE, ADMIN, YES >
< SOLID, CREATE SESSION, NO >
4 rows found.

Terlihat bahwa user SOLIDSNAKE memiliki privilege ADMIN sementara user SOLID memiliki privilege CREATE SESSION.   Seorang user minimal harus memiliki privilege CREATE SESSION agar bisa melakukan koneksi ke database.

Instance administrator SOLIDSNAKE dapat memberikan hak akses ADMIN ke SOLID dengan memberikan perintah berikut ini:

Command> GRANT ADMIN TO SOLID;

Command> SELECT * FROM SYS.DBA_SYS_PRIVS;
< SYS, ADMIN, YES >
< SYSTEM, ADMIN, YES >
< SOLIDSNAKE, ADMIN, YES >
< SOLID, CREATE SESSION, NO >
< SOLID, ADMIN, YES >
5 rows found.

Untuk membuang privilege ADMIN milik user SOLID, saya dapat memberikan perintah berikut ini:

Command> REVOKE ADMIN FROM SOLID;

Command> SELECT * FROM SYS.DBA_SYS_PRIVS;
< SYS, ADMIN, YES >
< SYSTEM, ADMIN, YES >
< SOLIDSNAKE, ADMIN, YES >
< SOLID, CREATE SESSION, NO >
4 rows found.

Membuat Database Oracle TimesTen Baru

Oracle TimesTen adalah sebuah database yang dioptimalkan untuk penggunaan in-memory.   Berdasarkan apa yang diiklankan, algoritma yang dipakai TimesTen mengandaikan bahwa seluruh data terdapat di memory sehingga dioptimalisasikan berdasarkan karakteristik memori bukan hard drive.   Kode program aplikasi pun dapat mengambil keuntungan dari database in-memory.   Sebagai contoh, masalah yang sering dihadapi dalam aplikasi bisnis adalah perhitungan total (misalnya total untuk nilai dari transaksi atau total untuk jumlah item yang tersedia).   Umumnya nilai total tersebut disimpan dan diperbaharui secara bertahap setiap kali ada perubahan transaksi (baik itu tambah, edit, atau hapus).   Agregasi seperti ini kerap membuat kode program menjadi lebih rumit dan rentan kesalahan.   Bila memakai database in-memory, kode program dapat melakukan perhitungan total untuk seluruh data yang ada kapan saja tanpa harus terlalu mengkhawatirkan masalah kinerja.

Seperti database in-memory lainnya, Oracle TimesTen tetap membutuhkan hard drive untuk keperluan logging/backup dan untuk menyimpan data secara permanen.   Sebuah database TimesTen diwakili oleh direktori yang berisi file data.   Database ini akan dirujuk oleh sebuah Data Manager DSN (Data Source Name).   Koneksi pertama kali ke sebuah DSN akan memindahkan database TimesTen yang dirujuknya ke memori.

Untuk membuat sebuah Data Manager DSN baru, saya membuka Control Panel, Administrative Tools, dan Data Sources (ODBC).   Pada dialog yang muncul, di tab User DSN, saya men-klik tombol Add… seperti yang terlihat pada gambar berikut ini:

Membuat DSN Baru

Membuat DSN Baru

Pada dialog Create New Data Source yang muncul, saya memilih TimesTen Data Manager 11.2.2, lalu men-klik tombol Finish seperti yang diperlihatkan pada gambar berikut ini:

Memilih Driver

Memilih Driver

Akan muncul sebuah dialog TimesTen ODBC Setup dimana saya bisa melakukan beberapa pengaturan.   Sebagai contoh, saya melakukan pengaturan pada tab Data Store menjadi seperti yang terlihat pada gambar berikut ini:

Atribut Data Store

Atribut Data Store

Data Source Name adalah DSN yang dipakai sebagai pengenal dalam melakukan koneksi nantinya.   Saya meletakkan lokasi dimana file database akan disimpan pada atribut Data Store Path.   Pada konfigurasi di atas, file database akan disimpan di folder C:\latihan dan setiap file database akan diawali dengan nama test.   Pada Database Character Set, saya memilih AL32UTF8 untuk memakai unicode.

Tab berikutnya, First Connection, adalah daftar atribut yang dipakai hanya pada saat koneksi pertama kali ke database (dimana database akan dipindahkan dari file ke memori).   Saya mengisinya seperti terlihat pada gambar berikut ini:

Atribut First Connection

Atribut First Connection

Nilai Permanent Data Size dan Temporary Data Size menentukan jumlah memori yang dipakai oleh database TimesTen ini.   Permanent data adalah bagian memori yang mewakili tabel dan index.   Isi dari permanent data akan dibaca dari file pada saat koneksi pertama kali dan akan disimpan ke file pada proses checkpoint.   Sebaliknya, isi dari temporary data akan hilang pada saat database dibersihkan dari memori.   Temporary data menampung cursor dan struktur data lainnya yang diperlukan pada saat mengerjakan query.   Pada database yang saya buat ini, ukuran permanent data adalah 256 MB dan ukuran temporary data adalah 128 MB.

Sebuah database yang tidak dapat menyimpan data secara permanen tidak akan banyak berguna.   Lalu, bila seluruh data ada di memori, kapan perubahan di memori akan ditulis (disimpan) ke file?   Aplikasi dapat memberikan perintah untuk mengerjakan operasi checkpoint, atau menunggu terjadinya operasi checkpoint.   Checkpoint adalah sebuah proses dimana isi database yang ada di memori akan dipindahkan ke file.   TimesTen mengerjakan checkpoint di balik layar secara otomatis sesuai dengan periode yang telah ditentukan.   Karena checkpoint merupakan operasi yang berat (menulis ke file), maka sebaiknya checkpoint tidak terlalu sering dilakukan.   Jangan lupa bahwa operasi checkpoint yang jarang dikerjakan meningkatkan resiko kehilangan data bila terjadi kegagalan sistem.   Khusus untuk menghindari hilangnya data akibat pemadaman listrik, gunakan UPS.   Untuk mengatur kapan operasi checkpoint dikerjakan, saya mengisi nilai atribut Ckpt Frequency (secs) (per detik) atau Ckpt Log Volume (per jumlah data yang telah diproses).   Sebagai contoh, pada database percobaan ini, saya mengatur agar operasi checkpoint bekerja setiap 1.800 detik atau 30 menit.

Pastikan bahwa tanda centang pada Auto create telah diberikan.   Konfigurasi ini menyebabkan TimesTen akan membuat file database secara otomatis bila sebelumnya tidak ada.   Walaupun demikian, saya tetap perlu membuat folder database (pada konfigurasi saya adalah c:\latihan) secara manual.

Pada tab berikutnya, General Connection, saya tidak melakukan perubahan.   Atribut yang menarik pada tab ini adalah durable commits. Saya tidak memberikan tanda centang di durable commits.   Ini menyebabkan seluruh transaksi saya adalah non-durable commit.   Bila perubahan data bersifat kritis (tidak boleh sampai hilang!), maka saya perlu memberikan tanda centang pada pilihan durable commits sehingga transaksi yang di-commit akan langsung ditulis ke log file pada saat itu juga.   Hal ini akan berdampak pada kinerja database in-memory, tetapi resiko kehilangan data akibat kegagalan sistem juga ikut berkurang.   Selain itu, aplikasi tetap mendapatkan keuntungan kinerja pada operasi SELECT yang hanya membaca data.

Pada tab NLS Connection,  saya memastikan bahwa character set yang dipakai untuk koneksi database sama dengan character set yang dipakai oleh database sehingga TimesTen tidak perlu melakukan konversi.

Atribut NLS Connections

Atribut NLS Connections

Saya tidak akan menjalankan database ini sebagai IMDB Cache (cache bagi Oracle Database) sehingga saya tidak mengubah tab IMDB Cache.   Saya akan melakukan direct connection di komputer yang sama dan tidak melakukan koneksi client-server sehingga saya juga tidak perlu mengatur tab Server.   Demikian juga saya juga membiarkan tab PL/SQL begitu saja tanpa perubahan.

Setelah selesai mengisi seluruh atribut yang ada, saya men-klik tombol OK.   Sampai disini, saya telah membuat Data Manager DSN bernama LATIHAN.

Langkah berikutnya, saya membuka Control Panel, Services untuk memastikan bahwa service TimesTen Data Manager 11.2.2 telah dijalankan.   Alternatif lainnya, saya dapat menjalankan TimesTen Data Manager melalui Command Prompt seperti yang terlihat pada gambar berikut ini:

Menjalankan TimesTen Data Manager dari Command Prompt

Menjalankan TimesTen Data Manager dari Command Prompt

Setelah itu, saya akan memakai tool ttIsql untuk mencoba melakukan koneksi ke database.   Tool ini bekerja mirip seperti mysql di database MySQL Server atau sqlplus di Oracle Database.   Satu hal yang penting adalah koneksi pertama ke database akan membuat file database bila belum dibuat sebelumnya dan memindahkan file database ke memori.   Untuk saat ini, hanya instance administrator saja yang berhak untuk menjalankan database saya pertama kalinya.   Instance administrator adalah user di sistem operasi yang memiliki akses untuk mengelola Oracle TimesTen.

Saya tidak menentukan UID (nama user) di Data Manager DSN yang saya buat sehingga nama user akan diambil dari nama user sistem operasi yang sedang saya pakai saat ini.   Jadi, saya hanya perlu memastikan bahwa user ini adalah user yang sama dengan yang men-install Oracle TimesTen.   Setelah itu, saya memberikan perintah seperti yang terlihat berikut ini:

C:\>ttIsql LATIHAN

Copyright (c) 1996, 2013, Oracle and/or its affiliates. All rights reserved.
Type ? or "help" for help, type "exit" to quit ttIsql.

connect "DSN=LATIHAN";
Connection successful: DSN=LATIHAN;UID=Snake;DataStore=C:\latihan\test;Dat
abaseCharacterSet=AL32UTF8;ConnectionCharacterSet=AL32UTF8;DRIVER=C:\TimesTen\TT
1122~1\bin\ttdv1122.dll;PermSize=256;TempSize=128;LogFlushMethod=1;CkptFrequency
=1800;TypeMode=0;PLSCOPE_SETTINGS=IDENTIFIERS:NONE;RangeIndexType=1;
(Default setting AutoCommit=1)
Command>

Setelah perintah di atas, file database akan dibuat dan isinya akan dipindahkan ke memori.   File database tersebut adalah test.ds0, test.ds1, test.log0, test.res0, test.res1, dan test.res2.   Saya juga dapat melihat status memori dengan memberikan perintah dssize pada ttIsql seperti yang terlihat berikut ini:

Memeriksa status memori

Memeriksa status memori

Menampilkan Log SQL Yang Dikerjakan MySQL

Kode program yang memakai ORM (object relational mapper) seperti JPA umumnya tidak memberikan query SQL secara langsung karena query akan dihasilkan oleh sang mapper.   Tapi terkadang developer perlu mengetahui apa saja query SQL yang dihasilkan oleh ORM, misalnya untuk keperluan troubleshooting atau mencari bottleneck kinerja.   Bila memakai database MySQL, si developer memiliki beberapa pilihan untuk melihat SQL yang dibuat oleh aplikasi tanpa perlu memakai tool tambahan.

JDBC bawaan untuk MySQL sudah menyediakan fasilitas logging.   Hasil log-nya lebih detail karena dilengkapi dengan nilai parameter dibandingkan dengan yang terlihat di log Hibernate yang hanya menuliskan isi prepared statement dimana nilai masih berupa tanda tanya (?).  Untuk mengaktifkan logging di JDBC, saya perlu menambahkan sesuatu di JDBC URL, yaitu nilai logger dan profileSQL.  Sebagai contoh, bila saya memakai JPA, maka saya mengubah isi berikut ini di persistence.xml:

...
<properties>
   ...
   <property name="javax.persistence.jdbc.url"
      value="jdbc:mysql://localhost/namadb?logger=com.mysql.jdbc.log.Slf4JLogger&amp;profileSQL=true" />
   ...
</properties>
...

Nilai profileSQL menunjukkan agar driver JDBC tersebut akan mencatat setiap SQL yang ada.   Sementara itu, nilai logger menunjukkan tujuan yang menyimpan catatan SQL nantinya.    Saya memilih menggunakan SlfjLogger yang akan mencatat sesuai dengan konfigurasi Log4j saya.  Saya memisahkan kedua nilai tersebut dengan &amp; karena ini adalah XML;  bila tidak memakai JPA, misalnya saya membuat koneksi di kode program, maka saya boleh langsung memakai tanda ampersand (&).

Langkah berikutnya adalah melakukan konfigurasi Log4J.  Bila memakai Griffon, maka perubahan ini dapat dilakukan di file Config.groovy.  Sebagai contoh, saya akan mencatat log SQL yang dikerjakan aplikasi ke sebuah file:

log4j = {
  ...
  appenders {
     rollingFile name: 'sqlLog', file: "${System.getProperty('user.home')/sql.log",
        layout: pattern(conversionPattern: '%d [%t] %-5p %c - %m%n'), maxFileSize: 10485760)
  }
  ...
  debug additivity: false, sqlLog: 'com.mysql.jdbc.log'
  ...

Setelah ini, bila aplikasi dijalankan, saya dapat menemukan seluruh SQL yang dikerjakan di file sql.log yang terletak di folder home (seperti C:\Users\nama\).

Alternatif lainnya, saya dapat melakukan pencatatan SQL ini disisi server MySQL itu sendiri.  Hal ini berguna bila database diakses oleh banyak user secara bersamaan, dan saya ingin melihat seluruh SQL yang dikerjakan oleh user-user yang terkoneksi.  Perlu diperhatikan bahwa pencatatan melalui general query log ini tidak harus berurut sesuai dengan eksekusinya, melainkan berdasarkan urutan saat diterima dari client.

Untuk melakukan pencatatan di sisi server, saya harus melakukan konfigurasi MySQL, misalnya dengan mengubah file my.ini yang ada di folder instalasi MySQL (seperti C:\Program Files\MySQL\MySQL Server 5.6\my.ini).  Saya harus mengubah file tersebut sehingga terdapat baris berikut ini:

log-output=FILE
general-log=1
general-log-file="sql.log"

Setelah me-restart server MySQL, maka seluruh SQL yang dikerjakan oleh server tersebut akan tercatat di file sql.log.  File ini terletak di lokasi yang sesuai dengan nilai datadir (nilainya tertera di file konfigurasi yang sama, atau gunakan perintah SHOW VARIABLES LIKE 'datadir'; untuk melihat nilainya)Secara default, lokasi ini adalah di C:\ProgramData\MySQL\MySQL Server 5.6\data.

Berikutnya, jalankan aplikasi, tunggu hingga log terkumpul (gunakan tail -f untuk memantau bila di Linux), lalu cari query yang menjadi biang kesalahannya 🙂

Oracle Database: Rumah Oracle di Windows XP

Saat meng-otak atik registry di Windows, aku menemukan bahwa Oracle menambahkan entry registry baru setiap kali aku memasukkan Oracle Home baru saat instalasi melalui Oracle Universal Installer. Padahal, di tengah proses wizard, aku telah memilih untuk membatalkan instalasi. Entry tersebut dapat ditemukan di HKEY_LOCAL_MACHINE\sOFTWARE\ORACLE.

Aku sering mendengar apa yang disebut variabel ORACLE_HOME. Tapi variabel ini tidak pernah di-set di environment, dan tidak direkomendasikan untuk melakukan hal tersebut. Lalu bagaimana aku bisa mengetahui nilai ORACLE_HOME? Ternyata aplikasi Oracle akan mencari file oracle.key di ORACLE_HOME\bin. Misalnya jika aku menjalankan:


c:\oracle\product\10.1.0\db_Latihan\bin\sqlplus.exe

maka Oracle akan mencari file berikut:


c:\oracle\product\10.1.0\db_Latihan\bin\oracle.key

dan di sistem-ku, isi file tersebut adalah:


SOFTWARE\ORACLE\KEY_OraDb10g_homeLatihan

baru kemudian Oracle mengambil informasi ORACLE_HOME di registry Windows.

My FAQ: Sekedar Catatan dan Review

Bagaimana cara melihat isi server parameter file?

Login ke SQL*Plus, kemudian ketik perintah SHOW PARAMETERS nama_parameter. Contoh:


SHOW PARAMETERS DB_NAME

  • Bagaimana cara mematikan database Oracle melalui SQL*Plus?Login ke SQL*Plus sebagai SYSDBA, lalu berikan perintah SHUTDOWN IMMEDIATE.
  • Bagaimana cara menyalakan kembali database Oracle melalui SQL*Plus?Login ke SQL*Plus sebagai SYSDBA, lalu berikan perintah STARTUP.
  • Bagaimana cara menutup session koneksi ke database?Tentukan terlebih dahulu SID dan Serial Number (SERIAL#) dari session yang akan di-terminate dengan memeriksa isi V$SESSION. Setelah itu, berikan perintah ALTER SYSTEM KILL SESSION ‘nomorSID,nomorSerial’, seperti:


    ALTER SYSTEM KILL SESSION '147,11';

  • Bagaimana membuat tabel temporary yang isinya selalu dihapus setiap kali commit?Buat tabel dengan perintah DDL seperti berikut:


    CREATE GLOBAL TEMPORARY TABLE tbl_temp (
      user_id CHAR(10),
      no# NUMBER(10)
    ) ON COMMIT DELETE ROWS;
  • O ya, aku menemukan instalasi Oracle dalam sistem-ku secara otomatis membuat job dalam scheduler-nya, yaitu PURGE_LOG dan GATHER_STATS_JOB (untuk mengumpulkan statistik yang berguna bagi query optimizer). Job PURGE_LOG dijadwalkan berjalan setiap hari pada jam 03:00:00 AM. Tapi karena aku tidak pernah meninggalkan Oracle-ku menyala setiap jam 3 pagi, maka job ini akan dikerjakan setiap kali aku pertama kali menyalakan komputer di pagi hari. Job GATHER_STATS_JOB dijadwalkan pada predefined window WEEKNIGHT_WINDOW (jam 10:00:00 PM dari Senin s/d Jumat) dan WEEKEND_WINDOW (tengah malam pada hari Sabtu). Pada log history untuk GATHER_STATS_JOB, aku melihat job tersebut beberapa kali gagal di-eksekusi mengingat alokasi memori di SGA yang aku berikan memang sangat terbatas.

    Sekilas Info: Tips Menjelang Tahun Baru

    Selamat merayakan tahun baru di malam tahun baru ini!!! Saat ini aku sedang membaca dan mengetik di depan notebook sambil mendengar suara kembang api saling meramaikan tiada henti. Aku yakin saat ini jalanan sedang penuh sesak dengan orang-orang yang tidak ingin melewatkan momen pergantian tahun malam nanti. Aku juga tidak ingin membiarkan semangat tahun baru ini berlalu begitu saja… Aku akan menghabiskan malam tahun baru ini dengan penuh semangat bersama…Oracle 10g 😉

    O ya, aku pernah menuliskan bahwa pada instalasi default, aku bisa connect ke SQL*Plus melalui user OS, dengan perintah seperti berikut:

    sqlplus / as sysdba

    Bila aku tidak suka, aku bisa membuka Oracle Net Manager, lalu memilih Local, Profile, kemudian pada dropdown yang ada, aku memilih Oracle Advanced Security. Setelah itu aku memindahkan item NTS yang ada di selected methods ke bagian available methods.

    Ingin memakai SQL*Plus berbasis Windows tapi hendak login sebagai SYSDBA? Caranya gampang saja, buka SQL*Plus for Windows, lalu saat diminta mengisi data logon, isi user name dengan SYS AS SYSDBA. Jangan mengisi bagian password, tetapi langsung tekan tombol OK. Setelah itu akan muncul Enter password:. Isi password dan selamat ber-SQL ria!!