Добрый день всем! Как вы знаете, недавно Выпущена PostgreSQL 9.2 и много интересного и полезного.
Недолго думая, мы решили обновить наш кластер потоковой репликации с версии 9.0 до 9.2. Все бы ничего, если бы не несколько обстоятельств:
- Это производство с высокой ежедневной посещаемостью.
- простой исключен.
Как мы это сделали и что из этого получилось, читайте дальше.
Для чего все это?
- желание получить те вкусности, которые появились в PostgreSQL 9.2;
- перенос мастера PostgreSQL на сервер с flashcache.
- 3 аппаратных сервера, на двух из которых размещена комбинация «главный+ведомый» 9.0 и еще один незанятый сервер с флэш-кэшем;
- пакет реплицируется с помощью встроенной потоковой репликации;
- С серверами баз данных постоянно работают четыре бэкенда с приложением и машина со сфинксом.
- кластер не будет работать, если просто обновить пакет с 9.0 до 9.2 (кластер необходимо переинициализировать или обновить);
- pg_upgrade невозможен без остановки кластера;
- Повторную инициализацию и последующую pg_restore тоже сделать нельзя, потому что это даунтайм;
- Вы не можете сначала обновить ведущее устройство, а затем обновить ведомое устройство.
Потоковая репликация между основными версиями работать не будет.
Плюс, по сравнению с предыдущим шагом, у нас теперь есть потоковая репликация.
И это тоже не проблема.
Мы немедленно реплицируем данные, реплицированные через Londiste, на только что созданный подчиненный сервер 9.2, используя потоковую репликацию.
Выходит отличная схема: реплицировав на 9.2, прозрачно заполним данными слейв 9.2. Итак схема и алгоритм решения задачи:
1. Административная часть:
- поднять ведущего и ведомого 9.2. Запускаем слейв 9.2 на порту 6543, так как стандартный порт уже занят (см.
картинку);
- поднимаем потоковую репликацию между ними;
- установить Skytools на свеженастроенный мастер 9.2;
- Настройте Лондонист. Из мастера 9.0 делаем провайдера, из мастера 9.2 делаем подписчика;
- запустите londiste и pgqd на мастере 9.2, затем проверьте работоспособность бандла встроенными в londiste инструментами;
- на стороне провайдера добавляем в репликацию все таблицы и последовательности (стоит отметить, что таблицы, способные к репликации, — это только те, которые имеют первичные ключи.
Если вы обнаружите таблицы без ключей, то вам следует создать там ключи или придется переместить их вручную.
у нас были частичные схемы, которые дешевле было перенести вручную, чем создавать там ключи);
- определяем те схемы и таблицы, которые нужно будет перенести вручную;
- На подписчике запускаем репликацию тестовой таблицы и по логам убеждаемся, что данные от провайдера 9.0 попадают на подписчика 9.2 и далее через потоковую репликацию попадают на слейв 9.2.
Теперь осталось только спланировать ход репликации и момент переключения.
Суббота выбрана в качестве дня переключения.
Если что-то пойдет не так, у нас еще есть воскресенье.
Мы разделили деятельность на два этапа: подготовительный этап и этап переключения.
Как будет осуществляться переключение? Для этого мы ввели два новых DNS-имени для нового пакета 9.2: db-master и db-slave. В нужный момент мы пропишем эти имена в конфиги бэкенда и перезапустим приложения.
Некоторые мероприятия подготовительного плана уже были описаны выше, но для полноты картины я все же оставлю их в кратком виде: До пятницы:
- поднять новый кластер pg-9.2;
- настроить лондисте между pg-9.0 и pg-9.2;
- поднять новый слейв.
pg-9.2 на соседнем порту и настроить потоковую репликацию с master.pg-9.2;
- подготавливайте свежие отчеты pgfouine от мастера 9.0 и подчиненного устройства 9.0 на любой день недели.
Отчеты понадобятся для сравнения наиболее популярных планов запросов;
- добавить в лондисте-провайдер все схемы, не требующие создания первичных ключей;
- проверить со всех бэкендов возможность подключения к новым экземплярам PostgreSQL;
- перепроверьте конфиги на наличие новых баз данных, лимитов подключений, настроек автоочистки;
- настроить мониторинг новых баз данных (мы используем zabbix вместе с самодельными bash-скриптами, которые подтягивают таблицы pg_stat*);
- для новых баз данных создайте DNS-имена db-master и db-slave;
- предупредить редакцию о проводимых в субботу работах (это просто предупреждение наверху, чтобы они были готовы и не задавали вопросов, если что-то произойдет).
- отключить ночной импорт (это адский импорт данных, механизм такой, что он 100% ломает лондистовую репликацию.
Это внутренняя кухня проекта, но я об этом упоминаю, потому что в любом проекте может быть подобный компонент, поэтому стоит принять это во внимание учет всех элементов, влияющих на цель операции — базу данных);
- запустить передачу данных через лондисте.
При добавлении таблицы подписчику запускается механизм репликации через COPY, после чего консистентное состояние таблицы фиксируется и она считается реплицированной);
- подготовить список схем для ручного переноса;
- проверить топ-10 запросов от мастера и слейва на 9.2 (может, игра все-таки не стоит свеч?);
- подготовить команды для ручного переноса схем (тупо набрать их в консоль и в нужный момент нажать Enter);
- остановить crons, демон фоновых задач и дождаться завершения активных задач;
- закрыть редактирование (в этот момент приложение не может выполнять операции записи в базу данных, таким образом мы избежим редактирования базы клиентами сайта и риска получения противоречивых данных при перезапуске приложений на бэкендах);
- сбросьте оставшиеся схемы в новую базу данных;
- разбиваем londiste репликацию (выводим таблицы, последовательности, узлы, останавливаем londiste и pgqd);
- исправить конфиги на бэкендах;
- перезапустить приложения на бэкэнде (nginx+passenger);
- обновите конфиг сфинкса и перезапустите его;
после этого репликация через лондисте становится неконсистентной, так как вся внешняя запись (источник записи - клиенты на сайте) уходила в кластер 9.2;
- исправьте конфигурацию демона фоновых задач и запустите его.
запустить crons;
- открыть редактирование;
- открой весь мониторинг и поищи возможные косяки.
- включить ночной импорт;
- проверьте журналы cron, журналы демона фоновых задач, задержку репликации.
- переместите db-slave на стандартный порт, чтобы сделать это:
- переключить бэкенды, работающие с слейвом, на работу с мастером;
- отключить пг-9.0;
- настроить новый pg-9.2 для работы с полным объемом памяти (помним, что на хосте было 2 экземпляра PostgreSQL, поэтому нам пришлось разделить память между ними);
- запустите db-slave на порту 5432, проверьте соединение с бэкендами и со сфинкса;
- проверить целостность и лаг репликации;
- поручите подчиненному устройству на внутренней стороне.
- закрыть редактирование;
- остановить демон фоновых задач и крона, дождаться завершения активных задач;
- поправьте в конфигах имена серверов баз данных на оригинальные, перезапустите бэкенды, запустите демон фоновых задач;
- откат конфига для сфинкса;
- открыть редактирование.
На мероприятии, конечно, не все пошло по генеральному плану.
К счастью, не было необходимости прибегать к плану отката.
Если говорить о том, что пошло не так, то тут всего пара моментов, Первый момент касается недавно запущенного сервиса и механизма ручной передачи схем (чего вообще желательно избегать).
Несколько слов о сервисе: сервис, основанный на работе pgq, дал сбой, не совсем было понятно, как реплицировать схему pgq (сам pgq был частью механизма репликации).
Ручной перенос также не исправил ситуацию, поэтому пришлось переинициализировать схему и перезапустить сервис (к счастью, это не критично, но все же баг).
По поводу передачи схем.
практика показала, что передача схем не всегда проходит так, как хотелось бы.
Учитывая, что схема всей базы данных создается на раннем этапе настройки репликации, в дальнейшем придется переносить либо схему поверх существующих объектов, либо отдельные данные, то при переносе можно столкнуться с ошибками типа: ОШИБКА: вставка или обновление таблицы нарушает ограничение внешнего ключа.
ПОДРОБНОСТИ: Ключ отсутствует в таблице.
Отсюда вывод, что лучше передавать такие схемы: Мы переименовываем существующую пустую схему в целевой базе данных, затем переносим всю схему из источника и удаляем старую переименованную схему из целевой базы данных.
Проверку одинаковости схем можно выполнить через конструкцию bash. Запускаем команду на обоих хостах, сравниваем вывод на предмет согласованности (используем diff)
В конце, конечно, хотелось бы отметить, что нужно несколько раз проверить все места, где может появиться запись в базе, и исключить возможность записи во время переключения, когда некоторые сервисы/бэкенды уже перешли на новую базу данных, а другие еще нет. Если подумать еще дальше, то теоретически можно полностью перевести том в режим «только для чтения» и выполнить переключение (mount/dmsetup/blockdev).# for i in schema_1 schema_2 schema_3; do psql -ltAF. -U postgres -c "\dt $i." db_name |cut -d. -f1,2 ; done |while read line ; do echo "$line" - $(psql -qAtX -U postgres -c "select count() from $line" db_name); done
Ну и немного графиков.
1. НьюРеликт. Процесс переключения серверной части
2. Заббикс.
Ежедневная работа сервера с PG 9.0 (понедельник, 10 сентября)
3. Заббикс.
Дневная работа сервера с PG 9.0 (понедельник, 10 сентября)
4. Заббикс.
Ежедневная работа сервера с PG 9.2 + FlashCache (понедельник, 17 сентября)
5. Заббикс.
Дневная работа сервера с PG 9.2 + FlashCache (понедельник, 17 сентября)
Самым большим злом в диаграммах Zabbix является черная линия, обозначающая iowait. Как видите, использование flashcache существенно снизило нагрузку на жесткие диски.
Для тех, кому интересны технические подробности: как настроить потоковую репликацию в PostgreSQL, см.
Здесь .
как настроить потабличную репликацию между кластерами PostgreSQL с помощью Skytools-3, см.
Здесь .
Это история одного субботника.
Спасибо за внимание! Теги: #postgresql 9.0 #postgresql 9.2 #postgresql
-
У Нас Есть Shielplus, А У Вас?
19 Oct, 24 -
Вы Читаете Журнал Linuxformat?
19 Oct, 24 -
Вышел Mozilla Firefox 3.6.3
19 Oct, 24 -
Недостатки Android В Планшетах
19 Oct, 24 -
Самый Быстрый Процессор Выпустит Ibm
19 Oct, 24 -
Встречайте Intellij Idea 2016.1
19 Oct, 24