MatrixGate FAQ

Этот документ содержит часто задаваемые вопросы по использованию MatrixGate.

1 Низкая производительность загрузки данных


При загрузке данных я обнаружил, что использование дискового ввода-вывода высоко, но скорость загрузки очень низкая.

Анализ проблемы

Используйте команду gpcheckperf для проверки производительности диска и сети, и выяснилось, что производительность диска составляет всего 80 МБ/с.

Решение

Загружайте данные с нескольких дисков для повышения производительности ввода-вывода; разделяйте диски WAL и данных для максимального повышения производительности ввода-вывода.

2 Не удалось получить ресурсы на одном или нескольких сегментах, критическая ошибка нехватки памяти


При одновременной загрузке 30 таблиц с включённым mxgate возникает исключение OOM.

Анализ проблемы

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

Решение

Настройте параметр ядра vm.overcommit_memory = 2 в /etc/sysctl.conf.
Настройте параметр mxgate prepared, изменив его с prepared=10 на prepared = 5.

3 mxgate блокируется, ожидая получения блокировки


Анализ проблемы

Проверьте статус процесса mxgate:

  1. mxgate status — проверьте статус процесса mxgate.
  2. Убедитесь, что данные корректно поступают в базу данных.
  3. Также можно использовать 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

Решение

  1. Если обнаружено, что транзакция находится в состоянии waiting или не завершена, даже получение блокировки на уровне строк повлияет на автоматическое создание подразделов.
  2. Найдите конкретный PID и завершите процесс с помощью команды SELECT pg_terminate_backend(pid);.
  3. UDF на Python не принимает сигналы kill.
  4. Рекомендуется использовать kill -3 для завершения процесса; лучше не применять kill -9.

4 Исключение столбца в mxgate


При использовании командной строки можно исключить указанные столбцы с помощью параметра --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 

5 Метод потоковой загрузки mxgate: добавление столбцов и продолжение работы


  1. Подготовьте тестовые данные
    // 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;
  2. Сгенерируйте конфигурационные файлы
    $ 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
  3. Запустите mxgate
    $ 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
  4. Loading data
    curl http://localhost:8086/ -X POST -H 'Content-Type: text/plain' --data-binary "@t1.csv"
  5. View data
    postgres=# SELECT * FROM t1;
    id  | a 
    -----+-------
    1 |  1
    2 |  2
    3 |  3
    4 |  4
    5 |  5
  6. Pause mxgate

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.

  1. Add a field

    =# ALTER TABLE t1 ADD COLUMN b int;
  2. Restart the specified task

    $ mxgate resume -R --job public.t1

    When the mxgate process is restored, an external table is created again.

  3. Loading data

    $ curl http://localhost:8086/ -X POST -H 'Content-Type: text/plain' --data-binary "@t1.csv"

    The data is loading normally.

6 mxgate socket file is missing?


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    

7 Ошибка формата данных: недопустимый синтаксис ввода для типа integer: "1970-01-01 00:00:01"


Анализ проблемы

Дизайн mxgate в первую очередь ориентирован на быструю загрузку временных данных, и первый столбец по умолчанию интерпретируется как тип времени.

Решение

Параметр time-format в mxgate по умолчанию установлен в unix-second; просто измените его на raw.

8 Значение по умолчанию поля времени входа в mxgate отличается на 8 часов


Анализ проблемы

По умолчанию mxgate использует unix-second в параметре time-format, что вызывает разницу в 8 часов при вводе данных.

Решение

Параметр time-format в mxgate по умолчанию установлен в unix-second; просто измените его на raw.

9 Операция прервана независимо от значения REJECT LIMIT, последняя ошибка: недопустимый синтаксис ввода для типа timestamp: ""22:31:01"", столбец 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, чтобы типы данных на обеих сторонах совпадали.

10 ERROR c.s.o.matrixdb.MatrixdbSource 77 - MatrixdbSource sendingPostRequest errorCode: 400, errorMsg: target table name is empty


Анализ проблемы

При записи в mxgate через HTTP возникает сообщение об отсутствии имени таблицы.

Решение

  1. Проверьте корректность заполнения формы при записи через HTTP.
  2. Убедитесь, что имя таблицы в конфигурационном файле mxgate.conf верно и таблица существует в базе данных.

11 responseCode:500 errorMsg: ERROR: invalid byte sequence for encoding "UTF8": 0x81


Анализ проблемы

При записи в mxgate через HTTP возникает ошибка кодировки.

Решение

Проверьте наличие ASCII-символов в исходных данных.

12 Размер тела превышает заданный лимит


Анализ проблемы

Объём данных, отправляемых при записи в mxgate через HTTP, превышает лимит max-body-bytes. Значение по умолчанию — 4M, его можно просмотреть в конфигурационном файле mxgate.conf.

Решение

Измените размер max-body-bytes в mxgate.conf по необходимости и перезапустите службу.

13 Ваша лицензия истекла 2022-11-02


При запуске 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}

14 Не удаётся запустить источник: --local-ip localhost — это недопустимый IP-адрес


Анализ проблемы

При использовании 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

15 При загрузке данных MatrixGate в таблицу появляются двойные кавычки


Анализ проблемы

Эту проблему можно проанализировать, создав тестовую таблицу. Шаги следующие:

  1. Создайте тестовую таблицу
    [mxadmin@mdw ~]$ psql -d mxdb
    mxdb=# CREATE TABLE public.test(order_no text,info text) DIETRIBUTED BY(order_no);
  2. Просмотрите тестовые данные
    [mxadmin@mdw ~]$ cat test.csv 
    "1x01"|"A"
    "1x02"|"B"
    "2x01"|"C"
    "2x02"|"D"
    "3x01"|"E"
    "3x02"|"F"
  3. Используйте 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 \
    --delimiter "|" \
    --target public.test \
    --parallel 256 \
    --stream-prepared 0 \
    --interval 250
  4. Проверьте данные в таблице — обнаружены двойные кавычки, проблема воспроизведена.
    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)

16 Обновление MatrixGate


Описание проблемы

В процессе использования MatrixGate требуется обновление по особым причинам, но неизвестно, как это сделать.

Решение

  1. Остановите запись MatrixGate.
  2. Используя пользователя mxadmin, остановите HTTP-сервис, запущенный MatrixGate.
    [root@mdw ~]# su - mxadmin
    [mxadmin@mdw ~]$ mxgate stop
  3. Используя пользователя root, остановите службу Supervisor.
    [root@mdw ~]# systemctl stop matrixdb.supervisor.service
  4. Используя пользователя 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
  1. Используя пользователя root, запустите службу Supervisor.
    [root@mdw ~]# systemctl start matrixdb.supervisor.service
  2. Запустите MatrixGate.
    [root@mdw ~]# su - mxadmin 
    [mxadmin@mdw ~]$ mxgate start --config /home/mxadmin/mxgate.conf
  3. Запустите службу записи данных на фронтенде MatrixGate.

17 MatrixGate должен загружать файл данных, содержащий данные в формате Unix-времени, но поле с Unix-данными в файле не является первым


Описание проблемы

При использовании MatrixGate для загрузки данных в формате Unix-времени, если поле с Unix-данными в файле не является первым, возникает ошибка из-за невозможности преобразования типов.

Мы можем воспроизвести и проанализировать эту проблему, создав тестовую таблицу. Примеры:

  1. Создайте тестовую таблицу
    [mxadmin@mdw ~]$ psql testdb
    testdb=# CREATE TABLE dest2(
     c1 int,
     c2 text,
     time timestamp,
     c3
    )DISTRIBUTED BY(c1);
  2. Подготовьте тестовые данные
    [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
  3. Выполните команду загрузки данных MatrixGate
    [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 по умолчанию интерпретирует первый столбец как поле времени.

Решение

  1. Требования к версии: MatrixGate v4.4.7 и выше.

  2. Сгенерируйте конфигурационный файл 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
  3. Измените конфигурационный файл 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},
                                                    ]}
                ]
  4. Инструкции по настройке

- 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

Примечание В настоящее время база данных поддерживает только точность временных меток в микросекундах; временные метки в наносекундах будут искажены.

  1. Выполните загрузку
    [mxadmin@mdw ~]$ tail -n +2 test2.csv| mxgate --config mxgate.conf

18 В файле данных, загружаемом MatrixGate, присутствуют символы \N


Анализ проблемы

Мы можем воспроизвести и проанализировать эту проблему, создав тестовую таблицу. Примеры:

  1. Создайте тестовую таблицу
    [mxadmin@mdw ~]$ psql -d mxdb
    mxdb=# CREATE TABLE test(f1 int,f2 varchar(50),f3 varchar(50));
  2. Просмотрите тестовые данные
    [mxadmin@mdw ~]$ cat test.csv
    1|test|\N
  3. Используйте 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
  4. Проверьте данные в таблице — присутствует символ N
    mxdb=# SELECT * FROM test;
    f1 |  f2  | f3
    ----+------+----
    1 | test | N

Ожидаемый результат должен быть следующим:

mxdb=# SELECT * FROM test;
 f1 |  f2  | f3
----+------+----
  1 | test | 

Решение

  1. При загрузке данных с помощью 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'
  2. Проверьте данные в таблице — получен ожидаемый результат
    mxdb=# SELECT * FROM test;
    f1 |  f2  | f3
    ----+------+----
    1 | test | 

19 Соединение было прервано на порту XXX


Анализ проблемы

Согласно описанию ошибки, первоначально предполагалось, что SSH-рукопожатие было прервано.

Дальнейшая проверка ошибок lz4 | COPY XXX TO PROGRAM ssh -o StrictHostKeyChecking=no -p XXX показала, что операционная система источника — Red Hat 8.3. Пакет lz4 по умолчанию не установлен, поэтому команда lz4 не распознаётся, однако параметр --compress lz4 включён в команду, что вызывает ошибку.

Решение

  1. Установите пакет lz4 на операционной системе источника.
  2. Удалите --compress lz4 из команды записи или измените параметр на --compress zstd.

20 Может ли MatrixGate реализовать произвольное преобразование временных меток столбцов?


Да.

Примечание!
Эта функция поддерживается только в MatrixGate v4.4.7 и более поздних версиях.

  1. Пример структуры таблицы базы данных:
    [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                     |           |          |
  2. Конфигурация файла 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 для извлечения соответствующего значения dest из структуры JSON;
    • enable=true означает, что данные столбца должны быть записаны в базу данных через mxgate; если указано false, данные не будут записаны;
    • transform — функция преобразования, определяющая точность временных меток:
      • secondsToTimestamp: Преобразование временной метки в секундах;
      • millionSecondsToTimestamp: Преобразование временной метки в миллисекундах;
      • microsecondsToTimestamp: Преобразование временной метки в микросекундах;
      • nanosecondsToTimestamp: Преобразование временной метки в наносекундах.

        Примечание! В настоящее время база данных поддерживает только точность временных меток в микросекундах; наносекундные временные метки будут искажены.

  1. Важные замечания (1). format настроен как 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.

21 Можно ли скачать JAR-пакет Java SDK MatrixGate для локального импорта?


Да.

Сначала скачайте последнюю версию SDK, следуя приведённой ниже инструкции: на изображении указана версия v1.0.17 — замените её на последнюю версию в соответствии с инструкциями на изображении.

![](https://img.ymatrix.cn/ymatrix_home/SDK download 1_1670997391.png) ![](https://img.ymatrix.cn/ymatrix_home/SDK download 2_1670997432.png)

Существует три способа импорта локальных JAR-пакетов: с использованием инструмента Maven, инструмента Gradle и интегрированной среды разработки IntelliJ IDEA — выберите любой из них. Методы импорта разнообразны, вы также можете использовать другие среды разработки и инструменты для упрощения операций.

  1. Использование инструмента Maven Затем добавьте следующее содержимое в файл 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>

Готово.

  1. Использование инструмента Gradle Предположим, что JAR-пакет хранится в локальном пути libs, используйте следующий код для импорта локального JAR-пакета:
    repositories {
    flatDir {
        dirs 'libs'
    }
    }
    dependencies {
    implementation name: 'cn.ymatrix:mxgate-sdk-java:1.0.17'
    }
  2. Использование интегрированной среды разработки IntelliJ IDEA ![](https://img.ymatrix.cn/ymatrix_home/local import 1_1673339102.png) ![](https://img.ymatrix.cn/ymatrix_home/local import 2_1673339122.png) Выберите файл mxgate-sdk-java.jar из локального пути. ![](https://img.ymatrix.cn/ymatrix_home/local import 3_1673339130.png) Убедитесь, что JAR-пакет успешно импортирован в текущий проект. ![](https://img.ymatrix.cn/ymatrix_home/local import 4_1673339139.png)

22 При потреблении Kafka поле key содержит символ @, при разборе данных значение не найдено


Анализ проблемы

Специальные символы @ не могут быть корректно распознаны.

Воспроизведение проблемы

  1. Тестовые данные
    {
     "@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
     }
    }
  2. Настройте доступ к данным Kafka через графический интерфейс (Mxui)

Решение

  1. После неудачной настройки через графический интерфейс найдите соответствующий сгенерированный файл mxgate.conf. Измените соответствующее значение transform.json:
    source = "$.@timestamp" --> source = "$['@timestamp']"
    source = "$.@Version" --> source = "$['@Version']"
  2. Запустите службу через командную строку на уровне хоста: поле key содержит символ @, и потребление данных проходит нормально.

23 Пользователь, не являющийся mxadmin, получает сообщение об отсутствии прав при использовании режима миграции mxgate


При использовании режима миграции 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, не имеют прав на создание внешних таблиц.

Решение

  1. При использовании режима миграции mxgate используйте пользователя mxadmin. Пользователь, использующий mxadmin, не изменит права исходной таблицы.

  2. Предоставьте другим пользователям права на внешние таблицы или повысьте права других пользователей до уровня администратора.