Баг или фича?

WP

^_^
Баг или фича?

Есть таблицы t1 и t2. MyISAM.
t1 содержит значительное кол-во рядов и в данном случае используется только для SELECT.
t2 заполняется с помощью INSERT INTO `t2` SELECT ... FROM `t1`.
Во время выполнения заполнения, t1 блокируется не только на запись, но и на чтение, что мне кажется неправильным. Ведь можно же читать одновременно в несколько потоков.
Также есть запросы на запись в t1, они как и нужно, висят как Locked.

MySQL 5.0.45-log.

Спасибо за внимание.
 

svetasmirnova

маленький монстрик
Не должна блокироваться на чтение. У меня в версии 5.0.51a не блокируется на тестовых данных. Обновись и если сможешь повторить сделай repeatable test case.
 

WP

^_^
Велика ли вероятность что после обновления пройдет? Просто есть некоторые ограничения)
 

svetasmirnova

маленький монстрик
Честно говоря лень тестировать на 5.0.45 :)

А как ограничения могу помешать? Таблицы же MyISAM. Смотри как проверить:

1. Ставишь новую версию в отдельную директорию
2. Копируешь t1.* и t2.* из директории базы в datadir новой версии
3. Запускаешь свой запрос.
4. Смотришь в другом клиенте.
 

WP

^_^
svetasmirnova
Спасибо, но как бы я в курсе =) кстати в этом случае не копировать, а mysqlhotcopy.

-~{}~ 04.06.08 06:39:

После обновления ничего не изменилось. Я подозреваю это происходит потому что выполняется долгий INSERT ... SELECT, еще выполняются UPDATE'ы (разумеется в статусе Locked висят), а они в свою очередь блокируют на чтение. Другого объяснения не нахожу.
 

antson

Новичок
Партнер клуба
WP
попробуй поиграть параметрами
bulk_insert_buffer_size
max_write_lock_count
 

antson

Новичок
Партнер клуба
4,294,967,295 по дефолту стоит как max_write_lock_count
в результате селесты всегда ждут окончания инсерта.
попробуй поставить 1000 в результате твой длинный инсерт
будет снимать блокировки и давать паралельным селектам
отработать.

если селектовская часть инсерта с тяжелым планым выполнения
или в условиях участвует таблица в которую ты вставляешь
данные, то попробуй разбить задачу на два запроса.
первым отбираешь во временную таблицу и только потом инсертишь.
 

WP

^_^
antson
Попробовал, увы, без изменений.

> если селектовская часть инсерта с тяжелым планым выполнения
Не участвует.

http://keeperweb.com/files/m.txt (после SET GLOBAL max_write_lock_count =1000 и запуска процесса)
 

antson

Новичок
Партнер клуба
INSERT IGNORE INTO `hints_old` SELECT
полный текскт запроса напишите ...
 

WP

^_^
[sql]INSERT IGNORE INTO `hints_old` SELECT NULL, `artist`, `title`, CRC32(LOWER(CONCAT(`artist`,"\x00",`title`))) FROM `project_crawler`.`media` WHERE `indexed` = 1[/sql]
 

antson

Новичок
Партнер клуба
что то я немного в шоке.
флаг индексации в медиа поднимается в единицу и потом не сбрасывается ?
в хинтах ключи, индексы какие ?

использованный Вами IGNORE наводит на мысли,
что вы каждый раз пытаетесь проинсертить кучу записей, только для того чтобы вставить несколько штук.
 

WP

^_^
antson
indexed это статус.
[sql]
CREATE TABLE `hints_old` (
`id` int(10) unsigned NOT NULL auto_increment,
`artist` varchar(200) NOT NULL,
`title` varchar(200) NOT NULL,
`unique` int(11) unsigned NOT NULL,
PRIMARY KEY (`id`),
UNIQUE KEY `unique` (`unique`),
KEY `artist` (`artist`),
KEY `title` (`title`)
) ENGINE=MyISAM DEFAULT CHARSET=utf8 AUTO_INCREMENT=1 ;
[/sql]
Да, 3 млн. записей, повторки тоже встречаются.
 

antson

Новичок
Партнер клуба
у тебя 5ка муськи
попробуй переписать через хранимку
CREATE PROCEDURE `hint_add`
BEGIN
DROP TEMPORARY TABLE IF EXISTS InsertRows;
CREATE TEMPORARY TABLE Insert Rows(
`artist` varchar( 200 ),
`title` varchar( 200 ) ,
`unique` int( 11 ) unsigned
) ENGINE=MEMORY;
// -- теперь отбираем в эту таблицу записи подходящие под вставку

insert into InsertRows select `artist` , `title` , CRC32(
LOWER( CONCAT( `artist` , "\x00", `title` ) ) from media where INDEXED=1 AND
not exist (select 1 from hints_old b where b.unique= CRC32(
LOWER( CONCAT( a.artist` , "\x00", a.title ) )
)

// полученные записи инсертим уже в хинты

INSERT ..
// КОНЕЦ
DROP TEMPORARY TABLE IF EXISTS InsertRows;

END
 

antson

Новичок
Партнер клуба
подзапросом отбираем только новые записи которых еще не было в таблице .
3 милиона записей писали ? вот только не сказали
где и каких .
в медиа сколько строк ?
в старых хинтах ?
в медиа со статусом индексед ?
сколько из них еще не вставлено ?

подзапросом отбираем к инсерту только те что нужны,
думаю их не так много и вставка только их пройдет быстрее
чем совать все в надежде на IGNORE
 

WP

^_^
> в медиа сколько строк ?
mysql> SELECT COUNT(*) FROM `media` WHERE indexed=1;
+----------+
| COUNT(*) |
+----------+
| 2001953 |
+----------+
1 row in set (0.00 sec)
> в старых хинтах ?
hints это таблица которая при запуске данной операции очищается и заполняется данными из media.
hints_old это для того чтобы на время операции сервис работал.
Т.е. после INSERT'а, hints становится hints_old и очищается, а hints_old становится hints и принимает на себя сервис.
> думаю их не так много и вставка только их пройдет быстрее
После вставки в hints, там 1,103,082.

-~{}~ 04.06.08 12:14:

Собственно проблема не в скорости выполнения вставки, она может хоть час выполняться - безразлично. Проблема в блокировке media на чтение... т.е. если вместо 5 мин. она будет блокироваться на 3 мин., это проблему не решит....
 

antson

Новичок
Партнер клуба
WP
раз таблицы тассуются у каждый раз ты выбираешь целиком попробуй вставлять в таблицу без индексов по артисту и титлу, после вставки через алтер табле их востановишь.
 
Сверху