Этот документ содержит часто задаваемые вопросы по использованию MatrixGate.
При загрузке данных я обнаружил, что использование дискового ввода-вывода высоко, но скорость загрузки очень низкая.
Анализ проблемы
Используйте команду gpcheckperf для проверки производительности диска и сети, и выяснилось, что производительность диска составляет всего 80 МБ/с.
Решение
Загружайте данные с нескольких дисков для повышения производительности ввода-вывода; разделяйте диски WAL и данных для максимального повышения производительности ввода-вывода.
При одновременной загрузке 30 таблиц с включённым mxgate возникает исключение OOM.
Анализ проблемы
MatrixDB работает в многопроцессном режиме. При высокой конкуренции запросов слишком много соединений, и система не может выделить память соответствующему запросу, что приводит к ошибке.
Решение
Настройте параметр ядра 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 /usr/local/matrixdb-4.3.11~rc6.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 /usr/local/matrixdb-4.3.11~rc6.enterprise/bin/mxgated
Log
Config
Анализ проблемы
Дизайн mxgate в первую очередь ориентирован на быструю загрузку временных данных, и первый столбец по умолчанию интерпретируется как тип времени.
Решение
Параметр time-format в mxgate по умолчанию установлен в unix-second; просто измените его на raw.
Анализ проблемы
По умолчанию mxgate использует unix-second в параметре time-format, что вызывает разницу в 8 часов при вводе данных.
Решение
Параметр time-format в mxgate по умолчанию установлен в unix-second; просто измените его на raw.
Анализ проблемы
При загрузке данных 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, чтобы типы данных на обеих сторонах совпадали.
Анализ проблемы
При записи в mxgate через HTTP возникает сообщение об отсутствии имени таблицы.
Решение
mxgate.conf верно и таблица существует в базе данных.Анализ проблемы
При записи в mxgate через HTTP возникает ошибка кодировки.
Решение
Проверьте наличие ASCII-символов в исходных данных.
Анализ проблемы
Объём данных, отправляемых при записи в mxgate через HTTP, превышает лимит max-body-bytes. Значение по умолчанию — 4M, его можно просмотреть в конфигурационном файле mxgate.conf.
Решение
Измените размер max-body-bytes в mxgate.conf по необходимости и перезапустите службу.
При запуске MatrixGate возникла ошибка:
you license is expired 2022-11-02
Анализ проблемы
Срок действия лицензионной авторизации истёк.
Решение
Сначала запросите новую лицензию у технического специалиста или продавца MatrixDB.
Затем удалите старый файл лицензии на всех узлах.
$ cd /usr/local/matrixdb/bin
$ rm LICENSE_${OLD}
Загрузите новый файл лицензии в /usr/local/matrixdb/bin на всех узлах и установите права 755.
$ chmod 755 LICENSE_${NEW}
Анализ проблемы
При использовании 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 требуется обновление по особым причинам, но неизвестно, как это сделать.
Решение
[root@mdw ~]# su - mxadmin
[mxadmin@mdw ~]$ mxgate stop
[root@mdw ~]# systemctl stop matrixdb.supervisor.service
/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
Анализ проблемы
Мы можем воспроизвести и проанализировать эту проблему, создав тестовую таблицу. Примеры:
[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
[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;
f1 | f2 | f3
----+------+----
1 | test | N
Ожидаемый результат должен быть следующим:
mxdb=# SELECT * FROM test;
f1 | f2 | f3
----+------+----
1 | test |
Решение
[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 |
Анализ проблемы
Согласно описанию ошибки, первоначально предполагалось, что 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 | | |
[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},
]}
]
false, данные не будут записаны;Примечание! В настоящее время база данных поддерживает только точность временных меток в микросекундах; наносекундные временные метки будут искажены.
## 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>
Готово.
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, не изменит права исходной таблицы.
Предоставьте другим пользователям права на внешние таблицы или повысьте права других пользователей до уровня администратора.