Можно ли делать вставку в слейв ноду
Что проверяют
Понимаете ли вы, как устроена репликация и что будет с данными, если писать мимо мастера. Следом обычно спрашивают, как в Go-сервисе разделить чтение и запись и что делать с отставанием реплики.
Как отвечать
Короткий ответ: технически иногда можно, но в классической схеме мастер и реплики так не делают. Дальше разберите по базам:
- PostgreSQL, физическая репликация: standby в режиме hot standby принимает только чтение, любой
INSERTпадает с ошибкойcannot execute INSERT in a read-only transaction. Вопрос снимает сама база; - PostgreSQL, логическая репликация: подписчик это обычная база, писать в неё можно. Но если ваша строка конфликтует с пришедшей от публикатора, например по уникальному ключу, применение изменений останавливается до ручного разбора;
- MySQL: реплика по умолчанию пишущая, от записи защищают
read_onlyиsuper_read_only. Без них вставка пройдёт, данные разойдутся, а поток репликации встанет на первой же ошибке дубликата ключа; - мультимастер (Galera, Group Replication в режиме multi-primary): запись на любой узел штатная, но платить приходится конфликтами и сертификацией транзакций.
Затем про код. В Go обычно держат два пула: *sql.DB или pgxpool.Pool для мастера и для реплик, и репозиторий явно выбирает нужный. В строке подключения pgx можно указать несколько хостов и target_session_attrs=read-write, тогда драйвер сам найдёт пишущий узел после переключения. Отдельно упомяните отставание реплики: чтение сразу после записи отправляют на мастер, иначе пользователь не увидит только что сохранённое.
Где спотыкаются
Отвечают «нельзя, реплика только для чтения» как закон природы. В MySQL это настройка, и если её забыли, приложение спокойно пишет в реплику неделями.
Путают физическую и логическую репликацию в PostgreSQL и переносят поведение одной на другую.
Забывают про отставание: разводят чтение и запись по разным пулам, а потом ловят баг «сохранил, обновил страницу, данных нет» и ищут его в коде хендлера.