Вопросик по InnoDBИспользую mysql 5.1.26
ОС : FreeBSD server.domain.com 6.3
ОЗУ : 3 Гига
Захотел я потестить InnoDB и столкнулся с проблемой.Создал я таблицу на 100000 записей, структура такова :
mysql> describe accounts;
+----------+-------------+------+-----+---------+----------------+
| Field | Type | Null | Key | Default | Extra |
+----------+-------------+------+-----+---------+----------------+
| id | bigint(20) | NO | PRI | NULL | auto_increment |
| username | varchar(32) | NO | | NULL | |
| password | varchar(32) | NO | | NULL | |
+----------+-------------+------+-----+---------+----------------+
3 rows in set (0.16 sec)
Запускаю приложение, которое подключается к серверу бд, выгребает первую запись и удаляет ее и ждет 5-10 секунд и продолжает.
Обращения есс-но идут к таблице вышеприведенной.Перечень запросов таков :
START TRANSACTION
SELECT id, username, password FROM accounts LIMIT 1 FOR UPDATE
проверяю то что вернулось , если все ок, то
DELETE FROM accounts WHERE id=" + result[0]
COMMITЕсли запускать в 10 потоках, то все работает на ура. Пробовал я запускать при 300 потоках - работало минут 10 нормально (обработало 30к записей), а потом
таблица залочилась :(В show processlist вот такое :
| 46046 | root | localhost | dev | Query | 768 | Sending data | SELECT id, username, password FROM accounts LIMIT 1 FOR UPDATE |
| 46047 | root | localhost | dev | Query | 767 | Sending data | SELECT id, username, password FROM accounts LIMIT 1 FOR UPDATE |
| 46048 | root | localhost | dev | Query | 767 | Sending data | SELECT id, username, password FROM accounts LIMIT 1 FOR UPDATE |
| 46049 | root | localhost | dev | Query | 767 | Sending data | SELECT id, username, password FROM accounts LIMIT 1 FOR UPDATE |
| 46050 | root | localhost | dev | Query | 767 | Sending data | SELECT id, username, password FROM accounts LIMIT 1 FOR UPDATE |
| 46059 | root | localhost | dev | Query | 0 | NULL | show processlist |
+-------+------+-----------+------+---------+------+--------------+----------------------------------------------------------------+
367 rows in set (0.00 sec)В логах мускула никах эксепшинов нету.
Может что то с настройками Innodb нето ?
Вот как у меня :# Uncomment the following if you are using InnoDB tables
innodb_data_home_dir = /usr/local/mysql/data/
innodb_data_file_path = ibdata1:10M:autoextend
innodb_log_group_home_dir = /usr/local/mysql/data/
# You can set .._buffer_pool_size up to 50 - 80 %
# of RAM but beware of setting memory usage too high
innodb_buffer_pool_size = 256M
innodb_additional_mem_pool_size = 20M
# Set .._log_file_size to 25 % of buffer pool size
innodb_log_file_size = 64M
innodb_log_buffer_size = 8M
innodb_flush_log_at_trx_commit = 1
innodb_lock_wait_timeout = 50
Как это побороть что бы таблица не лочилась ?Можете предложить какие значения должны быть, что бы работало хотя бы при 300-500 потоков и не лочилось ?
Заранее благодарен.
>Использую mysql 5.1.26попробуйте для начала обновиться до последней версии.
5.1.26 не была стабильной и в принципе не предназначена для использования в продакшене
>Перечень запросов таков :
>
>START TRANSACTION
>SELECT id, username, password FROM accounts LIMIT 1 FOR UPDATE
>проверяю то что вернулось , если все ок, то
>DELETE FROM accounts WHERE id=" + result[0]
>COMMITFOR UPDATE блокирует всю таблицу, а уже потом количество строк ограничивается до 1. Это весьма чётко отражено в документации.
>Можете предложить какие значения должны быть, что бы работало хотя бы при
>300-500 потоков и не лочилось ?Очень большое число потоков. Надо использовать оптимистичные блокировки.
Например так.1. SELECT id, username, password FROM accounts WHERE locked=false LIMIT 1
2. UPDATE accounts SET locked=true WHERE id = <id из первого запроса> AND locked=false
3. проверить если rows_updated<1 перейти к шагу 1
4. делай свои проверки
5. DELETE FROM accounts WHERE id = <id из первого запроса>
>Очень большое число потоков. Надо использовать оптимистичные блокировки.А что такое "оптимистичные блокировки" ? И что за locked в "WHERE locked=false". Вообще эта конструкция к innodb относится или к myisam ?
>И что за locked в "WHERE locked=false".Добавь поле в таблицу.
>Вообще эта конструкция к innodb относится или к myisam ?
Ни к тому ни к другому. Это обычный sql.
>>И что за locked в "WHERE locked=false".
>
>Добавь поле в таблицу.
>
>>Вообще эта конструкция к innodb относится или к myisam ?Спасибо огромное, я понял суть вашего примера. Только одного не могунайти, это как получить значение rows_updated после UPDATE запроса в Mysql.
>>>И что за locked в "WHERE locked=false".
>>
>>Добавь поле в таблицу.
>>
>>>Вообще эта конструкция к innodb относится или к myisam ?
>
>Спасибо огромное, я понял суть вашего примера. Только одного не могунайти, это
>как получить значение rows_updated после UPDATE запроса в Mysql.отвечаю сам себе : mysql_affected_rows :)
буду пробовать , спасибо svn