Миграция данных из Greenplum 6 в MatrixDB 4

Данный раздел документации в основном охватывает лучшие практики миграции данных из Greenplum 6 в MatrixDB 4.

1. Подготовка среды

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

Номер Шаги подготовки Инструкции Опционально
1 Резервное копирование данных кластера источника Миграция данных выполняет только чтение из кластера источника, без записи, поэтому не несёт риска повреждения данных в результате миграции Да
2 Установка и развертывание целевого программного обеспечения базы данных Нет, обязательный шаг
3 Развертывание мониторинга для целевого кластера Зависит от требований Да
4 Запретить все DDL-операции на стороне бизнеса Этот шаг важен и может создать риски для процесса миграции. Отнеситесь к нему серьёзно. Нет, обязательный шаг
5 Прервать все бизнес-подключения Нет, обязательный шаг
6 Сбор информации о кластере источника и целевом кластере Информация о программном и аппаратном обеспечении, топология кластера источника, топология целевого кластера и т.д. Нет, обязательный шаг
7 Резервное копирование исходной информации кластера источника DDL, имена схем, информация о пользователях и т.д. Нет, обязательный шаг
8 Исправление или оптимизация DDL Исправление — адаптация DDL-заявлений между Greenplum 6 и MatrixDB 4 для решения проблем совместимости (если это миграция данных из MatrixDB 4 в MatrixDB 4, исправление не требуется); оптимизация — максимально возможное улучшение производительности базы данных с самого начала Нет, обязательный шаг
9 Генерация SQL-файла для изменения полей таблиц Да
10 Добавление белого списка на все узлы кластера источника и целевого кластера Нет, обязательный шаг
11 Создание пользователя для целевого кластера Нет, обязательный шаг
12 Восстановление структуры таблиц Нет, обязательный шаг
13 Создание DDL для целевого кластера В MatrixDB эффективнее пересоздавать индексы после завершения операции миграции. Поэтому при создании DDL для целевого кластера до миграции рекомендуется создавать инструкции без индексов Нет, обязательный шаг
14 Изменение таблиц на C-символьный набор Да

На основе приведённой таблицы мы приводим конкретные примеры.

1.1 Резервное копирование данных кластера источника

Миграция данных выполняет только операции чтения и не записывает данные в кластер источника, поэтому не несёт риска повреждения данных в результате миграции. Однако, если вы всё ещё обеспокоены или имеете другие бизнес-требования, требующие сохранения данных, вы можете использовать инструмент mxbackup для параллельного резервного копирования кластера.

1.2 Установка и развертывание целевого программного обеспечения базы данных

Примечание!
Рекомендуем не развертывать зеркальные узлы (Mirrors) при развертывании кластера, а добавлять их после завершения миграции для повышения эффективности миграции.

Примечание!
Имена хостов целевого кластера не должны совпадать с именами хостов кластера источника!

См. стандартную документацию по развертыванию кластера:

1.3 Развертывание мониторинга для целевого кластера

См. документацию по мониторингу и оповещениям:

1.4 Запретить все DDL-операции на стороне бизнеса

Примечание!
До официальной остановки всех сервисов на стороне бизнеса сервис кластера Greenplum 6 не должен выполнять никаких DDL-операций, включая создание объектов, изменение объектов, добавление или удаление полей, а также запрещать выполнение операторов CREATE, ALTER, TRUNCATE и DROP.

1.5 Прервать все бизнес-подключения

Измените файл pg_hba.conf на мастере кластера Greenplum 6.

$ vim  pg_hba.conf

Добавьте адреса клиентов бизнеса в следующем формате, чтобы отключить удалённый доступ.

host     all         all         <Client IP Address>/<Subnet Mask Bits>       reject

Затем перезагрузите конфигурацию, чтобы применить изменения:

$ gpstop -u

1.6 Сбор информации о кластере источника и целевом кластере

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

Номер Команда Цель
1 free -g Просмотр информации о памяти операционной системы
2 lscpu Просмотр количества процессоров
3 cat /etc/system-release Просмотр версии операционной системы
4 uname -a Вывод всей информации ядра в следующем порядке (результаты -p и -i опущены, если они неопределённы): имя ядра; имя хоста в сети; номер выпуска ядра; версия ядра; имя аппаратной архитектуры хоста; тип процессора (не переносимо); аппаратная платформа или (не переносимо); имя операционной системы
5 tail -11 /proc/cpuinfo Просмотр информации о процессоре
6 gpcheckperf Проверка производительности сети, пропускной способности, дискового ввода-вывода

1.7 Резервное копирование исходной информации кластера источника

Под пользователем gpadmin используйте инструмент pg_dump для резервного копирования DDL, имён схем, информации о пользователях и т.д. кластера Greenplum 6.

# Backup global user objects
pg_dumpall -g -f global_user.sql

# Backup table structure
pg_dump <Source Database Name> -s -f orig.sql          

# Copy a backup
cp orig.sql copy.sql                        

Генерирует SQL-файл создания индексов.

$ cat get_index.sql 
WITH soi (oid, toid, SIZE, tschema, tname) AS
  ( SELECT soioid,
           soitableoid,
           soisize,
           soitableschemaname,
           soitablename
   FROM gp_toolkit.gp_size_of_index ),
     childrel (oid, coid)AS
  ( SELECT pp.parrelid,
           ppr.parchildrelid
   FROM pg_partition pp
   INNER JOIN pg_partition_rule ppr ON pp.oid = ppr.paroid ),
     irn (oid, toid, SIZE, tschema, tname, rn) AS
  ( SELECT *,
           row_number() OVER (
            ORDER BY dt.ssize DESC) rn
   FROM
     ( SELECT soi.oid,
              soi.toid ,
              sum(coalesce(dt2.SIZE, soi.SIZE)) ssize ,
                                                soi.tschema,
                                                soi.tname
      FROM soi
      LEFT JOIN
        ( SELECT childrel.oid,
                 soi.SIZE
         FROM soi
         INNER JOIN childrel ON soi.toid = childrel.coid ) dt2 ON soi.toid = dt2.oid
      GROUP BY 1,
               2,
               4,
               5 ) dt )
SELECT SQL || ';'
FROM
  ( SELECT pg_get_indexdef(oid) AS SQL ,
           (rn % 12 + (rn / 12)::int) % 12 AS orderkey
   FROM irn
   WHERE toid NOT IN
       (SELECT coid
        FROM childrel) ) dt
WHERE SQL NOT LIKE 'CREATE UNIQUE INDEX%'
ORDER BY dt.orderkey ;

Выполните вышеуказанный SQL через psql.

psql -d <Source Database Name> -U <Source database super username> -t -f get_index.sql > index.sql

1.8 Исправление или оптимизация DDL

Исправление — адаптация DDL-заявлений Greenplum 6 и MatrixDB для решения проблем совместимости (если это миграция данных из MatrixDB в MatrixDB, исправление не требуется); оптимизация — максимально возможное повышение производительности базы данных с самого начала. В настоящее время mxshift не поддерживает автоматическое исправление DDL. Ниже приведён пример ручного исправления или оптимизации, выполняемого в среде кластера Greenplum 6:

# Modify the compression algorithm
sed -i 's/quicklz/zstd/g' orig.sql   

# Modify the plpython version
sed -i 's/plpythonu/plpython3u/g' orig.sql     

# Added the creation plugin syntax
sed -i '1s/^/create language plpython3u;/' orig.sql  ####

# Delete index creation statement
sed -i -e '/CREATE INDEX.*;/d' -e '/CREATE INDEX/,/;/d' orig.sql  

# Optimized compression algorithm
sed -i 's/compresstype=zlib/compresstype=zstd/g' orig.sql  

# Modify compression level
sed -i 's/compresslevel=5/compresslevel=1/g' orig.sql        

Для вышеуказанных исправлений или оптимизаций даны следующие конкретные пояснения:

  • Изменение алгоритма сжатия. MatrixDB не поддерживает алгоритм сжатия quicklz.
  • Изменение версии plpython. MatrixDB поддерживает зависимости plpython3.
  • Добавление синтаксиса создания расширения. В MatrixDB необходимо создать некоторые расширения.
  • Удаление инструкции индекса. Если создавать DDL в целевой базе с индексом, эффективность миграции значительно снизится из-за увеличения числа сканирований. Рекомендуется сначала удалить инструкцию индекса, создать новую таблицу, а затем пересоздать индекс после завершения миграции.
  • Оптимизация алгоритма сжатия. В MatrixDB предпочтительнее использовать алгоритм сжатия zstd.
  • Изменение уровня сжатия. В MatrixDB лучше использовать уровень сжатия 1.

1.9 Генерация SQL-файлов для изменения полей таблиц

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

$ cat collate.sql
SELECT 'alter table '||quote_ident(b.schemaname)||'.'||quote_ident(b.tablename)||' alter column '||quote_ident(b.colname)||' type '||d.coltype||' COLLATE "pg_catalog"."C";'
FROM
  (SELECT DISTINCT a.schemaname,
                   a.tablename,
                   regexp_split_to_table(replace(a.keyindex,' ',''),',') AS colname
   FROM
     (SELECT schemaname,
             tablename,
             rtrim(split_part(indexdef,'(',2),')') AS keyindex,
             indexdef
      FROM pg_indexes
      WHERE schemaname NOT IN ('pg_catalog')
        AND indexname NOT LIKE '%pkey'
        AND indexdef LIKE 'CREATE INDEX%') a) b
INNER JOIN
  (SELECT c.oid,
          n.nspname,
          c.relname
   FROM pg_catalog.pg_class c
   LEFT JOIN pg_catalog.pg_namespace n ON n.oid = c.relnamespace) c ON b.schemaname=c.nspname
AND c.relname=b.tablename
INNER JOIN
  (SELECT e.attrelid,a.attname, pg_catalog.format_type(a.atttypid, a.atttypmod) AS coltype,
     (SELECT substring(pg_catalog.pg_get_expr(d.adbin, d.adrelid)
                       FOR 128)
      FROM pg_catalog.pg_attrdef d
      WHERE d.adrelid = a.attrelid
        AND d.adnum = a.attnum
        AND a.atthasdef), a.attnotnull,
                          a.attnum
   FROM pg_catalog.pg_attribute a
   LEFT OUTER JOIN pg_catalog.pg_attribute_encoding e ON e.attrelid = a .attrelid
   AND e.attnum = a.attnum
   WHERE a.attnum >0) d ON d.attrelid=c.oid
AND d.attname=b.colname;

1.10 Добавление белого списка для всех узлов кластера источника и целевого кластера

Примечание!
Если кластер источника и целевой кластер работают на одном сервере, просто пропустите этот шаг.

На мастере кластера источника и целевого кластера выполните следующую команду, чтобы добавить IP-адреса всех узлов кластера источника и целевого кластера в файл pg_hba.conf. IP-адрес и маска подсети в примере — 172.16.100.2/32 и 172.16.100.3/32.

Примечание!
Если имеется несколько хостов, необходимо записать все IP-адреса хостов в скрипт.

$ cat  config_hba.sh 

#!/bin/bash
for line  in `psql -Atc "select hostname||','|| datadir
from gp_segment_configuration order by 1 desc"`
do
hostname=`echo $line|awk -F "," '{print $1}'`
datadir=`echo $line|awk -F "," '{print $2}'`
gpssh -h $hostname -v -e "echo host    all    all    172.16.100.2/32    md5>> ${datadir}/pg_hba.conf"
gpssh -h $hostname -v -e "echo host    all    all    172.16.100.3/32    md5>> ${datadir}/pg_hba.conf"

done

In the source cluster and the target cluster master, execute the following command to add the host IP address and host name of all nodes of the source cluster and the target cluster to the /etc/hosts file. In the example, the host IP address is 172.16.100.195 and the host name is sdw1.

$ cat add_hosts.sh

!/bin/bash

for line in psql -Atc "select distinct hostname from gp_segment_configuration order by 1 desc" do gpssh -h $hostname -v -e "echo 172.16.100.195 sdw1 >> /etc/hosts"

done

Then reload the configuration to make the modified configuration file take effect

$ gpstop -u

### 1.11 Create a user for the target cluster
Execute the following command in a MatrixDB cluster environment.

$ psql -h -p -d -U -f global_user.sql

### 1.12 Create DDL for the target cluster
Execute the following command in a MatrixDB cluster environment.

$ psql -h -p -d -U -f orig.sql

### 1.13 Restore table structure
Use the backup orig.sql file to restore the table structure in the target cluster MatrixDB.

$ time psql -d -f orig.sql > restoreddl.log 2>&1 &

### 1.14 Modify the table to C sort character set

$ time psql -d -f collate.sql

## 2 Migration execution
> ***Notes!***  
For detailed parameters, please refer to [mxshift](/ru/doc/4.8/tools/mxshift)

First write the configuration file config_path.toml.

[database] [database.source]

Имя базы данных

    db-database= "testdb"
    ## Имя хоста мастера базы данных
    db-host="sdw3"
    ## Пароль базы данных
    db-password="xxxx"
    ## Порт мастера базы данных
    db-port=54322
    ## Имя пользователя базы данных
    db-user="gpadmin"

[database.target]
    ## Имя базы данных
    db-database="destdb"
    ## Имя хоста мастера базы данных
    db-host="172.16.100.32"
    ## Пароль базы данных
    db-password="yyyy"
    ## Порт мастера базы данных
    db-port=5432
    ## Имя пользователя базы данных
    db-user="mxadmin"

[scope] compress_method="lz4" gphome="/usr/local/greenplum-db-6.7.1" mode="normal" [[scope.table-list]] schema="test_schema_1" name="table_001" [[scope.table-list]] schema="test_schema_2" name="table_002"

    [[scope.exclude-table-list]]
            schema="test_schema_3"
            name="table_003"

     schema-list=["test_schema_1", "test_schema_2"]
     exclude-schema-list=["test_schema_5", "test_schema_8"]

[log] log-level="info"

Выводить лог без цвета.

no-color=false

[controller] both-way=true concurrency=5

[transfer] verify=true [transfer.table-data-where-sql] enabled=false global="txdate >= '2022-10-01' AND batchnum >= 100000000" [[transfer.table-data-where-sql.override]] where="abc > 10" [transfer.table-data-where-sql.override.table] schema="test_schema_1" name="table_001" [[transfer.table-data-where-sql.override]] where="tag != 'aabbcc' AND ts > '2022-01-01'" [transfer.table-data-where-sql.override.table] schema="test_schema_2" name="another_table"

[ddl] enabled=true

file-path="/tmp/mxshift.sql"

mode="output"

only-ddl=false

Во время передачи DDL, пропускать ли передачу очереди или группы ресурсов, по умолчанию — true.

skip-resource-queue-and-group=true

При передаче DDL следует пропускать передачу табличных пространств; по умолчанию — true.

skip-table-space=true

    [[ddl.replace]]  
    ## Применимо только для миграции из Greenplum в YMatrix  
            category="role"  
            [[ddl.replace.pairs]]  
                    old="gpadmin"  
                    new="mxadmin"      
The data migration is then performed on the target MatrixDB cluster.

$ mxshift -c config_path.toml

## 3 Follow-up tasks
### 3.1 Execute to create an index
Perform the creation of an index on the target cluster MatrixDB.

$ psql -h localhost -p -d -U -f index.sql >>idx.out 2>&1 &

### 3.2 Execute the analyzedb command
Update the library statistics on the target cluster MatrixDB.

$ export PGPORT=
time analyzedb -d -p 10 -a

### 3.3 Adding Mirror
Add Mirror on the target cluster MatrixDB. The steps are as follows:

Сначала проверьте текущую информацию о экземплярах кластера

postgres=# SELECT * from gp_segment_configuration order by 1;
dbid | content | role | preferred_role | mode | status | port | hostname | address | datadir
-----+-----------+------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
1 | -1 | p | p | n | u | 5432 | mdw | mdw | /home/mxdata_20220925154450/master/mxseg-1
2 | 0 | p | p | n | u | 6000 | sdw2 | sdw2 | /home/mxdata_20220925154450/primary/mxseg0
3 | 1 | p | p | n | u | 6001 | sdw2 | sdw2 | /home/mxdata_20220925154450/primary/mxseg1
4 | 2 | p | p | n | u | 6000 | sdw3 | sdw3 | /home/mxdata_20220925154450/primary/mxseg2
5 | 3 | p | p | n | u | 6001 | sdw3 | sdw3 | /home/mxdata_20220925154450/primary/mxseg3
6 | -1 | m | m | s | u | 5432 | sdw1 | sdw1 | /home/mxdata_20220925154450/standby/mxseg-1
(6 rows)

Создайте файл со всеми именами хостов

$ cat /home/mxadmin/seg_hosts
sdw1
sdw2
sdw3
sdw4

Пакетное добавление директорий Mirror с помощью команды gpssh

$ gpssh -f /home/mxadmin/seg_hosts -e 'mkdir -p /home/mxdata_20220925154450/mirror'

Сгенерируйте шаблонный файл Mirror

$ gpaddmirrors -o ./addmirror

Просмотрите шаблонный файл Mirror

$ cat addmirror

Выполните операцию добавления Mirror

$ gpaddmirrors -i addmirror

Наконец, снова проверьте конфигурацию экземпляров кластера

postgres=# SELECT * from gp_segment_configuration order by 1;
dbid | content | role | preferred_role | mode | status | port | hostname | address | datadir
-----+-----------+------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
1 | -1 | p | p | n | u | 5432 | mdw | mdw | /home/mxdata_20220925154450/master/mxseg-1
2 | 0 | p | p | n | u | 6000 | sdw2 | sdw2 | /home/mxdata_20220925154450/primary/mxseg0
3 | 1 | p | p | s | u | 6001 | sdw2 | sdw2 | /home/mxdata_20220925154450/primary/mxseg1
4 | 2 | p | p | s | u | 6000 | sdw3 | sdw3 | /home/mxdata_20220925154450/primary/mxseg2
5 | 3 | p | p | s | u | 6001 | sdw3 | sdw3 | /home/mxdata_20220925154450/primary/mxseg3
6 | -1 | m | m | s | u | 5432 | sdw1 | sdw1 | /home/mxdata_20220925154450/standby/mxseg-1
7 | 0 | m | m | n | d | 7000 | sdw3 | sdw3 | /home/mxdata_20220925154450/mirror/mxseg0
8 | 1 | m | m | s | u | 7001 | sdw3 | sdw3 | /home/mxdata_20220925154450/mirror/mxseg1
9 | 2 | m | m | s | u | 7000 | sdw2 | sdw2 | /home/mxdata_20220925154450/mirror/mxseg2
10 | 3 | m | m | s | u | 7001 | sdw2 | sdw2 | /home/mxdata_20220925154450/mirror/mxseg3
(10 rows)
``

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