Документ описывает лучшие практики миграции данных из Greenplum 4.3.X/5/6 в YMatrix 5.
Перед выполнением любых значимых операций крайне важно тщательно подготовиться — как с технической, так и с психологической точки зрения (так как проблемы могут возникнуть в любой момент). Хотя психологическая готовность индивидуальна, мы предоставляем подробный чек-лист для технической настройки. Некоторые шаги являются необязательными:
| № | Шаг подготовки | Описание | Необязательно |
|---|---|---|---|
| 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 | Добавить белые списки для всех узлов кластеров источника и назначения | Нет, обязательно | |
| 11 | Создать пользователей на целевом кластере | Нет, обязательно | |
| 12 | Восстановить структуры таблиц | Да, mxshift поддерживает автоматическую миграцию индексов — см. mxshift |
|
| 13 | Создать DDL на целевом кластере | В YMatrix эффективнее создавать индексы после миграции данных. Поэтому при создании DDL до миграции исключите инструкции создания индексов. | Да, mxshift поддерживает автоматическую миграцию DDL — см. mxshift |
| 14 | Изменить сортировку столбцов таблиц на C | Да |
Ниже приведены подробные примеры для каждого шага.
Миграция выполняет только операции чтения из кластера источника, поэтому целостность данных не подвержена риску. Однако, если вы хотите дополнительной уверенности или имеете другие сценарии использования данных, используйте инструмент mxbackup для параллельного резервного копирования кластера.
Примечание!
Рекомендуем развернуть кластер изначально без зеркальных сегментов. Добавьте зеркала после завершения миграции для повышения эффективности миграции.
Примечание!
Имена хостов целевого кластера не должны конфликтовать с именами хостов кластера источника.
См. стандартные руководства по развертыванию кластера:
См. документацию по мониторингу и оповещениям:
Примечание!
До остановки всего бизнес-трафика запрещены любые DDL-операции на кластере Greenplum источника. Это включает создание или изменение объектов, добавление или удаление столбцов, а также выполнение операцийCREATE,ALTER,TRUNCATE,DROP.
На Master-узле кластера Greenplum источника отредактируйте файл pg_hba.conf:
$ vim pg_hba.conf
Добавьте IP-адреса клиентов в следующем формате для блокировки удаленного доступа:
host all all <Client IP Address>/<CIDR Mask> reject
Перезагрузите конфигурацию для применения изменений:
$ gpstop -u
Соберите данные, включая количество физических машин, ОС, CPU, память, тип дисков, использование дисков, информацию о сетевых интерфейсах, топологии кластеров, лицензию базы данных, настройки групп ресурсов и т.д., адаптируя их под вашу среду. Полезные команды:
| № | Команда | Цель |
|---|---|---|
| 1 | free -g | Просмотр системной памяти |
| 2 | lscpu | Просмотр количества CPU |
| 3 | cat /etc/system-release | Просмотр версии ОС |
| 4 | uname -a | Вывод информации о ядре в порядке: имя ядра, hostname, версия ядра, версия ядра, архитектура оборудования, тип процессора, платформа, имя ОС (опущено, если неизвестно) |
| 5 | tail -11 /proc/cpuinfo | Просмотр деталей CPU |
| 6 | gpcheckperf | Тестирование пропускной способности сети и производительности дискового ввода-вывода |
От имени пользователя gpadmin используйте pg_dump для создания резервной копии DDL, схем и информации о пользователях из кластера Greenplum источника:
# Back up global user objects
pg_dumpall -g -f global_user.sql
# Back up table structures
pg_dump <source_db_name> -s -f orig.sql
# Make a backup copy
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_db_name> -U <superuser> -t -f get_index.sql > index.sql
mxshift теперь поддерживает автоматическую миграцию DDL — см. раздел "2 Выполнение миграции". Ручные корректировки описаны ниже.
Корректировки устраняют несовместимости между синтаксисом DDL Greenplum и YMatrix (не требуются при миграции YMatrix в YMatrix). Оптимизации направлены на достижение максимальной производительности с самого начала. Примеры команд, выполняемых на кластере 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
Пояснение:
quicklz.plpython3u.zstd обеспечивает лучшую производительность в YMatrix.После создания таблиц установите индексируемые столбцы на сортировку 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;
Примечание!
Пропустите этот шаг, если кластеры источника и назначения работают на одном сервере.
На Master-узлах обоих кластеров добавьте все 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 datadir 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
Также добавьте IP-адреса и имена хостов в /etc/hosts. Пример: IP 172.16.100.195, имя хоста 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
Перезагрузите конфигурацию для применения изменений.
Для Greenplum выполните: `gpstop`` $ gpstop -u
Для YMatrix 5 выполните:
`mxstop``
$ mxstop -u
Run the following command in the YMatrix environment:
$ psql -h <YMatrix_Server_IP> -p <target_port> -d <target_db> -U <target_superuser> -f global_user.sql
In the YMatrix environment:
$ psql -h <YMatrix_Server_IP> -p <target_port> -d <target_db> -U <target_superuser> -f orig.sql
Используйте созданную резервную копию orig.sql для восстановления структур таблиц на целевом кластере YMatrix:
$ time psql -d <target_db_name> -f orig.sql > restoreddl.log 2>&1 &
$ time psql -d <target_db_name> -f collate.sql
Примечание!
Полный список параметров см. в документации 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.1.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.1.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: 0/gzip/lz4/zstd
compress-method="lz4"
## Data transfer mode: normal/dryrun/fetch/motion
## dryrun: execute DDL only, no data transfer
## fetch: fetch data from source and discard
## motion: fetch, redistribute, then discard
mode="normal"
## SQL to select segment info from source
# 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
# 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: true)
# disable-data-increment=true
[log]
## Log level: debug/verbose/info
log-level="info"
## Disable colored log output
# no-color=false
[controller]
## By default, transfer starts from largest table. Use 'bothway' to start from both largest and smallest
both-way=true
## Number of tables to migrate 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
## Skip resource queue/group during DDL transfer (default: true)
# skip-resource-queue-and-group=true
## Skip tablespace during DDL transfer (default: true)
# skip-table-space=true
[[ddl.replace]]
## Applies only when migrating from Greenplum to YMatrix
category="role"
[[ddl.replace.pairs]]
old="gpadmin"
new="mxadmin"
## Disable incremental DDL migration (default: true)
# disable-ddl-increment=true
Затем выполните миграцию на целевом кластере YMatrix:
$ mxshift -c config_path.toml
На целевом кластере YMatrix:
psql -h localhost -p <target_port> -d <target_db_name> -U mxadmin -f index.sql >>idx.out 2>&1 &
Обновите статистику для всей базы данных на целевом кластере YMatrix:
export PGPORT=<target_port>
time analyzedb -d <target_db_name> -p 10 -a
Добавьте зеркальные сегменты на целевой кластер YMatrix. Процедура следующая:
# First, check 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)
После завершения вышеуказанных шагов восстановите доступ к бизнес-приложениям и отслеживайте поведение системы. Наблюдайте за кластером в течение продолжительного периода (продолжительность зависит от конкретных паттернов нагрузки). Если система работает стабильно — поздравляем! Миграция данных успешно завершена!