Гость
Map
Форумы / SQLite [игнор отключен] [закрыт для гостей] / database is locked database is locked - при вставке большого к-во записей / 20 сообщений из 20, страница 1 из 1
19.08.2019, 16:36
    #39851212
potkin
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
database is locked database is locked - при вставке большого к-во записей
Добрый День!
Использую: System.Data.SQLite 1.0.111.0 (3.28.0) + Транзакции
При вставке большого к-ва записей (350 в одну таблицу и 2 000 записей в другую) получаю исключение:
database is locked database is locked
При маленьком к-ве вставок - всё "ок".

Памяти 4 Гига. Вроде хватает.
На быстром ПК все отрабатывает, а на Сервера под нагрузкой - нет, но иногда бывает отработает, если нет нагрузки на Сервере.
Ну и пробовал баловаться с таймоутами, например так:
cmd.CommandTimeout = 100000;
не помогает

Подскажите, есть ли решение данной проблемы?
...
Рейтинг: 0 / 0
19.08.2019, 18:23
    #39851267
VSVLAD
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
database is locked database is locked - при вставке большого к-во записей
potkin,

Вставка происходит в одном потоке или несколько потоков/процессов пишут одновременно?
...
Рейтинг: 0 / 0
19.08.2019, 18:25
    #39851269
VSVLAD
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
database is locked database is locked - при вставке большого к-во записей
VSVLAD,

ну и ещё после вставки, закрывается ли корректно подключение? чистятся ресурсы (Dispose)?
...
Рейтинг: 0 / 0
19.08.2019, 20:52
    #39851352
potkin
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
database is locked database is locked - при вставке большого к-во записей
авторВставка происходит в одном потоке или несколько потоков/процессов пишут одновременно?
В одном потоке, конечно.
В контексте одной транзакции.
Я думаю тут вопрос с таймаутом, он вроде 30 секунд. Возможно при нагрузке этого мало.
Сохранения происходят в цикле for . Таких циклов 2 000 , на ~ 1 000 вылет с ошибкой.

авторну и ещё после вставки, закрывается ли корректно подключение? чистятся ресурсы (Dispose)?
Да, конечно.
Код: c#
1.
2.
3.
4.
5.
using(SQLiteConnection con = ...)
{
   //...
   con.Close(); con.Dispose(); //это не нужно, но я всё равно делаю.
}


Запускаю на отдельном аккаунте, где работаю я один, если загрузка Сервера и операция длится более 30 секунд - ошибка .

Я думаю вопрос таки в ТаймАуте, но как его увеличить?
Что я ни делал, все равно 30 секунд и ни секундой более! (((
...
Рейтинг: 0 / 0
20.08.2019, 07:44
    #39851406
Dima T
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
database is locked database is locked - при вставке большого к-во записей
potkinавторВставка происходит в одном потоке или несколько потоков/процессов пишут одновременно?
В одном потоке, конечно.
В контексте одной транзакции.
В одной транзакции не может быть такого в принципе. Эта ошибка возникает когда одно соединение открыло транзакцию и что-то делает, а в это время второе пытается начать транзакцию, но долго не может, в итоге вываливается с ошибкой.
Т.е. получается у тебя несколько соединений с БД, если такого быть не должно - разбирайся откуда они.

potkinЯ думаю тут вопрос с таймаутом, он вроде 30 секунд. Возможно при нагрузке этого мало.
Сохранения происходят в цикле for . Таких циклов 2 000 , на ~ 1 000 вылет с ошибкой.
Сделай обработку этой ошибки: когда произойдет - запускай слетевший цикл повторно.

Попробуй поиграть настройкой PRAGMA busy_timeout

PS Если заполнение БД не критично к сбоям, например база заполняется с нуля и умершую базу можно создать повторно, то можно ускорить этими настройками
Код: sql
1.
2.
3.
pragma synhronous=OFF;
pragma journal_mode=OFF;
pragma cache_size=-32678;
...
Рейтинг: 0 / 0
22.08.2019, 14:50
    #39852782
potkin
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
database is locked database is locked - при вставке большого к-во записей
авторВ одной транзакции не может быть такого в принципе. Эта ошибка возникает когда одно соединение открыло транзакцию и что-то делает, а в это время второе пытается начать транзакцию, но долго не может, в итоге вываливается с ошибкой.
Т.е. получается у тебя несколько соединений с БД, если такого быть не должно - разбирайся откуда они.

Проект писал я.
Запуская локально на "слабой" машине.
Транзакция только одна. Даже отдельный проект создал, там всего одна функция на запись в БД. Все тесты локально.
Вылетает ошибка, если запись в Базу длится более 30 секунд.
Если машина "сильная", то всё пишется (запись проходит быстрее 30 секунд).
Думал, что ошибка в провайдере "System.Data.SQLite", но у меня есть проект на Qt (Win, Lnux, ...), там такая же хреня ((((
Вся проблема в ТаймАуте!
авторСделай обработку этой ошибки: когда произойдет - запускай слетевший цикл повторно.
Опять ошибка вылетит, нужно время, вопрос как его увеличить более 30 секунд ...
авторPRAGMA busy_timeout
Уже перепробовал всё, что советовал гугл, пока что ничего не помогает.
Открываю соединение, запускаю команду: "PRAGMA busy_timeout=500000;" или такую "PRAGMA busy_timeout;".
Запускаю транзакцию.
Через 30 секунд - ошибка.
авторPS Если заполнение БД не критично к сбоям, например база заполняется с нуля и умершую базу можно создать повторно, то можно ускорить этими настройками

Критично.

Вопрос открыт: Как увеличить ТаймАут работы Транзакции?
...
Рейтинг: 0 / 0
22.08.2019, 15:01
    #39852790
potkin
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
database is locked database is locked - при вставке большого к-во записей
Кстати:
Код: c#
1.
2.
3.
4.
using (SQLiteConnection con = new SQLiteConnection("Data Source='d:\base.db';New=False;Version=3;foreign keys=true;Connection Timeout=10000000;Timeout=10000000;"))
{
   con.Open();
}


параметры имеют такие значения:
con.BusyTimeout = 0
con.ConnectionTimeout = 15
con.DefaultTimeout = 30
con.WaitTimeout = 30000
...
Рейтинг: 0 / 0
22.08.2019, 19:43
    #39852961
VSVLAD
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
database is locked database is locked - при вставке большого к-во записей
Создал тестовый проект
Код: vbnet
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
28.
29.
30.
31.
32.
33.
34.
35.
36.
37.
38.
39.
40.
41.
42.
43.
Imports System.Data.SQLite

Module Module1

    Sub Main()

        Using con As New SQLiteConnection("Data Source='d:\base.db';foreign keys=true")

            con.Open()
            Dim cmd = con.CreateCommand()

            cmd.CommandText = "select sqlite_version()"
            Console.WriteLine($"SQLite version: {cmd.ExecuteScalar()}")
            Console.WriteLine($"CommandTimeout = {cmd.CommandTimeout}")
            Console.WriteLine($"ConnectionTimeout = {con.ConnectionTimeout}")
            Console.WriteLine($"BusyTimeout = {con.BusyTimeout}")

            cmd.CommandText = "create table if not exists t1(num Integer, ondate datetime)"
            cmd.ExecuteNonQuery()

            Console.WriteLine("Открываем транзакцию")
            cmd.CommandText = "begin transaction"
            cmd.ExecuteNonQuery()

            cmd.CommandText = "insert into t1 values(@num, @ondate)"
            cmd.Parameters.Add("@num", DbType.Int32)
            cmd.Parameters.Add("@ondate", DbType.DateTime)

            For I = 1 To 600
                cmd.Parameters.Item("@num").Value = I
                cmd.Parameters.Item("@ondate").Value = Now()
                cmd.ExecuteNonQuery()

                Console.WriteLine($"Добавили запись #{I} и ждём 1 секунду")
                Threading.Thread.Sleep(1000)
            Next

            cmd.CommandText = "commit"
            cmd.ExecuteNonQuery()
        End Using
    End Sub

End Module



Запускаю. На 120 секунде устал смотреть, всё работает. Транзакция открыта и в неё пишется. Журнал транзакций растёт. PRAGMA busy_timeout стоит по умолчанию и равна 3000 мс. Настройки таймаута соединения и команды не трогаю. Также для успокоения совести нагуглил на стековерфлоу, что размер транзакции в SQLite не ограничен.

Отсюда вопрос: скорее всего или ваш провайдер старый или SQLite или ваш код имеет какие-то нюансы, поэтому нужен от вас минимальный проект, который даёт сбой.

Проверял на конфигурации:
Код: sql
1.
2.
3.
4.
5.
Пакет из Nuget System.Data.SQLite: 1.0.111.0
SQLite version: 3.28.0
CommandTimeout = 30
ConnectionTimeout = 15
BusyTimeout = 0
...
Рейтинг: 0 / 0
22.08.2019, 20:31
    #39852993
Dima T
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
database is locked database is locked - при вставке большого к-во записей
VSVLADСоздал тестовый проект
Тоже хотел так сделать, но ты опередил. Просьба к ТС повторить запуск этого кода, если работает, то приближать код к реальному до тех пор пока глюк не повторится.
ИМХО обычно при построении модели проблемы приходит решение как проблему обойти.
...
Рейтинг: 0 / 0
24.08.2019, 16:48
    #39853492
potkin
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
database is locked database is locked - при вставке большого к-во записей
Проблема была таки в чтении.
При записи данных, некоторые данные получались из той самой БД (из справочника).
1) Запускалась Транзакция
2) В цикле:
2.1) Читались некоторые данные - вот тут на шаге 426 (ровно 426) получал исключение о блокировки базы.
2.2) Писались в БД

При том все вариации Прагмы не помогают:
Код: sql
1.
PRAGMA locking_mode=ХХХ;



Решил:
До Транзакции читаю данные в массив и потом их подставляю в Инзерт.
...
Рейтинг: 0 / 0
24.08.2019, 16:49
    #39853493
potkin
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
database is locked database is locked - при вставке большого к-во записей
При том пробовал в одном соединении читать данные из справочника и писать
Пробовал создавал 2-а соединения: одним читаю, другим пишу + разные вариации ПРАГМы. Ошибка (
...
Рейтинг: 0 / 0
24.08.2019, 19:09
    #39853499
VSVLAD
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
database is locked database is locked - при вставке большого к-во записей
potkinПри том пробовал в одном соединении читать данные из справочника и писать
SQLite проектировался, чтобы было много читателей и один писатель. Блокировка происходит на уровне блокировки файла, поэтому не важно в двух соединениях происходит или даже в двух разных приложениях.

Если необходимо часто читать и одновременно дописывать, то можно попробовать включить режим журналирования WAL. Подробнее в официальной доке почитайте. В вашем проекте это может быть решением
...
Рейтинг: 0 / 0
26.08.2019, 09:55
    #39853656
Dima T
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
database is locked database is locked - при вставке большого к-во записей
potkinПроблема была таки в чтении.
При записи данных, некоторые данные получались из той самой БД (из справочника).
1) Запускалась Транзакция
2) В цикле:
2.1) Читались некоторые данные - вот тут на шаге 426 (ровно 426) получал исключение о блокировки базы.
2.2) Писались в БД

При том все вариации Прагмы не помогают:
Код: sql
1.
PRAGMA locking_mode=ХХХ;


Ты дэдлок устроил. Сначала запись идет в кэш, в это время стоит блокировка разрешающая чтение, но по заполнению кэша блокировка меняется на монопольную (запрещающую чтение) и начинается запись непосредственно в базу, тут при попытке чтения повисает. Т.е. надо увеличивать размер кэша
Код: sql
1.
pragma cache_size=...;



Еще можно попробовать разрешить грязное чтение, но тут я не уверен что это стоит делать
Код: sql
1.
pragma read_uncommitted=ON;


potkinРешил:
До Транзакции читаю данные в массив и потом их подставляю в Инзерт.
И правильно. Так будет лучше всего.
...
Рейтинг: 0 / 0
11.10.2019, 01:14
    #39874950
YUBA
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
database is locked database is locked - при вставке большого к-во записей
Dima T, не может быть такого, по 30 тыс строк пишу в одной транзакции до commit, и кеш вообще не трогал - по умолчанию. Никаких проблем. Версия 3.29.
М.б. версия древняя у товарища?
...
Рейтинг: 0 / 0
11.10.2019, 01:24
    #39874951
YUBA
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
database is locked database is locked - при вставке большого к-во записей
Dima T, имхо, согласно докам кеш автоматом увеличивается и моноблокировка происходит только по commit.
...
Рейтинг: 0 / 0
11.10.2019, 09:29
    #39874986
Dima T
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
database is locked database is locked - при вставке большого к-во записей
YUBADima T, не может быть такого, по 30 тыс строк пишу в одной транзакции до commit, и кеш вообще не трогал - по умолчанию. Никаких проблем. Версия 3.29.
М.б. версия древняя у товарища?
Топик пробовал почитать? 21956985
...
Рейтинг: 0 / 0
11.10.2019, 11:55
    #39875078
YUBA
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
database is locked database is locked - при вставке большого к-во записей
Dima T, пробовал. Не знаю, откуда у него такое.
А вот ты ерунду написал.)) Про кеш. Доки пробовал читать по Sqlite?
...
Рейтинг: 0 / 0
11.10.2019, 12:27
    #39875113
Dima T
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
database is locked database is locked - при вставке большого к-во записей
YUBADima T, пробовал. Не знаю, откуда у него такое.
А вот ты ерунду написал.)) Про кеш. Доки пробовал читать по Sqlite?
Пробовал, даже в переводе книги участвовал 21709672
Если ты что-то считаешь неверным - будь добр сам дать ссылку на документацию.
...
Рейтинг: 0 / 0
11.10.2019, 13:34
    #39875177
Dima T
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
database is locked database is locked - при вставке большого к-во записей
Нашел в книге 21709672
6.4.1 Переход в Состояние EXCLUSIVEКогда конкретно менеджер страниц меняет состояние RESERVED на EXCLUSIVE и почему?
...
Первому заполнению кэша страниц соответствует мягкий предел. В этот момент кэш хранит смесь из неизмененных и измененных страниц. Менеджер страниц пытается очистить кэш. Он проходит по кэшу, избавляясь от неизмененных страниц. После очистки менеджер продолжать работу с освобожденной памятью до тех пор, пока кэш не заполнится снова. Далее, если есть хоть одна неизмененная страница, можно повторить процесс очистки от них. Это означает появление жесткого предела. В этот момент менеджер
страниц не имеет другой возможности, кроме как переходить к состоянию EXCLUSIVE.

С другой стороны, прагма cach_size, проявляется в состоянии RESERVED. Как объяснялось в секции 5.4.3 , прагма управляет размером кэша страниц. Чем больше кэш, тем больше измененных страниц в нем может запомнить менеджер страниц и тем больше работы соединение может выполнить, не меняя свое состояние на EXCLUSIVE.
...
...
Рейтинг: 0 / 0
11.10.2019, 14:43
    #39875240
YUBA
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
database is locked database is locked - при вставке большого к-во записей
Dima T,
Код: plaintext
1.
Рекомендуемый размер кэша по умолчанию - -2000, что означает, что размер кэша ограничен 2048000 байтами памяти.

Если это не блобы, то уже этого размера на 2600 строк уже выше крыши.
...
Рейтинг: 0 / 0
Форумы / SQLite [игнор отключен] [закрыт для гостей] / database is locked database is locked - при вставке большого к-во записей / 20 сообщений из 20, страница 1 из 1
Целевая тема:
Создать новую тему:
Автор:
Найденые пользователи ...
Разблокировать пользователей ...
Читали тему (0):
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


Просмотр
0 / 0
Close
Debug Console [Select Text]