Миграция данных из Greenplum 4.3.X/5/6 в YMatrix 5

Документ описывает лучшие практики миграции данных из Greenplum 4.3.X/5/6 в YMatrix 5.

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

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

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

Ниже приведены подробные примеры для каждого шага.

1.1 Создание резервной копии данных кластера источника (необязательно)

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

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

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

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

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

1.3 Развертывание мониторинга целевого кластера (необязательно)

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

1.4 Отключение всех DDL-операций в бизнес-приложениях

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

1.5 Завершение всех бизнес-подключений

На Master-узле исходного кластера Greenplum отредактируйте файл pg_hba.conf.

$ vim pg_hba.conf

Добавьте IP-адреса клиентов в следующем формате для отключения удаленного доступа:

host     all         all         <Client IP Address>/<CIDR Mask>       reject

Перезагрузите конфигурацию для применения изменений:

$ gpstop -u

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

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

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

1.7 Создание резервной копии метаданных кластера источника

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

# Back up global user objects
pg_dumpall -g -f global_user.sql

# Back up table structures
pg_dump <source_database_name> -s -f orig.sql          

# Make a copy for 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 <superuser_name> -t -f get_index.sql > index.sql

1.8 Настройка или оптимизация DDL (необязательно)

mxshift теперь поддерживает автоматическую миграцию DDL. См. раздел "2 Выполнение миграции" для использования. Ниже описаны ручные корректировки.

Корректировки устраняют несовместимости между синтаксисом DDL Greenplum и YMatrix (не требуются при миграции из YMatrix 4 в YMatrix 5). Оптимизация направлена на достижение наилучшей производительности с самого начала. Примеры команд для выполнения на исходном кластере Greenplum:

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

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

# Add extension creation syntax
sed -i '1s/^/create language plpython3u;/' orig.sql  

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

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

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

Пояснение:

  • Смена алгоритма сжатия: YMatrix не поддерживает quicklz.
  • Обновление версии plpython: YMatrix поддерживает plpython3u.
  • Добавление синтаксиса создания расширений: Необходимо для создания расширений в YMatrix.
  • Удаление инструкций создания индексов: Создание индексов при создании таблиц увеличивает количество сканирований и снижает эффективность миграции. Лучше сначала создать таблицы, затем мигрировать данные, и только потом добавить индексы.
  • Оптимизация алгоритма сжатия: В YMatrix предпочтителен zstd.
  • Настройка уровня сжатия: Уровень 1 является оптимальным в YMatrix.

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 Добавление записи в белый список на Master кластера источника

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

На Master кластера источника добавьте IP-адрес Master целевого кластера в файл pg_hba.conf. Пример с IP 172.16.100.2:

host    all    all    172.16.100.2    md5

На Master целевого кластера запустите следующий скрипт для добавления IP и имени хоста кластера источника (172.16.100.195, sdw1) в файл /etc/hosts:

$ cat add_hosts.sh 
#!/bin/bash
for line in `psql -Atc "select distinct  hostname from gp_segment_configuration order by datadir desc"`
do
    gpssh -h $hostname -v -e "echo 172.16.100.195 sdw1 >> /etc/hosts"
done

Перезагрузите конфигурацию для применения изменений.
Для Greenplum выполните gpstop:

$ gpstop -u

Для YMatrix 5 выполните mxstop:

$ mxstop -u

1.11 Создание пользователей на целевом кластере

Запустите следующую команду в среде YMatrix:

$ psql -h <YMatrix_Server_IP> -p <target_port> -d <target_db> -U <target_superuser> -f global_user.sql

1.12 Создание DDL на целевом кластере (необязательно)

Запустите в среде YMatrix:

$ psql -h <YMatrix_Server_IP> -p <target_port> -d <target_db> -U <target_superuser> -f orig.sql 

1.13 Восстановление структуры таблиц (необязательно)

Используйте резервную копию файла orig.sql для восстановления структуры таблиц на целевом кластере YMatrix:

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

1.14 Изменение сортировки таблиц на C (необязательно)

$ time psql -d <target_db_name> -f collate.sql  

2 Выполнение миграции

Примечание!
Подробные параметры mxshift см. в документации mxshift.

Сначала создайте конфигурационный файл config_path.toml. Пример:

[database]
        [database.source]
        ## Name of database
        db-database= "testdb"
        ## Hostname of database master
        db-host="sdw3"
        ## password of database
        db-password="xxxx"
        ## Port of database master
        db-port=54322
        ## user name of database
        db-user="gpadmin"
        ## Version of database(Please use the result of 'SELECT version();' as value). Required only when
        ##       1. Source database is un-reachable, and 'ddl.only-ddl' is enabled and 'ddl.mode' is 'input'
        ##       2. Target database is un-reachable, and 'ddl.mode' is 'output' */
         # db-version="PostgreSQL 12 (MatrixDB 5.2.0-enterprise) (Greenplum Database 7.0.0+dev.17410.gedbdb5ef84 build dev) on arm-apple-darwin21.5.0, compiled by Apple clang version 13.0.0 (clang-1300.0.27.3), 64-bit compiled on Jun  5 2023 15:45:24"
         ## The installation directory of matrixdb
         install-dir="/usr/local/greenplum-db-6.7.1"
         [[database.source.hostname-to-ip]]
             ## Replace content within <> with actual values and remove <>
             node-hostname="<mdw>" 
             node-ip="<127.0.0.1>"
         [[database.source.hostname-to-ip]]
             node-hostname="<sdw1>"
             node-ip="<127.0.0.2>"
         [[database.source.hostname-to-ip]]
             node-hostname="<sdw2>"
             node-ip="<127.0.0.3>"

        [database.target]
        ## Name of database
        db-database="destdb"
        ## Hostname of database master
        db-host="172.16.100.32"
        ## password of database
        db-password="yyyy"
        ## Port of database master
        db-port=5432
        ## user name of database
        db-user="mxadmin"
        ## Version of database(Please use the result of 'SELECT version();' as value). Required only when
        ##       1. Source database is un-reachable, and 'ddl.only-ddl' is enabled and 'ddl.mode' is 'input'
        ##       2. Target database is un-reachable, and 'ddl.mode' is 'output' */
         # db-version="PostgreSQL 12 (MatrixDB 5.2.0-enterprise) (Greenplum Database 7.0.0+dev.17410.gedbdb5ef84 build dev) on arm-apple-darwin21.5.0, compiled by Apple clang version 13.0.0 (clang-1300.0.27.3), 64-bit compiled on Jun  5 2023 15:45:24"

[scope]
## Compression method for data transfer; allowed values: 0/gzip/lz4/zstd        
compress-method="lz4"
## Mode for transferring data from source to target; allowed values: normal/dryrun/fetch/motion.
## dryrun: execute DDL only, no data transfer
## fetch: fetch data from source and discard
## motion: fetch data, redistribute, then discard
mode="normal"
## SQL to select segment info from source database        
# select-source-segment-sql="SELECT dbid, content, port, hostname FROM gp_segment_configuration WHERE status = 'u' AND role = 'p' ORDER BY CONTENT;"
## SQL to select segment info from target database
# select-target-segment-sql="SELECT dbid, content, port, hostname FROM gp_segment_configuration WHERE status = 'u' AND role = 'p' ORDER BY CONTENT;"
        [[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"]
## Whether to disable incremental data migration; default is true.
# disable-data-increment=true

[log]
## Log level: debug/verbose/info.
log-level="info"
## Print log without color.
# no-color=false

[controller]
## By default, transfer starts from largest table. If set to 'bothway', starts from both largest and smallest.
both-way=true
## Number of tables to transfer concurrently
concurrency=3

[transfer]
## Verify record count for each table
verify=true
with-index=true

[ddl]
enabled=true
# file-path="/tmp/mxshift.sql"
# mode="output"
only-ddl=false
## During DDL transfer, skip resource queue/group? Default is true.
# skip-resource-queue-and-group=true
## During DDL transfer, skip tablespace? Default is true.
# skip-table-space=true
        [[ddl.replace]]
        ## Only applicable for Greenplum to YMatrix migration
                category="role"
                [[ddl.replace.pairs]]
                        old="gpadmin"
                        new="mxadmin"
## Whether to disable incremental DDL migration; default is true.
# disable-ddl-increment=true   

Затем выполните миграцию на целевом кластере YMatrix:

$ mxshift -c config_path.toml

3 Задачи после миграции

3.1 Создание индексов (необязательно)

Создайте индексы на целевом кластере YMatrix:

psql -h localhost -p <target_port> -d <target_db_name> -U mxadmin -f index.sql >>idx.out 2>&1 &

3.2 Запуск analyzedb

Обновите статистику для всей базы данных на целевом кластере YMatrix:

export PGPORT=<target_port>
time analyzedb -d <target_db_name> -p 10 -a 

3.3 Добавление зеркальных сегментов

Добавьте зеркальные сегменты на целевой кластер YMatrix. Процедура следующая:

# First, view the current cluster instance information
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)

# Create a file containing all hostnames
$ cat /home/mxadmin/seg_hosts 
sdw1
sdw2
sdw3
sdw4

# Use gpssh to create mirror directories in batch
$ gpssh -f /home/mxadmin/seg_hosts -e 'mkdir -p /home/mxdata_20220925154450/mirror'

# Generate the mirror configuration template file
$ mxaddmirrors -o ./addmirror

# View the generated mirror template file
$ cat addmirror

# Execute the command to add mirrors
$ mxaddmirrors -i addmirror

# Finally, check the cluster instance again
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)

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