MySQL & PostgreSQL: Часть 7. Репликация в PostgreSQL

Последнюю статью цикла мы посвятим обобщению предыдущих материалов и подведению итогов

Сергей Яковлев, Консультант, независимый специалист

Яковлев Сергей — независимый разработчик с многолетним опытом прикладного и системного программирования; вносит вклад в развитие open-source на своем персональном сайте www.iakovlev.org. Консультант.



19.01.2012

Кластер баз данных необходим для постоянного доступа к данным и балансировки нагрузки.

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

Первый подход: изменять данные позволяется только одному серверу – его называют ведущим (master). Остальные, читающие, узлы называются ведомыми (slave). Узлы, которые находятся в состоянии ожидания данных от ведущего и недоступны в этот момент, называются резервными (standby) узлами.

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

Есть два основных варианта решения этой проблемы – синхронный и асинхронный.

Сегодня мы рассмотрим следующие темы.

  1. Что такое синхронная и асинхронная репликация.
  2. Виды репликаций в PostgreSQL.
  3. Асинхронный мультимастер.
  4. Подведем итоги цикла статей.

1. Что такое синхронная и асинхронная репликация

Основным достоинством синхронной репликации является соблюдение принципов ACID на всех узлах. В основе синхронной репликации лежит двухфазный сетевой протокол.

Первая фаза: ведущий узел рассылает всем узлам SQL-запрос. Каждый узел проверяет корректность запроса и, если все нормально, отсылает OK.

Если подтверждение получено от всех узлов, начинается вторая фаза: ведущий отсылает команду на фиксацию запроса. Если на первой фазе хотя бы один узел не ответил OK, то мастер вместо подтверждения фиксации разошлет команду abort (отмена запроса).

Недостатки этого подхода: во-первых, он порождает сетевой трафик по обмену подтверждениями, во-вторых, снижает производительность, поскольку нужно ждать, пока все узлы будут синхронизированы.

Асинхронная репликация – это однофазный процесс.

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

Узел при получении запроса просто фиксирует его. Реализация асинхронной репликации зависит полностью от правильной логики приложения. Главный недостаток этого подхода – это возможность рассинхронизации данных по узлам. Но у него есть и масса достоинств: уменьшение сетевого трафика, повышение производительности. У ведущего узла, что называется, развязываются руки – не нужно ничего контролировать и синхронизировать.

2. Виды репликаций

С точки зрения атомарности, в PostgreSQL реализованы два вида репликаций.

Логическая репликация (её еще называют logical или statement replication) выполняется на уровне sql-запросов. Она проста с точки зрения реализации.

Физическая (построчная или row-based) основана на записях, которые лежат в журнале транзакций. Она более производительна и прозрачна.

Все реализации можно разбить по следующим категориям.

  1. Общий дисковый резерв (Shared Disk Failover).

    Для базы данных имеется копия. В случае отказа базы данных происходит монтирование копии. В качестве варианта возможно использование сетевой файловой системы.

  2. Теплый резерв (Warm Standby Using Point-In-Time Recovery – PITR).

    Данные из лога WAL (write-ahead log) асинхронно транслируются с ведущего узла на ведомый, где тут же применяются. В случае останова ведущего узла мы имеем его копию, однако во время этого процесса ведомым узлом пользоваться нельзя.

  3. Репликация ведущий-ведомый (Master-Slave Replication).

    Один ведущий узел асинхронно отсылает данные на ведомые узлы, работающие в режиме «только для чтения». Репликации на ведомые узлы могут выполняться как в синхронном, так и в асинхронном порядке. Вся пишущая нагрузка падает на ведущие узлы, все чтение должно идти на ведомые. Если ведущий узел останавливается, его может заменить ведомый. Этот тип репликации реализован в Slony-I (trigger-based replication), CommandPrompt Mammoth Replicator (Log-based replication), EnterpriseDB Replication Server (Trigger-based replication).

  4. Мультимастер (Multimaster Replication).

    В отличие от схемы ведущий-ведомый, здесь может быть несколько ведущих узлов. Каждый ведущий узел выполняет сначала свой запрос у себя, потом синхронизирует его на другом ведущем. Недостаток в том, что возможны конфликты между ведущими узлами на уровне транзакций. В Postgres используется асинхронный мультимастер-режим.

    Эта схема также реализована в Bucardo, rubyrep, PgPool-II, PgCluster, Sequoia.

  5. Разделение данных (Data Partitioning).

    Одна таблица разбивается на несколько частей и разносится по нескольким узлам. Если запрос делается к данным, которые лежат на нескольких узлах, может быть создана мастер-копия всей таблицы на одном из узлов в режиме «только чтение».

    Пример реализации – plproxy.


3. Асинхронный мультимастер

В отличие от синхронной репликации, здесь нет немедленного обновления других ведущих узлов. Основной проблемой является синхронизация данных. При этом могут возникнуть конфликты, которые можно разделить на три типа:

  1. конфликт обновления;
  2. конфликт уникальности;
  3. конфликт удаления.

Первый тип ошибок происходит в том случае, когда локальное обновление какого-то объекта опережает по времени отложенное удаленное обновление этого же объекта, т.е. локальное обновление объекта происходит раньше, чем приходит запрос на его обновление от другого узла. В результате нарушается правильная последовательность событий для этого объекта.

Второй тип ошибок возникает в том случае, когда происходит создание дубля для уникального объекта.

Третий тип ошибок аналогичен первому: выполняется операция над глобальным объектом, который уже удален на другом узле, но данные между узлами еще не синхронизированы.

Во избежание конфликтов уникальности прежде всего необходимо установить правильную политику присвоения идентификаторов (ID) новым объектам: множество ID должно быть разбито на несколько диапазонов, и каждому ведущему узлу отдан свой диапазон.

Для выявления и профилактики конфликтов обновления нужно использовать метки времени (timestamps). При возникновении конфликтов обновления нужно с помощью меток времени определить, какое действие должно фиксироваться раньше, и отменить недопустимое действие.

Одна из конкретных реализаций этого варианта включает в себя так называемый MASREP (Multi-master ASynchronous REPlication), который фактически является параллельным независимым сервером баз данных и выступает в роли клиента основной базы данных. Он принимает от всех ведущих узлов запросы типа insert, update, delete и формирует очереди для каждого ведущего узла, куда складывает эти запросы. Атомарная операция выполняется в течение так называемого репликационного цикла, во время которого запрос сначала отсылается ведущему узлу, потом делается пауза, после которой начинается следующий репликационный цикл.

MASREP состоит из пяти частей: экстрактор (extractor), диспетчер (dispatcher), коллектор (collector), инжектор (injector), резольвер (conflict resolver).

Экстрактор сортирует запросы и следит за тем, чтобы один и тот же запрос не выполнялся дважды на одном ведущем узле. Диспетчер рассылает запросы. Коллектор собирает их для рассылки. Инжектор опрашивает ведущие узлы на выполнение запроса. Резольвер разрешает конфликты.


4. Подведем итоги

Настало время подвести итоги этого цикла статей. Что мы имеем на данный момент?

Факты таковы: PostgreSQL – открытая база данных, соответствующая стандартам SQL-99, имеющая богатый набор инструментов для повышения производительности. У нее многочисленное сообщество разработчиков, она имеет более свободную лицензию, в то время как ситуация с MySQL после смены владельца не очень понятна (хотя Oracle обещает развивать проект и даже планирует инвестировать в MySQL больше средств, чем это делала Sun Microsystems). MySQL хорош на плоских запросах с отключенными транзакциями, в то время как PostgreSQL может поддерживать более серьезную нагрузку и сложные запросы параллельно с записью в базу данных.

Большим плюсом является наличие в PostgreSQL механизма MVCC (multi-version concurrency control).

Это позволяет выполнять одновременно читающую и пишущую транзакцию в одной таблице без блокировки самой таблицы, а также откатывать неудачную транзакцию. В MySQL MVCC реализован частично (InnoDB) с ограничениями на производительность.

Также сильно отличается механизм работы журнала транзакций. В PostgreSQL WAL (Write-Ahead Log) поддерживается атомарность на уровне событий в таблице. WAL позволяет откатить состояние объекта на произвольный момент времени. Такая транзакция называется физической или построчной, trigger-based, row-based. В MySQL транзакция принципиально иная – логическая (statement-based), добавление физической транзакции предполагается только в будущих версиях, начиная с версии 5.1.

PostgreSQL развивается достаточно динамично, в то время как развитие MySQL приостановилось в силу известных событий. Ниша, которую занимает PostgreSQL, более широкая, и потенциал у нее выше. Ниша MySQL скромнее, она оправдывает себя как хранилище для некритичных по нагрузке и производительности баз данных.

Когда выбираете между PostgreSQL или MySQL, вы должны понимать разницу между ними и радоваться тому, что у вас есть свобода выбора инструмента для хранения данных.

Ресурсы

Комментарии

developerWorks: Войти

Обязательные поля отмечены звездочкой (*).


Нужен IBM ID?
Забыли Ваш IBM ID?


Забыли Ваш пароль?
Изменить пароль

Нажимая Отправить, Вы принимаете Условия использования developerWorks.

 


Профиль создается, когда вы первый раз заходите в developerWorks. Информация в вашем профиле (имя, страна / регион, название компании) отображается для всех пользователей и будет сопровождать любой опубликованный вами контент пока вы специально не укажите скрыть название вашей компании. Вы можете обновить ваш IBM аккаунт в любое время.

Вся введенная информация защищена.

Выберите имя, которое будет отображаться на экране



При первом входе в developerWorks для Вас будет создан профиль и Вам нужно будет выбрать Отображаемое имя. Оно будет выводиться рядом с контентом, опубликованным Вами в developerWorks.

Отображаемое имя должно иметь длину от 3 символов до 31 символа. Ваше Имя в системе должно быть уникальным. В качестве имени по соображениям приватности нельзя использовать контактный e-mail.

Обязательные поля отмечены звездочкой (*).

(Отображаемое имя должно иметь длину от 3 символов до 31 символа.)

Нажимая Отправить, Вы принимаете Условия использования developerWorks.

 


Вся введенная информация защищена.


static.content.url=http://www.ibm.com/developerworks/js/artrating/
SITE_ID=40
Zone=Open source, Linux
ArticleID=788284
ArticleTitle=MySQL & PostgreSQL: Часть 7. Репликация в PostgreSQL
publish-date=01192012