Кластер Greenplum разрушен — экспорт данных посегметно

Возможна такая ситуация, когда у нас данные уже невозможно получить данные из кластера Greenplum. Например, кластер не стартует в обычном режиме. Тогда мы можем попытаться восстановить данные с каждого сегмента.

Техника получения данных с одного сегмента Greenplum следующая.

Если у нас не целостный кластер и мы каким-то образом хотим получить данные с отдельного инстанса, следует сделать следующее

Если кластер запускается хотя бы в master-only режиме (gpstart -m) — для удобства вытащить информацию о сегментах:

SELECT content, role, hostname, port, datadir FROM gp_segment_configuration;

Если кластер запущен — погасить кластер командой gpstop -a -M fast

Подключение к нужному сегменту Greenplum:

Заходим под пользователем gpadmin по ssh на хост hostname.

Запускаем отдельный инстанс сегмента, используя знания о datadir (пусть в примере datadir была равна '/data1/primary/gpseg0')

pg_ctl start -D /data1/primary/gpseg0

Теперь мы может подключиться к экземпляру в utility mode — используя знания о port (пусть в примере port был равен 6003).

Подключаемся к требуемой базе (в примере testdb).

PGOPTIONS='-c gp_session_role=utility' psql testdb -p 6003

В этом интерактивном сеансе мы можем убедиться, что требуемая таблица (скажем, tb_test1) целостная:

-- число записей
select count(*) from tb_test1;
-- fullscan вынудит сервер обратиться к каждой из строк данных и таким образом, если они повреждены данные, мы увидим тут ошибку
explain select * from tb_test1; 

Экспорт данных

Если мы не видим ошибок — видимо, данная таблица на данном сегменте в целостности. Эту часть таблицы можно экспортировать из экземпляра, например, в текстовый файл, чтобы потом его залить какую-либо действующую базу, имеющую примененный соответствующий DDL рассматриваемой таблицы (CREATE TABLE tb_test1 … в примере)

Произведем экспорт данных сегмента Greenplum. Для этого выйдем из psql и применим команду shell пакетно, с перенаправлением вывода в файл:

PGOPTIONS='-c gp_session_role=utility' psql testdb -p 6003 -c "COPY tb_test1 TO STDOUT (DELIMITER E'\t');" > /data/dump/tb_test1.txt

Разумеется, каталог /data/dump/ должен быть создан, и на нём должно быть достаточно места.

После того как данные успешно скопируются — необходимо остановить экземпляр командой 

pg_ctl stop -D /data1/primary/gpseg0

Импорт данных в новую базу Greenplum

Здесь мы работаем на кластере, запущенном в штатном режиме.

В базе, на которой мы хотим восстановить данные, должен быть применен соответствующий DDL таблицы (CREATE TABLE, соответствующий исходному).

Мы коннектимся psql к новой базе psql new_db

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

COPY tb_test1 FROM '/data/dump/tb_test1.txt' (DELIMITER E'\t');

После чего убеждаемся в корректности данных (число строк и т.п.)

Какие могут быть сложности?

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

Недостаточное количество места файловой системе. AO таблицы могут храниться с определенным режимом сжатия, и выходной файл при показанной техники может быть весьма большим. Тогда можно применить сжатие, используя внешнюю команду сжатия. Соответственно, это может загрузить процессор и замедлить процесс копирования. Если следовать этому методу, то команды экспорта и импорта будут такие (это команды в сессии psql в соответствующих базах).

Экспорт из отдельно запущенного инстанса:

COPY tb_test1 TO PROGRAM 'gzip > /data/dump/tb_test1.gz' DELIMITER E'\t';

Импорт на кластере в новую базу:

COPY tb_test1 FROM PROGRAM 'gzip -dc /data/dump/tb_test1.gz' DELIMITER E'\t';

Добавить комментарий

Ваш адрес email не будет опубликован.