Клиент одновременной вставки данных (golang) приводит к тому, что первые 50 строк отсутствуют в базе данных (postgres), но остальные 390 в порядке. - PullRequest
0 голосов
/ 13 апреля 2019

Я собираю данные о фондовом рынке и вставляю их в базу данных postgresql.У меня 500 акций за 60 дней исторических данных.Каждый день имеет 390 торговых минут, и каждая минута является строкой в ​​таблице базы данных.Суть проблемы заключается в том, что первые 20-50 минут каждого дня отсутствуют для каждой акции.Иногда его меньше 50, но никогда не больше 50. Каждую минуту после этого для каждого дня хорошо (РЕДАКТИРОВАТЬ: при дальнейшей проверке пропадают минуты повсюду).Максимум соответствует максимальному числу одновременных программ (https://github.com/korovkin/limiter).

. У меня дома установлено оборудование. У меня есть ноутбук, который извлекает данные, и 8-летний игровой компьютер, который был перераспределен какБаза данных postgres работает в Ubuntu. Они подключены через маршрутизатор netgear nighthawk x6 и обмениваются данными через локальную сеть.

На ноутбуке запущена программа go, которая извлекает данные и выполняет одновременную вставку. Я перебираю 60 дней,для каждого дня я чередую каждую акцию, и для каждой акции я читаю каждую минуту и ​​вставляю ее в базу данных с помощью оператора INSERT. Внутри минутного цикла я использовал библиотеку, которая ограничивает максимальное количество процедур.

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

Тем не менее, я хотел бы знать, что случилось, так как я хочуo лучше понять, как эти проблемы могут возникнуть под нагрузкой.Есть идеи?

limit := NewConcurrencyLimiter(50)
for _, m := range ms {
    limit.Execute(func() {
        m.Insert()
    })
}
limit.Wait()

1 Ответ

0 голосов
/ 16 апреля 2019

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

for i, _ := range ms {
    value := ms[i]
    limit.Execute(func() {
        Insert(value)
    })
}
limit.Wait()
...