- PVSM.RU - https://www.pvsm.ru -
Предлагаю ознакомиться с расшифровкой доклада 2018 года Андрея Сальникова "Практика обновления версий PostgreSQL"
В большинстве своем, системные администраторы и ДБА бояться как огня делать мажорные обновления версий баз данных (RDBMS), особенно если эта база данных в эксплуатации и имеет достаточно высокую нагрузку. Главной причиной тому некоторый даунтайм базы данных, который всегда подразумевается при планировании таких работ.
На практике, такого рода upgrade занимает довольно длительное время и зачастую администраторам с малым опытом подобных операций приходится откатываться на старую версию баз данных из-за достаточно банальных ошибок, которые можно было бы избежать еще на этапе подготовки.
В Data Egret мы накопили огромный опыт проведения мажорных апгрейдов PostgreSQL в проектах, где нет права на ошибку. Я поделюсь своим опытом и расскажу о следующих шагах процесса: как правильно подготовиться к upgrade-у PostgreSQL? что необходимо сделать на этапе подготовки? как запланировать последовательность действий на сам upgrade? как провести процедуру upgrade-а успешно, без возврата на предыдущую версию бд? как минимизировать или вообще избежать простоя всей системы во время upgrade-а? какие действия необходимо выполнить после успешного upgrade-а PostgreSQL? Я также расскажу про две наиболее популярные процедуры апгрейда PostgreSQL — pg_upgrade и pg_dump/pg_restore, плюсы и минусы каждого из методов и расскажу про все типичные проблемы на всех этапах этой процедуры, и как их избежать.
Доклад будет интересен как новичкам так и тем ДБА которые уже давно работают с PostgreSQL, но хотят побольше узнать о том как правильно планировать и проводить upgrade максимально безболезненно.
Здравствуйте! Я тружусь в компании Data Egret. Мы занимаемся тем, что поддерживаем сервера PostgreSQL и оказываем услуги консалтинга PostgreSQL. И практика показала, что очень мало людей обновляют базу данных. Они запустили проект, устанавливают версию актуальную на тот момент и работают до сих пор.
Доклад будет состоять из трех частей. Первая – вводная, чтобы к общей терминологии прийти. Вторая про минорные обновления. И третья про мажорные будет.
Цель доклада – дать ответ на вопросы.
В общем основная цель в том, чтобы люди старались поддерживать у себя актуальную версию Postgres.
Немного вводной информации о том, как нумеруются версии, чтобы общее понимание было. До 10 версии у нас нумерация бывает из трех цифр. Первые две цифры, разделенные точкой, отвечали за мажорную версию, последняя цифра – это минорная версия.
Начиная с 10-ой версии сообщество решило изменить стиль нумерации. Теперь у нас два числа, разделенные точкой. Первое число – это номер мажорной версии, последнее число – номер минорной версии.
Какие могут быть типы обновлений?
Минорные обновления. Тут важно понимать, что минорные обновления – это обновления в рамках одной мажорной версии. Если вы работаете с версией 9.6 и обновления между этими мелкими пачами, которые приходят, довольно важны, то будут обновления минорные. Это по последней цифре. Они самые легкие.
Для 10-ой версии начинается новый стиль нумерации. Ничего не изменяется, последнее число отвечает за минорную версию.
Мажорные обновления. Тут все достаточно интересно. В мажорных обновлениях мы прыгаем между версиями и стремимся за новыми фичами и возможностями баз данных, и всякими плюшками.
Тут уже минорные версии базы уже не играют роли. При мажорном обновлении мы будем стараться обновляться на самую последнюю доступную версию релиза.
Актуальные версии на сегодняшний день – это те, куда приехали патчи минорных обновлений. Их 6. Но одна помечена красным. И помечена по той причине, потому что эту версию сообщество уже перестало поддерживать. Т. е. они попатчили в 9.2. Это был последний патч, больше не будет, про 9.2 можно забыть. Если вы работаете на 9.2, то вам самое время обновляться.
Любая процедура обновления будет состоять из двух вещей: мы готовимся и делаем обновление.
Есть общие рекомендации. Перед любым обновлением, не зависимо от того минорная или мажорная эта версия, необходимо будет проделать перед обновлением на production следующее:
Советы общие, но частенько ими, к сожалению, пренебрегают.
Теперь перейдем к самим обновлениям. И начнем от легкого к более тяжелому по количеству действий и пониманию.
Минорное обновление хорошо тем, что несет исправления в коде самой базы данных. У нас не происходят никаких изменений со структуры данных, с внутренним представлением системного каталога Postgres. Там багфиксы самого движка Postgres.
Как это происходит:
Это к важности того, что нужно читать release notes.
Вот эта конкретная вырезка из официального Postgres.org. Релиз для версии 9.6.2. И тут черным по белому написано, что в этом релизе пофиксили создание конкурентных индексов всех.
Суть бага в чем была? Если ранее вы создавали конкурентный индекс по полю, по которому никогда до этого не было индекса и не участвовало оно ни в каком другом индексе, то у вас мог оказаться битый индекс и вы об этом бы не узнали. Потому что в базе данных он у вас выглядел бы валидным, а по факту в индексе были бы пропущены значения или ссылки были бы не на те строки в таблице. Что в итоге приводит к неожиданным результатам выполнения запросов.
И вот таких интересных штук в каждой минорной версии много. Просто так минорные версии сообщество не выпускает. Будьте внимательны. Читайте, пожалуйста, release notes. Это очень важно.
И вот иллюстрация о том, что пакеты по зависимостям не тянутся. В данном случае я обновлял серверную версию. Вы, как видите, что сервер у меня 9.6.5. А клиент по зависимостям у меня не подтянулся 9.6.1. Это тоже не очень хорошо, потому что не гарантируется обратная совместимость. И могут быть какие-то проблемы с клиентом. На минорной версии это мало вероятно, с мажорной – большая вероятность может быть. Поэтому обновили серверную часть – обновляйте другие пакеты.
И пример того, как нужно пройти по расширениям. Т. е. по каждой базе bash-скрипт напишите, который по каждой базе идет и тянет имя расширения. И просто нагенерируете себе alter extension, update и для душевного спокойствия запустите.
Какие итоги можно сделать?
Самая большая и интересная часть доклада – это мажорные обновления.
Есть несколько методик мажорных обновлений. Кому какая подходит, тот ту и выбирает. Моя цель рассказать о каждой и них.
И эти обновления тут стоят в порядке усложнения.
Как с помощью pg_dump будет выглядеть для вас процедура обновления?
Сложная и нудная процедура, но есть случаи, когда без нее никак не обойтись, к сожалению.
Некоторые особенности pg_dump:
Теперь переходим к нашей любимой утилите, к pg_upgrade.
Небольшой ликбез, как работает pg_upgrade. На входе мы должны иметь две базы данных: старую, которая у нас с данными и новый кластер пустой, который мы создали.
Соответственно, когда мы запускаем pg_upgrade, и он начинает делать свое светлое дело, то в первую очередь он чистит информацию в новом кластере о счетчиках транзакции, потому что нам нужно перенести счетчик транзакции из старой базы в новую. И когда мы стартанем, начнем ровно с того места, на котором мы закончили в старой версии базы данных. Тут происходит перенос этого счетчика транзакции.
И последняя самая массивная, но самая веселая вещь – pg_upgrade делает dump и restore схемы, он запускает pg_dump, restore с некоторыми флажками для того, чтобы восстановить новой базе всю схему данных, которая была в старой базе данных, но не переносит при этом данные. Это именно схема.
А перенос данных может быть осуществлен двумя вещами. Мы можем скопировать файлы с данными, а можем сделать хардлинк на существующие данные, потому что блок данных у нас не меняется с версией 8.4. В Postgres и мы можем позволить себе такой финт ушами.
И когда мы делаем хардлинк, то у вас в этот момент смотрят две версии базы данных (допустим, 9.0 и 10) на одни и те же дата-файлы. И если вы одновременно обе их запустите, то ваша база данных превратиться в тыкву, с которой вы потом ничего не сделаете. Поэтому будьте очень осторожны с линком. Но мы делаем через линк всегда, у нас руки не дрожат.
Тут именно такая процедура подготовки, которую мы всегда делаем перед реальным апгрейдом на production. Т. е. прежде чем устроить даунтайм и коллапс, мы сначала проверяем – действительно ли мы это можем сделать.
Сама процедура обновления, после того, как вы подготовились, довольно простая.
Создаем базу в новой locale, если мы пользовались pg_dumpall only, restore.
Останавливаем старую базу данных. При этом не забываем о том, что pgbouncer нам поможет подвесить соединение к базе данных, т. е. приложение не потеряет соединение, а просто подвиснут.
Не забываем про checkpoints, которые нам помогают очистить память и скинуть ее на диск, чтобы побыстрее остановить базу данных.
И следующим шагом запускаем обновление pg_upgrade. Сама процедура переноса счетчика транзакции, схемы данных и линковки довольно быстрая. Время обновления зависит от размера вашей базы данных именно в количестве объектов в базе данных. Может занять от минуты до 45 минут. Был у меня один раз критичный момент, когда обновление шло 45 минут, но это отдельная история. Чаще всего обновление занимает от минуты до 15 минут, независимо от размера базы данных. Это зависит от количества объектов в базе данных созданных.
Если мы копируем файл, то будет зависимость от размеров базы данных. Мы делаем через hard links. И создание линков занимает секунды в нормальной ситуации.
И запускаем новую версию PostgreSQL. Но мы еще не разрешаем приложению туда ходить. Почему мы не разрешаем приложению ходить в новую версию PostgreSQL? Потому что там нет статистики. К сожалению, pg_upgrade теряет статистику при обновлении.
И нам нужно собрать эту статистику.
И после этого мы разрешаем соединения с базой данных. Даунтайм у нас в зависимости от ситуации составляет от одной до 10 минут. И еще зависит от опытности человека, который проводит этот даунтайм.
По сбору статистики есть следующие замечания:
Стандартно pg_upgrade генерирует скрипт по сбору статистики. Суть его в том, что запускается вакуум по всем базам данных в трех стадиях: по одной цели, по 10 целям и полный сбор статистики.
Если у вас база небольшая или в ней немного объектов, то можно запустить сразу полноценный сбор статистики, игнорировав автосгенерированный скрипт.
Начиная с версии 9.5 можно немного подредактировать этот скрипт. В зависимости от того, сколько у вас ядер и насколько у вас позволяют диски и можно распараллелить сбор в статистики.
Мы обычно используем стандартный скрипт. И делаем следующим образом. Без статистики у нас планировщик сойдет с ума, он не будет знать, как правильно ему строить планы. Поэтому мы ждем, пока у нас vacuumdb соберет статистику по 1, 10 целям. И когда он уже приступает к сбору полноценной статистики, мы разрешаем соединение к БД приложению. Уже более-менее адекватной становится работа с базой данных. Планировщик более-менее адекватен. Хотя выверты могут быть, но это не так страшно, нежели ждать полной сборки статистики.
Но тут есть один фактор. Если приложение активно начинает менять записи в базе данных, то у вас возникнет блокировка. У вас придет автовакуум в какой-то момент. И возникнет блокировка между вакуум, который мы запустили после апгрейда, и автовакуумом. В это время нужно посидеть и последить за блокировками, прибивая автовакуум, чтобы он не мешал полноценному сбору статистики после апгрейда.
Кратко о процедуре обновления на слайде.
Очень часто задают вопрос – как обновлять реплики? Делается это просто:
Мы не очень это любим. Причин тут несколько:
С версией 9.4 появилась встроенная логическая репликация. С каждой версией она развивается. И я думаю, что с версии 10 на версию 11 можно уже с ее помощью мигрировать довольно легко.
Есть также сторонние репликации, которые появились ранее. Это Slony-l, Londiste, Bucardo и т. д. Их можно использовать.
Как выглядит процедура обновления с помощью логических репликаций?
Какие проблемы будут при этом присутствовать?
Тут небольшая сводная таблица, в которой приведены плюсы и минусы того или иного вида мажорного обновления. И довольно привлекательно выглядит pg_upgrade с линковкой файлов и логическая репликация, если вы действительно решите ее настраивать.
Почему мы используем апгрейд? Потому что, если у вас база 3 TB, то не все могут позволить себе 2 SSD RAID по 3 TB. Это достаточно дорогое удовольствие. А тут мы обновляемся ровно на те же файлы.
В случае с логической репликацией нам нужно больше дискового места. Это не всегда возможно.
Я посчитал, что Амазон дает гарантию, что у вас сервер работает 99 и сколько-то 9-ок после запятой. Это всегда больше 15 минут. Тут у вас даунтайм будет меньше 15 минут в общем случае. Я думаю. Что это позволительный даунтайм даже для очень онлайн-онлайн системы.
Тут приведены ссылки на полезную информацию, которую вы можете прочитать от разработчиков pg_upgrade. Также почитать об особенности сбора статистики. Там дополнительная и более детальная информация по этой теме.
На этом у меня все.
Вопросы
Добрый день! Когда мы ставим pgbouncer и потом включаем после рестарта, то если у нас идет большая нагрузка, то, соответственно, нам нужно еще дождаться, когда прогреются кэши. Как эта проблема у вас решается?
Нам в большинстве случаев кэши не приходится прогревать, потому что у нас большинство клиентов на SSD сидят хороших. И там разница чтения между операционной памятью и SSD не сильно большая, т. е. незаметно это время прогрева кэшей. Оно не сильно влияет на производительность систем. Но, конечно, просаживается, это да, надо подождать пока прогреются. И бывает, что если специально не прогревать, то может длиться часами прогрев кэшей. Это зависит от того, насколько активно идет общение с Postgres. Но специально мы обычно не прогреваем, только по просьбе.
К расширениям типа pg_worm и pg_hibernate, как относитесь для прогрева?
Я говорю, что мы в большинстве случаев не прогреваем, потому что оборудование у клиентов позволяет.
Спасибо за доклад! Можно ли реплики не перескачивать после обновлением pg_upgrade?
В принципе, можно. И те же ребята из Яндекса могут рассказать, как это делать. И смогут рассказать более подробно о граблях, на которых они попрыгали. Мы стараемся этого избегать, потому что довольно неизвестны последствия, если где-то пропустишь шаг, реплика может быть нерабочей. И когда нужно будет делать промоут на реплику, мы можем получить не базу, а просто набор файликов. И мы можем не знать об этом совсем, пока не сделаем промоут.
Там через rsync как-то?
А что rsync? Rsync можно с разными ключами запустить. Вы запустите, и он у вас не обновит файл, потому что даты, допустим, совпадают. Как это должно быть? Вы должны параллельно запустить сразу pg_upgrate мастер и реплики. Поднять мастер, собрать статистику. Потом на мастере сказать – pg_start_backup. И уже потом сделать rsync с мастера на реплику. Вот тогда вы можете более-менее себе гарантировать, что у вас rsync правильно сделает все, что вам нужно. Но не забывайте, что если у вас будет несколько дисков и вы забудете, допустим, про tablespace на HDD, сделаете rsync и запустите, то у вас сначала будет работать. А потом сделаете промоут – и все, реплики нет. Там очень много моментов, где вы можете ошибиться и просто испортить свою реплику. Лучше – надежный pg_basebackup.
Спасибо за доклад! Вы сначала сказали, что следует сначала обновить реплики…
Это касается минорного обновления.
Автор: Пацев Антон
Источник [1]
Сайт-источник PVSM.RU: https://www.pvsm.ru
Путь до страницы источника: https://www.pvsm.ru/postgresql/351548
Ссылки в тексте:
[1] Источник: https://habr.com/ru/post/495262/?utm_source=habrahabr&utm_medium=rss&utm_campaign=495262
Нажмите здесь для печати.