UMGUM.COM (лучше) 

Zabbix server upgrade from v.1.8 to v.2.0 ( Обновление сервера системы мониторинга с версии 1.8.3 до 2.0.5. )

24 марта 2013  (обновлено 2 ноября 2014)

OS: Linux Debian Squeeze.
Application: Zabbix v.1.8.3 to v.2.0.5.

Обновление с 1.8 до 2.0.5 должно пройти достаточно гладко. Обновление исполняемых файлов и компонентов "web"-интерфейса производится путём простого замещения и отдельному рассматриванию не подлежит. Самое интересное - обновление структуры и содержимого СУБД, в моём случае ещё и совмещённое с переносом данных с одной физической машины на другую.

Сразу предупреждаю - переносить на новый сервер старую базу и обновлять её до требований новой версии Zabbix дело не одного часа. У меня на перенос и обновление базы наработанной в течении года на мониторинге более полутора сотен единиц оборудования по ряду параметров ушло около семи часов чистого рабочего времени без учёта экспериментальных попыток. Так что, заранее пишем служебную записку на выход в выходной день или просто делаем это ночью.


В связи с затяжным характером процедур рекомендую запускать их в сеансах "screen", а то, обидно будет утерять связь с хостом после трёх часов ожидания, очень обидно.

# aptitude install screen

Создание сеанса:

# screen -S screen.postgres

Переподключение к сеансу (после разрыва связи, например, или сознательного отключения с помощью Ctrl+A+D):

# screen -r screen.postgres

Для начала остановим работу Zabbix-сервера, чтобы избежать его вмешательства в данные во время переноса и преобразования данных:

# /etc/init.d/zabbix-server stop

Дожидаемся, пока Postgres успокоится и приведёт в порядок свои внутренности после отрыва главного главного возмутителя - Zabbix`а. В моём случае Postgres после отключения Zabbix ещё минут пять что-то там делал от имени пользователя сервиса мониторинга.

Для полного спокойствия перезапустим Postgres, если на нём не висит более важных сервисов, разумеется:

# /etc/init.d/postgresql restart

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

Я предпочитаю вначале создавать резервную копию структуры базы, а потом уже сохранять сами данные. Такой подход позволяет произвести необходимые изменения в структуре прежде, чем располагать в ней данные. Особенно удобно это в случае, когда объём резервируемых данных измеряется в гигабайтах.

Сохраняем структуру данных:

# pg_dump --verbose --clean --schema-only --format=p --file="./file-name-structure.sql" --username="postgres" --password zabbix

Где:

"--clean" - указываем применять команды удаления всех объектов перед их восстановлением;
"--schema-only" - указываем сохранять только структуру объектов;
"--format {с|t|p}" - указываем на формат выходного файла, соответственно "gzip", "tar" или "plain text".

Сохраняем данные как таковые:

# pg_dump --verbose --blobs --data-only --format=c --compress=4 --file="./file-name-data.sql.gz" --username="postgres" --password zabbix

Где:

"--blobs" - указываем сохранять большие двоичные объекты наряду с обычными данными. В связи с использованием этого параметра необходимо так же применить архивирование данных в формат "tar" или "gzip";
"--data-only" - указываем сохранять только данные;
"--inserts" - применяем для восстановления записей команды INSERT вместо используемых по умолчанию команд COPY. Этот вариант безопаснее, так как одна поврежденная запись приводит к сбою всей команды COPY, хотя процесс восстановления и занимает больше времени;
"--format {с|t|p}" - указываем на формат выходного файла, соответственно "gzip", "tar" или "plain text" (для того, чтобы pg_dump смог архивировать данные соответствующие утилиты должны иметься в системе);
"--compress {0-9}" - указываем уровень сжатия (0 — минимальный, 9 — максимальный) при архивировании.

В режиме по умолчанию данные в резервной копии сохраняются для отрабатывания с помощью инструкции "COPY". Это гораздо быстрее, чем использование "INSERT", хотя и чревато полным сбоем восстановления таблицы в случае малейшей ошибки в теле файла резервной копии. Ситуация с выбором между инструкциями интересная: с одной стороны, при восстановлении много-гигабайтного файла применение инструкции "COPY" сэкономит часы ожидания, а с другой стороны - очень обидно будет из-за мелкой ошибки в одной ячейке таблицы обрести проблемы со всей базой. Думаю, что до объёмов базы в два-три гигабайта можно побаловаться "COPY", потом придёт время думать о надёжности, пусть и в ущерб времени, а после того, как размер базы зашкалит за сотню гигабайт, банальное восстановление из резервной копии вообще уже не будет рассматриваться как вариант.

Процедура создания резервной копии данных может быть долгой и зависит, в основном, от уровня производительности дисковой подсистемы; пока СУБД прочитает записи по запросу с диска, пока отдаст их утилите, да пока та их запишет снова на диск. На моей практике резервирование базы объёмом в пару гигабайт на машине с процессором "Pentium 4" и IDE дисками заняло около получаса. При этом загрузка процессора в среднем составляла 70-80%, расход оперативной памяти не поражал воображение.

Передаем получившиеся файлы "дампа" на удалённый компьютер, хотя бы с использованием SCP:

# scp "./file-name-data.sql.gz" user@remote_host:/target-dir/

Следующим шагом важно принять меры к тому, чтобы срок восстановления данных не стал исчисляется в сутках - временно откажемся от создания индексов к таблицам; иначе пересчёт таковых при каждой вставке порции данных сделает наш процесс оч-ч-чень затяжным.

Вырежем из файла резервной копии структуры данных "file-name-structure.sql" инструкции создающие и преобразующие индексы (ищем блоки по ключевым словосочетаниям "CREATE INDEX" и "ALTER INDEX") и вынесем их в отдельный SQL-сценарий "file-name-structure-indexes.sql", который применим позже, уже после восстановления данных. Сценарий для восстановления индексов будет выглядеть примерно следующим образом:

# cat ./file-name-structure-indexes.sql

--
-- PostgreSQL database custom dump
--
SET client_encoding = 'UTF8';
SET standard_conforming_strings = off;
SET check_function_bodies = false;
SET client_min_messages = warning;
SET escape_string_warning = off;
SET search_path = public, pg_catalog;
....
--
-- TOC entry 2635 (class 1259 OID 16779)
-- Dependencies: 1668
-- Name: acknowledges_1; Type: INDEX; Schema: public; Owner: zabbix; Tablespace:
--
CREATE INDEX acknowledges_1 ON acknowledges USING btree (userid);
....
--
-- TOC entry 2773 (class 1259 OID 17483)
-- Dependencies: 1712
-- Name: valuemaps_1; Type: INDEX; Schema: public; Owner: zabbix; Tablespace:
--
CREATE INDEX valuemaps_1 ON valuemaps USING btree (name);
....
--
-- PostgreSQL database custom dump complete
--

Восстанавливаем структуру базы данных:

# cat "./file-name-structure.sql" | psql --username zabbix zabbix 2> "./file-name-structure-error.log" 1> "./file-name-structure-access.log"

Теперь внесём данные. Учитывая то, что при создании резервной копии данных мы использовали архивирование, просто передать файл в качестве потока команд клиенту Postgres не выйдет (требуется промежуточная распаковка), проще воспользоваться умелой утилитой "pg_resore":

# pg_restore --verbose --exit-on-error --data-only --dbname="zabbix" --username="postgres" ./file-name-data.sql.gz

Примерный вид журнала событий утилиты восстановления pg_restore:

pg_restore: connecting to database for restore
pg_restore: executing SEQUENCE SET history_str_sync_id_seq
....
pg_restore: executing SEQUENCE SET proxy_history_id_seq
pg_restore: restoring data for table "acknowledges"
pg_restore: restoring data for table "actions"
....
pg_restore: restoring data for table "config"
....

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

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

# cat "./file-name-structure-indexes.sql" | psql --username zabbix zabbix 2> "./file-name-structure-indexes-error.log" 1> "./file-name-structure-indexes-access.log"

Создание индексов к данным большого объёма - операция весьма активного характера. И диски пошумят и процессор при этом погреется. Ещё час на гигабайт.

Убедимся в том, что клавиши нажимались не зря и строчки на экране не просто так мелькали, проверим, восстановились ли данные базы:

# psql -U zabbix

zabbix=> \dt

Schema |         Name  | Type  | Owner
-------+---------------+-------+--------
public | acknowledges  | table | zabbix
public | actions       | table | zabbix
public | alerts        | table | zabbix
public | applications  | table | zabbix
....
public | triggers      | table | zabbix
public | users         | table | zabbix
public | users_groups  | table | zabbix
public | usrgrp        | table | zabbix
public | valuemaps     | table | zabbix
....

zabbix=> \q

Теперь применим набор SQL-запросов от разработчиков, что изменят структуру и данные нашей базы данных до вида применимого в новой версии Zabbix. "Патч" мы получили с набором исходных кодов сервера Zabbix. Просто применим его:

# cat "/usr/src/zabbix-2.0.5/upgrades/dbpatches/2.0/postgresql/patch.sql" | psql --username zabbix zabbix 2> "./patch.error.log" 1> "./patch.access.log"

В дистрибутивном наборе Zabbix v.2.0.5 я обнаружил три набора "патчей", в отдельных директориях с названиями "1.6", "1.8" и "2.0". В документации от разработчиков особо отмечено, что для актуализации структуры баз данных Zabbix версий "1.6" необходимо вначале обновить их до версии "1.8", а уже потом запускать обновление до версии "2.0". Я понял это так:

"патч" из директории "1.6" следует запускать для актуализации "баз" версии младше "1.6" до финальной версии этой самой версии "1.6";
"патч" из директории "1.8" запускать для "баз" версий финальной "1.6" или перечня промежуточных версий "1.8" с целью обновить "базы" линейки "1.6" до "1.8" или актуализировать "базы" промежуточных версий "1.8" до финальной версии "1.8";
"патч" из директории "2.0" запускать для "баз" версий финальной "1.8" или перечня промежуточных версий "2.0" с целью обновить "базы" линейки "1.8" до "2.0" или актуализировать "базы" промежуточных версий "2.0" до финальной версии "2.0".

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

Вот, собственно, и всё. Можно запустить Zabbix сервер, зайти на "web"-панель управления и получить обновлённую систему мониторинга.

И да, для тех, кто вначале читает, а потом делает - для переноса только настроек системы мониторинга, без накопленных данных, достаточно просто экспортировать конфигурацию в виде XML-файла и импортировать её на обновлённом сервере с помощью специального web-инструмента в панели управления Zabbix сервера:

"Configuration" => "Export/Import" => "Export" => "All"

"Configuration" => "Export/Import" => "Import" => "All"

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


Заметки и комментарии к публикации:


Оставьте свой комментарий ( выразите мнение относительно публикации, поделитесь дополнительными сведениями или укажите на ошибку )