惯性聚合 高效追踪和阅读你感兴趣的博客、新闻、科技资讯
阅读原文 在惯性聚合中打开

推荐订阅源

T
Tenable Blog
D
DataBreaches.Net
S
Secure Thoughts
B
Blog
S
Schneier on Security
Y
Y Combinator Blog
P
Proofpoint News Feed
C
Cybersecurity and Infrastructure Security Agency CISA
C
Cyber Attacks, Cyber Crime and Cyber Security
D
Darknet – Hacking Tools, Hacker News & Cyber Security
CTFtime.org: upcoming CTF events
CTFtime.org: upcoming CTF events
F
Full Disclosure
Engineering at Meta
Engineering at Meta
L
LangChain Blog
T
Threatpost
阮一峰的网络日志
阮一峰的网络日志
freeCodeCamp Programming Tutorials: Python, JavaScript, Git & More
The Hacker News
The Hacker News
月光博客
月光博客
大猫的无限游戏
大猫的无限游戏
Cyberwarzone
Cyberwarzone
T
The Exploit Database - CXSecurity.com
雷峰网
雷峰网
博客园 - 司徒正美
Help Net Security
Help Net Security
www.infosecurity-magazine.com
www.infosecurity-magazine.com
Exploit-DB.com RSS Feed
Exploit-DB.com RSS Feed
Application and Cybersecurity Blog
Application and Cybersecurity Blog
P
Privacy International News Feed
OSCHINA 社区最新新闻
OSCHINA 社区最新新闻
V
Vulnerabilities – Threatpost
Cisco Talos Blog
Cisco Talos Blog
L
LINUX DO - 热门话题
酷 壳 – CoolShell
酷 壳 – CoolShell
T
Threat Research - Cisco Blogs
Recent Announcements
Recent Announcements
cs.CL updates on arXiv.org
cs.CL updates on arXiv.org
H
Heimdal Security Blog
Jina AI
Jina AI
C
Cisco Blogs
Attack and Defense Labs
Attack and Defense Labs
Microsoft Security Blog
Microsoft Security Blog
L
Lohrmann on Cybersecurity
aimingoo的专栏
aimingoo的专栏
D
Docker
I
Intezer
C
Check Point Blog
Cloudbric
Cloudbric
小众软件
小众软件
V2EX - 技术
V2EX - 技术

Все публикации подряд на Хабре

Ловим музу за клавиатуру: как айтишнику стать автором Что умеет Midjourney в 2026? Мой немного грустный разбор этого шикарного инструмента Никто не любит писать тесты, но ИИ может исправить это IPv8 выглядит как мечта. Поэтому почти наверняка не взлетит Производители вернули в продажу материнки с DDR3. Что происходит? Управление агентом с телефона через Telegram теперь в KodaCode От координации к лидерству: как меняется роль руководителя разработки Я сделала родителям бизнес вместо пенсии: зарабатываем 70 тысяч, мама не даёт продать В три раза быстрее приемка товара и оптимизация трудозатрат на 73%: как «РСТ-Инвент» помог Gulliver Group ИИ-шечный мир победил? О влиянии искусственного интеллекта на игропром Кремль снижает давление на Телеграмм пока Европа строит интернет по паспорту Как CEO, CTO и CIO за 8 часов собрали ИИ-директора, который умеет держать позицию под давлением Как (не) потерять домен за выходные Вместо 8 разных VPS: как я организовал практику студентам на одном сервере Почему твой Open Source проект не замечают? R&D: искусство управления неопределенностью в разработке AI-дефляция: вакансий для разработчиков больше, а рост зарплат — худший за 15 лет Мы отдали управление роботами OpenClaw. Что из этого вышло Галактический ID: система идентификации для всех форм разумной жизни Шесть основ бизнес-анализа: начинаем с вопроса «Кто в игре?» Код-ревью, в котором дело не в коде Данные переехали. Команда — нет Системной подход к сдаче OSWE в 2025 Почему комната управления реактором покрашена в цвет морской пены 4 YAML-файла вместо PySpark: как аналитикам строить пайплайны без разработчиков LLM-агент для поиска свободных доменов: автоматизируем подбор Когда, зачем и как правильно начинать новую сессию в Claude Code? Как я заставил нейросеть писать макросы для FreeCAD Анатомия ИИ‑агента для подбора персонала. От тысячи резюме к топ‑10 за минуты Опыт разработчика как экономика внимания Автономность как точка невозврата: кто будет субъектом в цифровом будущем Обучение ИИ в «диких» условиях: как рутинные действия превращаются в датасеты Как измерить LLM для задач кибербеза: обзор открытых бенчмарков Где хранить код? Сравнение GitHub, GitLab и Bitbucket Математика объясняет, почему нормальное распределение встречается повсюду Почему ваш FinOps не работает: 12 тезисов от практиков Как подписать проектную документацию УКЭП с использованием бесплатных лицензий Pilot Адаптивное администрирование Sigla Vision Я грузил уран в бочки, а потом 20 лет строил ИТ в атомной отрасли Чем позвонить с Эвереста? История и обзор спутниковой связи. Часть 2 Как языковая модель помогает контролировать качество инструктажей по охране труда в металлургии Как не передать на desktop свой IP в РКН Анатомия SAP Privileges: как устроено управление правами в macOS MoneyDev: Сказка про три главных слова Обновлённый токенизатор видео K-VAE 2.0 от Сбера Как сделать диспетчеризацию дома на 1284 квартиры почти бесплатно Как мы разогнали железную дорогу Мы дали агентам рутину. Теперь надо решить — что делать с освободившимся временем Токсичный контент, промпт-хакинг и защита ИИ — всё о Guardrails для LLM Умный город начинается с точного взгляда: как «Фалькон Тех» меняет пространство к лучшему Навайбкодил приложение для анализа графов Почему Дюну так интересно читать? Упрощаем работу с рутиной или как стать Гендальфом Белым Деконструкция Go: CPU, RAM и что там происходит. Go Assembler база. Часть 1.1 Какие профессии исчезнут из-за ИИ, а какие появятся? И что с этим делать Как мы построили IT-отдел, где хочется расти: архитектурные встречи, прозрачные метрики и книжные подарки Rufler: Делаем из Claude Code автономный рой через один YAML-конфиг Sing-box и белый список приложений Как построить надёжный обмен сообщениями в микросервисах: лучшие практики для enterprise OpenAI строит MLM-пирамиду, а McKinsey и Accenture помогают ей в этом Дом, который не построил Фишер (Часть 2) «Сверхзвуковой математик» против «Вдумчивого логиста»: битва алгоритмов 3D-упаковки Мультимодальные модели – грубый и дорогой инструмент Разговоры ничего не стоят. Код тоже Проверки физических лиц: с кого начнет ФНС Топ-10 бесплатных нейросетей для создания видео в 2026 году Первые слои кода: как наши решения сегодня определяют архитектуру ИИ на десятилетия Разработка нового статического анализатора: PVS-Studio JavaScript Поиск уязвимостей ПО: базовый минимум или роскошный максимум Почему оценка персонала не работает как инструмент управления Как мы разработали ИИ-ассистента и сократили рутину продуктовой команды на 50% Как я ушел из найма, нажарил косточек и продал на маркетплейсах на 168 млн в год Когда 1С:ERP уже внедрена, а нормального производственного плана всё ещё нет Как я сделал Claude мультимодальным, подключив к нему Qwen Omni Как приглашение на вакансию мечты превращается в атаку Infrastructure as Code: философия и лучшие практики IaC Тестируем Yandex Code Assistant на задаче, в которой нужно хранить секреты nxs-universal-chart v3.0: новое поколение универсального Helm-чарта Callback Injection: Техника, которая отправила Microsoft Defender в глухой нокаут «Все идеи на стол»: митап как способ вывести проект из тупика Сегодня я узнал нечто новое о GPU благодаря багу в своей игре Как заставить LLM ̶ ̶г̶а̶л̶л̶ю̶ ̶ эволюционировать Карта событий как фундамент аналитики: практический кейс для E-commerce Что выбрать для AI: x86, ARM или RISC-V? Дайджест железа за март Роль соматических мутаций в развитии аутоиммунных заболеваний: путь к избирательной терапии Mythos от Anthropic — тревожный сигнал для всех, а не только для банков Guardrails для LLM на Java: как приручить промпт‑инъекции и токсичные ответы Green-VLA: как мы собрали VLA-модель для реального антропоморфного робота и не потеряли обобщение Финансовая гонка вооружений: почему умные люди добровольно в ней участвуют Эра ИИ-агентов наступила: выбираем лучшего цифрового сотрудника # Практический опыт внедрения WinCC Redundancy на производственном предприятии Сделал MVP за 3 дня, а потом неделю прикручивал оплату. Оно того стоило? Физика против Маска: почему Starship V3 может оказаться ещё одной катастрофой Нефть Венесуэлы: крупнейшие запасы в мире, но не крупнейшая нефтяная держава JPA 4. Переосмысление Hibernate Почему зеркальная фотокамера Nikon D5 десятилетней давности идеально подошла для миссии «Артемида-2» Проект «Уровень-Спутник» или как мы сделали платформу для гидрологов «Замедлиться, чтобы ускориться»: почему ИИ повышает цену ошибок в требованиях и архитектуре Как с нуля поднять трафик IT-компании на 1657% при бюджете 55 тыс. и выжить Pixel-perfect Downsampling — идеальная отрисовка 50 миллионов точек без потерь
Мажорное обновление Greengage с помощью pg_upgrade и ggupgrade
Olga Sergeeva · 2026-06-26 · via Все публикации подряд на Хабре

Средний

16 мин

22

Мажорное обновление Greengage с помощью pg_upgrade и ggupgrade

В данной статье описывается процесс мажорного обновления СУБД Greengage (open-source форк Greenplum) с помощью утилит pg_upgrade и ggupgrade. Утилиты находятся на этапе финальных доработок, тестирования и отладки на момент выхода статьи. Все дальнейшее описание и примеры актуальны для перехода Greengage с версии 6 на 7.

Введение

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

Вот основные причины обновления СУБД:

  1. Повышение безопасности.

  2. Рост производительности.

  3. Новые функциональные возможности.

  4. Актуальность и поддержка сообщества. Оставаясь на актуальных версиях, можно получать полноценную поддержку от сообщества и разработчиков.

Более подробно с изменениями в новых версиях Greengage можно ознакомиться на странице Релизы.

Обновление СУБД можно разделить на два типа: минорное и мажорное. Минорное обновление версии СУБД PostgreSQL и Greengage (например, с версии 6.29 до 6.30) предполагает, что формат хранения данных не будет меняться, и поэтому достаточно обновить бинарные файлы СУБД. Мажорное обновление версии (например, с версии 6.29 до 7.4) может менять структуру системных объектов, поэтому здесь недостаточно обновить бинарные файлы — необходимо выполнить миграцию (перенос) данных в кластер следующей мажорной версии.

Миграцию данных выполняют с помощью логического бэкапа, что занимает достаточно много времени. В процессе создания логического бэкапа кластер должен быть неактивен для записи, а во время восстановления — полностью остановлен, если мы восстанавливаем на той же инфраструктуре. В производственных средах вопрос минимизации простоя БД стоит особенно остро. Для баз данных размером сотни терабайт и более, как для Greengage, это может означать часы или даже дни простоя, что неприемлемо для критически важных бизнес-процессов.

Обновление PostgreSQL с помощью утилиты pg_upgrade

Кластер Greengage — это распределенный кластер, состоящий из десятков или сотен инстансов, основанных на PostgreSQL. Более подробно ознакомиться с архитектурой Greengage можно в документации. Поэтому сначала рассмотрим утилиту pg_upgrade для обновления PostgreSQL, так как именно она взята за основу обновления кластера Greengage.

Идея pg_upgrade заключается в том, что в мажорных версиях меняется в основном структура системного каталога, а само физическое хранение данных — нет, за некоторыми исключениями, речь о которых пойдет ниже. Поэтому утилита генерирует команды создания объектов (БД, схемы, таблицы, функции и т.д.) и выполняет их на новом сервере, а затем копирует файлы данных.

Новые объекты должны иметь те же идентификаторы, что и на исходном кластере. Связано это в основном с тем, что в данных хранятся ссылки на TOAST-таблицы, то есть содержатся oid TOAST-таблиц. Изменить oid существующего объекта нельзя. Перед созданием каждого объекта pg_upgrade вызывает функцию, которая запоминает нужный oid, а затем это сохраненное значение используется при создании объекта. Таким образом, все пользовательские объекты имеют те же идентификаторы на новом кластере, что и на обновляемом кластере.

Далее выполняется копирование файлов данных сгенерированных объектов на новый кластер. Если заменить копирование файлов данных на создание жестких ссылок (включается параметром --link в pg_upgrade), то процесс обновления будет быстрее, чем в режиме копирования файлов данных. В режиме создания жестких ссылок pg_upgrade файлы данных исходного кластера не копируются, а создаются жесткие ссылки на них в обновляемом кластере. Файлы данных старого кластера можно будет в дальнейшем удалять, это не повлияет на данные целевого кластера. Ограничение составляет только изменение данных на старом кластере, так как в этом случае будет изменяться один и тот же файл, который используется в новом кластере. В случае использования жестких ссылок использовать одновременно исходный и целевой кластер нельзя, иначе будут изменяться одни и те же данные.

Для пользователя схема обновления PostgreSQL с помощью pg_upgrade выглядит следующим образом:

  1. Установка новой версии PostgreSQL на кластере, который нужно обновить.

  2. Инициализация кластера новой версии.

  3. Запуск утилиты pg_upgrade с указанными директориями бинарных файлов и файлов данных для исходного и целевого кластера.

Утилита pg_upgrade выполняет предварительную проверку обновляемого сервера, в результате которой могут возникнуть ошибки для:

  • Устаревших типов данных.

  • Неподдерживаемого синтаксиса.

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

  • Отсутствующих расширений.

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

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

Перед обновлением кластера рекомендуется внимательно ознакомиться с изменениями в версии, на которую планируется обновляться.

Обновление Greengage с помощью утилиты pg_upgrade

Так как Greengage состоит из множества инстансов PostgreSQL, то за основу для реализации утилиты обновления Greengage можно взять pg_upgrade PostgreSQL.

В Greengage есть объекты, которых нет в PostgreSQL, например append-optimized таблицы. Для таких таблиц существуют служебные таблицы, структура которых также может измениться в новой мажорной версии, поэтому перенести данные этих таблиц с помощью копирования файлов (или жестких ссылок) не удастся. Речь идет о служебных таблицах:

Неоптимальным будет генерировать и выполнять создание объектов на всех сегментах кластера Greengage. Так как структура объектов в кластере (метаинформация) на всех сегментах одинакова, то не нужно каждый раз создавать все объекты на всех сегментах кластера. Достаточно создать объекты на координаторе и скопировать полученные файлы системного каталога кластера с координатора на сегменты. На сегментах остается запустить копирование или создание жестких ссылок файлов данных.

Таким образом, утилита pg_upgrade для Greengage — это утилита pg_upgrade PostgreSQL, доработанная для объектов Greengage, а также оптимизированная на обновление метаинформации. Для этого у нее есть два режима запуска:

  • dispatcher — запуск на координаторе для формирования метаинформации.

  • segment — запуск на сегментах для переноса данных.

Перед запуском pg_upgrade необходимо остановить исходный и целевой кластеры.

Схема обновления кластера Greengage с помощью утилиты pg_upgrade выглядит следующим образом:

  1. Запуск pg_upgrade на координаторе для создания объектов БД с теми же идентификаторами, что и на кластере предыдущей версии, в режиме dispatcher:

    pg_upgrade на координаторе

    pg_upgrade на координаторе

  2. Копирование файлов метаинформации на сегменты:

    Копирование метаинформации на сегменты

    Копирование метаинформации на сегменты

  3. Запуск pg_upgrade на primary-сегментах для копирования файлов данных или создания жестких ссылок (параметр --link):

    pg_upgrade на primary-сегментах

    pg_upgrade на primary-сегментах

  4. Запуск gprecoverseg для восстановления mirror-сегментов.

  5. Пересоздание standby с помощью gpinitstandby.

После запуска, обновления статистики и проверки кластера новой версии можно удалить старый кластер, для этого pg_upgrade генерирует скрипты.

Далее приведен пример обновления кластера Greengage 6 до Greengage 7 на Ubuntu 22.04, где уже установлен и инициализирован кластер версии 7. Этот пример представлен для понимания, как происходит мажорное обновление Greengage и его можно повторить на тестовых кластерах Greengage.

Выполнение обновления кластера Greengage 6 до Greengage 7 на Ubuntu 22.04

Для обновления кластера Greengage сначала необходимо установить Greengage новой версии на все хосты кластера текущей версии. Доработанная утилита pg_upgrade идет в составе Greengage 7.

Установка и инициализация кластера Greengage достаточно подробно описаны в документации Greengage. Чтобы исключить конфликты при установке утилиты inetutils-ping в Ubuntu, уберем ее из установки зависимостей для Ubuntu перед запуском README.Ubuntu.bash, так как она уже была ранее установлена для Greengage 6:

# удаляем установку inetutils-ping из файла README.Ubuntu.bash
$ sed -i 's/inetutils-ping / /g' README.Ubuntu.bash

После установки бинарных файлов Greengage 7 на все хосты кластера необходимо инициализировать его на координаторе с помощью gpinitsystem той же самой конфигурации (с таким же количеством хостов и сегментов, а также набором расширений), что и обновляемый кластер.

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

1. Обновление метаинформации на координаторе

Для обновления на координаторе необходимо остановить кластеры версий 6 и 7 и выполнить следующие команды:

# установка путей до Greengage
# /usr/local/gpdb7 - директория, где установлен Greengage 7
# /ggdb7/data1/master/gpseg-1 - директория данных координатора
# 5433 - порт кластера Greengage 7
$ source /usr/local/gpdb7/greengage_path.sh && export MASTER_DATA_DIRECTORY=/ggdb7/data1/master/gpseg-1 && export PGPORT=5433

# запуск утилиты pg_upgrade, установленной с Greengage 7
# /usr/lib/gpdb/bin - директория с бинарными файлами Greengage 6
# /usr/local/gpdb7/bin - директория с бинарными файлами Greengage 7
# /data1/master/gpseg-1 - директория данных кластера Greengage 6
# /ggdb7/data1/master/gpseg-1 - директория данных кластера Greengage 7
$ pg_upgrade -b /usr/lib/gpdb/bin -B /usr/local/gpdb7/bin -d /data1/master/gpseg-1 -D /ggdb7/data1/master/gpseg-1 --mode=dispatcher

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

Для устранения ошибок при обновлении необходимо:

  • Заменить объекты в исходном кластере с учетом различий версий 6 и 7 Greengage.

  • Установить необходимые расширения на новом кластере, которые использовались в исходном.

  • Объекты, которые нельзя перенести с помощью копирования файлов данных и по которым возникли ошибки, выгрузить отдельно и удалить перед повторным обновлением. Это, например, таблицы, содержащие составные системные типы данных, индексы партиционированных таблиц. После обновления выгруженные объекты нужно будет отдельно загрузить на новый кластер.

После устранения проблем и повторного запуска pg_upgrade на координаторе в случае успешного выполнения будет выведена следующая информация:

    Performing Consistency Checks
    -----------------------------
    Checking cluster versions                                   ok
    Checking database user is the install user                  ok
    Checking database connection settings                       ok
    Checking for prepared transactions                          ok
    Checking for system-defined composite types in user tables  ok
    ...
Полный вывод
Performing Consistency Checks
    -----------------------------
    Checking cluster versions                                   ok
    Checking database user is the install user                  ok
    Checking database connection settings                       ok
    Checking for prepared transactions                          ok
    Checking for system-defined composite types in user tables  ok
    Checking for reg* data types in user tables                 ok
    Checking for contrib/isn with bigint-passing mismatch       ok
    Checking for online expansion status                        ok
    Checking for external tables used in partitioning           ok
    Checking for non-covering indexes on partitioned AO tables  ok
    Checking for indexes on partitioned tables                  ok
    Checking for orphaned TOAST relations                       ok
    Checking array types derived from partitions                ok
    Checking for multi-column LIST partition keys               ok
    Checking for functions dependent on plpython2               ok
    Checking for views with removed operators                   ok
    Checking for views with removed functions                   ok
    Checking for views with removed types                       ok
    Checking for disallowed OPERATOR =>                         ok
    Checking for SHA-256 hashed passwords                       ok
    Checking for removed "abstime" data type in user tables     ok
    Checking for removed "reltime" data type in user tables     ok
    Checking for removed "tinterval" data type in user tables   ok
    Checking for tables WITH OIDS                               ok
    Checking for invalid "sql_identifier" user columns          ok
    Checking for invalid "unknown" user columns                 ok
    Checking for roles starting with "pg_"                      ok
    Checking for appendonly materialized view with relfrozenxid ok
    Creating dump of global objects                             ok
    Creating dump of database schemas
                                                                ok
    Checking for presence of required libraries                 ok
    Checking database user is the install user                  ok
    Checking for prepared transactions                          ok
    Checking for new cluster tablespace directories             ok

    If pg_upgrade fails after this point, you must re-initdb the
    new cluster before continuing.

    Performing Upgrade
    ------------------
    Analyzing all rows in the new cluster                       ok
    Freezing all rows in the new cluster                        ok
    Setting next distributed transaction ID for new cluster     ok
    Deleting files from new pg_xact                             ok
    Copying old pg_clog to new server                           ok
    Setting oldest XID for new cluster                          ok
    Setting next transaction ID and epoch for new cluster       ok
    Deleting files from new pg_multixact/offsets                ok
    Copying old pg_multixact/offsets to new server              ok
    Deleting files from new pg_multixact/members                ok
    Copying old pg_multixact/members to new server              ok
    Setting next multixact ID and offset for new cluster        ok
    Resetting WAL archives                                      ok
    Setting next OID for new cluster                            ok
    Deleting files from new pg_distributedlog                   ok
    Copying old pg_distributedlog to new server                 ok
    Setting frozenxid and minmxid counters in new cluster       ok
    Restoring global objects in the new cluster                 ok
    Restoring database schemas in the new cluster
                                                                ok
    Invalidating bitmap indexes in new cluster                  ok
    Freezing all rows in new master after pg_restore            ok
    Copying user relation files
                                                                ok
    Sync data directory to disk                                 ok
    Creating script to analyze new cluster                      ok
    Creating script to delete old cluster                       ok
    Checking for hash indexes                                   ok
    Checking for extension updates                              ok

    Upgrade Complete
    ----------------
    Optimizer statistics are not transferred by pg_upgrade so,
    once you start the new server, consider running:
        ./analyze_new_cluster.sh

    Running this script will delete the old cluster's data files:
        ./delete_old_cluster.sh

2. Копирование файлов метаинформации с координатора на primary-сегменты

Для начала очистим директории данных на primary-сегментах:

# segment_hosts.hosts - файл с описанием всех сегментных хостов кластера
# /ggdb7/data1/primary/data - вспомогательная директория
$ gpssh -f segment_hosts.hosts -e 'rm -r /ggdb7/data1/primary/*/*/' && \
  gpssh -f segment_hosts.hosts -e 'mkdir /ggdb7/data1/primary/data'

Скопируйте файлы данных на каждый primary-сегмент каждого сегментного хоста:

# копирование данных
$ gpscp -f segment_hosts.hosts -r /ggdb7/data1/master/gpseg-1/*/ =:/ggdb7/data1/primary/data && \
  gpssh -f segment_hosts.hosts -e 'find /ggdb7/data1/primary -type d -name "gpseg*" -exec cp -r /ggdb7/data1/primary/data/* {} \;' &&  \
# удаление вспомогательной директории
  gpssh -f ~/segment_hosts.hosts -e 'rm -r /ggdb7/data1/primary/data'

3. Запуск pg_upgrade на всех сегментах

Для запуска pg_upgrade в режиме копирования файлов на всех сегментах можно воспользоваться следующей командой на координаторе:

# запуск утилиты pg_upgrade, установленной с Greengage 7, на сегментах
# /usr/lib/gpdb/bin - директория с бинарными файлами Greengage 6
# /usr/local/gpdb7/bin - директория с бинарными файлами Greengage 7
# /data1/primary - директория данных primary-сегментов кластера Greengage 6
# /ggdb7/data1/primary - директория данных primary-сегментов кластера Greengage 7
$ gpssh -f segment_hosts.hosts -e 'source /usr/local/gpdb7/greengage_path.sh && for dir in $(ls /ggdb7/data1/primary) ; do pg_upgrade -b /usr/lib/gpdb/bin -B /usr/local/gpdb7/bin -d /data1/primary/$dir -D /ggdb7/data1/primary/$dir --mode=segment; done'

Чтобы запустить pg_upgrade в режиме жестких ссылок, необходимо добавить параметр --link:

$ gpssh -f segment_hosts.hosts -e 'source /usr/local/gpdb7/greengage_path.sh && for dir in $(ls /ggdb7/data1/primary) ; do pg_upgrade -b /usr/lib/gpdb/bin -B /usr/local/gpdb7/bin -d /data1/primary/$dir -D /ggdb7/data1/primary/$dir --mode=segment --link; done'

При отсутствии ошибок для каждого сегмента должна быть выведена следующая информация:

    Performing Consistency Checks
    -----------------------------
    Checking cluster versions                                   ok
    Checking database user is the install user                  ok
    Checking database connection settings                       ok
    Checking for prepared transactions                          ok
    Checking for system-defined composite types in user tables  ok
    ...

Полный вывод

Полный вывод
    Performing Consistency Checks
    -----------------------------
    Checking cluster versions                                   ok
    Checking database user is the install user                  ok
    Checking database connection settings                       ok
    Checking for prepared transactions                          ok
    Checking for system-defined composite types in user tables  ok
    Checking for reg* data types in user tables                 ok
    Checking for contrib/isn with bigint-passing mismatch       ok
    Checking for external tables used in partitioning           ok
    Checking for non-covering indexes on partitioned AO tables  ok
    Checking for indexes on partitioned tables                  ok
    Checking for orphaned TOAST relations                       ok
    Checking array types derived from partitions                ok
    Checking for multi-column LIST partition keys               ok
    Checking for functions dependent on plpython2               ok
    Checking for views with removed operators                   ok
    Checking for views with removed functions                   ok
    Checking for views with removed types                       ok
    Checking for disallowed OPERATOR =>                         ok
    Checking for SHA-256 hashed passwords                       ok
    Checking for removed "abstime" data type in user tables     ok
    Checking for removed "reltime" data type in user tables     ok
    Checking for removed "tinterval" data type in user tables   ok
    Checking for tables WITH OIDS                               ok
    Checking for invalid "sql_identifier" user columns          ok
    Checking for invalid "unknown" user columns                 ok
    Checking for roles starting with "pg_"                      ok
    Checking for appendonly materialized view with relfrozenxid ok
    Checking for presence of required libraries                 ok
    Checking database user is the install user                  ok
    Checking for prepared transactions                          ok
    Checking for new cluster tablespace directories             ok

    If pg_upgrade fails after this point, you must re-initdb the
    new cluster before continuing.

    Performing Upgrade
    ------------------
    Freezing all rows in the new cluster                        ok
    Setting next distributed transaction ID for new cluster     ok
    Deleting files from new pg_xact                             ok
    Copying old pg_clog to new server                           ok
    Setting oldest XID for new cluster                          ok
    Setting next transaction ID and epoch for new cluster       ok
    Deleting files from new pg_multixact/offsets                ok
    Copying old pg_multixact/offsets to new server              ok
    Deleting files from new pg_multixact/members                ok
    Copying old pg_multixact/members to new server              ok
    Setting next multixact ID and offset for new cluster        ok
    Resetting WAL archives                                      ok
    Setting next OID for new cluster                            ok
    Deleting files from new pg_distributedlog                   ok
    Copying old pg_distributedlog to new server                 ok
    Restoring append-only auxiliary tables in new cluster       ok
    Copying user relation files
                                                                ok
    Setting database system identifier for new cluster          ok
    Sync data directory to disk                                 ok
    Creating script to analyze new cluster                      ok
    Creating script to delete old cluster                       ok
    Checking for hash indexes                                   ok
    Checking for extension updates                              ok

    Upgrade Complete
    ----------------
    Optimizer statistics are not transferred by pg_upgrade so,
    once you start the new server, consider running:
        ./analyze_new_cluster.sh

    Running this script will delete the old cluster's data files:
        ./delete_old_cluster.sh

4. Проверка обновленного кластера и запуск gprecoverseg

После выполнения обновления нужно запустить кластер версии 7, проверить его работоспособность и запустить восстановление зеркал:

# установка пути до Greengage 7
$ source /usr/local/gpdb7/greengage_path.sh && export MASTER_DATA_DIRECTORY=/ggdb7/data1/master/gpseg-1 && export PGPORT=5433

# запуск кластера версии 7
$ gpstart

# проверка
$ psql postgres

# восстановление зеркал
$ gprecoverseg -F

Сравнение gpbackup/gprestore с pg_upgrade для обновления Greengage с версии 6 на 7

Проводилось сравнение обновления Greengage с версии 6 на версию 7 с помощью логического бэкапа и с помощью pg_upgrade на одном и том же кластере.

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

Тип

CPU

RAM

HDD

Размер данных

Координатор

8

32 ГБ

150 ГБ

17 ГБ

Сегмент 1

16

32 ГБ

1,5 ТБ

364 ГБ (primary) + 360 ГБ (mirror)

Сегмент 2

16

32 ГБ

1,5 ТБ

364 ГБ (primary) + 360 ГБ (mirror)

В базе данных кластера было 90 000 равномерно заполненных таблиц, из которых было 76 000 append-optimized таблиц.

Были получены следующие результаты.

gpbackup/gprestore

Операция

Затраченное время

gpbackup только данных (4 jobs)

1 ч 10 мин

gpbackup только данных (8 jobs)

1 ч

Создание метаинформации

10 мин

gprestore только данные (4 jobs)

5 ч 7 мин

gprestore только данные (8 jobs)

5 ч 8 мин

Общее время gpbackup / gprestore

6 ч 18 мин

pg_upgrade

Операция

Затраченное время

pg_upgrade обновление координатора

10 мин

Копирование метаинформации на сегменты

5 мин

Обновление сегментов в режиме копирования файлов

1 ч 50 мин

Обновление сегментов в режиме жестких ссылок (--link)

15 мин

Общее время в режиме копирования файлов pg_upgrade

2 ч 5 мин

Общее время в режиме жестких ссылок pg_upgrade

25 мин

В случае режима копирования файлов pg_upgrade быстрее в 3 раза, чем миграция данных с помощью логического бэкапа. В режиме создания жестких ссылок на данные pg_upgrade выигрыш составляет 15 раз. Выигрыш по переносу данных pg_upgrade составил 20 раз! Есть еще одно преимущество режима жестких ссылок для pg_upgrade: так как сами данные не копируются, а на них создаются ссылки, то свободного места потребуется гораздо меньше — только на метаинформацию и некоторые отдельно перенесенные объекты.

Обновление Greengage с помощью утилиты ggupgrade

Отличные результаты pg_upgrade мотивируют развивать дальше этот механизм. Как видно из вышеприведенного примера обновления Greengage с помощью pg_upgrade, пользователю необходимо выполнить достаточно много ручных действий.

Чтобы автоматизировать эту работу, была создана утилита ggupgrade, которая выполняет следующее:

  • инициализирует новый кластер;

  • выполняет дополнительные скрипты на старом кластере;

  • запускает pg_upgrade на координаторе;

  • копирует метаинформацию на все сегменты;

  • запускает pg_upgrade на всех primary-сегментах;

  • запускает скрипты на новом кластере;

  • обновляет standby и зеркала;

  • настраивает новый кластер на использование порта старого кластера.

Здесь можно отметить, что в случае pg_upgrade кластер новой версии приходилось сначала инициализировать, а ggupgrade делает это самостоятельно на основе конфигурации старого кластера.

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

Для того чтобы выполнить обновление кластера с помощью ggupgrade, пользователю нужно:

  1. Установить новую версию Greengage на все хосты обновляемого кластера.

  2. Установить/скопировать утилиту ggupgrade на все хосты обновляемого кластера.

  3. Скопировать дополнительные скрипты на координатор.

  4. Установить путь до ggupgrade в PATH на координаторе.

  5. Настроить конфигурационный файл на координаторе.

    Пример содержимого конфигурационного файла ggupgrade_config для ggupgrade:

    # The source cluster master port.
    source_master_port = 5432
    
    # The installation path for the source cluster.
    # For example, /usr/local/<source-greengage-version>.
    source_gphome = /usr/lib/gpdb
    
    # The installation path for the target cluster.
    # For example, /usr/local/<target-greengage-version>.
    target_gphome = /usr/local/gpdb7
    
    # Whether to upgrade using "link" or "copy" mode.
    # The copy method performs the upgrade on a copy of the primary segments.
    # The link method directly upgrades the primary segments.
    mode = link
  6. Запустить ggupgrade на координаторе. Есть 4 основных этапа работы утилиты:

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

    • execute, где запускается pg_upgrade на координаторе и всех сегментах с копированием метаинформации с координатора на сегменты.

    • revert, при запуске которого кластер версии 6 восстанавливается в исходное состояние. Этот режим можно запускать на любом этапе до этапа finalize.

    • finalize, на этом этапе запускаются дополнительные скрипты, обновление статистики, а также запуск обновленного кластера на порте исходного кластера.

    Пример запуска ggupgrade:

    # этап инициализации
    $ ggupgrade initialize -v -f /opt/ggupgrade/ggupgrade_config
    
    # этап выполнения
    $ ggupgrade execute
    
    # этап финализации
    $ ggupgrade finalize

Заключение

Текущие версии pg_upgrade и ggupgrade уже показывают отличные результаты. Приглашаем всех желающих испытать их на прочность на своих тестовых стендах — ваша обратная связь важна для финального релиза.