innodb adaptive hash index nedir ?

Eğer bir InnoDB bir tablo ayrılan bellek alanının tamamını doldurursa, mySQL hızlı sonuç döndürmek için b-tree indexler yerine innodb adaptive hash indexleri kullanmayı tercih eder. InnoDB adaptive hash indexler var olan B-Tree indexleme mimarisine göre oluşturulur ve yeni bellek eklediğiniz de InnoDB daha çok hash indexler oluşturacaktır. Burada unutulmaması gereken bu indexlerinde normal indexler gibi arada bir elden geçirilip optimize edilmesi gerektiğidir.

InnoDB bir tabloda tanımlanmış indexlerin kullanımlarını inceler. Daha sonrasında sık talep edilen indexleri bellekte otomatik oluşturulan bir hash tablosunda tutar. İndexlerin keylerine göre isimlendirerek tutar. Böylece bütün b-tree indexlerini bellekte tutmak zorunda kalmaz ve sadece en çok erişilen, istenen indexleri tutar.

Bu da ciddi performans kazanımlarına vesile olur.

B-Tree ve InnoDB adaptive hash index ile ilgili bir kaç link :

http://www.youtube.com/watch?v=coRJrcIYbF4
http://en.wikipedia.org/wiki/B-tree
http://dev.mysql.com/doc/innodb-plugin/1.0/en/innodb-performance-adaptive_hash_index.html
http://dev.mysql.com/doc/refman/5.0/en/innodb-adaptive-hash.html

Posted in MySQL, Veritabanları on November 13th, 2013 by Kürşad DARA | | 0 Comments

Innodb veritabanları için ibdata1’in dosyasının boyutunu küçültme (shrink edilmesi )

Innodb veritabanı kullanıyorsanız bir süre sonra ibdata1 dosyanızın çok fazla büyüdüğünü göreceksiniz.

Bu dosyanın büyümesi performans ve disk kullanımı açısından problem yaratacaktır. MySQL üstünde bu dosyanın küçültülmesi ile ilgili direk bir komut yok. O yüzden biraz çetrefilli bir yöntemle bu dosyanın boyutunu küçültmek gerekiyor.

Kısaca;

1. MySQL sunucuyu durdurun,
2. MySQL data dizinini komple yedekleyin,
3. MySQL sunucuyu tekrar başlatın,
4. Veritabanının yedeğini mysqldump ile alın,
5. Veritabanlarını silin,
6. MySQL sunucuyu tekrar durdurun,
7. ibdata1, ib_logfile0 ve ib_logfile1 dosyalarını silin,
8. MySQL sunucuyu tekrar çalıştırın,
9. Aldığınız yedeği tekrar yükleyin ( import )

bu adımlarla bu işlemi yapıyoruz.

Detaylara gelirsek;

1. MySQL sunucuyu durdurun.

2. MySQL data dizininin tamamını yedekleyin. Böylece herhangi bir sorun halinde geri dönmemiz kolay olacaktır.

3. MySQL sunucuyu tekrar başlatın.

4. Öncelikle veritabanının yedeğini alıyoruz.


/usr/bin/mysqldump --opt --routines --triggers --all-databases > all.sql

Yedeğin sağlık ve hatasız bir şekilde alındığından emin olun.

5. Veribanlarını drop ile silin.

6. MySQL sunucuyu tekrar durdurun.

7. MySQL data dizininde bulunan ibdata1, ib_logfile0 ve ib_logfile1 dosyalarını silin.

8. MySQL sunucuyu tekrar başlatın. MySQL sunucusunu çalıştırmadan önce. Konfigürasyon dosyanıza ( my.cnf )


innodb_file_per_table

parametresini ekleyin. Böylece artık her tablo için daha küçük bir ibd oluşmasını sağlayacaktır. Bu sayede ilerde çok büyüyen tabloları dump ve restore edip downtime yaşanmadan bu işlemleri yapabilir olursunuz.

Detaylı bilgi için : http://dev.mysql.com/doc/refman/5.6/en/innodb-multiple-tablespaces.html

9. Şimdi mysqldump ile aldığımız dosyayı tekrar import edip veritabanlarını tekrar yükleyin.


/usr/bin/mysql < all.sql

Posted in Linux, MySQL on November 21st, 2012 by Kürşad DARA | | 0 Comments

InnoDB en ideal log file size belirleme.

InnoDB kullandığınız yerlerde en ideal log file size ayarlamak için aşağıdaki gibi bir test yapabilirsiniz.

Bu işlem mySQL’de InnoDB veritabanlarının 1 dakikada aşağı yukarı ne kadar log yazdığını görüyoruz.

Bu işlemi veritabanının en yoğun zamanlarında yapmanız önerilir.

Öncelikle istediğimiz veriyi alabilmemiz için pager komutu ile sequenceleri yakalıyoruz.

mysql> pager grep sequence
PAGER set to 'grep sequence'

Sonra aşağıdaki gibi show innodb status çıktısını 1 dakika aralıklarla çalıştırıp başlangıç ve bitişte ne kadar log yazmış onu buluyoruz.

mysql> show engine innodb status\G select sleep(60); show engine innodb status\G

Log sequence number 156081984562
1 row in set (0.00 sec)

1 row in set (59.99 sec)

Log sequence number 156092992419
1 row in set (0.00 sec)

Daha sonra pager i tekrar sıfırlıyoruz.

mysql> pager
Default pager wasn't set, using stdout.

Şimdi aradaki farklı Mb cinsinden buluyoruz.

mysql> select ( 156092992419 - 156081984562 ) / 1024 / 1024 as mb;
+-------------+
| mb          |
+-------------+
| 10.49791050 |
+-------------+
1 row in set (0.00 sec)

Buradan anladığımız dakikada 10 mb veri yazılmış.

Saatlik bazda bakarsak 60*10=600MB.

innodb_log_file_size parametresini 600-700 Mb arası yapabiliriz.

Yukarıda yaptığımız testi mySQL 5.0 dan sonra SHOW GLOBAL STATUS komutu ile görebiliriz.

Bu komut çıktısındaki Innodb_os_log_written parametresinden de elde edebiliriz.

mysql> SHOW GLOBAL STATUS like '%Innodb_os_log_written%';
+-----------------------+-----------+
| Variable_name         | Value     |
+-----------------------+-----------+
| Innodb_os_log_written | 632924672 |
+-----------------------+-----------+
1 row in set (0.00 sec)

Posted in Linux, MySQL on November 16th, 2012 by Kürşad DARA | | 0 Comments

myisam ve innodb veritabanları için key_buffer_size ve innodb_buffer_pool_size hesaplayan query

İşinize yarayabilir.

Myisam için;

SELECT CONCAT(ROUND(KBS/POWER(1024,
IF(PowerOf1024<0,0,IF(PowerOf1024>3,0,PowerOf1024)))+0.4999),
SUBSTR(' KMG',IF(PowerOf1024<0,0,
IF(PowerOf1024>3,0,PowerOf1024))+1,1))
recommended_key_buffer_size FROM
(SELECT LEAST(POWER(2,32),KBS1) KBS
FROM (SELECT SUM(index_length) KBS1
FROM information_schema.tables
WHERE engine='MyISAM' AND
table_schema NOT IN ('information_schema','mysql')) AA ) A,
(SELECT 2 PowerOf1024) B;
mysql> SELECT CONCAT(ROUND(KBS/POWER(1024,
    -> IF(PowerOf1024<0,0,IF(PowerOf1024>3,0,PowerOf1024)))+0.4999),
    -> SUBSTR(' KMG',IF(PowerOf1024<0,0,
    -> IF(PowerOf1024>3,0,PowerOf1024))+1,1))inn
    -> recommended_key_buffer_size FROM
    -> (SELECT LEAST(POWER(2,32),KBS1) KBS
    -> FROM (SELECT SUM(index_length) KBS1
    -> FROM information_schema.tables
    -> WHERE engine='MyISAM' AND
    -> table_schema NOT IN ('information_schema','mysql')) AA ) A,
    -> (SELECT 2 PowerOf1024) B;
+-----------------------------+
| recommended_key_buffer_size |
+-----------------------------+
| 2095M                       |
+-----------------------------+
1 row in set (43.45 sec)

InnoDB için;

SELECT CONCAT(ROUND(KBS/POWER(1024,
IF(PowerOf1024<0,0,IF(PowerOf1024>3,0,PowerOf1024)))+0.49999),
SUBSTR(' KMG',IF(PowerOf1024<0,0,
IF(PowerOf1024>3,0,PowerOf1024))+1,1)) recommended_innodb_buffer_pool_size
FROM (SELECT SUM(data_length+index_length) KBS FROM information_schema.tables
WHERE engine='InnoDB') A,
(SELECT 2 PowerOf1024) B;
mysql> SELECT CONCAT(ROUND(KBS/POWER(1024,
    -> IF(PowerOf1024<0,0,IF(PowerOf1024>3,0,PowerOf1024)))+0.49999),
    -> SUBSTR(' KMG',IF(PowerOf1024<0,0,
    -> IF(PowerOf1024>3,0,PowerOf1024))+1,1)) recommended_innodb_buffer_pool_size
    -> FROM (SELECT SUM(data_length+index_length) KBS FROM information_schema.tables
    -> WHERE engine='InnoDB') A,
    -> (SELECT 2 PowerOf1024) B;
+-------------------------------------+
| recommended_innodb_buffer_pool_size |
+-------------------------------------+
| 93089M                              |
+-------------------------------------+
1 row in set (35.77 sec)

Kaynak : http://dba.stackexchange.com/questions/1/what-are-the-main-differences-between-innodb-and-myisam/2194#2194

Posted in Linux, MySQL on November 16th, 2012 by Kürşad DARA | | 0 Comments

InnoDB: Unable to lock ./xxxxxx/xxxxx.ibd, error: 11 hatası.

InnoDB bir veritabanında sunucuyu resetledikten sonra aşağıdaki hatayı aldık.

120209 05:12:29 mysqld_safe Starting mysqld daemon with databases from /usr/local/mysql/data/
120209  5:12:29 [Note] Plugin 'FEDERATED' is disabled.
InnoDB: The log sequence number in ibdata files does not match
InnoDB: the log sequence number in the ib_logfiles!
120209  5:12:29  InnoDB: Database was not shut down normally!
InnoDB: Starting crash recovery.
InnoDB: Reading tablespace information from the .ibd files...
InnoDB: Restoring possible half-written data pages from the doublewrite
InnoDB: buffer...
InnoDB: Unable to lock ./xxxxxx/xxxxx.ibd, error: 11
InnoDB: Check that you do not already have another mysqld process
InnoDB: using the same InnoDB data or log files.
120209  5:12:29  InnoDB: Assertion failure in thread 47546054463296 in file fil/fil0fil.c line 635
InnoDB: Failing assertion: ret
InnoDB: We intentionally generate a memory trap.
InnoDB: Submit a detailed bug report to http://bugs.mysql.com.
InnoDB: If you get repeated assertion failures or crashes, even
InnoDB: immediately after the mysqld startup, there may be
InnoDB: corruption in the InnoDB tablespace. Please refer to
InnoDB: http://dev.mysql.com/doc/refman/5.1/en/forcing-recovery.html
InnoDB: about forcing recovery.
120209  5:12:29 - mysqld got signal 6 ;
This could be because you hit a bug. It is also possible that this binary
or one of the libraries it was linked against is corrupt, improperly built,
or misconfigured. This error can also be caused by malfunctioning hardware.
We will try our best to scrape up some info that will hopefully help diagnose
the problem, but since we have already crashed, something is definitely wrong
and this may fail.

key_buffer_size=104857600
read_buffer_size=52428800
max_used_connections=0
max_threads=512
threads_connected=0
It is possible that mysqld could use up to 
key_buffer_size + (read_buffer_size + sort_buffer_size)*max_threads = 52536408 K
bytes of memory
Hope that's ok; if not, decrease some variables in the equation.

thd: 0x0
Attempting backtrace. You can use the following information to find out
where mysqld died. If you see no messages after this, something went
terribly wrong...
stack_bottom = (nil) thread_stack 0x40000
/usr/local/mysql/bin/mysqld(my_print_stacktrace+0x2e)[0x8ad46e]
/usr/local/mysql/bin/mysqld(handle_segfault+0x322)[0x5e05c2]
/lib64/libpthread.so.0[0x39a0a0e4c0]
/lib64/libc.so.6(gsignal+0x35)[0x39a0230215]
/lib64/libc.so.6(abort+0x110)[0x39a0231cc0]
/usr/local/mysql/bin/mysqld[0x7acc5c]
/usr/local/mysql/bin/mysqld[0x7acdf9]
/usr/local/mysql/bin/mysqld(fil_space_get_size+0xde)[0x7b407e]
/usr/local/mysql/bin/mysqld(fil_check_adress_in_tablespace+0x9)[0x7b4159]
/usr/local/mysql/bin/mysqld(trx_sys_doublewrite_init_or_restore_pages+0x2d5)[0x82b6d5]
/usr/local/mysql/bin/mysqld(recv_recovery_from_checkpoint_start+0x175b)[0x7dbe0b]
/usr/local/mysql/bin/mysqld(innobase_start_or_create_for_mysql+0x115f)[0x81b8cf]
/usr/local/mysql/bin/mysqld[0x777d64]
/usr/local/mysql/bin/mysqld(_Z24ha_initialize_handlertonP13st_plugin_int+0x31)[0x6cf411]
/usr/local/mysql/bin/mysqld[0x75513a]
/usr/local/mysql/bin/mysqld(_Z11plugin_initPiPPci+0x875)[0x757c95]
/usr/local/mysql/bin/mysqld[0x5e0d95]
/usr/local/mysql/bin/mysqld(main+0x1c1)[0x5e50b1]
/lib64/libc.so.6(__libc_start_main+0xf4)[0x39a021d974]
/usr/local/mysql/bin/mysqld(fmod+0x62)[0x513c0a]
The manual page at http://dev.mysql.com/doc/mysql/en/crashing.html contains
information that should help you find out what is causing the crash.
120209 05:12:29 mysqld_safe mysqld from pid file /usr/local/mysql/data//xxxxxx.pid ended

Çözüm olarak mysql i durdurup *.ibd dosyalarını taşıyıp tekrar cp -a ile kopyaladık ve mysql i çalıştırdık sorunumuz düzeldi.

Basit shell script şöyle :

#!/bin/bash
for i in `ls -a *.ibd`  
do  
  mv $i $i.bak
  cp -a $i.bak $i
done 

Posted in Linux, MySQL on February 9th, 2012 by Kürşad DARA | | 0 Comments

mySQL `ERROR 1205 (HY000): Lock wait timeout exceeded; try restarting transaction` hatası

Herhangi bir mySQL’de InnodB olan bir veritabanında update gibi table-lock koyan sorgusu çalıştırırken

ERROR 1205 (HY000): Lock wait timeout exceeded; try restarting transaction

hatasını alıyorsanız, konfigürasyon dosyasından

innodb_lock_wait_timeout=300

ekleyip mySQL i yeniden başlatırsanız sorununuz çözülecektir. Parametrenin değeri olan 300 saniye cinsindendir ve varsayılan değeri 50 sn. dir.

Bakınız : http://dev.mysql.com/doc/refman/5.0/en/innodb-parameters.html#sysvar_innodb_lock_wait_timeout

Posted in Linux, MySQL on January 9th, 2012 by Kürşad DARA | | 0 Comments