Доброго времени.Досталась мне в обслуживание система биллинга на связке php + mysql. Тип таблиц - InnoDB.
Критичная область проблемы - выборочное исполнение (точнее, неисполнение запросов к базе). Пример:
$_db->query('START TRANSACTION;'); // Запрос #1if(!$_db->query('INSERT INTO table1 (p1, p2) VALUES (v1, v2);')) { // Запрос #2
$_db->query('ROLLBACK;');
$_log->write('epic fail');
return;
}// исполнение кода
if(!$_db->query('INSERT INTO table2 (p1, p2) VALUES (v1, v2);')) { // Запрос #3
$_db->query('ROLLBACK;');
$_log->write('epic fail');
return;
}
$_db->query('COMMIT;');
$_log->write('ok');В итоге, при ~500-550 qps имеем следующую ситуацию:
1. В логах всегда Ok
2. Периодически данных по запросу #2 или #3 найти невозможно. DELETE FROM над таблицами не используется.Конфиг mysql http://pastebin.org/97730
Админ объясняет это траблами в InnoDB. Не верю, чтоб были такие явные косяки. Может быть, кто-то сталкивался с такой ерундой?PS: на PG / Oracle переходить не предлагать. Переписывать систему не комильфо.
>Админ объясняет это траблами в InnoDB. Не верю, чтоб были такие явные
>косяки. Может быть, кто-то сталкивался с такой ерундой?
>grep innodb my.cnf
ls -l <mysqldatadir> | grep innodb
show innodb status
grep:
innodb_additional_mem_pool_size = 16M
innodb_buffer_pool_size = 1G
innodb_data_file_path = ibdata1:10M:autoextend
innodb_file_io_threads = 16
innodb_thread_concurrency = 400
innodb_flush_log_at_trx_commit = 2
innodb_log_buffer_size = 8M
innodb_log_file_size = 256M
innodb_log_files_in_group = 5
innodb_max_dirty_pages_pct = 90
innodb_lock_wait_timeout = 50
ls :
-rw-rw---- 1 mysql wheel 268435456 Feb 26 14:57 ib_logfile0
-rw-rw---- 1 mysql wheel 268435456 Feb 26 14:57 ib_logfile1
-rw-rw---- 1 mysql wheel 268435456 Feb 26 03:09 ib_logfile2
-rw-rw---- 1 mysql wheel 268435456 Feb 26 06:59 ib_logfile3
-rw-rw---- 1 mysql wheel 268435456 Feb 26 10:32 ib_logfile4
-rw-rw---- 1 mysql wheel 2980052992 Feb 26 14:57 ibdata1| InnoDB |
=====================================
100226 14:58:13 INNODB MONITOR OUTPUT
=====================================
Per second averages calculated from the last 23 seconds
----------
SEMAPHORES
----------
OS WAIT ARRAY INFO: reservation count 8732595, signal count 7895654
Mutex spin waits 0, rounds 3490253727, OS waits 2228184
RW-shared spins 10518077, OS waits 3542295; RW-excl spins 10215858, OS waits 1218629
------------
TRANSACTIONS
------------
Trx id counter 0 926863299
Purge done for trx's n:o < 0 926861822 undo n:o < 0 0
History list length 312
LIST OF TRANSACTIONS FOR EACH SESSION:
---TRANSACTION 0 0, not started, OS thread id 559960448
MySQL thread id 36284963, query id 332161548 localhost root| FILE I/O |
--------
I/O thread 0 state: waiting for i/o request (insert buffer thread)
I/O thread 1 state: waiting for i/o request (log thread)
I/O thread 2 state: waiting for i/o request (read thread)
I/O thread 3 state: waiting for i/o request (write thread)
Pending normal aio reads: 0, aio writes: 0,
ibuf aio reads: 0, log i/o's: 0, sync i/o's: 0
Pending flushes (fsync) log: 0; buffer pool: 0
2071667 OS file reads, 39079783 OS file writes, 779674 OS fsyncs
0.22 reads/s, 16384 avg bytes/read, 86.00 writes/s, 1.35 fsyncs/s
-------------------------------------
INSERT BUFFER AND ADAPTIVE HASH INDEX
-------------------------------------
Ibuf: size 1, free list len 15, seg size 17,
291473 inserts, 291472 merged recs, 110870 merges
Hash table size 2212699, node heap has 9322 buffer(s)
21026.26 hash searches/s, 1639.84 non-hash searches/s---
LOG
---
Log sequence number 31 2793368864
Log flushed up to 31 2793368386
Last checkpoint at 31 2779903588
0 pending log writes, 0 pending chkp writes
38369147 log i/o's done, 85.00 log i/o's/second----------------------
BUFFER POOL AND MEMORY
----------------------
Total memory allocated 1199697336; in additional pool allocated 14679552
Dictionary memory allocated 539000
Buffer pool size 65536
Free buffers 1
Database pages 56213
Modified db pages 634
Pending reads 0
Pending writes: LRU 0, flush list 0, single page 0
Pages read 10935911, created 18868, written 883463
0.22 reads/s, 0.00 creates/s, 1.78 writes/s
Buffer pool hit rate 1000 / 1000
--------------
ROW OPERATIONS
--------------
0 queries inside InnoDB, 0 queries in queue
1 read views open inside InnoDB
Main thread id 559951616, state: sleeping
Number of rows inserted 1933044, updated 45122875, deleted 1341543, read 33814593609
2.26 inserts/s, 164.34 updates/s, 0.13 deletes/s, 40046.65 reads/s
----------------------------
END OF INNODB MONITOR OUTPUT
============================
> if(!$_db->query('INSERT INTO table1 (p1, p2) VALUES (v1, v2);')) { // Запрос #2
> $_db->query('ROLLBACK;');
> $_log->write('epic fail');
> return;
> }А если заменить "if(!$_db->..." на "if(false === $db->..." ?
>А если заменить "if(!$_db->..." на "if(false === $db->..." ?Не напоминает
if( strlen( booltostr($value) ) < 5 ){
#true
...
}else{
#false
...
}? :)
>2. Периодически данных по запросу #2 или #3 найти невозможно.Невозможно найти запросом в том же скрипте, или даже спустя какое-то время (ну, напр., 1 сек)? Т.е. иными словами, данные из #2 и #3 таблицу не записываются вообще?
>Конфиг mysql http://pastebin.org/97730
Там что-то пусто. В вашем конфиге так же? :)
>innodb_flush_log_at_trx_commit = 2
А со значением 1 траблы наблюдаются?
И вообще, в этом скрипте вам принципиально использовать транзакции? Вам надо "либо 0 инсертов, либо сразу 2"?