[MySql] конкурирующие update/select

oleg1331

Есть таблица:

CREATE TABLE `Objects` (
`objectId` int(10) unsigned NOT NULL auto_increment,
`templateName` varchar(900) NOT NULL default '',
`articleName` varchar(900) NOT NULL default '',
`updateStatus` enum('none','update','add','delete') NOT NULL default 'none',
PRIMARY KEY (`objectId`
KEY `articleName` (`articleName`(30
KEY `templateName` (`templateName`(30
KEY `artTemplIndex` (`articleName`(30`templateName`(10
) ENGINE=InnoDB AUTO_INCREMENT=815211 DEFAULT CHARSET=utf8

есть запросы типа:
  
UPDATE LOW_PRIORITY Objects SET updateStatus = "delete" WHERE articleName = "#articleName#" AND templateName NOT IN ('some', 'templates')

SELECT objectId FROM Objects WHERE articleName="#articleName#" AND templateName="#templateName#"

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

dgaf

LOW_PRIORITY не имеет смысла для InnoDB

oleg1331

просто изначально было MyISAM
но спасибо за комментарий, не знал.

Marinavo_0507

я бы проверил, что индекс правильный используется для обоих запросов

NAIL

Возможно ли их преобразовать так, чтобы они не лочили друг друга? Точнее, чтобы апдейт не лочил все.
Апдейт не лочит записи для селектов (если те конечно без FOR UPDATE в конце). Проблемы не вижу.
Или что-то другое лочится ?
Напиши конкретную последовательность запросов с номерами консолек в которых их выполняешь - тогда будет шанс понять в чём проблема.

NAIL

А если проблема действительно есть покажи что возвращает запрос:
  show variables like 'tx_isolation'; 

oleg1331

 
mysql> show variables like 'tx_isolation';
+---------------+-----------------+
| Variable_name | Value |
+---------------+-----------------+
| tx_isolation | REPEATABLE-READ |
+---------------+-----------------+
1 row in set (0.00 sec)

  
mysql> show processlist \G
*************************** 1. row ***************************
Id: 1499816
User: root
Host: localhost
db: WikiParsedInfo_3
Command: Query
Time: 0
State: NULL
Info: show processlist
*************************** 2. row ***************************
Id: 1499818
User: root
Host: localhost
db: WikiParsedInfo_4
Command: Query
Time: 8
State: Locked
Info: UPDATE LOW_PRIORITY Objects SET updateStatus = "delete" WHERE articleName = "Участник:Sergiu
*************************** 3. row ***************************
Id: 1499820
User: root
Host: localhost
db: WikiParsedInfo_4
Command: Sleep
Time: 0
State:
Info: NULL
*************************** 4. row ***************************
Id: 1499822
User: root
Host: localhost
db: WikiParsedInfo_4
Command: Query
Time: 7
State: Locked
Info: INSERT INTO `Objects` SET `articleName` = 'Обсуждение:Даосизм', `templateName` = '�
*************************** 5. row ***************************
Id: 1499824
User: root
Host: localhost
db: WikiParsedInfo_4
Command: Query
Time: 9
State: Locked
Info: UPDATE LOW_PRIORITY Objects SET updateStatus = "delete" WHERE articleName = "Обсуждение:П
*************************** 6. row ***************************
Id: 1499826
User: root
Host: localhost
db: WikiParsedInfo_4
Command: Query
Time: 4
State: Locked
Info: UPDATE LOW_PRIORITY Objects SET updateStatus = "delete" WHERE articleName = "Обсуждение:Э
*************************** 7. row ***************************
Id: 1499828
User: root
Host: localhost
db: WikiParsedInfo_4
Command: Query
Time: 7
State: Locked
Info: INSERT INTO `Objects` SET `articleName` = 'Участник:HedgeHog', `templateName` = 'Babel-3', `
*************************** 8. row ***************************
Id: 1499830
User: root
Host: localhost
db: WikiParsedInfo_4
Command: Query
Time: 8
State: Locked
Info: INSERT INTO `Objects` SET `articleName` = 'Категория:Созвездия', `templateName` =
*************************** 9. row ***************************
Id: 1499832
User: root
Host: localhost
db: WikiParsedInfo_4
Command: Query
Time: 8
State: Locked
Info: INSERT INTO `Objects` SET `articleName` = 'Уши', `templateName` = 'неоднозначность
*************************** 10. row ***************************
Id: 1499834
User: root
Host: localhost
db: WikiParsedInfo_4
Command: Query
Time: 1
State: Locked
Info: UPDATE LOW_PRIORITY Objects SET updateStatus = "delete" WHERE articleName = "Шаблон:Земли
*************************** 11. row ***************************
Id: 1499836
User: root
Host: localhost
db: WikiParsedInfo_4
Command: Query
Time: 9
State: Updating
Info: UPDATE LOW_PRIORITY Objects SET updateStatus = "delete" WHERE articleName = "Участник:SPr"
*************************** 12. row ***************************
Id: 1499837
User: wikifacts12
Host: 195.239.104.198:50635
db: WikiSource_ru3
Command: Sleep
Time: 24
State:
Info: NULL
12 rows in set (0.00 sec)


В цикле обрабатываются однотипные данные. Для каждого куска данных - выполняется этот апдейт. Соответственно, пока один тред не отработает - другие стоят.

oleg1331

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

oleg1331

Сменил движок на MyISAM - картина изменилась. вот и селекты залоченные :(
  
mysql> show processlist \G;
*************************** 1. row ***************************
Id: 1499816
User: root
Host: localhost
db: WikiParsedInfo_3
Command: Query
Time: 0
State: NULL
Info: show processlist
*************************** 2. row ***************************
Id: 1499820
User: root
Host: localhost
db: WikiParsedInfo_4
Command: Query
Time: 7
State: Locked
Info: UPDATE LOW_PRIORITY Objects SET updateStatus = "delete" WHERE articleName = "Музей Прусси
*************************** 3. row ***************************
Id: 1499828
User: root
Host: localhost
db: WikiParsedInfo_4
Command: Query
Time: 1
State: Locked
Info: SELECT objectId FROM Objects WHERE articleName="Категория:Литература" AND templat
*************************** 4. row ***************************
Id: 1499830
User: root
Host: localhost
db: WikiParsedInfo_4
Command: Query
Time: 13
State: Updating
Info: UPDATE LOW_PRIORITY Objects SET updateStatus = "delete" WHERE articleName = "Обсуждение:К
*************************** 5. row ***************************
Id: 1499832
User: root
Host: localhost
db: WikiParsedInfo_4
Command: Query
Time: 45
State: Locked
Info: SELECT objectId FROM Objects WHERE articleName="Категория:Электричество" AND t
*************************** 6. row ***************************
Id: 1499834
User: root
Host: localhost
db: WikiParsedInfo_4
Command: Query
Time: 32
State: Locked
Info: SELECT objectId FROM Objects WHERE articleName="Обсуждение:FreeBSD" AND templateName="talk
*************************** 7. row ***************************
Id: 1499836
User: root
Host: localhost
db: WikiParsedInfo_4
Command: Query
Time: 38
State: Locked
Info: SELECT objectId FROM Objects WHERE articleName="Обсуждение участника:Persona/Ар
*************************** 8. row ***************************
Id: 1499838
User: root
Host: localhost
db: WikiParsedInfo_4
Command: Query
Time: 4
State: Locked
Info: UPDATE LOW_PRIORITY Objects SET updateStatus = "delete" WHERE articleName = "Обсуждение:З
*************************** 9. row ***************************
Id: 1499840
User: root
Host: localhost
db: WikiParsedInfo_4
Command: Query
Time: 10
State: Locked
Info: SELECT objectId FROM Objects WHERE articleName="Изображение:Kerch Mitridat.jpg" AND templ
*************************** 10. row ***************************
Id: 1499842
User: root
Host: localhost
db: WikiParsedInfo_4
Command: Query
Time: 54
State: Locked
Info: SELECT objectId FROM Objects WHERE articleName="Обсуждение шаблона:Орисс" AND
*************************** 11. row ***************************
Id: 1499844
User: root
Host: localhost
db: WikiParsedInfo_4
Command: Query
Time: 16
State: Locked
Info: SELECT objectId FROM Objects WHERE articleName="Обсуждение:Мормоны" AND templateNam
*************************** 12. row ***************************
Id: 1499845
User: wikifacts12
Host: 195.239.104.198:51226
db: WikiSource_ru3
Command: Sleep
Time: 285
State:
Info: NULL
12 rows in set (0.00 sec)

NAIL

Тогда всё нормально. Надо переписать апдейты чтобы они работали следующим образом:
 
select objectId from Objects where articleName = "#articleName#" AND templateName NOT IN ('some', 'templates')
update Objects set updateStatus = "delete" WHERE objectId in (#object_ids#)

object_ids - полученные id через запятую (если они есть конечно). Тогда куски ключей лочиться не будут, а будут лочиться конкретные ряды таблицы. То есть если потом другой поток попытается проапдейтить конкретно те же самые ряды, то он конечно, подождёт, а если другие то будет работать.
Если одни и те же ряды апдейтятся разными потоками и всё это в офлайне - надо делать инсерты в очередь (инсерты не блокируются) и потом отдельным скриптом апдейтить. А если в онлайне, то что-то ты делаешь не так :)
И кстати рекомендую вообще забыть слово MyISAM :)

oleg1331

нет. все конечно же в оффлайне, скрипт-демон на сервере :)
Спасибо за комментарий, сейчас попробую сделать.
Оставить комментарий
Имя или ник:
Комментарий: