|
дедлоки...
|
|||
---|---|---|---|
#18+
Есть таблица, туда загружается большой файл. То есть примерно 40 потоков параллельно делают следущее: BEGIN TRAN SELECT * FROM T WHERE FIELD=? если есть запись UPDATE T SET ... WHERE FIELD=? иначе INSERT INTO T... COMMIT Часть записей отваливается с ошибкой что то вроде deadlock detected victim... Я подозреваю происходит это из-за: поток 1 выполнил селект на запись SHAREDLOCK, второй(ые) выполняют селект и ставят опят SHAREDLOCK на ту же запись, никто из них не может выполнить UPDATE из-за наставленных SHAREDLOCK ов. SELECT WITH(UPDLOCK) не помогает. Как здесь организовать что то наподобие ораклового SELECT FOR UPDATE ? Что бы ставил сразу WRITELOCK при селекте до конца транзакции? Или может есть лучше варианты? ... |
|||
:
Нравится:
Не нравится:
|
|||
03.03.2018, 00:23 |
|
дедлоки...
|
|||
---|---|---|---|
#18+
no56892, Надо профайлером поймать граф дедлока. Перед этим можно посмотреть на фактический план выполнения подобных запросов. Большой файл надо балком запульнуть в staging-таблицу и всякой построчной фигней заниматься на staging-таблице. ... |
|||
:
Нравится:
Не нравится:
|
|||
03.03.2018, 00:40 |
|
дедлоки...
|
|||
---|---|---|---|
#18+
на поле FIELD есть индекс? грузите болшой файл построчно? ... |
|||
:
Нравится:
Не нравится:
|
|||
03.03.2018, 00:42 |
|
дедлоки...
|
|||
---|---|---|---|
#18+
авторБольшой файл надо балком запульнуть в staging-таблицу и всякой построчной фигней заниматься на staging-таблице. Не вариант авторгрузите болшой файл построчно? Да, там условно в нем присутствуют элементы, которые по одному читаются и раскидываются по 40 потокам, чья задача собственно и запихнуть в базу по одному. авторна поле FIELD есть индекс? Делал, не помогло. Может не того типа? Nonclustered, поле VARCHAR ... |
|||
:
Нравится:
Не нравится:
|
|||
03.03.2018, 00:49 |
|
дедлоки...
|
|||
---|---|---|---|
#18+
надо повышать уровень изоляции ... |
|||
:
Нравится:
Не нравится:
|
|||
03.03.2018, 08:06 |
|
дедлоки...
|
|||
---|---|---|---|
#18+
или новые индексы создавать. ... |
|||
:
Нравится:
Не нравится:
|
|||
03.03.2018, 08:08 |
|
дедлоки...
|
|||
---|---|---|---|
#18+
какой тип там у FILEID? int? ... |
|||
:
Нравится:
Не нравится:
|
|||
03.03.2018, 08:10 |
|
дедлоки...
|
|||
---|---|---|---|
#18+
Varchar(30). Опытным путем установлено, что select with (update) ставит U блокировку на ROW, а также IU на PAGE. Я так понял IU этонорм и от нее не избавиться? Тоесть все ок вроде бы, пока не закоммитится селект, вторая транзакция висит на селекте ждет, что ок. Правда тестировал на другом скл сервере, мб настройки разные у них, но это вряд ли... ... |
|||
:
Нравится:
Не нравится:
|
|||
03.03.2018, 09:36 |
|
дедлоки...
|
|||
---|---|---|---|
#18+
1. Бестолку обсуждать дедлок без его графа. 2. no56892BEGIN TRAN SELECT * FROM T WHERE FIELD=? если есть запись UPDATE T SET ... WHERE FIELD=? иначе INSERT INTO T... COMMITЭту красоту заменить на один MERGE. Или, по крайней мере, убрать SELECT. ... |
|||
:
Нравится:
Не нравится:
|
|||
03.03.2018, 09:48 |
|
дедлоки...
|
|||
---|---|---|---|
#18+
no56892, авторпока не закоммитится селект Это не быстро. Надо подождать пока это придумают. ... |
|||
:
Нравится:
Не нравится:
|
|||
03.03.2018, 10:31 |
|
дедлоки...
|
|||
---|---|---|---|
#18+
no5689240 потоков параллельно делают следущее: SELECT * FROM T WHERE FIELD=?на вскидку... - раскидывайте по потокам данные с разными FIELD чтобы вероятность их пересечения минимизировалась - делать в три шага (если допустимо с точки зрения транзакционности): 1. получить из файла уникальные FIELD 2. прочитать таблицу пометив какие FIELD есть каких нет (читать из таблицы PK если есть и складывать в памяти в структуру маппинга FIELD - PK) 3. делать update 4. делать инсерт - таблицу секционировать чтобы отдельный поток лился в свою секцию (секции потом объединять если нужно) это так, вообще а, конкретика только после графа дедлока ... |
|||
:
Нравится:
Не нравится:
|
|||
03.03.2018, 11:03 |
|
дедлоки...
|
|||
---|---|---|---|
#18+
Varchar(30) классный тип, Вы нормализацию пробовали делать? ... |
|||
:
Нравится:
Не нравится:
|
|||
03.03.2018, 11:26 |
|
дедлоки...
|
|||
---|---|---|---|
#18+
no56892авторБольшой файл надо балком запульнуть в staging-таблицу и всякой построчной фигней заниматься на staging-таблице. Не вариант Ну... продолжайте маяться фигней... в сорок потоков. no56892Как здесь организовать что то наподобие ораклового SELECT FOR UPDATE ? Что бы ставил сразу WRITELOCK при селекте до конца транзакции? Или может есть лучше варианты? Код: sql 1.
no56892Или может есть лучше варианты? Как вам уже докладывали, лучше - BULK INSERT. Хоть в сорок потоков. А потом... merge в один. ... |
|||
:
Нравится:
Не нравится:
|
|||
03.03.2018, 12:10 |
|
дедлоки...
|
|||
---|---|---|---|
#18+
aleks222, нету, ключ длинный ... |
|||
:
Нравится:
Не нравится:
|
|||
03.03.2018, 12:28 |
|
дедлоки...
|
|||
---|---|---|---|
#18+
main.BMSG: BMSGID NUMMERIC(18,0) NOT NULL BMSG_NUMBER VARCHAR(30) NOT NULL BMSG_PAYLOAD VARCHAR(255) NULL NONCLUSTEREDINDEX (NON UNIQUE, NONCLUSTERD) ON BMSG)NUMBER ... |
|||
:
Нравится:
Не нравится:
|
|||
04.03.2018, 18:11 |
|
дедлоки...
|
|||
---|---|---|---|
#18+
invmЭту красоту заменить на один MERGE. Или, по крайней мере, убрать SELECT. 40 потоков MERGE? OMG... Как насчет секционирования или даже разбиения исходной таблицы на несколько? ... |
|||
:
Нравится:
Не нравится:
|
|||
04.03.2018, 21:39 |
|
дедлоки...
|
|||
---|---|---|---|
#18+
Опытным путем установлена доп инфа: Select for update with (updlock) where x=y а затем update where x=y работают как и ржидалось. Тоесть пока не закоммитится транзакция с select with updlock, останые select with updlock висят в ожидании, все супер, тоесть такую ситуацию создает insert как то косвенно, вот бы понять как...вариант без селекта, тоесть фигачим апдейт если 0 rows аffected то insert если unique constraint то снова update не желательно, тк тут soa и все дела, айдишники выдает сторонний сервис, перерасход нежелателен...никак не могу понять, как инсерт создает дедлок здесь, так же есть вариант, если deadlock, то еще раз повторить, но это все полумеры какие то ... |
|||
:
Нравится:
Не нравится:
|
|||
04.03.2018, 22:18 |
|
дедлоки...
|
|||
---|---|---|---|
#18+
Тредстартеру 40 потоков важнее эффективности. Можно расходиться. ... |
|||
:
Нравится:
Не нравится:
|
|||
05.03.2018, 05:53 |
|
дедлоки...
|
|||
---|---|---|---|
#18+
Выше я выкладывал дедлок граф, по нему вообще ничего не понятно? А что скл сервер не умеет работать параллельно с десятком сессий над одной таблицей? Хмм, выше все предложенное как уже писал на мой взгляд полумеры, хотя инсерты + мердж даже будут побыстрее, но тут есть некоторые ограничения (исторические) на вызов самого метода кот все это делает(читает и заливает файл) ... |
|||
:
Нравится:
Не нравится:
|
|||
05.03.2018, 09:17 |
|
дедлоки...
|
|||
---|---|---|---|
#18+
Дарю для размышлений кейс решения подобной задачи. Кролик слал сообщения в таблицу БД через вызов ХП (внутри 1 insert), максимальная скорость составляла 60 штук в секунду. На определенном этапе эта скорость оказалась недостаточной. Проблему стали решать двумя способами. Первый сводился к многопоточной записи, дал скорость около 150 в секунду и был принят во всей организации, кроме моей делянки. Второй способ, разработанный мной, позволил SSIS лезть напрямую в шину и выкачивать сообщения пачкой, после чего разбираться с ними в целом. Средняя скорость обработки (с учетом пауз) доходила до 1000 в секунду и выше. Описание сильно в общих чертах, потому опускаю ожидание, подтверждение, логирование и прочие удовольствия. Побочный эффект - коллеги обратились с жалобой, что очередь никто не слушает. А, нет, есть слушатель... Ой, снова нет! Правильно, после получения пачки SSIS отсоединялся (хотя можно было этого и не делать). После перенастройки Заббикса коллеги перестали тревожиться. ... |
|||
:
Нравится:
Не нравится:
|
|||
05.03.2018, 09:38 |
|
дедлоки...
|
|||
---|---|---|---|
#18+
no56892Выше я выкладывал дедлок граф, по нему вообще ничего не понятно?у вас несколько процессов взаимоблокируют друг друга на операциях SELECT и UPDATE пытаясь наложить U блокировку на ключ индекса. типа так: process1 SELECT ждёт "А" process2 UPDATE заблокировал "Б" ждёт "А" process3 SELECT ждёт "Б" process4 UPDATE ждёт "Б" заблокировал "А" ... |
|||
:
Нравится:
Не нравится:
|
|||
05.03.2018, 09:43 |
|
дедлоки...
|
|||
---|---|---|---|
#18+
покажите планы ваших запросов, как у вас используется индекс. ... |
|||
:
Нравится:
Не нравится:
|
|||
05.03.2018, 09:49 |
|
|
Start [/forum/topic.php?answer_author=sparrow&do_answer=39609903&fid=46&msg=39609903&tid=1690139]: |
0ms |
get settings: |
2ms |
get forum list: |
7ms |
check forum access: |
0ms |
check topic access: |
0ms |
track hit: |
9ms |
get topic data: |
10ms |
get forum data: |
1ms |
get page messages: |
22ms |
get tp. blocked users: |
0ms |
others: | 82ms |
total: | 133ms |
0 / 0 |