Состояние гонки с базой данных чтения реплик с помощью Sequelize - PullRequest
0 голосов
/ 27 сентября 2018

Мы используем Sequelize с базой данных AWS Aurora Postgresql с базой данных для чтения и записи.Sequelize настроен на использование реплики чтения и записи баз данных.

У нас есть таблица users и таблица follows.Тип объекта User имеет поля, которые являются подзапросами, например поле следующееCount для пользователя:

...
followingCount: {
  type: new GraphQLNonNull(GraphQLInt),
  resolve(user) {
    return db.Follower.count({
      where: { followerId: user.id, status: "Approved" }
    });
  }
},

Когда мы добавляем запись в таблицу follows для пользователя, затем возвращаем этот пользовательский экземплярfollowingCount не обновляется.Я на 99% уверен, что это потому, что он читает из базы данных реплики / чтения, которая не имеет данных.Я подтвердил это, отключив реплику и увидев, что проблема исчезла.

Я не решаюсь добавить опцию useMaster в эти поля, так как это сводит на нет нашу стратегию параллелизма.

Здесьэто точный код, который я вызываю:

const followingUser = await db.User.findOne({
  where: {
    id
  }
});

await db.Follower.create({
  followerId: getCurrentUserId(context),
  followingId: id,
  status: followingUser.privateProfile ? "Pending" : "Approved"
});

return followingUser.reload();

Поле followingCount в пользовательском экземпляре (followingUser) не возвращает самый новый счет, даже если он существует в базе данных master / write.

Какие есть варианты?Могу ли я каким-то образом обернуть свои мутации в блок, чтобы все, что выполняется внутри, использовало базу данных Master / Write?Обернул бы это в справку по транзакции, и если да, то как мне передать транзакцию моей

ЛЮБОЙ оцененной помощи

psql 9.6.8

sequelize 4.38.0

Ответы [ 2 ]

0 голосов
/ 02 октября 2018

Мне удалось решить эту проблему, вызвав reload() в объекте БД, который я возвращал, и передав его useMaster: true

followingUser.reload({ useMaster: true });

Я создал заявку с последующим расширениемимеет больше контекста, если это полезно для кого-либо: https://github.com/sequelize/sequelize/issues/9971

0 голосов
/ 28 сентября 2018

В PostgreSQL репликация может быть выполнена различными способами:

  • Синхронный
  • Асинхронный

Если вы используете Асинхронная репликация данные могут попасть в подчиненное устройство ПОСЛЕ того, как транзакция была зафиксирована на основном сервере (главном сервере).Обычно существует небольшая задержка репликации.

Вы можете реплицировать синхронно на столько ведомых устройств, сколько вы хотите, чтобы убедиться, что COMMIT действителен только после того, как он будет подтвержден требуемым числом PostgreSQL.серверы.

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

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

https://www.cybertec -postgresql.com / ru / services / postgresql-репликация / синхронная синхронная репликация /

Чтобы настроить синхронную репликацию, необходимо настроить имя синхронного_стандбайтаи параметры synchronous_commit в файле postgresql.conf.Параметр synchronous_commit может иметь следующие значения: off, on, remote_write, remote_apply (функция Postgres 9.6) и local.

Подробнее о настройке репликации синхронизации

...