Этот документ содержит часто задаваемые вопросы по использованию MatrixGate.
При загрузке данных я обнаружил, что использование дискового ввода-вывода высоко, но скорость загрузки очень низкая.
Анализ проблемы
Используйте команду gpcheckperf для проверки производительности диска и сети, и выяснилось, что производительность диска составляет всего 80 МБ/с.
Решение
Загружайте данные с нескольких дисков для повышения производительности ввода-вывода; разделяйте диски WAL и данных для максимально возможного повышения производительности ввода-вывода.
failed to acquire resources on on or more segments ,fatal out of memoryПри включении mxgate и одновременной загрузке 30 таблиц возникает исключение OOM.
Анализ проблемы
YMatrix работает в многопроцессном режиме; при высокой конкуренции запросов слишком много соединений, и память не может быть выделена соответствующему запросу, что приводит к ошибке.
Решение
Настройте параметр ядра vm.overcommit_memory = 2 в /etc/sysctl.conf.
Настройте параметр mxgate prepared, изменив его с prepared=10 на prepared = 5.
Анализ проблемы
Проверьте статус процесса mxgate:
ps -ef|grep mxgate для просмотра статуса процесса mxgate.Проверьте информацию о блокировках:
Значение столбца granted равно false, что указывает на процесс, который еще не получил блокировку. Для просмотра используйте следующий SQL-запрос:
=# CREATE VIEW v_locks_monitor AS
WITH t_wait AS
(
SELECT a.mode,a.locktype,a.database,a.relation,a.page,a.tuple,a.classid,a.granted,
a.objid,a.objsubid,a.pid,a.virtualtransaction,a.virtualxid,a.transactionid,a.fastpath,
b.state,b.query,b.xact_start,b.query_start,b.usename,b.datname,b.client_addr,b.client_port,b.application_name
FROM pg_locks a,pg_stat_activity b WHERE a.pid=b.pid AND NOT a.granted
),
t_run AS
(
SELECT a.mode,a.locktype,a.database,a.relation,a.page,a.tuple,a.classid,a.granted,
a.objid,a.objsubid,a.pid,a.virtualtransaction,a.virtualxid,a.transactionid,a.fastpath,
b.state,b.query,b.xact_start,b.query_start,b.usename,b.datname,b.client_addr,b.client_port,b.application_name
FROM pg_locks a,pg_stat_activity b WHERE a.pid=b.pid AND a.granted
),
t_overlap AS
(
SELECT r.* FROM t_wait w JOIN t_run r ON
(
r.locktype IS NOT DISTINCT FROM w.locktype AND
r.database IS NOT DISTINCT FROM w.database AND
r.relation IS NOT DISTINCT FROM w.relation AND
r.page IS NOT DISTINCT FROM w.page AND
r.tuple IS NOT DISTINCT FROM w.tuple AND
r.virtualxid IS NOT DISTINCT FROM w.virtualxid AND
r.transactionid IS NOT DISTINCT FROM w.transactionid AND
r.classid IS NOT DISTINCT FROM w.classid AND
r.objid IS NOT DISTINCT FROM w.objid AND
r.objsubid IS NOT DISTINCT FROM w.objsubid AND
r.pid <> w.pid
)
),
t_unionall AS
(
SELECT r.* FROM t_overlap r
UNION ALL
SELECT w.* FROM t_wait w
)
SELECT locktype,datname,relation::regclass,page,tuple,virtualxid,transactionid::text,classid::regclass,objid,objsubid,
string_agg(
'Pid: '||CASE WHEN pid IS NULL THEN 'NULL' ELSE pid::text END||chr(10)||
'Lock_Granted: '||CASE WHEN granted IS NULL THEN 'NULL' ELSE granted::text END||' , Mode: '||CASE WHEN mode IS NULL THEN 'NULL' ELSE mode::text END||' , FastPath: '||CASE WHEN fastpath IS NULL THEN 'NULL' else fastpath::text END||' , VirtualTransaction: '||CASE WHEN virtualtransaction IS NULL THEN 'NULL' else virtualtransaction::text END||' , Session_State: '||CASE WHEN state IS NULL THEN 'NULL' else state::text END||chr(10)||
'Username: '||CASE WHEN usename IS NULL THEN 'NULL' else usename::text END||' , Database: '||CASE WHEN datname IS null THEN 'NULL' else datname::text END||' , Client_Addr: '||CASE WHEN client_addr IS NULL THEN 'NULL' else client_addr::text END||' , Client_Port: '||CASE WHEN client_port IS NULL THEN 'NULL' else client_port::text END||' , Application_Name: '||CASE WHEN application_name IS NULL THEN 'NULL' else application_name::text END||chr(10)||
'Xact_Start: '||CASE WHEN xact_start IS NULL THEN 'NULL' else xact_start::text END||' , Query_Start: '||CASE WHEN query_start IS NULL THEN 'NULL' else query_start::text END||' , Xact_Elapse: '||CASE WHEN (now()-xact_start) IS NULL THEN 'NULL' else (now()-xact_start)::text END||' , Query_Elapse: '||CASE WHEN (now()-query_start) IS NULL THEN 'NULL' else (now()-query_start)::text END||chr(10)||
'SQL (Current SQL in Transaction): '||chr(10)||
CASE WHEN query IS NULL THEN 'NULL' else query::text END,
chr(10)||'--------'||chr(10)
ORDER BY
( CASE mode
WHEN 'INVALID' THEN 0
WHEN 'AccessShareLock' THEN 1
WHEN 'RowShareLock' THEN 2
WHEN 'RowExclusiveLock' THEN 3
WHEN 'ShareUpdateExclusiveLock' THEN 4
WHEN 'ShareLock' THEN 5
WHEN 'ShareRowExclusiveLock' THEN 6
WHEN 'ExclusiveLock' THEN 7
WHEN 'AccessExclusiveLock' THEN 8
ELSE 0
END ) DESC,
(CASE WHEN granted THEN 0 ELSE 1 END)
) AS lock_conflict
FROM t_unionall
GROUP BY
locktype,datname,relation,page,tuple,virtualxid,transactionid::text,classid,objid,objsubid ;
Проверьте информацию о блокировке конкретной таблицы; если другие процессы находятся в idle in transaction, найдите mppsessionid:
=# SELECT * FROM pg_locks WHERE relation='t1_p'::regclass;
locktype | database | relation | page | tuple | virtualxid | transactionid | classid | objid | objsubid | virtualtransaction | pid | mode | g
ranted | fastpath | mppsessionid | mppiswriter | gp_segment_id
----------+------------+---------+------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
-------+----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
relation | 693089 | 2693588 | | | | | | | | 23/40692 | 100289 | RowExclusiveLock | t
| t | 37099 | t | -1
relation | 693089 | 2693588 | | | | | | | | 33/198609 | 100676 | AccessShareLock | t
| t | 37099 | t | 4
relation | 693089 | 2693588 | | | | | | | | 33/198609 | 100676 | RowExclusiveLock | t
| t | 37099 | t | 4
(3 rows)
Проверьте, находится ли транзакция в состоянии waiting:
[mxadmin@sdw21 gpconfigs]$ gpssh -f ./seg_host
=> ps -ef|grep 37099
[sdw18] mxadmin 213588 152755 0 21:19 ? 00:00:00 postgres: 8000, mxadmin test 192.168.100.32(31024) con37099 seg8 idle
[sdw18] mxadmin 213589 152762 0 21:19 ? 00:00:00 postgres: 8001, mxadmin test 192.168.100.32(20614) con37099 seg9 idle
[sdw18] mxadmin 213590 152766 0 21:19 ? 00:00:00 postgres: 8002, mxadmin test 192.168.100.32(22542) con37099 seg10 idle
[sdw18] mxadmin 213591 152778 0 21:19 ? 00:00:00 postgres: 8003, mxadmin test 192.168.100.32(45560) con37099 seg11 idle
[sdw18] mxadmin 213592 152782 0 21:19 ? 00:00:00 postgres: 8004, mxadmin test 192.168.100.32(27438) con37099 seg12 idle
[sdw18] mxadmin 213593 152788 0 21:19 ? 00:00:00 postgres: 8005, mxadmin test 192.168.100.32(47258) con37099 seg13 idle
[sdw18] mxadmin 213594 152791 0 21:19 ? 00:00:00 postgres: 8006, mxadmin test 192.168.100.32(62898) con37099 seg14 idle
[sdw18] mxadmin 213966 212889 0 21:20 pts/2 00:00:00 grep --color=auto 37099
[sdw19] mxadmin 236149 203253 0 21:19 ? 00:00:00 postgres: 8000, mxadmin test 192.168.100.32(27718) con37099 seg16 idle
[sdw19] mxadmin 236150 203248 0 21:19 ? 00:00:00 postgres: 9007, mxadmin test 192.168.100.32(37320) con37099 seg15 idle
[sdw19] mxadmin 236151 203267 0 21:19 ? 00:00:00 postgres: 8003, mxadmin test 192.168.100.32(64854) con37099 seg19 idle
[sdw19] mxadmin 236152 203263 0 21:19 ? 00:00:00 postgres: 8002, mxadmin test 192.168.100.32(65230) con37099 seg18 idle
[sdw19] mxadmin 236153 203257 0 21:19 ? 00:00:00 postgres: 8001, mxadmin test 192.168.100.32(40968) con37099 seg17 idle
[sdw19] mxadmin 236154 203269 0 21:19 ? 00:00:00 postgres: 8004, mxadmin test 192.168.100.32(54360) con37099 seg20 idle
[sdw19] mxadmin 236155 203278 0 21:19 ? 00:00:00 postgres: 8005, mxadmin test 192.168.100.32(41424) con37099 seg21 idle
[sdw19] mxadmin 236156 203279 0 21:19 ? 00:00:00 postgres: 8006, mxadmin test 192.168.100.32(41532) con37099 seg22 idle
[sdw19] mxadmin 236157 203280 0 21:19 ? 00:00:00 postgres: 8007, mxadmin test 192.168.100.32(23184) con37099 seg23 idle
[sdw19] mxadmin 236295 235047 0 21:20 pts/1 00:00:00 grep --color=auto 37099
[sdw20] mxadmin 188516 35758 0 21:19 ? 00:00:00 postgres: 8000, mxadmin test 192.168.100.32(47346) con37099 seg24 idle
[sdw20] mxadmin 188517 35773 0 21:19 ? 00:00:00 postgres: 8003, mxadmin test 192.168.100.32(59058) con37099 seg27 idle
[sdw20] mxadmin 188518 35779 0 21:19 ? 00:00:00 postgres: 8004, mxadmin test 192.168.100.32(58736) con37099 seg28 idle
[sdw20] mxadmin 188519 35767 0 21:19 ? 00:00:00 postgres: 8002, mxadmin test 192.168.100.32(11736) con37099 seg26 idle
[sdw20] mxadmin 188520 35783 0 21:19 ? 00:00:00 postgres: 8005, mxadmin test 192.168.100.32(45638) con37099 seg29 idle
[sdw20] mxadmin 188521 35760 0 21:19 ? 00:00:00 postgres: 8001, mxadmin test 192.168.100.32(52888) con37099 seg25 idle
[sdw20] mxadmin 188522 35784 0 21:19 ? 00:00:00 postgres: 8006, mxadmin test 192.168.100.32(42540) con37099 seg30 idle
[sdw20] mxadmin 188523 35785 0 21:19 ? 00:00:00 postgres: 8007, mxadmin test 192.168.100.32(41324) con37099 seg31 idle
[sdw20] mxadmin 188650 187294 0 21:20 pts/1 00:00:00 grep --color=auto 37099
Решение
waiting или не завершена, даже получение блокировки на уровне строки повлияет на автоматическое создание подразделов.SELECT pg_terminate_backend(pid);.kill -3 для завершения процесса; лучше не применять kill -9.При использовании командной строки можно исключить указанные столбцы с помощью параметра --exclude-columns. Если используется фоновый режим, измените параметр exclude-columns=["Column name"] в конфигурационном файле и перезапустите сервис — изменения вступят в силу.
Пример
Загрузите CSV-файл (с заголовками) через команду, используя tail -n +2 для исключения первого столбца.
$ tail -n +2 /home/mxadmin/workspace/nyc-taxi-data/yellow_tripdata_2016-01.csv | mxgate --source stdin --db-database postgres --db-master-host mdw --db-master-port 5432 --db-user mxadmin --time-format raw --target trip --parallel 256 --delimiter ',' --exclude-columns trip_duration
// Create table
CREATE TABLE t1(id int,a int);
// Generate test data
INSERT INTO t1 SELECT i,i FROM generate_series(1,10) AS i;
// Export to file
COPY t1 TO '/home/mxadmin/data/t1.csv' WITH delimiter '|';
// Clear
TRUNCATE TABLE t1;
$ mxgate config --db-database postgres \
--db-master-host localhost \
--db-master-port 6432 \
--db-user mxadmin \
--target public.t1 \
--time-format raw \
--delimiter '|' \
> mxgate.conf
$ mxgate start --config mxgate.conf
****************************************************************
__ __ _ _ ____ _
| \/ | __ _| |_ _ __(_)_ __/ ___| __ _| |_ ___
| |\/| |/ _` | __| '__| \ \/ / | _ / _` | __/ _ \
| | | | (_| | |_| | | |> <| |_| | (_| | || __/
|_| |_|\__,_|\__|_| |_/_/\_\\____|\__,_|\__\___|
Version: v4.6.5+Dev (git: master 4f01c039)
Your Copy is Licensed to: http://www.ymatrix.cn
****************************************************************
Launching MatrixGate daemon...
MatrixGate daemon started successfully
curl http://localhost:8086/ -X POST -H 'Content-Type: text/plain' --data-binary "@t1.csv"
postgres=# SELECT * FROM t1;
id | a
-----+-------
1 | 1
2 | 2
3 | 3
4 | 4
5 | 5
Specifies that the process pid pauses.
$ mxgate pause -X -S -p 133478
Specify the job name schema.table pause.
$ mxgate pause -X -S --job public.t1
pause по умолчанию асинхронен, при этом существует эксклюзивная блокировка строки. Если вы хотите добавить поле, вы будете ждать эксклюзивной блокировки строки.
Добавление параметра -S означает, что процесс mxgate приостанавливается синхронно.
Вывод будет следующим:
****************************************************************
__ __ _ _ ____ _
| \/ | __ _| |_ _ __(_)_ __/ ___| __ _| |_ ___
| |\/| |/ _` | __| '__| \ \/ / | _ / _` | __/ _ \
| | | | (_| | |_| | | |> <| |_| | (_| | || __/
|_| |_|\__,_|\__|_| |_/_/\_\\____|\__,_|\__\___|
Version: v4.6.5+Dev (git: master 4f01c039)
Your Copy is Licensed to: http://www.ymatrix.cn
****************************************************************
begin to pause all jobs, please wait...
public.t1 paused
When the mxgate task is paused, the definition of the external table of the web is deleted.
Add a field
=# ALTER TABLE t1 ADD COLUMN b int;
Restart the specified task
$ mxgate resume -R --job public.t1
When the mxgate process is restored, an external table is created again.
Loading data
$ curl http://localhost:8086/ -X POST -H 'Content-Type: text/plain' --data-binary "@t1.csv"
The data is loading normally.
Under normal circumstances, the socket file is as follows:
$ cat /tmp/.s.MXGATED.4329.17056.lock
## This mxgate process is part of MatrixDB internal tools
90969
/var/log/matrixdb/matrixgate.2022-09-15_093212-90969.log
0
4329.17056
17056
/tmp/mxgate.conf
После устранения неполадок выяснилось, что файл /tmp/.s.MXGATED.8086.0.lock мог быть удален системой из-за длительного неиспользования.
Решение
$ ps -ef |grep mxgate
mxadmin 59272 277634 0 11:57 pts/1 00:00:00 grep --color=auto mxgate
mxadmin 68731 1 40 Jan27 ? 7-11:13:10 /opt/ymatrix/matrixdb-5.0.0+enterprise/bin/mxgated daemon --config mxgate_chj_iot.conf
$ kill 68731
$ touch /tmp/.s.MXGATED.8086.0.lock
$ cat /tmp/.s.MXGATED.8086.0.lock # Содержимое неважно, важно, чтобы файл содержал 6 строк
336941
$ wc -l /tmp/.s.MXGATED.8086.0.lock
6 /tmp/.s.MXGATED.8086.0.lock
$ chmod 644 .s.MXGATED.8086.0.lock
$ mxgate status
****************************************************************
__ __ _ _ ____ _
| \/ | __ _| |_ _ __(_)_ __/ ___| __ _| |_ ___
| |\/| |/ _` | __| '__| \ \/ / | _ / _` | __/ _ \
| | | | (_| | |_| | | |> <| |_| | (_| | || __/
|_| |_|\__,_|\__|_| |_/_/\_\\____|\__,_|\__\___|
Version: v4.3.13 (git: HEAD cef61ced)
Your Copy is Licensed to: yMatrix.cn; 2022-04-13; any
****************************************************************
PID 336941 alive
Launched At 2022-01-28 21:08:16
Up For 18 days 0 hours 39 minutes 15 seconds
Binary /opt/ymatrix/matrixdb-5.0.0+enterprise/bin/mxgated
Log
Config
data format error: invalid input syntax for type integer: "1970-01-01 00:00:01"Анализ проблемы
Дизайн mxgate в первую очередь ориентирован на быструю загрузку временных данных, и первый столбец по умолчанию имеет тип времени.
Решение
Параметр time-format в mxgate по умолчанию равен unix-second; просто измените его на raw.
Анализ проблемы
По умолчанию mxgate использует unix-second в параметре time-format, что вызывает разницу в 8 часов при вводе данных.
Решение
Параметр time-format в mxgate по умолчанию равен unix-second; просто измените его на raw.
Aborting operation regardless of REJECT LIMIT value, last error was: invalid input syntax for type timestamp: ""22:31:01"", column batch_numАнализ проблемы
При загрузке данных mxgate возникают ошибки, если типы данных на источнике и целевом конце не совпадают.
Структура таблицы.
=# CREATE TABLE s1.test1
id character varying(36),
created_date_time timestamp(6) without time zone ,
modified_date_time timestamp(6) without time zone ,
substep character varying(36) ,
substep_id character varying(6) ,
txdate date ,
batch_num time(0) without time zone
)
DIETRIBUTED BY (id)
Выполните команду.
$ mxgate --source transfer --src-host 172.26.14.15 --src-port 5432 --src-db wdp --src-user user1 --src-password password1 --src-schema s1 --src-table test1 --compress "gzip" --port-base 9000 --local-ip 172.26.14.17 --db-master-host 172.26.14.17 --db-database wdp --target s1.test1 --format csv --time-format raw --use-auto-increment=false
Лог ошибки сегмента бэкенда.
"Aborting operation regardless of REJECT LIMIT value, last error was: invalid input syntax for type timestamp: ""22:31:01"", column batch_num",
Решение
Измените тип batch_num на целевой стороне на тип time(0) without time zone; типы данных на обеих сторонах должны совпадать.
ERROR c.s.o.matrixdb.MatrixdbSource 77 -MatrixdbSource sendingPostRequest errorCode: 400, errorMsg: target table name is emptyАнализ проблемы
При записи в mxgate через HTTP сообщение об ошибке отсутствует.
Решение
mxgate.conf верно и таблица существует в базе данных.responseCode:500 errorMsg: ERROR: invalid byte sequence for encoding "UTF8": 0x81Анализ проблемы
При записи в mxgate через HTTP возникает ошибка кодировки.
Решение
Проверьте, содержатся ли в исходных данных символы ASCII.
body size exceeds the given limitАнализ проблемы
Объем данных, отправляемых при записи в mxgate через HTTP, превышает лимит max-body-bytes. Значение по умолчанию — 4M, его можно просмотреть в конфигурационном файле mxgate.conf.
Решение
Измените размер max-body-bytes в mxgate.conf по необходимости и перезапустите сервис.
При запуске MatrixGate возникла ошибка:
you license is expired 2022-11-02
Анализ проблемы
Срок действия лицензионной авторизации истек.
Решение
Сначала запросите новую лицензию у технического специалиста или продавца YMatrix.
Затем удалите старый файл лицензии на всех узлах.
$ cd /opt/ymatrix/matrixdb5/bin
$ rm LICENSE_${OLD}
Загрузите новый файл лицензии в /opt/ymatrix/matrixdb5/bin на всех узлах и установите права 755.
$ chmod 755 LICENSE_${NEW}
Cannot start source: --local-ip localhost is not a valid IP addressАнализ проблемы
При использовании mxgate для миграции данных возникают ошибки.
Код миграции:
[mxadmin@mdw ~]$ mxgate --source transfer \
--src-host localhost \
--src-port 5432 \
--src-db mxdb_poc \
--src-user mxadmin \
--src-password 123123 \
--src-schema public \
--src-table t_hash \
--compress "lz4" \
--port-base 9393 \
--local-ip localhost \
--db-database mxdb_poc \
--db-user mxadmin \
--db-password 123123 \
--target public.t_hash_new \
--format csv \
--parallel 256 \
--stream-prepared 0 \
--interval 250 \
--time-format raw
Лог ошибки:
main.go:210: 2022-12-24:21:29:43.018 matrixgate:mxadmin:sdw4:023119-[CRITICAL]:-2022-12-24:21:29:43.018 matrixgate:mxadmin:sdw4:023119-[CRITICAL]:-Cannot start source: --local-ip localhost is not a valid IP address
github.com/ymatrix-data/go-common-libs/utils/logger.FatalOnError
/home/runner/go/pkg/mod/github.com/ymatrix-data/[email protected]/utils/logger/logger.go:395
main.failQuit.func1
/home/runner/work/matrixdb-ci/matrixdb-ci/src/bin/mxgated/main.go:210
sync.(*Once).doSlow
/opt/hostedtoolcache/go/1.19.2/x64/src/sync/once.go:74
sync.(*Once).Do
/opt/hostedtoolcache/go/1.19.2/x64/src/sync/once.go:65
main.failQuit
/home/runner/work/matrixdb-ci/matrixdb-ci/src/bin/mxgated/main.go:207
main.main
/home/runner/work/matrixdb-ci/matrixdb-ci/src/bin/mxgated/main.go:113
runtime.main
/opt/hostedtoolcache/go/1.19.2/x64/src/runtime/proc.go:250
runtime.goexit
/opt/hostedtoolcache/go/1.19.2/x64/src/runtime/asm_amd64.s:1594
exit status 1
Решение
Замените параметр --local-ip в режиме миграции на фактический физический IP-адрес, например: 192.168.247.132.
Исправленный код миграции:
[mxadmin@mdw ~]$ mxgate --source transfer \
--src-host localhost \
--src-port 5432 \
--src-db mxdb_poc \
--src-user mxadmin \
--src-password 123123 \
--src-schema public \
--src-table t_hash \
--compress "lz4" \
--port-base 9393 \
--local-ip 192.168.247.132 \
--db-database mxdb_poc \
--db-user mxadmin \
--db-password 123123 \
--target public.t_hash_new \
--format csv \
--parallel 256 \
--stream-prepared 0 \
--interval 250 \
--time-format raw
Анализ проблемы
Эту проблему можно проанализировать, создав тестовую таблицу. Конкретные шаги следующие:
[mxadmin@mdw ~]$ psql -d mxdb
mxdb=# CREATE TABLE public.test(order_no text,info text) DIETRIBUTED BY(order_no);
[mxadmin@mdw ~]$ cat test.csv
"1x01"|"A"
"1x02"|"B"
"2x01"|"C"
"2x02"|"D"
"3x01"|"E"
"3x02"|"F"
[mxadmin@mdw ~]$ cat test.csv| \
mxgate --source stdin \
--db-database mxdb_poc \
--db-master-host 127.0.0.1 \
--db-master-port 5432 \
--db-user mxadmin \
--db-password 123123 \
--time-format raw \
--delimiter "|" \
--target public.test \
--parallel 256 \
--stream-prepared 0 \
--interval 250
mxdb=# SELECT * FROM test;
order_no | info
---------+-----
"1x01" | "A"
"1x02" | "B"
"3x01" | "E"
"2x01" | "C"
"2x02" | "D"
"3x02" | "F"
(6 rows)
Ожидаемый результат должен быть следующим:
mxdb=# SELECT * FROM test;
order_no | info
---------+-----
1x01 | A
1x02 | B
2x01 | C
2x02 | D
3x01 | E
3x02 | F
(6 rows)
Решение
При загрузке данных добавьте параметр --format csv.
[mxadmin@mdw ~]$ cat test.csv| \
mxgate --source stdin \
--db-database mxdb_poc \
--db-master-host 127.0.0.1 \
--db-master-port 5432 \
--db-user mxadmin \
--db-password 123123 \
--time-format raw \
--format csv \
--delimiter "|" \
--target public.test \
--parallel 256 \
--stream-prepared 0 \
--interval 250
Теперь проверьте данные в таблице — вы получите ожидаемый результат.
mxdb=# SELECT * FROM test;
order_no | info
---------+-----
1x01 | A
1x02 | B
2x01 | C
2x02 | D
3x01 | E
3x02 | F
(6 rows)
Описание проблемы
В процессе использования MatrixGate требуется обновление по особым причинам, но я не знаю, как это сделать.
Решение
Завершите запись MatrixGate.
Используя пользователя mxadmin, остановите HTTP-сервис, запущенный MatrixGate.
[root@mdw ~]# su - mxadmin
[mxadmin@mdw ~]$ mxgate stop
Используя пользователя root, остановите службу Supervisor.
[root@mdw ~]# systemctl stop matrixdb.supervisor.service
Используя пользователя root, замените двоичный файл MatrixGate.
Сначала перейдите в каталог /bin.
[root@mdw ~]# cd /usr/local/matrixdb/bin/
Затем создайте резервную копию исходного двоичного файла MatrixGate.
[root@mdw ~]# mv mxgate mxgate."bak."`date +%Y%m%d%H%M`
[root@mdw ~]# mv mxgated mxgated."bak."`date +%Y%m%d%H%M`
Загрузите новый двоичный файл MatrixGate в /usr/local/matrixdb/bin/ и установите права 755.
[root@mdw ~]# chmod 755 mxgate
[root@mdw ~]# chmod 755 mxgated
Наконец, проверьте информацию о версии после замены.
[root@mdw ~]# su - mxadmin
[mxadmin@mdw ~]$ mxgate --version
[root@mdw ~]# systemctl start matrixdb.supervisor.service
[root@mdw ~]# su - mxadmin
[mxadmin@mdw ~]$ mxgate start --config /home/mxadmin/mxgate.conf
Описание проблемы
При использовании MatrixGate для загрузки данных в формате Unix-времени, но поле с Unix-временем в файле данных не является первым, возникает ошибка из-за невозможности преобразования типов.
Мы можем воспроизвести и проанализировать эту проблему, создав тестовую таблицу. Примеры:
[mxadmin@mdw ~]$ psql testdb
testdb=# CREATE TABLE dest2(
c1 int,
c2 text,
time timestamp,
c3
)DISTRIBUTED BY(c1);
[mxadmin@mdw ~]$ cat test2.csv
1,2,1603777821678,2
1,2,1603777822670,3
1,2,1603777823628,4
1,2,1603777824673,5
1,2,1603777825578,6
[mxadmin@mdw ~]$ cat test2.csv| \
mxgate \
--source stdin \
--db-database testdb \
--db-master-host mdw \
--db-master-port 5432 \
--db-user mxadmin \
--time-format unix-ms \
--target dest2 \
--delimiter ',' \
--parallel 256 \
--stream-prepared 0
Сообщение об ошибке:
stdin.go:168: 2022-04-15:12:38:52.443 matrixgate:mxadmin:mdw:006560-[ERROR]:-[Source.STDIN] load error: data format error: invalid input syntax for type integer: "1970-01-01 00:00:00.001", column c1
Анализ проблемы
MatrixGate по умолчанию интерпретирует первое поле как поле времени.
Решение
Требования к версии: MatrixGate v4.4.7 и выше.
Сгенерируйте конфигурационный файл mxgate
[mxadmin@mdw ~]$ mxgate config --db-database testdb \
--db-master-host localhost \
--db-master-port 5432 \
--db-user mxadmin \
--target public.dest2 \
--format csv \
--time-format unix-ms \
--delimiter ',' \
--parallel 256 \
--stream-prepared 0 \
--interval 250 \
--transform plain \
--source stdin \
> mxgate.conf
Измените конфигурационный файл mxgate
[mxadmin@mdw ~]$ vi mxgate.conf
#Find the corresponding place to modify
[[job.target]]
# deduplicate-key = []
delimiter = ","
# error-handling = "accurate"
# exclude-columns = []
format = "csv"
name = "job_csv_to_public.dest2"
# null-as = ""
schema = "public"
table = "dest2"
time-format = "unix-ms"
# upsert-key = []
# use-auto-increment = true
#Find the corresponding place to modify
transform = "plain"
[transform.plain]
mapping = [
# secondsToTimestamp Second-level timestamp conversion 1603777825 => 2020-10-27 05:50:25
# millionsecondsToTimestamp millionseconds-level timestamp conversion 1603777825123 => 2020-10-27 05:50:25.123
# microsecondsToTimestamp microseconds time stamp conversion 1603777825123456 => 2020-10-27 05:50:25.123456
# nanosecondsToTimestamp Nanoseconds Timestamp conversion 1603777825123456789 => 2020-10-27 05:50:25.123457 (Note: Currently, the database only supports microseconds time stamp accuracy, and nanoseconds time stamps will be distorted)
{table-name = "public.dest2", field-map = [{dest = "c1", source = "0", enabled = true},
{dest = "c2", source = "1", enabled = true},
{dest = "ts", source = "2", enabled = true,transform = ["millisecondsToTimestamp"]},
{dest = "c3", source = "3", enabled = true},
]}
]
Инструкции по настройке
- table-name = "public.dest2" Specify the table name;
- dest corresponds to the column name in each column of the database;
- source represents the way to obtain the corresponding column of the dest from the data source entering mxgate:
- plain: The csv data entering MatrixGate is the csv data, and the corresponding source represents the column number of a column in the csv;
- json: The JSON data entering MatrixGate is the JSON data, and the corresponding source is the JSON-Path expression that obtains the corresponding value of dest from a JSON structure (for JSON-Path, you can refer to this document. JSON Path-related information summary)
- enable=true means that the column data needs to be written to the database through MatrixGate, and if it is false, it will not be written;
- Transform conversion function that represents the time stamp accuracy:
- secondsToTimestamp: Seconds Timestamp Conversion
- millionsecondsToTimestamp: millionseconds-level timestamp conversion
- microsecondsToTimestamp: microseconds time stamp conversion
- nanosecondsToTimestamp: nanoseconds time stamp conversion
Примечание В настоящее время база данных поддерживает только точность меток времени в микросекундах; метки времени в наносекундах будут искажены.
[mxadmin@mdw ~]$ tail -n +2 test2.csv| mxgate --config mxgate.conf
\NАнализ проблемы
Мы можем воспроизвести и проанализировать эту проблему, создав тестовую таблицу. Примеры:
Создайте тестовую таблицу
[mxadmin@mdw ~]$ psql -d mxdb
mxdb=# CREATE TABLE test(f1 int,f2 varchar(50),f3 varchar(50));
Просмотрите тестовые данные
[mxadmin@mdw ~]$ cat test.csv
1|test|\N
Используйте MatrixGate для выполнения команды загрузки данных
[mxadmin@mdw ~]$ cat test.csv| \
mxgate --source stdin \
--db-database mxdb_poc \
--db-master-host 127.0.0.1 \
--db-master-port 5432 \
--db-user mxadmin \
--db-password 123123 \
--time-format raw \
--format csv \
--delimiter "|" \
--target public.test \
--parallel 256 \
--stream-prepared 0 \
--interval 250
Проверьте данные в таблице — символ N присутствует
mxdb=# SELECT * FROM test;
f1 | f2 | f3
----+------+----
1 | test | N
Ожидаемый результат должен быть следующим:
mxdb=# SELECT * FROM test;
f1 | f2 | f3
----+------+----
1 | test |
Решение
При загрузке данных с помощью MatrixGate добавьте параметр --null-as '\N'
[mxadmin@mdw ~]$ cat test.csv| \
mxgate --source stdin \
--db-database mxdb_poc \
--db-master-host 127.0.0.1 \
--db-master-port 5432 \
--db-user mxadmin \
--db-password 123123 \
--time-format raw \
--format csv \
--delimiter "|" \
--target public.test \
--parallel 256 \
--stream-prepared 0 \
--interval 250 \
--null-as '\N'
Проверьте данные в таблице — получите ожидаемый результат
mxdb=# SELECT * FROM test;
f1 | f2 | f3
----+------+----
1 | test |
Handshaking was terminated on port XXXАнализ проблемы
Согласно описанию ошибки, первоначально предполагалось, что SSH-рукопожатие было прервано.
Дальнейшая проверка ошибок lz4 | COPY XXX TO PROGRAM ssh -o StrictHostKeyChecking=no -p XXX показала, что операционная система на источнике — Red Hat 8.3. Пакет lz4 по умолчанию не установлен, поэтому команда lz4 не распознается, однако параметр --compress lz4 включен в команду, что вызывает ошибку.
Решение
--compress lz4 из команды записи или измените параметр на --compress zstd.Да.
Примечание!
Эта функция поддерживается только в MatrixGate v4.4.7 и более поздних версиях.
Пример структуры таблицы базы данных
[mxadmin@mdw ~]$ psql testdb
testdb=# CREATE TABLE vehicle_basic_data_mars2(
daq_time timestamp,
vin varchar(32) ,
lng float ,
lat float ,
speed float ,
license_template varchar(16) ,
flag integer
);
Table "public.vehicle_basic_data_mars2"
Column | Type | Collation | Nullable | Default
------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
daq_time | timestamp without time zone | | |
vin | character varying(32) | | |
lng | double precision | | |
lat | double precision | | |
speed | double precision | | |
license_template | character varying(16) | | |
flag | integer | | |
Конфигурация файла mxgate
В теге [transform] сначала укажите тип преобразования:
transform = "json": формат данных, поступающих в mxgate, — JSON; transform = "plain": формат данных, поступающих в mxgate, — CSV. [transform]
## Overall parallel level for transform, only for non-strict mode
# parallel = 16
## Transform decodes input data and perform type/format conversion
## Types restricted to: plain/json/nil/tsbs
# transform = "json"
# [transform.json]
# mapping = [
# # secondsToTimestamp
# # millionSecondsToTimestamp
# # microsecondsToTimestamp
# # nanosecondsToTimestamp
# {table-name = "public.vehicle_basic_data_mars2", field-map = [{dest = "daq_time", source = "$.daq_time", enabled = true},
# {dest = "vin", source = "$.vin", enabled = true},
# {dest = "lng", source = "$.lng", enabled = true},
# {dest = "lat", source = "$.lat", enabled = true},
# {dest = "speed", source = "$.speed", enabled = true},
# {dest = "license_template", source = "$.license_template"},
# {dest = "flag", source = "$.flag", enabled = true},
# ]}
# ]
transform = "plain"
[transform.plain]
mapping = [
# secondsToTimestamp
# millionSecondsToTimestamp
# microsecondsToTimestamp
# nanosecondsToTimestamp
{table-name = "public.vehicle_basic_data_mars2", field-map = [{dest = "daq_time", source = "0", enabled = true, transform = ["secondsToTimestamp"]},
{dest = "vin", source = "1", enabled = true},
{dest = "lng", source = "2", enabled = true},
{dest = "lat", source = "3", enabled = true},
{dest = "speed", source = "4", enabled = true},
{dest = "license_template", source = "5"},
{dest = "flag", source = "6", enabled = true},
]}
]
Описание конфигурации:
table-name = "public.vehicle_basic_data_mars2" — указывает имя таблицы; dest — имя столбца в базе данных; source — способ получения соответствующего столбца dest из источника данных, поступающего в mxgate: plain: для CSV-данных, поступающих в mxgate, source представляет номер столбца в CSV; json: для JSON-данных, поступающих в mxgate, source — выражение JSON-Path для извлечения соответствующего значения из структуры JSON; enable=true означает, что данные столбца должны быть записаны в базу данных через mxgate; если указано false, данные не будут записаны; transform — функция преобразования, определяющая точность временных меток: secondsToTimestamp: преобразование временной метки с точностью до секунд; millionSecondsToTimestamp: преобразование временной метки с точностью до миллисекунд; microsecondsToTimestamp: преобразование временной метки с точностью до микросекунд; nanosecondsToTimestamp: преобразование временной метки с точностью до наносекунд. Примечание!
В настоящее время база данных поддерживает только точность временных меток в микросекундах; наносекундные метки будут искажены.
(1) Формат настроен как CSV
## Data format to be read: text or csv
## text : faster but cannot have delimiter or line breaks in textual fields
## csv : support delimiter or line break in textual fields, must be double-quoted
format = "csv"
## Schema and table name must be in lower-case
[[job.target]]
# delimiter = "|"
format = "csv"
name = "public.vehicle_basic_data_mars2"
schema = "public"
table = "vehicle_basic_data_mars2"
time-format = "raw"
(2) В сопоставлении необходимо настроить каждый столбец базы данных. Нельзя настраивать только столбцы, требующие преобразования временных меток. Если столбец не настроен, его данные не будут записаны в YMatrix.
(3) Исходный формат времени должен быть настроен как raw.
(4) Поддерживается одновременная настройка преобразования временных меток для нескольких столбцов.
(5) Для конфигурации json или plain в transform можно настроить только один из них для одного процесса mxgate одновременно.
Да.
Сначала скачайте последнюю версию SDK. Следуйте инструкциям на изображении ниже: в примере указана версия v1.0.17 — замените её на последнюю доступную версию в соответствии с инструкциями.


Существует три способа импорта локальных JAR-пакетов: с помощью Maven, Gradle или интегрированной среды разработки IntelliJ IDEA — выберите любой из них. Методы импорта разнообразны, вы также можете использовать другие среды и инструменты разработки для упрощения операций.
Затем добавьте следующее содержимое в файл pom.xml:
<!-- Configure in the pom.xml file -->
<dependencies>
...
<dependency>
<groupId>cn.ymatrix</groupId>
<artifactId>mxgate-sdk-java</artifactId>
<version>1.0</version>
<scope>system</scope>
<!-- The absolute path of the JAR package is filled in the systemPath, where ${project.basedir} refers to the current project folder path -->
<systemPath>${project.basedir}/lib/mxgate-sdk-java-1.0.jar</systemPath>
</dependency>
...
</dependencies>
Примечание!
Если вы используете интегрированную среду разработки IntelliJ IDEA, настройте автоматическую перезагрузку для автоматического обновления файлов. Если автоматическая перезагрузка не включена, после запуска нового кода необходимо вручную обновить файл, нажав кнопку "m" в правом верхнем углу.
Наконец, для обеспечения корректного использования JAR-пакетов (чтобы избежать ошибок, связанных с class not found), добавьте следующее содержимое в pom.xml, чтобы целевая папка содержала необходимые зависимости:
<plugins>
...
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<version>3.8.0</version>
<configuration>
<!-- Specify the jdk version, which is the same as the local one. If it is 1.8, fill in 8.-->
<source>8</source>
<target>8</target>
<compilerArguments>
<!-- Specify the directory where the local jar is located. In the following example, the lib directory is stored in the local jar under project -->
<extdirs>${project.basedir}/lib</extdirs>
</compilerArguments>>
</configuration>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-jar-plugin</artifactId>
<version>3.2.2</version>
<configuration>
<archive>
<manifest>
<!-- Add classpath to MANIFEST.MF when generating jar file -->
<addClasspath>true</addClasspath>
<!-- Defining the prefix of the above classpath needs to be consistent with the outputDirectory of the following maven-dependent-plugin -->
<classpathPrefix>lib</classpathPrefix>
<mainClass>Main.Main</mainClass>
</manifest>
<manifestEntries>
<!-- Add jar to MANIFEST.MF -->
<Class-Path>lib/mxgate-sdk-java-1.0.jar</Class-Path>
</manifestEntries>>
</archive>
</configuration>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-dependency-plugin</artifactId>
<executions>
<execution>
<id>copy-dependencies</id>
<phase>prepare-package</phase>
<goals>
<goal>copy-dependencies</goal>
</goals>
<configuration>
<!-- Generate the lib directory in the maven product target directory and copy all remote and local jars to this directory -->
<outputDirectory>${project.build.directory}/lib</outputDirectory>
</configuration>
</execution>
</executions>
</plugin>
...
</plugins>
Готово.
Предположим, что JAR-пакет хранится в локальной директории libs. Используйте следующий код для импорта локального JAR-пакета:
repositories {
flatDir {
dirs 'libs'
}
}
dependencies {
implementation name: 'cn.ymatrix:mxgate-sdk-java:1.0.17'
}


Выберите файл mxgate-sdk-java.jar из локального пути.

Убедитесь, что JAR-пакет успешно импортирован в текущий проект.

key содержит символ @, парсинг данных не может найти значениеАнализ проблемы
Специальные символы @ не могут быть корректно распарсены.
Воспроизведение проблемы
{
"@timestamp": "2023-04-21T04:00:23.413+08:00",
"@version": "1",
"message": ">End--->.<Tid 189> Response(code=330110, description=, responseTime=1682020823413, responseBody=FlowVO(tips=请求异常,请稍后再试, flowData=null, queryTime=1682020823411, errCode=1))",
"logger": "com.reachauto.cloud.log.aop.LogAspect",
"thread": "XNIO-1 task-3",
"level": "DEBUG",
"levelVal": 10000,
"springAppName": "reachcloud-vsp-sdk-bff-auth",
"kafaServer": "test1.com.com:9092,test2.com:9092",
"springProfileActive": "test",
"callerSource": "auth_sdk",
"ydtargs": "[89860803192030000383]",
"ydtpath": "/api/v1/flow/query",
"ydtuserid": "5816d78e4rh31aa5a3c1bce523a764deea36cfd551fcbdbb8",
"callerVersion": "1.30.17",
"ydttype": "message",
"ydtmethod": "GET",
"PtxId": "6883576",
"PspanId": "-5187341585210826311",
"grayVersion": "unknown",
"ydtrequrl": "http://vsp-show-vehicle.reachauto-mobility.com/api/v1/flow/query",
"ydttime": "233",
"ydtusertype": "VU",
"ydtclass": "FlowController.queryFlow(String)",
"caller":
{
"class": "com.reachauto.cloud.log.aop.LogAspect",
"method": "around",
"file": "LogAspect.java",
"line": 99
}
}
Решение
После неудачной конфигурации через графический интерфейс найдите соответствующий сгенерированный файл mxgate.conf. Измените соответствующее значение transform.json:
source = "$.@timestamp" --> source = "$['@timestamp']"
source = "$.@Version" --> source = "$['@Version']"
Запустите службу через командную строку на уровне хоста. Поле key содержит символ @, и потребление данных проходит корректно.
При использовании режима миграции mxgate возникла ошибка:
Create external table failed: create external table error for public.ddd_back, ERROR: permission denied: no privilege to create a readable gpfdist(s) external table (SQLSTATE 42501), will retry after 3 seconds
Анализ проблемы
При использовании режима миграции mxgate данные синхронизируются путём создания внешних таблиц. Пользователи, не являющиеся mxadmin, не имеют прав на создание внешних таблиц.
Решение
При использовании режима миграции mxgate используйте пользователя mxadmin. Пользователь mxadmin не изменяет права исходной таблицы.
Предоставьте другим пользователям права на внешние таблицы или повысьте права других пользователей до уровня администратора.